summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2019-04-02 17:47:25 +0200
committerJustus Winter <justus@sequoia-pgp.org>2019-04-02 17:53:18 +0200
commit653e71c835b5ce2f0a8f25e25e2992994622dbaf (patch)
tree25a51bf84ba50baafef19ad0344f1f5709426a4d
parent035b9dc26e58f7bf6f648aebdd36bec4e7ba89b2 (diff)
openpgp: Support the Trust packet.
- Fixes #235.
-rw-r--r--openpgp/src/lib.rs4
-rw-r--r--openpgp/src/packet/mod.rs4
-rw-r--r--openpgp/src/packet/prelude.rs1
-rw-r--r--openpgp/src/packet/trust.rs74
-rw-r--r--openpgp/src/parse/parse.rs37
-rw-r--r--openpgp/src/serialize/mod.rs25
-rw-r--r--tool/src/commands/dump.rs5
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,