diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2021-03-17 13:47:48 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2021-06-07 12:32:15 +0200 |
commit | 1a9708fcc43830fb7f617381af0b42f56f4b8924 (patch) | |
tree | e4a79b33054140244ff8477a48e66444de0a0530 | |
parent | b1ddb1f3c03e3340c461f1d90a64616884f11ceb (diff) |
openpgp: Add decryption test vectors.
- These test vectors are generated by GnuPG (and the one with the
unclamped cv25519 secret by RNP).
23 files changed, 142 insertions, 5 deletions
diff --git a/openpgp/src/parse/stream.rs b/openpgp/src/parse/stream.rs index 26ca706e..4058cc9f 100644 --- a/openpgp/src/parse/stream.rs +++ b/openpgp/src/parse/stream.rs @@ -2927,6 +2927,9 @@ mod test { use crate::parse::Parse; use crate::policy::StandardPolicy as P; use crate::serialize::Serialize; + use crate::{ + crypto::Password, + }; #[derive(PartialEq)] struct VHelper { @@ -2935,6 +2938,9 @@ mod test { bad: usize, error: usize, certs: Vec<Cert>, + keys: Vec<Cert>, + passwords: Vec<Password>, + for_decryption: bool, error_out: bool, } @@ -2958,6 +2964,9 @@ mod test { bad: 0, error: 0, certs: Vec::default(), + keys: Vec::default(), + passwords: Default::default(), + for_decryption: false, error_out: true, } } @@ -2973,6 +2982,27 @@ mod test { bad, error, certs, + keys: Default::default(), + passwords: Default::default(), + for_decryption: false, + error_out: true, + } + } + + fn for_decryption(good: usize, unknown: usize, bad: usize, error: usize, + certs: Vec<Cert>, + keys: Vec<Cert>, + passwords: Vec<Password>) + -> Self { + VHelper { + good, + unknown, + bad, + error, + certs, + keys, + passwords, + for_decryption: true, error_out: true, } } @@ -3002,11 +3032,13 @@ mod test { } } MessageLayer::Compression { .. } => (), - _ => unreachable!(), + MessageLayer::Encryption { .. } => (), } } - if ! self.error_out || (self.good > 0 && self.bad == 0) { + if ! self.error_out || (self.good > 0 && self.bad == 0) + || (self.for_decryption && self.certs.is_empty()) + { Ok(()) } else { Err(anyhow::anyhow!("Verification failed: {:?}", self)) @@ -3015,12 +3047,34 @@ mod test { } impl DecryptionHelper for VHelper { - fn decrypt<D>(&mut self, _: &[PKESK], _: &[SKESK], - _: Option<SymmetricAlgorithm>, _: D) + fn decrypt<D>(&mut self, pkesks: &[PKESK], _skesks: &[SKESK], + sym_algo: Option<SymmetricAlgorithm>, mut decrypt: D) -> Result<Option<Fingerprint>> where D: FnMut(SymmetricAlgorithm, &SessionKey) -> bool { - unreachable!(); + let p = P::new(); + if ! self.for_decryption { + unreachable!("Shouldn't be called for verifications"); + } + + for pkesk in pkesks { + for key in &self.keys { + for subkey in key.with_policy(&p, None)?.keys().secret() + .key_handle(pkesk.recipient()) + { + if let Some((algo, sk)) = + subkey.key().clone().into_keypair().ok() + .and_then(|mut k| pkesk.decrypt(&mut k, sym_algo)) + { + if decrypt(algo, &sk) { + return Ok(None); + } + } + } + } + } + + Err(Error::MissingSessionKey("Decryption failed".into()).into()) } } @@ -3163,6 +3217,62 @@ mod test { Ok(()) } + #[test] + fn decryptor() -> Result<()> { + let p = P::new(); + for alg in &[ + "rsa", "elg", "cv25519", "cv25519.unclamped", + "nistp256", "nistp384", "nistp521", + "brainpoolP256r1", "brainpoolP384r1", "brainpoolP512r1", + "secp256k1", + ] { + let key = Cert::from_bytes(crate::tests::message( + &format!("encrypted/{}.sec.pgp", alg)))?; + if let Some(k) = + key.with_policy(&p, None)?.keys().subkeys().supported().next() + { + use crate::crypto::mpi::PublicKey; + match k.mpis() { + PublicKey::ECDH { curve, .. } if ! curve.is_supported() => { + eprintln!("Skipping {} because we don't support \ + the curve {}", alg, curve); + continue; + }, + _ => (), + } + } else { + eprintln!("Skipping {} because we don't support algorithm", + alg); + continue; + } + + let h = VHelper::for_decryption(0, 0, 0, 0, Vec::new(), + vec![key], Vec::new()); + let mut d = DecryptorBuilder::from_bytes( + crate::tests::message(&format!("encrypted/{}.msg.pgp", alg)))? + .with_policy(&p, None, h)?; + assert!(d.message_processed()); + + if d.helper_ref().error > 0 { + // Expected error. No point in trying to read + // something. + continue; + } + + let mut content = Vec::new(); + d.read_to_end(&mut content).unwrap(); + if content[0] == b'H' { + assert_eq!(&b"Hello World!\n"[..], &content[..]); + } else { + assert_eq!("дружба", &String::from_utf8_lossy(&content)); + } + eprintln!("decrypted {:?} using {}", + String::from_utf8(content).unwrap(), alg); + } + + Ok(()) + } + /// Tests legacy two-pass signature scheme, corner cases. /// /// XXX: This test needs to be adapted once diff --git a/openpgp/tests/data/messages/encrypted/brainpoolP256r1.msg.pgp b/openpgp/tests/data/messages/encrypted/brainpoolP256r1.msg.pgp new file mode 100644 index 00000000..6acbcbac --- /dev/null +++ b/openpgp/tests/data/messages/encrypted/brainpoolP256r1.msg.pgp @@ -0,0 +1 @@ +~VH 2\d~^\;4yD:":rOS0P/jNvUQ0(YZ*'Go{cձI01,~|
pB
lЋ*HPnbK#OQ6Tk}UfS2!<ɬ*!@% eIg=V聩,
\ No newline at end of file diff --git a/openpgp/tests/data/messages/encrypted/brainpoolP256r1.sec.pgp b/openpgp/tests/data/messages/encrypted/brainpoolP256r1.sec.pgp Binary files differnew file mode 100644 index 00000000..215d5166 --- /dev/null +++ b/openpgp/tests/data/messages/encrypted/brainpoolP256r1.sec.pgp diff --git a/openpgp/tests/data/messages/encrypted/brainpoolP384r1.msg.pgp b/openpgp/tests/data/messages/encrypted/brainpoolP384r1.msg.pgp new file mode 100644 index 00000000..45377539 --- /dev/null +++ b/openpgp/tests/data/messages/encrypted/brainpoolP384r1.msg.pgp @@ -0,0 +1,2 @@ +~=e\8i%-1nv8.Ѡ}8T%*Kza<Ե=*;kXn;q w@ 霝H0&_q=!b5MLXW$*XAVYb@uc[HÏ<5hӚj˷2A]+7 '^#jS98tDI1 +ۑH
\ No newline at end of file diff --git a/openpgp/tests/data/messages/encrypted/brainpoolP384r1.sec.pgp b/openpgp/tests/data/messages/encrypted/brainpoolP384r1.sec.pgp Binary files differnew file mode 100644 index 00000000..58f94eb9 --- /dev/null +++ b/openpgp/tests/data/messages/encrypted/brainpoolP384r1.sec.pgp diff --git a/openpgp/tests/data/messages/encrypted/brainpoolP512r1.msg.pgp b/openpgp/tests/data/messages/encrypted/brainpoolP512r1.msg.pgp Binary files differnew file mode 100644 index 00000000..1b40e3b2 --- /dev/null +++ b/openpgp/tests/data/messages/encrypted/brainpoolP512r1.msg.pgp diff --git a/openpgp/tests/data/messages/encrypted/brainpoolP512r1.sec.pgp b/openpgp/tests/data/messages/encrypted/brainpoolP512r1.sec.pgp Binary files differnew file mode 100644 index 00000000..b7714ecd --- /dev/null +++ b/openpgp/tests/data/messages/encrypted/brainpoolP512r1.sec.pgp diff --git a/openpgp/tests/data/messages/encrypted/cv25519.msg.pgp b/openpgp/tests/data/messages/encrypted/cv25519.msg.pgp new file mode 100644 index 00000000..0b1f4ba3 --- /dev/null +++ b/openpgp/tests/data/messages/encrypted/cv25519.msg.pgp @@ -0,0 +1 @@ +^̛@|WlA!Pdp!WU&Us3n1$8|0](ƩXgRxUO-SWTIGgfH79$p94]5aK+>]^^9_{3FA8! "BRS~"Q
\ No newline at end of file diff --git a/openpgp/tests/data/messages/encrypted/cv25519.sec.pgp b/openpgp/tests/data/messages/encrypted/cv25519.sec.pgp Binary files differnew file mode 100644 index 00000000..5f4ce836 --- /dev/null +++ b/openpgp/tests/data/messages/encrypted/cv25519.sec.pgp diff --git a/openpgp/tests/data/messages/encrypted/cv25519.unclamped.msg.pgp b/openpgp/tests/data/messages/encrypted/cv25519.unclamped.msg.pgp new file mode 100644 index 00000000..629be44f --- /dev/null +++ b/openpgp/tests/data/messages/encrypted/cv25519.unclamped.msg.pgp @@ -0,0 +1 @@ +^.@/6@"k_S%ϸ3BϾ0h\]0_7Tu\w;̙/#0'֞7~.'IRGA=_VOϙC,X/`Ϥ`
@B2Va:e
|
\ No newline at end of file diff --git a/openpgp/tests/data/messages/encrypted/cv25519.unclamped.sec.pgp b/openpgp/tests/data/messages/encrypted/cv25519.unclamped.sec.pgp new file mode 100644 index 00000000..e2e1d1f4 --- /dev/null +++ b/openpgp/tests/data/messages/encrypted/cv25519.unclamped.sec.pgp @@ -0,0 +1,17 @@ +-----BEGIN PGP PRIVATE KEY BLOCK----- +Comment: 6EB1 AAF4 9909 C4D6 9DB9 A076 FABF 532A 9796 DB44 +Comment: Sophia <sophia-marie@probier.email> + +xVgEYHlWqBYJKwYBBAHaRw8BAQdAT0rTifl9zp6j44CoZdKhXsnF/3E0yv2uzUh7 +LNGQlfgAAP4q0sXWe0kwbbtzR+K39las7uzHiPZKGObOH9bprBKu9BRvzSNTb3Bo +aWEgPHNvcGhpYS1tYXJpZUBwcm9iaWVyLmVtYWlsPsKRBBMWCAA5FiEEbrGq9JkJ +xNaduaB2+r9TKpeW20QFAmB5VqgFCQWjmoACGwMFCwkIBwIGFQgJCgsCBRYCAwEA +AAoJEPq/UyqXlttELOUBANJY+rkNIxdewZV4Zb3cjAeW8TP3JScxchc3qhIT9A06 +AP9HUlo2+3Bg3Mcwe/VBBMwYvxiZydOIagSTwJAuuxuWDsddBGB5VqgSCisGAQQB +l1UBBQEBB0BWG69GdC/O1fBnhecujTQ/Mvvgaj102ocw41SwKiIvYQMBCAcAAQCy +n9/2FKzeog32ZQqTB8535jNrXa3upYMH4neGtdDCXBHlwn4EGBYIACYWIQRusar0 +mQnE1p25oHb6v1Mql5bbRAUCYHlWqAUJBaOagAIbDAAKCRD6v1Mql5bbRAJcAP4r +TlRX4mxr53ex8O65oB0v4jbGzLIQy/Q8jjkKL0F3EwD9GJpopr3nN1S02L78jZsS +q7Tc7UerH2gugiEh5AA3vwM= +=+v1P +-----END PGP PRIVATE KEY BLOCK----- diff --git a/openpgp/tests/data/messages/encrypted/elg.msg.pgp b/openpgp/tests/data/messages/encrypted/elg.msg.pgp Binary files differnew file mode 100644 index 00000000..1b06254a --- /dev/null +++ b/openpgp/tests/data/messages/encrypted/elg.msg.pgp diff --git a/openpgp/tests/data/messages/encrypted/elg.sec.pgp b/openpgp/tests/data/messages/encrypted/elg.sec.pgp Binary files differnew file mode 100644 index 00000000..f07020c4 --- /dev/null +++ b/openpgp/tests/data/messages/encrypted/elg.sec.pgp diff --git a/openpgp/tests/data/messages/encrypted/nistp256.msg.pgp b/openpgp/tests/data/messages/encrypted/nistp256.msg.pgp new file mode 100644 index 00000000..1822d59e --- /dev/null +++ b/openpgp/tests/data/messages/encrypted/nistp256.msg.pgp @@ -0,0 +1,3 @@ +~|û +ng^MQ.پH6D#4gVR(k@@/h+s|0z_e;˫XInƃ悜Ѕ{9k&VkH鹁^%~x +K,(LJסvXwWqVrVb\s8í`ԊP
\ No newline at end of file diff --git a/openpgp/tests/data/messages/encrypted/nistp256.sec.pgp b/openpgp/tests/data/messages/encrypted/nistp256.sec.pgp Binary files differnew file mode 100644 index 00000000..9a560e15 --- /dev/null +++ b/openpgp/tests/data/messages/encrypted/nistp256.sec.pgp diff --git a/openpgp/tests/data/messages/encrypted/nistp384.msg.pgp b/openpgp/tests/data/messages/encrypted/nistp384.msg.pgp Binary files differnew file mode 100644 index 00000000..23668ae1 --- /dev/null +++ b/openpgp/tests/data/messages/encrypted/nistp384.msg.pgp diff --git a/openpgp/tests/data/messages/encrypted/nistp384.sec.pgp b/openpgp/tests/data/messages/encrypted/nistp384.sec.pgp Binary files differnew file mode 100644 index 00000000..ef6f5026 --- /dev/null +++ b/openpgp/tests/data/messages/encrypted/nistp384.sec.pgp diff --git a/openpgp/tests/data/messages/encrypted/nistp521.msg.pgp b/openpgp/tests/data/messages/encrypted/nistp521.msg.pgp Binary files differnew file mode 100644 index 00000000..7bb3eaaa --- /dev/null +++ b/openpgp/tests/data/messages/encrypted/nistp521.msg.pgp diff --git a/openpgp/tests/data/messages/encrypted/nistp521.sec.pgp b/openpgp/tests/data/messages/encrypted/nistp521.sec.pgp Binary files differnew file mode 100644 index 00000000..60a7b9ca --- /dev/null +++ b/openpgp/tests/data/messages/encrypted/nistp521.sec.pgp diff --git a/openpgp/tests/data/messages/encrypted/rsa.msg.pgp b/openpgp/tests/data/messages/encrypted/rsa.msg.pgp Binary files differnew file mode 100644 index 00000000..dc55f711 --- /dev/null +++ b/openpgp/tests/data/messages/encrypted/rsa.msg.pgp diff --git a/openpgp/tests/data/messages/encrypted/rsa.sec.pgp b/openpgp/tests/data/messages/encrypted/rsa.sec.pgp Binary files differnew file mode 100644 index 00000000..1282f05e --- /dev/null +++ b/openpgp/tests/data/messages/encrypted/rsa.sec.pgp diff --git a/openpgp/tests/data/messages/encrypted/secp256k1.msg.pgp b/openpgp/tests/data/messages/encrypted/secp256k1.msg.pgp new file mode 100644 index 00000000..5e6ea557 --- /dev/null +++ b/openpgp/tests/data/messages/encrypted/secp256k1.msg.pgp @@ -0,0 +1,2 @@ +~Eb|٣\-78}ëR,$f&EJEKm`Ta0a,]dThW0<2bx72ۑ1+[{=y"~5J]ȴHKAr8y +p!`xB'0XRO.UU.J0ro+4$4Ҁ%
\ No newline at end of file diff --git a/openpgp/tests/data/messages/encrypted/secp256k1.sec.pgp b/openpgp/tests/data/messages/encrypted/secp256k1.sec.pgp Binary files differnew file mode 100644 index 00000000..f8316514 --- /dev/null +++ b/openpgp/tests/data/messages/encrypted/secp256k1.sec.pgp |