summaryrefslogtreecommitdiffstats
path: root/openpgp/src/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'openpgp/src/crypto')
-rw-r--r--openpgp/src/crypto/backend/sha1cd.rs63
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(())
+ }
+}