Fix naked-key upload test (test_no_selfsig)

Previously, the test used Sequoia's high-level API which attached a
Direct-Key Signature to the key. As such, this wasn't a truly
naked-key.

This test uses low-level API to contruct a bare key and checks if the
import fails. Then it attaches a DKS which causes the import to
succeed. Then it revokes that key and checks if the revocation is
correctly propagated.
This commit is contained in:
Wiktor Kwapisiewicz
2025-07-28 13:26:30 +02:00
parent 12f0eef5be
commit 5b28cedf37

View File

@@ -16,9 +16,13 @@
use std::convert::{TryFrom, TryInto};
use std::str::FromStr;
use std::time::SystemTime;
use crate::types::{Email, Fingerprint, KeyID};
use crate::{Database, Query};
use sequoia_openpgp::packet::Key;
use sequoia_openpgp::packet::key::{Key4, PrimaryRole, PublicParts, SecretParts};
use sequoia_openpgp::types::{Features, HashAlgorithm};
use sequoia_openpgp::{
Cert, Packet,
cert::{CertBuilder, UserIDRevocationBuilder},
@@ -1329,16 +1333,60 @@ pub fn test_unsigned_uids<'a>(db: &'a mut impl Database<'a>) {
}
pub fn test_no_selfsig<'a>(db: &'a mut impl Database<'a>) {
let (mut tpk, revocation) = CertBuilder::new().generate().unwrap();
let mut key: Key<SecretParts, PrimaryRole> =
Key4::generate_ecc(true, sequoia_openpgp::types::Curve::Ed25519)
.unwrap()
.into();
let mut tpk = Cert::try_from(vec![Packet::SecretKey(key.clone())]).unwrap();
let fpr = Fingerprint::try_from(tpk.fingerprint()).unwrap();
// don't allow upload of naked key
assert!(db.merge(tpk.clone()).is_err());
// with revocation, it's ok
tpk = tpk.insert_packets(revocation).unwrap();
let tpk_status = db.merge(tpk).unwrap().into_tpk_status();
// create direct-key signature manually
let date = SystemTime::now();
key.set_creation_time(date).unwrap();
let sig = SignatureBuilder::new(SignatureType::DirectKey)
.set_hash_algo(sequoia_openpgp::types::HashAlgorithm::SHA512)
.set_signature_creation_time(date)
.unwrap()
.set_features(Features::sequoia())
.unwrap()
.set_key_flags(KeyFlags::empty().set_certification())
.unwrap()
.set_preferred_hash_algorithms(vec![(HashAlgorithm::SHA512), (HashAlgorithm::SHA256)])
.unwrap();
let mut signer = key.clone().into_keypair().unwrap();
let sig = sig
.sign_direct_key(&mut signer, key.parts_as_public().role_as_primary())
.unwrap();
tpk = tpk.insert_packets(sig).unwrap();
let tpk_status = db.merge(tpk.clone()).unwrap().into_tpk_status();
check_log_entry(db, &fpr);
// the key is not revoked with only a DKS
assert_eq!(
TpkStatus {
is_revoked: false,
email_status: vec!(),
unparsed_uids: 0
},
tpk_status
);
// now revoke it
let revocation = tpk
.revoke(
&mut key.clone().into_keypair().unwrap(),
ReasonForRevocation::KeyCompromised,
b"whoopsie!",
)
.unwrap();
tpk = tpk.insert_packets(revocation).unwrap();
let tpk_status = db.merge(tpk.clone()).unwrap().into_tpk_status();
check_log_entry(db, &fpr);
// it's correctly revoked
assert_eq!(
TpkStatus {
is_revoked: true,