From 01fce410a5ff45cab8fe6f52a6b0d29a0a8a213c Mon Sep 17 00:00:00 2001 From: ryan Date: Sun, 5 Nov 2023 23:57:41 -0600 Subject: [PATCH] keyfork-derive-openpgp: fix encryption keys --- keyfork-derive-openpgp/src/lib.rs | 34 +++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/keyfork-derive-openpgp/src/lib.rs b/keyfork-derive-openpgp/src/lib.rs index 23b4b94..f1df991 100644 --- a/keyfork-derive-openpgp/src/lib.rs +++ b/keyfork-derive-openpgp/src/lib.rs @@ -21,6 +21,9 @@ pub enum Error { #[error("{0}")] Anyhow(#[from] anyhow::Error), + #[error("Key configured with both encryption and non-encryption key flags: {0:?}")] + InvalidKeyFlags(KeyFlags), + #[error("Incorrect derived data: {0}")] IncorrectDerivedData(#[from] TryFromDerivationResponseError), @@ -79,13 +82,32 @@ pub fn derive(data: DerivationResponse, keys: &[KeyFlags], userid: UserID) -> Re // Generate subkey let index = u32::try_from(index)?; let derived_key = xprv.derive_child(&DerivationIndex::new(index, true)?)?; - let subkey = Key::from( - Key4::<_, SubordinateRole>::import_secret_ed25519( - &PrivateKey::to_bytes(derived_key.private_key()), - epoch, + let is_enc = + subkey_flags.for_transport_encryption() || subkey_flags.for_storage_encryption(); + let is_non_enc = subkey_flags.for_certification() + || subkey_flags.for_signing() + || subkey_flags.for_authentication(); + let subkey = if is_enc && is_non_enc { + return Err(Error::InvalidKeyFlags(subkey_flags.clone())); + } else if is_enc { + Key::from( + Key4::<_, SubordinateRole>::import_secret_cv25519( + &PrivateKey::to_bytes(derived_key.private_key()), + None, + None, + epoch, + ) + .expect("keyforkd gave invalid cv25519 key"), ) - .unwrap(), - ); + } else { + Key::from( + Key4::<_, SubordinateRole>::import_secret_ed25519( + &PrivateKey::to_bytes(derived_key.private_key()), + epoch, + ) + .expect("keyforkd gave invalid ed25519 key"), + ) + }; // As per OpenPGP spec, signing keys must backsig the primary key let builder = if subkey_flags.for_signing() {