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

openSUSE Build Service is sponsored by