Skip to main content

rustls_ring/
sign.rs

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