Skip to main content

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
308            .algorithm()
309            .unwrap_or(SignatureAlgorithm::Unknown(0))
310    }
311}
312
313impl Debug for EcdsaSigningKey {
314    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
315        f.debug_struct("EcdsaSigningKey")
316            .field("algorithm", &self.algorithm())
317            .finish()
318    }
319}
320
321struct EcdsaSigner {
322    key: Arc<EcdsaKeyPair>,
323    scheme: SignatureScheme,
324}
325
326impl Signer for EcdsaSigner {
327    fn sign(&self, message: &[u8]) -> Result<Vec<u8>, Error> {
328        let rng = SystemRandom::new();
329        self.key
330            .sign(&rng, message)
331            .map_err(|_| Error::General("signing failed".into()))
332            .map(|sig| sig.as_ref().into())
333    }
334
335    fn scheme(&self) -> SignatureScheme {
336        self.scheme
337    }
338}
339
340impl Debug for EcdsaSigner {
341    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
342        f.debug_struct("EcdsaSigner")
343            .field("scheme", &self.scheme)
344            .finish()
345    }
346}
347
348/// A SigningKey that uses exactly one TLS-level SignatureScheme
349/// and one ring-level signature::SigningAlgorithm.
350///
351/// Compare this to RsaSigningKey, which for a particular key is
352/// willing to sign with several algorithms.  This is quite poor
353/// cryptography practice, but is necessary because a given RSA key
354/// is expected to work in TLS1.2 (PKCS#1 signatures) and TLS1.3
355/// (PSS signatures) -- nobody is willing to obtain certificates for
356/// different protocol versions.
357///
358/// Currently this is only implemented for Ed25519 keys.
359struct Ed25519SigningKey {
360    key: Arc<Ed25519KeyPair>,
361    scheme: SignatureScheme,
362}
363
364impl Ed25519SigningKey {
365    /// Make a new `Ed25519SigningKey` from a DER encoding in PKCS#8 format,
366    /// expecting a key usable with precisely the given signature scheme.
367    fn new(der: &PrivatePkcs8KeyDer<'_>, scheme: SignatureScheme) -> Result<Self, Error> {
368        match Ed25519KeyPair::from_pkcs8_maybe_unchecked(der.secret_pkcs8_der()) {
369            Ok(key_pair) => Ok(Self {
370                key: Arc::new(key_pair),
371                scheme,
372            }),
373            Err(e) => Err(Error::General(format!(
374                "failed to parse Ed25519 private key: {e}"
375            ))),
376        }
377    }
378}
379
380impl SigningKey for Ed25519SigningKey {
381    fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn Signer>> {
382        if offered.contains(&self.scheme) {
383            Some(Box::new(Ed25519Signer {
384                key: self.key.clone(),
385                scheme: self.scheme,
386            }))
387        } else {
388            None
389        }
390    }
391
392    fn public_key(&self) -> Option<SubjectPublicKeyInfoDer<'_>> {
393        Some(public_key_to_spki(&alg_id::ED25519, self.key.public_key()))
394    }
395
396    fn algorithm(&self) -> SignatureAlgorithm {
397        self.scheme
398            .algorithm()
399            .unwrap_or(SignatureAlgorithm::Unknown(0))
400    }
401}
402
403impl Debug for Ed25519SigningKey {
404    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
405        f.debug_struct("Ed25519SigningKey")
406            .field("algorithm", &self.algorithm())
407            .finish()
408    }
409}
410
411struct Ed25519Signer {
412    key: Arc<Ed25519KeyPair>,
413    scheme: SignatureScheme,
414}
415
416impl Signer for Ed25519Signer {
417    fn sign(&self, message: &[u8]) -> Result<Vec<u8>, Error> {
418        Ok(self.key.sign(message).as_ref().into())
419    }
420
421    fn scheme(&self) -> SignatureScheme {
422        self.scheme
423    }
424}
425
426impl Debug for Ed25519Signer {
427    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
428        f.debug_struct("Ed25519Signer")
429            .field("scheme", &self.scheme)
430            .finish()
431    }
432}
433
434#[cfg(test)]
435mod tests {
436    use alloc::format;
437
438    use pki_types::{PrivatePkcs1KeyDer, PrivateSec1KeyDer};
439
440    use super::*;
441
442    #[test]
443    fn can_load_ecdsa_nistp256_pkcs8() {
444        let key =
445            PrivatePkcs8KeyDer::from(&include_bytes!("../../testdata/nistp256key.pkcs8.der")[..]);
446        assert!(any_eddsa_type(&key).is_err());
447        let key = PrivateKeyDer::Pkcs8(key);
448        assert!(any_supported_type(&key).is_ok());
449        assert!(any_ecdsa_type(&key).is_ok());
450    }
451
452    #[test]
453    fn can_load_ecdsa_nistp256_sec1() {
454        let key = PrivateKeyDer::Sec1(PrivateSec1KeyDer::from(
455            &include_bytes!("../../testdata/nistp256key.der")[..],
456        ));
457        assert!(any_supported_type(&key).is_ok());
458        assert!(any_ecdsa_type(&key).is_ok());
459    }
460
461    #[test]
462    fn can_sign_ecdsa_nistp256() {
463        let key = PrivateKeyDer::Sec1(PrivateSec1KeyDer::from(
464            &include_bytes!("../../testdata/nistp256key.der")[..],
465        ));
466
467        let k = any_supported_type(&key).unwrap();
468        assert_eq!(format!("{k:?}"), "EcdsaSigningKey { algorithm: ECDSA }");
469        assert_eq!(k.algorithm(), SignatureAlgorithm::ECDSA);
470
471        assert!(
472            k.choose_scheme(&[SignatureScheme::RSA_PKCS1_SHA256])
473                .is_none()
474        );
475        assert!(
476            k.choose_scheme(&[SignatureScheme::ECDSA_NISTP384_SHA384])
477                .is_none()
478        );
479        let s = k
480            .choose_scheme(&[SignatureScheme::ECDSA_NISTP256_SHA256])
481            .unwrap();
482        assert_eq!(
483            format!("{s:?}"),
484            "EcdsaSigner { scheme: ECDSA_NISTP256_SHA256 }"
485        );
486        assert_eq!(s.scheme(), SignatureScheme::ECDSA_NISTP256_SHA256);
487        // nb. signature is variable length and asn.1-encoded
488        assert!(
489            s.sign(b"hello")
490                .unwrap()
491                .starts_with(&[0x30])
492        );
493    }
494
495    #[test]
496    fn can_load_ecdsa_nistp384_pkcs8() {
497        let key =
498            PrivatePkcs8KeyDer::from(&include_bytes!("../../testdata/nistp384key.pkcs8.der")[..]);
499        assert!(any_eddsa_type(&key).is_err());
500        let key = PrivateKeyDer::Pkcs8(key);
501        assert!(any_supported_type(&key).is_ok());
502        assert!(any_ecdsa_type(&key).is_ok());
503    }
504
505    #[test]
506    fn can_load_ecdsa_nistp384_sec1() {
507        let key = PrivateKeyDer::Sec1(PrivateSec1KeyDer::from(
508            &include_bytes!("../../testdata/nistp384key.der")[..],
509        ));
510        assert!(any_supported_type(&key).is_ok());
511        assert!(any_ecdsa_type(&key).is_ok());
512    }
513
514    #[test]
515    fn can_sign_ecdsa_nistp384() {
516        let key = PrivateKeyDer::Sec1(PrivateSec1KeyDer::from(
517            &include_bytes!("../../testdata/nistp384key.der")[..],
518        ));
519
520        let k = any_supported_type(&key).unwrap();
521        assert_eq!(format!("{k:?}"), "EcdsaSigningKey { algorithm: ECDSA }");
522        assert_eq!(k.algorithm(), SignatureAlgorithm::ECDSA);
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::ECDSA_NISTP384_SHA384])
534            .unwrap();
535        assert_eq!(
536            format!("{s:?}"),
537            "EcdsaSigner { scheme: ECDSA_NISTP384_SHA384 }"
538        );
539        assert_eq!(s.scheme(), SignatureScheme::ECDSA_NISTP384_SHA384);
540        // nb. signature is variable length and asn.1-encoded
541        assert!(
542            s.sign(b"hello")
543                .unwrap()
544                .starts_with(&[0x30])
545        );
546    }
547
548    #[test]
549    fn can_load_eddsa_pkcs8() {
550        let key = PrivatePkcs8KeyDer::from(&include_bytes!("../../testdata/eddsakey.der")[..]);
551        assert!(any_eddsa_type(&key).is_ok());
552        let key = PrivateKeyDer::Pkcs8(key);
553        assert!(any_supported_type(&key).is_ok());
554        assert!(any_ecdsa_type(&key).is_err());
555    }
556
557    #[test]
558    fn can_sign_eddsa() {
559        let key = PrivatePkcs8KeyDer::from(&include_bytes!("../../testdata/eddsakey.der")[..]);
560
561        let k = any_eddsa_type(&key).unwrap();
562        assert_eq!(format!("{k:?}"), "Ed25519SigningKey { algorithm: ED25519 }");
563        assert_eq!(k.algorithm(), SignatureAlgorithm::ED25519);
564
565        assert!(
566            k.choose_scheme(&[SignatureScheme::RSA_PKCS1_SHA256])
567                .is_none()
568        );
569        assert!(
570            k.choose_scheme(&[SignatureScheme::ECDSA_NISTP256_SHA256])
571                .is_none()
572        );
573        let s = k
574            .choose_scheme(&[SignatureScheme::ED25519])
575            .unwrap();
576        assert_eq!(format!("{s:?}"), "Ed25519Signer { scheme: ED25519 }");
577        assert_eq!(s.scheme(), SignatureScheme::ED25519);
578        assert_eq!(s.sign(b"hello").unwrap().len(), 64);
579    }
580
581    #[test]
582    fn can_load_rsa2048_pkcs8() {
583        let key =
584            PrivatePkcs8KeyDer::from(&include_bytes!("../../testdata/rsa2048key.pkcs8.der")[..]);
585        assert!(any_eddsa_type(&key).is_err());
586        let key = PrivateKeyDer::Pkcs8(key);
587        assert!(any_supported_type(&key).is_ok());
588        assert!(any_ecdsa_type(&key).is_err());
589    }
590
591    #[test]
592    fn can_load_rsa2048_pkcs1() {
593        let key = PrivateKeyDer::Pkcs1(PrivatePkcs1KeyDer::from(
594            &include_bytes!("../../testdata/rsa2048key.pkcs1.der")[..],
595        ));
596        assert!(any_supported_type(&key).is_ok());
597        assert!(any_ecdsa_type(&key).is_err());
598    }
599
600    #[test]
601    fn can_sign_rsa2048() {
602        let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
603            &include_bytes!("../../testdata/rsa2048key.pkcs8.der")[..],
604        ));
605
606        let k = any_supported_type(&key).unwrap();
607        assert_eq!(format!("{k:?}"), "RsaSigningKey { algorithm: RSA }");
608        assert_eq!(k.algorithm(), SignatureAlgorithm::RSA);
609
610        assert!(
611            k.choose_scheme(&[SignatureScheme::ECDSA_NISTP256_SHA256])
612                .is_none()
613        );
614        assert!(
615            k.choose_scheme(&[SignatureScheme::ED25519])
616                .is_none()
617        );
618
619        let s = k
620            .choose_scheme(&[SignatureScheme::RSA_PSS_SHA256])
621            .unwrap();
622        assert_eq!(format!("{s:?}"), "RsaSigner { scheme: RSA_PSS_SHA256 }");
623        assert_eq!(s.scheme(), SignatureScheme::RSA_PSS_SHA256);
624        assert_eq!(s.sign(b"hello").unwrap().len(), 256);
625
626        for scheme in &[
627            SignatureScheme::RSA_PKCS1_SHA256,
628            SignatureScheme::RSA_PKCS1_SHA384,
629            SignatureScheme::RSA_PKCS1_SHA512,
630            SignatureScheme::RSA_PSS_SHA256,
631            SignatureScheme::RSA_PSS_SHA384,
632            SignatureScheme::RSA_PSS_SHA512,
633        ] {
634            k.choose_scheme(&[*scheme]).unwrap();
635        }
636    }
637
638    #[test]
639    fn cannot_load_invalid_pkcs8_encoding() {
640        let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(&b"invalid"[..]));
641        assert_eq!(
642            any_supported_type(&key).err(),
643            Some(Error::General(
644                "failed to parse private key as RSA, ECDSA, or EdDSA".into()
645            ))
646        );
647        assert_eq!(
648            any_ecdsa_type(&key).err(),
649            Some(Error::General(
650                "failed to parse ECDSA private key as PKCS#8 or SEC1".into()
651            ))
652        );
653        assert_eq!(
654            RsaSigningKey::new(&key).err(),
655            Some(Error::General(
656                "failed to parse RSA private key: InvalidEncoding".into()
657            ))
658        );
659    }
660}
661
662#[cfg(bench)]
663mod benchmarks {
664    use super::{PrivateKeyDer, PrivatePkcs8KeyDer, SignatureScheme};
665
666    #[bench]
667    fn bench_rsa2048_pkcs1_sha256(b: &mut test::Bencher) {
668        let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
669            &include_bytes!("../../testdata/rsa2048key.pkcs8.der")[..],
670        ));
671        let sk = super::any_supported_type(&key).unwrap();
672        let signer = sk
673            .choose_scheme(&[SignatureScheme::RSA_PKCS1_SHA256])
674            .unwrap();
675
676        b.iter(|| {
677            test::black_box(
678                signer
679                    .sign(SAMPLE_TLS13_MESSAGE)
680                    .unwrap(),
681            );
682        });
683    }
684
685    #[bench]
686    fn bench_rsa2048_pss_sha256(b: &mut test::Bencher) {
687        let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
688            &include_bytes!("../../testdata/rsa2048key.pkcs8.der")[..],
689        ));
690        let sk = super::any_supported_type(&key).unwrap();
691        let signer = sk
692            .choose_scheme(&[SignatureScheme::RSA_PSS_SHA256])
693            .unwrap();
694
695        b.iter(|| {
696            test::black_box(
697                signer
698                    .sign(SAMPLE_TLS13_MESSAGE)
699                    .unwrap(),
700            );
701        });
702    }
703
704    #[bench]
705    fn bench_eddsa(b: &mut test::Bencher) {
706        let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
707            &include_bytes!("../../testdata/eddsakey.der")[..],
708        ));
709        let sk = super::any_supported_type(&key).unwrap();
710        let signer = sk
711            .choose_scheme(&[SignatureScheme::ED25519])
712            .unwrap();
713
714        b.iter(|| {
715            test::black_box(
716                signer
717                    .sign(SAMPLE_TLS13_MESSAGE)
718                    .unwrap(),
719            );
720        });
721    }
722
723    #[bench]
724    fn bench_ecdsa_p256_sha256(b: &mut test::Bencher) {
725        let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
726            &include_bytes!("../../testdata/nistp256key.pkcs8.der")[..],
727        ));
728        let sk = super::any_supported_type(&key).unwrap();
729        let signer = sk
730            .choose_scheme(&[SignatureScheme::ECDSA_NISTP256_SHA256])
731            .unwrap();
732
733        b.iter(|| {
734            test::black_box(
735                signer
736                    .sign(SAMPLE_TLS13_MESSAGE)
737                    .unwrap(),
738            );
739        });
740    }
741
742    #[bench]
743    fn bench_ecdsa_p384_sha384(b: &mut test::Bencher) {
744        let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
745            &include_bytes!("../../testdata/nistp384key.pkcs8.der")[..],
746        ));
747        let sk = super::any_supported_type(&key).unwrap();
748        let signer = sk
749            .choose_scheme(&[SignatureScheme::ECDSA_NISTP384_SHA384])
750            .unwrap();
751
752        b.iter(|| {
753            test::black_box(
754                signer
755                    .sign(SAMPLE_TLS13_MESSAGE)
756                    .unwrap(),
757            );
758        });
759    }
760
761    #[bench]
762    fn bench_load_and_validate_rsa2048(b: &mut test::Bencher) {
763        let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
764            &include_bytes!("../../testdata/rsa2048key.pkcs8.der")[..],
765        ));
766
767        b.iter(|| {
768            test::black_box(super::any_supported_type(&key).unwrap());
769        });
770    }
771
772    #[bench]
773    fn bench_load_and_validate_rsa4096(b: &mut test::Bencher) {
774        let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
775            &include_bytes!("../../testdata/rsa4096key.pkcs8.der")[..],
776        ));
777
778        b.iter(|| {
779            test::black_box(super::any_supported_type(&key).unwrap());
780        });
781    }
782
783    #[bench]
784    fn bench_load_and_validate_p256(b: &mut test::Bencher) {
785        let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
786            &include_bytes!("../../testdata/nistp256key.pkcs8.der")[..],
787        ));
788
789        b.iter(|| {
790            test::black_box(super::any_ecdsa_type(&key).unwrap());
791        });
792    }
793
794    #[bench]
795    fn bench_load_and_validate_p384(b: &mut test::Bencher) {
796        let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
797            &include_bytes!("../../testdata/nistp384key.pkcs8.der")[..],
798        ));
799
800        b.iter(|| {
801            test::black_box(super::any_ecdsa_type(&key).unwrap());
802        });
803    }
804
805    #[bench]
806    fn bench_load_and_validate_eddsa(b: &mut test::Bencher) {
807        let key = PrivatePkcs8KeyDer::from(&include_bytes!("../../testdata/eddsakey.der")[..]);
808
809        b.iter(|| {
810            test::black_box(super::any_eddsa_type(&key).unwrap());
811        });
812    }
813
814    const SAMPLE_TLS13_MESSAGE: &[u8] = &[
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, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
819        0x20, 0x20, 0x20, 0x20, 0x54, 0x4c, 0x53, 0x20, 0x31, 0x2e, 0x33, 0x2c, 0x20, 0x73, 0x65,
820        0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
821        0x65, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x00, 0x04, 0xca, 0xc4, 0x48, 0x0e, 0x70, 0xf2,
822        0x1b, 0xa9, 0x1c, 0x16, 0xca, 0x90, 0x48, 0xbe, 0x28, 0x2f, 0xc7, 0xf8, 0x9b, 0x87, 0x72,
823        0x93, 0xda, 0x4d, 0x2f, 0x80, 0x80, 0x60, 0x1a, 0xd3, 0x08, 0xe2, 0xb7, 0x86, 0x14, 0x1b,
824        0x54, 0xda, 0x9a, 0xc9, 0x6d, 0xe9, 0x66, 0xb4, 0x9f, 0xe2, 0x2c,
825    ];
826}