summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2022-02-22 13:40:55 +0100
committerJustus Winter <justus@sequoia-pgp.org>2022-02-22 13:40:55 +0100
commit3bae25b173da467c0ab3b6bb8ec6538fce20c6f0 (patch)
treefcddd5d5af32dd0a2e154e0bcf6df64201a768d9
parent676ccb079d0e9af6e81e77d9dc0b0f912ada5b3c (diff)
openpgp: Fix decrypting SKESK4 packets, simple S2K, no ESK.
- Previously, Sequoia refused to decrypt ESK-less SKESK4 using S2K::Simple. This behavior was introduced very early on in 2a66a5aa. In the commit message, Kai wrote: Also fixed a bug where ESK-less SKESK with simple S2K were accepted despite the RFC forbidding it. Which is an odd conclusion because the last paragraph of Section 5.3 is right next to the paragraph talking about having an ESK. - In any case, I think this advice actually applies to both variants. In both cases, CFB is used with an all zero IV, and then a high-entropy session key (if ESK is present) or a high-entropy first block (if we're using the SK to encrypt with a SEIPD packet). If session-key reuse is a problem despite the plaintext starting with a high-entropy string, then it is a problem in either case. - I see that as an advice for producers, I don't see any harm in consuming and decrypting such an artifact. - Fixes #796.
-rw-r--r--openpgp/src/packet/skesk.rs67
-rw-r--r--openpgp/tests/data/messages/s2k/iterated.max.esk.pgp11
-rw-r--r--openpgp/tests/data/messages/s2k/iterated.max.pgp10
-rw-r--r--openpgp/tests/data/messages/s2k/iterated.min.esk.pgp11
-rw-r--r--openpgp/tests/data/messages/s2k/iterated.min.pgp10
-rw-r--r--openpgp/tests/data/messages/s2k/salted.esk.pgp11
-rw-r--r--openpgp/tests/data/messages/s2k/salted.pgp10
-rw-r--r--openpgp/tests/data/messages/s2k/simple.esk.pgp11
-rw-r--r--openpgp/tests/data/messages/s2k/simple.pgp10
9 files changed, 142 insertions, 9 deletions
diff --git a/openpgp/src/packet/skesk.rs b/openpgp/src/packet/skesk.rs
index 1c2cfd05..0f4d7468 100644
--- a/openpgp/src/packet/skesk.rs
+++ b/openpgp/src/packet/skesk.rs
@@ -272,15 +272,7 @@ impl SKESK4 {
Ok((sym, plain[1..].into()))
} else {
// No ESK, we return the derived key.
-
- #[allow(deprecated)]
- match self.s2k {
- S2K::Simple{ .. } =>
- Err(Error::InvalidOperation(
- "SKESK4: Cannot use Simple S2K without ESK".into())
- .into()),
- _ => Ok((self.sym_algo, key)),
- }
+ Ok((self.sym_algo, key))
}
}
}
@@ -658,4 +650,61 @@ mod test {
packets[0].serialize(&mut serialized).unwrap();
assert_eq!(&raw[..], &serialized[..]);
}
+
+ /// Tests various S2K methods, with and without encrypted session
+ /// key.
+ #[test]
+ fn skesk4_s2k_variants() -> Result<()> {
+ use std::io::Read;
+ use crate::{
+ Cert,
+ Fingerprint,
+ packet::{SKESK, PKESK},
+ parse::stream::*,
+ };
+
+ struct H();
+ impl VerificationHelper for H {
+ fn get_certs(&mut self, _ids: &[crate::KeyHandle])
+ -> Result<Vec<Cert>> {
+ Ok(Vec::new())
+ }
+
+ fn check(&mut self, _m: MessageStructure)
+ -> Result<()> {
+ Ok(())
+ }
+ }
+
+ impl DecryptionHelper for H {
+ fn decrypt<D>(&mut self, _: &[PKESK], skesks: &[SKESK],
+ _: Option<SymmetricAlgorithm>,
+ mut decrypt: D) -> Result<Option<Fingerprint>>
+ where D: FnMut(SymmetricAlgorithm, &SessionKey) -> bool
+ {
+ assert_eq!(skesks.len(), 1);
+ let (cipher, sk) = skesks[0].decrypt(&"password".into())?;
+ assert_eq!(cipher, SymmetricAlgorithm::AES256);
+ let r = decrypt(cipher, &sk);
+ assert!(r);
+ Ok(None)
+ }
+ }
+
+ let p = &crate::policy::StandardPolicy::new();
+ for variant in &["simple", "salted", "iterated.min", "iterated.max"] {
+ for esk in &["", ".esk"] {
+ let name = format!("s2k/{}{}.pgp", variant, esk);
+ eprintln!("{}", name);
+ let mut verifier = DecryptorBuilder::from_bytes(
+ crate::tests::message(&name))?
+ .with_policy(p, None, H())?;
+ let mut b = Vec::new();
+ verifier.read_to_end(&mut b)?;
+ assert_eq!(&b, b"Hello World :)");
+ }
+ }
+
+ Ok(())
+ }
}
diff --git a/openpgp/tests/data/messages/s2k/iterated.max.esk.pgp b/openpgp/tests/data/messages/s2k/iterated.max.esk.pgp
new file mode 100644
index 00000000..119d84a3
--- /dev/null
+++ b/openpgp/tests/data/messages/s2k/iterated.max.esk.pgp
@@ -0,0 +1,11 @@
+-----BEGIN PGP MESSAGE-----
+Comment: Plaintext is "Hello World :)"
+Comment: Encrypted using AES with 256-bit key
+Comment: With password "password"
+Comment: Session key: AFCD3A8910A8ADBE5A48F033044689566E4D4BFD461844C241C4DF6388C37010
+
+wy4ECQMIc2FsemlnZXL/PWYsKTYZu1dmAvo2NZHz1KSZ4EqNgtyCyBSaQixxQjao
+0j8BrYkuY8PDV8hToxH1h+aH/NOS5x//CeiEz2tRibRJqWiqiKKqUmxphuwJQOxw
+iOiziEvRvA7AcERGzT0O+lo=
+=6uC5
+-----END PGP MESSAGE-----
diff --git a/openpgp/tests/data/messages/s2k/iterated.max.pgp b/openpgp/tests/data/messages/s2k/iterated.max.pgp
new file mode 100644
index 00000000..1eca7c4a
--- /dev/null
+++ b/openpgp/tests/data/messages/s2k/iterated.max.pgp
@@ -0,0 +1,10 @@
+-----BEGIN PGP MESSAGE-----
+Comment: Plaintext is "Hello World :)"
+Comment: Encrypted using AES with 256-bit key
+Comment: With password "password"
+Comment: Session key: 57879CA6CEB2F7D76172125FDAC91EC77B7704B4023F4CE2CBF5B7BA65242CC0
+
+ww0ECQMIc2FsemlnZXL/0j8BxN2QzkE7NU/J1KSGEMF5rEy5ZOH8nUaFXmeLbpra
+V5e4Mi/tBNgfXbOzoiZIsi0V03FaVJdNWOAdOvJ5FEI=
+=xQCy
+-----END PGP MESSAGE-----
diff --git a/openpgp/tests/data/messages/s2k/iterated.min.esk.pgp b/openpgp/tests/data/messages/s2k/iterated.min.esk.pgp
new file mode 100644
index 00000000..9408a7a4
--- /dev/null
+++ b/openpgp/tests/data/messages/s2k/iterated.min.esk.pgp
@@ -0,0 +1,11 @@
+-----BEGIN PGP MESSAGE-----
+Comment: Plaintext is "Hello World :)"
+Comment: Encrypted using AES with 256-bit key
+Comment: With password "password"
+Comment: Session key: 7A90B25006892A1BE99CB23DD66ABA3179527A0C57727CC739A2720DF141037C
+
+wy4ECQMIc2FsemlnZXIACAONbKs8V5vyuqFuaWn9F4yw3r4upcloGvG6Cc5jgh5P
+0j8BUmF4AMMTSmQhJXESmP2cK5XlHXtRRTG9zeFciL8GcTJ/RnJLyCE4mLR3ekav
+5DsJyvOo6WP9B6X08yBif+g=
+=nAcr
+-----END PGP MESSAGE-----
diff --git a/openpgp/tests/data/messages/s2k/iterated.min.pgp b/openpgp/tests/data/messages/s2k/iterated.min.pgp
new file mode 100644
index 00000000..a8bafdf3
--- /dev/null
+++ b/openpgp/tests/data/messages/s2k/iterated.min.pgp
@@ -0,0 +1,10 @@
+-----BEGIN PGP MESSAGE-----
+Comment: Plaintext is "Hello World :)"
+Comment: Encrypted using AES with 256-bit key
+Comment: With password "password"
+Comment: Session key: CD6E0EAC04B24CCC7B4239904D7FA11D04C6280FA60BFF35C16E618558712B18
+
+ww0ECQMIc2FsemlnZXIA0j8B+7eKr5xSCAIS7nJLIi50TLyJLEhy9PGQGp+spl95
+DjEIv1oiOjgfSi/rgbbDls49Nb5J3abyuiqBmhl0uR8=
+=UNqy
+-----END PGP MESSAGE-----
diff --git a/openpgp/tests/data/messages/s2k/salted.esk.pgp b/openpgp/tests/data/messages/s2k/salted.esk.pgp
new file mode 100644
index 00000000..93db15fb
--- /dev/null
+++ b/openpgp/tests/data/messages/s2k/salted.esk.pgp
@@ -0,0 +1,11 @@
+-----BEGIN PGP MESSAGE-----
+Comment: Plaintext is "Hello World :)"
+Comment: Encrypted using AES with 256-bit key
+Comment: With password "password"
+Comment: Session key: 04E9B7F2FF576BCF58C15699A807D2BAA2FF80F32BF1418F11FE372B03091617
+
+wy0ECQEIc2FsemlnZXKpbLXDWn+1j/z/FSsnJ0fd0p7DUlh3SPYD622+DmtCDdLS
+PwEQOFIMH1EyBP1bC/5zyLXvIMLZYoMyItB5avmqWqFOdBkl8oqcCuxCHc8mCDO1
+Kw8czozzP6znyOXuhpVU+g==
+=AKER
+-----END PGP MESSAGE-----
diff --git a/openpgp/tests/data/messages/s2k/salted.pgp b/openpgp/tests/data/messages/s2k/salted.pgp
new file mode 100644
index 00000000..ce68d582
--- /dev/null
+++ b/openpgp/tests/data/messages/s2k/salted.pgp
@@ -0,0 +1,10 @@
+-----BEGIN PGP MESSAGE-----
+Comment: Plaintext is "Hello World :)"
+Comment: Encrypted using AES with 256-bit key
+Comment: With password "password"
+Comment: Session key: 3A8B0B29434E9E1E4B766E44F1E46D7CA97DBC52FE8CAA6444CEBA16743949C9
+
+wwwECQEIc2FsemlnZXLSPwEwiCJ1RFrZS9lZcBsKlZTaeBSKbowG2edGWnTYpDes
+WUqXCYxvdgzPgGtfaa03p5C+yyJX7uBWUXvwBAs9lw==
+=c2+S
+-----END PGP MESSAGE-----
diff --git a/openpgp/tests/data/messages/s2k/simple.esk.pgp b/openpgp/tests/data/messages/s2k/simple.esk.pgp
new file mode 100644
index 00000000..6505cda5
--- /dev/null
+++ b/openpgp/tests/data/messages/s2k/simple.esk.pgp
@@ -0,0 +1,11 @@
+-----BEGIN PGP MESSAGE-----
+Comment: Plaintext is "Hello World :)"
+Comment: Encrypted using AES with 256-bit key
+Comment: With password "password"
+Comment: Session key: 4B6550EB3F56F615DF8177840B9E5FBC24F2431BB15CAC60BBDE257B8248E2C0
+
+wyUECQAIW6I9qHFmEqeeJ/bRXD8l/xOvUrPXA0AUBjMiJ8L/Fsfy0j8BQ09Zwuee
+3Dauo9MQhOzLkYID2sJRQHOYoPr86rIKa0T6olRryDgpO9i4OMRIc/54xZ0JkZNb
+WeWLTCyGlho=
+=AdKO
+-----END PGP MESSAGE-----
diff --git a/openpgp/tests/data/messages/s2k/simple.pgp b/openpgp/tests/data/messages/s2k/simple.pgp
new file mode 100644
index 00000000..0bfbb7f6
--- /dev/null
+++ b/openpgp/tests/data/messages/s2k/simple.pgp
@@ -0,0 +1,10 @@
+-----BEGIN PGP MESSAGE-----
+Comment: Plaintext is "Hello World :)"
+Comment: Encrypted using AES with 256-bit key
+Comment: With password "password"
+Comment: Session key: 5E884898DA28047151D0E56F8DC6292773603D0D6AABBDD62A11EF721D1542D8
+
+wwQECQAI0j8Bx5MtUEkqounwg7oaL9wfBZc3osExb9GXKu8WcV7wlW/w23E2JEWH
+2aGoKjLEmuWhx7cgzrx49ItD6HjJxFk=
+=GqhP
+-----END PGP MESSAGE-----