55use cryptography_x509:: common:: EcParameters ;
66use cryptography_x509:: ec_constants;
77
8- use crate :: { KeyParsingError , KeyParsingResult } ;
8+ use crate :: { KeyParsingError , KeyParsingResult , KeySerializationResult } ;
99
1010// From RFC 5915 Section 3
11- #[ derive( asn1:: Asn1Read ) ]
11+ #[ derive( asn1:: Asn1Read , asn1 :: Asn1Write ) ]
1212pub ( crate ) struct EcPrivateKey < ' a > {
1313 pub ( crate ) version : u8 ,
1414 pub ( crate ) private_key : & ' a [ u8 ] ,
@@ -18,6 +18,37 @@ pub(crate) struct EcPrivateKey<'a> {
1818 pub ( crate ) public_key : Option < asn1:: BitString < ' a > > ,
1919}
2020
21+ pub ( crate ) fn group_to_curve_oid (
22+ group : & openssl:: ec:: EcGroupRef ,
23+ ) -> Option < asn1:: ObjectIdentifier > {
24+ let nid = group. curve_name ( ) ?;
25+ match nid {
26+ openssl:: nid:: Nid :: X9_62_PRIME192V1 => Some ( cryptography_x509:: oid:: EC_SECP192R1 ) ,
27+ openssl:: nid:: Nid :: SECP224R1 => Some ( cryptography_x509:: oid:: EC_SECP224R1 ) ,
28+ openssl:: nid:: Nid :: X9_62_PRIME256V1 => Some ( cryptography_x509:: oid:: EC_SECP256R1 ) ,
29+ openssl:: nid:: Nid :: SECP384R1 => Some ( cryptography_x509:: oid:: EC_SECP384R1 ) ,
30+ openssl:: nid:: Nid :: SECP521R1 => Some ( cryptography_x509:: oid:: EC_SECP521R1 ) ,
31+ openssl:: nid:: Nid :: SECP256K1 => Some ( cryptography_x509:: oid:: EC_SECP256K1 ) ,
32+ openssl:: nid:: Nid :: SECT233R1 => Some ( cryptography_x509:: oid:: EC_SECT233R1 ) ,
33+ openssl:: nid:: Nid :: SECT283R1 => Some ( cryptography_x509:: oid:: EC_SECT283R1 ) ,
34+ openssl:: nid:: Nid :: SECT409R1 => Some ( cryptography_x509:: oid:: EC_SECT409R1 ) ,
35+ openssl:: nid:: Nid :: SECT571R1 => Some ( cryptography_x509:: oid:: EC_SECT571R1 ) ,
36+ openssl:: nid:: Nid :: SECT163R2 => Some ( cryptography_x509:: oid:: EC_SECT163R2 ) ,
37+ openssl:: nid:: Nid :: SECT163K1 => Some ( cryptography_x509:: oid:: EC_SECT163K1 ) ,
38+ openssl:: nid:: Nid :: SECT233K1 => Some ( cryptography_x509:: oid:: EC_SECT233K1 ) ,
39+ openssl:: nid:: Nid :: SECT283K1 => Some ( cryptography_x509:: oid:: EC_SECT283K1 ) ,
40+ openssl:: nid:: Nid :: SECT409K1 => Some ( cryptography_x509:: oid:: EC_SECT409K1 ) ,
41+ openssl:: nid:: Nid :: SECT571K1 => Some ( cryptography_x509:: oid:: EC_SECT571K1 ) ,
42+ #[ cfg( not( any( CRYPTOGRAPHY_IS_BORINGSSL , CRYPTOGRAPHY_IS_AWSLC ) ) ) ]
43+ openssl:: nid:: Nid :: BRAINPOOL_P256R1 => Some ( cryptography_x509:: oid:: EC_BRAINPOOLP256R1 ) ,
44+ #[ cfg( not( any( CRYPTOGRAPHY_IS_BORINGSSL , CRYPTOGRAPHY_IS_AWSLC ) ) ) ]
45+ openssl:: nid:: Nid :: BRAINPOOL_P384R1 => Some ( cryptography_x509:: oid:: EC_BRAINPOOLP384R1 ) ,
46+ #[ cfg( not( any( CRYPTOGRAPHY_IS_BORINGSSL , CRYPTOGRAPHY_IS_AWSLC ) ) ) ]
47+ openssl:: nid:: Nid :: BRAINPOOL_P512R1 => Some ( cryptography_x509:: oid:: EC_BRAINPOOLP512R1 ) ,
48+ _ => None ,
49+ }
50+ }
51+
2152pub ( crate ) fn ec_params_to_group (
2253 params : & EcParameters < ' _ > ,
2354) -> KeyParsingResult < openssl:: ec:: EcGroup > {
@@ -88,6 +119,29 @@ pub(crate) fn ec_params_to_group(
88119 }
89120}
90121
122+ pub fn serialize_pkcs1_private_key (
123+ ec : & openssl:: ec:: EcKeyRef < openssl:: pkey:: Private > ,
124+ ) -> KeySerializationResult < Vec < u8 > > {
125+ let curve_oid = group_to_curve_oid ( ec. group ( ) ) . expect ( "Unknown curve" ) ;
126+
127+ let private_key_bytes = ec. private_key ( ) . to_vec ( ) ;
128+
129+ let mut bn_ctx = openssl:: bn:: BigNumContext :: new ( ) ?;
130+ let public_key_bytes = ec. public_key ( ) . to_bytes (
131+ ec. group ( ) ,
132+ openssl:: ec:: PointConversionForm :: UNCOMPRESSED ,
133+ & mut bn_ctx,
134+ ) ?;
135+
136+ let key = EcPrivateKey {
137+ version : 1 ,
138+ private_key : & private_key_bytes,
139+ parameters : Some ( EcParameters :: NamedCurve ( curve_oid) ) ,
140+ public_key : Some ( asn1:: BitString :: new ( & public_key_bytes, 0 ) . unwrap ( ) ) ,
141+ } ;
142+ Ok ( asn1:: write_single ( & key) ?)
143+ }
144+
91145pub fn parse_pkcs1_private_key (
92146 data : & [ u8 ] ,
93147 ec_params : Option < EcParameters < ' _ > > ,
0 commit comments