From 2670cf63a3bd534aa07686c46a144f07fe66e32c Mon Sep 17 00:00:00 2001 From: ryan Date: Tue, 26 Dec 2023 15:45:11 -0500 Subject: [PATCH] keyfork-shard: homogenize function signatures, start work on decrypt_one() --- keyfork-shard/src/openpgp.rs | 66 ++++++++++++++++++++++++++++-------- 1 file changed, 52 insertions(+), 14 deletions(-) diff --git a/keyfork-shard/src/openpgp.rs b/keyfork-shard/src/openpgp.rs index 7160e26..be74ba9 100644 --- a/keyfork-shard/src/openpgp.rs +++ b/keyfork-shard/src/openpgp.rs @@ -232,8 +232,8 @@ fn decode_metadata_v1(buf: &[u8]) -> Result<(u8, Cert, Vec)> { // single message. fn decrypt_with_manager( threshold: u8, - certs: &[Cert], messages: &mut HashMap, + certs: &[Cert], policy: NullPolicy, manager: &mut SmartcardManager, ) -> Result>> { @@ -276,10 +276,10 @@ fn decrypt_with_manager( // NOTE: When using single-decryptor mechanism, only a single key should be provided in Keyring to // decrypt messages with. fn decrypt_with_keyring( + messages: &mut HashMap, certs: &[Cert], policy: &NullPolicy, keyring: &mut Keyring, - messages: &mut HashMap, ) -> Result>, Error> { let mut decrypted_messages = HashMap::new(); @@ -309,6 +309,53 @@ fn decrypt_with_keyring( Ok(decrypted_messages) } +fn decrypt_metadata( + message: &EncryptedMessage, + policy: &NullPolicy, + keyring: &mut Keyring, + manager: &mut SmartcardManager, +) -> Result> { + Ok(if keyring.is_empty() { + manager.load_any_card()?; + message.decrypt_with(policy, manager)? + } else { + message.decrypt_with(policy, keyring)? + }) +} + +fn decrypt_one( + messages: Vec, + keyring: &mut Keyring, + manager: &mut SmartcardManager, + metadata: EncryptedMessage, +) -> Result> { + let policy = NullPolicy::new(); + + let content = decrypt_metadata(&metadata, &policy, &mut *keyring, &mut *manager)?; + + let (_threshold, root_cert, certs) = decode_metadata_v1(&content)?; + + keyring.set_root_cert(root_cert.clone()); + manager.set_root_cert(root_cert); + + let mut messages: HashMap = + HashMap::from_iter(certs.iter().map(|c| c.keyid()).zip(messages)); + + let decrypted_messages = decrypt_with_keyring(&mut messages, &certs, &policy, keyring)?; + + if let Some(message) = decrypted_messages.into_values().next() { + return Ok(message); + } + + let decrypted_messages = decrypt_with_manager(1, &mut messages, &certs, policy, manager)?; + + if let Some(message) = decrypted_messages.into_values().next() { + return Ok(message); + } + + unreachable!("smartcard manager should always decrypt") +} + pub fn combine( certs: Vec, metadata: EncryptedMessage, @@ -321,16 +368,7 @@ pub fn combine( let mut keyring = Keyring::new(certs)?; let mut manager = SmartcardManager::new()?; - let content = if keyring.is_empty() { - // NOTE: Any card plugged in that can't decrypt, will raise issues. - // This should not be used on a system where OpenPGP cards are available that shouldn't be - // used. The manager will try every wildcard packet for the card on the system, and once no - // matching PKESK packet has been found, will return an error. - manager.load_any_card()?; - metadata.decrypt_with(&policy, &mut manager)? - } else { - metadata.decrypt_with(&policy, &mut keyring)? - }; + let content = decrypt_metadata(&metadata, &policy, &mut keyring, &mut manager)?; let (threshold, root_cert, certs) = decode_metadata_v1(&content)?; @@ -344,7 +382,7 @@ pub fn combine( HashMap::from_iter(certs.iter().map(|c| c.keyid()).zip(messages)); let mut decrypted_messages = - decrypt_with_keyring(&certs, &policy, &mut keyring, &mut messages)?; + decrypt_with_keyring(&mut messages, &certs, &policy, &mut keyring)?; // clean decrypted messages from encrypted messages messages.retain(|k, _v| !decrypted_messages.contains_key(k)); @@ -353,8 +391,8 @@ pub fn combine( if left_from_threshold > 0 { let new_messages = decrypt_with_manager( left_from_threshold as u8, - &certs, &mut messages, + &certs, policy, &mut manager, )?;