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