diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2020-11-12 15:37:46 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2020-11-12 15:37:46 +0100 |
commit | e23b8fe6256d57205c99f6a3df7353eb14c0ab42 (patch) | |
tree | 0d015ecc2f72adc70e96f4728c86d433a9ea8c81 /openpgp/src/crypto | |
parent | 8b390e8a38d8a31b5ada19a5ebbce924ee777fd8 (diff) |
openpgp: Add test vector from SHA-1 is a Shambles.
Diffstat (limited to 'openpgp/src/crypto')
-rw-r--r-- | openpgp/src/crypto/backend/sha1cd.rs | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/openpgp/src/crypto/backend/sha1cd.rs b/openpgp/src/crypto/backend/sha1cd.rs index 1de5f078..d5c44ebb 100644 --- a/openpgp/src/crypto/backend/sha1cd.rs +++ b/openpgp/src/crypto/backend/sha1cd.rs @@ -28,3 +28,66 @@ impl Digest for sha1collisiondetection::Sha1CD { r.map_err(Into::into) } } + +#[cfg(test)] +mod test { + use crate::*; + use crate::parse::Parse; + + /// Test vector from the "SHA-1 is a Shambles" paper. + /// + /// The scenario is the following. Bob obtains a certification + /// from a CA, and transfers it to a key claiming to belong to + /// Alice. Now the CA certifies an illegitimate binding to + /// Alice's userid. + #[test] + fn shambles() -> Result<()> { + let alice = + PacketPile::from_bytes(crate::tests::key("sha-mbles.alice.asc"))?; + let bob = + PacketPile::from_bytes(crate::tests::key("sha-mbles.bob.asc"))?; + let ca_keyid: KeyID = "AFBB 1FED 6951 A956".parse()?; + + assert_eq!(alice.children().count(), 4); + assert_eq!(bob.children().count(), 7); + + let alice_sha1_fingerprint: Fingerprint = + "43CD 5C5B 04FF 5742 FA14 1ABC A9D7 55A9 6354 8C78".parse()?; + let bob_sha1_fingerprint: Fingerprint = + "C6BF E2FC BBE5 1A89 2BEB 7798 1233 D4CC 61DB D9C4".parse()?; + + let alice_sha1cd_fingerprint: Fingerprint = + "4D84 B08A A181 21DB D79E EA05 9CD0 8D5B 1680 87E2".parse()?; + let bob_sha1cd_fingerprint: Fingerprint = + "6434 B04B 4648 BA41 15BD C5C2 B67A DB26 6F74 DF89".parse()?; + + // The illegitimate certification is on Bob's user attribute. + assert_eq!(bob.path_ref(&[6]).unwrap(), alice.path_ref(&[3]).unwrap()); + match bob.path_ref(&[6]).unwrap() { + Packet::Signature(s) => { + assert_eq!(s.issuers().nth(0).unwrap(), &ca_keyid); + }, + o => panic!("unexpected packet: {:?}", o), + } + + let alice = Cert::from_packets(alice.into_children())?; + let bob = Cert::from_packets(bob.into_children())?; + + // Check mitigations. First, the illegitimate certification + // should be discarded. + assert_eq!(alice.bad_signatures().len(), 1); + // Bob's userid also got certified, hence there are two bad + // signatures. + assert_eq!(bob.bad_signatures().len(), 2); + + // The mitigation also changes the identities of the keys + // containing the collision attack. This is a good thing, + // because we cannot trust SHA-1 to discriminate keys + // containing attacks. + assert!(alice.fingerprint() != alice_sha1_fingerprint); + assert_eq!(alice.fingerprint(), alice_sha1cd_fingerprint); + assert!(bob.fingerprint() != bob_sha1_fingerprint); + assert_eq!(bob.fingerprint(), bob_sha1cd_fingerprint); + Ok(()) + } +} |