File 3871-Support-Ed25519-Ed448-SSH-host-keys-in-OpenSSL-forma.patch of Package erlang

From d450ebc24ec469e00cb487c8c5027d158e1f1246 Mon Sep 17 00:00:00 2001
From: Jon Carstens <jjcarstens@me.com>
Date: Thu, 16 Dec 2021 20:12:36 -0700
Subject: [PATCH] Support Ed25519/Ed448 SSH host keys in OpenSSL format

---
 lib/ssh/src/ssh_transport.erl                  | 18 ++++++++++++++++++
 lib/ssh/test/ssh_pubkey_SUITE.erl              | 18 +++++++++---------
 .../old_format/ssh_host_ed25519_key            |  4 ++++
 .../old_format/ssh_host_ed25519_key.pub        |  1 +
 .../old_format/ssh_host_ed448_key              |  5 +++++
 .../old_format/ssh_host_ed448_key.pub          |  1 +
 .../old_format_passphrase/ssh_host_ed25519_key |  4 ++++
 .../ssh_host_ed25519_key.pub                   |  1 +
 .../old_format_passphrase/ssh_host_ed448_key   |  5 +++++
 .../ssh_host_ed448_key.pub                     |  1 +
 10 files changed, 49 insertions(+), 9 deletions(-)
 create mode 100644 lib/ssh/test/ssh_pubkey_SUITE_data/old_format/ssh_host_ed25519_key
 create mode 100644 lib/ssh/test/ssh_pubkey_SUITE_data/old_format/ssh_host_ed25519_key.pub
 create mode 100644 lib/ssh/test/ssh_pubkey_SUITE_data/old_format/ssh_host_ed448_key
 create mode 100644 lib/ssh/test/ssh_pubkey_SUITE_data/old_format/ssh_host_ed448_key.pub
 create mode 100644 lib/ssh/test/ssh_pubkey_SUITE_data/old_format_passphrase/ssh_host_ed25519_key
 create mode 100644 lib/ssh/test/ssh_pubkey_SUITE_data/old_format_passphrase/ssh_host_ed25519_key.pub
 create mode 100644 lib/ssh/test/ssh_pubkey_SUITE_data/old_format_passphrase/ssh_host_ed448_key
 create mode 100644 lib/ssh/test/ssh_pubkey_SUITE_data/old_format_passphrase/ssh_host_ed448_key.pub

diff --git a/lib/ssh/src/ssh_transport.erl b/lib/ssh/src/ssh_transport.erl
index 13c6c67134..e43c345130 100644
--- a/lib/ssh/src/ssh_transport.erl
+++ b/lib/ssh/src/ssh_transport.erl
@@ -930,6 +930,19 @@ extract_public_key(#'RSAPrivateKey'{modulus = N, publicExponent = E}) ->
     #'RSAPublicKey'{modulus = N, publicExponent = E};
 extract_public_key(#'DSAPrivateKey'{y = Y, p = P, q = Q, g = G}) ->
     {Y,  #'Dss-Parms'{p=P, q=Q, g=G}};
+extract_public_key(#'ECPrivateKey'{parameters = {namedCurve,OID},
+				   publicKey = Pub0, privateKey = Priv}) when
+      OID == ?'id-Ed25519'orelse
+      OID == ?'id-Ed448' ->
+    case {pubkey_cert_records:namedCurves(OID), Pub0} of
+        {Alg, asn1_NOVALUE} ->
+            %% If we're missing the public key, we can create it with
+            %% the private key.
+            {Pub, Priv} = crypto:generate_key(eddsa, Alg, Priv),
+            {ed_pub, Alg, Pub};
+        {Alg, Pub} ->
+            {ed_pub, Alg, Pub}
+    end;
 extract_public_key(#'ECPrivateKey'{parameters = {namedCurve,OID},
 				   publicKey = Q}) when is_tuple(OID) ->
     {#'ECPoint'{point=Q}, {namedCurve,OID}};
@@ -1505,6 +1518,9 @@ sign(SigData, HashAlg, #{algorithm:=SigAlg} = Key) ->
     crypto:sign(SigAlg, HashAlg, SigData, Key);
 sign(SigData, HashAlg,  #'DSAPrivateKey'{} = Key) ->
     mk_dss_sig(public_key:sign(SigData, HashAlg, Key));
+sign(SigData, HashAlg, Key = #'ECPrivateKey'{parameters = {namedCurve, Curve}})
+  when (Curve == ?'id-Ed25519') orelse (Curve == ?'id-Ed448') ->
+    public_key:sign(SigData, HashAlg, Key);
 sign(SigData, HashAlg, Key = #'ECPrivateKey'{}) ->
     DerEncodedSign =  public_key:sign(SigData, HashAlg, Key),
     #'ECDSA-Sig-Value'{r=R, s=S} = public_key:der_decode('ECDSA-Sig-Value', DerEncodedSign),
@@ -2047,8 +2063,10 @@ valid_key_sha_alg(private, #'DSAPrivateKey'{},  'ssh-dss') -> true;
 
 valid_key_sha_alg(public, {ed_pub, ed25519,_},  'ssh-ed25519') -> true;
 valid_key_sha_alg(private, {ed_pri, ed25519,_,_},'ssh-ed25519') -> true;
+valid_key_sha_alg(private, #'ECPrivateKey'{parameters = {namedCurve,OID}},'ssh-ed25519') when OID == ?'id-Ed25519' -> true;
 valid_key_sha_alg(public, {ed_pub, ed448,_},    'ssh-ed448') -> true;
 valid_key_sha_alg(private, {ed_pri, ed448,_,_},  'ssh-ed448') -> true;
+valid_key_sha_alg(private, #'ECPrivateKey'{parameters = {namedCurve,OID}},'ssh-ed448') when OID == ?'id-Ed448' -> true;
 
 valid_key_sha_alg(public, {#'ECPoint'{},{namedCurve,OID}}, Alg) when is_tuple(OID) ->
     valid_key_sha_alg_ec(OID, Alg);
diff --git a/lib/ssh/test/ssh_pubkey_SUITE.erl b/lib/ssh/test/ssh_pubkey_SUITE.erl
index 6c78cd2d68..81c32e0197 100644
--- a/lib/ssh/test/ssh_pubkey_SUITE.erl
+++ b/lib/ssh/test/ssh_pubkey_SUITE.erl
@@ -119,14 +119,16 @@ all() ->
                     connect_dsa_to_ecdsa,
                     connect_ecdsa_to_rsa_sha2,
                     connect_ecdsa_to_dsa,
-                    connect_ecdsa_to_ecdsa
-                   ]).
-
--define(tests_new, [connect_dsa_to_ed25519,
-                    connect_dsa_to_ed448,
+                    connect_ecdsa_to_ecdsa,
+                    connect_dsa_to_ed25519,
                     connect_ecdsa_to_ed25519,
+                    connect_rsa_sha2_to_ed25519,
+                    connect_dsa_to_ed448,
                     connect_ecdsa_to_ed448,
-                    connect_ed25519_to_dsa,
+                    connect_rsa_sha2_to_ed448
+                   ]).
+
+-define(tests_new, [connect_ed25519_to_dsa,
                     connect_ed25519_to_ecdsa,
                     connect_ed25519_to_ed448,
                     connect_ed25519_to_ed25519,
@@ -135,9 +137,7 @@ all() ->
                     connect_ed448_to_ecdsa,
                     connect_ed448_to_ed25519,
                     connect_ed448_to_ed448,
-                    connect_ed448_to_rsa_sha2,
-                    connect_rsa_sha2_to_ed25519,
-                    connect_rsa_sha2_to_ed448
+                    connect_ed448_to_rsa_sha2
                     | ?tests_old % but taken from the new format directory
                    ]).
 
diff --git a/lib/ssh/test/ssh_pubkey_SUITE_data/old_format/ssh_host_ed25519_key b/lib/ssh/test/ssh_pubkey_SUITE_data/old_format/ssh_host_ed25519_key
new file mode 100644
index 0000000000..6542cc7218
--- /dev/null
+++ b/lib/ssh/test/ssh_pubkey_SUITE_data/old_format/ssh_host_ed25519_key
@@ -0,0 +1,4 @@
+-----BEGIN EC PRIVATE KEY-----
+MFECAQEEIFZTDpCko9CxtWW5UKzRqvMXPTJZfIdcA5u/IOV3EmU4oAUGAytlcKEj
+AyEAIAJ1D3OUNmUJRCDQ8uPkVCeTV6oNOtpubn2I7x2VxM0=
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_pubkey_SUITE_data/old_format/ssh_host_ed25519_key.pub b/lib/ssh/test/ssh_pubkey_SUITE_data/old_format/ssh_host_ed25519_key.pub
new file mode 100644
index 0000000000..4a1b4c7f3d
--- /dev/null
+++ b/lib/ssh/test/ssh_pubkey_SUITE_data/old_format/ssh_host_ed25519_key.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICACdQ9zlDZlCUQg0PLj5FQnk1eqDTrabm59iO8dlcTN uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_pubkey_SUITE_data/old_format/ssh_host_ed448_key b/lib/ssh/test/ssh_pubkey_SUITE_data/old_format/ssh_host_ed448_key
new file mode 100644
index 0000000000..ac7320e12c
--- /dev/null
+++ b/lib/ssh/test/ssh_pubkey_SUITE_data/old_format/ssh_host_ed448_key
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MIGDAgEBBDlf6cdZBOKnN7msVY8oloq9Se2ee5RBXGf3Ofs96djk8uqEAyQdWUe+
+fWMNDPVnyViy7qceZkECkf6gBQYDK2VxoTwDOgCLHixRiwKzXM1/OOTdsC1L06OS
+3BntXrBWpqKU2Xhr1acxidyCB/0hhtf89NtZVm0zkXBf/zL6jQA=
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_pubkey_SUITE_data/old_format/ssh_host_ed448_key.pub b/lib/ssh/test/ssh_pubkey_SUITE_data/old_format/ssh_host_ed448_key.pub
new file mode 100644
index 0000000000..c97f1e3003
--- /dev/null
+++ b/lib/ssh/test/ssh_pubkey_SUITE_data/old_format/ssh_host_ed448_key.pub
@@ -0,0 +1 @@
+ssh-ed448 AAAACXNzaC1lZDQ0OAAAADmLHixRiwKzXM1/OOTdsC1L06OS3BntXrBWpqKU2Xhr1acxidyCB/0hhtf89NtZVm0zkXBf/zL6jQA= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_pubkey_SUITE_data/old_format_passphrase/ssh_host_ed25519_key b/lib/ssh/test/ssh_pubkey_SUITE_data/old_format_passphrase/ssh_host_ed25519_key
new file mode 100644
index 0000000000..6542cc7218
--- /dev/null
+++ b/lib/ssh/test/ssh_pubkey_SUITE_data/old_format_passphrase/ssh_host_ed25519_key
@@ -0,0 +1,4 @@
+-----BEGIN EC PRIVATE KEY-----
+MFECAQEEIFZTDpCko9CxtWW5UKzRqvMXPTJZfIdcA5u/IOV3EmU4oAUGAytlcKEj
+AyEAIAJ1D3OUNmUJRCDQ8uPkVCeTV6oNOtpubn2I7x2VxM0=
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_pubkey_SUITE_data/old_format_passphrase/ssh_host_ed25519_key.pub b/lib/ssh/test/ssh_pubkey_SUITE_data/old_format_passphrase/ssh_host_ed25519_key.pub
new file mode 100644
index 0000000000..4a1b4c7f3d
--- /dev/null
+++ b/lib/ssh/test/ssh_pubkey_SUITE_data/old_format_passphrase/ssh_host_ed25519_key.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICACdQ9zlDZlCUQg0PLj5FQnk1eqDTrabm59iO8dlcTN uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_pubkey_SUITE_data/old_format_passphrase/ssh_host_ed448_key b/lib/ssh/test/ssh_pubkey_SUITE_data/old_format_passphrase/ssh_host_ed448_key
new file mode 100644
index 0000000000..ac7320e12c
--- /dev/null
+++ b/lib/ssh/test/ssh_pubkey_SUITE_data/old_format_passphrase/ssh_host_ed448_key
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MIGDAgEBBDlf6cdZBOKnN7msVY8oloq9Se2ee5RBXGf3Ofs96djk8uqEAyQdWUe+
+fWMNDPVnyViy7qceZkECkf6gBQYDK2VxoTwDOgCLHixRiwKzXM1/OOTdsC1L06OS
+3BntXrBWpqKU2Xhr1acxidyCB/0hhtf89NtZVm0zkXBf/zL6jQA=
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_pubkey_SUITE_data/old_format_passphrase/ssh_host_ed448_key.pub b/lib/ssh/test/ssh_pubkey_SUITE_data/old_format_passphrase/ssh_host_ed448_key.pub
new file mode 100644
index 0000000000..c97f1e3003
--- /dev/null
+++ b/lib/ssh/test/ssh_pubkey_SUITE_data/old_format_passphrase/ssh_host_ed448_key.pub
@@ -0,0 +1 @@
+ssh-ed448 AAAACXNzaC1lZDQ0OAAAADmLHixRiwKzXM1/OOTdsC1L06OS3BntXrBWpqKU2Xhr1acxidyCB/0hhtf89NtZVm0zkXBf/zL6jQA= uabhnil@elxadlj3q32
-- 
2.31.1

openSUSE Build Service is sponsored by