rustls/crypto/aws_lc_rs/
sign.rs

1#![allow(clippy::duplicate_mod)]
2
3use alloc::boxed::Box;
4use alloc::string::ToString;
5use alloc::vec::Vec;
6use alloc::{format, vec};
7use core::fmt::{self, Debug, Formatter};
8
9use pki_types::{PrivateKeyDer, PrivatePkcs8KeyDer, SubjectPublicKeyInfoDer, alg_id};
10
11use super::ring_like::rand::SystemRandom;
12use super::ring_like::signature::{self, EcdsaKeyPair, Ed25519KeyPair, KeyPair, RsaKeyPair};
13use crate::crypto::signer::{Signer, SigningKey, public_key_to_spki};
14use crate::enums::{SignatureAlgorithm, SignatureScheme};
15use crate::error::Error;
16use crate::sync::Arc;
17
18/// Parse `der` as any supported key encoding/type, returning
19/// the first which works.
20pub fn any_supported_type(der: &PrivateKeyDer<'_>) -> Result<Arc<dyn SigningKey>, Error> {
21    if let Ok(rsa) = RsaSigningKey::new(der) {
22        return Ok(Arc::new(rsa));
23    }
24
25    if let Ok(ecdsa) = any_ecdsa_type(der) {
26        return Ok(ecdsa);
27    }
28
29    if let PrivateKeyDer::Pkcs8(pkcs8) = der {
30        if let Ok(eddsa) = any_eddsa_type(pkcs8) {
31            return Ok(eddsa);
32        }
33    }
34
35    Err(Error::General(
36        "failed to parse private key as RSA, ECDSA, or EdDSA".into(),
37    ))
38}
39
40/// Parse `der` as any ECDSA key type, returning the first which works.
41///
42/// Both SEC1 (PEM section starting with 'BEGIN EC PRIVATE KEY') and PKCS8
43/// (PEM section starting with 'BEGIN PRIVATE KEY') encodings are supported.
44pub fn any_ecdsa_type(der: &PrivateKeyDer<'_>) -> Result<Arc<dyn SigningKey>, Error> {
45    if let Ok(ecdsa_p256) = EcdsaSigningKey::new(
46        der,
47        SignatureScheme::ECDSA_NISTP256_SHA256,
48        &signature::ECDSA_P256_SHA256_ASN1_SIGNING,
49    ) {
50        return Ok(Arc::new(ecdsa_p256));
51    }
52
53    if let Ok(ecdsa_p384) = EcdsaSigningKey::new(
54        der,
55        SignatureScheme::ECDSA_NISTP384_SHA384,
56        &signature::ECDSA_P384_SHA384_ASN1_SIGNING,
57    ) {
58        return Ok(Arc::new(ecdsa_p384));
59    }
60
61    if let Ok(ecdsa_p521) = EcdsaSigningKey::new(
62        der,
63        SignatureScheme::ECDSA_NISTP521_SHA512,
64        &signature::ECDSA_P521_SHA512_ASN1_SIGNING,
65    ) {
66        return Ok(Arc::new(ecdsa_p521));
67    }
68
69    Err(Error::General(
70        "failed to parse ECDSA private key as PKCS#8 or SEC1".into(),
71    ))
72}
73
74/// Parse `der` as any EdDSA key type, returning the first which works.
75///
76/// Note that, at the time of writing, Ed25519 does not have wide support
77/// in browsers.  It is also not supported by the WebPKI, because the
78/// CA/Browser Forum Baseline Requirements do not support it for publicly
79/// trusted certificates.
80pub fn any_eddsa_type(der: &PrivatePkcs8KeyDer<'_>) -> Result<Arc<dyn SigningKey>, Error> {
81    // TODO: Add support for Ed448
82    Ok(Arc::new(Ed25519SigningKey::new(
83        der,
84        SignatureScheme::ED25519,
85    )?))
86}
87
88/// A `SigningKey` for RSA-PKCS1 or RSA-PSS.
89///
90/// This is used by the test suite, so it must be `pub`, but it isn't part of
91/// the public, stable, API.
92#[doc(hidden)]
93pub struct RsaSigningKey {
94    key: Arc<RsaKeyPair>,
95}
96
97static ALL_RSA_SCHEMES: &[SignatureScheme] = &[
98    SignatureScheme::RSA_PSS_SHA512,
99    SignatureScheme::RSA_PSS_SHA384,
100    SignatureScheme::RSA_PSS_SHA256,
101    SignatureScheme::RSA_PKCS1_SHA512,
102    SignatureScheme::RSA_PKCS1_SHA384,
103    SignatureScheme::RSA_PKCS1_SHA256,
104];
105
106impl RsaSigningKey {
107    /// Make a new `RsaSigningKey` from a DER encoding, in either
108    /// PKCS#1 or PKCS#8 format.
109    pub fn new(der: &PrivateKeyDer<'_>) -> Result<Self, Error> {
110        let key_pair = match der {
111            PrivateKeyDer::Pkcs1(pkcs1) => RsaKeyPair::from_der(pkcs1.secret_pkcs1_der()),
112            PrivateKeyDer::Pkcs8(pkcs8) => RsaKeyPair::from_pkcs8(pkcs8.secret_pkcs8_der()),
113            _ => {
114                return Err(Error::General(
115                    "failed to parse RSA private key as either PKCS#1 or PKCS#8".into(),
116                ));
117            }
118        }
119        .map_err(|key_rejected| {
120            Error::General(format!("failed to parse RSA private key: {key_rejected}"))
121        })?;
122
123        Ok(Self {
124            key: Arc::new(key_pair),
125        })
126    }
127}
128
129impl SigningKey for RsaSigningKey {
130    fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn Signer>> {
131        ALL_RSA_SCHEMES
132            .iter()
133            .find(|scheme| offered.contains(scheme))
134            .map(|scheme| RsaSigner::new(self.key.clone(), *scheme))
135    }
136
137    fn public_key(&self) -> Option<SubjectPublicKeyInfoDer<'_>> {
138        Some(public_key_to_spki(
139            &alg_id::RSA_ENCRYPTION,
140            self.key.public_key(),
141        ))
142    }
143
144    fn algorithm(&self) -> SignatureAlgorithm {
145        SignatureAlgorithm::RSA
146    }
147}
148
149impl Debug for RsaSigningKey {
150    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
151        f.debug_struct("RsaSigningKey")
152            .field("algorithm", &self.algorithm())
153            .finish()
154    }
155}
156
157struct RsaSigner {
158    key: Arc<RsaKeyPair>,
159    scheme: SignatureScheme,
160    encoding: &'static dyn signature::RsaEncoding,
161}
162
163impl RsaSigner {
164    fn new(key: Arc<RsaKeyPair>, scheme: SignatureScheme) -> Box<dyn Signer> {
165        let encoding: &dyn signature::RsaEncoding = match scheme {
166            SignatureScheme::RSA_PKCS1_SHA256 => &signature::RSA_PKCS1_SHA256,
167            SignatureScheme::RSA_PKCS1_SHA384 => &signature::RSA_PKCS1_SHA384,
168            SignatureScheme::RSA_PKCS1_SHA512 => &signature::RSA_PKCS1_SHA512,
169            SignatureScheme::RSA_PSS_SHA256 => &signature::RSA_PSS_SHA256,
170            SignatureScheme::RSA_PSS_SHA384 => &signature::RSA_PSS_SHA384,
171            SignatureScheme::RSA_PSS_SHA512 => &signature::RSA_PSS_SHA512,
172            _ => unreachable!(),
173        };
174
175        Box::new(Self {
176            key,
177            scheme,
178            encoding,
179        })
180    }
181}
182
183impl Signer for RsaSigner {
184    fn sign(&self, message: &[u8]) -> Result<Vec<u8>, Error> {
185        let mut sig = vec![0; self.key.public_modulus_len()];
186
187        let rng = SystemRandom::new();
188        self.key
189            .sign(self.encoding, &rng, message, &mut sig)
190            .map(|_| sig)
191            .map_err(|_| Error::General("signing failed".to_string()))
192    }
193
194    fn scheme(&self) -> SignatureScheme {
195        self.scheme
196    }
197}
198
199impl Debug for RsaSigner {
200    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
201        f.debug_struct("RsaSigner")
202            .field("scheme", &self.scheme)
203            .finish()
204    }
205}
206
207/// A SigningKey that uses exactly one TLS-level SignatureScheme
208/// and one ring-level signature::SigningAlgorithm.
209///
210/// Compare this to RsaSigningKey, which for a particular key is
211/// willing to sign with several algorithms.  This is quite poor
212/// cryptography practice, but is necessary because a given RSA key
213/// is expected to work in TLS1.2 (PKCS#1 signatures) and TLS1.3
214/// (PSS signatures) -- nobody is willing to obtain certificates for
215/// different protocol versions.
216///
217/// Currently this is only implemented for ECDSA keys.
218struct EcdsaSigningKey {
219    key: Arc<EcdsaKeyPair>,
220    scheme: SignatureScheme,
221}
222
223impl EcdsaSigningKey {
224    /// Make a new `ECDSASigningKey` from a DER encoding in PKCS#8 or SEC1
225    /// format, expecting a key usable with precisely the given signature
226    /// scheme.
227    fn new(
228        der: &PrivateKeyDer<'_>,
229        scheme: SignatureScheme,
230        sigalg: &'static signature::EcdsaSigningAlgorithm,
231    ) -> Result<Self, ()> {
232        let key_pair = match der {
233            PrivateKeyDer::Sec1(sec1) => {
234                EcdsaKeyPair::from_private_key_der(sigalg, sec1.secret_sec1_der())
235                    .map_err(|_| ())?
236            }
237            PrivateKeyDer::Pkcs8(pkcs8) => {
238                EcdsaKeyPair::from_pkcs8(sigalg, pkcs8.secret_pkcs8_der()).map_err(|_| ())?
239            }
240            _ => return Err(()),
241        };
242
243        Ok(Self {
244            key: Arc::new(key_pair),
245            scheme,
246        })
247    }
248}
249
250impl SigningKey for EcdsaSigningKey {
251    fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn Signer>> {
252        if offered.contains(&self.scheme) {
253            Some(Box::new(EcdsaSigner {
254                key: self.key.clone(),
255                scheme: self.scheme,
256            }))
257        } else {
258            None
259        }
260    }
261
262    fn public_key(&self) -> Option<SubjectPublicKeyInfoDer<'_>> {
263        let id = match self.scheme {
264            SignatureScheme::ECDSA_NISTP256_SHA256 => alg_id::ECDSA_P256,
265            SignatureScheme::ECDSA_NISTP384_SHA384 => alg_id::ECDSA_P384,
266            SignatureScheme::ECDSA_NISTP521_SHA512 => alg_id::ECDSA_P521,
267            _ => unreachable!(),
268        };
269
270        Some(public_key_to_spki(&id, self.key.public_key()))
271    }
272
273    fn algorithm(&self) -> SignatureAlgorithm {
274        self.scheme.algorithm()
275    }
276}
277
278impl Debug for EcdsaSigningKey {
279    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
280        f.debug_struct("EcdsaSigningKey")
281            .field("algorithm", &self.algorithm())
282            .finish()
283    }
284}
285
286struct EcdsaSigner {
287    key: Arc<EcdsaKeyPair>,
288    scheme: SignatureScheme,
289}
290
291impl Signer for EcdsaSigner {
292    fn sign(&self, message: &[u8]) -> Result<Vec<u8>, Error> {
293        let rng = SystemRandom::new();
294        self.key
295            .sign(&rng, message)
296            .map_err(|_| Error::General("signing failed".into()))
297            .map(|sig| sig.as_ref().into())
298    }
299
300    fn scheme(&self) -> SignatureScheme {
301        self.scheme
302    }
303}
304
305impl Debug for EcdsaSigner {
306    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
307        f.debug_struct("EcdsaSigner")
308            .field("scheme", &self.scheme)
309            .finish()
310    }
311}
312
313/// A SigningKey that uses exactly one TLS-level SignatureScheme
314/// and one ring-level signature::SigningAlgorithm.
315///
316/// Compare this to RsaSigningKey, which for a particular key is
317/// willing to sign with several algorithms.  This is quite poor
318/// cryptography practice, but is necessary because a given RSA key
319/// is expected to work in TLS1.2 (PKCS#1 signatures) and TLS1.3
320/// (PSS signatures) -- nobody is willing to obtain certificates for
321/// different protocol versions.
322///
323/// Currently this is only implemented for Ed25519 keys.
324struct Ed25519SigningKey {
325    key: Arc<Ed25519KeyPair>,
326    scheme: SignatureScheme,
327}
328
329impl Ed25519SigningKey {
330    /// Make a new `Ed25519SigningKey` from a DER encoding in PKCS#8 format,
331    /// expecting a key usable with precisely the given signature scheme.
332    fn new(der: &PrivatePkcs8KeyDer<'_>, scheme: SignatureScheme) -> Result<Self, Error> {
333        match Ed25519KeyPair::from_pkcs8_maybe_unchecked(der.secret_pkcs8_der()) {
334            Ok(key_pair) => Ok(Self {
335                key: Arc::new(key_pair),
336                scheme,
337            }),
338            Err(e) => Err(Error::General(format!(
339                "failed to parse Ed25519 private key: {e}"
340            ))),
341        }
342    }
343}
344
345impl SigningKey for Ed25519SigningKey {
346    fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn Signer>> {
347        if offered.contains(&self.scheme) {
348            Some(Box::new(Ed25519Signer {
349                key: self.key.clone(),
350                scheme: self.scheme,
351            }))
352        } else {
353            None
354        }
355    }
356
357    fn public_key(&self) -> Option<SubjectPublicKeyInfoDer<'_>> {
358        Some(public_key_to_spki(&alg_id::ED25519, self.key.public_key()))
359    }
360
361    fn algorithm(&self) -> SignatureAlgorithm {
362        self.scheme.algorithm()
363    }
364}
365
366impl Debug for Ed25519SigningKey {
367    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
368        f.debug_struct("Ed25519SigningKey")
369            .field("algorithm", &self.algorithm())
370            .finish()
371    }
372}
373
374struct Ed25519Signer {
375    key: Arc<Ed25519KeyPair>,
376    scheme: SignatureScheme,
377}
378
379impl Signer for Ed25519Signer {
380    fn sign(&self, message: &[u8]) -> Result<Vec<u8>, Error> {
381        Ok(self.key.sign(message).as_ref().into())
382    }
383
384    fn scheme(&self) -> SignatureScheme {
385        self.scheme
386    }
387}
388
389impl Debug for Ed25519Signer {
390    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
391        f.debug_struct("Ed25519Signer")
392            .field("scheme", &self.scheme)
393            .finish()
394    }
395}
396
397#[cfg(test)]
398mod tests {
399    use alloc::format;
400
401    use pki_types::{PrivatePkcs1KeyDer, PrivateSec1KeyDer};
402
403    use super::*;
404
405    #[test]
406    fn can_load_ecdsa_nistp256_pkcs8() {
407        let key =
408            PrivatePkcs8KeyDer::from(&include_bytes!("../../testdata/nistp256key.pkcs8.der")[..]);
409        assert!(any_eddsa_type(&key).is_err());
410        let key = PrivateKeyDer::Pkcs8(key);
411        assert!(any_supported_type(&key).is_ok());
412        assert!(any_ecdsa_type(&key).is_ok());
413    }
414
415    #[test]
416    fn can_load_ecdsa_nistp256_sec1() {
417        let key = PrivateKeyDer::Sec1(PrivateSec1KeyDer::from(
418            &include_bytes!("../../testdata/nistp256key.der")[..],
419        ));
420        assert!(any_supported_type(&key).is_ok());
421        assert!(any_ecdsa_type(&key).is_ok());
422    }
423
424    #[test]
425    fn can_sign_ecdsa_nistp256() {
426        let key = PrivateKeyDer::Sec1(PrivateSec1KeyDer::from(
427            &include_bytes!("../../testdata/nistp256key.der")[..],
428        ));
429
430        let k = any_supported_type(&key).unwrap();
431        assert_eq!(format!("{k:?}"), "EcdsaSigningKey { algorithm: ECDSA }");
432        assert_eq!(k.algorithm(), SignatureAlgorithm::ECDSA);
433
434        assert!(
435            k.choose_scheme(&[SignatureScheme::RSA_PKCS1_SHA256])
436                .is_none()
437        );
438        assert!(
439            k.choose_scheme(&[SignatureScheme::ECDSA_NISTP384_SHA384])
440                .is_none()
441        );
442        let s = k
443            .choose_scheme(&[SignatureScheme::ECDSA_NISTP256_SHA256])
444            .unwrap();
445        assert_eq!(
446            format!("{s:?}"),
447            "EcdsaSigner { scheme: ECDSA_NISTP256_SHA256 }"
448        );
449        assert_eq!(s.scheme(), SignatureScheme::ECDSA_NISTP256_SHA256);
450        // nb. signature is variable length and asn.1-encoded
451        assert!(
452            s.sign(b"hello")
453                .unwrap()
454                .starts_with(&[0x30])
455        );
456    }
457
458    #[test]
459    fn can_load_ecdsa_nistp384_pkcs8() {
460        let key =
461            PrivatePkcs8KeyDer::from(&include_bytes!("../../testdata/nistp384key.pkcs8.der")[..]);
462        assert!(any_eddsa_type(&key).is_err());
463        let key = PrivateKeyDer::Pkcs8(key);
464        assert!(any_supported_type(&key).is_ok());
465        assert!(any_ecdsa_type(&key).is_ok());
466    }
467
468    #[test]
469    fn can_load_ecdsa_nistp384_sec1() {
470        let key = PrivateKeyDer::Sec1(PrivateSec1KeyDer::from(
471            &include_bytes!("../../testdata/nistp384key.der")[..],
472        ));
473        assert!(any_supported_type(&key).is_ok());
474        assert!(any_ecdsa_type(&key).is_ok());
475    }
476
477    #[test]
478    fn can_sign_ecdsa_nistp384() {
479        let key = PrivateKeyDer::Sec1(PrivateSec1KeyDer::from(
480            &include_bytes!("../../testdata/nistp384key.der")[..],
481        ));
482
483        let k = any_supported_type(&key).unwrap();
484        assert_eq!(format!("{k:?}"), "EcdsaSigningKey { algorithm: ECDSA }");
485        assert_eq!(k.algorithm(), SignatureAlgorithm::ECDSA);
486
487        assert!(
488            k.choose_scheme(&[SignatureScheme::RSA_PKCS1_SHA256])
489                .is_none()
490        );
491        assert!(
492            k.choose_scheme(&[SignatureScheme::ECDSA_NISTP256_SHA256])
493                .is_none()
494        );
495        let s = k
496            .choose_scheme(&[SignatureScheme::ECDSA_NISTP384_SHA384])
497            .unwrap();
498        assert_eq!(
499            format!("{s:?}"),
500            "EcdsaSigner { scheme: ECDSA_NISTP384_SHA384 }"
501        );
502        assert_eq!(s.scheme(), SignatureScheme::ECDSA_NISTP384_SHA384);
503        // nb. signature is variable length and asn.1-encoded
504        assert!(
505            s.sign(b"hello")
506                .unwrap()
507                .starts_with(&[0x30])
508        );
509    }
510
511    #[test]
512    fn can_load_ecdsa_nistp521_pkcs8() {
513        let key =
514            PrivatePkcs8KeyDer::from(&include_bytes!("../../testdata/nistp521key.pkcs8.der")[..]);
515        assert!(any_eddsa_type(&key).is_err());
516        let key = PrivateKeyDer::Pkcs8(key);
517        assert!(any_supported_type(&key).is_ok());
518        assert!(any_ecdsa_type(&key).is_ok());
519    }
520
521    #[test]
522    fn can_load_ecdsa_nistp521_sec1() {
523        let key = PrivateKeyDer::Sec1(PrivateSec1KeyDer::from(
524            &include_bytes!("../../testdata/nistp521key.der")[..],
525        ));
526        assert!(any_supported_type(&key).is_ok());
527        assert!(any_ecdsa_type(&key).is_ok());
528    }
529
530    #[test]
531    fn can_sign_ecdsa_nistp521() {
532        let key = PrivateKeyDer::Sec1(PrivateSec1KeyDer::from(
533            &include_bytes!("../../testdata/nistp521key.der")[..],
534        ));
535
536        let k = any_supported_type(&key).unwrap();
537        assert_eq!(format!("{k:?}"), "EcdsaSigningKey { algorithm: ECDSA }");
538        assert_eq!(k.algorithm(), SignatureAlgorithm::ECDSA);
539
540        assert!(
541            k.choose_scheme(&[SignatureScheme::RSA_PKCS1_SHA256])
542                .is_none()
543        );
544        assert!(
545            k.choose_scheme(&[SignatureScheme::ECDSA_NISTP256_SHA256])
546                .is_none()
547        );
548        assert!(
549            k.choose_scheme(&[SignatureScheme::ECDSA_NISTP384_SHA384])
550                .is_none()
551        );
552        let s = k
553            .choose_scheme(&[SignatureScheme::ECDSA_NISTP521_SHA512])
554            .unwrap();
555        assert_eq!(
556            format!("{s:?}"),
557            "EcdsaSigner { scheme: ECDSA_NISTP521_SHA512 }"
558        );
559        assert_eq!(s.scheme(), SignatureScheme::ECDSA_NISTP521_SHA512);
560        // nb. signature is variable length and asn.1-encoded
561        assert!(
562            s.sign(b"hello")
563                .unwrap()
564                .starts_with(&[0x30])
565        );
566    }
567
568    #[test]
569    fn can_load_eddsa_pkcs8() {
570        let key = PrivatePkcs8KeyDer::from(&include_bytes!("../../testdata/eddsakey.der")[..]);
571        assert!(any_eddsa_type(&key).is_ok());
572        let key = PrivateKeyDer::Pkcs8(key);
573        assert!(any_supported_type(&key).is_ok());
574        assert!(any_ecdsa_type(&key).is_err());
575    }
576
577    #[test]
578    fn can_sign_eddsa() {
579        let key = PrivatePkcs8KeyDer::from(&include_bytes!("../../testdata/eddsakey.der")[..]);
580
581        let k = any_eddsa_type(&key).unwrap();
582        assert_eq!(format!("{k:?}"), "Ed25519SigningKey { algorithm: ED25519 }");
583        assert_eq!(k.algorithm(), SignatureAlgorithm::ED25519);
584
585        assert!(
586            k.choose_scheme(&[SignatureScheme::RSA_PKCS1_SHA256])
587                .is_none()
588        );
589        assert!(
590            k.choose_scheme(&[SignatureScheme::ECDSA_NISTP256_SHA256])
591                .is_none()
592        );
593        let s = k
594            .choose_scheme(&[SignatureScheme::ED25519])
595            .unwrap();
596        assert_eq!(format!("{s:?}"), "Ed25519Signer { scheme: ED25519 }");
597        assert_eq!(s.scheme(), SignatureScheme::ED25519);
598        assert_eq!(s.sign(b"hello").unwrap().len(), 64);
599    }
600
601    #[test]
602    fn can_load_rsa2048_pkcs8() {
603        let key =
604            PrivatePkcs8KeyDer::from(&include_bytes!("../../testdata/rsa2048key.pkcs8.der")[..]);
605        assert!(any_eddsa_type(&key).is_err());
606        let key = PrivateKeyDer::Pkcs8(key);
607        assert!(any_supported_type(&key).is_ok());
608        assert!(any_ecdsa_type(&key).is_err());
609    }
610
611    #[test]
612    fn can_load_rsa2048_pkcs1() {
613        let key = PrivateKeyDer::Pkcs1(PrivatePkcs1KeyDer::from(
614            &include_bytes!("../../testdata/rsa2048key.pkcs1.der")[..],
615        ));
616        assert!(any_supported_type(&key).is_ok());
617        assert!(any_ecdsa_type(&key).is_err());
618    }
619
620    #[test]
621    fn can_sign_rsa2048() {
622        let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
623            &include_bytes!("../../testdata/rsa2048key.pkcs8.der")[..],
624        ));
625
626        let k = any_supported_type(&key).unwrap();
627        assert_eq!(format!("{k:?}"), "RsaSigningKey { algorithm: RSA }");
628        assert_eq!(k.algorithm(), SignatureAlgorithm::RSA);
629
630        assert!(
631            k.choose_scheme(&[SignatureScheme::ECDSA_NISTP256_SHA256])
632                .is_none()
633        );
634        assert!(
635            k.choose_scheme(&[SignatureScheme::ED25519])
636                .is_none()
637        );
638
639        let s = k
640            .choose_scheme(&[SignatureScheme::RSA_PSS_SHA256])
641            .unwrap();
642        assert_eq!(format!("{s:?}"), "RsaSigner { scheme: RSA_PSS_SHA256 }");
643        assert_eq!(s.scheme(), SignatureScheme::RSA_PSS_SHA256);
644        assert_eq!(s.sign(b"hello").unwrap().len(), 256);
645
646        for scheme in &[
647            SignatureScheme::RSA_PKCS1_SHA256,
648            SignatureScheme::RSA_PKCS1_SHA384,
649            SignatureScheme::RSA_PKCS1_SHA512,
650            SignatureScheme::RSA_PSS_SHA256,
651            SignatureScheme::RSA_PSS_SHA384,
652            SignatureScheme::RSA_PSS_SHA512,
653        ] {
654            k.choose_scheme(&[*scheme]).unwrap();
655        }
656    }
657
658    #[test]
659    fn cannot_load_invalid_pkcs8_encoding() {
660        let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(&b"invalid"[..]));
661        assert_eq!(
662            any_supported_type(&key).err(),
663            Some(Error::General(
664                "failed to parse private key as RSA, ECDSA, or EdDSA".into()
665            ))
666        );
667        assert_eq!(
668            any_ecdsa_type(&key).err(),
669            Some(Error::General(
670                "failed to parse ECDSA private key as PKCS#8 or SEC1".into()
671            ))
672        );
673        assert_eq!(
674            RsaSigningKey::new(&key).err(),
675            Some(Error::General(
676                "failed to parse RSA private key: InvalidEncoding".into()
677            ))
678        );
679    }
680}
681
682#[cfg(bench)]
683mod benchmarks {
684    use super::{PrivateKeyDer, PrivatePkcs8KeyDer, SignatureScheme};
685
686    #[bench]
687    fn bench_rsa2048_pkcs1_sha256(b: &mut test::Bencher) {
688        let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
689            &include_bytes!("../../testdata/rsa2048key.pkcs8.der")[..],
690        ));
691        let sk = super::any_supported_type(&key).unwrap();
692        let signer = sk
693            .choose_scheme(&[SignatureScheme::RSA_PKCS1_SHA256])
694            .unwrap();
695
696        b.iter(|| {
697            test::black_box(
698                signer
699                    .sign(SAMPLE_TLS13_MESSAGE)
700                    .unwrap(),
701            );
702        });
703    }
704
705    #[bench]
706    fn bench_rsa2048_pss_sha256(b: &mut test::Bencher) {
707        let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
708            &include_bytes!("../../testdata/rsa2048key.pkcs8.der")[..],
709        ));
710        let sk = super::any_supported_type(&key).unwrap();
711        let signer = sk
712            .choose_scheme(&[SignatureScheme::RSA_PSS_SHA256])
713            .unwrap();
714
715        b.iter(|| {
716            test::black_box(
717                signer
718                    .sign(SAMPLE_TLS13_MESSAGE)
719                    .unwrap(),
720            );
721        });
722    }
723
724    #[bench]
725    fn bench_eddsa(b: &mut test::Bencher) {
726        let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
727            &include_bytes!("../../testdata/eddsakey.der")[..],
728        ));
729        let sk = super::any_supported_type(&key).unwrap();
730        let signer = sk
731            .choose_scheme(&[SignatureScheme::ED25519])
732            .unwrap();
733
734        b.iter(|| {
735            test::black_box(
736                signer
737                    .sign(SAMPLE_TLS13_MESSAGE)
738                    .unwrap(),
739            );
740        });
741    }
742
743    #[bench]
744    fn bench_ecdsa_p256_sha256(b: &mut test::Bencher) {
745        let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
746            &include_bytes!("../../testdata/nistp256key.pkcs8.der")[..],
747        ));
748        let sk = super::any_supported_type(&key).unwrap();
749        let signer = sk
750            .choose_scheme(&[SignatureScheme::ECDSA_NISTP256_SHA256])
751            .unwrap();
752
753        b.iter(|| {
754            test::black_box(
755                signer
756                    .sign(SAMPLE_TLS13_MESSAGE)
757                    .unwrap(),
758            );
759        });
760    }
761
762    #[bench]
763    fn bench_ecdsa_p384_sha384(b: &mut test::Bencher) {
764        let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
765            &include_bytes!("../../testdata/nistp384key.pkcs8.der")[..],
766        ));
767        let sk = super::any_supported_type(&key).unwrap();
768        let signer = sk
769            .choose_scheme(&[SignatureScheme::ECDSA_NISTP384_SHA384])
770            .unwrap();
771
772        b.iter(|| {
773            test::black_box(
774                signer
775                    .sign(SAMPLE_TLS13_MESSAGE)
776                    .unwrap(),
777            );
778        });
779    }
780
781    #[bench]
782    fn bench_ecdsa_p521_sha512(b: &mut test::Bencher) {
783        let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
784            &include_bytes!("../../testdata/nistp521key.pkcs8.der")[..],
785        ));
786        let sk = super::any_supported_type(&key).unwrap();
787        let signer = sk
788            .choose_scheme(&[SignatureScheme::ECDSA_NISTP521_SHA512])
789            .unwrap();
790
791        b.iter(|| {
792            test::black_box(
793                signer
794                    .sign(SAMPLE_TLS13_MESSAGE)
795                    .unwrap(),
796            );
797        });
798    }
799
800    #[bench]
801    fn bench_load_and_validate_rsa2048(b: &mut test::Bencher) {
802        let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
803            &include_bytes!("../../testdata/rsa2048key.pkcs8.der")[..],
804        ));
805
806        b.iter(|| {
807            test::black_box(super::any_supported_type(&key).unwrap());
808        });
809    }
810
811    #[bench]
812    fn bench_load_and_validate_rsa4096(b: &mut test::Bencher) {
813        let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
814            &include_bytes!("../../testdata/rsa4096key.pkcs8.der")[..],
815        ));
816
817        b.iter(|| {
818            test::black_box(super::any_supported_type(&key).unwrap());
819        });
820    }
821
822    #[bench]
823    fn bench_load_and_validate_p256(b: &mut test::Bencher) {
824        let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
825            &include_bytes!("../../testdata/nistp256key.pkcs8.der")[..],
826        ));
827
828        b.iter(|| {
829            test::black_box(super::any_ecdsa_type(&key).unwrap());
830        });
831    }
832
833    #[bench]
834    fn bench_load_and_validate_p384(b: &mut test::Bencher) {
835        let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
836            &include_bytes!("../../testdata/nistp384key.pkcs8.der")[..],
837        ));
838
839        b.iter(|| {
840            test::black_box(super::any_ecdsa_type(&key).unwrap());
841        });
842    }
843
844    #[bench]
845    fn bench_load_and_validate_p521(b: &mut test::Bencher) {
846        let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
847            &include_bytes!("../../testdata/nistp521key.pkcs8.der")[..],
848        ));
849
850        b.iter(|| {
851            test::black_box(super::any_ecdsa_type(&key).unwrap());
852        });
853    }
854
855    #[bench]
856    fn bench_load_and_validate_eddsa(b: &mut test::Bencher) {
857        let key = PrivatePkcs8KeyDer::from(&include_bytes!("../../testdata/eddsakey.der")[..]);
858
859        b.iter(|| {
860            test::black_box(super::any_eddsa_type(&key).unwrap());
861        });
862    }
863
864    const SAMPLE_TLS13_MESSAGE: &[u8] = &[
865        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
866        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
867        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
868        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
869        0x20, 0x20, 0x20, 0x20, 0x54, 0x4c, 0x53, 0x20, 0x31, 0x2e, 0x33, 0x2c, 0x20, 0x73, 0x65,
870        0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
871        0x65, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x00, 0x04, 0xca, 0xc4, 0x48, 0x0e, 0x70, 0xf2,
872        0x1b, 0xa9, 0x1c, 0x16, 0xca, 0x90, 0x48, 0xbe, 0x28, 0x2f, 0xc7, 0xf8, 0x9b, 0x87, 0x72,
873        0x93, 0xda, 0x4d, 0x2f, 0x80, 0x80, 0x60, 0x1a, 0xd3, 0x08, 0xe2, 0xb7, 0x86, 0x14, 0x1b,
874        0x54, 0xda, 0x9a, 0xc9, 0x6d, 0xe9, 0x66, 0xb4, 0x9f, 0xe2, 0x2c,
875    ];
876}