1 //! One-pass signature packets. 2 //! 3 //! See [Section 5.4 of RFC 4880] for details. 4 //! 5 //! [Section 5.4 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-5.4 6 7 use std::fmt; 8 9 #[cfg(any(test, feature = "quickcheck"))] 10 use quickcheck::{Arbitrary, Gen}; 11 12 use crate::Error; 13 use crate::Packet; 14 use crate::packet; 15 use crate::packet::Signature; 16 use crate::Result; 17 use crate::KeyID; 18 use crate::HashAlgorithm; 19 use crate::PublicKeyAlgorithm; 20 use crate::SignatureType; 21 22 /// Holds a one-pass signature packet. 23 /// 24 /// See [Section 5.4 of RFC 4880] for details. 25 /// 26 /// [Section 5.4 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-5.4 27 /// 28 /// # A note on equality 29 /// 30 /// The `last` flag is represented as a `u8` and is compared 31 /// literally, not semantically. 32 // IMPORTANT: If you add fields to this struct, you need to explicitly 33 // IMPORTANT: implement PartialEq, Eq, and Hash. 34 #[derive(Clone, PartialEq, Eq, Hash)] 35 pub struct OnePassSig3 { 36 /// CTB packet header fields. 37 pub(crate) common: packet::Common, 38 /// Type of the signature. 39 typ: SignatureType, 40 /// Hash algorithm used to compute the signature. 41 hash_algo: HashAlgorithm, 42 /// Public key algorithm of this signature. 43 pk_algo: PublicKeyAlgorithm, 44 /// Key ID of the signing key. 45 issuer: KeyID, 46 /// A one-octet number holding a flag showing whether the signature 47 /// is nested. 48 last: u8, 49 } 50 51 impl fmt::Debug for OnePassSig3 { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result52 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 53 f.debug_struct("OnePassSig3") 54 .field("typ", &self.typ) 55 .field("hash_algo", &self.hash_algo) 56 .field("pk_algo", &self.pk_algo) 57 .field("issuer", &self.issuer) 58 .field("last", &self.last) 59 .finish() 60 } 61 } 62 63 impl OnePassSig3 { 64 /// Returns a new `Signature` packet. new(typ: SignatureType) -> Self65 pub fn new(typ: SignatureType) -> Self { 66 OnePassSig3 { 67 common: Default::default(), 68 typ, 69 hash_algo: HashAlgorithm::Unknown(0), 70 pk_algo: PublicKeyAlgorithm::Unknown(0), 71 issuer: KeyID::new(0), 72 last: 1, 73 } 74 } 75 76 /// Gets the signature type. typ(&self) -> SignatureType77 pub fn typ(&self) -> SignatureType { 78 self.typ 79 } 80 81 /// Sets the signature type. set_type(&mut self, t: SignatureType) -> SignatureType82 pub fn set_type(&mut self, t: SignatureType) -> SignatureType { 83 ::std::mem::replace(&mut self.typ, t) 84 } 85 86 /// Gets the public key algorithm. pk_algo(&self) -> PublicKeyAlgorithm87 pub fn pk_algo(&self) -> PublicKeyAlgorithm { 88 self.pk_algo 89 } 90 91 /// Sets the public key algorithm. set_pk_algo(&mut self, algo: PublicKeyAlgorithm) -> PublicKeyAlgorithm92 pub fn set_pk_algo(&mut self, algo: PublicKeyAlgorithm) -> PublicKeyAlgorithm { 93 ::std::mem::replace(&mut self.pk_algo, algo) 94 } 95 96 /// Gets the hash algorithm. hash_algo(&self) -> HashAlgorithm97 pub fn hash_algo(&self) -> HashAlgorithm { 98 self.hash_algo 99 } 100 101 /// Sets the hash algorithm. set_hash_algo(&mut self, algo: HashAlgorithm) -> HashAlgorithm102 pub fn set_hash_algo(&mut self, algo: HashAlgorithm) -> HashAlgorithm { 103 ::std::mem::replace(&mut self.hash_algo, algo) 104 } 105 106 /// Gets the issuer. issuer(&self) -> &KeyID107 pub fn issuer(&self) -> &KeyID { 108 &self.issuer 109 } 110 111 /// Sets the issuer. set_issuer(&mut self, issuer: KeyID) -> KeyID112 pub fn set_issuer(&mut self, issuer: KeyID) -> KeyID { 113 ::std::mem::replace(&mut self.issuer, issuer) 114 } 115 116 /// Gets the last flag. last(&self) -> bool117 pub fn last(&self) -> bool { 118 self.last > 0 119 } 120 121 /// Sets the last flag. set_last(&mut self, last: bool) -> bool122 pub fn set_last(&mut self, last: bool) -> bool { 123 ::std::mem::replace(&mut self.last, if last { 1 } else { 0 }) > 0 124 } 125 126 /// Gets the raw value of the last flag. last_raw(&self) -> u8127 pub fn last_raw(&self) -> u8 { 128 self.last 129 } 130 131 /// Sets the raw value of the last flag. set_last_raw(&mut self, last: u8) -> u8132 pub fn set_last_raw(&mut self, last: u8) -> u8 { 133 ::std::mem::replace(&mut self.last, last) 134 } 135 } 136 137 impl From<OnePassSig3> for super::OnePassSig { from(s: OnePassSig3) -> Self138 fn from(s: OnePassSig3) -> Self { 139 super::OnePassSig::V3(s) 140 } 141 } 142 143 impl From<OnePassSig3> for Packet { from(p: OnePassSig3) -> Self144 fn from(p: OnePassSig3) -> Self { 145 super::OnePassSig::from(p).into() 146 } 147 } 148 149 impl<'a> std::convert::TryFrom<&'a Signature> for OnePassSig3 { 150 type Error = anyhow::Error; 151 try_from(s: &'a Signature) -> Result<Self>152 fn try_from(s: &'a Signature) -> Result<Self> { 153 let issuer = match s.issuers().nth(0) { 154 Some(i) => i.clone(), 155 None => 156 return Err(Error::InvalidArgument( 157 "Signature has no issuer".into()).into()), 158 }; 159 160 Ok(OnePassSig3 { 161 common: Default::default(), 162 typ: s.typ(), 163 hash_algo: s.hash_algo(), 164 pk_algo: s.pk_algo(), 165 issuer, 166 last: 0, 167 }) 168 } 169 } 170 171 #[cfg(any(test, feature = "quickcheck"))] 172 impl Arbitrary for super::OnePassSig { arbitrary<G: Gen>(g: &mut G) -> Self173 fn arbitrary<G: Gen>(g: &mut G) -> Self { 174 OnePassSig3::arbitrary(g).into() 175 } 176 } 177 178 #[cfg(any(test, feature = "quickcheck"))] 179 impl Arbitrary for OnePassSig3 { arbitrary<G: Gen>(g: &mut G) -> Self180 fn arbitrary<G: Gen>(g: &mut G) -> Self { 181 let mut ops = OnePassSig3::new(SignatureType::arbitrary(g)); 182 ops.set_hash_algo(HashAlgorithm::arbitrary(g)); 183 ops.set_pk_algo(PublicKeyAlgorithm::arbitrary(g)); 184 ops.set_issuer(KeyID::arbitrary(g)); 185 ops.set_last_raw(u8::arbitrary(g)); 186 ops 187 } 188 } 189 190 #[cfg(test)] 191 mod tests { 192 use super::*; 193 use crate::parse::Parse; 194 use crate::serialize::MarshalInto; 195 196 quickcheck! { 197 fn roundtrip(p: OnePassSig3) -> bool { 198 let q = OnePassSig3::from_bytes(&p.to_vec().unwrap()).unwrap(); 199 assert_eq!(p, q); 200 true 201 } 202 } 203 } 204