ts_crypto/
any.rs

1//! Blind parsing of a DER to a key
2
3use const_oid::db::{
4    rfc5753::ID_EC_PUBLIC_KEY,
5    rfc5912::{RSA_ENCRYPTION, SECP_256_R_1, SECP_384_R_1, SECP_521_R_1},
6    rfc8410::{ID_ED_448, ID_ED_25519},
7};
8use der::Decode;
9use pkcs8::PrivateKeyInfoRef;
10use rsa::pkcs1;
11use spki::SubjectPublicKeyInfoRef;
12
13use crate::{
14    decode_pem,
15    ecdsa::{
16        P256SigningKey, P256VerifyingKey, P384SigningKey, P384VerifyingKey, P521SigningKey,
17        P521VerifyingKey, SigningKey as _, VerifyingKey as _,
18    },
19    eddsa::{
20        Ed448SigningKey, Ed448VerifyingKey, Ed25519SigningKey, Ed25519VerifyingKey,
21        SigningKey as _, VerifyingKey as _,
22    },
23    rsa::{RsaSigningKey, RsaVerifyingKey, SigningKey as _, VerifyingKey as _},
24};
25
26/// Any verifying key.
27#[allow(clippy::exhaustive_enums)]
28pub enum VerifyingKey {
29    /// An ECDSA verifying key.
30    Ecdsa(Box<dyn crate::ecdsa::VerifyingKey>),
31    /// An `EdDSA` verifying key.
32    EdDsa(Box<dyn crate::eddsa::VerifyingKey>),
33    /// An RSA verifying key.
34    Rsa(Box<dyn crate::rsa::VerifyingKey>),
35}
36
37/// Any signing key.
38#[allow(clippy::exhaustive_enums)]
39pub enum SigningKey {
40    /// An ECDSA signing key.
41    Ecdsa(Box<dyn crate::ecdsa::SigningKey>),
42    /// An `EdDSA` signing key.
43    EdDsa(Box<dyn crate::eddsa::SigningKey>),
44    /// An RSA signing key.
45    Rsa(Box<dyn crate::rsa::SigningKey>),
46}
47
48impl VerifyingKey {
49    /// Get the inner `EdDSA` key
50    pub fn as_ecdsa(&self) -> Option<&dyn crate::ecdsa::VerifyingKey> {
51        let Self::Ecdsa(key) = &self else {
52            return None;
53        };
54        Some(key.as_ref())
55    }
56
57    /// Get the inner ECDSA key
58    pub fn as_eddsa(&self) -> Option<&dyn crate::eddsa::VerifyingKey> {
59        let Self::EdDsa(key) = &self else {
60            return None;
61        };
62        Some(key.as_ref())
63    }
64
65    /// Get the inner RSA key
66    pub fn as_rsa(&self) -> Option<&dyn crate::rsa::VerifyingKey> {
67        let Self::Rsa(key) = &self else {
68            return None;
69        };
70        Some(key.as_ref())
71    }
72
73    /// Create a verifying key from a DER encoded document.
74    pub fn from_unknown_der(der: &[u8]) -> Option<Self> {
75        if let Ok(spki) = SubjectPublicKeyInfoRef::from_der(der) {
76            match spki.algorithm.oid {
77                ID_EC_PUBLIC_KEY => match spki.algorithm.parameters_oid().ok()? {
78                    SECP_256_R_1 => {
79                        let key = P256VerifyingKey::from_spki_der(der)?;
80                        Some(Self::Ecdsa(Box::new(key)))
81                    }
82                    SECP_384_R_1 => {
83                        let key = P384VerifyingKey::from_spki_der(der)?;
84                        Some(Self::Ecdsa(Box::new(key)))
85                    }
86                    SECP_521_R_1 => {
87                        let key = P521VerifyingKey::from_spki_der(der)?;
88                        Some(Self::Ecdsa(Box::new(key)))
89                    }
90                    _ => None,
91                },
92                RSA_ENCRYPTION => {
93                    let key = RsaVerifyingKey::from_spki_der(der)?;
94                    Some(Self::Rsa(Box::new(key)))
95                }
96                ID_ED_25519 => {
97                    let key = Ed25519VerifyingKey::from_spki_der(der)?;
98                    Some(Self::EdDsa(Box::new(key)))
99                }
100                ID_ED_448 => {
101                    let key = Ed448VerifyingKey::from_spki_der(der)?;
102                    Some(Self::EdDsa(Box::new(key)))
103                }
104                _ => None,
105            }
106        } else if let Ok(key) = pkcs1::RsaPublicKey::from_der(der) {
107            let key = RsaVerifyingKey::try_from(key).ok()?;
108            Some(Self::Rsa(Box::new(key)))
109        } else {
110            None
111        }
112    }
113
114    /// Create a verifying key from a PEM encoded document.
115    pub fn from_unknown_pem(pem: &[u8]) -> Option<Self> {
116        let der = decode_pem(pem)?;
117        Self::from_unknown_der(&der)
118    }
119}
120
121impl SigningKey {
122    /// Get the inner `EdDSA` key
123    pub fn as_ecdsa(&self) -> Option<&dyn crate::ecdsa::SigningKey> {
124        let Self::Ecdsa(key) = &self else {
125            return None;
126        };
127        Some(key.as_ref())
128    }
129
130    /// Get the inner ECDSA key
131    pub fn as_eddsa(&self) -> Option<&dyn crate::eddsa::SigningKey> {
132        let Self::EdDsa(key) = &self else {
133            return None;
134        };
135        Some(key.as_ref())
136    }
137
138    /// Get the inner RSA key
139    pub fn as_rsa(&self) -> Option<&dyn crate::rsa::SigningKey> {
140        let Self::Rsa(key) = &self else {
141            return None;
142        };
143        Some(key.as_ref())
144    }
145
146    /// Create a signing key from a DER encoded document.
147    pub fn from_unknown_der(der: &[u8]) -> Option<Self> {
148        if let Ok(pkcs) = PrivateKeyInfoRef::from_der(der) {
149            match pkcs.algorithm.oid {
150                ID_EC_PUBLIC_KEY => match pkcs.algorithm.parameters_oid().ok()? {
151                    SECP_256_R_1 => {
152                        let key = P256SigningKey::from_pkcs8_der(der)?;
153                        Some(Self::Ecdsa(Box::new(key)))
154                    }
155                    SECP_384_R_1 => {
156                        let key = P384SigningKey::from_pkcs8_der(der)?;
157                        Some(Self::Ecdsa(Box::new(key)))
158                    }
159                    SECP_521_R_1 => {
160                        let key = P521SigningKey::from_pkcs8_der(der)?;
161                        Some(Self::Ecdsa(Box::new(key)))
162                    }
163                    _ => None,
164                },
165                RSA_ENCRYPTION => {
166                    let key = RsaSigningKey::from_pkcs8_der(der)?;
167                    Some(Self::Rsa(Box::new(key)))
168                }
169                ID_ED_25519 => {
170                    let key = Ed25519SigningKey::from_pkcs8_der(der)?;
171                    Some(Self::EdDsa(Box::new(key)))
172                }
173                ID_ED_448 => {
174                    let key = Ed448SigningKey::from_pkcs8_der(der)?;
175                    Some(Self::EdDsa(Box::new(key)))
176                }
177                _ => None,
178            }
179        } else if let Ok(key) = sec1::EcPrivateKey::from_der(der) {
180            match key.parameters?.named_curve()? {
181                SECP_256_R_1 => {
182                    let key = P256SigningKey::from_sec1_der(der)?;
183                    Some(Self::Ecdsa(Box::new(key)))
184                }
185                SECP_384_R_1 => {
186                    let key = P384SigningKey::from_sec1_der(der)?;
187                    Some(Self::Ecdsa(Box::new(key)))
188                }
189                SECP_521_R_1 => {
190                    let key = P521SigningKey::from_sec1_der(der)?;
191                    Some(Self::Ecdsa(Box::new(key)))
192                }
193                _ => None,
194            }
195        } else if let Ok(key) = pkcs1::RsaPrivateKey::from_der(der) {
196            let key = RsaSigningKey::try_from(key).ok()?;
197            Some(Self::Rsa(Box::new(key)))
198        } else {
199            None
200        }
201    }
202
203    /// Create a verifying key from a PEM encoded document.
204    pub fn from_unknown_pem(pem: &[u8]) -> Option<Self> {
205        let der = decode_pem(pem)?;
206        Self::from_unknown_der(&der)
207    }
208}