diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2019-04-02 17:47:25 +0200 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2019-04-02 17:53:18 +0200 |
commit | 653e71c835b5ce2f0a8f25e25e2992994622dbaf (patch) | |
tree | 25a51bf84ba50baafef19ad0344f1f5709426a4d | |
parent | 035b9dc26e58f7bf6f648aebdd36bec4e7ba89b2 (diff) |
openpgp: Support the Trust packet.
- Fixes #235.
-rw-r--r-- | openpgp/src/lib.rs | 4 | ||||
-rw-r--r-- | openpgp/src/packet/mod.rs | 4 | ||||
-rw-r--r-- | openpgp/src/packet/prelude.rs | 1 | ||||
-rw-r--r-- | openpgp/src/packet/trust.rs | 74 | ||||
-rw-r--r-- | openpgp/src/parse/parse.rs | 37 | ||||
-rw-r--r-- | openpgp/src/serialize/mod.rs | 25 | ||||
-rw-r--r-- | tool/src/commands/dump.rs | 5 |
7 files changed, 149 insertions, 1 deletions
diff --git a/openpgp/src/lib.rs b/openpgp/src/lib.rs index 835a0f36..e3b99d7a 100644 --- a/openpgp/src/lib.rs +++ b/openpgp/src/lib.rs @@ -262,6 +262,8 @@ pub enum Packet { SecretSubkey(packet::Key), /// Marker packet. Marker(packet::Marker), + /// Trust packet. + Trust(packet::Trust), /// User ID packet. UserID(packet::UserID), /// User attribute packet. @@ -299,6 +301,7 @@ impl Packet { &Packet::SecretKey(_) => Tag::SecretKey, &Packet::SecretSubkey(_) => Tag::SecretSubkey, &Packet::Marker(_) => Tag::Marker, + &Packet::Trust(_) => Tag::Trust, &Packet::UserID(_) => Tag::UserID, &Packet::UserAttribute(_) => Tag::UserAttribute, &Packet::Literal(_) => Tag::Literal, @@ -329,6 +332,7 @@ impl Packet { &Packet::SecretKey(_) => Some(Tag::SecretKey), &Packet::SecretSubkey(_) => Some(Tag::SecretSubkey), &Packet::Marker(_) => Some(Tag::Marker), + &Packet::Trust(_) => Some(Tag::Trust), &Packet::UserID(_) => Some(Tag::UserID), &Packet::UserAttribute(_) => Some(Tag::UserAttribute), &Packet::Literal(_) => Some(Tag::Literal), diff --git a/openpgp/src/packet/mod.rs b/openpgp/src/packet/mod.rs index b6ab488c..6f23f26a 100644 --- a/openpgp/src/packet/mod.rs +++ b/openpgp/src/packet/mod.rs @@ -32,6 +32,8 @@ pub mod one_pass_sig; pub mod key; mod marker; pub use self::marker::Marker; +mod trust; +pub use self::trust::Trust; mod userid; pub use self::userid::UserID; pub mod user_attribute; @@ -67,6 +69,7 @@ impl<'a> Deref for Packet { &Packet::SecretKey(ref packet) => &packet.common, &Packet::SecretSubkey(ref packet) => &packet.common, &Packet::Marker(ref packet) => &packet.common, + &Packet::Trust(ref packet) => &packet.common, &Packet::UserID(ref packet) => &packet.common, &Packet::UserAttribute(ref packet) => &packet.common, &Packet::Literal(ref packet) => &packet.common, @@ -93,6 +96,7 @@ impl<'a> DerefMut for Packet { &mut Packet::SecretKey(ref mut packet) => &mut packet.common, &mut Packet::SecretSubkey(ref mut packet) => &mut packet.common, &mut Packet::Marker(ref mut packet) => &mut packet.common, + &mut Packet::Trust(ref mut packet) => &mut packet.common, &mut Packet::UserID(ref mut packet) => &mut packet.common, &mut Packet::UserAttribute(ref mut packet) => &mut packet.common, &mut Packet::Literal(ref mut packet) => &mut packet.common, diff --git a/openpgp/src/packet/prelude.rs b/openpgp/src/packet/prelude.rs index 069f97ac..a86c3024 100644 --- a/openpgp/src/packet/prelude.rs +++ b/openpgp/src/packet/prelude.rs @@ -11,6 +11,7 @@ pub use super::{ key::Key4, key::SecretKey, Marker, + Trust, UserID, user_attribute, UserAttribute, diff --git a/openpgp/src/packet/trust.rs b/openpgp/src/packet/trust.rs new file mode 100644 index 00000000..af89ca0c --- /dev/null +++ b/openpgp/src/packet/trust.rs @@ -0,0 +1,74 @@ +use std::fmt; +use quickcheck::{Arbitrary, Gen}; + +use packet; +use Packet; + +/// Holds a Trust packet. +/// +/// See [Section 5.10 of RFC 4880] for details. +/// +/// [Section 5.10 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-5.10 +#[derive(PartialEq, Eq, Hash, Clone)] +pub struct Trust { + pub(crate) common: packet::Common, + value: Vec<u8>, +} + +impl From<Vec<u8>> for Trust { + fn from(u: Vec<u8>) -> Self { + Trust { + common: Default::default(), + value: u, + } + } +} + +impl fmt::Display for Trust { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let trust = String::from_utf8_lossy(&self.value[..]); + write!(f, "{}", trust) + } +} + +impl fmt::Debug for Trust { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Trust") + .field("value", &::conversions::hex::encode(&self.value)) + .finish() + } +} + +impl Trust { + /// Gets the trust packet's value. + pub fn value(&self) -> &[u8] { + self.value.as_slice() + } +} + +impl From<Trust> for Packet { + fn from(s: Trust) -> Self { + Packet::Trust(s) + } +} + +impl Arbitrary for Trust { + fn arbitrary<G: Gen>(g: &mut G) -> Self { + Vec::<u8>::arbitrary(g).into() + } +} + +#[cfg(test)] +mod tests { + use super::*; + use parse::Parse; + use serialize::SerializeInto; + + quickcheck! { + fn roundtrip(p: Trust) -> bool { + let q = Trust::from_bytes(&p.to_vec().unwrap()).unwrap(); + assert_eq!(p, q); + true + } + } +} diff --git a/openpgp/src/parse/parse.rs b/openpgp/src/parse/parse.rs index 2a858b83..ecccfac2 100644 --- a/openpgp/src/parse/parse.rs +++ b/openpgp/src/parse/parse.rs @@ -1514,6 +1514,40 @@ impl<'a> Parse<'a, Key> for Key { } } +impl Trust { + /// Parses the body of a trust packet. + fn parse<'a>(mut php: PacketHeaderParser<'a>) -> Result<PacketParser<'a>> { + make_php_try!(php); + let value = php_try!(php.parse_bytes_eof("value")); + php.ok(Packet::Trust(Trust::from(value))) + } +} + +impl<'a> Parse<'a, Trust> for Trust { + fn from_reader<R: 'a + Read>(reader: R) -> Result<Self> { + let ppr = PacketParser::from_reader(reader)?; + let (p, ppr) = match ppr { + PacketParserResult::Some(mut pp) => { + pp.next()? + }, + PacketParserResult::EOF(_) => + return Err(Error::InvalidOperation( + "Unexpected EOF".into()).into()), + }; + + match (p, ppr) { + (Packet::Trust(u), PacketParserResult::EOF(_)) => + Ok(u), + (p, PacketParserResult::EOF(_)) => + Err(Error::InvalidOperation( + format!("Not a Trust packet: {:?}", p)).into()), + (_, PacketParserResult::Some(_)) => + Err(Error::InvalidOperation( + "Excess data after packet".into()).into()), + } + } +} + impl UserID { /// Parses the body of a user id packet. fn parse<'a>(mut php: PacketHeaderParser<'a>) -> Result<PacketParser<'a>> { @@ -3022,6 +3056,7 @@ impl <'a> PacketParser<'a> { Tag::PublicKey => Key::parse(parser), Tag::SecretKey => Key::parse(parser), Tag::SecretSubkey => Key::parse(parser), + Tag::Trust => Trust::parse(parser), Tag::UserID => UserID::parse(parser), Tag::UserAttribute => UserAttribute::parse(parser), Tag::Marker => Marker::parse(parser), @@ -3279,7 +3314,7 @@ impl <'a> PacketParser<'a> { Packet::Unknown(_) | Packet::Signature(_) | Packet::OnePassSig(_) | Packet::PublicKey(_) | Packet::PublicSubkey(_) | Packet::SecretKey(_) | Packet::SecretSubkey(_) - | Packet::Marker(_) + | Packet::Marker(_) | Packet::Trust(_) | Packet::UserID(_) | Packet::UserAttribute(_) | Packet::Literal(_) | Packet::PKESK(_) | Packet::SKESK(_) | Packet::SEIP(_) | Packet::MDC(_) | Packet::AED(_) => { diff --git a/openpgp/src/serialize/mod.rs b/openpgp/src/serialize/mod.rs index 18b420af..4d7c2ffe 100644 --- a/openpgp/src/serialize/mod.rs +++ b/openpgp/src/serialize/mod.rs @@ -1334,6 +1334,29 @@ impl SerializeInto for Marker { } } +impl Serialize for Trust { + fn serialize<W: io::Write>(&self, o: &mut W) -> Result<()> { + let len = self.value().len(); + + CTB::new(Tag::Trust).serialize(o)?; + BodyLength::Full(len as u32).serialize(o)?; + o.write_all(self.value())?; + + Ok(()) + } +} + +impl SerializeInto for Trust { + fn serialized_len(&self) -> usize { + 1 + BodyLength::Full(self.value().len() as u32).serialized_len() + + self.value().len() + } + + fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> { + generic_serialize_into(self, buf) + } +} + impl Serialize for UserID { fn serialize<W: io::Write>(&self, o: &mut W) -> Result<()> { let len = self.value().len(); @@ -1917,6 +1940,7 @@ impl Serialize for Packet { &Packet::SecretKey(ref p) => p.serialize(o, tag), &Packet::SecretSubkey(ref p) => p.serialize(o, tag), &Packet::Marker(ref p) => p.serialize(o), + &Packet::Trust(ref p) => p.serialize(o), &Packet::UserID(ref p) => p.serialize(o), &Packet::UserAttribute(ref p) => p.serialize(o), &Packet::Literal(ref p) => p.serialize(o), @@ -1942,6 +1966,7 @@ impl SerializeInto for Packet { &Packet::SecretKey(ref p) => p.serialized_len(tag), &Packet::SecretSubkey(ref p) => p.serialized_len(tag), &Packet::Marker(ref p) => p.serialized_len(), + &Packet::Trust(ref p) => p.serialized_len(), &Packet::UserID(ref p) => p.serialized_len(), &Packet::UserAttribute(ref p) => p.serialized_len(), &Packet::Literal(ref p) => p.serialized_len(), diff --git a/tool/src/commands/dump.rs b/tool/src/commands/dump.rs index d5ab49fe..f926832b 100644 --- a/tool/src/commands/dump.rs +++ b/tool/src/commands/dump.rs @@ -272,6 +272,11 @@ impl PacketDumper { } }, + Trust(ref p) => { + writeln!(output, "Trust Packet")?; + writeln!(output, "{} Value: {}", i, hex::encode(p.value()))?; + }, + UserID(ref u) => { writeln!(output, "User ID Packet")?; writeln!(output, "{} Value: {}", i, |