cmail_rpgp/types/
mod.rs

1mod compression;
2mod fingerprint;
3mod key_id;
4mod mpi;
5mod packet;
6mod params;
7mod public_key;
8mod revocation_key;
9mod s2k;
10mod secret_key;
11mod secret_key_repr;
12mod user;
13
14use log::debug;
15
16pub use self::compression::*;
17pub use self::fingerprint::*;
18pub use self::key_id::*;
19pub use self::mpi::*;
20pub use self::packet::*;
21pub use self::params::*;
22pub use self::public_key::*;
23pub use self::revocation_key::*;
24pub use self::s2k::*;
25pub use self::secret_key::*;
26pub use self::secret_key_repr::*;
27pub use self::user::*;
28use crate::crypto::sym::SymmetricKeyAlgorithm;
29
30/// An OpenPGP cryptographic signature.
31///
32/// It is an element of a [crate::packet::Signature] packet.
33/// Historically, cryptographic signatures in OpenPGP were encoded as [crate::types::Mpi],
34/// however, in RFC 9580, native encoding is used for the modern Ed25519 and Ed448 signatures.
35///
36/// This type can represent both flavors of cryptographic signature data.
37#[derive(Debug, PartialEq, Eq, Clone)]
38pub enum SignatureBytes {
39    /// A cryptographic signature that is represented as a set of [Mpi]s.
40    ///
41    /// This format has been used for all OpenPGP cryptographic signatures in RFCs 4880 and 6637.
42    Mpis(Vec<Mpi>),
43
44    /// A cryptographic signature that is represented in native format.
45    ///
46    /// This format was introduced in RFC 9580 and is currently only used for Ed25519 and Ed448.
47    Native(Vec<u8>),
48}
49
50impl SignatureBytes {
51    pub(crate) fn to_writer<W: std::io::Write>(&self, writer: &mut W) -> crate::errors::Result<()> {
52        use crate::ser::Serialize;
53
54        match &self {
55            SignatureBytes::Mpis(mpis) => {
56                // the actual signature
57                for val in mpis {
58                    debug!("writing: {}", hex::encode(val));
59                    val.to_writer(writer)?;
60                }
61            }
62            SignatureBytes::Native(sig) => {
63                writer.write_all(sig)?;
64            }
65        }
66
67        Ok(())
68    }
69}
70
71impl<'a> TryFrom<&'a SignatureBytes> for &'a [Mpi] {
72    type Error = crate::errors::Error;
73
74    fn try_from(value: &'a SignatureBytes) -> std::result::Result<Self, Self::Error> {
75        match value {
76            SignatureBytes::Mpis(mpis) => Ok(mpis),
77
78            // We reject this operation because it doesn't fit with the intent of the Sig abstraction
79            SignatureBytes::Native(_) => bail!("Native Sig can't be transformed into Mpis"),
80        }
81    }
82}
83
84impl<'a> TryFrom<&'a SignatureBytes> for &'a [u8] {
85    type Error = crate::errors::Error;
86
87    fn try_from(value: &'a SignatureBytes) -> std::result::Result<Self, Self::Error> {
88        match value {
89            // We reject this operation because it doesn't fit with the intent of the Sig abstraction
90            SignatureBytes::Mpis(_) => bail!("Mpi-based Sig can't be transformed into &[u8]"),
91
92            SignatureBytes::Native(native) => Ok(native),
93        }
94    }
95}
96
97impl From<Vec<Mpi>> for SignatureBytes {
98    fn from(value: Vec<Mpi>) -> Self {
99        SignatureBytes::Mpis(value)
100    }
101}
102
103impl From<Vec<u8>> for SignatureBytes {
104    fn from(value: Vec<u8>) -> Self {
105        SignatureBytes::Native(value)
106    }
107}
108
109/// Select which type of encrypted session key data should be produced in an encryption step
110#[derive(Debug)]
111pub enum EskType {
112    /// V3 PKESK or V4 SKESK (these are used in RFC 4880 and 2440)
113    V3_4,
114
115    /// V6 PKESK or SKESK (introduced in RFC 9580)
116    V6,
117}
118
119/// Values comprising a Public Key Encrypted Session Key
120#[derive(Clone, Debug, Eq, PartialEq)]
121pub enum PkeskBytes {
122    Rsa {
123        mpi: Mpi,
124    },
125    Elgamal {
126        first: Mpi,
127        second: Mpi,
128    },
129    Ecdh {
130        public_point: Mpi,
131        encrypted_session_key: Vec<u8>,
132    },
133    X25519 {
134        /// Ephemeral X25519 public key (32 bytes).
135        ephemeral: [u8; 32],
136
137        /// Encrypted and wrapped session key.
138        session_key: Vec<u8>,
139
140        /// Set for v3 PKESK only (the sym_alg is not encrypted with the session key for X25519)
141        sym_alg: Option<SymmetricKeyAlgorithm>,
142    },
143    X448 {
144        /// Ephemeral X448 public key (56 bytes).
145        ephemeral: [u8; 56],
146
147        /// Encrypted and wrapped session key.
148        session_key: Vec<u8>,
149
150        /// Set for v3 PKESK only (the sym_alg is not encrypted with the session key for X448)
151        sym_alg: Option<SymmetricKeyAlgorithm>,
152    },
153    Other,
154}