summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--guide/src/chapter_02.md20
-rw-r--r--ipc/examples/gpg-agent-decrypt.rs4
-rw-r--r--ipc/tests/gpg-agent.rs6
-rw-r--r--openpgp-ffi/src/packet/pkesk.rs6
-rw-r--r--openpgp/examples/decrypt-with.rs5
-rw-r--r--openpgp/examples/generate-encrypt-decrypt.rs5
-rw-r--r--openpgp/src/packet/pkesk.rs14
-rw-r--r--openpgp/src/parse/stream.rs8
-rw-r--r--openpgp/src/policy.rs5
-rw-r--r--openpgp/src/serialize/stream.rs5
-rw-r--r--sop/src/main.rs24
-rw-r--r--tool/src/commands/decrypt.rs30
12 files changed, 80 insertions, 52 deletions
diff --git a/guide/src/chapter_02.md b/guide/src/chapter_02.md
index 64ba07cb..91b01513 100644
--- a/guide/src/chapter_02.md
+++ b/guide/src/chapter_02.md
@@ -137,10 +137,11 @@ fn main() {
# let mut pair = key.into_keypair().unwrap();
#
# pkesks[0].decrypt(&mut pair, sym_algo)
-# .and_then(|(algo, session_key)| decrypt(algo, &session_key))
-# .map(|_| None)
+# .and_then(|(algo, session_key)| decrypt(algo, &session_key).ok());
+#
# // XXX: In production code, return the Fingerprint of the
# // recipient's Cert here
+# Ok(None)
# }
# }
```
@@ -282,10 +283,11 @@ fn generate() -> openpgp::Result<openpgp::Cert> {
# let mut pair = key.into_keypair().unwrap();
#
# pkesks[0].decrypt(&mut pair, sym_algo)
-# .and_then(|(algo, session_key)| decrypt(algo, &session_key))
-# .map(|_| None)
+# .and_then(|(algo, session_key)| decrypt(algo, &session_key).ok());
+#
# // XXX: In production code, return the Fingerprint of the
# // recipient's Cert here
+# Ok(None)
# }
# }
```
@@ -427,10 +429,11 @@ fn encrypt(policy: &dyn Policy,
# let mut pair = key.into_keypair().unwrap();
#
# pkesks[0].decrypt(&mut pair, sym_algo)
-# .and_then(|(algo, session_key)| decrypt(algo, &session_key))
-# .map(|_| None)
+# .and_then(|(algo, session_key)| decrypt(algo, &session_key).ok());
+#
# // XXX: In production code, return the Fingerprint of the
# // recipient's Cert here
+# Ok(None)
# }
# }
```
@@ -586,10 +589,11 @@ impl<'a> DecryptionHelper for Helper<'a> {
let mut pair = key.into_keypair().unwrap();
pkesks[0].decrypt(&mut pair, sym_algo)
- .and_then(|(algo, session_key)| decrypt(algo, &session_key))
- .map(|_| None)
+ .and_then(|(algo, session_key)| decrypt(algo, &session_key).ok());
+
// XXX: In production code, return the Fingerprint of the
// recipient's Cert here
+ Ok(None)
}
}
```
diff --git a/ipc/examples/gpg-agent-decrypt.rs b/ipc/examples/gpg-agent-decrypt.rs
index 254aebdd..b580b353 100644
--- a/ipc/examples/gpg-agent-decrypt.rs
+++ b/ipc/examples/gpg-agent-decrypt.rs
@@ -106,8 +106,8 @@ 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, sym_algo)
- .and_then(|(algo, session_key)| decrypt(algo, &session_key))
+ if let Some(_) = pkesk.decrypt(&mut pair, sym_algo)
+ .and_then(|(algo, session_key)| decrypt(algo, &session_key).ok())
{
break;
}
diff --git a/ipc/tests/gpg-agent.rs b/ipc/tests/gpg-agent.rs
index 9b0e2fc9..606dd683 100644
--- a/ipc/tests/gpg-agent.rs
+++ b/ipc/tests/gpg-agent.rs
@@ -287,10 +287,12 @@ fn decrypt() -> openpgp::Result<()> {
.unwrap();
pkesks[0].decrypt(&mut keypair, sym_algo)
- .and_then(|(algo, session_key)| decrypt(algo, &session_key))
- .map(|_| None)
+ .and_then(
+ |(algo, session_key)| decrypt(algo, &session_key).ok());
+
// XXX: In production code, return the Fingerprint of the
// recipient's Cert here
+ Ok(None)
}
}
}
diff --git a/openpgp-ffi/src/packet/pkesk.rs b/openpgp-ffi/src/packet/pkesk.rs
index 084505ff..bbecddb0 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>,
{
Ok(mut keypair) => {
match pkesk.decrypt(&mut keypair, None /* XXX */) {
- Ok((a, k)) => {
+ Some((a, k)) => {
*algo = a.into();
if !key.is_null() && *key_len >= k.len() {
unsafe {
@@ -60,7 +60,9 @@ pub extern "C" fn pgp_pkesk_decrypt(errp: Option<&mut *mut crate::error::Error>,
*key_len = k.len();
Status::Success
},
- Err(e) => ffi_try_status!(Err::<(), anyhow::Error>(e)),
+ None => ffi_try_status!(Err::<(), anyhow::Error>(
+ openpgp::Error::InvalidSessionKey(
+ "Decryption failed".into()).into())),
}
},
Err(e) => {
diff --git a/openpgp/examples/decrypt-with.rs b/openpgp/examples/decrypt-with.rs
index 09f44794..3a5723bc 100644
--- a/openpgp/examples/decrypt-with.rs
+++ b/openpgp/examples/decrypt-with.rs
@@ -89,8 +89,9 @@ 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, sym_algo)
- .and_then(|(algo, session_key)| decrypt(algo, &session_key))
+ if let Some(_) = pkesk.decrypt(pair, sym_algo)
+ .and_then(|(algo, session_key)| decrypt(algo, &session_key)
+ .ok())
{
break;
}
diff --git a/openpgp/examples/generate-encrypt-decrypt.rs b/openpgp/examples/generate-encrypt-decrypt.rs
index 3960b22e..c7e2e38d 100644
--- a/openpgp/examples/generate-encrypt-decrypt.rs
+++ b/openpgp/examples/generate-encrypt-decrypt.rs
@@ -128,9 +128,10 @@ impl<'a> DecryptionHelper for Helper<'a> {
let mut pair = key.into_keypair().unwrap();
pkesks[0].decrypt(&mut pair, sym_algo)
- .and_then(|(algo, session_key)| decrypt(algo, &session_key))
- .map(|_| None)
+ .and_then(|(algo, session_key)| decrypt(algo, &session_key).ok());
+
// XXX: In production code, return the Fingerprint of the
// recipient's Cert here
+ Ok(None)
}
}
diff --git a/openpgp/src/packet/pkesk.rs b/openpgp/src/packet/pkesk.rs
index 0724e50f..f92c596e 100644
--- a/openpgp/src/packet/pkesk.rs
+++ b/openpgp/src/packet/pkesk.rs
@@ -128,8 +128,22 @@ impl PKESK3 {
///
/// Returns the session key and symmetric algorithm used to
/// encrypt the following payload.
+ ///
+ /// Returns `None` on errors. This prevents leaking information
+ /// to an attacker, which could lead to compromise of secret key
+ /// material with certain algorithms (RSA). See [Section 14 of
+ /// RFC 4880].
+ ///
+ /// [Section 14 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-14
pub fn decrypt(&self, decryptor: &mut dyn Decryptor,
sym_algo_hint: Option<SymmetricAlgorithm>)
+ -> Option<(SymmetricAlgorithm, SessionKey)>
+ {
+ self.decrypt_insecure(decryptor, sym_algo_hint).ok()
+ }
+
+ fn decrypt_insecure(&self, decryptor: &mut dyn Decryptor,
+ sym_algo_hint: Option<SymmetricAlgorithm>)
-> Result<(SymmetricAlgorithm, SessionKey)>
{
let plaintext_len = if let Some(s) = sym_algo_hint {
diff --git a/openpgp/src/parse/stream.rs b/openpgp/src/parse/stream.rs
index bf4fc4bc..69513432 100644
--- a/openpgp/src/parse/stream.rs
+++ b/openpgp/src/parse/stream.rs
@@ -1390,8 +1390,8 @@ pub trait DecryptionHelper {
/// if ! key.secret().is_encrypted() {
/// let mut keypair = key.clone().into_keypair()?;
/// if pkesk.decrypt(&mut keypair, sym_algo)
- /// .and_then(|(algo, sk)| decrypt(algo, &sk))
- /// .is_ok()
+ /// .and_then(|(algo, sk)| decrypt(algo, &sk).ok())
+ /// .is_some()
/// {
/// return Ok(Some(fp));
/// }
@@ -1407,8 +1407,8 @@ pub trait DecryptionHelper {
/// if ! key.secret().is_encrypted() {
/// let mut keypair = key.clone().into_keypair()?;
/// if pkesk.decrypt(&mut keypair, sym_algo)
- /// .and_then(|(algo, sk)| decrypt(algo, &sk))
- /// .is_ok()
+ /// .and_then(|(algo, sk)| decrypt(algo, &sk).ok())
+ /// .is_some()
/// {
/// return Ok(Some(fp));
/// }
diff --git a/openpgp/src/policy.rs b/openpgp/src/policy.rs
index 259099d2..fe266b79 100644
--- a/openpgp/src/policy.rs
+++ b/openpgp/src/policy.rs
@@ -1819,8 +1819,9 @@ mod test {
.for_transport_encryption().secret().nth(0).unwrap()
.key().clone().into_keypair()?;
pkesks[0].decrypt(&mut pair, algo)
- .and_then(|(algo, session_key)| decrypt(algo, &session_key))
- .map(|_| None)
+ .and_then(|(algo, session_key)|
+ decrypt(algo, &session_key).ok());
+ Ok(None)
}
}
diff --git a/openpgp/src/serialize/stream.rs b/openpgp/src/serialize/stream.rs
index 357fa871..7228bcd5 100644
--- a/openpgp/src/serialize/stream.rs
+++ b/openpgp/src/serialize/stream.rs
@@ -3065,8 +3065,9 @@ mod test {
.clone().parts_into_secret().unwrap()
.into_keypair().unwrap();
pkesks[0].decrypt(&mut keypair, sym_algo)
- .and_then(|(algo, session_key)| decrypt(algo, &session_key))
- .map(|_| None)
+ .and_then(|(algo, session_key)|
+ decrypt(algo, &session_key).ok());
+ Ok(None)
}
}
diff --git a/sop/src/main.rs b/sop/src/main.rs
index f8abce91..5d707b8c 100644
--- a/sop/src/main.rs
+++ b/sop/src/main.rs
@@ -669,18 +669,18 @@ impl<'a> Helper<'a> {
algo: Option<SymmetricAlgorithm>,
keypair: &mut dyn crypto::Decryptor,
decrypt: &mut D)
- -> openpgp::Result<(SymmetricAlgorithm,
- SessionKey,
- Option<Fingerprint>)>
+ -> Option<(SymmetricAlgorithm,
+ SessionKey,
+ Option<Fingerprint>)>
where D: FnMut(SymmetricAlgorithm, &SessionKey) -> openpgp::Result<()>
{
let keyid = keypair.public().fingerprint().into();
let (algo, sk) = pkesk.decrypt(keypair, algo)
.and_then(|(algo, sk)| {
- decrypt(algo, &sk)?; Ok((algo, sk))
+ decrypt(algo, &sk).ok()?; Some((algo, sk))
})?;
- Ok((algo, sk, self.identities.get(&keyid).map(|fp| fp.clone())))
+ Some((algo, sk, self.identities.get(&keyid).map(|fp| fp.clone())))
}
/// Dumps the session key.
@@ -726,9 +726,10 @@ impl<'a> DecryptionHelper for Helper<'a> {
let keyid = pkesk.recipient();
if let Some(key) = self.secret_keys.get(&keyid) {
if ! key.secret().is_encrypted() {
- if let Ok((algo, sk, fp)) = key.clone().into_keypair()
- .and_then(|mut k|
- self.try_decrypt(pkesk, algo, &mut k, &mut decrypt))
+ if let Some((algo, sk, fp)) =
+ key.clone().into_keypair().ok().and_then(|mut k| {
+ self.try_decrypt(pkesk, algo, &mut k, &mut decrypt)
+ })
{
self.dump_session_key(algo, &sk)?;
return Ok(fp);
@@ -743,9 +744,10 @@ impl<'a> DecryptionHelper for Helper<'a> {
for pkesk in pkesks.iter().filter(|p| p.recipient().is_wildcard()) {
for key in self.secret_keys.values() {
if ! key.secret().is_encrypted() {
- if let Ok((algo, sk, fp)) = key.clone().into_keypair()
- .and_then(|mut k|
- self.try_decrypt(pkesk, algo, &mut k, &mut decrypt))
+ if let Some((algo, sk, fp)) =
+ key.clone().into_keypair().ok().and_then(|mut k| {
+ self.try_decrypt(pkesk, algo, &mut k, &mut decrypt)
+ })
{
self.dump_session_key(algo, &sk)?;
return Ok(fp);
diff --git a/tool/src/commands/decrypt.rs b/tool/src/commands/decrypt.rs
index 9e951af4..ea48eb0b 100644
--- a/tool/src/commands/decrypt.rs
+++ b/tool/src/commands/decrypt.rs
@@ -89,26 +89,22 @@ impl<'a> Helper<'a> {
sym_algo: Option<SymmetricAlgorithm>,
keypair: &mut dyn crypto::Decryptor,
decrypt: &mut D)
- -> openpgp::Result<Option<Fingerprint>>
+ -> Option<Option<Fingerprint>>
where D: FnMut(SymmetricAlgorithm, &SessionKey) -> openpgp::Result<()>
{
let keyid = keypair.public().fingerprint().into();
match pkesk.decrypt(keypair, sym_algo)
.and_then(|(algo, sk)| {
- decrypt(algo, &sk)?; Ok(sk)
+ decrypt(algo, &sk).ok()?; Some(sk)
})
{
- Ok(sk) => {
+ Some(sk) => {
if self.dump_session_key {
eprintln!("Session key: {}", hex::encode(&sk));
}
- Ok(self.key_identities.get(&keyid).map(|fp| fp.clone()))
- },
- Err(e) => {
- eprintln!("Decryption using {} failed:\n {}",
- self.key_hints.get(&keyid).unwrap(), e);
- Err(e)
+ Some(self.key_identities.get(&keyid).map(|fp| fp.clone()))
},
+ None => None,
}
}
}
@@ -144,7 +140,7 @@ impl<'a> DecryptionHelper for Helper<'a> {
let keyid = pkesk.recipient();
if let Some(key) = self.secret_keys.get(&keyid) {
if ! key.secret().is_encrypted() {
- if let Ok(fp) = key.clone().into_keypair()
+ if let Some(fp) = key.clone().into_keypair().ok()
.and_then(|mut k|
self.try_decrypt(pkesk, sym_algo, &mut k, &mut decrypt))
{
@@ -183,8 +179,10 @@ impl<'a> DecryptionHelper for Helper<'a> {
}
};
- if let Ok(fp) = self.try_decrypt(pkesk, sym_algo, &mut keypair,
- &mut decrypt) {
+ if let Some(fp) =
+ self.try_decrypt(pkesk, sym_algo, &mut keypair,
+ &mut decrypt)
+ {
return Ok(fp);
}
}
@@ -196,7 +194,7 @@ impl<'a> DecryptionHelper for Helper<'a> {
for pkesk in pkesks.iter().filter(|p| p.recipient().is_wildcard()) {
for key in self.secret_keys.values() {
if ! key.secret().is_encrypted() {
- if let Ok(fp) = key.clone().into_keypair()
+ if let Some(fp) = key.clone().into_keypair().ok()
.and_then(|mut k|
self.try_decrypt(pkesk, sym_algo, &mut k, &mut decrypt))
{
@@ -240,8 +238,10 @@ impl<'a> DecryptionHelper for Helper<'a> {
}
};
- if let Ok(fp) = self.try_decrypt(pkesk, sym_algo, &mut keypair,
- &mut decrypt) {
+ if let Some(fp) =
+ self.try_decrypt(pkesk, sym_algo, &mut keypair,
+ &mut decrypt)
+ {
return Ok(fp);
}
}