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