@@ -55,26 +55,32 @@ use crate::ec::encoding::sec1::{
55
55
marshal_sec1_private_key, marshal_sec1_public_point, marshal_sec1_public_point_into_buffer,
56
56
parse_sec1_private_bn,
57
57
} ;
58
- use crate :: ec:: { encoding, evp_key_generate} ;
58
+ use crate :: ec:: { encoding, evp_key_generate, } ;
59
+ #[ cfg( not( feature = "fips" ) ) ]
60
+ use crate :: ec:: verify_evp_key_nid;
61
+ #[ cfg( feature = "fips" ) ]
62
+ use crate :: ec:: validate_evp_key;
59
63
use crate :: error:: { KeyRejected , Unspecified } ;
60
64
use crate :: hex;
61
65
use crate :: ptr:: ConstPointer ;
62
66
pub use ephemeral:: { agree_ephemeral, EphemeralPrivateKey } ;
63
67
64
68
use crate :: aws_lc:: {
65
69
EVP_PKEY_derive , EVP_PKEY_derive_init , EVP_PKEY_derive_set_peer , EVP_PKEY_get0_EC_KEY ,
66
- NID_X9_62_prime256v1 , NID_secp384r1 , NID_secp521r1 , EVP_PKEY , EVP_PKEY_X25519 , NID_X25519 ,
70
+ NID_X9_62_prime256v1 , NID_secp384r1 , NID_secp521r1 , EVP_PKEY , EVP_PKEY_EC , EVP_PKEY_X25519 ,
71
+ NID_X25519 ,
67
72
} ;
68
73
69
74
use crate :: buffer:: Buffer ;
70
75
use crate :: ec;
71
76
use crate :: ec:: encoding:: rfc5915:: parse_rfc5915_private_key;
72
77
use crate :: encoding:: {
73
78
AsBigEndian , AsDer , Curve25519SeedBin , EcPrivateKeyBin , EcPrivateKeyRfc5915Der ,
74
- EcPublicKeyCompressedBin , EcPublicKeyUncompressedBin , PublicKeyX509Der ,
79
+ EcPublicKeyCompressedBin , EcPublicKeyUncompressedBin , Pkcs8V1Der , PublicKeyX509Der ,
75
80
} ;
76
81
use crate :: evp_pkey:: No_EVP_PKEY_CTX_consumer ;
77
82
use crate :: fips:: indicator_check;
83
+ use crate :: pkcs8:: Version ;
78
84
use crate :: ptr:: LcPtr ;
79
85
use core:: fmt;
80
86
use core:: fmt:: { Debug , Formatter } ;
@@ -293,7 +299,13 @@ impl PrivateKey {
293
299
if AlgorithmID :: X25519 == alg. id {
294
300
return Err ( KeyRejected :: invalid_encoding ( ) ) ;
295
301
}
296
- let evp_pkey = parse_rfc5915_private_key ( key_bytes, alg. id . nid ( ) ) ?;
302
+ let evp_pkey = LcPtr :: < EVP_PKEY > :: parse_rfc5208_private_key ( key_bytes, EVP_PKEY_EC )
303
+ . or ( parse_rfc5915_private_key ( key_bytes, alg. id . nid ( ) ) ) ?;
304
+ #[ cfg( not( feature = "fips" ) ) ]
305
+ verify_evp_key_nid ( & evp_pkey. as_const ( ) , alg. id . nid ( ) ) ?;
306
+ #[ cfg( feature = "fips" ) ]
307
+ validate_evp_key ( & evp_pkey. as_const ( ) , alg. id . nid ( ) ) ?;
308
+
297
309
Ok ( Self :: new ( alg, evp_pkey) )
298
310
}
299
311
@@ -449,6 +461,26 @@ impl AsDer<EcPrivateKeyRfc5915Der<'static>> for PrivateKey {
449
461
}
450
462
}
451
463
464
+ impl AsDer < Pkcs8V1Der < ' static > > for PrivateKey {
465
+ /// Serializes the key as a PKCS #8 private key structure.
466
+ ///
467
+ /// X25519 is not supported.
468
+ ///
469
+ /// # Errors
470
+ /// `error::Unspecified` if serialization failed.
471
+ fn as_der ( & self ) -> Result < Pkcs8V1Der < ' static > , Unspecified > {
472
+ if AlgorithmID :: X25519 == self . inner_key . algorithm ( ) . id {
473
+ return Err ( Unspecified ) ;
474
+ }
475
+
476
+ Ok ( Pkcs8V1Der :: new (
477
+ self . inner_key
478
+ . get_evp_pkey ( )
479
+ . marshal_rfc5208_private_key ( Version :: V1 ) ?,
480
+ ) )
481
+ }
482
+ }
483
+
452
484
impl AsBigEndian < EcPrivateKeyBin < ' static > > for PrivateKey {
453
485
/// Exposes the private key encoded as a big-endian fixed-length integer.
454
486
///
@@ -785,7 +817,7 @@ mod tests {
785
817
} ;
786
818
use crate :: encoding:: {
787
819
AsBigEndian , AsDer , Curve25519SeedBin , EcPrivateKeyBin , EcPrivateKeyRfc5915Der ,
788
- EcPublicKeyCompressedBin , EcPublicKeyUncompressedBin , PublicKeyX509Der ,
820
+ EcPublicKeyCompressedBin , EcPublicKeyUncompressedBin , Pkcs8V1Der , PublicKeyX509Der ,
789
821
} ;
790
822
use crate :: { rand, test} ;
791
823
@@ -930,6 +962,18 @@ mod tests {
930
962
assert_eq ! ( result, Ok ( ( ) ) ) ;
931
963
}
932
964
965
+ let pkcs8_private_key_buffer: Pkcs8V1Der = my_private. as_der ( ) . unwrap ( ) ;
966
+ let pkcs8_private_key =
967
+ PrivateKey :: from_private_key_der ( & ECDH_P256 , pkcs8_private_key_buffer. as_ref ( ) )
968
+ . unwrap ( ) ;
969
+ {
970
+ let result = agree ( & pkcs8_private_key, & peer_public, ( ) , |key_material| {
971
+ assert_eq ! ( key_material, & output[ ..] ) ;
972
+ Ok ( ( ) )
973
+ } ) ;
974
+ assert_eq ! ( result, Ok ( ( ) ) ) ;
975
+ }
976
+
933
977
let computed_public = my_private. compute_public_key ( ) . unwrap ( ) ;
934
978
assert_eq ! ( computed_public. as_ref( ) , & my_public[ ..] ) ;
935
979
0 commit comments