diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2022-09-29 18:02:43 +0200 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2022-09-29 18:04:36 +0200 |
commit | f89695585459799981d83c0b6eecb13511490e56 (patch) | |
tree | b493f6a8834ddb2a67e75d98abf1d7c820192847 /ipc | |
parent | dd14446c736745e9cac9f6076c91421dd7726fdb (diff) |
ipc: Fix computing keygrips.
Diffstat (limited to 'ipc')
-rw-r--r-- | ipc/src/keygrip.rs | 74 | ||||
-rw-r--r-- | ipc/tests/data/keys/alpha.pgp | 28 | ||||
-rw-r--r-- | ipc/tests/data/keys/zulu.pgp | 23 |
3 files changed, 114 insertions, 11 deletions
diff --git a/ipc/src/keygrip.rs b/ipc/src/keygrip.rs index 5bb2ee07..82b5f87f 100644 --- a/ipc/src/keygrip.rs +++ b/ipc/src/keygrip.rs @@ -92,9 +92,26 @@ impl Keygrip { use self::PublicKey::*; let mut hash = HashAlgorithm::SHA1.context().unwrap(); - fn hash_sexp_mpi(hash: &mut dyn hash::Digest, kind: char, prefix: &[u8], - mpi: &MPI) + fn hash_sexp_mpi(hash: &mut dyn hash::Digest, kind: char, mpi: &MPI) { + // gcrypt's MPIs can be signed or unsigned. Our MPIs are + // always unsigned (well, for us they are opaque byte + // strings, so the concept of a sign does not apply). + // Every now and then we need to pay attention to this, as + // gcrypt sometimes prepends a zero to prevent the most + // significant bit from being interpreted as a sign bit. + // Computing keygrips is one of these times. + let prefix = if mpi.value().get(0).map(|msb| msb & 0x80 > 0) + .unwrap_or(false) + { + // The most significant bit is set. Prepend a zero + // byte so that the MSB will not be interpreted as a + // sign bit. + &b"\x00"[..] + } else { + // The MSB is not set, no need to prepend anything. + &b""[..] + }; hash_sexp(hash, kind, prefix, mpi.value()); } @@ -153,18 +170,16 @@ impl Keygrip { }, &DSA { ref p, ref q, ref g, ref y } => { - // Empirical evidence suggest that we need to prepend - // a 0 to some parameters. - hash_sexp_mpi(&mut hash, 'p', b"\x00", p); - hash_sexp_mpi(&mut hash, 'q', b"\x00", q); - hash_sexp_mpi(&mut hash, 'g', b"", g); - hash_sexp_mpi(&mut hash, 'y', b"", y); + hash_sexp_mpi(&mut hash, 'p', p); + hash_sexp_mpi(&mut hash, 'q', q); + hash_sexp_mpi(&mut hash, 'g', g); + hash_sexp_mpi(&mut hash, 'y', y); }, &ElGamal { ref p, ref g, ref y } => { - hash_sexp_mpi(&mut hash, 'p', b"\x00", p); - hash_sexp_mpi(&mut hash, 'g', b"", g); - hash_sexp_mpi(&mut hash, 'y', b"", y); + hash_sexp_mpi(&mut hash, 'p', p); + hash_sexp_mpi(&mut hash, 'g', g); + hash_sexp_mpi(&mut hash, 'y', y); }, &EdDSA { ref curve, ref q } => hash_ecc(&mut hash, curve, q)?, @@ -405,4 +420,41 @@ mod tests { } } } + + /// Tests vectors from GPGME, using GnuPG as oracle. + #[test] + fn gpgme_keys() { + use std::collections::HashMap; + use openpgp::Fingerprint as FP; + use super::Keygrip as KG; + use openpgp::parse::Parse; + + let keygrips: HashMap<FP, KG> = [ + // alpha.pgp + ("A0FF4590BB6122EDEF6E3C542D727CC768697734".parse::<FP>().unwrap(), + "76F7E2B35832976B50A27A282D9B87E44577EB66".parse::<KG>().unwrap()), + ("3B3FBC948FE59301ED629EFB6AE6D7EE46A871F8".parse::<FP>().unwrap(), + "A0747D5F9425E6664F4FFBEED20FBCA79FDED2BD".parse::<KG>().unwrap()), + // zulu.pgp + ("23FD347A419429BACCD5E72D6BC4778054ACD246".parse::<FP>().unwrap(), + "13CBE3758AFE42B5E5E2AE4CED27AFA455E3F87F".parse::<KG>().unwrap()), + ("2DCA5A1392DE06ED4FCB8C53EF9DC276A172C881".parse::<FP>().unwrap(), + "7A030357C0F253A5BBCD282FFC4E521B37558F5C".parse::<KG>().unwrap()), + ].iter().cloned().collect(); + + for (name, cert) in [ + "alpha.pgp", + "zulu.pgp", + ] + .iter().map(|n| (n, openpgp::Cert::from_bytes(crate::tests::key(n)).unwrap())) + { + eprintln!("{}", name); + for key in cert.keys().map(|a| a.key()) { + let fp = key.fingerprint(); + eprintln!("(sub)key: {}", fp); + assert_eq!(&Keygrip::of(key.mpis()).unwrap(), + keygrips.get(&fp).unwrap()); + } + } + } } diff --git a/ipc/tests/data/keys/alpha.pgp b/ipc/tests/data/keys/alpha.pgp new file mode 100644 index 00000000..6d5b3b4f --- /dev/null +++ b/ipc/tests/data/keys/alpha.pgp @@ -0,0 +1,28 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQGiBDbjjp4RBAC2ZbFDX0wmJI8yLDYQdIiZeAuHLmfyHsqXaLGUMZtWiAvn/hNp +ctwahmzKm5oXinHUvUkLOQ0s8rOlu15nhw4azc30rTP1LsIkn5zORNnFdgYC6RKy +hOeim/63+/yGtdnTm49lVfaCqwsEmBCEkXaeWDGq+ie1b89J89T6n/JquwCgoQkj +VeVGG+B/SzJ6+yifdHWQVkcD/RXDyLXX4+WHGP2aet51XlKojWGwsZmc9LPPYhwU +/RcUO7ce1QQb0XFlUVFBhY0JQpM/ty/kNi+aGWFzigbQ+HAWZkUvA8+VIAVneN+p ++SHhGIyLTXKpAYTq46AwvllZ5Cpvf02Cp/+W1aVyA0qnBWMyeIxXmR9HOi6lxxn5 +cjajA/9VZufOXWqCXkBvz4Oy3Q5FbjQQ0/+ty8rDn8OTaiPi41FyUnEi6LO+qyBS +09FjnZj++PkcRcXW99SNxmEJRY7MuNHt5wIvEH2jNEOJ9lszzZFBDbuwsjXHK35+ +lPbGEy69xCP26iEafysKKbRXJhE1C+tk8SnK+Gm62sivmK/5arQpQWxwaGEgVGVz +dCAoZGVtbyBrZXkpIDxhbHBoYUBleGFtcGxlLm5ldD6IVQQTEQIAFQUCNuOOngML +CgMDFQMCAxYCAQIXgAAKCRAtcnzHaGl3NDl4AKCBLmRplv/8ZfSqep5IjqEAuaXv +WwCgl6NEzT+/WewPTGcwZY+pLkycLv20EEFsaWNlIChkZW1vIGtleSmIVQQTEQIA +FQUCNuO2qwMLCgMDFQMCAxYCAQIXgAAKCRAtcnzHaGl3NCeMAJ9MeUVrago5Jc6P +dwdeN5OMwby37QCghW65cZTQlD1bBlIq/QM8bz9AN4G0J0FsZmEgVGVzdCAoZGVt +byBrZXkpIDxhbGZhQGV4YW1wbGUubmV0PohVBBMRAgAVBQI247hYAwsKAwMVAwID +FgIBAheAAAoJEC1yfMdoaXc0t8IAoJPwa6j+Vm5Vi3Nvuo8JZri4PJ/DAJ9dqbma +JdB8FdJnHfGh1rXK3y/JcrkBDQQ2448PEAQAnI3XH1f0uyN9fZnw72zsHMw706g7 +EW29nD4UDQG4OzRZViSrUa5n39eI7QrfTO+1meVvs0y8F/PvFst5jH68rPLnGSrX +z4sTl1T4cop1FBkquvCAKwPLy0lE7jjtCyItOSwIOo8xoTfY4JEEXmcqsbm+KHv9 +yYSF/YK4Cf7bIzcAAwcD/Rnl5jKxoucDA96pD2829TKsLFQSau+Xiy8bvOSSDdly +ABsOkNBSaeKO3eAQEKgDM7dzjVNTnAlpQ0EQ8Y9Z8pxOWYEQYlaMrnRBC4DZ2Iad +zEhLlIOz5BVp/jfhrr8oVVBwKZXsrz9PZLz+e4Yn+siUUvlei9boD9L2ZgSOHakP +iEYEGBECAAYFAjbjjw8ACgkQLXJ8x2hpdzQgqQCfcDXmD8uNVdKg/C9vqI3JSndq +knsAnRxzVeHi/iJ73OCKtvFrHbV9Gogq +=sBZo +-----END PGP PUBLIC KEY BLOCK----- diff --git a/ipc/tests/data/keys/zulu.pgp b/ipc/tests/data/keys/zulu.pgp new file mode 100644 index 00000000..b1811ced --- /dev/null +++ b/ipc/tests/data/keys/zulu.pgp @@ -0,0 +1,23 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQGiBDbjtcsRBACBDJOGX9C/xxCVZNP6OHz6cL5vM3PimUAhV+9HAVVPQViTnFKr +kYPSQyRfWzjOU8RO1Tp5CHz747oOb6j9P74yH1uy78yFg4UuhXBWinhuCKKq4IIW +wJkCKBFr1U8fu8a6Y6NcjqiDA0KmGRJrMPmXenXkJpFGHG78rUvNi9IMfwCgugzN +ILh/3XZCZU+BUPYeXL+nUAEEAIDXZhj1vFXHgi9lmijKDjJocEBoamN/taQy6Ox1 +RRD6HtfAPY5TER1n7xm9hMzE+Ov1IKpH/E872Rha1qu1v7eOa6eTuNWF0NvmSR95 +5freRsNuR8JNIb6StI2ER9pzBUfjykC9pg2wPeC7wpQJIF9TF+Ja1BvG2I+ha2xJ +786AA/sHEUvAOsc58YbPlbIPyp2JdEHvXTRT2NISVRuTMQsg8vV99nMYR2CUh270 +uPyy2xZaD/kYcJ9/1ngY7C9pbbNWoV70PkEMO/qj67OIViWVPzUhIdURorbpGhuc +3oBzUxOgial7IbISPRItDgg2oZoY4hqyQNx8Cj2ZZAzDpM2vCrQnWnVsdSBUZXN0 +IChkZW1vIGtleSkgPHp1bHVAZXhhbXBsZS5uZXQ+iFUEExECABUFAjbjtcsDCwoD +AxUDAgMWAgECF4AACgkQa8R3gFSs0kZA6wCeJUyRzuFbsZ0uQulvpgOIRTLTKscA +oLd3InVEj20peTUQ5b2NOimSXnKxuQENBDbjtfIQBADMfPDBQoMzv52Mmjb8SdaY +KKNzqDd9K1oY2hcMSi+LcHag+KJFOyKBf3SoHmcU/vCEN+LyTgljYSKDmEf4wZ2+ +eLfqFgSdBJp2xm55ih+9CHXg3dXx9SbHiGJCIxfJaIsnNz3VmJGPDDjBlaf/hjl/ +7SZvR+MJpVLFPGjj7uOhTwADBQP/Sgv0abeCXVdVXwGEmhdV0VDo833IQRdRu1yt ++QLnWRMGTY1oQapsH6QLwYSZfDJlxbsBA3tfqKStpRSbdGNNTsK+RIehsGddi3sW +GplRGm5Xt5KpkY/mc/tLFaYJNMqAgfWQcKlZHBp7EoWMgiRiDJUWq0TH1wRDoPaR +c+H5GdqIRgQYEQIABgUCNuO18gAKCRBrxHeAVKzSRn1jAKC5Gp5sHM9sWdZeM6qf +u54F2OwMQACfTjYXfpMApAROPkjhhFNqH0d8x5E= +=Ch/w +-----END PGP PUBLIC KEY BLOCK----- |