From 304dd8f81e28ed04cde9f6f7ac1f79870da1c2cd Mon Sep 17 00:00:00 2001 From: Maxim Fedorov Date: Wed, 18 Apr 2018 15:48:34 -0700 Subject: public_key: PKCS8 (Private-Key Information Syntax Standard) encoded private key support This patch adds support for RSA, DSA and EC private keys encoded using PKCS8 format. Test *.pem files are made with converting existing *.pem files using openssl: openssl pkcs8 -in ... -out ... -topk8 -nocrypt --- lib/public_key/src/public_key.erl | 20 ++++++++++++++- lib/public_key/test/public_key_SUITE.erl | 30 ++++++++++++++++++++++ .../test/public_key_SUITE_data/dsa_key_pkcs8.pem | 9 +++++++ .../test/public_key_SUITE_data/ec_key_pkcs8.pem | 5 ++++ .../test/public_key_SUITE_data/rsa_key_pkcs8.pem | 10 ++++++++ 5 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 lib/public_key/test/public_key_SUITE_data/dsa_key_pkcs8.pem create mode 100644 lib/public_key/test/public_key_SUITE_data/ec_key_pkcs8.pem create mode 100644 lib/public_key/test/public_key_SUITE_data/rsa_key_pkcs8.pem diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl index 931901640a..6900ede946 100644 --- a/lib/public_key/src/public_key.erl +++ b/lib/public_key/src/public_key.erl @@ -237,7 +237,7 @@ der_decode(Asn1Type, Der) when (Asn1Type == 'PrivateKeyInfo') or andalso is_binary(Der) -> try {ok, Decoded} = 'PKCS-FRAME':decode(Asn1Type, Der), - Decoded + der_priv_key_decode(Decoded) catch error:{badmatch, {error, _}} = Error -> erlang:error(Error) @@ -276,6 +276,24 @@ der_encode(Asn1Type, Entity) when is_atom(Asn1Type) -> erlang:error(Error) end. +der_priv_key_decode({'PrivateKeyInfo', v1, PKAlgo, PrivKey, _} = PKCS8Key) -> + % do actual decoding + {'PrivateKeyInfo_privateKeyAlgorithm', Algorithm, {asn1_OPENTYPE, Parameters}} = PKAlgo, + case Algorithm of + ?'id-ecPublicKey' -> + EcpkParameters = public_key:der_decode('EcpkParameters', Parameters), + EcPrivKey = public_key:der_decode('ECPrivateKey', PrivKey), + EcPrivKey#'ECPrivateKey'{parameters = EcpkParameters}; + ?'rsaEncryption' -> + public_key:der_decode('RSAPrivateKey', PrivKey); + ?'id-dsa' -> + {params, #'Dss-Parms'{p=P, q=Q, g=G}} = public_key:der_decode('DSAParams', Parameters), + X = public_key:der_decode('Prime-p', PrivKey), + #'DSAPrivateKey'{p=P, q=Q, g=G, x=X}; + _ -> + PKCS8Key + end. + %%-------------------------------------------------------------------- -spec pkix_decode_cert(Cert::binary(), plain | otp) -> #'Certificate'{} | #'OTPCertificate'{}. diff --git a/lib/public_key/test/public_key_SUITE.erl b/lib/public_key/test/public_key_SUITE.erl index 449d1fc040..f5a6f79136 100644 --- a/lib/public_key/test/public_key_SUITE.erl +++ b/lib/public_key/test/public_key_SUITE.erl @@ -64,6 +64,7 @@ all() -> groups() -> [{pem_decode_encode, [], [dsa_pem, rsa_pem, ec_pem, encrypted_pem, dh_pem, cert_pem, pkcs7_pem, pkcs10_pem, ec_pem2, + rsa_priv_pkcs8, dsa_priv_pkcs8, ec_priv_pkcs8, ec_pem_encode_generated, gen_ec_param_prime_field, gen_ec_param_char_2_field ]}, @@ -181,6 +182,16 @@ dsa_pem(Config) when is_list(Config) -> DSAPubPemNoEndNewLines = strip_superfluous_newlines(DSAPubPem), DSAPubPemNoEndNewLines = strip_superfluous_newlines(public_key:pem_encode([PubEntry0])). +dsa_priv_pkcs8() -> + [{doc, "DSA PKCS8 private key decode"}]. +dsa_priv_pkcs8(Config) when is_list(Config) -> + Datadir = proplists:get_value(data_dir, Config), + [{'PrivateKeyInfo', DerDSAKey, not_encrypted} = Entry0 ] = + erl_make_certs:pem_to_der(filename:join(Datadir, "dsa_key_pkcs8.pem")), + DSAKey = public_key:der_decode('PrivateKeyInfo', DerDSAKey), + DSAKey = public_key:pem_entry_decode(Entry0), + true = check_entry_type(DSAKey, 'DSAPrivateKey'). + %%-------------------------------------------------------------------- rsa_pem() -> @@ -216,6 +227,16 @@ rsa_pem(Config) when is_list(Config) -> RSARawPemNoEndNewLines = strip_superfluous_newlines(RSARawPem), RSARawPemNoEndNewLines = strip_superfluous_newlines(public_key:pem_encode([PubEntry1])). +rsa_priv_pkcs8() -> + [{doc, "RSA PKCS8 private key decode"}]. +rsa_priv_pkcs8(Config) when is_list(Config) -> + Datadir = proplists:get_value(data_dir, Config), + [{'PrivateKeyInfo', DerRSAKey, not_encrypted} = Entry0 ] = + erl_make_certs:pem_to_der(filename:join(Datadir, "rsa_key_pkcs8.pem")), + RSAKey = public_key:der_decode('PrivateKeyInfo', DerRSAKey), + RSAKey = public_key:pem_entry_decode(Entry0), + true = check_entry_type(RSAKey, 'RSAPrivateKey'). + %%-------------------------------------------------------------------- ec_pem() -> @@ -262,6 +283,15 @@ ec_pem2(Config) when is_list(Config) -> ECPemNoEndNewLines = strip_superfluous_newlines(ECPrivPem), ECPemNoEndNewLines = strip_superfluous_newlines(public_key:pem_encode([Entry1, Entry2])). +ec_priv_pkcs8() -> + [{doc, "EC PKCS8 private key decode"}]. +ec_priv_pkcs8(Config) when is_list(Config) -> + Datadir = proplists:get_value(data_dir, Config), + {ok, ECPrivPem} = file:read_file(filename:join(Datadir, "ec_key_pkcs8.pem")), + [{'PrivateKeyInfo', _, not_encrypted} = PKCS8Key] = public_key:pem_decode(ECPrivPem), + ECPrivKey = public_key:pem_entry_decode(PKCS8Key), + true = check_entry_type(ECPrivKey, 'ECPrivateKey'), + true = check_entry_type(ECPrivKey#'ECPrivateKey'.parameters, 'EcpkParameters'). init_ec_pem_encode_generated(Config) -> case catch true = lists:member('secp384r1', crypto:ec_curves()) of diff --git a/lib/public_key/test/public_key_SUITE_data/dsa_key_pkcs8.pem b/lib/public_key/test/public_key_SUITE_data/dsa_key_pkcs8.pem new file mode 100644 index 0000000000..86e38e2c76 --- /dev/null +++ b/lib/public_key/test/public_key_SUITE_data/dsa_key_pkcs8.pem @@ -0,0 +1,9 @@ +-----BEGIN PRIVATE KEY----- +MIIBSwIBADCCASwGByqGSM44BAEwggEfAoGBALez5tklY5CdFeTMos899pA6i4u4 +uCtszgBzrdBk6cl5FVqzdzWMGTQiynnTpGsrOESinzP06Ip+pG15We2OORwgvCxD +/W95aCiN0/+MdiXqlsmboBARMzsa+SmBENN3gF/+tuuEAFzOXU1q2cmEywRLyfbM +2KIBVE/TChWYw2eRAhUA1R64VvcQ90XA8SOKVDmMA0dBzukCgYEAlLMYP0pbgBlg +HQVO3/avAHlWNrIq52Lxk7SdPJWgMvPjTK9Z6sv88kxsCcydtjvO439j1yqcwk50 +GQc+86ktBWWz93/HkIdnFyqafef4mmWvm2Uq6ClQKS+A0Asfaj8Mys+HUMiI+qsf +djRbyIpwb7MX1nsVdsKzALnZNMW27A0EFgIUWYCfDrv5tqwPWKJu00ez0R192SY= +-----END PRIVATE KEY----- diff --git a/lib/public_key/test/public_key_SUITE_data/ec_key_pkcs8.pem b/lib/public_key/test/public_key_SUITE_data/ec_key_pkcs8.pem new file mode 100644 index 0000000000..8280a3671a --- /dev/null +++ b/lib/public_key/test/public_key_SUITE_data/ec_key_pkcs8.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgB349XXSmba5BbJT5UuCK +OoyoPHsygy6n+WzP1J+8eYShRANCAATTJdDtiqV9Hs7q+Y/yak1z3uJpukFQGYmr +lJ2iztxfv7bz10eJ5yM/GNqG8kK0w7SIzjedsIkfjRK7bX6mP7h4 +-----END PRIVATE KEY----- diff --git a/lib/public_key/test/public_key_SUITE_data/rsa_key_pkcs8.pem b/lib/public_key/test/public_key_SUITE_data/rsa_key_pkcs8.pem new file mode 100644 index 0000000000..9ef5b3353f --- /dev/null +++ b/lib/public_key/test/public_key_SUITE_data/rsa_key_pkcs8.pem @@ -0,0 +1,10 @@ +-----BEGIN PRIVATE KEY----- +MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEA1GLJmDS5yLvg1zqa +epnwCgOXzxpPvHokDQx+AcgfO14SPtCD6UTlDEwYBp+6tUTm+qgeQN/CTi7POwIA +m7P3UwIDAQABAkALFiEJ1e7AwLXq5j88GR8Dls5s3CW/Y+zP1ZAaTbT7p0QUMxG+ +0ko7h8NoxcQJHZU27sZXCjog/IBqn577Xv4RAiEA8/aQ09kz0jxi4aNvlix4B+bW +gX0sYtcCDkBzx8Y6iMkCIQDe3WCxV9PuiDjpuC8cAy3UMC5PBygZG4iK3arpgzxp +OwIhAKxKJg+mpgVEJiTpsiVhNEeIS1bZWp5W75m3BM1B/haZAiBQOhEcxikcrR0P +xaXvx5Uv1UhWWpUstKSqmLF17jBJEQIhAMx4HMLqwaGeYwOcxfzxz6Al8fnPmfAR +hqFR28fVJrWX +-----END PRIVATE KEY----- -- cgit v1.2.3 From 9539125a8ee97855e7cca4a8060cbf91957d0d98 Mon Sep 17 00:00:00 2001 From: Maxim Fedorov Date: Thu, 10 May 2018 12:48:15 -0700 Subject: PKCS8 handling improvements: * added PKCS8 encoder for DSA, RSA and EC private keys * added tests (full loop, PKCS8 decode/encode operations) * rewritten private key decoder to be more Erlang-y --- lib/public_key/src/pubkey_pem.erl | 2 ++ lib/public_key/src/public_key.erl | 51 +++++++++++++++++++++----------- lib/public_key/test/public_key_SUITE.erl | 29 +++++++++++------- 3 files changed, 54 insertions(+), 28 deletions(-) diff --git a/lib/public_key/src/pubkey_pem.erl b/lib/public_key/src/pubkey_pem.erl index 06a4455b3f..bacc9ec600 100644 --- a/lib/public_key/src/pubkey_pem.erl +++ b/lib/public_key/src/pubkey_pem.erl @@ -209,6 +209,8 @@ pem_start('DSAPrivateKey') -> <<"-----BEGIN DSA PRIVATE KEY-----">>; pem_start('DHParameter') -> <<"-----BEGIN DH PARAMETERS-----">>; +pem_start('PrivateKeyInfo') -> + <<"-----BEGIN PRIVATE KEY-----">>; pem_start('EncryptedPrivateKeyInfo') -> <<"-----BEGIN ENCRYPTED PRIVATE KEY-----">>; pem_start('CertificationRequest') -> diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl index 6900ede946..42fbd59e3c 100644 --- a/lib/public_key/src/public_key.erl +++ b/lib/public_key/src/public_key.erl @@ -204,6 +204,24 @@ pem_entry_encode('SubjectPublicKeyInfo', {'AlgorithmIdentifier', ?'id-ecPublicKey', Params}, Key}, pem_entry_encode('SubjectPublicKeyInfo', Spki); +pem_entry_encode('PrivateKeyInfo', #'DSAPrivateKey'{p=P, q=Q, g=G, x=X}) -> + pem_entry_encode('PrivateKeyInfo', + {'PrivateKeyInfo', v1, + {'PrivateKeyInfo_privateKeyAlgorithm', ?'id-dsa', + {asn1_OPENTYPE, der_encode('Dss-Parms', #'Dss-Parms'{p=P, q=Q, g=G})}}, + der_encode('Prime-p', X), asn1_NOVALUE}); +pem_entry_encode('PrivateKeyInfo', #'RSAPrivateKey'{} = PrivKey) -> + pem_entry_encode('PrivateKeyInfo', + {'PrivateKeyInfo', v1, + {'PrivateKeyInfo_privateKeyAlgorithm', ?'rsaEncryption', + {asn1_OPENTYPE, <<5, 0>>}}, + der_encode('RSAPrivateKey', PrivKey), asn1_NOVALUE}); +pem_entry_encode('PrivateKeyInfo', #'ECPrivateKey'{parameters = Parameters} = PrivKey) -> + pem_entry_encode('PrivateKeyInfo', + {'PrivateKeyInfo', v1, + {'PrivateKeyInfo_privateKeyAlgorithm', ?'id-ecPublicKey', + {asn1_OPENTYPE, der_encode('EcpkParameters', Parameters)}}, + der_encode('ECPrivateKey', PrivKey#'ECPrivateKey'{parameters = asn1_NOVALUE}), asn1_NOVALUE}); pem_entry_encode(Asn1Type, Entity) when is_atom(Asn1Type) -> Der = der_encode(Asn1Type, Entity), {Asn1Type, Der, not_encrypted}. @@ -252,6 +270,21 @@ der_decode(Asn1Type, Der) when is_atom(Asn1Type), is_binary(Der) -> erlang:error(Error) end. +der_priv_key_decode({'PrivateKeyInfo', v1, + {'PrivateKeyInfo_privateKeyAlgorithm', ?'id-ecPublicKey', {asn1_OPENTYPE, Parameters}}, PrivKey, _}) -> + EcPrivKey = der_decode('ECPrivateKey', PrivKey), + EcPrivKey#'ECPrivateKey'{parameters = der_decode('EcpkParameters', Parameters)}; +der_priv_key_decode({'PrivateKeyInfo', v1, + {'PrivateKeyInfo_privateKeyAlgorithm', ?'rsaEncryption', _}, PrivKey, _}) -> + der_decode('RSAPrivateKey', PrivKey); +der_priv_key_decode({'PrivateKeyInfo', v1, + {'PrivateKeyInfo_privateKeyAlgorithm', ?'id-dsa', {asn1_OPENTYPE, Parameters}}, PrivKey, _}) -> + {params, #'Dss-Parms'{p=P, q=Q, g=G}} = der_decode('DSAParams', Parameters), + X = der_decode('Prime-p', PrivKey), + #'DSAPrivateKey'{p=P, q=Q, g=G, x=X}; +der_priv_key_decode(PKCS8Key) -> + PKCS8Key. + %%-------------------------------------------------------------------- -spec der_encode(asn1_type(), term()) -> Der::binary(). %% @@ -276,24 +309,6 @@ der_encode(Asn1Type, Entity) when is_atom(Asn1Type) -> erlang:error(Error) end. -der_priv_key_decode({'PrivateKeyInfo', v1, PKAlgo, PrivKey, _} = PKCS8Key) -> - % do actual decoding - {'PrivateKeyInfo_privateKeyAlgorithm', Algorithm, {asn1_OPENTYPE, Parameters}} = PKAlgo, - case Algorithm of - ?'id-ecPublicKey' -> - EcpkParameters = public_key:der_decode('EcpkParameters', Parameters), - EcPrivKey = public_key:der_decode('ECPrivateKey', PrivKey), - EcPrivKey#'ECPrivateKey'{parameters = EcpkParameters}; - ?'rsaEncryption' -> - public_key:der_decode('RSAPrivateKey', PrivKey); - ?'id-dsa' -> - {params, #'Dss-Parms'{p=P, q=Q, g=G}} = public_key:der_decode('DSAParams', Parameters), - X = public_key:der_decode('Prime-p', PrivKey), - #'DSAPrivateKey'{p=P, q=Q, g=G, x=X}; - _ -> - PKCS8Key - end. - %%-------------------------------------------------------------------- -spec pkix_decode_cert(Cert::binary(), plain | otp) -> #'Certificate'{} | #'OTPCertificate'{}. diff --git a/lib/public_key/test/public_key_SUITE.erl b/lib/public_key/test/public_key_SUITE.erl index f5a6f79136..572748edc9 100644 --- a/lib/public_key/test/public_key_SUITE.erl +++ b/lib/public_key/test/public_key_SUITE.erl @@ -183,14 +183,17 @@ dsa_pem(Config) when is_list(Config) -> DSAPubPemNoEndNewLines = strip_superfluous_newlines(public_key:pem_encode([PubEntry0])). dsa_priv_pkcs8() -> - [{doc, "DSA PKCS8 private key decode"}]. + [{doc, "DSA PKCS8 private key decode/encode"}]. dsa_priv_pkcs8(Config) when is_list(Config) -> Datadir = proplists:get_value(data_dir, Config), - [{'PrivateKeyInfo', DerDSAKey, not_encrypted} = Entry0 ] = - erl_make_certs:pem_to_der(filename:join(Datadir, "dsa_key_pkcs8.pem")), + {ok, DsaPem} = file:read_file(filename:join(Datadir, "dsa_key_pkcs8.pem")), + [{'PrivateKeyInfo', DerDSAKey, not_encrypted} = Entry0 ] = public_key:pem_decode(DsaPem), DSAKey = public_key:der_decode('PrivateKeyInfo', DerDSAKey), DSAKey = public_key:pem_entry_decode(Entry0), - true = check_entry_type(DSAKey, 'DSAPrivateKey'). + true = check_entry_type(DSAKey, 'DSAPrivateKey'), + PrivEntry0 = public_key:pem_entry_encode('PrivateKeyInfo', DSAKey), + DSAPemNoEndNewLines = strip_superfluous_newlines(DsaPem), + DSAPemNoEndNewLines = strip_superfluous_newlines(public_key:pem_encode([PrivEntry0])). %%-------------------------------------------------------------------- @@ -228,14 +231,17 @@ rsa_pem(Config) when is_list(Config) -> RSARawPemNoEndNewLines = strip_superfluous_newlines(public_key:pem_encode([PubEntry1])). rsa_priv_pkcs8() -> - [{doc, "RSA PKCS8 private key decode"}]. + [{doc, "RSA PKCS8 private key decode/encode"}]. rsa_priv_pkcs8(Config) when is_list(Config) -> Datadir = proplists:get_value(data_dir, Config), - [{'PrivateKeyInfo', DerRSAKey, not_encrypted} = Entry0 ] = - erl_make_certs:pem_to_der(filename:join(Datadir, "rsa_key_pkcs8.pem")), + {ok, RsaPem} = file:read_file(filename:join(Datadir, "rsa_key_pkcs8.pem")), + [{'PrivateKeyInfo', DerRSAKey, not_encrypted} = Entry0 ] = public_key:pem_decode(RsaPem), RSAKey = public_key:der_decode('PrivateKeyInfo', DerRSAKey), RSAKey = public_key:pem_entry_decode(Entry0), - true = check_entry_type(RSAKey, 'RSAPrivateKey'). + true = check_entry_type(RSAKey, 'RSAPrivateKey'), + PrivEntry0 = public_key:pem_entry_encode('PrivateKeyInfo', RSAKey), + RSAPemNoEndNewLines = strip_superfluous_newlines(RsaPem), + RSAPemNoEndNewLines = strip_superfluous_newlines(public_key:pem_encode([PrivEntry0])). %%-------------------------------------------------------------------- @@ -284,14 +290,17 @@ ec_pem2(Config) when is_list(Config) -> ECPemNoEndNewLines = strip_superfluous_newlines(public_key:pem_encode([Entry1, Entry2])). ec_priv_pkcs8() -> - [{doc, "EC PKCS8 private key decode"}]. + [{doc, "EC PKCS8 private key decode/encode"}]. ec_priv_pkcs8(Config) when is_list(Config) -> Datadir = proplists:get_value(data_dir, Config), {ok, ECPrivPem} = file:read_file(filename:join(Datadir, "ec_key_pkcs8.pem")), [{'PrivateKeyInfo', _, not_encrypted} = PKCS8Key] = public_key:pem_decode(ECPrivPem), ECPrivKey = public_key:pem_entry_decode(PKCS8Key), true = check_entry_type(ECPrivKey, 'ECPrivateKey'), - true = check_entry_type(ECPrivKey#'ECPrivateKey'.parameters, 'EcpkParameters'). + true = check_entry_type(ECPrivKey#'ECPrivateKey'.parameters, 'EcpkParameters'), + PrivEntry0 = public_key:pem_entry_encode('PrivateKeyInfo', ECPrivKey), + ECPemNoEndNewLines = strip_superfluous_newlines(ECPrivPem), + ECPemNoEndNewLines = strip_superfluous_newlines(public_key:pem_encode([PrivEntry0])). init_ec_pem_encode_generated(Config) -> case catch true = lists:member('secp384r1', crypto:ec_curves()) of -- cgit v1.2.3 From 26c3c3b6496c40f28b59fdbb11351c1830d090b9 Mon Sep 17 00:00:00 2001 From: Maxim Fedorov Date: Tue, 15 May 2018 09:02:01 -0700 Subject: Use DER_NULL macro instead or <<5,0>> --- lib/public_key/src/public_key.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl index 42fbd59e3c..d992037357 100644 --- a/lib/public_key/src/public_key.erl +++ b/lib/public_key/src/public_key.erl @@ -214,7 +214,7 @@ pem_entry_encode('PrivateKeyInfo', #'RSAPrivateKey'{} = PrivKey) -> pem_entry_encode('PrivateKeyInfo', {'PrivateKeyInfo', v1, {'PrivateKeyInfo_privateKeyAlgorithm', ?'rsaEncryption', - {asn1_OPENTYPE, <<5, 0>>}}, + {asn1_OPENTYPE, ?DER_NULL}}, der_encode('RSAPrivateKey', PrivKey), asn1_NOVALUE}); pem_entry_encode('PrivateKeyInfo', #'ECPrivateKey'{parameters = Parameters} = PrivKey) -> pem_entry_encode('PrivateKeyInfo', -- cgit v1.2.3 From 8125494dc169d86e6266842e2e1bfa712ee9ffa8 Mon Sep 17 00:00:00 2001 From: Maxim Fedorov Date: Mon, 21 May 2018 16:43:36 -0700 Subject: PKCS8 encoder must be symmetrical to PKCS8 decoder, thus it has to be in der_encode, and not pem_encode as it was in original implementation --- lib/public_key/src/public_key.erl | 38 +++++++++++++++++++------------------- lib/public_key/test/pbe_SUITE.erl | 10 ++-------- 2 files changed, 21 insertions(+), 27 deletions(-) diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl index d992037357..1c4acc9e1a 100644 --- a/lib/public_key/src/public_key.erl +++ b/lib/public_key/src/public_key.erl @@ -204,24 +204,6 @@ pem_entry_encode('SubjectPublicKeyInfo', {'AlgorithmIdentifier', ?'id-ecPublicKey', Params}, Key}, pem_entry_encode('SubjectPublicKeyInfo', Spki); -pem_entry_encode('PrivateKeyInfo', #'DSAPrivateKey'{p=P, q=Q, g=G, x=X}) -> - pem_entry_encode('PrivateKeyInfo', - {'PrivateKeyInfo', v1, - {'PrivateKeyInfo_privateKeyAlgorithm', ?'id-dsa', - {asn1_OPENTYPE, der_encode('Dss-Parms', #'Dss-Parms'{p=P, q=Q, g=G})}}, - der_encode('Prime-p', X), asn1_NOVALUE}); -pem_entry_encode('PrivateKeyInfo', #'RSAPrivateKey'{} = PrivKey) -> - pem_entry_encode('PrivateKeyInfo', - {'PrivateKeyInfo', v1, - {'PrivateKeyInfo_privateKeyAlgorithm', ?'rsaEncryption', - {asn1_OPENTYPE, ?DER_NULL}}, - der_encode('RSAPrivateKey', PrivKey), asn1_NOVALUE}); -pem_entry_encode('PrivateKeyInfo', #'ECPrivateKey'{parameters = Parameters} = PrivKey) -> - pem_entry_encode('PrivateKeyInfo', - {'PrivateKeyInfo', v1, - {'PrivateKeyInfo_privateKeyAlgorithm', ?'id-ecPublicKey', - {asn1_OPENTYPE, der_encode('EcpkParameters', Parameters)}}, - der_encode('ECPrivateKey', PrivKey#'ECPrivateKey'{parameters = asn1_NOVALUE}), asn1_NOVALUE}); pem_entry_encode(Asn1Type, Entity) when is_atom(Asn1Type) -> Der = der_encode(Asn1Type, Entity), {Asn1Type, Der, not_encrypted}. @@ -290,7 +272,25 @@ der_priv_key_decode(PKCS8Key) -> %% %% Description: Encodes a public key entity with asn1 DER encoding. %%-------------------------------------------------------------------- -der_encode(Asn1Type, Entity) when (Asn1Type == 'PrivateKeyInfo') or + +der_encode('PrivateKeyInfo', #'DSAPrivateKey'{p=P, q=Q, g=G, x=X}) -> + der_encode('PrivateKeyInfo', + {'PrivateKeyInfo', v1, + {'PrivateKeyInfo_privateKeyAlgorithm', ?'id-dsa', + {asn1_OPENTYPE, der_encode('Dss-Parms', #'Dss-Parms'{p=P, q=Q, g=G})}}, + der_encode('Prime-p', X), asn1_NOVALUE}); +der_encode('PrivateKeyInfo', #'RSAPrivateKey'{} = PrivKey) -> + der_encode('PrivateKeyInfo', + {'PrivateKeyInfo', v1, + {'PrivateKeyInfo_privateKeyAlgorithm', ?'rsaEncryption', {asn1_OPENTYPE, ?DER_NULL}}, + der_encode('RSAPrivateKey', PrivKey), asn1_NOVALUE}); +der_encode('PrivateKeyInfo', #'ECPrivateKey'{parameters = Parameters} = PrivKey) -> + der_encode('PrivateKeyInfo', + {'PrivateKeyInfo', v1, + {'PrivateKeyInfo_privateKeyAlgorithm', ?'id-ecPublicKey', + {asn1_OPENTYPE, der_encode('EcpkParameters', Parameters)}}, + der_encode('ECPrivateKey', PrivKey#'ECPrivateKey'{parameters = asn1_NOVALUE}), asn1_NOVALUE}); +der_encode(Asn1Type, Entity) when (Asn1Type == 'PrivateKeyInfo') or (Asn1Type == 'EncryptedPrivateKeyInfo') -> try {ok, Encoded} = 'PKCS-FRAME':encode(Asn1Type, Entity), diff --git a/lib/public_key/test/pbe_SUITE.erl b/lib/public_key/test/pbe_SUITE.erl index 44caf479e5..8a5db4efec 100644 --- a/lib/public_key/test/pbe_SUITE.erl +++ b/lib/public_key/test/pbe_SUITE.erl @@ -226,11 +226,6 @@ pbes2(Config) when is_list(Config) -> ok end. -check_key_info(#'PrivateKeyInfo'{privateKeyAlgorithm = - #'PrivateKeyInfo_privateKeyAlgorithm'{algorithm = ?rsaEncryption}, - privateKey = Key}) -> - #'RSAPrivateKey'{} = public_key:der_decode('RSAPrivateKey', iolist_to_binary(Key)). - decode_encode_key_file(File, Password, Cipher, Config) -> Datadir = proplists:get_value(data_dir, Config), {ok, PemKey} = file:read_file(filename:join(Datadir, File)), @@ -238,11 +233,10 @@ decode_encode_key_file(File, Password, Cipher, Config) -> PemEntry = public_key:pem_decode(PemKey), ct:print("Pem entry: ~p" , [PemEntry]), [{Asn1Type, _, {Cipher,_} = CipherInfo} = PubEntry] = PemEntry, - KeyInfo = public_key:pem_entry_decode(PubEntry, Password), + #'RSAPrivateKey'{} = KeyInfo = public_key:pem_entry_decode(PubEntry, Password), PemKey1 = public_key:pem_encode([public_key:pem_entry_encode(Asn1Type, KeyInfo, {CipherInfo, Password})]), Pem = strip_ending_newlines(PemKey), - Pem = strip_ending_newlines(PemKey1), - check_key_info(KeyInfo). + Pem = strip_ending_newlines(PemKey1). strip_ending_newlines(Bin) -> string:strip(binary_to_list(Bin), right, 10). -- cgit v1.2.3