ts_crypto/known/
signing.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;
17
18use crate::{
19    FromDer, SignMessage, ToVerifier,
20    edwards::{self, Curve448, Curve25519},
21    elliptic,
22    known::verifying,
23    rsa::{self, Pkcs, Pss, Scheme, SetScheme, U256, U384, U512},
24};
25
26/// `ECDSA` using the prime-256 curve
27pub type ES256 = elliptic::SigningKey<NistP256>;
28/// `ECDSA` using the prime-384 curve
29pub type ES384 = elliptic::SigningKey<NistP384>;
30/// `ECDSA` using the prime-521 curve
31pub type ES512 = elliptic::SigningKey<NistP521>;
32/// `EdDSA` using curve 25519
33pub type Ed25519 = edwards::SigningKey<Curve25519>;
34/// `EdDSA` using curve 448
35pub type Ed448 = edwards::SigningKey<Curve448>;
36/// 256 byte `RSA` PKCS1v1.5 padding and SHA-256
37pub type RS256 = rsa::SigningKey<Pkcs, U256>;
38/// 384 byte `RSA` PKCS1v1.5 padding and SHA-384
39pub type RS384 = rsa::SigningKey<Pkcs, U384>;
40/// 512 byte `RSA` PKCS1v1.5 padding and SHA-512
41pub type RS512 = rsa::SigningKey<Pkcs, U512>;
42/// 256 byte `RSA` `PSS` padding and SHA-256
43pub type PS256 = rsa::SigningKey<Pss, U256>;
44/// 384 byte `RSA` `PSS` padding and SHA-384
45pub type PS384 = rsa::SigningKey<Pss, U384>;
46/// 512 byte `RSA` `PSS` padding and SHA-512
47pub type PS512 = rsa::SigningKey<Pss, U512>;
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
60/// A known Edwards key
61#[allow(clippy::exhaustive_enums)]
62#[allow(clippy::large_enum_variant)]
63pub enum EdwardsKey {
64    /// `EdDSA` using curve 25519
65    Ed25519(Ed25519),
66    /// `EdDSA` using curve 448
67    Ed448(Ed448),
68}
69
70/// A known RSA key
71#[allow(clippy::exhaustive_enums)]
72pub enum RsaKey {
73    /// 256 byte `RSA` PKCS1v1.5 padding and SHA-256
74    RS256(RS256),
75    /// 384 byte `RSA` PKCS1v1.5 padding and SHA-384
76    RS384(RS384),
77    /// 512 byte `RSA` PKCS1v1.5 padding and SHA-512
78    RS512(RS512),
79    /// 256 byte `RSA` `PSS` padding and SHA-256
80    PS256(PS256),
81    /// 384 byte `RSA` `PSS` padding and SHA-384
82    PS384(PS384),
83    /// 512 byte `RSA` `PSS` padding and SHA-512
84    PS512(PS512),
85}
86
87/// A known signing key
88#[allow(clippy::exhaustive_enums)]
89#[allow(clippy::large_enum_variant)]
90pub enum SigningKey {
91    /// Elliptic key
92    Elliptic(EllipticKey),
93    /// Edwards key
94    Edwards(EdwardsKey),
95    /// RSA key
96    Rsa(RsaKey),
97}
98
99impl SignMessage for RsaKey {
100    fn sign(&self, message: &[u8]) -> Vec<u8> {
101        match &self {
102            Self::RS256(key) => key.sign(message),
103            Self::RS384(key) => key.sign(message),
104            Self::RS512(key) => key.sign(message),
105            Self::PS256(key) => key.sign(message),
106            Self::PS384(key) => key.sign(message),
107            Self::PS512(key) => key.sign(message),
108        }
109    }
110}
111
112impl<S: Scheme> SetScheme<S> for RsaKey {
113    type Output = Self;
114
115    fn set_scheme(self) -> Self::Output {
116        match self {
117            Self::RS256(key) => Self::PS256(key.set_scheme()),
118            Self::RS384(key) => Self::PS384(key.set_scheme()),
119            Self::RS512(key) => Self::PS512(key.set_scheme()),
120            Self::PS256(key) => Self::RS256(key.set_scheme()),
121            Self::PS384(key) => Self::RS384(key.set_scheme()),
122            Self::PS512(key) => Self::RS512(key.set_scheme()),
123        }
124    }
125}
126
127impl ToVerifier for RsaKey {
128    type Key = verifying::RsaKey;
129
130    fn verifying_key(&self) -> Self::Key {
131        match &self {
132            Self::RS256(key) => verifying::RsaKey::RS256(key.verifying_key()),
133            Self::RS384(key) => verifying::RsaKey::RS384(key.verifying_key()),
134            Self::RS512(key) => verifying::RsaKey::RS512(key.verifying_key()),
135            Self::PS256(key) => verifying::RsaKey::PS256(key.verifying_key()),
136            Self::PS384(key) => verifying::RsaKey::PS384(key.verifying_key()),
137            Self::PS512(key) => verifying::RsaKey::PS512(key.verifying_key()),
138        }
139    }
140}
141
142impl SignMessage for EllipticKey {
143    fn sign(&self, message: &[u8]) -> Vec<u8> {
144        match &self {
145            Self::ES256(key) => key.sign(message),
146            Self::ES384(key) => key.sign(message),
147            Self::ES512(key) => key.sign(message),
148        }
149    }
150}
151
152impl ToVerifier for EllipticKey {
153    type Key = verifying::EllipticKey;
154
155    fn verifying_key(&self) -> Self::Key {
156        match &self {
157            Self::ES256(key) => verifying::EllipticKey::ES256(key.verifying_key()),
158            Self::ES384(key) => verifying::EllipticKey::ES384(key.verifying_key()),
159            Self::ES512(key) => verifying::EllipticKey::ES512(key.verifying_key()),
160        }
161    }
162}
163
164impl SignMessage for EdwardsKey {
165    fn sign(&self, message: &[u8]) -> Vec<u8> {
166        match &self {
167            Self::Ed25519(key) => key.sign(message),
168            Self::Ed448(key) => key.sign(message),
169        }
170    }
171}
172
173impl ToVerifier for EdwardsKey {
174    type Key = verifying::EdwardsKey;
175
176    fn verifying_key(&self) -> Self::Key {
177        match &self {
178            Self::Ed25519(key) => verifying::EdwardsKey::Ed25519(key.verifying_key()),
179            Self::Ed448(key) => verifying::EdwardsKey::Ed448(key.verifying_key()),
180        }
181    }
182}
183
184impl SignMessage for SigningKey {
185    fn sign(&self, message: &[u8]) -> Vec<u8> {
186        match &self {
187            Self::Elliptic(key) => key.sign(message),
188            Self::Edwards(key) => key.sign(message),
189            Self::Rsa(key) => key.sign(message),
190        }
191    }
192}
193
194impl ToVerifier for SigningKey {
195    type Key = verifying::VerifyingKey;
196
197    fn verifying_key(&self) -> Self::Key {
198        match &self {
199            Self::Elliptic(key) => verifying::VerifyingKey::Elliptic(key.verifying_key()),
200            Self::Edwards(key) => verifying::VerifyingKey::Edwards(key.verifying_key()),
201            Self::Rsa(key) => verifying::VerifyingKey::Rsa(key.verifying_key()),
202        }
203    }
204}
205
206impl SigningKey {
207    /// Create a key from a `pkcs8` structure
208    fn from_pkcs8_der(der: &[u8]) -> Option<Self> {
209        let pkcs = PrivateKeyInfoRef::from_der(der).ok()?;
210        match pkcs.algorithm.oid {
211            ID_EC_PUBLIC_KEY => {
212                let curve = pkcs.algorithm.parameters_oid().ok()?;
213                match curve {
214                    SECP_256_R_1 => {
215                        let key = p256::ecdsa::SigningKey::try_from(pkcs).ok()?;
216                        Some(Self::Elliptic(EllipticKey::ES256(ES256 { key })))
217                    }
218                    SECP_384_R_1 => {
219                        let key = p384::ecdsa::SigningKey::try_from(pkcs).ok()?;
220                        Some(Self::Elliptic(EllipticKey::ES384(ES384 { key })))
221                    }
222                    SECP_521_R_1 => {
223                        let key = p521::ecdsa::SigningKey::try_from(pkcs).ok()?;
224                        Some(Self::Elliptic(EllipticKey::ES512(ES512 { key })))
225                    }
226                    _ => None,
227                }
228            }
229            RSA_ENCRYPTION => {
230                let key = RsaPrivateKey::try_from(pkcs).ok()?;
231                match key.size() {
232                    256 => Some(Self::Rsa(RsaKey::RS256(RS256 {
233                        key,
234                        scheme: PhantomData,
235                        size: PhantomData,
236                    }))),
237                    384 => Some(Self::Rsa(RsaKey::RS384(RS384 {
238                        key,
239                        scheme: PhantomData,
240                        size: PhantomData,
241                    }))),
242                    512 => Some(Self::Rsa(RsaKey::RS512(RS512 {
243                        key,
244                        scheme: PhantomData,
245                        size: PhantomData,
246                    }))),
247                    _ => None,
248                }
249            }
250            ID_ED_25519 => {
251                let octet_string = OctetString::from_der(pkcs.private_key.as_bytes()).ok()?;
252                let key = ed25519_dalek::SecretKey::try_from(octet_string.as_bytes()).ok()?;
253                let key = ed25519_dalek::SigningKey::from(key);
254                Some(Self::Edwards(EdwardsKey::Ed25519(Ed25519 { key })))
255            }
256            ID_ED_448 => {
257                // https://github.com/RustCrypto/elliptic-curves/issues/1326
258                let octet_string = OctetString::from_der(pkcs.private_key.as_bytes()).ok()?;
259                let key = ed448_goldilocks::SecretKey::try_from(octet_string.as_bytes()).ok()?;
260                let key = ed448_goldilocks::SigningKey::from(key);
261                Some(Self::Edwards(EdwardsKey::Ed448(Ed448 { key })))
262            }
263            _ => None,
264        }
265    }
266
267    /// Create a key from a `sec1` EC private key
268    fn from_ec_der(der: &[u8]) -> Option<Self> {
269        let key = EcPrivateKey::from_der(der).ok()?;
270        let curve = key.parameters?.named_curve()?;
271        match curve {
272            SECP_256_R_1 => {
273                let key = p256::ecdsa::SigningKey::from_slice(key.private_key).ok()?;
274                Some(Self::Elliptic(EllipticKey::ES256(ES256 { key })))
275            }
276            SECP_384_R_1 => {
277                let key = p384::ecdsa::SigningKey::from_slice(key.private_key).ok()?;
278                Some(Self::Elliptic(EllipticKey::ES384(ES384 { key })))
279            }
280            SECP_521_R_1 => {
281                let key = p521::ecdsa::SigningKey::from_slice(key.private_key).ok()?;
282                Some(Self::Elliptic(EllipticKey::ES512(ES512 { key })))
283            }
284            _ => None,
285        }
286    }
287}
288
289impl FromDer for SigningKey {
290    #[allow(clippy::manual_map)]
291    fn from_der(der: &[u8]) -> Option<Self> {
292        if let Some(key) = Self::from_pkcs8_der(der) {
293            Some(key)
294        } else if let Some(key) = Self::from_ec_der(der) {
295            Some(key)
296        } else {
297            None
298        }
299    }
300}