keyfork-derive-openpgp: decouple key signature time from key creation time

This commit is contained in:
Ryan Heywood 2024-02-19 17:59:55 -05:00
parent 425aa30aa6
commit b15d088905
Signed by: ryan
GPG Key ID: 8E401478A3FBEF72
1 changed files with 13 additions and 9 deletions

View File

@ -71,6 +71,7 @@ pub fn derive(xprv: XPrv, keys: &[KeyFlags], userid: &UserID) -> Result<Cert> {
}; };
let epoch = SystemTime::UNIX_EPOCH + Duration::from_secs(1); let epoch = SystemTime::UNIX_EPOCH + Duration::from_secs(1);
let now = SystemTime::now();
let expiration_date = match std::env::var("KEYFORK_OPENPGP_EXPIRE").as_mut() { let expiration_date = match std::env::var("KEYFORK_OPENPGP_EXPIRE").as_mut() {
Ok(var) => { Ok(var) => {
let ch = var.pop(); let ch = var.pop();
@ -82,26 +83,27 @@ pub fn derive(xprv: XPrv, keys: &[KeyFlags], userid: &UserID) -> Result<Cert> {
'y' => 365, 'y' => 365,
_ => unreachable!(), _ => unreachable!(),
}; };
SystemTime::now() + Duration::from_secs(60 * 60 * 24 * expire * multiplier) now + Duration::from_secs(60 * 60 * 24 * expire * multiplier)
} }
_ => SystemTime::now() + Duration::from_secs(60 * 60 * 24), _ => now + Duration::from_secs(60 * 60 * 24),
} }
} }
Err(_) => SystemTime::now() + Duration::from_secs(60 * 60 * 24), Err(_) => now + Duration::from_secs(60 * 60 * 24),
}; };
// Create certificate with initial key and signature // Create certificate with initial key and signature
let derived_primary_key = xprv.derive_child(&DerivationIndex::new(0, true)?)?; let derived_primary_key = xprv.derive_child(&DerivationIndex::new(0, true)?)?;
let primary_key = Key::from(Key4::<_, PrimaryRole>::import_secret_ed25519( let mut primary_key = Key::from(Key4::<_, PrimaryRole>::import_secret_ed25519(
&PrivateKey::to_bytes(derived_primary_key.private_key()), &PrivateKey::to_bytes(derived_primary_key.private_key()),
epoch, epoch,
)?); )?);
primary_key.set_creation_time(epoch)?;
let cert = Cert::from_packets(vec![Packet::SecretKey(primary_key.clone())].into_iter())?; let cert = Cert::from_packets(vec![Packet::SecretKey(primary_key.clone())].into_iter())?;
// Sign and attach primary key and primary userid // Sign and attach primary key and primary userid
let builder = SignatureBuilder::new(SignatureType::PositiveCertification) let builder = SignatureBuilder::new(SignatureType::PositiveCertification)
.set_key_validity_period(expiration_date.duration_since(epoch)?)? .set_key_validity_period(expiration_date.duration_since(epoch)?)?
.set_signature_creation_time(epoch)? // .set_signature_creation_time(now)?
.set_key_flags(primary_key_flags.clone())?; .set_key_flags(primary_key_flags.clone())?;
let binding = userid.bind(&mut primary_key.clone().into_keypair()?, &cert, builder)?; let binding = userid.bind(&mut primary_key.clone().into_keypair()?, &cert, builder)?;
let cert = cert.insert_packets(vec![Packet::from(userid.clone()), binding.into()])?; let cert = cert.insert_packets(vec![Packet::from(userid.clone()), binding.into()])?;
@ -123,7 +125,7 @@ pub fn derive(xprv: XPrv, keys: &[KeyFlags], userid: &UserID) -> Result<Cert> {
let is_non_enc = subkey_flags.for_certification() let is_non_enc = subkey_flags.for_certification()
|| subkey_flags.for_signing() || subkey_flags.for_signing()
|| subkey_flags.for_authentication(); || subkey_flags.for_authentication();
let subkey = if is_enc && is_non_enc { let mut subkey = if is_enc && is_non_enc {
return Err(Error::InvalidKeyFlags(subkey_flags.clone())); return Err(Error::InvalidKeyFlags(subkey_flags.clone()));
} else if is_enc { } else if is_enc {
// Clamp key before exporting as OpenPGP. Reference: // Clamp key before exporting as OpenPGP. Reference:
@ -143,15 +145,17 @@ pub fn derive(xprv: XPrv, keys: &[KeyFlags], userid: &UserID) -> Result<Cert> {
)?) )?)
}; };
subkey.set_creation_time(epoch)?;
// As per OpenPGP spec, signing keys must backsig the primary key // As per OpenPGP spec, signing keys must backsig the primary key
let builder = if subkey_flags.for_signing() { let builder = if subkey_flags.for_signing() {
SignatureBuilder::new(SignatureType::SubkeyBinding) SignatureBuilder::new(SignatureType::SubkeyBinding)
.set_key_flags(subkey_flags.clone())? .set_key_flags(subkey_flags.clone())?
.set_signature_creation_time(epoch)? // .set_signature_creation_time(epoch)?
.set_key_validity_period(expiration_date.duration_since(epoch)?)? .set_key_validity_period(expiration_date.duration_since(epoch)?)?
.set_embedded_signature( .set_embedded_signature(
SignatureBuilder::new(SignatureType::PrimaryKeyBinding) SignatureBuilder::new(SignatureType::PrimaryKeyBinding)
.set_signature_creation_time(epoch)? //.set_signature_creation_time(epoch)?
.sign_primary_key_binding( .sign_primary_key_binding(
&mut subkey.clone().into_keypair()?, &mut subkey.clone().into_keypair()?,
&primary_key, &primary_key,
@ -161,7 +165,7 @@ pub fn derive(xprv: XPrv, keys: &[KeyFlags], userid: &UserID) -> Result<Cert> {
} else { } else {
SignatureBuilder::new(SignatureType::SubkeyBinding) SignatureBuilder::new(SignatureType::SubkeyBinding)
.set_key_flags(subkey_flags.clone())? .set_key_flags(subkey_flags.clone())?
.set_signature_creation_time(epoch)? // .set_signature_creation_time(epoch)?
.set_key_validity_period(expiration_date.duration_since(epoch)?)? .set_key_validity_period(expiration_date.duration_since(epoch)?)?
}; };