diff options
-rw-r--r-- | guide/src/chapter_02.md | 12 | ||||
-rw-r--r-- | ipc/examples/gpg-agent-decrypt.rs | 3 | ||||
-rw-r--r-- | ipc/tests/gpg-agent.rs | 3 | ||||
-rw-r--r-- | openpgp-ffi/include/sequoia/openpgp/types.h | 1 | ||||
-rw-r--r-- | openpgp-ffi/src/parse/stream.rs | 4 | ||||
-rw-r--r-- | openpgp/examples/decrypt-with.rs | 3 | ||||
-rw-r--r-- | openpgp/examples/generate-encrypt-decrypt.rs | 3 | ||||
-rw-r--r-- | openpgp/src/packet/aed.rs | 4 | ||||
-rw-r--r-- | openpgp/src/parse/stream.rs | 18 | ||||
-rw-r--r-- | openpgp/src/policy.rs | 3 | ||||
-rw-r--r-- | openpgp/src/serialize/stream.rs | 3 | ||||
-rw-r--r-- | tool/src/commands/decrypt.rs | 21 |
12 files changed, 58 insertions, 20 deletions
diff --git a/guide/src/chapter_02.md b/guide/src/chapter_02.md index 8eda8284..88dfe1d7 100644 --- a/guide/src/chapter_02.md +++ b/guide/src/chapter_02.md @@ -128,6 +128,7 @@ fn main() { # fn decrypt<D>(&mut self, # pkesks: &[openpgp::packet::PKESK], # _skesks: &[openpgp::packet::SKESK], +# sym_algo: Option<SymmetricAlgorithm>, # mut decrypt: D) # -> openpgp::Result<Option<openpgp::Fingerprint>> # where D: FnMut(SymmetricAlgorithm, &SessionKey) -> openpgp::Result<()> @@ -139,7 +140,7 @@ fn main() { # // The secret key is not encrypted. # let mut pair = key.mark_parts_secret().unwrap().into_keypair().unwrap(); # -# pkesks[0].decrypt(&mut pair, None) +# pkesks[0].decrypt(&mut pair, sym_algo) # .and_then(|(algo, session_key)| decrypt(algo, &session_key)) # .map(|_| None) # // XXX: In production code, return the Fingerprint of the @@ -276,6 +277,7 @@ fn generate() -> openpgp::Result<openpgp::Cert> { # fn decrypt<D>(&mut self, # pkesks: &[openpgp::packet::PKESK], # _skesks: &[openpgp::packet::SKESK], +# sym_algo: Option<SymmetricAlgorithm>, # mut decrypt: D) # -> openpgp::Result<Option<openpgp::Fingerprint>> # where D: FnMut(SymmetricAlgorithm, &SessionKey) -> openpgp::Result<()> @@ -287,7 +289,7 @@ fn generate() -> openpgp::Result<openpgp::Cert> { # // The secret key is not encrypted. # let mut pair = key.mark_parts_secret().unwrap().into_keypair().unwrap(); # -# pkesks[0].decrypt(&mut pair, None) +# pkesks[0].decrypt(&mut pair, sym_algo) # .and_then(|(algo, session_key)| decrypt(algo, &session_key)) # .map(|_| None) # // XXX: In production code, return the Fingerprint of the @@ -424,6 +426,7 @@ fn encrypt(policy: &dyn Policy, # fn decrypt<D>(&mut self, # pkesks: &[openpgp::packet::PKESK], # _skesks: &[openpgp::packet::SKESK], +# sym_algo: Option<SymmetricAlgorithm>, # mut decrypt: D) # -> openpgp::Result<Option<openpgp::Fingerprint>> # where D: FnMut(SymmetricAlgorithm, &SessionKey) -> openpgp::Result<()> @@ -435,7 +438,7 @@ fn encrypt(policy: &dyn Policy, # // The secret key is not encrypted. # let mut pair = key.mark_parts_secret().unwrap().into_keypair().unwrap(); # -# pkesks[0].decrypt(&mut pair, None) +# pkesks[0].decrypt(&mut pair, sym_algo) # .and_then(|(algo, session_key)| decrypt(algo, &session_key)) # .map(|_| None) # // XXX: In production code, return the Fingerprint of the @@ -586,6 +589,7 @@ impl<'a> DecryptionHelper for Helper<'a> { fn decrypt<D>(&mut self, pkesks: &[openpgp::packet::PKESK], _skesks: &[openpgp::packet::SKESK], + sym_algo: Option<SymmetricAlgorithm>, mut decrypt: D) -> openpgp::Result<Option<openpgp::Fingerprint>> where D: FnMut(SymmetricAlgorithm, &SessionKey) -> openpgp::Result<()> @@ -596,7 +600,7 @@ impl<'a> DecryptionHelper for Helper<'a> { // The secret key is not encrypted. let mut pair = key.mark_parts_secret().unwrap().into_keypair().unwrap(); - pkesks[0].decrypt(&mut pair, None) + pkesks[0].decrypt(&mut pair, sym_algo) .and_then(|(algo, session_key)| decrypt(algo, &session_key)) .map(|_| None) // XXX: In production code, return the Fingerprint of the diff --git a/ipc/examples/gpg-agent-decrypt.rs b/ipc/examples/gpg-agent-decrypt.rs index 9dc0fbe2..97397363 100644 --- a/ipc/examples/gpg-agent-decrypt.rs +++ b/ipc/examples/gpg-agent-decrypt.rs @@ -96,6 +96,7 @@ impl<'a> DecryptionHelper for Helper<'a> { fn decrypt<D>(&mut self, pkesks: &[openpgp::packet::PKESK], _skesks: &[openpgp::packet::SKESK], + sym_algo: Option<SymmetricAlgorithm>, mut decrypt: D) -> openpgp::Result<Option<openpgp::Fingerprint>> where D: FnMut(SymmetricAlgorithm, &SessionKey) -> openpgp::Result<()> @@ -104,7 +105,7 @@ impl<'a> DecryptionHelper for Helper<'a> { for pkesk in pkesks { if let Some(key) = self.keys.get(pkesk.recipient()) { let mut pair = KeyPair::new(self.ctx, key)?; - if let Ok(_) = pkesk.decrypt(&mut pair, None) + if let Ok(_) = pkesk.decrypt(&mut pair, sym_algo) .and_then(|(algo, session_key)| decrypt(algo, &session_key)) { break; diff --git a/ipc/tests/gpg-agent.rs b/ipc/tests/gpg-agent.rs index 91794509..2322e6d9 100644 --- a/ipc/tests/gpg-agent.rs +++ b/ipc/tests/gpg-agent.rs @@ -277,6 +277,7 @@ fn decrypt() { fn decrypt<D>(&mut self, pkesks: &[openpgp::packet::PKESK], _skesks: &[openpgp::packet::SKESK], + sym_algo: Option<SymmetricAlgorithm>, mut decrypt: D) -> openpgp::Result<Option<openpgp::Fingerprint>> where D: FnMut(SymmetricAlgorithm, &SessionKey) -> @@ -289,7 +290,7 @@ fn decrypt() { .take(1).next().unwrap().key()) .unwrap(); - pkesks[0].decrypt(&mut keypair, None) + pkesks[0].decrypt(&mut keypair, sym_algo) .and_then(|(algo, session_key)| decrypt(algo, &session_key)) .map(|_| None) // XXX: In production code, return the Fingerprint of the diff --git a/openpgp-ffi/include/sequoia/openpgp/types.h b/openpgp-ffi/include/sequoia/openpgp/types.h index e99413d0..46deb520 100644 --- a/openpgp-ffi/include/sequoia/openpgp/types.h +++ b/openpgp-ffi/include/sequoia/openpgp/types.h @@ -510,6 +510,7 @@ typedef pgp_status_t (pgp_decryptor_do_decrypt_cb_t) ( typedef pgp_status_t (*pgp_decryptor_decrypt_cb_t) (void *, pgp_pkesk_t *, size_t, pgp_skesk_t *, size_t, + uint8_t, /* XXX: SymmetricAlgorithm */ pgp_decryptor_do_decrypt_cb_t *, void *, pgp_fingerprint_t *); diff --git a/openpgp-ffi/src/parse/stream.rs b/openpgp-ffi/src/parse/stream.rs index 0fb0bec9..5c9c92a3 100644 --- a/openpgp-ffi/src/parse/stream.rs +++ b/openpgp-ffi/src/parse/stream.rs @@ -335,6 +335,7 @@ type InspectCallback = fn(*mut HelperCookie, *const PacketParser) -> Status; type DecryptCallback = fn(*mut HelperCookie, *const *const PKESK, usize, *const *const SKESK, usize, + u8, // XXX SymmetricAlgorithm extern "C" fn (*mut c_void, u8, *const crypto::SessionKey) -> Status, @@ -733,6 +734,7 @@ impl DecryptionHelper for DHelper { } fn decrypt<D>(&mut self, pkesks: &[PKESK], skesks: &[SKESK], + sym_algo: Option<SymmetricAlgorithm>, mut decrypt: D) -> openpgp::Result<Option<openpgp::Fingerprint>> where D: FnMut(SymmetricAlgorithm, &SessionKey) -> openpgp::Result<()> @@ -769,6 +771,7 @@ impl DecryptionHelper for DHelper { let result = (self.decrypt_cb)( self.vhelper.cookie, pkesks.as_ptr(), pkesks.len(), skesks.as_ptr(), skesks.len(), + sym_algo.map(|s| u8::from(s)).unwrap_or(0), trampoline::<D>, &mut decrypt as *mut _ as *mut c_void, &mut identity); @@ -847,6 +850,7 @@ impl DecryptionHelper for DHelper { /// decrypt_cb (void *cookie_opaque, /// pgp_pkesk_t *pkesks, size_t pkesk_count, /// pgp_skesk_t *skesks, size_t skesk_count, +/// uint8_t sym_algo_hint, /// pgp_decryptor_do_decrypt_cb_t *decrypt, /// void *decrypt_cookie, /// pgp_fingerprint_t *identity_out) diff --git a/openpgp/examples/decrypt-with.rs b/openpgp/examples/decrypt-with.rs index a72f0a7d..860c4a56 100644 --- a/openpgp/examples/decrypt-with.rs +++ b/openpgp/examples/decrypt-with.rs @@ -84,6 +84,7 @@ impl DecryptionHelper for Helper { fn decrypt<D>(&mut self, pkesks: &[openpgp::packet::PKESK], _skesks: &[openpgp::packet::SKESK], + sym_algo: Option<SymmetricAlgorithm>, mut decrypt: D) -> openpgp::Result<Option<openpgp::Fingerprint>> where D: FnMut(SymmetricAlgorithm, &SessionKey) -> openpgp::Result<()> @@ -91,7 +92,7 @@ impl DecryptionHelper for Helper { // Try each PKESK until we succeed. for pkesk in pkesks { if let Some(pair) = self.keys.get_mut(pkesk.recipient()) { - if let Ok(_) = pkesk.decrypt(pair, None) + if let Ok(_) = pkesk.decrypt(pair, sym_algo) .and_then(|(algo, session_key)| decrypt(algo, &session_key)) { break; diff --git a/openpgp/examples/generate-encrypt-decrypt.rs b/openpgp/examples/generate-encrypt-decrypt.rs index abf0d04b..110c8b1a 100644 --- a/openpgp/examples/generate-encrypt-decrypt.rs +++ b/openpgp/examples/generate-encrypt-decrypt.rs @@ -120,6 +120,7 @@ impl<'a> DecryptionHelper for Helper<'a> { fn decrypt<D>(&mut self, pkesks: &[openpgp::packet::PKESK], _skesks: &[openpgp::packet::SKESK], + sym_algo: Option<SymmetricAlgorithm>, mut decrypt: D) -> openpgp::Result<Option<openpgp::Fingerprint>> where D: FnMut(SymmetricAlgorithm, &SessionKey) -> openpgp::Result<()> @@ -130,7 +131,7 @@ impl<'a> DecryptionHelper for Helper<'a> { // The secret key is not encrypted. let mut pair = key.mark_parts_secret().unwrap().into_keypair().unwrap(); - pkesks[0].decrypt(&mut pair, None) + pkesks[0].decrypt(&mut pair, sym_algo) .and_then(|(algo, session_key)| decrypt(algo, &session_key)) .map(|_| None) // XXX: In production code, return the Fingerprint of the diff --git a/openpgp/src/packet/aed.rs b/openpgp/src/packet/aed.rs index a8d1bfa0..40e3124d 100644 --- a/openpgp/src/packet/aed.rs +++ b/openpgp/src/packet/aed.rs @@ -88,8 +88,8 @@ impl AED1 { } /// Sets the sym_algo algorithm. - pub fn set_sym_algo(&mut self, sym_algo: SymmetricAlgorithm) - -> SymmetricAlgorithm { + pub fn set_symmetric_algo(&mut self, sym_algo: SymmetricAlgorithm) + -> SymmetricAlgorithm { ::std::mem::replace(&mut self.sym_algo, sym_algo) } diff --git a/openpgp/src/parse/stream.rs b/openpgp/src/parse/stream.rs index 3e0dad10..eadba97c 100644 --- a/openpgp/src/parse/stream.rs +++ b/openpgp/src/parse/stream.rs @@ -1352,6 +1352,7 @@ impl DetachedVerifier { /// } /// impl DecryptionHelper for Helper { /// fn decrypt<D>(&mut self, _: &[PKESK], skesks: &[SKESK], +/// _sym_algo: Option<SymmetricAlgorithm>, /// mut decrypt: D) -> Result<Option<openpgp::Fingerprint>> /// where D: FnMut(SymmetricAlgorithm, &SessionKey) -> Result<()> /// { @@ -1430,7 +1431,11 @@ pub trait DecryptionHelper { /// algorithm and session key from one of the PKESK packets, the /// SKESKs, or retrieve it from a cache, and then call `decrypt` /// with the symmetric algorithm and session key. + /// + /// If a symmetric algorithm is given, it should be passed on to + /// PKESK::decrypt. fn decrypt<D>(&mut self, pkesks: &[PKESK], skesks: &[SKESK], + sym_algo: Option<SymmetricAlgorithm>, decrypt: D) -> Result<Option<Fingerprint>> where D: FnMut(SymmetricAlgorithm, &SessionKey) -> Result<()>; } @@ -1557,6 +1562,12 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> { return Err(err.context("Malformed OpenPGP message").into()); } + let sym_algo_hint = if let Packet::AED(ref aed) = pp.packet { + Some(aed.symmetric_algo()) + } else { + None + }; + match pp.packet { Packet::CompressedData(ref p) => v.structure.new_compression_layer(p.algo()), @@ -1578,6 +1589,7 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> { v.identity = v.helper.decrypt(&pkesks[..], &skesks[..], + sym_algo_hint, decryption_proxy)?; } if ! pp.decrypted() { @@ -2015,7 +2027,8 @@ mod test { } impl DecryptionHelper for VHelper { - fn decrypt<D>(&mut self, _: &[PKESK], _: &[SKESK], _: D) + fn decrypt<D>(&mut self, _: &[PKESK], _: &[SKESK], + _: Option<SymmetricAlgorithm>, _: D) -> Result<Option<Fingerprint>> where D: FnMut(SymmetricAlgorithm, &SessionKey) -> Result<()> { @@ -2143,7 +2156,8 @@ mod test { } } impl DecryptionHelper for VHelper { - fn decrypt<D>(&mut self, _: &[PKESK], _: &[SKESK], _: D) + fn decrypt<D>(&mut self, _: &[PKESK], _: &[SKESK], + _: Option<SymmetricAlgorithm>, _: D) -> Result<Option<Fingerprint>> where D: FnMut(SymmetricAlgorithm, &SessionKey) -> Result<()> { diff --git a/openpgp/src/policy.rs b/openpgp/src/policy.rs index 471a6bc2..20ae9b24 100644 --- a/openpgp/src/policy.rs +++ b/openpgp/src/policy.rs @@ -561,7 +561,8 @@ mod test { } impl DecryptionHelper for VHelper { - fn decrypt<D>(&mut self, _: &[PKESK], _: &[SKESK], _: D) + fn decrypt<D>(&mut self, _: &[PKESK], _: &[SKESK], + _: Option<SymmetricAlgorithm>,_: D) -> Result<Option<Fingerprint>> where D: FnMut(SymmetricAlgorithm, &SessionKey) -> Result<()> { diff --git a/openpgp/src/serialize/stream.rs b/openpgp/src/serialize/stream.rs index f8d3ed4b..961298b9 100644 --- a/openpgp/src/serialize/stream.rs +++ b/openpgp/src/serialize/stream.rs @@ -1699,6 +1699,7 @@ mod test { } impl<'a> DecryptionHelper for Helper<'a> { fn decrypt<D>(&mut self, pkesks: &[PKESK], _skesks: &[SKESK], + sym_algo: Option<SymmetricAlgorithm>, mut decrypt: D) -> Result<Option<crate::Fingerprint>> where D: FnMut(SymmetricAlgorithm, &SessionKey) -> Result<()> { @@ -1707,7 +1708,7 @@ mod test { .map(|ka| ka.key()).next().unwrap() .clone().mark_parts_secret().unwrap() .into_keypair().unwrap(); - pkesks[0].decrypt(&mut keypair, None) + pkesks[0].decrypt(&mut keypair, sym_algo) .and_then(|(algo, session_key)| decrypt(algo, &session_key)) .map(|_| None) } diff --git a/tool/src/commands/decrypt.rs b/tool/src/commands/decrypt.rs index 410c24d2..6c459967 100644 --- a/tool/src/commands/decrypt.rs +++ b/tool/src/commands/decrypt.rs @@ -86,13 +86,14 @@ impl<'a> Helper<'a> { /// Tries to decrypt the given PKESK packet with `keypair` and try /// to decrypt the packet parser using `decrypt`. fn try_decrypt<D>(&self, pkesk: &PKESK, + sym_algo: Option<SymmetricAlgorithm>, keypair: &mut dyn crypto::Decryptor, decrypt: &mut D) -> openpgp::Result<Option<Fingerprint>> where D: FnMut(SymmetricAlgorithm, &SessionKey) -> openpgp::Result<()> { let keyid = keypair.public().fingerprint().into(); - match pkesk.decrypt(keypair, None) + match pkesk.decrypt(keypair, sym_algo) .and_then(|(algo, sk)| { decrypt(algo, &sk)?; Ok(sk) }) @@ -137,6 +138,7 @@ impl<'a> DecryptionHelper for Helper<'a> { } fn decrypt<D>(&mut self, pkesks: &[PKESK], skesks: &[SKESK], + sym_algo: Option<SymmetricAlgorithm>, mut decrypt: D) -> openpgp::Result<Option<Fingerprint>> where D: FnMut(SymmetricAlgorithm, &SessionKey) -> openpgp::Result<()> { @@ -148,7 +150,7 @@ impl<'a> DecryptionHelper for Helper<'a> { if key.secret().map(|s| ! s.is_encrypted()).unwrap_or(false) { if let Ok(fp) = key.clone().into_keypair() .and_then(|mut k| - self.try_decrypt(pkesk, &mut k, &mut decrypt)) + self.try_decrypt(pkesk, sym_algo, &mut k, &mut decrypt)) { return Ok(fp); } @@ -188,7 +190,7 @@ impl<'a> DecryptionHelper for Helper<'a> { } }; - if let Ok(fp) = self.try_decrypt(pkesk, &mut keypair, + if let Ok(fp) = self.try_decrypt(pkesk, sym_algo, &mut keypair, &mut decrypt) { return Ok(fp); } @@ -203,7 +205,7 @@ impl<'a> DecryptionHelper for Helper<'a> { if key.secret().map(|s| ! s.is_encrypted()).unwrap_or(false) { if let Ok(fp) = key.clone().into_keypair() .and_then(|mut k| - self.try_decrypt(pkesk, &mut k, &mut decrypt)) + self.try_decrypt(pkesk, sym_algo, &mut k, &mut decrypt)) { return Ok(fp); } @@ -248,7 +250,7 @@ impl<'a> DecryptionHelper for Helper<'a> { } }; - if let Ok(fp) = self.try_decrypt(pkesk, &mut keypair, + if let Ok(fp) = self.try_decrypt(pkesk, sym_algo, &mut keypair, &mut decrypt) { return Ok(fp); } @@ -324,12 +326,19 @@ pub fn decrypt_unwrap(ctx: &Context, policy: &dyn Policy, let mut pkesks: Vec<packet::PKESK> = Vec::new(); let mut skesks: Vec<packet::SKESK> = Vec::new(); while let PacketParserResult::Some(mut pp) = ppr { + let sym_algo_hint = if let Packet::AED(ref aed) = pp.packet { + Some(aed.symmetric_algo()) + } else { + None + }; + match pp.packet { Packet::SEIP(_) | Packet::AED(_) => { { let decrypt = |algo, secret: &SessionKey| pp.decrypt(algo, secret); - helper.decrypt(&pkesks[..], &skesks[..], decrypt)?; + helper.decrypt(&pkesks[..], &skesks[..], sym_algo_hint, + decrypt)?; } if ! pp.decrypted() { // XXX: That is not quite the right error to return. |