diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2023-02-15 17:20:08 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2024-03-13 10:59:08 +0100 |
commit | e447b892e7490b8c7090bc0ab66a651259af254c (patch) | |
tree | 58c2ef203300af7f5eac85783adaadd8747c33e1 | |
parent | b6c06886844dc000d25d4c0c51f74f4d5045ff8b (diff) |
openpgp: Implement v6 key IDs.
- v4 and v6 key IDs are both 8 octets in length, hence we cannot
distinguish them.
- Rename KeyID::V4 to KeyID::Long to reflect this. Handle aliasing
with v6 fingerprints.
-rw-r--r-- | openpgp/src/keyhandle.rs | 39 | ||||
-rw-r--r-- | openpgp/src/keyid.rs | 24 | ||||
-rw-r--r-- | openpgp/src/serialize.rs | 6 |
3 files changed, 47 insertions, 22 deletions
diff --git a/openpgp/src/keyhandle.rs b/openpgp/src/keyhandle.rs index a667979e..32f23536 100644 --- a/openpgp/src/keyhandle.rs +++ b/openpgp/src/keyhandle.rs @@ -261,14 +261,31 @@ impl KeyHandle { /// # = "0123 4567 8901 2345 6789 0123 AACB 3243 6300 52D9" /// # .parse::<Fingerprint>()?.into(); /// # + /// # let v6_fpr1 : KeyHandle + /// # = "AACB3243630052D9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + /// # .parse::<Fingerprint>()?.into(); + /// # + /// # let v6_fpr2 : KeyHandle + /// # = "AACB3243630052D9BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" + /// # .parse::<Fingerprint>()?.into(); + /// # /// # let keyid : KeyHandle = "AACB 3243 6300 52D9".parse::<KeyID>()? /// # .into(); /// # - /// // fpr1 and fpr2 are different fingerprints with the same KeyID. + /// // fpr1 and fpr2 are different v4 fingerprints with the same KeyID. /// assert!(! fpr1.eq(&fpr2)); /// assert!(fpr1.aliases(&keyid)); /// assert!(fpr2.aliases(&keyid)); /// assert!(! fpr1.aliases(&fpr2)); + /// + /// // v6_fpr1 and v6_fpr2 are different v6 fingerprints with the same KeyID. + /// assert!(! v6_fpr1.eq(&v6_fpr2)); + /// assert!(v6_fpr1.aliases(&keyid)); + /// assert!(v6_fpr2.aliases(&keyid)); + /// assert!(! v6_fpr1.aliases(&v6_fpr2)); + /// + /// // And of course, v4 and v6 don't alias. + /// assert!(! fpr1.aliases(&v6_fpr1)); /// # Ok(()) } /// ``` pub fn aliases<H>(&self, other: H) -> bool @@ -280,8 +297,8 @@ impl KeyHandle { } else { match (self, other) { (KeyHandle::Fingerprint(Fingerprint::V4(f)), - KeyHandle::KeyID(KeyID::V4(i))) - | (KeyHandle::KeyID(KeyID::V4(i)), + KeyHandle::KeyID(KeyID::Long(i))) + | (KeyHandle::KeyID(KeyID::Long(i)), KeyHandle::Fingerprint(Fingerprint::V4(f))) => { // Avoid a heap allocation by embedding our @@ -292,10 +309,14 @@ impl KeyHandle { // fingerprint. &f[12..] == i }, - (KeyHandle::Fingerprint(f), KeyHandle::KeyID(i)) - | (KeyHandle::KeyID(i), KeyHandle::Fingerprint(f)) => + (KeyHandle::Fingerprint(Fingerprint::V6(f)), + KeyHandle::KeyID(KeyID::Long(i))) + | (KeyHandle::KeyID(KeyID::Long(i)), + KeyHandle::Fingerprint(Fingerprint::V6(f))) => { - &KeyID::from(f) == i + // A v6 key ID are the 8 left-most octets of a v4 + // fingerprint. + &f[..8] == i }, _ => false, } @@ -423,7 +444,7 @@ mod tests { let handle = KeyHandle::Fingerprint(Fingerprint::Invalid(Box::new([10, 2, 3, 4]))); assert_eq!(format!("{:X}", handle), "0A020304"); - let handle = KeyHandle::KeyID(KeyID::V4([10, 2, 3, 4, 5, 6, 7, 8])); + let handle = KeyHandle::KeyID(KeyID::Long([10, 2, 3, 4, 5, 6, 7, 8])); assert_eq!(format!("{:X}", handle), "0A02030405060708"); let handle = KeyHandle::KeyID(KeyID::Invalid(Box::new([10, 2]))); @@ -439,7 +460,7 @@ mod tests { let handle = KeyHandle::Fingerprint(Fingerprint::Invalid(Box::new([10, 2, 3, 4]))); assert_eq!(format!("{:x}", handle), "0a020304"); - let handle = KeyHandle::KeyID(KeyID::V4([10, 2, 3, 4, 5, 6, 7, 8])); + let handle = KeyHandle::KeyID(KeyID::Long([10, 2, 3, 4, 5, 6, 7, 8])); assert_eq!(format!("{:x}", handle), "0a02030405060708"); let handle = KeyHandle::KeyID(KeyID::Invalid(Box::new([10, 2]))); @@ -456,7 +477,7 @@ mod tests { 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45, 0x67]); let handle: KeyHandle = "89AB CDEF 0123 4567".parse()?; - assert_match!(&KeyHandle::KeyID(KeyID::V4(_)) = &handle); + assert_match!(&KeyHandle::KeyID(KeyID::Long(_)) = &handle); assert_eq!(handle.as_bytes(), [0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45, 0x67]); diff --git a/openpgp/src/keyid.rs b/openpgp/src/keyid.rs index 244f9d6d..4052e6a2 100644 --- a/openpgp/src/keyid.rs +++ b/openpgp/src/keyid.rs @@ -59,8 +59,12 @@ use crate::Result; #[non_exhaustive] #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Hash)] pub enum KeyID { - /// Lower 8 byte SHA-1 hash. - V4([u8;8]), + /// A long (8 bytes) key ID. + /// + /// For v4, this is the right-most 8 bytes of the v4 fingerprint. + /// For v6, this is the left-most 8 bytes of the v6 fingerprint. + Long([u8; 8]), + /// Used for holding invalid keyids encountered during parsing /// e.g. wrong number of bytes. Invalid(Box<[u8]>), @@ -121,7 +125,7 @@ impl From<KeyID> for Vec<u8> { fn from(id: KeyID) -> Self { let mut r = Vec::with_capacity(8); match id { - KeyID::V4(ref b) => r.extend_from_slice(b), + KeyID::Long(ref b) => r.extend_from_slice(b), KeyID::Invalid(ref b) => r.extend_from_slice(b), } r @@ -146,7 +150,7 @@ impl From<&Fingerprint> for KeyID { Fingerprint::V4(fp) => KeyID::from_bytes(&fp[fp.len() - 8..]), Fingerprint::V6(fp) => - KeyID::Invalid(fp.iter().cloned().collect()), + KeyID::from_bytes(&fp[..8]), Fingerprint::Invalid(fp) => { KeyID::Invalid(fp.clone()) } @@ -160,7 +164,7 @@ impl From<Fingerprint> for KeyID { Fingerprint::V4(fp) => KeyID::from_bytes(&fp[fp.len() - 8..]), Fingerprint::V6(fp) => - KeyID::Invalid(fp.into()), + KeyID::from_bytes(&fp[..8]), Fingerprint::Invalid(fp) => { KeyID::Invalid(fp) } @@ -200,7 +204,7 @@ impl KeyID { /// ``` pub fn as_u64(&self) -> Result<u64> { match &self { - KeyID::V4(ref b) => + KeyID::Long(ref b) => Ok(u64::from_be_bytes(*b)), KeyID::Invalid(_) => Err(Error::InvalidArgument("Invalid KeyID".into()).into()), @@ -226,7 +230,7 @@ impl KeyID { if raw.len() == 8 { let mut keyid : [u8; 8] = Default::default(); keyid.copy_from_slice(raw); - KeyID::V4(keyid) + KeyID::Long(keyid) } else { KeyID::Invalid(raw.to_vec().into_boxed_slice()) } @@ -249,7 +253,7 @@ impl KeyID { /// ``` pub fn as_bytes(&self) -> &[u8] { match self { - KeyID::V4(ref id) => id, + KeyID::Long(ref id) => id, KeyID::Invalid(ref id) => id, } } @@ -392,11 +396,11 @@ impl KeyID { let pretty = f.alternate(); let raw = match self { - KeyID::V4(ref fp) => &fp[..], + KeyID::Long(ref fp) => &fp[..], KeyID::Invalid(ref fp) => &fp[..], }; - // We currently only handle V4 Key IDs, which look like: + // We currently only handle long Key IDs, which look like: // // AACB 3243 6300 52D9 // diff --git a/openpgp/src/serialize.rs b/openpgp/src/serialize.rs index 0925310e..510e9bf8 100644 --- a/openpgp/src/serialize.rs +++ b/openpgp/src/serialize.rs @@ -870,7 +870,7 @@ impl seal::Sealed for KeyID {} impl Marshal for KeyID { fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> { let raw = match self { - KeyID::V4(ref fp) => &fp[..], + KeyID::Long(ref fp) => &fp[..], KeyID::Invalid(ref fp) => &fp[..], }; o.write_all(raw)?; @@ -882,7 +882,7 @@ impl SerializeInto for KeyID {} impl MarshalInto for KeyID { fn serialized_len(&self) -> usize { match self { - KeyID::V4(_) => 8, + KeyID::Long(_) => 8, KeyID::Invalid(ref fp) => fp.len(), } } @@ -1732,7 +1732,7 @@ impl Marshal for Signature3 { .map(|sp| sp.value()) { match keyid { - KeyID::V4(bytes) => { + KeyID::Long(bytes) => { assert_eq!(bytes.len(), 8); o.write_all(&bytes[..])?; } |