Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:23
erlang
2533-public_key-Add-support-for-EDDSA-key-on-RF...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 2533-public_key-Add-support-for-EDDSA-key-on-RFC-5958-for.patch of Package erlang
From 37a58368d7876e325710a4c269f0af27b40434c6 Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin <ingela@erlang.org> Date: Fri, 9 Apr 2021 12:34:00 +0200 Subject: [PATCH 3/8] public_key: Add support for EDDSA key on RFC 5958 format For now make minimal ASN-1 addition. We probably want to modernize all ASN-1 specs. --- lib/public_key/asn1/ECPrivateKey.asn1 | 7 +++- lib/public_key/asn1/PKCS-8.asn1 | 16 ++++++++ lib/public_key/src/pubkey_pem.erl | 2 + lib/public_key/src/public_key.erl | 38 +++++++++++++++++-- lib/public_key/test/public_key_SUITE.erl | 16 +++++++- .../eddsa_key_rfc5958.pem | 5 +++ 6 files changed, 78 insertions(+), 6 deletions(-) create mode 100644 lib/public_key/test/public_key_SUITE_data/eddsa_key_rfc5958.pem diff --git a/lib/public_key/asn1/ECPrivateKey.asn1 b/lib/public_key/asn1/ECPrivateKey.asn1 index 5f7267506f..e0f4c3a011 100644 --- a/lib/public_key/asn1/ECPrivateKey.asn1 +++ b/lib/public_key/asn1/ECPrivateKey.asn1 @@ -18,9 +18,14 @@ ECPrivateKey ::= SEQUENCE { version INTEGER, privateKey CurvePrivateKey, parameters [0] EcpkParameters OPTIONAL, - publicKey [1] BIT STRING OPTIONAL + publicKey [1] CurvePublicKey OPTIONAL, + -- Should be PKCS-8 Attributes but problem at the moment with PKCS-8 beeing part + -- of PCKS-FRAME and PKIX1Algorithms88 is part of OTP-PUB-KEY. Procrastinate + -- the solution as it mostly not used anyway + attributes ANY OPTIONAL } CurvePrivateKey ::= OCTET STRING +CurvePublicKey ::= BIT STRING END diff --git a/lib/public_key/asn1/PKCS-8.asn1 b/lib/public_key/asn1/PKCS-8.asn1 index 292a7b2029..87b3ecd99c 100644 --- a/lib/public_key/asn1/PKCS-8.asn1 +++ b/lib/public_key/asn1/PKCS-8.asn1 @@ -51,6 +51,22 @@ PrivateKeyInfo ::= SEQUENCE { privateKey PrivateKey, attributes [0] Attributes OPTIONAL } +-- START FROM RFC 5958 +OneAsymmetricKey ::= SEQUENCE { + version Version, + privateKeyAlgorithm AlgorithmIdentifier {{...}}, + privateKey PrivateKey, + attributes [0] Attributes OPTIONAL, + ..., + [[2: publicKey [1] PublicKey OPTIONAL ]], + ... + } + +PublicKey ::= BIT STRING + -- Content varies based on type of key. The + -- algorithm identifier dictates the format of + -- the key. +-- END FROM RFC 5958 Version ::= INTEGER {v1(0)} (v1,...) PrivateKey ::= OCTET STRING diff --git a/lib/public_key/src/pubkey_pem.erl b/lib/public_key/src/pubkey_pem.erl index a33db4ecf0..a4d54c9e63 100644 --- a/lib/public_key/src/pubkey_pem.erl +++ b/lib/public_key/src/pubkey_pem.erl @@ -212,6 +212,8 @@ pem_start('DHParameter') -> <<"-----BEGIN DH PARAMETERS-----">>; pem_start('PrivateKeyInfo') -> <<"-----BEGIN PRIVATE KEY-----">>; +pem_start('OneAsymmetricKey') -> + <<"-----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 4f097a1e2d..b9eeac1b12 100644 --- a/lib/public_key/src/public_key.erl +++ b/lib/public_key/src/public_key.erl @@ -291,7 +291,7 @@ der_decode(Asn1Type, Der) when (((Asn1Type == 'PrivateKeyInfo') der_priv_key_decode(Decoded) catch error:{badmatch, {error, _}} = Error -> - erlang:error(Error) + handle_pkcs_frame_error(Asn1Type, Der, Error) end; der_decode(Asn1Type, Der) when is_atom(Asn1Type), is_binary(Der) -> @@ -303,6 +303,17 @@ der_decode(Asn1Type, Der) when is_atom(Asn1Type), is_binary(Der) -> erlang:error(Error) end. +handle_pkcs_frame_error('PrivateKeyInfo', Der, _) -> + try + {ok, Decoded} = 'PKCS-FRAME':decode('OneAsymmetricKey', Der), + der_priv_key_decode(Decoded) + catch + error:{badmatch, {error, _}} = Error -> + erlang:error(Error) + end; +handle_pkcs_frame_error(_, _, Error) -> + erlang:error(Error). + der_priv_key_decode({'PrivateKeyInfo', v1, {'PrivateKeyInfo_privateKeyAlgorithm', ?'id-ecPublicKey', {asn1_OPENTYPE, Parameters}}, PrivKey, _}) -> EcPrivKey = der_decode('ECPrivateKey', PrivKey), @@ -312,6 +323,13 @@ der_priv_key_decode({'PrivateKeyInfo', v1, CurveOId == ?'id-Ed25519'orelse CurveOId == ?'id-Ed448' -> #'ECPrivateKey'{version = 1, parameters = {namedCurve, CurveOId}, privateKey = PrivKey}; +der_priv_key_decode({'OneAsymmetricKey', _, + {'OneAsymmetricKey_privateKeyAlgorithm', CurveOId, _}, PrivKey, Attr, PubKey}) when + CurveOId == ?'id-Ed25519'orelse + CurveOId == ?'id-Ed448' -> + #'ECPrivateKey'{version = 2, parameters = {namedCurve, CurveOId}, privateKey = PrivKey, + attributes = Attr, + publicKey = PubKey}; der_priv_key_decode({'PrivateKeyInfo', v1, {'PrivateKeyInfo_privateKeyAlgorithm', ?'rsaEncryption', _}, PrivKey, _}) -> der_decode('RSAPrivateKey', PrivKey); @@ -351,10 +369,10 @@ der_encode('PrivateKeyInfo', #'RSAPrivateKey'{} = PrivKey) -> der_encode('PrivateKeyInfo', {#'RSAPrivateKey'{} = PrivKey, Parameters}) -> der_encode('PrivateKeyInfo', {'PrivateKeyInfo', v1, - {'PrivateKeyInfo_privateKeyAlgorithm', ?'id-RSASSA-PSS', + {'PrivateKeyInfo_privateKeyAlgorithm', ?'id-RSASSA-PSS', {asn1_OPENTYPE, der_encode('RSASSA-PSS-params', Parameters)}}, der_encode('RSAPrivateKey', PrivKey), asn1_NOVALUE}); -der_encode('PrivateKeyInfo', #'ECPrivateKey'{parameters = {namedCurve, CurveOId} = Parameters, +der_encode('PrivateKeyInfo', #'ECPrivateKey'{parameters = {namedCurve, CurveOId}, privateKey = PrivKey}) when CurveOId == ?'id-Ed25519' orelse CurveOId == ?'id-Ed448' -> @@ -369,7 +387,19 @@ der_encode('PrivateKeyInfo', #'ECPrivateKey'{parameters = Parameters} = PrivKey) {asn1_OPENTYPE, der_encode('EcpkParameters', Parameters)}}, der_encode('ECPrivateKey', PrivKey#'ECPrivateKey'{parameters = asn1_NOVALUE}), asn1_NOVALUE}); -der_encode(Asn1Type, Entity) when (Asn1Type == 'PrivateKeyInfo') or +der_encode('OneAsymmetricKey', #'ECPrivateKey'{parameters = {namedCurve, CurveOId}, + privateKey = PrivKey, + attributes = Attr, + publicKey = PubKey}) -> + der_encode('OneAsymmetricKey', + {'OneAsymmetricKey', 1, + {'OneAsymmetricKey_privateKeyAlgorithm', CurveOId, asn1_NOVALUE}, + PrivKey, + Attr, + PubKey + }); +der_encode(Asn1Type, Entity) when (Asn1Type == 'PrivateKeyInfo') orelse + (Asn1Type == 'OneAsymmetricKey') orelse (Asn1Type == 'EncryptedPrivateKeyInfo') -> try {ok, Encoded} = 'PKCS-FRAME':encode(Asn1Type, Entity), diff --git a/lib/public_key/test/public_key_SUITE.erl b/lib/public_key/test/public_key_SUITE.erl index ae16eca83e..bbd458c036 100644 --- a/lib/public_key/test/public_key_SUITE.erl +++ b/lib/public_key/test/public_key_SUITE.erl @@ -57,6 +57,8 @@ ec_priv_pkcs8/1, eddsa_priv_pkcs8/0, eddsa_priv_pkcs8/1, + eddsa_priv_rfc5958/0, + eddsa_priv_rfc5958/1, init_ec_pem_encode_generated/1, ec_pem_encode_generated/0, ec_pem_encode_generated/1, @@ -159,7 +161,7 @@ groups() -> [{pem_decode_encode, [], [dsa_pem, rsa_pem, rsa_pss_pss_pem, ec_pem, encrypted_pem, dh_pem, cert_pem, pkcs7_pem, pkcs10_pem, ec_pem2, rsa_priv_pkcs8, dsa_priv_pkcs8, ec_priv_pkcs8, - eddsa_priv_pkcs8, + eddsa_priv_pkcs8, eddsa_priv_rfc5958, ec_pem_encode_generated, gen_ec_param_prime_field, gen_ec_param_char_2_field ]}, @@ -415,6 +417,18 @@ eddsa_priv_pkcs8(Config) when is_list(Config) -> ECPemNoEndNewLines = strip_superfluous_newlines(ECPrivPem), ECPemNoEndNewLines = strip_superfluous_newlines(public_key:pem_encode([PrivEntry0])). +eddsa_priv_rfc5958() -> + [{doc, "EDDSA PKCS8 private key decode/encode"}]. +eddsa_priv_rfc5958(Config) when is_list(Config) -> + Datadir = proplists:get_value(data_dir, Config), + {ok, ECPrivPem} = file:read_file(filename:join(Datadir, "eddsa_key_rfc5958.pem")), + [{'PrivateKeyInfo', _, not_encrypted} = PKCS8Key] = public_key:pem_decode(ECPrivPem), + ECPrivKey = public_key:pem_entry_decode(PKCS8Key), + true = check_entry_type(ECPrivKey, 'ECPrivateKey'), + true = ECPrivKey#'ECPrivateKey'.parameters == {namedCurve, ?'id-Ed25519'}, + PrivEntry0 = public_key:pem_entry_encode('OneAsymmetricKey', 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 diff --git a/lib/public_key/test/public_key_SUITE_data/eddsa_key_rfc5958.pem b/lib/public_key/test/public_key_SUITE_data/eddsa_key_rfc5958.pem new file mode 100644 index 0000000000..7179f294ba --- /dev/null +++ b/lib/public_key/test/public_key_SUITE_data/eddsa_key_rfc5958.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MHICAQEwBQYDK2VwBCIEINTuctv5E1hK1bbY8fdp+K06/nwoy/HU++CXqI9EdVhC +oB8wHQYKKoZIhvcNAQkJFDEPDA1DdXJkbGUgQ2hhaXJzgSEAGb9ECWmEzf6FQbrB +Z9w7lshQhqowtrbLDFw4rXAxZuE= +-----END PRIVATE KEY----- \ No newline at end of file -- 2.26.2
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor