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