pretty_good/
types.rs

1use digest::Digest;
2use failure::Error;
3use yasna::models::ObjectIdentifier;
4
5/// Type for public key algorithms supported by OpenPGP.
6#[derive(Clone, Copy, Debug, PartialEq, Eq)]
7#[repr(u8)]
8pub enum PublicKeyAlgorithm {
9    Rsa = 1,
10    RsaEncryptOnly = 2,
11    RsaSignOnly = 3,
12    ElgamalEncryptOnly = 16,
13    Dsa = 17,
14    EllipticCurve = 18,
15    Ecdsa = 19,
16    Elgamal = 20,
17    DiffieHellman = 21,
18    Unknown = 255,
19}
20
21impl From<u8> for PublicKeyAlgorithm {
22    fn from(val: u8) -> PublicKeyAlgorithm {
23        match val {
24            1 => PublicKeyAlgorithm::Rsa,
25            2 => PublicKeyAlgorithm::RsaEncryptOnly,
26            3 => PublicKeyAlgorithm::RsaSignOnly,
27            16 => PublicKeyAlgorithm::ElgamalEncryptOnly,
28            17 => PublicKeyAlgorithm::Dsa,
29            18 => PublicKeyAlgorithm::EllipticCurve,
30            19 => PublicKeyAlgorithm::Ecdsa,
31            20 => PublicKeyAlgorithm::Elgamal,
32            21 => PublicKeyAlgorithm::DiffieHellman,
33            _ => PublicKeyAlgorithm::Unknown,
34        }
35    }
36}
37
38impl From<PublicKeyAlgorithm> for u8 {
39    fn from(val: PublicKeyAlgorithm) -> u8 {
40        match val {
41            PublicKeyAlgorithm::Rsa => 1,
42            PublicKeyAlgorithm::RsaEncryptOnly => 2,
43            PublicKeyAlgorithm::RsaSignOnly => 3,
44            PublicKeyAlgorithm::ElgamalEncryptOnly => 16,
45            PublicKeyAlgorithm::Dsa => 17,
46            PublicKeyAlgorithm::EllipticCurve => 18,
47            PublicKeyAlgorithm::Ecdsa => 19,
48            PublicKeyAlgorithm::Elgamal => 20,
49            PublicKeyAlgorithm::DiffieHellman => 21,
50            PublicKeyAlgorithm::Unknown => 0xFF,
51        }
52    }
53}
54
55/// Type for hash algorithms supported by OpenPGP.
56#[derive(Clone, Copy, Debug, PartialEq, Eq)]
57#[repr(u8)]
58pub enum HashAlgorithm {
59    Md5 = 1,
60    Sha1 = 2,
61    Ripemd160 = 3,
62    Sha256 = 8,
63    Sha384 = 9,
64    Sha512 = 10,
65    Sha224 = 11,
66    Unknown = 255,
67}
68
69impl From<u8> for HashAlgorithm {
70    fn from(val: u8) -> HashAlgorithm {
71        match val {
72            1 => HashAlgorithm::Md5,
73            2 => HashAlgorithm::Sha1,
74            3 => HashAlgorithm::Ripemd160,
75            8 => HashAlgorithm::Sha256,
76            9 => HashAlgorithm::Sha384,
77            10 => HashAlgorithm::Sha512,
78            11 => HashAlgorithm::Sha224,
79            _ => HashAlgorithm::Unknown,
80        }
81    }
82}
83
84impl From<HashAlgorithm> for u8 {
85    fn from(val: HashAlgorithm) -> u8 {
86        match val {
87            HashAlgorithm::Md5 => 1,
88            HashAlgorithm::Sha1 => 2,
89            HashAlgorithm::Ripemd160 => 3,
90            HashAlgorithm::Sha256 => 8,
91            HashAlgorithm::Sha384 => 9,
92            HashAlgorithm::Sha512 => 10,
93            HashAlgorithm::Sha224 => 11,
94            HashAlgorithm::Unknown => 0xFF,
95        }
96    }
97}
98
99macro_rules! hash {
100    ($res:expr) => (Vec::from($res.as_ref()))
101}
102
103impl HashAlgorithm {
104    pub fn asn1_oid(&self) -> Result<ObjectIdentifier, Error> {
105        let oid = match *self {
106            HashAlgorithm::Md5 => ObjectIdentifier::from_slice(&[1, 2, 840, 113_549, 2, 5]),
107            HashAlgorithm::Sha1 => ObjectIdentifier::from_slice(&[1, 3, 14, 3, 2, 26]),
108            HashAlgorithm::Ripemd160 => ObjectIdentifier::from_slice(&[1, 3, 36, 3, 2, 1]),
109            HashAlgorithm::Sha256 => {
110                ObjectIdentifier::from_slice(&[2, 16, 840, 1, 101, 3, 4, 2, 1])
111            }
112            HashAlgorithm::Sha384 => {
113                ObjectIdentifier::from_slice(&[2, 16, 840, 1, 101, 3, 4, 2, 2])
114            }
115            HashAlgorithm::Sha512 => {
116                ObjectIdentifier::from_slice(&[2, 16, 840, 1, 101, 3, 4, 2, 3])
117            }
118            HashAlgorithm::Sha224 => {
119                ObjectIdentifier::from_slice(&[2, 16, 840, 1, 101, 3, 4, 2, 4])
120            }
121            HashAlgorithm::Unknown => bail!(AlgorithmError::HashAlgorithmError),
122        };
123
124        Ok(oid)
125    }
126
127    pub fn hash<T: AsRef<[u8]>>(&self, contents: T) -> Result<Vec<u8>, Error> {
128        let contents = contents.as_ref();
129        let hash_result = match *self {
130            HashAlgorithm::Md5 => hash!(::md5::Md5::digest(contents)),
131            HashAlgorithm::Sha1 => hash!(::sha1::Sha1::digest(contents)),
132            HashAlgorithm::Ripemd160 => hash!(::ripemd160::Ripemd160::digest(contents)),
133            HashAlgorithm::Sha256 => hash!(::sha2::Sha256::digest(contents)),
134            HashAlgorithm::Sha384 => hash!(::sha2::Sha384::digest(contents)),
135            HashAlgorithm::Sha512 => hash!(::sha2::Sha512::digest(contents)),
136            HashAlgorithm::Sha224 => hash!(::sha2::Sha224::digest(contents)),
137            HashAlgorithm::Unknown => bail!(AlgorithmError::HashAlgorithmError),
138        };
139
140        Ok(hash_result)
141    }
142}
143
144/// Type for symmetric key algorithms supported by OpenPGP.
145#[derive(Clone, Copy, Debug, PartialEq, Eq)]
146#[repr(u8)]
147pub enum SymmetricKeyAlgorithm {
148    Plaintext = 0,
149    Idea = 1,
150    TripleDes = 2,
151    Cast5 = 3,
152    Blowfish = 4,
153    Aes128 = 7,
154    Aes192 = 8,
155    Aes256 = 9,
156    Twofish = 10,
157    Reserved,
158    Unknown,
159}
160
161impl SymmetricKeyAlgorithm {
162    /// The block size of this cipher in bytes.
163    pub fn block_bytes(&self) -> usize {
164        match *self {
165            SymmetricKeyAlgorithm::Plaintext => 0,
166            SymmetricKeyAlgorithm::Idea => 8,
167            SymmetricKeyAlgorithm::TripleDes => 8,
168            SymmetricKeyAlgorithm::Cast5 => 8,
169            SymmetricKeyAlgorithm::Blowfish => 8,
170            SymmetricKeyAlgorithm::Aes128 | SymmetricKeyAlgorithm::Aes192 | SymmetricKeyAlgorithm::Aes256 => 16,
171            SymmetricKeyAlgorithm::Twofish => 16,
172            SymmetricKeyAlgorithm::Reserved | SymmetricKeyAlgorithm::Unknown => 0,
173        }
174    }
175}
176
177impl From<u8> for SymmetricKeyAlgorithm {
178    fn from(val: u8) -> SymmetricKeyAlgorithm {
179        match val {
180            0 => SymmetricKeyAlgorithm::Plaintext,
181            1 => SymmetricKeyAlgorithm::Idea,
182            2 => SymmetricKeyAlgorithm::TripleDes,
183            3 => SymmetricKeyAlgorithm::Cast5,
184            4 => SymmetricKeyAlgorithm::Blowfish,
185            7 => SymmetricKeyAlgorithm::Aes128,
186            8 => SymmetricKeyAlgorithm::Aes192,
187            9 => SymmetricKeyAlgorithm::Aes256,
188            10 => SymmetricKeyAlgorithm::Twofish,
189            5 | 6 => SymmetricKeyAlgorithm::Reserved,
190            _ => SymmetricKeyAlgorithm::Unknown,
191        }
192    }
193}
194
195#[derive(Clone, Copy, Debug, PartialEq, Eq)]
196#[repr(u32)]
197pub(crate) enum NomError {
198    Unimplemented = 1,
199    UseOfReservedValue = 2,
200    IntegerReadError = 3,
201    Unknown,
202}
203
204impl From<u32> for NomError {
205    fn from(val: u32) -> NomError {
206        match val {
207            1 => NomError::Unimplemented,
208            2 => NomError::UseOfReservedValue,
209            3 => NomError::IntegerReadError,
210            _ => NomError::Unknown,
211        }
212    }
213}
214
215/// Error type for [`PublicKeyAlgorithm`] and [`HashAlgorithm`]-related operations.
216///
217/// [`PublicKeyAlgorithm`]: enum.PublicKeyAlgorithm.html
218/// [`HashAlgorithm`]: enum.HashAlgorithm.html
219#[derive(Clone, Debug, Fail)]
220pub enum AlgorithmError {
221    #[fail(display = "unknown public key algorithm")]
222    PublicKeyAlgorithmError,
223    #[fail(display = "unknown hash algorithm")]
224    HashAlgorithmError,
225}