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