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