1
+ #[ cfg( feature = "crypto" ) ]
1
2
use std:: fmt;
2
3
3
4
#[ cfg( feature = "pem" ) ]
@@ -29,30 +30,23 @@ use crate::{sign_algo::SignatureAlgorithm, Error};
29
30
30
31
/// A key pair variant
31
32
#[ allow( clippy:: large_enum_variant) ]
33
+ #[ cfg( feature = "crypto" ) ]
32
34
pub ( crate ) enum KeyPairKind {
33
35
/// A Ecdsa key pair
34
- #[ cfg( feature = "crypto" ) ]
35
36
Ec ( EcdsaKeyPair ) ,
36
37
/// A Ed25519 key pair
37
- #[ cfg( feature = "crypto" ) ]
38
38
Ed ( Ed25519KeyPair ) ,
39
39
/// A RSA key pair
40
- #[ cfg( feature = "crypto" ) ]
41
40
Rsa ( RsaKeyPair , & ' static dyn RsaEncoding ) ,
42
- /// A remote key pair
43
- Remote ( Box < dyn SigningKey + Send + Sync > ) ,
44
41
}
45
42
43
+ #[ cfg( feature = "crypto" ) ]
46
44
impl fmt:: Debug for KeyPairKind {
47
45
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
48
46
match self {
49
- #[ cfg( feature = "crypto" ) ]
50
47
Self :: Ec ( key_pair) => write ! ( f, "{:?}" , key_pair) ,
51
- #[ cfg( feature = "crypto" ) ]
52
48
Self :: Ed ( key_pair) => write ! ( f, "{:?}" , key_pair) ,
53
- #[ cfg( feature = "crypto" ) ]
54
49
Self :: Rsa ( key_pair, _) => write ! ( f, "{:?}" , key_pair) ,
55
- Self :: Remote ( _) => write ! ( f, "Box<dyn RemotePrivateKey>" ) ,
56
50
}
57
51
}
58
52
}
@@ -64,12 +58,14 @@ impl fmt::Debug for KeyPairKind {
64
58
/// `openssl genrsa` doesn't work. See ring's [documentation](ring::signature::RsaKeyPair::from_pkcs8)
65
59
/// for how to generate RSA keys in the wanted format
66
60
/// and conversion between the formats.
61
+ #[ cfg( feature = "crypto" ) ]
67
62
pub struct KeyPair {
68
63
pub ( crate ) kind : KeyPairKind ,
69
64
pub ( crate ) alg : & ' static SignatureAlgorithm ,
70
65
pub ( crate ) serialized_der : Vec < u8 > ,
71
66
}
72
67
68
+ #[ cfg( feature = "crypto" ) ]
73
69
impl fmt:: Debug for KeyPair {
74
70
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
75
71
f. debug_struct ( "KeyPair" )
@@ -80,6 +76,7 @@ impl fmt::Debug for KeyPair {
80
76
}
81
77
}
82
78
79
+ #[ cfg( feature = "crypto" ) ]
83
80
impl KeyPair {
84
81
/// Generate a new random [`PKCS_ECDSA_P256_SHA256`] key pair
85
82
#[ cfg( feature = "crypto" ) ]
@@ -187,15 +184,6 @@ impl KeyPair {
187
184
Self :: try_from ( private_key. contents ( ) )
188
185
}
189
186
190
- /// Obtains the key pair from a raw public key and a remote private key
191
- pub fn from_remote ( key_pair : Box < dyn SigningKey + Send + Sync > ) -> Result < Self , Error > {
192
- Ok ( Self {
193
- alg : key_pair. algorithm ( ) ,
194
- kind : KeyPairKind :: Remote ( key_pair) ,
195
- serialized_der : Vec :: new ( ) ,
196
- } )
197
- }
198
-
199
187
/// Obtains the key pair from a DER formatted key
200
188
/// using the specified [`SignatureAlgorithm`]
201
189
///
@@ -399,43 +387,12 @@ impl KeyPair {
399
387
std:: iter:: once ( self . alg )
400
388
}
401
389
402
- pub ( crate ) fn sign ( & self , msg : & [ u8 ] , writer : DERWriter ) -> Result < ( ) , Error > {
403
- match & self . kind {
404
- #[ cfg( feature = "crypto" ) ]
405
- KeyPairKind :: Ec ( kp) => {
406
- let system_random = SystemRandom :: new ( ) ;
407
- let signature = kp. sign ( & system_random, msg) . _err ( ) ?;
408
- let sig = & signature. as_ref ( ) ;
409
- writer. write_bitvec_bytes ( sig, & sig. len ( ) * 8 ) ;
410
- } ,
411
- #[ cfg( feature = "crypto" ) ]
412
- KeyPairKind :: Ed ( kp) => {
413
- let signature = kp. sign ( msg) ;
414
- let sig = & signature. as_ref ( ) ;
415
- writer. write_bitvec_bytes ( sig, & sig. len ( ) * 8 ) ;
416
- } ,
417
- #[ cfg( feature = "crypto" ) ]
418
- KeyPairKind :: Rsa ( kp, padding_alg) => {
419
- let system_random = SystemRandom :: new ( ) ;
420
- let mut signature = vec ! [ 0 ; rsa_key_pair_public_modulus_len( kp) ] ;
421
- kp. sign ( * padding_alg, & system_random, msg, & mut signature)
422
- . _err ( ) ?;
423
- let sig = & signature. as_ref ( ) ;
424
- writer. write_bitvec_bytes ( sig, & sig. len ( ) * 8 ) ;
425
- } ,
426
- KeyPairKind :: Remote ( kp) => {
427
- let signature = kp. sign ( msg) ?;
428
- writer. write_bitvec_bytes ( & signature, & signature. len ( ) * 8 ) ;
429
- } ,
430
- }
431
- Ok ( ( ) )
432
- }
433
-
434
390
/// Return the key pair's public key in DER format
435
391
///
436
392
/// The key is formatted according to the SubjectPublicKeyInfo struct of
437
393
/// X.509.
438
394
/// See [RFC 5280 section 4.1](https://tools.ietf.org/html/rfc5280#section-4.1).
395
+ #[ cfg( feature = "crypto" ) ]
439
396
pub fn public_key_der ( & self ) -> Vec < u8 > {
440
397
yasna:: construct_der ( |writer| serialize_public_key_der ( self , writer) )
441
398
}
@@ -454,11 +411,6 @@ impl KeyPair {
454
411
///
455
412
/// Panics if called on a remote key pair.
456
413
pub fn serialize_der ( & self ) -> Vec < u8 > {
457
- #[ cfg_attr( not( feature = "crypto" ) , allow( irrefutable_let_patterns) ) ]
458
- if let KeyPairKind :: Remote ( _) = self . kind {
459
- panic ! ( "Serializing a remote key pair is not supported" )
460
- }
461
-
462
414
self . serialized_der . clone ( )
463
415
}
464
416
@@ -467,24 +419,9 @@ impl KeyPair {
467
419
///
468
420
/// Panics if called on a remote key pair.
469
421
pub fn serialized_der ( & self ) -> & [ u8 ] {
470
- #[ cfg_attr( not( feature = "crypto" ) , allow( irrefutable_let_patterns) ) ]
471
- if let KeyPairKind :: Remote ( _) = self . kind {
472
- panic ! ( "Serializing a remote key pair is not supported" )
473
- }
474
-
475
422
& self . serialized_der
476
423
}
477
424
478
- /// Access the remote key pair if it is a remote one
479
- pub fn as_remote ( & self ) -> Option < & ( dyn SigningKey + Send + Sync ) > {
480
- #[ cfg_attr( not( feature = "crypto" ) , allow( irrefutable_let_patterns) ) ]
481
- if let KeyPairKind :: Remote ( remote) = & self . kind {
482
- Some ( remote. as_ref ( ) )
483
- } else {
484
- None
485
- }
486
- }
487
-
488
425
/// Serializes the key pair (including the private key) in PKCS#8 format in PEM
489
426
#[ cfg( feature = "pem" ) ]
490
427
pub fn serialize_pem ( & self ) -> String {
@@ -494,16 +431,34 @@ impl KeyPair {
494
431
}
495
432
}
496
433
434
+ #[ cfg( feature = "crypto" ) ]
435
+ impl SigningKey for KeyPair {
436
+ fn sign ( & self , msg : & [ u8 ] ) -> Result < Vec < u8 > , Error > {
437
+ Ok ( match & self . kind {
438
+ KeyPairKind :: Ec ( kp) => {
439
+ let system_random = SystemRandom :: new ( ) ;
440
+ let signature = kp. sign ( & system_random, msg) . _err ( ) ?;
441
+ signature. as_ref ( ) . to_owned ( )
442
+ } ,
443
+ KeyPairKind :: Ed ( kp) => kp. sign ( msg) . as_ref ( ) . to_owned ( ) ,
444
+ KeyPairKind :: Rsa ( kp, padding_alg) => {
445
+ let system_random = SystemRandom :: new ( ) ;
446
+ let mut signature = vec ! [ 0 ; rsa_key_pair_public_modulus_len( kp) ] ;
447
+ kp. sign ( * padding_alg, & system_random, msg, & mut signature)
448
+ . _err ( ) ?;
449
+ signature
450
+ } ,
451
+ } )
452
+ }
453
+ }
454
+
455
+ #[ cfg( feature = "crypto" ) ]
497
456
impl PublicKeyData for KeyPair {
498
457
fn public_key_der ( & self ) -> & [ u8 ] {
499
458
match & self . kind {
500
- #[ cfg( feature = "crypto" ) ]
501
459
KeyPairKind :: Ec ( kp) => kp. public_key ( ) . as_ref ( ) ,
502
- #[ cfg( feature = "crypto" ) ]
503
460
KeyPairKind :: Ed ( kp) => kp. public_key ( ) . as_ref ( ) ,
504
- #[ cfg( feature = "crypto" ) ]
505
461
KeyPairKind :: Rsa ( kp, _) => kp. public_key ( ) . as_ref ( ) ,
506
- KeyPairKind :: Remote ( kp) => kp. public_key_der ( ) ,
507
462
}
508
463
}
509
464
@@ -635,7 +590,7 @@ pub enum RsaKeySize {
635
590
}
636
591
637
592
pub ( crate ) fn sign_der (
638
- key : & KeyPair ,
593
+ key : & impl SigningKey ,
639
594
f : impl FnOnce ( & mut DERWriterSeq < ' _ > ) -> Result < ( ) , Error > ,
640
595
) -> Result < Vec < u8 > , Error > {
641
596
yasna:: try_construct_der ( |writer| {
@@ -644,20 +599,19 @@ pub(crate) fn sign_der(
644
599
writer. next ( ) . write_der ( & data) ;
645
600
646
601
// Write signatureAlgorithm
647
- key. alg . write_alg_ident ( writer. next ( ) ) ;
602
+ key. algorithm ( ) . write_alg_ident ( writer. next ( ) ) ;
648
603
649
604
// Write signature
650
- key. sign ( & data, writer. next ( ) ) ?;
605
+ let sig = key. sign ( & data) ?;
606
+ let writer = writer. next ( ) ;
607
+ writer. write_bitvec_bytes ( & sig, sig. len ( ) * 8 ) ;
651
608
652
609
Ok ( ( ) )
653
610
} )
654
611
} )
655
612
}
656
613
657
614
/// A private key that is not directly accessible, but can be used to sign messages
658
- ///
659
- /// Trait objects based on this trait can be passed to the [`KeyPair::from_remote`] function for generating certificates
660
- /// from a remote and raw private key, for example an HSM.
661
615
pub trait SigningKey : PublicKeyData {
662
616
/// Signs `msg` using the selected algorithm
663
617
fn sign ( & self , msg : & [ u8 ] ) -> Result < Vec < u8 > , Error > ;
0 commit comments