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(self.key.clone(), *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: self.key.clone(),
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: self.key.clone(),
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!(format!("{k:?}"), "Ed25519SigningKey { algorithm: ED25519 }");
559        assert_eq!(k.algorithm(), SignatureAlgorithm::ED25519);
560
561        assert!(
562            k.choose_scheme(&[SignatureScheme::RSA_PKCS1_SHA256])
563                .is_none()
564        );
565        assert!(
566            k.choose_scheme(&[SignatureScheme::ECDSA_NISTP256_SHA256])
567                .is_none()
568        );
569        let s = k
570            .choose_scheme(&[SignatureScheme::ED25519])
571            .unwrap();
572        assert_eq!(format!("{s:?}"), "Ed25519Signer { scheme: ED25519 }");
573        assert_eq!(s.scheme(), SignatureScheme::ED25519);
574        assert_eq!(s.sign(b"hello").unwrap().len(), 64);
575    }
576
577    #[test]
578    fn can_load_rsa2048_pkcs8() {
579        let key =
580            PrivatePkcs8KeyDer::from(&include_bytes!("../../testdata/rsa2048key.pkcs8.der")[..]);
581        assert!(any_eddsa_type(&key).is_err());
582        let key = PrivateKeyDer::Pkcs8(key);
583        assert!(any_supported_type(&key).is_ok());
584        assert!(any_ecdsa_type(&key).is_err());
585    }
586
587    #[test]
588    fn can_load_rsa2048_pkcs1() {
589        let key = PrivateKeyDer::Pkcs1(PrivatePkcs1KeyDer::from(
590            &include_bytes!("../../testdata/rsa2048key.pkcs1.der")[..],
591        ));
592        assert!(any_supported_type(&key).is_ok());
593        assert!(any_ecdsa_type(&key).is_err());
594    }
595
596    #[test]
597    fn can_sign_rsa2048() {
598        let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
599            &include_bytes!("../../testdata/rsa2048key.pkcs8.der")[..],
600        ));
601
602        let k = any_supported_type(&key).unwrap();
603        assert_eq!(format!("{k:?}"), "RsaSigningKey { algorithm: RSA }");
604        assert_eq!(k.algorithm(), SignatureAlgorithm::RSA);
605
606        assert!(
607            k.choose_scheme(&[SignatureScheme::ECDSA_NISTP256_SHA256])
608                .is_none()
609        );
610        assert!(
611            k.choose_scheme(&[SignatureScheme::ED25519])
612                .is_none()
613        );
614
615        let s = k
616            .choose_scheme(&[SignatureScheme::RSA_PSS_SHA256])
617            .unwrap();
618        assert_eq!(format!("{s:?}"), "RsaSigner { scheme: RSA_PSS_SHA256 }");
619        assert_eq!(s.scheme(), SignatureScheme::RSA_PSS_SHA256);
620        assert_eq!(s.sign(b"hello").unwrap().len(), 256);
621
622        for scheme in &[
623            SignatureScheme::RSA_PKCS1_SHA256,
624            SignatureScheme::RSA_PKCS1_SHA384,
625            SignatureScheme::RSA_PKCS1_SHA512,
626            SignatureScheme::RSA_PSS_SHA256,
627            SignatureScheme::RSA_PSS_SHA384,
628            SignatureScheme::RSA_PSS_SHA512,
629        ] {
630            k.choose_scheme(&[*scheme]).unwrap();
631        }
632    }
633
634    #[test]
635    fn cannot_load_invalid_pkcs8_encoding() {
636        let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(&b"invalid"[..]));
637        assert_eq!(
638            any_supported_type(&key).err(),
639            Some(Error::General(
640                "failed to parse private key as RSA, ECDSA, or EdDSA".into()
641            ))
642        );
643        assert_eq!(
644            any_ecdsa_type(&key).err(),
645            Some(Error::General(
646                "failed to parse ECDSA private key as PKCS#8 or SEC1".into()
647            ))
648        );
649        assert_eq!(
650            RsaSigningKey::new(&key).err(),
651            Some(Error::General(
652                "failed to parse RSA private key: InvalidEncoding".into()
653            ))
654        );
655    }
656}
657
658#[cfg(bench)]
659mod benchmarks {
660    use super::{PrivateKeyDer, PrivatePkcs8KeyDer, SignatureScheme};
661
662    #[bench]
663    fn bench_rsa2048_pkcs1_sha256(b: &mut test::Bencher) {
664        let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
665            &include_bytes!("../../testdata/rsa2048key.pkcs8.der")[..],
666        ));
667        let sk = super::any_supported_type(&key).unwrap();
668        let signer = sk
669            .choose_scheme(&[SignatureScheme::RSA_PKCS1_SHA256])
670            .unwrap();
671
672        b.iter(|| {
673            test::black_box(
674                signer
675                    .sign(SAMPLE_TLS13_MESSAGE)
676                    .unwrap(),
677            );
678        });
679    }
680
681    #[bench]
682    fn bench_rsa2048_pss_sha256(b: &mut test::Bencher) {
683        let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
684            &include_bytes!("../../testdata/rsa2048key.pkcs8.der")[..],
685        ));
686        let sk = super::any_supported_type(&key).unwrap();
687        let signer = sk
688            .choose_scheme(&[SignatureScheme::RSA_PSS_SHA256])
689            .unwrap();
690
691        b.iter(|| {
692            test::black_box(
693                signer
694                    .sign(SAMPLE_TLS13_MESSAGE)
695                    .unwrap(),
696            );
697        });
698    }
699
700    #[bench]
701    fn bench_eddsa(b: &mut test::Bencher) {
702        let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
703            &include_bytes!("../../testdata/eddsakey.der")[..],
704        ));
705        let sk = super::any_supported_type(&key).unwrap();
706        let signer = sk
707            .choose_scheme(&[SignatureScheme::ED25519])
708            .unwrap();
709
710        b.iter(|| {
711            test::black_box(
712                signer
713                    .sign(SAMPLE_TLS13_MESSAGE)
714                    .unwrap(),
715            );
716        });
717    }
718
719    #[bench]
720    fn bench_ecdsa_p256_sha256(b: &mut test::Bencher) {
721        let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
722            &include_bytes!("../../testdata/nistp256key.pkcs8.der")[..],
723        ));
724        let sk = super::any_supported_type(&key).unwrap();
725        let signer = sk
726            .choose_scheme(&[SignatureScheme::ECDSA_NISTP256_SHA256])
727            .unwrap();
728
729        b.iter(|| {
730            test::black_box(
731                signer
732                    .sign(SAMPLE_TLS13_MESSAGE)
733                    .unwrap(),
734            );
735        });
736    }
737
738    #[bench]
739    fn bench_ecdsa_p384_sha384(b: &mut test::Bencher) {
740        let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
741            &include_bytes!("../../testdata/nistp384key.pkcs8.der")[..],
742        ));
743        let sk = super::any_supported_type(&key).unwrap();
744        let signer = sk
745            .choose_scheme(&[SignatureScheme::ECDSA_NISTP384_SHA384])
746            .unwrap();
747
748        b.iter(|| {
749            test::black_box(
750                signer
751                    .sign(SAMPLE_TLS13_MESSAGE)
752                    .unwrap(),
753            );
754        });
755    }
756
757    #[bench]
758    fn bench_load_and_validate_rsa2048(b: &mut test::Bencher) {
759        let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
760            &include_bytes!("../../testdata/rsa2048key.pkcs8.der")[..],
761        ));
762
763        b.iter(|| {
764            test::black_box(super::any_supported_type(&key).unwrap());
765        });
766    }
767
768    #[bench]
769    fn bench_load_and_validate_rsa4096(b: &mut test::Bencher) {
770        let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
771            &include_bytes!("../../testdata/rsa4096key.pkcs8.der")[..],
772        ));
773
774        b.iter(|| {
775            test::black_box(super::any_supported_type(&key).unwrap());
776        });
777    }
778
779    #[bench]
780    fn bench_load_and_validate_p256(b: &mut test::Bencher) {
781        let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
782            &include_bytes!("../../testdata/nistp256key.pkcs8.der")[..],
783        ));
784
785        b.iter(|| {
786            test::black_box(super::any_ecdsa_type(&key).unwrap());
787        });
788    }
789
790    #[bench]
791    fn bench_load_and_validate_p384(b: &mut test::Bencher) {
792        let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
793            &include_bytes!("../../testdata/nistp384key.pkcs8.der")[..],
794        ));
795
796        b.iter(|| {
797            test::black_box(super::any_ecdsa_type(&key).unwrap());
798        });
799    }
800
801    #[bench]
802    fn bench_load_and_validate_eddsa(b: &mut test::Bencher) {
803        let key = PrivatePkcs8KeyDer::from(&include_bytes!("../../testdata/eddsakey.der")[..]);
804
805        b.iter(|| {
806            test::black_box(super::any_eddsa_type(&key).unwrap());
807        });
808    }
809
810    const SAMPLE_TLS13_MESSAGE: &[u8] = &[
811        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
812        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
813        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
814        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
815        0x20, 0x20, 0x20, 0x20, 0x54, 0x4c, 0x53, 0x20, 0x31, 0x2e, 0x33, 0x2c, 0x20, 0x73, 0x65,
816        0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
817        0x65, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x00, 0x04, 0xca, 0xc4, 0x48, 0x0e, 0x70, 0xf2,
818        0x1b, 0xa9, 0x1c, 0x16, 0xca, 0x90, 0x48, 0xbe, 0x28, 0x2f, 0xc7, 0xf8, 0x9b, 0x87, 0x72,
819        0x93, 0xda, 0x4d, 0x2f, 0x80, 0x80, 0x60, 0x1a, 0xd3, 0x08, 0xe2, 0xb7, 0x86, 0x14, 0x1b,
820        0x54, 0xda, 0x9a, 0xc9, 0x6d, 0xe9, 0x66, 0xb4, 0x9f, 0xe2, 0x2c,
821    ];
822}