summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2021-03-17 13:47:48 +0100
committerJustus Winter <justus@sequoia-pgp.org>2021-06-07 12:32:15 +0200
commit1a9708fcc43830fb7f617381af0b42f56f4b8924 (patch)
treee4a79b33054140244ff8477a48e66444de0a0530
parentb1ddb1f3c03e3340c461f1d90a64616884f11ceb (diff)
openpgp: Add decryption test vectors.
- These test vectors are generated by GnuPG (and the one with the unclamped cv25519 secret by RNP).
-rw-r--r--openpgp/src/parse/stream.rs120
-rw-r--r--openpgp/tests/data/messages/encrypted/brainpoolP256r1.msg.pgp1
-rw-r--r--openpgp/tests/data/messages/encrypted/brainpoolP256r1.sec.pgpbin0 -> 2413 bytes
-rw-r--r--openpgp/tests/data/messages/encrypted/brainpoolP384r1.msg.pgp2
-rw-r--r--openpgp/tests/data/messages/encrypted/brainpoolP384r1.sec.pgpbin0 -> 2461 bytes
-rw-r--r--openpgp/tests/data/messages/encrypted/brainpoolP512r1.msg.pgpbin0 -> 266 bytes
-rw-r--r--openpgp/tests/data/messages/encrypted/brainpoolP512r1.sec.pgpbin0 -> 2509 bytes
-rw-r--r--openpgp/tests/data/messages/encrypted/cv25519.msg.pgp1
-rw-r--r--openpgp/tests/data/messages/encrypted/cv25519.sec.pgpbin0 -> 2382 bytes
-rw-r--r--openpgp/tests/data/messages/encrypted/cv25519.unclamped.msg.pgp1
-rw-r--r--openpgp/tests/data/messages/encrypted/cv25519.unclamped.sec.pgp17
-rw-r--r--openpgp/tests/data/messages/encrypted/elg.msg.pgpbin0 -> 859 bytes
-rw-r--r--openpgp/tests/data/messages/encrypted/elg.sec.pgpbin0 -> 3127 bytes
-rw-r--r--openpgp/tests/data/messages/encrypted/nistp256.msg.pgp3
-rw-r--r--openpgp/tests/data/messages/encrypted/nistp256.sec.pgpbin0 -> 2412 bytes
-rw-r--r--openpgp/tests/data/messages/encrypted/nistp384.msg.pgpbin0 -> 234 bytes
-rw-r--r--openpgp/tests/data/messages/encrypted/nistp384.sec.pgpbin0 -> 2457 bytes
-rw-r--r--openpgp/tests/data/messages/encrypted/nistp521.msg.pgpbin0 -> 270 bytes
-rw-r--r--openpgp/tests/data/messages/encrypted/nistp521.sec.pgpbin0 -> 2510 bytes
-rw-r--r--openpgp/tests/data/messages/encrypted/rsa.msg.pgpbin0 -> 473 bytes
-rw-r--r--openpgp/tests/data/messages/encrypted/rsa.sec.pgpbin0 -> 3658 bytes
-rw-r--r--openpgp/tests/data/messages/encrypted/secp256k1.msg.pgp2
-rw-r--r--openpgp/tests/data/messages/encrypted/secp256k1.sec.pgpbin0 -> 2409 bytes
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
new file mode 100644
index 00000000..215d5166
--- /dev/null
+++ b/openpgp/tests/data/messages/encrypted/brainpoolP256r1.sec.pgp
Binary files differ
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%-1nv׬8.Ѡ }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
new file mode 100644
index 00000000..58f94eb9
--- /dev/null
+++ b/openpgp/tests/data/messages/encrypted/brainpoolP384r1.sec.pgp
Binary files differ
diff --git a/openpgp/tests/data/messages/encrypted/brainpoolP512r1.msg.pgp b/openpgp/tests/data/messages/encrypted/brainpoolP512r1.msg.pgp
new file mode 100644
index 00000000..1b40e3b2
--- /dev/null
+++ b/openpgp/tests/data/messages/encrypted/brainpoolP512r1.msg.pgp
Binary files differ
diff --git a/openpgp/tests/data/messages/encrypted/brainpoolP512r1.sec.pgp b/openpgp/tests/data/messages/encrypted/brainpoolP512r1.sec.pgp
new file mode 100644
index 00000000..b7714ecd
--- /dev/null
+++ b/openpgp/tests/data/messages/encrypted/brainpoolP512r1.sec.pgp
Binary files differ
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
new file mode 100644
index 00000000..5f4ce836
--- /dev/null
+++ b/openpgp/tests/data/messages/encrypted/cv25519.sec.pgp
Binary files differ
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=_V⿫Oϙ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
new file mode 100644
index 00000000..1b06254a
--- /dev/null
+++ b/openpgp/tests/data/messages/encrypted/elg.msg.pgp
Binary files differ
diff --git a/openpgp/tests/data/messages/encrypted/elg.sec.pgp b/openpgp/tests/data/messages/encrypted/elg.sec.pgp
new file mode 100644
index 00000000..f07020c4
--- /dev/null
+++ b/openpgp/tests/data/messages/encrypted/elg.sec.pgp
Binary files differ
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.پH6 D#4gVR(k@@/h+s|0z_e;˫XInƃ悜Ѕ{9k&Vk H鹁^%~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
new file mode 100644
index 00000000..9a560e15
--- /dev/null
+++ b/openpgp/tests/data/messages/encrypted/nistp256.sec.pgp
Binary files differ
diff --git a/openpgp/tests/data/messages/encrypted/nistp384.msg.pgp b/openpgp/tests/data/messages/encrypted/nistp384.msg.pgp
new file mode 100644
index 00000000..23668ae1
--- /dev/null
+++ b/openpgp/tests/data/messages/encrypted/nistp384.msg.pgp
Binary files differ
diff --git a/openpgp/tests/data/messages/encrypted/nistp384.sec.pgp b/openpgp/tests/data/messages/encrypted/nistp384.sec.pgp
new file mode 100644
index 00000000..ef6f5026
--- /dev/null
+++ b/openpgp/tests/data/messages/encrypted/nistp384.sec.pgp
Binary files differ
diff --git a/openpgp/tests/data/messages/encrypted/nistp521.msg.pgp b/openpgp/tests/data/messages/encrypted/nistp521.msg.pgp
new file mode 100644
index 00000000..7bb3eaaa
--- /dev/null
+++ b/openpgp/tests/data/messages/encrypted/nistp521.msg.pgp
Binary files differ
diff --git a/openpgp/tests/data/messages/encrypted/nistp521.sec.pgp b/openpgp/tests/data/messages/encrypted/nistp521.sec.pgp
new file mode 100644
index 00000000..60a7b9ca
--- /dev/null
+++ b/openpgp/tests/data/messages/encrypted/nistp521.sec.pgp
Binary files differ
diff --git a/openpgp/tests/data/messages/encrypted/rsa.msg.pgp b/openpgp/tests/data/messages/encrypted/rsa.msg.pgp
new file mode 100644
index 00000000..dc55f711
--- /dev/null
+++ b/openpgp/tests/data/messages/encrypted/rsa.msg.pgp
Binary files differ
diff --git a/openpgp/tests/data/messages/encrypted/rsa.sec.pgp b/openpgp/tests/data/messages/encrypted/rsa.sec.pgp
new file mode 100644
index 00000000..1282f05e
--- /dev/null
+++ b/openpgp/tests/data/messages/encrypted/rsa.sec.pgp
Binary files differ
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
new file mode 100644
index 00000000..f8316514
--- /dev/null
+++ b/openpgp/tests/data/messages/encrypted/secp256k1.sec.pgp
Binary files differ