summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2019-05-28 22:21:47 +0200
committerJustus Winter <justus@sequoia-pgp.org>2019-05-30 12:09:47 +0200
commitbe8bf91c14485a844a2c6143893105a21fd6f26e (patch)
treeb2e632196964ebe6e94fb709b77d24d031c0ea2f
parenta0378343f6f0d311021437435c14670a6d7dc3e2 (diff)
openpgp: Make PKESK::decrypt use crypto::Decryptor.
-rw-r--r--guide/src/chapter_02.md28
-rw-r--r--openpgp-ffi/src/packet/pkesk.rs20
-rw-r--r--openpgp/examples/decrypt-with.rs4
-rw-r--r--openpgp/examples/generate-encrypt-decrypt.rs4
-rw-r--r--openpgp/src/packet/key.rs24
-rw-r--r--openpgp/src/packet/pkesk.rs143
-rw-r--r--tool/src/commands/decrypt.rs15
7 files changed, 93 insertions, 145 deletions
diff --git a/guide/src/chapter_02.md b/guide/src/chapter_02.md
index f66e15b3..06d38342 100644
--- a/guide/src/chapter_02.md
+++ b/guide/src/chapter_02.md
@@ -121,11 +121,11 @@ fn main() {
# let key = self.secret.subkeys().nth(0)
# .map(|binding| binding.subkey().clone())
# .unwrap();
-#
+#
# // The secret key is not encrypted.
-# let pair = key.into_keypair().unwrap();
-#
-# pkesks[0].decrypt(pair.public(), pair.secret())
+# let mut pair = key.into_keypair().unwrap();
+#
+# pkesks[0].decrypt(&mut pair)
# .and_then(|(algo, session_key)| decrypt(algo, &session_key))
# .map(|_| None)
# // XXX: In production code, return the Fingerprint of the
@@ -255,11 +255,11 @@ fn generate() -> openpgp::Result<openpgp::TPK> {
# let key = self.secret.subkeys().nth(0)
# .map(|binding| binding.subkey().clone())
# .unwrap();
-#
+#
# // The secret key is not encrypted.
-# let pair = key.into_keypair().unwrap();
-#
-# pkesks[0].decrypt(pair.public(), pair.secret())
+# let mut pair = key.into_keypair().unwrap();
+#
+# pkesks[0].decrypt(&mut pair)
# .and_then(|(algo, session_key)| decrypt(algo, &session_key))
# .map(|_| None)
# // XXX: In production code, return the Fingerprint of the
@@ -389,11 +389,11 @@ fn encrypt(sink: &mut Write, plaintext: &str, recipient: &openpgp::TPK)
# let key = self.secret.subkeys().nth(0)
# .map(|binding| binding.subkey().clone())
# .unwrap();
-#
+#
# // The secret key is not encrypted.
-# let pair = key.into_keypair().unwrap();
-#
-# pkesks[0].decrypt(pair.public(), pair.secret())
+# let mut pair = key.into_keypair().unwrap();
+#
+# pkesks[0].decrypt(&mut pair)
# .and_then(|(algo, session_key)| decrypt(algo, &session_key))
# .map(|_| None)
# // XXX: In production code, return the Fingerprint of the
@@ -539,9 +539,9 @@ impl<'a> DecryptionHelper for Helper<'a> {
.unwrap();
// The secret key is not encrypted.
- let pair = key.into_keypair().unwrap();
+ let mut pair = key.into_keypair().unwrap();
- pkesks[0].decrypt(pair.public(), pair.secret())
+ pkesks[0].decrypt(&mut pair)
.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 af87be5f..e50f0cc9 100644
--- a/openpgp-ffi/src/packet/pkesk.rs
+++ b/openpgp-ffi/src/packet/pkesk.rs
@@ -4,7 +4,7 @@ use failure;
use libc::{uint8_t, size_t};
extern crate sequoia_openpgp as openpgp;
-use self::openpgp::packet::{PKESK, key::SecretKey};
+use self::openpgp::packet::PKESK;
use super::super::keyid::KeyID;
use super::super::packet::key::Key;
@@ -44,9 +44,9 @@ pub extern "C" fn pgp_pkesk_decrypt(errp: Option<&mut *mut ::error::Error>,
let algo = ffi_param_ref_mut!(algo);
let key_len = ffi_param_ref_mut!(key_len);
- match secret_key.secret() {
- Some(SecretKey::Unencrypted{ mpis: secret_parts }) => {
- match pkesk.decrypt(secret_key, secret_parts) {
+ match secret_key.clone().into_keypair() {
+ Ok(mut keypair) => {
+ match pkesk.decrypt(&mut keypair) {
Ok((a, k)) => {
*algo = a.into();
if !key.is_null() && *key_len >= k.len() {
@@ -61,14 +61,10 @@ pub extern "C" fn pgp_pkesk_decrypt(errp: Option<&mut *mut ::error::Error>,
},
Err(e) => ffi_try_status!(Err::<(), failure::Error>(e)),
}
- }
- Some(thing @ SecretKey::Encrypted{ .. }) => {
+ },
+ Err(e) => {
// XXX: Better message, don't panic.
- panic!("Secret parts not unencrypted: {:?}", thing);
- }
- None => {
- // XXX: Better message, don't panic.
- panic!("No secret parts: {:?}", secret_key.secret());
- }
+ panic!("Secret parts not unencrypted in {:?}: {}", secret_key, e);
+ },
}
}
diff --git a/openpgp/examples/decrypt-with.rs b/openpgp/examples/decrypt-with.rs
index 63582299..a13dc98b 100644
--- a/openpgp/examples/decrypt-with.rs
+++ b/openpgp/examples/decrypt-with.rs
@@ -87,8 +87,8 @@ impl DecryptionHelper for Helper {
{
// Try each PKESK until we succeed.
for pkesk in pkesks {
- if let Some(pair) = self.keys.get(pkesk.recipient()) {
- if let Ok(_) = pkesks[0].decrypt(pair.public(), pair.secret())
+ if let Some(pair) = self.keys.get_mut(pkesk.recipient()) {
+ if let Ok(_) = pkesks[0].decrypt(pair)
.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 4645cb0c..8a450d24 100644
--- a/openpgp/examples/generate-encrypt-decrypt.rs
+++ b/openpgp/examples/generate-encrypt-decrypt.rs
@@ -114,9 +114,9 @@ impl<'a> DecryptionHelper for Helper<'a> {
.unwrap();
// The secret key is not encrypted.
- let pair = key.into_keypair().unwrap();
+ let mut pair = key.into_keypair().unwrap();
- pkesks[0].decrypt(pair.public(), pair.secret())
+ pkesks[0].decrypt(&mut pair)
.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.rs b/openpgp/src/packet/key.rs
index 42339644..56416de3 100644
--- a/openpgp/src/packet/key.rs
+++ b/openpgp/src/packet/key.rs
@@ -798,7 +798,6 @@ mod tests {
#[test]
fn encryption_roundtrip() {
- use packet::key::SecretKey;
use crypto::SessionKey;
use constants::Curve::*;
@@ -810,21 +809,13 @@ mod tests {
for key in keys.into_iter() {
let key = Key::from(key);
- let secret =
- if let Some(SecretKey::Unencrypted {
- ref mpis,
- }) = key.secret() {
- mpis.clone()
- } else {
- unreachable!()
- };
-
+ let mut keypair = key.clone().into_keypair().unwrap();
let cipher = SymmetricAlgorithm::AES256;
let sk = SessionKey::new(&mut Default::default(),
cipher.key_size().unwrap());
let pkesk = PKESK3::for_recipient(cipher, &sk, &key).unwrap();
- let (cipher_, sk_) = pkesk.decrypt(&key, &secret).unwrap();
+ let (cipher_, sk_) = pkesk.decrypt(&mut keypair).unwrap();
assert_eq!(cipher, cipher_);
assert_eq!(sk, sk_);
@@ -956,14 +947,11 @@ mod tests {
let dek = b"\xA5\x58\x3A\x04\x35\x8B\xC7\x3F\x4A\xEF\x0C\x5A\xEB\xED\x59\xCA\xFD\x96\xB5\x32\x23\x26\x0C\x91\x78\xD1\x31\x12\xF0\x41\x42\x9D";
let sk = SessionKey::from(Vec::from(&dek[..]));
- // Expected
- let sec = match key.secret() {
- Some(&SecretKey::Unencrypted{ ref mpis }) => mpis,
- _ => unreachable!(),
- };
- let got_sk = pkesk.decrypt(&key, sec).unwrap();
+ // Expected
+ let mut decryptor = key.into_keypair().unwrap();
+ let got_sk = pkesk.decrypt(&mut decryptor).unwrap();
- assert_eq!(got_sk.1, sk);
+ assert_eq!(got_sk.1, sk);
}
#[test]
diff --git a/openpgp/src/packet/pkesk.rs b/openpgp/src/packet/pkesk.rs
index ad56d03a..1f638da6 100644
--- a/openpgp/src/packet/pkesk.rs
+++ b/openpgp/src/packet/pkesk.rs
@@ -10,6 +10,7 @@ use quickcheck::{Arbitrary, Gen};
use Error;
use packet::Key;
use KeyID;
+use crypto::Decryptor;
use crypto::mpis::{self, MPI, Ciphertext};
use Packet;
use PublicKeyAlgorithm;
@@ -144,46 +145,10 @@ impl PKESK3 {
/// Decrypts the ESK and returns the session key and symmetric algorithm
/// used to encrypt the following payload.
- pub fn decrypt(&self, recipient: &Key, recipient_sec: &mpis::SecretKey)
+ pub fn decrypt(&self, decryptor: &mut Decryptor)
-> Result<(SymmetricAlgorithm, SessionKey)>
{
- use PublicKeyAlgorithm::*;
- use crypto::mpis::PublicKey;
- use nettle::rsa;
-
- let plain: SessionKey = match
- (self.pk_algo, recipient.mpis(), recipient_sec, &self.esk)
- {
- (RSAEncryptSign,
- &PublicKey::RSA{ ref e, ref n },
- &mpis::SecretKey::RSA{ ref p, ref q, ref d, .. },
- &mpis::Ciphertext::RSA{ ref c }) => {
- let public = rsa::PublicKey::new(&n.value, &e.value)?;
- let secret = rsa::PrivateKey::new(&d.value, &p.value,
- &q.value, Option::None)?;
- let mut rand = Yarrow::default();
- rsa::decrypt_pkcs1(&public, &secret, &mut rand, &c.value)?
- }
-
- (ElgamalEncrypt,
- &PublicKey::Elgamal{ .. },
- &mpis::SecretKey::Elgamal{ .. },
- &mpis::Ciphertext::Elgamal{ .. }) =>
- return Err(
- Error::UnsupportedPublicKeyAlgorithm(self.pk_algo).into()),
-
- (ECDH,
- PublicKey::ECDH{ .. },
- mpis::SecretKey::ECDH { .. },
- mpis::Ciphertext::ECDH { .. }) =>
- ecdh::unwrap_session_key(recipient, recipient_sec, &self.esk)?,
-
- (algo, public, secret, cipher) =>
- return Err(Error::MalformedPacket(format!(
- "unsupported combination of algorithm {:?}, key pair {:?}/{:?} and ciphertext {:?}",
- algo, public, secret, cipher)).into()),
- }.into();
-
+ let plain = decryptor.decrypt(&self.esk)?;
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();
@@ -258,20 +223,18 @@ mod tests {
::tests::key("testy-private.pgp")).unwrap();
let pile = PacketPile::from_bytes(
::tests::message("encrypted-to-testy.gpg")).unwrap();
- let pair = tpk.subkeys().next().unwrap().subkey();
+ let mut keypair =
+ tpk.subkeys().next().unwrap()
+ .subkey().clone().into_keypair().unwrap();
- if let Some(SecretKey::Unencrypted{ mpis: ref sec }) = pair.secret() {
- let pkg = pile.descendants().skip(0).next().clone();
+ let pkg = pile.descendants().skip(0).next().clone();
- if let Some(Packet::PKESK(ref pkesk)) = pkg {
- let plain = pkesk.decrypt(&pair, sec).unwrap();
+ if let Some(Packet::PKESK(ref pkesk)) = pkg {
+ let plain = pkesk.decrypt(&mut keypair).unwrap();
- eprintln!("plain: {:?}", plain);
- } else {
- panic!("message is not a PKESK packet");
- }
+ eprintln!("plain: {:?}", plain);
} else {
- panic!("secret key is encrypted/missing");
+ panic!("message is not a PKESK packet");
}
}
@@ -281,20 +244,18 @@ mod tests {
::tests::key("testy-new-private.pgp")).unwrap();
let pile = PacketPile::from_bytes(
::tests::message("encrypted-to-testy-new.pgp")).unwrap();
- let pair = tpk.subkeys().next().unwrap().subkey();
+ let mut keypair =
+ tpk.subkeys().next().unwrap()
+ .subkey().clone().into_keypair().unwrap();
- if let Some(SecretKey::Unencrypted{ mpis: ref sec }) = pair.secret() {
- let pkg = pile.descendants().skip(0).next().clone();
+ let pkg = pile.descendants().skip(0).next().clone();
- if let Some(Packet::PKESK(ref pkesk)) = pkg {
- let plain = pkesk.decrypt(&pair, sec).unwrap();
+ if let Some(Packet::PKESK(ref pkesk)) = pkg {
+ let plain = pkesk.decrypt(&mut keypair).unwrap();
- eprintln!("plain: {:?}", plain);
- } else {
- panic!("message is not a PKESK packet");
- }
+ eprintln!("plain: {:?}", plain);
} else {
- panic!("secret key is encrypted/missing");
+ panic!("message is not a PKESK packet");
}
}
@@ -304,20 +265,18 @@ mod tests {
::tests::key("testy-nistp256-private.pgp")).unwrap();
let pile = PacketPile::from_bytes(
::tests::message("encrypted-to-testy-nistp256.pgp")).unwrap();
- let pair = tpk.subkeys().next().unwrap().subkey();
+ let mut keypair =
+ tpk.subkeys().next().unwrap()
+ .subkey().clone().into_keypair().unwrap();
- if let Some(SecretKey::Unencrypted{ mpis: ref sec }) = pair.secret() {
- let pkg = pile.descendants().skip(0).next().clone();
+ let pkg = pile.descendants().skip(0).next().clone();
- if let Some(Packet::PKESK(ref pkesk)) = pkg {
- let plain = pkesk.decrypt(&pair, sec).unwrap();
+ if let Some(Packet::PKESK(ref pkesk)) = pkg {
+ let plain = pkesk.decrypt(&mut keypair).unwrap();
- eprintln!("plain: {:?}", plain);
- } else {
- panic!("message is not a PKESK packet");
- }
+ eprintln!("plain: {:?}", plain);
} else {
- panic!("secret key is encrypted/missing");
+ panic!("message is not a PKESK packet");
}
}
@@ -327,20 +286,18 @@ mod tests {
::tests::key("testy-nistp384-private.pgp")).unwrap();
let pile = PacketPile::from_bytes(
::tests::message("encrypted-to-testy-nistp384.pgp")).unwrap();
- let pair = tpk.subkeys().next().unwrap().subkey();
+ let mut keypair =
+ tpk.subkeys().next().unwrap()
+ .subkey().clone().into_keypair().unwrap();
- if let Some(SecretKey::Unencrypted{ mpis: ref sec }) = pair.secret() {
- let pkg = pile.descendants().skip(0).next().clone();
+ let pkg = pile.descendants().skip(0).next().clone();
- if let Some(Packet::PKESK(ref pkesk)) = pkg {
- let plain = pkesk.decrypt(&pair, sec).unwrap();
+ if let Some(Packet::PKESK(ref pkesk)) = pkg {
+ let plain = pkesk.decrypt(&mut keypair).unwrap();
- eprintln!("plain: {:?}", plain);
- } else {
- panic!("message is not a PKESK packet");
- }
+ eprintln!("plain: {:?}", plain);
} else {
- panic!("secret key is encrypted/missing");
+ panic!("message is not a PKESK packet");
}
}
@@ -350,20 +307,18 @@ mod tests {
::tests::key("testy-nistp521-private.pgp")).unwrap();
let pile = PacketPile::from_bytes(
::tests::message("encrypted-to-testy-nistp521.pgp")).unwrap();
- let pair = tpk.subkeys().next().unwrap().subkey();
+ let mut keypair =
+ tpk.subkeys().next().unwrap()
+ .subkey().clone().into_keypair().unwrap();
- if let Some(SecretKey::Unencrypted{ mpis: ref sec }) = pair.secret() {
- let pkg = pile.descendants().skip(0).next().clone();
+ let pkg = pile.descendants().skip(0).next().clone();
- if let Some(Packet::PKESK(ref pkesk)) = pkg {
- let plain = pkesk.decrypt(&pair, sec).unwrap();
+ if let Some(Packet::PKESK(ref pkesk)) = pkg {
+ let plain = pkesk.decrypt(&mut keypair).unwrap();
- eprintln!("plain: {:?}", plain);
- } else {
- panic!("message is not a PKESK packet");
- }
+ eprintln!("plain: {:?}", plain);
} else {
- panic!("secret key is encrypted/missing");
+ panic!("message is not a PKESK packet");
}
}
@@ -403,14 +358,18 @@ mod tests {
let private_mpis = mpis::SecretKey::ECDH {
scalar: MPI::new(&sec[..]),
};
- let key: Key = Key4::new(time::now().canonicalize(),
- PublicKeyAlgorithm::ECDH, public_mpis, None)
+ let mut key: Key = Key4::new(time::now().canonicalize(),
+ PublicKeyAlgorithm::ECDH,
+ public_mpis, None)
.unwrap().into();
+ key.set_secret(Some(SecretKey::Unencrypted {
+ mpis: private_mpis,
+ }));
let mut rng = Yarrow::default();
let sess_key = SessionKey::new(&mut rng, 32);
let pkesk = PKESK3::for_recipient(SymmetricAlgorithm::AES256, &sess_key,
&key).unwrap();
-
- pkesk.decrypt(&key, &private_mpis).unwrap();
+ let mut keypair = key.into_keypair().unwrap();
+ pkesk.decrypt(&mut keypair).unwrap();
}
}
diff --git a/tool/src/commands/decrypt.rs b/tool/src/commands/decrypt.rs
index c762c454..a8c72f96 100644
--- a/tool/src/commands/decrypt.rs
+++ b/tool/src/commands/decrypt.rs
@@ -122,8 +122,9 @@ impl<'a> DecryptionHelper for Helper<'a> {
for pkesk in pkesks {
let keyid = pkesk.recipient();
if let Some(key) = self.secret_keys.get(&keyid) {
- if let Some(SecretKey::Unencrypted { mpis }) = key.secret() {
- if let Ok(sk) = pkesks[0].decrypt(key, mpis)
+ if let Some(SecretKey::Unencrypted { .. }) = key.secret() {
+ if let Ok(sk) = key.clone().into_keypair()
+ .and_then(|mut keypair| pkesks[0].decrypt(&mut keypair))
.and_then(|(algo, sk)| { decrypt(algo, &sk)?; Ok(sk) })
{
if self.dump_session_key {
@@ -159,10 +160,14 @@ impl<'a> DecryptionHelper for Helper<'a> {
self.key_hints.get(&keyid).unwrap())))
?.into();
- if let Ok(mpis) =
- key.secret().unwrap().decrypt(key.pk_algo(), &p)
+ let mut key = key.clone();
+ let algo = key.pk_algo();
+ if let Some(()) =
+ key.secret_mut()
+ .and_then(|s| s.decrypt_in_place(algo, &p).ok())
{
- match pkesk.decrypt(key, &mpis)
+ let mut keypair = key.into_keypair().unwrap();
+ match pkesk.decrypt(&mut keypair)
.and_then(|(algo, sk)| {
decrypt(algo, &sk)?; Ok(sk)
})