summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2020-02-12 12:32:36 +0100
committerJustus Winter <justus@sequoia-pgp.org>2020-02-12 15:12:21 +0100
commitb0648d984bc618686a18d5e0a5173c16b2328549 (patch)
treee09b99d4fd9cceea8eb064f6a2267d5df757e5b8
parente5d72b7c92d5af171855c8267c57f5e33ff6cc2e (diff)
openpgp: Add optional cipher argument to PKESK3::decrypt.
-rw-r--r--guide/src/chapter_02.md8
-rw-r--r--ipc/examples/gpg-agent-decrypt.rs2
-rw-r--r--ipc/tests/gpg-agent.rs2
-rw-r--r--openpgp-ffi/src/packet/pkesk.rs2
-rw-r--r--openpgp/examples/decrypt-with.rs2
-rw-r--r--openpgp/examples/generate-encrypt-decrypt.rs2
-rw-r--r--openpgp/src/packet/key/mod.rs11
-rw-r--r--openpgp/src/packet/pkesk.rs53
-rw-r--r--openpgp/src/serialize/stream.rs2
-rw-r--r--tool/src/commands/decrypt.rs2
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)
})