rustls/crypto/ring/
sign.rs

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