@@ -13,13 +13,13 @@ use crate::MIN_DH_MODULUS_SIZE;
13
13
use crate :: { ec, rsa, KeyParsingError , KeyParsingResult } ;
14
14
15
15
// RFC 5208 Section 5
16
- #[ derive( asn1:: Asn1Read ) ]
17
- struct PrivateKeyInfo < ' a > {
18
- version : u8 ,
19
- algorithm : AlgorithmIdentifier < ' a > ,
20
- private_key : & ' a [ u8 ] ,
16
+ #[ derive( asn1:: Asn1Read , asn1 :: Asn1Write ) ]
17
+ pub struct PrivateKeyInfo < ' a > {
18
+ pub version : u8 ,
19
+ pub algorithm : AlgorithmIdentifier < ' a > ,
20
+ pub private_key : & ' a [ u8 ] ,
21
21
#[ implicit( 0 ) ]
22
- _attributes : Option < Attributes < ' a > > ,
22
+ pub attributes : Option < Attributes < ' a > > ,
23
23
}
24
24
25
25
pub fn parse_private_key (
@@ -331,3 +331,116 @@ pub fn parse_encrypted_private_key(
331
331
332
332
parse_private_key ( & plaintext)
333
333
}
334
+
335
+ pub fn serialize_private_key (
336
+ pkey : & openssl:: pkey:: PKeyRef < openssl:: pkey:: Private > ,
337
+ ) -> crate :: KeySerializationResult < Vec < u8 > > {
338
+ let p_bytes;
339
+ let q_bytes;
340
+ let g_bytes;
341
+ let q_bytes_dh;
342
+
343
+ let ( params, private_key_der) = if let Ok ( rsa) = pkey. rsa ( ) {
344
+ let pkcs1_der = rsa:: serialize_pkcs1_private_key ( & rsa) ?;
345
+ ( AlgorithmParameters :: Rsa ( Some ( ( ) ) ) , pkcs1_der)
346
+ } else if let Ok ( ec) = pkey. ec_key ( ) {
347
+ let curve_oid = ec:: group_to_curve_oid ( ec. group ( ) ) . expect ( "Unknown curve" ) ;
348
+ let pkcs1_der = ec:: serialize_pkcs1_private_key ( & ec, false ) ?;
349
+ (
350
+ AlgorithmParameters :: Ec ( cryptography_x509:: common:: EcParameters :: NamedCurve (
351
+ curve_oid,
352
+ ) ) ,
353
+ pkcs1_der,
354
+ )
355
+ } else if pkey. id ( ) == openssl:: pkey:: Id :: ED25519 {
356
+ let raw_bytes = pkey. raw_private_key ( ) ?;
357
+ let private_key_der = asn1:: write_single ( & raw_bytes. as_slice ( ) ) ?;
358
+ ( AlgorithmParameters :: Ed25519 , private_key_der)
359
+ } else if pkey. id ( ) == openssl:: pkey:: Id :: X25519 {
360
+ let raw_bytes = pkey. raw_private_key ( ) ?;
361
+ let private_key_der = asn1:: write_single ( & raw_bytes. as_slice ( ) ) ?;
362
+ ( AlgorithmParameters :: X25519 , private_key_der)
363
+ } else if crate :: utils:: is_ed448 ( pkey. id ( ) ) {
364
+ let raw_bytes = pkey. raw_private_key ( ) ?;
365
+ let private_key_der = asn1:: write_single ( & raw_bytes. as_slice ( ) ) ?;
366
+ ( AlgorithmParameters :: Ed448 , private_key_der)
367
+ } else if crate :: utils:: is_x448 ( pkey. id ( ) ) {
368
+ let raw_bytes = pkey. raw_private_key ( ) ?;
369
+ let private_key_der = asn1:: write_single ( & raw_bytes. as_slice ( ) ) ?;
370
+ ( AlgorithmParameters :: X448 , private_key_der)
371
+ } else if let Ok ( dsa) = pkey. dsa ( ) {
372
+ p_bytes = cryptography_openssl:: utils:: bn_to_big_endian_bytes ( dsa. p ( ) ) ?;
373
+ q_bytes = cryptography_openssl:: utils:: bn_to_big_endian_bytes ( dsa. q ( ) ) ?;
374
+ g_bytes = cryptography_openssl:: utils:: bn_to_big_endian_bytes ( dsa. g ( ) ) ?;
375
+
376
+ let priv_key_bytes = cryptography_openssl:: utils:: bn_to_big_endian_bytes ( dsa. priv_key ( ) ) ?;
377
+ let priv_key_int = asn1:: BigUint :: new ( & priv_key_bytes) . unwrap ( ) ;
378
+ let private_key_der = asn1:: write_single ( & priv_key_int) ?;
379
+
380
+ let dsa_params = cryptography_x509:: common:: DssParams {
381
+ p : asn1:: BigUint :: new ( & p_bytes) . unwrap ( ) ,
382
+ q : asn1:: BigUint :: new ( & q_bytes) . unwrap ( ) ,
383
+ g : asn1:: BigUint :: new ( & g_bytes) . unwrap ( ) ,
384
+ } ;
385
+
386
+ ( AlgorithmParameters :: Dsa ( dsa_params) , private_key_der)
387
+ } else if let Ok ( dh) = pkey. dh ( ) {
388
+ p_bytes = cryptography_openssl:: utils:: bn_to_big_endian_bytes ( dh. prime_p ( ) ) ?;
389
+ g_bytes = cryptography_openssl:: utils:: bn_to_big_endian_bytes ( dh. generator ( ) ) ?;
390
+ q_bytes_dh = dh
391
+ . prime_q ( )
392
+ . map ( cryptography_openssl:: utils:: bn_to_big_endian_bytes)
393
+ . transpose ( ) ?;
394
+
395
+ let priv_key_bytes = cryptography_openssl:: utils:: bn_to_big_endian_bytes ( dh. private_key ( ) ) ?;
396
+ let priv_key_int = asn1:: BigUint :: new ( & priv_key_bytes) . unwrap ( ) ;
397
+ let private_key_der = asn1:: write_single ( & priv_key_int) ?;
398
+
399
+ let params = if let Some ( ref q_bytes) = q_bytes_dh {
400
+ let dhx_params = cryptography_x509:: common:: DHXParams {
401
+ p : asn1:: BigUint :: new ( & p_bytes) . unwrap ( ) ,
402
+ g : asn1:: BigUint :: new ( & g_bytes) . unwrap ( ) ,
403
+ q : asn1:: BigUint :: new ( q_bytes) . unwrap ( ) ,
404
+ j : None ,
405
+ validation_params : None ,
406
+ } ;
407
+ AlgorithmParameters :: Dh ( dhx_params)
408
+ } else {
409
+ let basic_params = cryptography_x509:: common:: BasicDHParams {
410
+ p : asn1:: BigUint :: new ( & p_bytes) . unwrap ( ) ,
411
+ g : asn1:: BigUint :: new ( & g_bytes) . unwrap ( ) ,
412
+ private_value_length : None ,
413
+ } ;
414
+ AlgorithmParameters :: DhKeyAgreement ( basic_params)
415
+ } ;
416
+
417
+ ( params, private_key_der)
418
+ } else {
419
+ unimplemented ! ( "Unknown key type" ) ;
420
+ } ;
421
+
422
+ let pki = PrivateKeyInfo {
423
+ version : 0 ,
424
+ algorithm : AlgorithmIdentifier {
425
+ oid : asn1:: DefinedByMarker :: marker ( ) ,
426
+ params,
427
+ } ,
428
+ private_key : & private_key_der,
429
+ attributes : None ,
430
+ } ;
431
+ Ok ( asn1:: write_single ( & pki) ?)
432
+ }
433
+
434
+ #[ cfg( test) ]
435
+ mod tests {
436
+ use super :: serialize_private_key;
437
+
438
+ #[ cfg( not( CRYPTOGRAPHY_IS_BORINGSSL ) ) ]
439
+ #[ test]
440
+ #[ should_panic( expected = "Unknown key type" ) ]
441
+ fn test_serialize_private_key_unknown_key_type ( ) {
442
+ let pkey = openssl:: pkey:: PKey :: hmac ( & [ 0u8 ; 16 ] ) . unwrap ( ) ;
443
+ // Expected to panic
444
+ _ = serialize_private_key ( & pkey) ;
445
+ }
446
+ }
0 commit comments