rustls/crypto/ring/
sign.rs

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