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, Pkcs256, Pkcs384, Pkcs512, Pss256, Pss384, Pss512},
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<Pkcs256>;
38/// 384 byte `RSA` PKCS1v1.5 padding and SHA-384
39pub type RS384 = rsa::SigningKey<Pkcs384>;
40/// 512 byte `RSA` PKCS1v1.5 padding and SHA-512
41pub type RS512 = rsa::SigningKey<Pkcs512>;
42/// 256 byte `RSA` `PSS` padding and SHA-256
43pub type PS256 = rsa::SigningKey<Pss256>;
44/// 384 byte `RSA` `PSS` padding and SHA-384
45pub type PS384 = rsa::SigningKey<Pss384>;
46/// 512 byte `RSA` `PSS` padding and SHA-512
47pub type PS512 = rsa::SigningKey<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
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 ToVerifier for RsaKey {
113    type Key = verifying::RsaKey;
114
115    fn verifying_key(&self) -> Self::Key {
116        match &self {
117            Self::RS256(key) => verifying::RsaKey::RS256(key.verifying_key()),
118            Self::RS384(key) => verifying::RsaKey::RS384(key.verifying_key()),
119            Self::RS512(key) => verifying::RsaKey::RS512(key.verifying_key()),
120            Self::PS256(key) => verifying::RsaKey::PS256(key.verifying_key()),
121            Self::PS384(key) => verifying::RsaKey::PS384(key.verifying_key()),
122            Self::PS512(key) => verifying::RsaKey::PS512(key.verifying_key()),
123        }
124    }
125}
126
127impl SignMessage for EllipticKey {
128    fn sign(&self, message: &[u8]) -> Vec<u8> {
129        match &self {
130            Self::ES256(key) => key.sign(message),
131            Self::ES384(key) => key.sign(message),
132            Self::ES512(key) => key.sign(message),
133        }
134    }
135}
136
137impl ToVerifier for EllipticKey {
138    type Key = verifying::EllipticKey;
139
140    fn verifying_key(&self) -> Self::Key {
141        match &self {
142            Self::ES256(key) => verifying::EllipticKey::ES256(key.verifying_key()),
143            Self::ES384(key) => verifying::EllipticKey::ES384(key.verifying_key()),
144            Self::ES512(key) => verifying::EllipticKey::ES512(key.verifying_key()),
145        }
146    }
147}
148
149impl SignMessage for EdwardsKey {
150    fn sign(&self, message: &[u8]) -> Vec<u8> {
151        match &self {
152            Self::Ed25519(key) => key.sign(message),
153            Self::Ed448(key) => key.sign(message),
154        }
155    }
156}
157
158impl ToVerifier for EdwardsKey {
159    type Key = verifying::EdwardsKey;
160
161    fn verifying_key(&self) -> Self::Key {
162        match &self {
163            Self::Ed25519(key) => verifying::EdwardsKey::Ed25519(key.verifying_key()),
164            Self::Ed448(key) => verifying::EdwardsKey::Ed448(key.verifying_key()),
165        }
166    }
167}
168
169impl SignMessage for SigningKey {
170    fn sign(&self, message: &[u8]) -> Vec<u8> {
171        match &self {
172            Self::Elliptic(key) => key.sign(message),
173            Self::Edwards(key) => key.sign(message),
174            Self::Rsa(key) => key.sign(message),
175        }
176    }
177}
178
179impl ToVerifier for SigningKey {
180    type Key = verifying::VerifyingKey;
181
182    fn verifying_key(&self) -> Self::Key {
183        match &self {
184            Self::Elliptic(key) => verifying::VerifyingKey::Elliptic(key.verifying_key()),
185            Self::Edwards(key) => verifying::VerifyingKey::Edwards(key.verifying_key()),
186            Self::Rsa(key) => verifying::VerifyingKey::Rsa(key.verifying_key()),
187        }
188    }
189}
190
191impl SigningKey {
192    /// Create a key from a `pkcs8` structure
193    fn from_pkcs8_der(der: &[u8]) -> Option<Self> {
194        let pkcs = PrivateKeyInfoRef::from_der(der).ok()?;
195        match pkcs.algorithm.oid {
196            ID_EC_PUBLIC_KEY => {
197                let curve = pkcs.algorithm.parameters_oid().ok()?;
198                match curve {
199                    SECP_256_R_1 => {
200                        let key = p256::ecdsa::SigningKey::try_from(pkcs).ok()?;
201                        Some(Self::Elliptic(EllipticKey::ES256(ES256 { key })))
202                    }
203                    SECP_384_R_1 => {
204                        let key = p384::ecdsa::SigningKey::try_from(pkcs).ok()?;
205                        Some(Self::Elliptic(EllipticKey::ES384(ES384 { key })))
206                    }
207                    SECP_521_R_1 => {
208                        let key = p521::ecdsa::SigningKey::try_from(pkcs).ok()?;
209                        Some(Self::Elliptic(EllipticKey::ES512(ES512 { key })))
210                    }
211                    _ => None,
212                }
213            }
214            RSA_ENCRYPTION => {
215                let key = RsaPrivateKey::try_from(pkcs).ok()?;
216                match key.size() {
217                    256 => Some(Self::Rsa(RsaKey::RS256(RS256 {
218                        key,
219                        scheme: PhantomData,
220                    }))),
221                    384 => Some(Self::Rsa(RsaKey::RS384(RS384 {
222                        key,
223                        scheme: PhantomData,
224                    }))),
225                    512 => Some(Self::Rsa(RsaKey::RS512(RS512 {
226                        key,
227                        scheme: PhantomData,
228                    }))),
229                    _ => None,
230                }
231            }
232            ID_ED_25519 => {
233                let octet_string = OctetString::from_der(pkcs.private_key.as_bytes()).ok()?;
234                let key = ed25519_dalek::SecretKey::try_from(octet_string.as_bytes()).ok()?;
235                let key = ed25519_dalek::SigningKey::from(key);
236                Some(Self::Edwards(EdwardsKey::Ed25519(Ed25519 { key })))
237            }
238            ID_ED_448 => {
239                // https://github.com/RustCrypto/elliptic-curves/issues/1326
240                let octet_string = OctetString::from_der(pkcs.private_key.as_bytes()).ok()?;
241                let key = ed448_goldilocks::SecretKey::try_from(octet_string.as_bytes()).ok()?;
242                let key = ed448_goldilocks::SigningKey::from(key);
243                Some(Self::Edwards(EdwardsKey::Ed448(Ed448 { key })))
244            }
245            _ => None,
246        }
247    }
248
249    /// Create a key from a `sec1` EC private key
250    fn from_ec_der(der: &[u8]) -> Option<Self> {
251        let key = EcPrivateKey::from_der(der).ok()?;
252        let curve = key.parameters?.named_curve()?;
253        match curve {
254            SECP_256_R_1 => {
255                let key = p256::ecdsa::SigningKey::from_slice(key.private_key).ok()?;
256                Some(Self::Elliptic(EllipticKey::ES256(ES256 { key })))
257            }
258            SECP_384_R_1 => {
259                let key = p384::ecdsa::SigningKey::from_slice(key.private_key).ok()?;
260                Some(Self::Elliptic(EllipticKey::ES384(ES384 { key })))
261            }
262            SECP_521_R_1 => {
263                let key = p521::ecdsa::SigningKey::from_slice(key.private_key).ok()?;
264                Some(Self::Elliptic(EllipticKey::ES512(ES512 { key })))
265            }
266            _ => None,
267        }
268    }
269}
270
271impl FromDer for SigningKey {
272    #[allow(clippy::manual_map)]
273    fn from_der(der: &[u8]) -> Option<Self> {
274        if let Some(key) = Self::from_pkcs8_der(der) {
275            Some(key)
276        } else if let Some(key) = Self::from_ec_der(der) {
277            Some(key)
278        } else {
279            None
280        }
281    }
282}