diff options
author | Neal H. Walfield <neal@pep.foundation> | 2018-05-17 12:32:14 +0200 |
---|---|---|
committer | Neal H. Walfield <neal@pep.foundation> | 2018-05-17 12:32:14 +0200 |
commit | 1406b481db870b13e66ee542d21159e32dd99d56 (patch) | |
tree | 248bb751ee65b4bf3d2da88d1d9772d0fddadca0 /openpgp | |
parent | df4549921627c0706c32abffe68806c2afb65806 (diff) |
openpgp: Move KeyID and Fingerprint details to their own modules
- Move the KeyID and Fingerprint implementation details to their own
modules.
Diffstat (limited to 'openpgp')
-rw-r--r-- | openpgp/src/fingerprint.rs | 128 | ||||
-rw-r--r-- | openpgp/src/keyid.rs | 135 | ||||
-rw-r--r-- | openpgp/src/lib.rs | 261 |
3 files changed, 266 insertions, 258 deletions
diff --git a/openpgp/src/fingerprint.rs b/openpgp/src/fingerprint.rs new file mode 100644 index 00000000..c33d995b --- /dev/null +++ b/openpgp/src/fingerprint.rs @@ -0,0 +1,128 @@ +use std::fmt; + +use Fingerprint; +use KeyID; + +impl fmt::Display for Fingerprint { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.to_string()) + } +} + +impl fmt::Debug for Fingerprint { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_tuple("Fingerprint") + .field(&self.to_string()) + .finish() + } +} + +impl Fingerprint { + /// Reads a binary fingerprint. + pub fn from_bytes(raw: &[u8]) -> Fingerprint { + if raw.len() == 20 { + let mut fp : [u8; 20] = Default::default(); + fp.copy_from_slice(raw); + Fingerprint::V4(fp) + } else { + Fingerprint::Invalid(raw.to_vec().into_boxed_slice()) + } + } + + /// Reads a hexadecimal fingerprint. + /// + /// This function ignores whitespace. + /// + /// # Example + /// + /// ``` + /// # use openpgp::Fingerprint; + /// let hex = "3E8877C877274692975189F5D03F6F865226FE8B"; + /// let fp = Fingerprint::from_hex(hex); + /// assert!(fp.is_some()); + /// assert_eq!(fp.unwrap().to_hex(), hex); + /// ``` + pub fn from_hex(hex: &str) -> Option<Fingerprint> { + Some(Fingerprint::from_bytes(&::from_hex(hex, true)?[..])) + } + + /// Converts the fingerprint to its standard representation. + /// + /// Returns the fingerprint suitable for human consumption. + pub fn to_string(&self) -> String { + self.convert_to_string(true) + } + + /// Converts the fingerprint to a hexadecimal number. + pub fn to_hex(&self) -> String { + self.convert_to_string(false) + } + + /// Common code for the above functions. + fn convert_to_string(&self, pretty: bool) -> String { + let raw = match self { + &Fingerprint::V4(ref fp) => &fp[..], + &Fingerprint::Invalid(ref fp) => &fp[..], + }; + + // We currently only handle V4 fingerprints, which look like: + // + // 8F17 7771 18A3 3DDA 9BA4 8E62 AACB 3243 6300 52D9 + // + // Since we have no idea how to format an invalid fingerprint, + // just format it like a V4 fingerprint and hope for the best. + + let mut output = Vec::with_capacity( + // Each byte results in to hex characters. + raw.len() * 2 + + if pretty { + // Every 2 bytes of output, we insert a space. + raw.len() / 2 + // After 5 groups, there is another space. + + raw.len() / 10 + } else { 0 }); + + for (i, b) in raw.iter().enumerate() { + if pretty && i > 0 && i % 2 == 0 { + output.push(' ' as u8); + } + + if pretty && i > 0 && i % 10 == 0 { + output.push(' ' as u8); + } + + let top = b >> 4; + let bottom = b & 0xFu8; + + if top < 10u8 { + output.push('0' as u8 + top) + } else { + output.push('A' as u8 + (top - 10u8)) + } + + if bottom < 10u8 { + output.push('0' as u8 + bottom) + } else { + output.push('A' as u8 + (bottom - 10u8)) + } + } + + // We know the content is valid UTF-8. + String::from_utf8(output).unwrap() + } + + /// Converts the fingerprint to a key ID. + pub fn to_keyid(&self) -> KeyID { + match self { + &Fingerprint::V4(ref fp) => + KeyID::from_bytes(&fp[fp.len() - 8..]), + &Fingerprint::Invalid(ref fp) => { + if fp.len() < 8 { + KeyID::from_bytes(&[0; 8]) + } else { + KeyID::from_bytes(&fp[fp.len() - 8..]) + } + } + } + } +} diff --git a/openpgp/src/keyid.rs b/openpgp/src/keyid.rs new file mode 100644 index 00000000..976ad7ba --- /dev/null +++ b/openpgp/src/keyid.rs @@ -0,0 +1,135 @@ +use std::fmt; + +use KeyID; + +impl fmt::Display for KeyID { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.to_string()) + } +} + +impl fmt::Debug for KeyID { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_tuple("KeyID") + .field(&self.to_string()) + .finish() + } +} + +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::Invalid(ref b) => r.extend_from_slice(b), + } + r + } +} + +impl KeyID { + /// Converts a u64 to a KeyID. + pub fn new(data: u64) -> KeyID { + let bytes = [ + (data >> (7 * 8)) as u8, + (data >> (6 * 8)) as u8, + (data >> (5 * 8)) as u8, + (data >> (4 * 8)) as u8, + (data >> (3 * 8)) as u8, + (data >> (2 * 8)) as u8, + (data >> (1 * 8)) as u8, + (data >> (0 * 8)) as u8 + ]; + Self::from_bytes(&bytes[..]) + } + + /// Reads a binary key ID. + pub fn from_bytes(raw: &[u8]) -> KeyID { + if raw.len() == 8 { + let mut keyid : [u8; 8] = Default::default(); + keyid.copy_from_slice(raw); + KeyID::V4(keyid) + } else { + KeyID::Invalid(raw.to_vec().into_boxed_slice()) + } + } + + /// Reads a hex-encoded Key ID. + pub fn from_hex(hex: &str) -> Option<KeyID> { + let bytes = ::from_hex(hex, true)?; + + // A KeyID is exactly 8 bytes long. + if bytes.len() != 8 { + return None; + } + + Some(KeyID::from_bytes(&bytes[..])) + } + + /// Returns a reference to the raw KeyID. + pub fn as_slice(&self) -> &[u8] { + match self { + &KeyID::V4(ref id) => id, + &KeyID::Invalid(ref id) => id, + } + } + + /// Converts the key ID to its standard representation. + /// + /// Returns the fingerprint suitable for human consumption. + pub fn to_string(&self) -> String { + self.convert_to_string(true) + } + + /// Converts the key ID to a hexadecimal number. + pub fn to_hex(&self) -> String { + self.convert_to_string(false) + } + + /// Common code for the above functions. + fn convert_to_string(&self, pretty: bool) -> String { + let raw = match self { + &KeyID::V4(ref fp) => &fp[..], + &KeyID::Invalid(ref fp) => &fp[..], + }; + + // We currently only handle V4 key IDs, which look like: + // + // AACB 3243 6300 52D9 + // + // Since we have no idea how to format an invalid key ID, just + // format it like a V4 fingerprint and hope for the best. + + let mut output = Vec::with_capacity( + // Each byte results in to hex characters. + raw.len() * 2 + + if pretty { + // Every 2 bytes of output, we insert a space. + raw.len() / 2 + } else { 0 }); + + for (i, b) in raw.iter().enumerate() { + if pretty && i > 0 && i % 2 == 0 { + output.push(' ' as u8); + } + + let top = b >> 4; + let bottom = b & 0xFu8; + + if top < 10u8 { + output.push('0' as u8 + top) + } else { + output.push('A' as u8 + (top - 10u8)) + } + + if bottom < 10u8 { + output.push('0' as u8 + bottom) + } else { + output.push('A' as u8 + (bottom - 10u8)) + } + } + + // We know the content is valid UTF-8. + String::from_utf8(output).unwrap() + } +} diff --git a/openpgp/src/lib.rs b/openpgp/src/lib.rs index 400fb0db..50b48563 100644 --- a/openpgp/src/lib.rs +++ b/openpgp/src/lib.rs @@ -53,8 +53,6 @@ extern crate quickcheck; #[cfg(not(test))] extern crate quickcheck; -use std::fmt; - pub mod armor; pub mod ctb; @@ -102,6 +100,9 @@ pub use constants::{ }; mod tag; pub use tag::Tag; + +mod fingerprint; +mod keyid; pub type Result<T> = ::std::result::Result<T, failure::Error>; @@ -502,130 +503,6 @@ pub enum Fingerprint { Invalid(Box<[u8]>) } -impl fmt::Display for Fingerprint { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.to_string()) - } -} - -impl fmt::Debug for Fingerprint { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_tuple("Fingerprint") - .field(&self.to_string()) - .finish() - } -} - -impl Fingerprint { - /// Reads a binary fingerprint. - pub fn from_bytes(raw: &[u8]) -> Fingerprint { - if raw.len() == 20 { - let mut fp : [u8; 20] = Default::default(); - fp.copy_from_slice(raw); - Fingerprint::V4(fp) - } else { - Fingerprint::Invalid(raw.to_vec().into_boxed_slice()) - } - } - - /// Reads a hexadecimal fingerprint. - /// - /// This function ignores whitespace. - /// - /// # Example - /// - /// ``` - /// # use openpgp::Fingerprint; - /// let hex = "3E8877C877274692975189F5D03F6F865226FE8B"; - /// let fp = Fingerprint::from_hex(hex); - /// assert!(fp.is_some()); - /// assert_eq!(fp.unwrap().to_hex(), hex); - /// ``` - pub fn from_hex(hex: &str) -> Option<Fingerprint> { - Some(Fingerprint::from_bytes(&from_hex(hex, true)?[..])) - } - - /// Converts the fingerprint to its standard representation. - /// - /// Returns the fingerprint suitable for human consumption. - pub fn to_string(&self) -> String { - self.convert_to_string(true) - } - - /// Converts the fingerprint to a hexadecimal number. - pub fn to_hex(&self) -> String { - self.convert_to_string(false) - } - - /// Common code for the above functions. - fn convert_to_string(&self, pretty: bool) -> String { - let raw = match self { - &Fingerprint::V4(ref fp) => &fp[..], - &Fingerprint::Invalid(ref fp) => &fp[..], - }; - - // We currently only handle V4 fingerprints, which look like: - // - // 8F17 7771 18A3 3DDA 9BA4 8E62 AACB 3243 6300 52D9 - // - // Since we have no idea how to format an invalid fingerprint, - // just format it like a V4 fingerprint and hope for the best. - - let mut output = Vec::with_capacity( - // Each byte results in to hex characters. - raw.len() * 2 - + if pretty { - // Every 2 bytes of output, we insert a space. - raw.len() / 2 - // After 5 groups, there is another space. - + raw.len() / 10 - } else { 0 }); - - for (i, b) in raw.iter().enumerate() { - if pretty && i > 0 && i % 2 == 0 { - output.push(' ' as u8); - } - - if pretty && i > 0 && i % 10 == 0 { - output.push(' ' as u8); - } - - let top = b >> 4; - let bottom = b & 0xFu8; - - if top < 10u8 { - output.push('0' as u8 + top) - } else { - output.push('A' as u8 + (top - 10u8)) - } - - if bottom < 10u8 { - output.push('0' as u8 + bottom) - } else { - output.push('A' as u8 + (bottom - 10u8)) - } - } - - // We know the content is valid UTF-8. - String::from_utf8(output).unwrap() - } - - /// Converts the fingerprint to a key ID. - pub fn to_keyid(&self) -> KeyID { - match self { - &Fingerprint::V4(ref fp) => - KeyID::from_bytes(&fp[fp.len() - 8..]), - &Fingerprint::Invalid(ref fp) => { - if fp.len() < 8 { - KeyID::from_bytes(&[0; 8]) - } else { - KeyID::from_bytes(&fp[fp.len() - 8..]) - } - } - } - } -} - /// Holds a KeyID. /// /// A KeyID is a fingerprint fragment. It identifies a public key, @@ -641,135 +518,3 @@ pub enum KeyID { // that the Issuer subpacket contains the wrong number of bytes. Invalid(Box<[u8]>) } - -impl fmt::Display for KeyID { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.to_string()) - } -} - -impl fmt::Debug for KeyID { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_tuple("KeyID") - .field(&self.to_string()) - .finish() - } -} - -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::Invalid(ref b) => r.extend_from_slice(b), - } - r - } -} - -impl KeyID { - /// Converts a u64 to a KeyID. - pub fn new(data: u64) -> KeyID { - let bytes = [ - (data >> (7 * 8)) as u8, - (data >> (6 * 8)) as u8, - (data >> (5 * 8)) as u8, - (data >> (4 * 8)) as u8, - (data >> (3 * 8)) as u8, - (data >> (2 * 8)) as u8, - (data >> (1 * 8)) as u8, - (data >> (0 * 8)) as u8 - ]; - Self::from_bytes(&bytes[..]) - } - - /// Reads a binary key ID. - pub fn from_bytes(raw: &[u8]) -> KeyID { - if raw.len() == 8 { - let mut keyid : [u8; 8] = Default::default(); - keyid.copy_from_slice(raw); - KeyID::V4(keyid) - } else { - KeyID::Invalid(raw.to_vec().into_boxed_slice()) - } - } - - /// Reads a hex-encoded Key ID. - pub fn from_hex(hex: &str) -> Option<KeyID> { - let bytes = from_hex(hex, true)?; - - // A KeyID is exactly 8 bytes long. - if bytes.len() != 8 { - return None; - } - - Some(KeyID::from_bytes(&bytes[..])) - } - - /// Returns a reference to the raw KeyID. - pub fn as_slice(&self) -> &[u8] { - match self { - &KeyID::V4(ref id) => id, - &KeyID::Invalid(ref id) => id, - } - } - - /// Converts the key ID to its standard representation. - /// - /// Returns the fingerprint suitable for human consumption. - pub fn to_string(&self) -> String { - self.convert_to_string(true) - } - - /// Converts the key ID to a hexadecimal number. - pub fn to_hex(&self) -> String { - self.convert_to_string(false) - } - - /// Common code for the above functions. - fn convert_to_string(&self, pretty: bool) -> String { - let raw = match self { - &KeyID::V4(ref fp) => &fp[..], - &KeyID::Invalid(ref fp) => &fp[..], - }; - - // We currently only handle V4 key IDs, which look like: - // - // AACB 3243 6300 52D9 - // - // Since we have no idea how to format an invalid key ID, just - // format it like a V4 fingerprint and hope for the best. - - let mut output = Vec::with_capacity( - // Each byte results in to hex characters. - raw.len() * 2 - + if pretty { - // Every 2 bytes of output, we insert a space. - raw.len() / 2 - } else { 0 }); - - for (i, b) in raw.iter().enumerate() { - if pretty && i > 0 && i % 2 == 0 { - output.push(' ' as u8); - } - - let top = b >> 4; - let bottom = b & 0xFu8; - - if top < 10u8 { - output.push('0' as u8 + top) - } else { - output.push('A' as u8 + (top - 10u8)) - } - - if bottom < 10u8 { - output.push('0' as u8 + bottom) - } else { - output.push('A' as u8 + (bottom - 10u8)) - } - } - - // We know the content is valid UTF-8. - String::from_utf8(output).unwrap() - } -} |