ts_crypto/known/
verifying.rs

1//! Known signing key types
2
3use core::marker::PhantomData;
4
5use ::rsa::{
6    RsaPrivateKey,
7    pkcs1::{DecodeRsaPrivateKey, DecodeRsaPublicKey},
8    traits::PublicKeyParts,
9};
10use const_oid::db::{
11    rfc5753::ID_EC_PUBLIC_KEY,
12    rfc5912::{RSA_ENCRYPTION, SECP_256_R_1, SECP_384_R_1, SECP_521_R_1},
13    rfc8410::{ID_ED_448, ID_ED_25519},
14};
15use der::{Decode, asn1::OctetString};
16use p256::NistP256;
17use p384::NistP384;
18use p521::NistP521;
19use pkcs8::PrivateKeyInfoRef;
20use sec1::EcPrivateKey;
21use spki::SubjectPublicKeyInfoRef;
22
23use crate::{
24    FromDer, VerifySignature,
25    edwards::{self, Curve448, Curve25519},
26    elliptic,
27    rsa::{self, Pkcs, Pss, Scheme, SetScheme, U256, U384, U512},
28};
29
30/// `ECDSA` using the prime-256 curve
31pub type ES256 = elliptic::VerifyingKey<NistP256>;
32/// `ECDSA` using the prime-384 curve
33pub type ES384 = elliptic::VerifyingKey<NistP384>;
34/// `ECDSA` using the prime-521 curve
35pub type ES512 = elliptic::VerifyingKey<NistP521>;
36/// `EdDSA` using curve 25519
37pub type Ed25519 = edwards::VerifyingKey<Curve25519>;
38/// `EdDSA` using curve 448
39pub type Ed448 = edwards::VerifyingKey<Curve448>;
40/// 256 byte `RSA` PKCS1v1.5 padding and SHA-256
41pub type RS256 = rsa::VerifyingKey<Pkcs, U256>;
42/// 384 byte `RSA` PKCS1v1.5 padding and SHA-384
43pub type RS384 = rsa::VerifyingKey<Pkcs, U384>;
44/// 512 byte `RSA` PKCS1v1.5 padding and SHA-512
45pub type RS512 = rsa::VerifyingKey<Pkcs, U512>;
46/// 256 byte `RSA` `PSS` padding and SHA-256
47pub type PS256 = rsa::VerifyingKey<Pss, U256>;
48/// 384 byte `RSA` `PSS` padding and SHA-384
49pub type PS384 = rsa::VerifyingKey<Pss, U384>;
50/// 512 byte `RSA` `PSS` padding and SHA-512
51pub type PS512 = rsa::VerifyingKey<Pss, U512>;
52
53/// A known elliptic key
54#[allow(clippy::exhaustive_enums)]
55pub enum EllipticKey {
56    /// `ECDSA` using the prime-256 curve
57    ES256(ES256),
58    /// `ECDSA` using the prime-384 curve
59    ES384(ES384),
60    /// `ECDSA` using the prime-521 curve
61    ES512(ES512),
62}
63
64impl elliptic::Parameters for EllipticKey {
65    fn x(&self) -> Vec<u8> {
66        match &self {
67            Self::ES256(key) => key.x(),
68            Self::ES384(key) => key.x(),
69            Self::ES512(key) => key.x(),
70        }
71    }
72
73    fn y(&self) -> Vec<u8> {
74        match &self {
75            Self::ES256(key) => key.y(),
76            Self::ES384(key) => key.y(),
77            Self::ES512(key) => key.y(),
78        }
79    }
80}
81
82/// A known Edwards key
83#[allow(clippy::exhaustive_enums)]
84#[allow(clippy::large_enum_variant)]
85pub enum EdwardsKey {
86    /// `EdDSA` using curve 25519
87    Ed25519(Ed25519),
88    /// `EdDSA` using curve 448
89    Ed448(Ed448),
90}
91
92impl edwards::Parameters for EdwardsKey {
93    fn raw_bytes(&self) -> &[u8] {
94        match &self {
95            Self::Ed25519(key) => key.raw_bytes(),
96            Self::Ed448(key) => key.raw_bytes(),
97        }
98    }
99}
100
101/// A known RSA key
102#[allow(clippy::exhaustive_enums)]
103pub enum RsaKey {
104    /// 256 byte `RSA` PKCS1v1.5 padding and SHA-256
105    RS256(RS256),
106    /// 384 byte `RSA` PKCS1v1.5 padding and SHA-384
107    RS384(RS384),
108    /// 512 byte `RSA` PKCS1v1.5 padding and SHA-512
109    RS512(RS512),
110    /// 256 byte `RSA` `PSS` padding and SHA-256
111    PS256(PS256),
112    /// 384 byte `RSA` `PSS` padding and SHA-384
113    PS384(PS384),
114    /// 512 byte `RSA` `PSS` padding and SHA-512
115    PS512(PS512),
116}
117
118impl rsa::Parameters for RsaKey {
119    fn modulus(&self) -> Vec<u8> {
120        match &self {
121            Self::RS256(key) => key.modulus(),
122            Self::RS384(key) => key.modulus(),
123            Self::RS512(key) => key.modulus(),
124            Self::PS256(key) => key.modulus(),
125            Self::PS384(key) => key.modulus(),
126            Self::PS512(key) => key.modulus(),
127        }
128    }
129
130    fn exponent(&self) -> Vec<u8> {
131        match &self {
132            Self::RS256(key) => key.exponent(),
133            Self::RS384(key) => key.exponent(),
134            Self::RS512(key) => key.exponent(),
135            Self::PS256(key) => key.exponent(),
136            Self::PS384(key) => key.exponent(),
137            Self::PS512(key) => key.exponent(),
138        }
139    }
140
141    fn size(&self) -> usize {
142        match &self {
143            Self::RS256(key) => key.size(),
144            Self::RS384(key) => key.size(),
145            Self::RS512(key) => key.size(),
146            Self::PS256(key) => key.size(),
147            Self::PS384(key) => key.size(),
148            Self::PS512(key) => key.size(),
149        }
150    }
151}
152
153/// A known signing key
154#[allow(clippy::exhaustive_enums)]
155#[allow(clippy::large_enum_variant)]
156pub enum VerifyingKey {
157    /// Elliptic key
158    Elliptic(EllipticKey),
159    /// Edwards key
160    Edwards(EdwardsKey),
161    /// RSA key
162    Rsa(RsaKey),
163}
164
165impl<S: Scheme> SetScheme<S> for RsaKey {
166    type Output = Self;
167
168    fn set_scheme(self) -> Self::Output {
169        match self {
170            Self::RS256(key) => Self::PS256(key.set_scheme()),
171            Self::RS384(key) => Self::PS384(key.set_scheme()),
172            Self::RS512(key) => Self::PS512(key.set_scheme()),
173            Self::PS256(key) => Self::RS256(key.set_scheme()),
174            Self::PS384(key) => Self::RS384(key.set_scheme()),
175            Self::PS512(key) => Self::RS512(key.set_scheme()),
176        }
177    }
178}
179
180impl VerifySignature for RsaKey {
181    fn verifies_signature(&self, signature: &[u8], message: &[u8]) -> bool {
182        match &self {
183            Self::RS256(key) => key.verifies_signature(signature, message),
184            Self::RS384(key) => key.verifies_signature(signature, message),
185            Self::RS512(key) => key.verifies_signature(signature, message),
186            Self::PS256(key) => key.verifies_signature(signature, message),
187            Self::PS384(key) => key.verifies_signature(signature, message),
188            Self::PS512(key) => key.verifies_signature(signature, message),
189        }
190    }
191}
192
193impl VerifySignature for EllipticKey {
194    fn verifies_signature(&self, signature: &[u8], message: &[u8]) -> bool {
195        match &self {
196            Self::ES256(key) => key.verifies_signature(signature, message),
197            Self::ES384(key) => key.verifies_signature(signature, message),
198            Self::ES512(key) => key.verifies_signature(signature, message),
199        }
200    }
201}
202impl VerifySignature for EdwardsKey {
203    fn verifies_signature(&self, signature: &[u8], message: &[u8]) -> bool {
204        match &self {
205            Self::Ed25519(key) => key.verifies_signature(signature, message),
206            Self::Ed448(key) => key.verifies_signature(signature, message),
207        }
208    }
209}
210impl VerifySignature for VerifyingKey {
211    fn verifies_signature(&self, signature: &[u8], message: &[u8]) -> bool {
212        match &self {
213            Self::Elliptic(key) => key.verifies_signature(signature, message),
214            Self::Edwards(key) => key.verifies_signature(signature, message),
215            Self::Rsa(key) => key.verifies_signature(signature, message),
216        }
217    }
218}
219
220impl VerifyingKey {
221    /// Create a key from a `DER` encoded Subject Public Key Info structure.
222    fn from_spki_der(der: &[u8]) -> Option<Self> {
223        let spki = SubjectPublicKeyInfoRef::from_der(der).ok()?;
224        let key = spki.subject_public_key.as_bytes()?;
225        match spki.algorithm.oid {
226            ID_EC_PUBLIC_KEY => {
227                let curve = spki.algorithm.parameters_oid().ok()?;
228                match curve {
229                    SECP_256_R_1 => {
230                        let key = p256::ecdsa::VerifyingKey::try_from(key).ok()?;
231                        Some(Self::Elliptic(EllipticKey::ES256(ES256 { key })))
232                    }
233                    SECP_384_R_1 => {
234                        let key = p384::ecdsa::VerifyingKey::try_from(key).ok()?;
235                        Some(Self::Elliptic(EllipticKey::ES384(ES384 { key })))
236                    }
237                    SECP_521_R_1 => {
238                        let key = p521::ecdsa::VerifyingKey::try_from(key).ok()?;
239                        Some(Self::Elliptic(EllipticKey::ES512(ES512 { key })))
240                    }
241                    _ => None,
242                }
243            }
244            RSA_ENCRYPTION => {
245                let key = ::rsa::RsaPublicKey::try_from(spki).ok()?;
246                match key.size() {
247                    256 => Some(Self::Rsa(RsaKey::RS256(RS256 {
248                        key,
249                        scheme: PhantomData,
250                        size: PhantomData,
251                    }))),
252                    384 => Some(Self::Rsa(RsaKey::RS384(RS384 {
253                        key,
254                        scheme: PhantomData,
255                        size: PhantomData,
256                    }))),
257                    512 => Some(Self::Rsa(RsaKey::RS512(RS512 {
258                        key,
259                        scheme: PhantomData,
260                        size: PhantomData,
261                    }))),
262                    _ => None,
263                }
264            }
265            ID_ED_25519 => {
266                let bytes = spki.subject_public_key.as_bytes()?.try_into().ok()?;
267                let key = ed25519_dalek::VerifyingKey::from_bytes(bytes).ok()?;
268                Some(Self::Edwards(EdwardsKey::Ed25519(Ed25519 { key })))
269            }
270            ID_ED_448 => {
271                let bytes = spki.subject_public_key.as_bytes()?.try_into().ok()?;
272                let key = ed448_goldilocks::VerifyingKey::from_bytes(bytes).ok()?;
273                Some(Self::Edwards(EdwardsKey::Ed448(Ed448 { key })))
274            }
275            _ => None,
276        }
277    }
278
279    /// Create a key from a `pkcs8` structure
280    fn from_pkcs8_der(der: &[u8]) -> Option<Self> {
281        let pkcs = PrivateKeyInfoRef::from_der(der).ok()?;
282        match pkcs.algorithm.oid {
283            ID_EC_PUBLIC_KEY => {
284                let curve = pkcs.algorithm.parameters_oid().ok()?;
285                match curve {
286                    SECP_256_R_1 => {
287                        let key = p256::ecdsa::SigningKey::try_from(pkcs).ok()?;
288                        let key = *key.verifying_key();
289                        Some(Self::Elliptic(EllipticKey::ES256(ES256 { key })))
290                    }
291                    SECP_384_R_1 => {
292                        let key = p384::ecdsa::SigningKey::try_from(pkcs).ok()?;
293                        let key = *key.verifying_key();
294                        Some(Self::Elliptic(EllipticKey::ES384(ES384 { key })))
295                    }
296                    SECP_521_R_1 => {
297                        let key = p521::ecdsa::SigningKey::try_from(pkcs).ok()?;
298                        let key = *key.verifying_key();
299                        Some(Self::Elliptic(EllipticKey::ES512(ES512 { key })))
300                    }
301                    _ => None,
302                }
303            }
304            RSA_ENCRYPTION => {
305                let key = RsaPrivateKey::try_from(pkcs).ok()?;
306                let key = key.to_public_key();
307                match key.size() {
308                    256 => Some(Self::Rsa(RsaKey::RS256(RS256 {
309                        key,
310                        scheme: PhantomData,
311                        size: PhantomData,
312                    }))),
313                    384 => Some(Self::Rsa(RsaKey::RS384(RS384 {
314                        key,
315                        scheme: PhantomData,
316                        size: PhantomData,
317                    }))),
318                    512 => Some(Self::Rsa(RsaKey::RS512(RS512 {
319                        key,
320                        scheme: PhantomData,
321                        size: PhantomData,
322                    }))),
323                    _ => None,
324                }
325            }
326            ID_ED_25519 => {
327                let octet_string = OctetString::from_der(pkcs.private_key.as_bytes()).ok()?;
328                let key = ed25519_dalek::SecretKey::try_from(octet_string.as_bytes()).ok()?;
329                let key = ed25519_dalek::SigningKey::from(key).verifying_key();
330                Some(Self::Edwards(EdwardsKey::Ed25519(Ed25519 { key })))
331            }
332            ID_ED_448 => {
333                // https://github.com/RustCrypto/elliptic-curves/issues/1326
334                let octet_string = OctetString::from_der(pkcs.private_key.as_bytes()).ok()?;
335                let key = ed448_goldilocks::SecretKey::try_from(octet_string.as_bytes()).ok()?;
336                let key = ed448_goldilocks::SigningKey::from(key).verifying_key();
337                Some(Self::Edwards(EdwardsKey::Ed448(Ed448 { key })))
338            }
339            _ => None,
340        }
341    }
342
343    /// Create a key from a `sec1` EC private key
344    fn from_private_ec_der(der: &[u8]) -> Option<Self> {
345        let key = EcPrivateKey::from_der(der).ok()?;
346        let curve = key.parameters?.named_curve()?;
347        match curve {
348            SECP_256_R_1 => {
349                let key = p256::ecdsa::SigningKey::from_slice(key.private_key).ok()?;
350                let key = *key.verifying_key();
351                Some(Self::Elliptic(EllipticKey::ES256(ES256 { key })))
352            }
353            SECP_384_R_1 => {
354                let key = p384::ecdsa::SigningKey::from_slice(key.private_key).ok()?;
355                let key = *key.verifying_key();
356                Some(Self::Elliptic(EllipticKey::ES384(ES384 { key })))
357            }
358            SECP_521_R_1 => {
359                let key = p521::ecdsa::SigningKey::from_slice(key.private_key).ok()?;
360                let key = *key.verifying_key();
361                Some(Self::Elliptic(EllipticKey::ES512(ES512 { key })))
362            }
363            _ => None,
364        }
365    }
366
367    /// Create a key from an (un)compressed elliptic curve point
368    fn from_ec_point(bytes: &[u8]) -> Option<Self> {
369        if let Ok(point) = p256::EncodedPoint::from_bytes(bytes)
370            && let Ok(key) = p256::ecdsa::VerifyingKey::from_encoded_point(&point)
371        {
372            Some(Self::Elliptic(EllipticKey::ES256(ES256 { key })))
373        } else if let Ok(point) = p384::EncodedPoint::from_bytes(bytes)
374            && let Ok(key) = p384::ecdsa::VerifyingKey::from_encoded_point(&point)
375        {
376            Some(Self::Elliptic(EllipticKey::ES384(ES384 { key })))
377        } else if let Ok(point) = p521::EncodedPoint::from_bytes(bytes)
378            && let Ok(key) = p521::ecdsa::VerifyingKey::from_encoded_point(&point)
379        {
380            Some(Self::Elliptic(EllipticKey::ES512(ES512 { key })))
381        } else {
382            None
383        }
384    }
385
386    /// Create a key from a raw Edwards key
387    fn from_raw_edwards(bytes: &[u8]) -> Option<Self> {
388        if let Ok(bytes) = bytes.try_into()
389            && let Ok(key) = ed25519_dalek::VerifyingKey::from_bytes(bytes)
390        {
391            Some(Self::Edwards(EdwardsKey::Ed25519(Ed25519 { key })))
392        } else if let Ok(bytes) = bytes.try_into()
393            && let Ok(key) = ed448_goldilocks::VerifyingKey::from_bytes(bytes)
394        {
395            Some(Self::Edwards(EdwardsKey::Ed448(Ed448 { key })))
396        } else {
397            None
398        }
399    }
400
401    /// Create an RSA key from a PKCS1 DER
402    fn from_pkcs1_der(der: &[u8]) -> Option<Self> {
403        if let Ok(key) = ::rsa::RsaPublicKey::from_pkcs1_der(der) {
404            match key.size() {
405                256 => Some(Self::Rsa(RsaKey::RS256(RS256 {
406                    key,
407                    scheme: PhantomData,
408                    size: PhantomData,
409                }))),
410                384 => Some(Self::Rsa(RsaKey::RS384(RS384 {
411                    key,
412                    scheme: PhantomData,
413                    size: PhantomData,
414                }))),
415                512 => Some(Self::Rsa(RsaKey::RS512(RS512 {
416                    key,
417                    scheme: PhantomData,
418                    size: PhantomData,
419                }))),
420                _ => None,
421            }
422        } else if let Ok(key) = ::rsa::RsaPrivateKey::from_pkcs1_der(der) {
423            let key = key.to_public_key();
424            match key.size() {
425                256 => Some(Self::Rsa(RsaKey::RS256(RS256 {
426                    key,
427                    scheme: PhantomData,
428                    size: PhantomData,
429                }))),
430                384 => Some(Self::Rsa(RsaKey::RS384(RS384 {
431                    key,
432                    scheme: PhantomData,
433                    size: PhantomData,
434                }))),
435                512 => Some(Self::Rsa(RsaKey::RS512(RS512 {
436                    key,
437                    scheme: PhantomData,
438                    size: PhantomData,
439                }))),
440                _ => None,
441            }
442        } else {
443            None
444        }
445    }
446}
447
448impl FromDer for VerifyingKey {
449    #[allow(clippy::manual_map)]
450    fn from_der(der: &[u8]) -> Option<Self> {
451        if let Some(key) = Self::from_spki_der(der) {
452            Some(key)
453        } else if let Some(key) = Self::from_pkcs8_der(der) {
454            Some(key)
455        } else if let Some(key) = Self::from_private_ec_der(der) {
456            Some(key)
457        } else if let Some(key) = Self::from_ec_point(der) {
458            Some(key)
459        } else if let Some(key) = Self::from_raw_edwards(der) {
460            Some(key)
461        } else if let Some(key) = Self::from_pkcs1_der(der) {
462            Some(key)
463        } else {
464            None
465        }
466    }
467}