File 2561-public_key-Fix-EDDSA-private-key-ASN-1-decode-encode.patch of Package erlang
From 14c8774fac2c82aa14c7a2195f2668fd538b378e Mon Sep 17 00:00:00 2001
From: Stefan Grundmann <sg2342@googlemail.com>
Date: Fri, 27 Aug 2021 03:02:48 +0000
Subject: [PATCH] public_key: Fix EDDSA private key ASN-1 decode/encode
RFC8410 Section 7: the private key is wrapped in a CurvePrivateKey
object and wrapped by the OCTET STRING of the "privateKey" field
- unwrap CurvePrivateKey in public_key:der_decode/2
- wrap in CurvePrivateKey in public_key:der_encode/2
- assert key size in DER decode tests
---
lib/public_key/src/public_key.erl | 23 ++++++++++++++++++++---
lib/public_key/test/public_key_SUITE.erl | 2 ++
2 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl
index e88c33c0db..b8f9573249 100644
--- a/lib/public_key/src/public_key.erl
+++ b/lib/public_key/src/public_key.erl
@@ -342,17 +342,19 @@ der_priv_key_decode(#'PrivateKeyInfo'{version = v1,
EcPrivKey#'ECPrivateKey'{parameters = der_decode('EcpkParameters', Parameters)};
der_priv_key_decode(#'PrivateKeyInfo'{version = v1,
privateKeyAlgorithm =#'PrivateKeyInfo_privateKeyAlgorithm'{algorithm = CurveOId},
- privateKey = PrivKey}) when
+ privateKey = CurvePrivKey}) when
CurveOId == ?'id-Ed25519'orelse
CurveOId == ?'id-Ed448' ->
+ PrivKey = der_decode('CurvePrivateKey', CurvePrivKey),
#'ECPrivateKey'{version = 1, parameters = {namedCurve, CurveOId}, privateKey = PrivKey};
der_priv_key_decode(#'OneAsymmetricKey'{
privateKeyAlgorithm = #'OneAsymmetricKey_privateKeyAlgorithm'{algorithm = CurveOId},
- privateKey = PrivKey,
+ privateKey = CurvePrivKey,
attributes = Attr,
publicKey = PubKey}) when
CurveOId == ?'id-Ed25519'orelse
CurveOId == ?'id-Ed448' ->
+ PrivKey = der_decode('CurvePrivateKey', CurvePrivKey),
#'ECPrivateKey'{version = 2, parameters = {namedCurve, CurveOId}, privateKey = PrivKey,
attributes = Attr,
publicKey = PubKey};
@@ -415,10 +417,11 @@ der_encode('PrivateKeyInfo', #'ECPrivateKey'{parameters = {namedCurve, CurveOId}
privateKey = Key}) when
CurveOId == ?'id-Ed25519' orelse
CurveOId == ?'id-Ed448' ->
+ CurvePrivKey = der_encode('CurvePrivateKey', Key),
Alg = #'PrivateKeyInfo_privateKeyAlgorithm'{algorithm = CurveOId},
der_encode('PrivateKeyInfo', #'PrivateKeyInfo'{version = v1,
privateKeyAlgorithm = Alg,
- privateKey = Key});
+ privateKey = CurvePrivKey});
der_encode('PrivateKeyInfo', #'ECPrivateKey'{parameters = Parameters} = PrivKey) ->
Params = der_encode('EcpkParameters', Parameters),
Alg = #'PrivateKeyInfo_privateKeyAlgorithm'{algorithm = ?'id-ecPublicKey',
@@ -428,6 +431,20 @@ der_encode('PrivateKeyInfo', #'ECPrivateKey'{parameters = Parameters} = PrivKey)
#'PrivateKeyInfo'{version = v1,
privateKeyAlgorithm = Alg,
privateKey = Key});
+der_encode('OneAsymmetricKey', #'ECPrivateKey'{parameters = {namedCurve, CurveOId},
+ privateKey = Key,
+ attributes = Attr,
+ publicKey = PubKey}) when
+ CurveOId == ?'id-Ed25519' orelse
+ CurveOId == ?'id-Ed448' ->
+ CurvePrivKey = der_encode('CurvePrivateKey', Key),
+ Alg = #'OneAsymmetricKey_privateKeyAlgorithm'{algorithm = CurveOId},
+ der_encode('OneAsymmetricKey',
+ #'OneAsymmetricKey'{version = 1,
+ privateKeyAlgorithm = Alg,
+ privateKey = CurvePrivKey,
+ attributes = Attr,
+ publicKey = PubKey});
der_encode('OneAsymmetricKey', #'ECPrivateKey'{parameters = {namedCurve, CurveOId},
privateKey = Key,
attributes = Attr,
diff --git a/lib/public_key/test/public_key_SUITE.erl b/lib/public_key/test/public_key_SUITE.erl
index a6c0f0d6ee..51808f831a 100644
--- a/lib/public_key/test/public_key_SUITE.erl
+++ b/lib/public_key/test/public_key_SUITE.erl
@@ -413,6 +413,7 @@ eddsa_priv_pkcs8(Config) when is_list(Config) ->
ECPrivKey = public_key:pem_entry_decode(PKCS8Key),
true = check_entry_type(ECPrivKey, 'ECPrivateKey'),
true = ECPrivKey#'ECPrivateKey'.parameters == {namedCurve, ?'id-Ed25519'},
+ true = size(ECPrivKey#'ECPrivateKey'.privateKey) == 32,
PrivEntry0 = public_key:pem_entry_encode('PrivateKeyInfo', ECPrivKey),
ECPemNoEndNewLines = strip_superfluous_newlines(ECPrivPem),
ECPemNoEndNewLines = strip_superfluous_newlines(public_key:pem_encode([PrivEntry0])).
@@ -426,6 +427,7 @@ eddsa_priv_rfc5958(Config) when is_list(Config) ->
ECPrivKey = public_key:pem_entry_decode(PKCS8Key),
true = check_entry_type(ECPrivKey, 'ECPrivateKey'),
true = ECPrivKey#'ECPrivateKey'.parameters == {namedCurve, ?'id-Ed25519'},
+ true = size(ECPrivKey#'ECPrivateKey'.privateKey) == 32,
PrivEntry0 = public_key:pem_entry_encode('OneAsymmetricKey', ECPrivKey),
ECPemNoEndNewLines = strip_superfluous_newlines(ECPrivPem),
ECPemNoEndNewLines = strip_superfluous_newlines(public_key:pem_encode([PrivEntry0])).
--
2.31.1