Skip to main content

rustls/crypto/aws_lc_rs/
sign.rs

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