sequoia_openpgp/packet/one_pass_sig/
v6.rs1use std::convert::TryFrom;
4use std::fmt;
5use std::mem;
6
7#[cfg(test)]
8use quickcheck::{Arbitrary, Gen};
9
10use crate::{
11 Error,
12 Fingerprint,
13 HashAlgorithm,
14 Packet,
15 PublicKeyAlgorithm,
16 Result,
17 SignatureType,
18 packet::{
19 Signature,
20 OnePassSig,
21 one_pass_sig::{
22 OnePassSig3,
23 },
24 },
25};
26
27#[derive(PartialEq, Eq, Hash, Clone)]
42pub struct OnePassSig6 {
43 pub(crate) common: OnePassSig3,
44 salt: Vec<u8>,
45 issuer: Fingerprint,
46}
47assert_send_and_sync!(OnePassSig6);
48
49impl TryFrom<OnePassSig> for OnePassSig6 {
50 type Error = anyhow::Error;
51
52 fn try_from(ops: OnePassSig) -> Result<Self> {
53 match ops {
54 OnePassSig::V6(ops) => Ok(ops),
55 ops => Err(
56 Error::InvalidArgument(
57 format!(
58 "Got a v{}, require a v6 one-pass signature",
59 ops.version()))
60 .into()),
61 }
62 }
63}
64
65impl fmt::Debug for OnePassSig6 {
66 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
67 f.debug_struct("OnePassSig6")
68 .field("typ", &self.typ())
69 .field("hash_algo", &self.hash_algo())
70 .field("pk_algo", &self.pk_algo())
71 .field("salt", &crate::fmt::hex::encode(self.salt()))
72 .field("issuer", &self.issuer())
73 .field("last", &self.last())
74 .finish()
75 }
76}
77
78impl OnePassSig6 {
79 pub fn new(typ: SignatureType, issuer: Fingerprint) -> Self {
81 OnePassSig6 {
82 common: OnePassSig3::new(typ),
83 salt: vec![],
84 issuer,
85 }
86 }
87
88 pub fn typ(&self) -> SignatureType {
90 self.common.typ()
91 }
92
93 pub fn set_type(&mut self, t: SignatureType) -> SignatureType {
95 self.common.set_type(t)
96 }
97
98 pub fn pk_algo(&self) -> PublicKeyAlgorithm {
100 self.common.pk_algo()
101 }
102
103 pub fn set_pk_algo(&mut self, algo: PublicKeyAlgorithm) -> PublicKeyAlgorithm {
105 self.common.set_pk_algo(algo)
106 }
107
108 pub fn hash_algo(&self) -> HashAlgorithm {
110 self.common.hash_algo()
111 }
112
113 pub fn set_hash_algo(&mut self, algo: HashAlgorithm) -> HashAlgorithm {
115 self.common.set_hash_algo(algo)
116 }
117
118 pub fn salt(&self) -> &[u8] {
120 &self.salt
121 }
122
123 pub fn set_salt(&mut self, salt: Vec<u8>) -> Vec<u8> {
125 mem::replace(&mut self.salt, salt)
126 }
127
128 pub fn issuer(&self) -> &Fingerprint {
130 &self.issuer
131 }
132
133 pub fn set_issuer(&mut self, issuer: Fingerprint) -> Fingerprint {
135 mem::replace(&mut self.issuer, issuer)
136 }
137
138 pub fn last(&self) -> bool {
140 self.common.last()
141 }
142
143 pub fn set_last(&mut self, last: bool) -> bool {
145 self.common.set_last(last)
146 }
147
148 pub fn last_raw(&self) -> u8 {
150 self.common.last_raw()
151 }
152
153 pub fn set_last_raw(&mut self, last: u8) -> u8 {
155 self.common.set_last_raw(last)
156 }
157}
158
159impl From<OnePassSig6> for OnePassSig {
160 fn from(s: OnePassSig6) -> Self {
161 OnePassSig::V6(s)
162 }
163}
164
165impl From<OnePassSig6> for Packet {
166 fn from(p: OnePassSig6) -> Self {
167 OnePassSig::from(p).into()
168 }
169}
170
171impl<'a> std::convert::TryFrom<&'a Signature> for OnePassSig6 {
172 type Error = anyhow::Error;
173
174 fn try_from(s: &'a Signature) -> Result<Self> {
175 let s = if let Signature::V6(s) = s {
176 s
177 } else {
178 return Err(Error::InvalidArgument(format!(
179 "Can not derive a v6 OnePassSig from a v{} Signature",
180 s.version())).into());
181 };
182
183 let issuer = match s.issuer_fingerprints().next() {
184 Some(i) => i.clone(),
185 None =>
186 return Err(Error::InvalidArgument(
187 "Signature has no issuer fingerprints".into()).into()),
188 };
189 let mut common = OnePassSig3::new(s.typ());
190 common.set_hash_algo(s.hash_algo());
191 common.set_pk_algo(s.pk_algo());
192 Ok(OnePassSig6 {
193 common,
194 salt: s.salt().to_vec(),
195 issuer,
196 })
197 }
198}
199
200#[cfg(test)]
201mod tests {
202 use super::*;
203 use crate::arbitrary_helper::arbitrary_bounded_vec;
204 use crate::parse::Parse;
205 use crate::serialize::MarshalInto;
206
207 impl Arbitrary for OnePassSig6 {
208 fn arbitrary(g: &mut Gen) -> Self {
209 let mut ops = OnePassSig6::new(SignatureType::arbitrary(g),
210 Fingerprint::arbitrary_v6(g));
211 ops.set_hash_algo(HashAlgorithm::arbitrary(g));
212 ops.set_pk_algo(PublicKeyAlgorithm::arbitrary(g));
213 ops.set_last_raw(u8::arbitrary(g));
214 ops.set_salt(arbitrary_bounded_vec(g, 256));
215 ops
216 }
217 }
218
219 quickcheck! {
220 fn roundtrip(p: OnePassSig6) -> bool {
221 let q = OnePassSig6::from_bytes(&p.to_vec().unwrap()).unwrap();
222 assert_eq!(p, q);
223 true
224 }
225 }
226}