diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2020-02-12 12:32:36 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2020-02-12 15:12:21 +0100 |
commit | b0648d984bc618686a18d5e0a5173c16b2328549 (patch) | |
tree | e09b99d4fd9cceea8eb064f6a2267d5df757e5b8 | |
parent | e5d72b7c92d5af171855c8267c57f5e33ff6cc2e (diff) |
openpgp: Add optional cipher argument to PKESK3::decrypt.
-rw-r--r-- | guide/src/chapter_02.md | 8 | ||||
-rw-r--r-- | ipc/examples/gpg-agent-decrypt.rs | 2 | ||||
-rw-r--r-- | ipc/tests/gpg-agent.rs | 2 | ||||
-rw-r--r-- | openpgp-ffi/src/packet/pkesk.rs | 2 | ||||
-rw-r--r-- | openpgp/examples/decrypt-with.rs | 2 | ||||
-rw-r--r-- | openpgp/examples/generate-encrypt-decrypt.rs | 2 | ||||
-rw-r--r-- | openpgp/src/packet/key/mod.rs | 11 | ||||
-rw-r--r-- | openpgp/src/packet/pkesk.rs | 53 | ||||
-rw-r--r-- | openpgp/src/serialize/stream.rs | 2 | ||||
-rw-r--r-- | tool/src/commands/decrypt.rs | 2 |
10 files changed, 62 insertions, 24 deletions
diff --git a/guide/src/chapter_02.md b/guide/src/chapter_02.md index ffa0b29b..8eda8284 100644 --- a/guide/src/chapter_02.md +++ b/guide/src/chapter_02.md @@ -139,7 +139,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) +# pkesks[0].decrypt(&mut pair, None) # .and_then(|(algo, session_key)| decrypt(algo, &session_key)) # .map(|_| None) # // XXX: In production code, return the Fingerprint of the @@ -287,7 +287,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) +# pkesks[0].decrypt(&mut pair, None) # .and_then(|(algo, session_key)| decrypt(algo, &session_key)) # .map(|_| None) # // XXX: In production code, return the Fingerprint of the @@ -435,7 +435,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) +# pkesks[0].decrypt(&mut pair, None) # .and_then(|(algo, session_key)| decrypt(algo, &session_key)) # .map(|_| None) # // XXX: In production code, return the Fingerprint of the @@ -596,7 +596,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) + pkesks[0].decrypt(&mut pair, None) .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 853a020c..9dc0fbe2 100644 --- a/ipc/examples/gpg-agent-decrypt.rs +++ b/ipc/examples/gpg-agent-decrypt.rs @@ -104,7 +104,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) + if let Ok(_) = pkesk.decrypt(&mut pair, None) .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 61fd8ccc..91794509 100644 --- a/ipc/tests/gpg-agent.rs +++ b/ipc/tests/gpg-agent.rs @@ -289,7 +289,7 @@ fn decrypt() { .take(1).next().unwrap().key()) .unwrap(); - pkesks[0].decrypt(&mut keypair) + pkesks[0].decrypt(&mut keypair, None) .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/src/packet/pkesk.rs b/openpgp-ffi/src/packet/pkesk.rs index 82227065..50845fe8 100644 --- a/openpgp-ffi/src/packet/pkesk.rs +++ b/openpgp-ffi/src/packet/pkesk.rs @@ -48,7 +48,7 @@ pub extern "C" fn pgp_pkesk_decrypt(errp: Option<&mut *mut crate::error::Error>, .into_keypair() { Ok(mut keypair) => { - match pkesk.decrypt(&mut keypair) { + match pkesk.decrypt(&mut keypair, None /* XXX */) { Ok((a, k)) => { *algo = a.into(); if !key.is_null() && *key_len >= k.len() { diff --git a/openpgp/examples/decrypt-with.rs b/openpgp/examples/decrypt-with.rs index fdcb3f7e..a72f0a7d 100644 --- a/openpgp/examples/decrypt-with.rs +++ b/openpgp/examples/decrypt-with.rs @@ -91,7 +91,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) + if let Ok(_) = pkesk.decrypt(pair, None) .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 9f3b8d6a..abf0d04b 100644 --- a/openpgp/examples/generate-encrypt-decrypt.rs +++ b/openpgp/examples/generate-encrypt-decrypt.rs @@ -130,7 +130,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) + pkesks[0].decrypt(&mut pair, None) .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/key/mod.rs b/openpgp/src/packet/key/mod.rs index f01b0257..875cf5b1 100644 --- a/openpgp/src/packet/key/mod.rs +++ b/openpgp/src/packet/key/mod.rs @@ -1658,7 +1658,13 @@ mod tests { let pkesk = PKESK3::for_recipient(cipher, &sk, &key.mark_parts_public()) .unwrap(); - let (cipher_, sk_) = pkesk.decrypt(&mut keypair).unwrap(); + let (cipher_, sk_) = pkesk.decrypt(&mut keypair, None).unwrap(); + + assert_eq!(cipher, cipher_); + assert_eq!(sk, sk_); + + let (cipher_, sk_) = + pkesk.decrypt(&mut keypair, Some(cipher)).unwrap(); assert_eq!(cipher, cipher_); assert_eq!(sk, sk_); @@ -1802,8 +1808,7 @@ mod tests { // Expected let mut decryptor = key.into_keypair().unwrap(); - let got_sk = pkesk.decrypt(&mut decryptor).unwrap(); - + let got_sk = pkesk.decrypt(&mut decryptor, None).unwrap(); assert_eq!(got_sk.1, sk); } diff --git a/openpgp/src/packet/pkesk.rs b/openpgp/src/packet/pkesk.rs index 7e85c61b..8f32d86d 100644 --- a/openpgp/src/packet/pkesk.rs +++ b/openpgp/src/packet/pkesk.rs @@ -130,12 +130,25 @@ impl PKESK3 { ::std::mem::replace(&mut self.esk, esk) } - /// Decrypts the ESK and returns the session key and symmetric algorithm - /// used to encrypt the following payload. - pub fn decrypt(&self, decryptor: &mut dyn Decryptor) + /// Decrypts the encrypted session key. + /// + /// If the symmetric algorithm used to encrypt the message is + /// known in advance, it should be given as argument. This allows + /// us to reduce the side-channel leakage of the decryption + /// operation for RSA. + /// + /// Returns the session key and symmetric algorithm used to + /// encrypt the following payload. + pub fn decrypt(&self, decryptor: &mut dyn Decryptor, + sym_algo_hint: Option<SymmetricAlgorithm>) -> Result<(SymmetricAlgorithm, SessionKey)> { - let plain = decryptor.decrypt(&self.esk, None)?; + let plaintext_len = if let Some(s) = sym_algo_hint { + Some(1 /* cipher octet */ + s.key_size()? + 2 /* chksum */) + } else { + None + }; + let plain = decryptor.decrypt(&self.esk, plaintext_len)?; let key_rgn = 1..(plain.len() - 2); let sym_algo: SymmetricAlgorithm = plain[0].into(); let mut key: SessionKey = vec![0u8; sym_algo.key_size()?].into(); @@ -216,7 +229,11 @@ mod tests { let pkg = pile.descendants().skip(0).next().clone(); if let Some(Packet::PKESK(ref pkesk)) = pkg { - let plain = pkesk.decrypt(&mut keypair).unwrap(); + let plain = pkesk.decrypt(&mut keypair, None).unwrap(); + let plain_ = + pkesk.decrypt(&mut keypair, Some(SymmetricAlgorithm::AES256)) + .unwrap(); + assert_eq!(plain, plain_); eprintln!("plain: {:?}", plain); } else { @@ -237,7 +254,11 @@ mod tests { let pkg = pile.descendants().skip(0).next().clone(); if let Some(Packet::PKESK(ref pkesk)) = pkg { - let plain = pkesk.decrypt(&mut keypair).unwrap(); + let plain = pkesk.decrypt(&mut keypair, None).unwrap(); + let plain_ = + pkesk.decrypt(&mut keypair, Some(SymmetricAlgorithm::AES256)) + .unwrap(); + assert_eq!(plain, plain_); eprintln!("plain: {:?}", plain); } else { @@ -258,7 +279,11 @@ mod tests { let pkg = pile.descendants().skip(0).next().clone(); if let Some(Packet::PKESK(ref pkesk)) = pkg { - let plain = pkesk.decrypt(&mut keypair).unwrap(); + let plain = pkesk.decrypt(&mut keypair, None).unwrap(); + let plain_ = + pkesk.decrypt(&mut keypair, Some(SymmetricAlgorithm::AES256)) + .unwrap(); + assert_eq!(plain, plain_); eprintln!("plain: {:?}", plain); } else { @@ -279,7 +304,11 @@ mod tests { let pkg = pile.descendants().skip(0).next().clone(); if let Some(Packet::PKESK(ref pkesk)) = pkg { - let plain = pkesk.decrypt(&mut keypair).unwrap(); + let plain = pkesk.decrypt(&mut keypair, None).unwrap(); + let plain_ = + pkesk.decrypt(&mut keypair, Some(SymmetricAlgorithm::AES256)) + .unwrap(); + assert_eq!(plain, plain_); eprintln!("plain: {:?}", plain); } else { @@ -300,7 +329,11 @@ mod tests { let pkg = pile.descendants().skip(0).next().clone(); if let Some(Packet::PKESK(ref pkesk)) = pkg { - let plain = pkesk.decrypt(&mut keypair).unwrap(); + let plain = pkesk.decrypt(&mut keypair, None).unwrap(); + let plain_ = + pkesk.decrypt(&mut keypair, Some(SymmetricAlgorithm::AES256)) + .unwrap(); + assert_eq!(plain, plain_); eprintln!("plain: {:?}", plain); } else { @@ -353,6 +386,6 @@ mod tests { &key).unwrap(); let mut keypair = key.mark_parts_secret().unwrap().into_keypair().unwrap(); - pkesk.decrypt(&mut keypair).unwrap(); + pkesk.decrypt(&mut keypair, None).unwrap(); } } diff --git a/openpgp/src/serialize/stream.rs b/openpgp/src/serialize/stream.rs index a3760b84..f8d3ed4b 100644 --- a/openpgp/src/serialize/stream.rs +++ b/openpgp/src/serialize/stream.rs @@ -1707,7 +1707,7 @@ mod test { .map(|ka| ka.key()).next().unwrap() .clone().mark_parts_secret().unwrap() .into_keypair().unwrap(); - pkesks[0].decrypt(&mut keypair) + pkesks[0].decrypt(&mut keypair, None) .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 ba71689e..410c24d2 100644 --- a/tool/src/commands/decrypt.rs +++ b/tool/src/commands/decrypt.rs @@ -92,7 +92,7 @@ impl<'a> Helper<'a> { where D: FnMut(SymmetricAlgorithm, &SessionKey) -> openpgp::Result<()> { let keyid = keypair.public().fingerprint().into(); - match pkesk.decrypt(keypair) + match pkesk.decrypt(keypair, None) .and_then(|(algo, sk)| { decrypt(algo, &sk)?; Ok(sk) }) |