@@ -30,6 +30,7 @@ use rsa::pkcs1::EncodeRsaPublicKey;
30
30
use rsa:: traits:: PublicKeyParts ;
31
31
use rsa:: RsaPrivateKey ;
32
32
use rsa:: RsaPublicKey ;
33
+ use sec1:: der:: Tag ;
33
34
use sec1:: der:: Writer as _;
34
35
use sec1:: pem:: PemLabel as _;
35
36
use sec1:: DecodeEcPrivateKey as _;
@@ -46,7 +47,10 @@ use spki::EncodePublicKey as _;
46
47
use spki:: SubjectPublicKeyInfoRef ;
47
48
48
49
use super :: dh;
50
+ use super :: dh:: DiffieHellmanGroup ;
49
51
use super :: digest:: match_fixed_digest_with_oid;
52
+ use super :: pkcs3;
53
+ use super :: pkcs3:: DhParameter ;
50
54
use super :: primes:: Prime ;
51
55
52
56
#[ derive( Clone ) ]
@@ -66,8 +70,7 @@ pub enum AsymmetricPrivateKey {
66
70
Ec ( EcPrivateKey ) ,
67
71
X25519 ( x25519_dalek:: StaticSecret ) ,
68
72
Ed25519 ( ed25519_dalek:: SigningKey ) ,
69
- #[ allow( unused) ]
70
- Dh ( dh:: PrivateKey ) ,
73
+ Dh ( DhPrivateKey ) ,
71
74
}
72
75
73
76
#[ derive( Clone ) ]
@@ -125,17 +128,21 @@ pub enum EcPrivateKey {
125
128
P384 ( p384:: SecretKey ) ,
126
129
}
127
130
131
+ #[ derive( Clone ) ]
132
+ pub struct DhPrivateKey {
133
+ pub key : dh:: PrivateKey ,
134
+ pub params : DhParameter ,
135
+ }
136
+
128
137
#[ derive( Clone ) ]
129
138
pub enum AsymmetricPublicKey {
130
139
Rsa ( rsa:: RsaPublicKey ) ,
131
140
RsaPss ( RsaPssPublicKey ) ,
132
141
Dsa ( dsa:: VerifyingKey ) ,
133
142
Ec ( EcPublicKey ) ,
134
- #[ allow( unused) ]
135
143
X25519 ( x25519_dalek:: PublicKey ) ,
136
144
Ed25519 ( ed25519_dalek:: VerifyingKey ) ,
137
- #[ allow( unused) ]
138
- Dh ( dh:: PublicKey ) ,
145
+ Dh ( DhPublicKey ) ,
139
146
}
140
147
141
148
#[ derive( Clone ) ]
@@ -151,6 +158,12 @@ pub enum EcPublicKey {
151
158
P384 ( p384:: PublicKey ) ,
152
159
}
153
160
161
+ #[ derive( Clone ) ]
162
+ pub struct DhPublicKey {
163
+ pub key : dh:: PublicKey ,
164
+ pub params : DhParameter ,
165
+ }
166
+
154
167
impl KeyObjectHandle {
155
168
/// Returns the private key if the handle is an asymmetric private key.
156
169
pub fn as_private_key ( & self ) -> Option < & AsymmetricPrivateKey > {
@@ -492,9 +505,18 @@ impl KeyObjectHandle {
492
505
bytes. copy_from_slice ( string_ref. as_bytes ( ) ) ;
493
506
AsymmetricPrivateKey :: Ed25519 ( ed25519_dalek:: SigningKey :: from ( bytes) )
494
507
}
495
- DH_KEY_AGREEMENT_OID => AsymmetricPrivateKey :: Dh (
496
- dh:: PrivateKey :: from_bytes ( pk_info. private_key ) ,
497
- ) ,
508
+ DH_KEY_AGREEMENT_OID => {
509
+ let params = pk_info
510
+ . algorithm
511
+ . parameters
512
+ . ok_or_else ( || type_error ( "missing dh parameters" ) ) ?;
513
+ let params = pkcs3:: DhParameter :: from_der ( & params. to_der ( ) . unwrap ( ) )
514
+ . map_err ( |_| type_error ( "malformed dh parameters" ) ) ?;
515
+ AsymmetricPrivateKey :: Dh ( DhPrivateKey {
516
+ key : dh:: PrivateKey :: from_bytes ( pk_info. private_key ) ,
517
+ params,
518
+ } )
519
+ }
498
520
_ => return Err ( type_error ( "unsupported private key oid" ) ) ,
499
521
} ;
500
522
@@ -634,11 +656,20 @@ impl KeyObjectHandle {
634
656
AsymmetricPublicKey :: Ed25519 ( verifying_key)
635
657
}
636
658
DH_KEY_AGREEMENT_OID => {
659
+ let params = spki
660
+ . algorithm
661
+ . parameters
662
+ . ok_or_else ( || type_error ( "missing dh parameters" ) ) ?;
663
+ let params = pkcs3:: DhParameter :: from_der ( & params. to_der ( ) . unwrap ( ) )
664
+ . map_err ( |_| type_error ( "malformed dh parameters" ) ) ?;
637
665
let Some ( subject_public_key) = spki. subject_public_key . as_bytes ( )
638
666
else {
639
667
return Err ( type_error ( "malformed or missing public key in dh spki" ) ) ;
640
668
} ;
641
- AsymmetricPublicKey :: Dh ( dh:: PublicKey :: from_bytes ( subject_public_key) )
669
+ AsymmetricPublicKey :: Dh ( DhPublicKey {
670
+ key : dh:: PublicKey :: from_bytes ( subject_public_key) ,
671
+ params,
672
+ } )
642
673
}
643
674
_ => return Err ( type_error ( "unsupported public key oid" ) ) ,
644
675
} ;
@@ -788,16 +819,18 @@ impl AsymmetricPublicKey {
788
819
. into_boxed_slice ( )
789
820
}
790
821
AsymmetricPublicKey :: Dh ( key) => {
791
- let public_key_bytes = key. clone ( ) . into_vec ( ) ;
792
- let spki =
793
- SubjectPublicKeyInfoRef {
794
- algorithm : rsa:: pkcs8:: AlgorithmIdentifierRef {
795
- oid : DH_KEY_AGREEMENT_OID ,
796
- parameters : None ,
797
- } ,
798
- subject_public_key : BitStringRef :: from_bytes ( & public_key_bytes)
799
- . map_err ( |_| type_error ( "invalid DH public key" ) ) ?,
800
- } ;
822
+ let public_key_bytes = key. key . clone ( ) . into_vec ( ) ;
823
+ let params = key. params . to_der ( ) . unwrap ( ) ;
824
+ let spki = SubjectPublicKeyInfoRef {
825
+ algorithm : rsa:: pkcs8:: AlgorithmIdentifierRef {
826
+ oid : DH_KEY_AGREEMENT_OID ,
827
+ parameters : Some ( AnyRef :: new ( Tag :: Sequence , & params) . unwrap ( ) ) ,
828
+ } ,
829
+ subject_public_key : BitStringRef :: from_bytes ( & public_key_bytes)
830
+ . map_err ( |_| {
831
+ type_error ( "invalid DH public key" )
832
+ } ) ?,
833
+ } ;
801
834
spki
802
835
. to_der ( )
803
836
. map_err ( |_| type_error ( "invalid DH public key" ) ) ?
@@ -917,11 +950,12 @@ impl AsymmetricPrivateKey {
917
950
. into_boxed_slice ( )
918
951
}
919
952
AsymmetricPrivateKey :: Dh ( key) => {
920
- let private_key = key. clone ( ) . into_vec ( ) ;
953
+ let private_key = key. key . clone ( ) . into_vec ( ) ;
954
+ let params = key. params . to_der ( ) . unwrap ( ) ;
921
955
let private_key = PrivateKeyInfo {
922
956
algorithm : rsa:: pkcs8:: AlgorithmIdentifierRef {
923
957
oid : DH_KEY_AGREEMENT_OID ,
924
- parameters : None ,
958
+ parameters : Some ( AnyRef :: new ( Tag :: Sequence , & params ) . unwrap ( ) ) ,
925
959
} ,
926
960
private_key : & private_key,
927
961
public_key : None ,
@@ -1514,21 +1548,66 @@ pub async fn op_node_generate_ed25519_key_async() -> KeyObjectHandlePair {
1514
1548
spawn_blocking ( ed25519_generate) . await . unwrap ( )
1515
1549
}
1516
1550
1551
+ fn u32_slice_to_u8_slice ( slice : & [ u32 ] ) -> & [ u8 ] {
1552
+ // SAFETY: just reinterpreting the slice as u8
1553
+ unsafe {
1554
+ std:: slice:: from_raw_parts (
1555
+ slice. as_ptr ( ) as * const u8 ,
1556
+ std:: mem:: size_of_val ( slice) ,
1557
+ )
1558
+ }
1559
+ }
1560
+
1517
1561
fn dh_group_generate (
1518
1562
group_name : & str ,
1519
1563
) -> Result < KeyObjectHandlePair , AnyError > {
1520
- let dh = match group_name {
1521
- "modp5" => dh:: DiffieHellman :: group :: < dh:: Modp1536 > ( ) ,
1522
- "modp14" => dh:: DiffieHellman :: group :: < dh:: Modp2048 > ( ) ,
1523
- "modp15" => dh:: DiffieHellman :: group :: < dh:: Modp3072 > ( ) ,
1524
- "modp16" => dh:: DiffieHellman :: group :: < dh:: Modp4096 > ( ) ,
1525
- "modp17" => dh:: DiffieHellman :: group :: < dh:: Modp6144 > ( ) ,
1526
- "modp18" => dh:: DiffieHellman :: group :: < dh:: Modp8192 > ( ) ,
1564
+ let ( dh, prime, generator) = match group_name {
1565
+ "modp5" => (
1566
+ dh:: DiffieHellman :: group :: < dh:: Modp1536 > ( ) ,
1567
+ dh:: Modp1536 :: MODULUS ,
1568
+ dh:: Modp1536 :: GENERATOR ,
1569
+ ) ,
1570
+ "modp14" => (
1571
+ dh:: DiffieHellman :: group :: < dh:: Modp2048 > ( ) ,
1572
+ dh:: Modp2048 :: MODULUS ,
1573
+ dh:: Modp2048 :: GENERATOR ,
1574
+ ) ,
1575
+ "modp15" => (
1576
+ dh:: DiffieHellman :: group :: < dh:: Modp3072 > ( ) ,
1577
+ dh:: Modp3072 :: MODULUS ,
1578
+ dh:: Modp3072 :: GENERATOR ,
1579
+ ) ,
1580
+ "modp16" => (
1581
+ dh:: DiffieHellman :: group :: < dh:: Modp4096 > ( ) ,
1582
+ dh:: Modp4096 :: MODULUS ,
1583
+ dh:: Modp4096 :: GENERATOR ,
1584
+ ) ,
1585
+ "modp17" => (
1586
+ dh:: DiffieHellman :: group :: < dh:: Modp6144 > ( ) ,
1587
+ dh:: Modp6144 :: MODULUS ,
1588
+ dh:: Modp6144 :: GENERATOR ,
1589
+ ) ,
1590
+ "modp18" => (
1591
+ dh:: DiffieHellman :: group :: < dh:: Modp8192 > ( ) ,
1592
+ dh:: Modp8192 :: MODULUS ,
1593
+ dh:: Modp8192 :: GENERATOR ,
1594
+ ) ,
1527
1595
_ => return Err ( type_error ( "Unsupported group name" ) ) ,
1528
1596
} ;
1597
+ let params = DhParameter {
1598
+ prime : asn1:: Int :: new ( u32_slice_to_u8_slice ( prime) ) . unwrap ( ) ,
1599
+ base : asn1:: Int :: new ( generator. to_be_bytes ( ) . as_slice ( ) ) . unwrap ( ) ,
1600
+ private_value_length : None ,
1601
+ } ;
1529
1602
Ok ( KeyObjectHandlePair :: new (
1530
- AsymmetricPrivateKey :: Dh ( dh. private_key ) ,
1531
- AsymmetricPublicKey :: Dh ( dh. public_key ) ,
1603
+ AsymmetricPrivateKey :: Dh ( DhPrivateKey {
1604
+ key : dh. private_key ,
1605
+ params : params. clone ( ) ,
1606
+ } ) ,
1607
+ AsymmetricPublicKey :: Dh ( DhPublicKey {
1608
+ key : dh. public_key ,
1609
+ params,
1610
+ } ) ,
1532
1611
) )
1533
1612
}
1534
1613
@@ -1558,10 +1637,21 @@ fn dh_generate(
1558
1637
let prime = prime
1559
1638
. map ( |p| p. into ( ) )
1560
1639
. unwrap_or_else ( || Prime :: generate ( prime_len) ) ;
1561
- let dh = dh:: DiffieHellman :: new ( prime, generator) ;
1640
+ let dh = dh:: DiffieHellman :: new ( prime. clone ( ) , generator) ;
1641
+ let params = DhParameter {
1642
+ prime : asn1:: Int :: new ( & prime. 0 . to_bytes_be ( ) ) . unwrap ( ) ,
1643
+ base : asn1:: Int :: new ( generator. to_be_bytes ( ) . as_slice ( ) ) . unwrap ( ) ,
1644
+ private_value_length : None ,
1645
+ } ;
1562
1646
Ok ( KeyObjectHandlePair :: new (
1563
- AsymmetricPrivateKey :: Dh ( dh. private_key ) ,
1564
- AsymmetricPublicKey :: Dh ( dh. public_key ) ,
1647
+ AsymmetricPrivateKey :: Dh ( DhPrivateKey {
1648
+ key : dh. private_key ,
1649
+ params : params. clone ( ) ,
1650
+ } ) ,
1651
+ AsymmetricPublicKey :: Dh ( DhPublicKey {
1652
+ key : dh. public_key ,
1653
+ params,
1654
+ } ) ,
1565
1655
) )
1566
1656
}
1567
1657
0 commit comments