sequoia_openpgp/packet/
one_pass_sig.rs

1//! One-pass signature packets.
2//!
3//! See [One-Pass Signature Packet] for details.
4//!
5//! [One-Pass Signature Packet]: https://www.rfc-editor.org/rfc/rfc9580.html#name-one-pass-signature-packet-t
6
7#[cfg(test)]
8use quickcheck::{Arbitrary, Gen};
9
10use crate::{
11    Error,
12    KeyHandle,
13    Result,
14    packet::{
15        Packet,
16        Signature,
17    },
18    types::{
19        SignatureType,
20        PublicKeyAlgorithm,
21        HashAlgorithm,
22    },
23};
24
25mod v3;
26pub use v3::OnePassSig3;
27mod v6;
28pub use v6::OnePassSig6;
29
30/// Holds a one-pass signature packet.
31///
32/// See [One-Pass Signature Packet] for details.
33///
34/// A `OnePassSig` packet is not normally instantiated directly.  In
35/// most cases, you'll create one as a side effect of signing a
36/// message using the [streaming serializer], or parsing a signed
37/// message using the [`PacketParser`].
38///
39/// [One-Pass Signature Packet]: https://www.rfc-editor.org/rfc/rfc9580.html#name-one-pass-signature-packet-t
40/// [`PacketParser`]: crate::parse::PacketParser
41/// [streaming serializer]: crate::serialize::stream
42#[non_exhaustive]
43#[derive(PartialEq, Eq, Hash, Clone, Debug)]
44pub enum OnePassSig {
45    /// OnePassSig packet version 3.
46    V3(OnePassSig3),
47
48    /// OnePassSig packet version 6.
49    V6(OnePassSig6),
50}
51assert_send_and_sync!(OnePassSig);
52
53impl OnePassSig {
54    /// Gets the version.
55    pub fn version(&self) -> u8 {
56        match self {
57            OnePassSig::V3(_) => 3,
58            OnePassSig::V6(_) => 6,
59        }
60    }
61
62    /// Gets the signature type.
63    pub fn typ(&self) -> SignatureType {
64        match self {
65            OnePassSig::V3(p) => p.typ(),
66            OnePassSig::V6(p) => p.typ(),
67        }
68    }
69
70    /// Gets the public key algorithm.
71    pub fn pk_algo(&self) -> PublicKeyAlgorithm {
72        match self {
73            OnePassSig::V3(p) => p.pk_algo(),
74            OnePassSig::V6(p) => p.pk_algo(),
75        }
76    }
77
78    /// Gets the hash algorithm.
79    pub fn hash_algo(&self) -> HashAlgorithm {
80        match self {
81            OnePassSig::V3(p) => p.hash_algo(),
82            OnePassSig::V6(p) => p.hash_algo(),
83        }
84    }
85
86    /// Gets the salt, if any.
87    pub fn salt(&self) -> Option<&[u8]> {
88        match self {
89            OnePassSig::V3(_) => None,
90            OnePassSig::V6(p) => Some(p.salt()),
91        }
92    }
93
94    /// Gets the issuer.
95    pub fn issuer(&self) -> KeyHandle {
96        match self {
97            OnePassSig::V3(p) => p.issuer().into(),
98            OnePassSig::V6(p) => p.issuer().into(),
99        }
100    }
101
102    /// Gets the last flag.
103    pub fn last(&self) -> bool {
104        match self {
105            OnePassSig::V3(p) => p.last(),
106            OnePassSig::V6(p) => p.last(),
107        }
108    }
109
110    /// Sets the last flag.
111    pub fn set_last(&mut self, last: bool) -> bool {
112        match self {
113            OnePassSig::V3(p) => p.set_last(last),
114            OnePassSig::V6(p) => p.set_last(last),
115        }
116    }
117
118    /// Gets the raw value of the last flag.
119    pub fn last_raw(&self) -> u8 {
120        match self {
121            OnePassSig::V3(p) => p.last_raw(),
122            OnePassSig::V6(p) => p.last_raw(),
123        }
124    }
125}
126
127impl From<OnePassSig> for Packet {
128    fn from(s: OnePassSig) -> Self {
129        Packet::OnePassSig(s)
130    }
131}
132
133impl<'a> std::convert::TryFrom<&'a Signature> for OnePassSig {
134    type Error = anyhow::Error;
135
136    fn try_from(s: &'a Signature) -> Result<Self> {
137        match s.version() {
138            3 | 4 => OnePassSig3::try_from(s).map(Into::into),
139            6 => OnePassSig6::try_from(s).map(Into::into),
140            n => Err(Error::InvalidOperation(
141                format!("Unsupported signature version {}", n)).into()),
142        }
143    }
144}
145
146#[cfg(test)]
147impl Arbitrary for super::OnePassSig {
148    fn arbitrary(g: &mut Gen) -> Self {
149        if Arbitrary::arbitrary(g) {
150            OnePassSig3::arbitrary(g).into()
151        } else {
152            OnePassSig6::arbitrary(g).into()
153        }
154    }
155}