ts_crypto/known/
verifying.rs

1//! Known signing key types
2
3use core::marker::PhantomData;
4
5use ::rsa::{RsaPrivateKey, traits::PublicKeyParts};
6use const_oid::db::{
7    rfc5753::ID_EC_PUBLIC_KEY,
8    rfc5912::{RSA_ENCRYPTION, SECP_256_R_1, SECP_384_R_1, SECP_521_R_1},
9    rfc8410::{ID_ED_448, ID_ED_25519},
10};
11use der::{Decode, asn1::OctetString};
12use p256::NistP256;
13use p384::NistP384;
14use p521::NistP521;
15use pkcs8::PrivateKeyInfoRef;
16use sec1::EcPrivateKey;
17use spki::SubjectPublicKeyInfoRef;
18
19use crate::{
20    FromDer, VerifySignature,
21    edwards::{self, Curve448, Curve25519},
22    elliptic,
23    rsa::{self, Pkcs256, Pkcs384, Pkcs512, Pss256, Pss384, Pss512},
24};
25
26/// `ECDSA` using the prime-256 curve
27pub type ES256 = elliptic::VerifyingKey<NistP256>;
28/// `ECDSA` using the prime-384 curve
29pub type ES384 = elliptic::VerifyingKey<NistP384>;
30/// `ECDSA` using the prime-521 curve
31pub type ES512 = elliptic::VerifyingKey<NistP521>;
32/// `EdDSA` using curve 25519
33pub type Ed25519 = edwards::VerifyingKey<Curve25519>;
34/// `EdDSA` using curve 448
35pub type Ed448 = edwards::VerifyingKey<Curve448>;
36/// 256 byte `RSA` PKCS1v1.5 padding and SHA-256
37pub type RS256 = rsa::VerifyingKey<Pkcs256>;
38/// 384 byte `RSA` PKCS1v1.5 padding and SHA-384
39pub type RS384 = rsa::VerifyingKey<Pkcs384>;
40/// 512 byte `RSA` PKCS1v1.5 padding and SHA-512
41pub type RS512 = rsa::VerifyingKey<Pkcs512>;
42/// 256 byte `RSA` `PSS` padding and SHA-256
43pub type PS256 = rsa::VerifyingKey<Pss256>;
44/// 384 byte `RSA` `PSS` padding and SHA-384
45pub type PS384 = rsa::VerifyingKey<Pss384>;
46/// 512 byte `RSA` `PSS` padding and SHA-512
47pub type PS512 = rsa::VerifyingKey<Pss512>;
48
49/// A known elliptic key
50#[allow(clippy::exhaustive_enums)]
51pub enum EllipticKey {
52    /// `ECDSA` using the prime-256 curve
53    ES256(ES256),
54    /// `ECDSA` using the prime-384 curve
55    ES384(ES384),
56    /// `ECDSA` using the prime-521 curve
57    ES512(ES512),
58}
59
60impl elliptic::Parameters for EllipticKey {
61    fn x(&self) -> Vec<u8> {
62        match &self {
63            Self::ES256(key) => key.x(),
64            Self::ES384(key) => key.x(),
65            Self::ES512(key) => key.x(),
66        }
67    }
68
69    fn y(&self) -> Vec<u8> {
70        match &self {
71            Self::ES256(key) => key.y(),
72            Self::ES384(key) => key.y(),
73            Self::ES512(key) => key.y(),
74        }
75    }
76}
77
78/// A known Edwards key
79#[allow(clippy::exhaustive_enums)]
80#[allow(clippy::large_enum_variant)]
81pub enum EdwardsKey {
82    /// `EdDSA` using curve 25519
83    Ed25519(Ed25519),
84    /// `EdDSA` using curve 448
85    Ed448(Ed448),
86}
87
88impl edwards::Parameters for EdwardsKey {
89    fn raw_bytes(&self) -> &[u8] {
90        match &self {
91            Self::Ed25519(key) => key.raw_bytes(),
92            Self::Ed448(key) => key.raw_bytes(),
93        }
94    }
95}
96
97/// A known RSA key
98#[allow(clippy::exhaustive_enums)]
99pub enum RsaKey {
100    /// 256 byte `RSA` PKCS1v1.5 padding and SHA-256
101    RS256(RS256),
102    /// 384 byte `RSA` PKCS1v1.5 padding and SHA-384
103    RS384(RS384),
104    /// 512 byte `RSA` PKCS1v1.5 padding and SHA-512
105    RS512(RS512),
106    /// 256 byte `RSA` `PSS` padding and SHA-256
107    PS256(PS256),
108    /// 384 byte `RSA` `PSS` padding and SHA-384
109    PS384(PS384),
110    /// 512 byte `RSA` `PSS` padding and SHA-512
111    PS512(PS512),
112}
113
114impl rsa::Parameters for RsaKey {
115    fn modulus(&self) -> Vec<u8> {
116        match &self {
117            Self::RS256(key) => key.modulus(),
118            Self::RS384(key) => key.modulus(),
119            Self::RS512(key) => key.modulus(),
120            Self::PS256(key) => key.modulus(),
121            Self::PS384(key) => key.modulus(),
122            Self::PS512(key) => key.modulus(),
123        }
124    }
125
126    fn exponent(&self) -> Vec<u8> {
127        match &self {
128            Self::RS256(key) => key.exponent(),
129            Self::RS384(key) => key.exponent(),
130            Self::RS512(key) => key.exponent(),
131            Self::PS256(key) => key.exponent(),
132            Self::PS384(key) => key.exponent(),
133            Self::PS512(key) => key.exponent(),
134        }
135    }
136
137    fn size(&self) -> usize {
138        match &self {
139            Self::RS256(key) => key.size(),
140            Self::RS384(key) => key.size(),
141            Self::RS512(key) => key.size(),
142            Self::PS256(key) => key.size(),
143            Self::PS384(key) => key.size(),
144            Self::PS512(key) => key.size(),
145        }
146    }
147}
148
149/// A known signing key
150#[allow(clippy::exhaustive_enums)]
151#[allow(clippy::large_enum_variant)]
152pub enum VerifyingKey {
153    /// Elliptic key
154    Elliptic(EllipticKey),
155    /// Edwards key
156    Edwards(EdwardsKey),
157    /// RSA key
158    Rsa(RsaKey),
159}
160
161impl VerifySignature for RsaKey {
162    fn verifies_signature(&self, signature: &[u8], message: &[u8]) -> bool {
163        match &self {
164            Self::RS256(key) => key.verifies_signature(signature, message),
165            Self::RS384(key) => key.verifies_signature(signature, message),
166            Self::RS512(key) => key.verifies_signature(signature, message),
167            Self::PS256(key) => key.verifies_signature(signature, message),
168            Self::PS384(key) => key.verifies_signature(signature, message),
169            Self::PS512(key) => key.verifies_signature(signature, message),
170        }
171    }
172}
173
174impl VerifySignature for EllipticKey {
175    fn verifies_signature(&self, signature: &[u8], message: &[u8]) -> bool {
176        match &self {
177            Self::ES256(key) => key.verifies_signature(signature, message),
178            Self::ES384(key) => key.verifies_signature(signature, message),
179            Self::ES512(key) => key.verifies_signature(signature, message),
180        }
181    }
182}
183impl VerifySignature for EdwardsKey {
184    fn verifies_signature(&self, signature: &[u8], message: &[u8]) -> bool {
185        match &self {
186            Self::Ed25519(key) => key.verifies_signature(signature, message),
187            Self::Ed448(key) => key.verifies_signature(signature, message),
188        }
189    }
190}
191impl VerifySignature for VerifyingKey {
192    fn verifies_signature(&self, signature: &[u8], message: &[u8]) -> bool {
193        match &self {
194            Self::Elliptic(key) => key.verifies_signature(signature, message),
195            Self::Edwards(key) => key.verifies_signature(signature, message),
196            Self::Rsa(key) => key.verifies_signature(signature, message),
197        }
198    }
199}
200
201impl VerifyingKey {
202    /// Create a key from a `DER` encoded Subject Public Key Info structure.
203    fn from_spki_der(der: &[u8]) -> Option<Self> {
204        let spki = SubjectPublicKeyInfoRef::from_der(der).ok()?;
205        let key = spki.subject_public_key.as_bytes()?;
206        match spki.algorithm.oid {
207            ID_EC_PUBLIC_KEY => {
208                let curve = spki.algorithm.parameters_oid().ok()?;
209                match curve {
210                    SECP_256_R_1 => {
211                        let key = p256::ecdsa::VerifyingKey::try_from(key).ok()?;
212                        Some(Self::Elliptic(EllipticKey::ES256(ES256 { key })))
213                    }
214                    SECP_384_R_1 => {
215                        let key = p384::ecdsa::VerifyingKey::try_from(key).ok()?;
216                        Some(Self::Elliptic(EllipticKey::ES384(ES384 { key })))
217                    }
218                    SECP_521_R_1 => {
219                        let key = p521::ecdsa::VerifyingKey::try_from(key).ok()?;
220                        Some(Self::Elliptic(EllipticKey::ES512(ES512 { key })))
221                    }
222                    _ => None,
223                }
224            }
225            RSA_ENCRYPTION => {
226                let key = ::rsa::RsaPublicKey::try_from(spki).ok()?;
227                match key.size() {
228                    256 => Some(Self::Rsa(RsaKey::RS256(RS256 {
229                        key,
230                        scheme: PhantomData,
231                    }))),
232                    384 => Some(Self::Rsa(RsaKey::RS384(RS384 {
233                        key,
234                        scheme: PhantomData,
235                    }))),
236                    512 => Some(Self::Rsa(RsaKey::RS512(RS512 {
237                        key,
238                        scheme: PhantomData,
239                    }))),
240                    _ => None,
241                }
242            }
243            ID_ED_25519 => {
244                let bytes = spki.subject_public_key.as_bytes()?.try_into().ok()?;
245                let key = ed25519_dalek::VerifyingKey::from_bytes(bytes).ok()?;
246                Some(Self::Edwards(EdwardsKey::Ed25519(Ed25519 { key })))
247            }
248            ID_ED_448 => {
249                let bytes = spki.subject_public_key.as_bytes()?.try_into().ok()?;
250                let key = ed448_goldilocks::VerifyingKey::from_bytes(bytes).ok()?;
251                Some(Self::Edwards(EdwardsKey::Ed448(Ed448 { key })))
252            }
253            _ => None,
254        }
255    }
256
257    /// Create a key from a `pkcs8` structure
258    fn from_pkcs8_der(der: &[u8]) -> Option<Self> {
259        let pkcs = PrivateKeyInfoRef::from_der(der).ok()?;
260        match pkcs.algorithm.oid {
261            ID_EC_PUBLIC_KEY => {
262                let curve = pkcs.algorithm.parameters_oid().ok()?;
263                match curve {
264                    SECP_256_R_1 => {
265                        let key = p256::ecdsa::SigningKey::try_from(pkcs).ok()?;
266                        let key = *key.verifying_key();
267                        Some(Self::Elliptic(EllipticKey::ES256(ES256 { key })))
268                    }
269                    SECP_384_R_1 => {
270                        let key = p384::ecdsa::SigningKey::try_from(pkcs).ok()?;
271                        let key = *key.verifying_key();
272                        Some(Self::Elliptic(EllipticKey::ES384(ES384 { key })))
273                    }
274                    SECP_521_R_1 => {
275                        let key = p521::ecdsa::SigningKey::try_from(pkcs).ok()?;
276                        let key = *key.verifying_key();
277                        Some(Self::Elliptic(EllipticKey::ES512(ES512 { key })))
278                    }
279                    _ => None,
280                }
281            }
282            RSA_ENCRYPTION => {
283                let key = RsaPrivateKey::try_from(pkcs).ok()?;
284                let key = key.to_public_key();
285                match key.size() {
286                    256 => Some(Self::Rsa(RsaKey::RS256(RS256 {
287                        key,
288                        scheme: PhantomData,
289                    }))),
290                    384 => Some(Self::Rsa(RsaKey::RS384(RS384 {
291                        key,
292                        scheme: PhantomData,
293                    }))),
294                    512 => Some(Self::Rsa(RsaKey::RS512(RS512 {
295                        key,
296                        scheme: PhantomData,
297                    }))),
298                    _ => None,
299                }
300            }
301            ID_ED_25519 => {
302                let octet_string = OctetString::from_der(pkcs.private_key.as_bytes()).ok()?;
303                let key = ed25519_dalek::SecretKey::try_from(octet_string.as_bytes()).ok()?;
304                let key = ed25519_dalek::SigningKey::from(key).verifying_key();
305                Some(Self::Edwards(EdwardsKey::Ed25519(Ed25519 { key })))
306            }
307            ID_ED_448 => {
308                // https://github.com/RustCrypto/elliptic-curves/issues/1326
309                let octet_string = OctetString::from_der(pkcs.private_key.as_bytes()).ok()?;
310                let key = ed448_goldilocks::SecretKey::try_from(octet_string.as_bytes()).ok()?;
311                let key = ed448_goldilocks::SigningKey::from(key).verifying_key();
312                Some(Self::Edwards(EdwardsKey::Ed448(Ed448 { key })))
313            }
314            _ => None,
315        }
316    }
317
318    /// Create a key from a `sec1` EC private key
319    fn from_ec_der(der: &[u8]) -> Option<Self> {
320        let key = EcPrivateKey::from_der(der).ok()?;
321        let curve = key.parameters?.named_curve()?;
322        match curve {
323            SECP_256_R_1 => {
324                let key = p256::ecdsa::SigningKey::from_slice(key.private_key).ok()?;
325                let key = *key.verifying_key();
326                Some(Self::Elliptic(EllipticKey::ES256(ES256 { key })))
327            }
328            SECP_384_R_1 => {
329                let key = p384::ecdsa::SigningKey::from_slice(key.private_key).ok()?;
330                let key = *key.verifying_key();
331                Some(Self::Elliptic(EllipticKey::ES384(ES384 { key })))
332            }
333            SECP_521_R_1 => {
334                let key = p521::ecdsa::SigningKey::from_slice(key.private_key).ok()?;
335                let key = *key.verifying_key();
336                Some(Self::Elliptic(EllipticKey::ES512(ES512 { key })))
337            }
338            _ => None,
339        }
340    }
341}
342
343impl FromDer for VerifyingKey {
344    #[allow(clippy::manual_map)]
345    fn from_der(der: &[u8]) -> Option<Self> {
346        if let Some(key) = Self::from_spki_der(der) {
347            Some(key)
348        } else if let Some(key) = Self::from_pkcs8_der(der) {
349            Some(key)
350        } else if let Some(key) = Self::from_ec_der(der) {
351            Some(key)
352        } else {
353            None
354        }
355    }
356}