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