File 2534-ssl-Add-support-for-EDDSA.patch of Package erlang

From 0706f322ba1864ab83b74e752602f7d3e1feb2c2 Mon Sep 17 00:00:00 2001
From: Ingela Anderton Andin <ingela@erlang.org>
Date: Mon, 12 Apr 2021 14:21:43 +0200
Subject: [PATCH 4/8] ssl: Add support for EDDSA

Closes #4637
---
 lib/ssl/doc/src/standards_compliance.xml   | 10 ++--
 lib/ssl/src/ssl.erl                        | 10 ++--
 lib/ssl/src/ssl_certificate.erl            |  6 +++
 lib/ssl/src/ssl_cipher.erl                 | 12 ++---
 lib/ssl/src/ssl_handshake.erl              |  4 ++
 lib/ssl/src/tls_handshake_1_3.erl          |  8 +++-
 lib/ssl/src/tls_v1.erl                     | 20 +++++---
 lib/ssl/test/openssl_client_cert_SUITE.erl | 52 +++++++++++++-------
 lib/ssl/test/openssl_server_cert_SUITE.erl | 50 ++++++++++++-------
 lib/ssl/test/ssl_cert_SUITE.erl            | 56 +++++++++++++++++-----
 lib/ssl/test/ssl_test_lib.erl              | 29 ++++++++++-
 11 files changed, 185 insertions(+), 72 deletions(-)

diff --git a/lib/ssl/doc/src/standards_compliance.xml b/lib/ssl/doc/src/standards_compliance.xml
index b2e7d17c45..7b12a15261 100644
--- a/lib/ssl/doc/src/standards_compliance.xml
+++ b/lib/ssl/doc/src/standards_compliance.xml
@@ -134,7 +134,7 @@
       <item>Groups: all standard groups supported for the Diffie-Hellman key exchange</item>
       <item>Ciphers: all cipher suites are supported</item>
       <item>Signature Algorithms: All algorithms form RFC 8446</item>
-      <item>Certificates: RSA and ECDSA keys</item>
+      <item>Certificates: RSA, ECDSA and EDDSA keys</item>
     </list>
     <p>Other notable features:</p>
     <list type="bulleted">
@@ -762,13 +762,13 @@
       <row>
         <cell align="left" valign="middle"></cell>
         <cell align="left" valign="middle">ed25519</cell>
-	<cell align="left" valign="middle"><em>NC</em></cell>
+	<cell align="left" valign="middle"><em>24</em></cell>
 	<cell align="left" valign="middle"></cell>
       </row>
       <row>
         <cell align="left" valign="middle"></cell>
         <cell align="left" valign="middle">ed448</cell>
-	<cell align="left" valign="middle"><em>NC</em></cell>
+	<cell align="left" valign="middle"><em>24</em></cell>
 	<cell align="left" valign="middle"></cell>
       </row>
       <row>
@@ -865,13 +865,13 @@
       <row>
         <cell align="left" valign="middle"></cell>
         <cell align="left" valign="middle">ed25519</cell>
-	<cell align="left" valign="middle"><em>NC</em></cell>
+	<cell align="left" valign="middle"><em>24</em></cell>
 	<cell align="left" valign="middle"></cell>
       </row>
       <row>
         <cell align="left" valign="middle"></cell>
         <cell align="left" valign="middle">ed448</cell>
-	<cell align="left" valign="middle"><em>NC</em></cell>
+	<cell align="left" valign="middle"><em>24</em></cell>
 	<cell align="left" valign="middle"></cell>
       </row>
       <row>
diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl
index d15345ac57..92c5af68c5 100644
--- a/lib/ssl/src/ssl.erl
+++ b/lib/ssl/src/ssl.erl
@@ -188,11 +188,10 @@
 
 -type legacy_hash()             :: md5.
 
--type sign_algo()               :: rsa | dsa | ecdsa. % exported
+-type sign_algo()               :: rsa | dsa | ecdsa | eddsa. % exported
 
--type sign_scheme()             :: rsa_pkcs1_sha256 
-                                 | rsa_pkcs1_sha384
-                                 | rsa_pkcs1_sha512
+-type sign_scheme()             :: eddsa_ed25519
+                                 | eddsa_ed448
                                  | ecdsa_secp256r1_sha256
                                  | ecdsa_secp384r1_sha384
                                  | ecdsa_secp521r1_sha512
@@ -202,6 +201,9 @@
                                  | rsa_pss_pss_sha256
                                  | rsa_pss_pss_sha384
                                  | rsa_pss_pss_sha512
+                                 | rsa_pkcs1_sha256
+                                 | rsa_pkcs1_sha384
+                                 | rsa_pkcs1_sha512
                                  | rsa_pkcs1_sha1
                                  | ecdsa_sha1. % exported
 
diff --git a/lib/ssl/src/ssl_certificate.erl b/lib/ssl/src/ssl_certificate.erl
index 0b4211e1c3..8181c321eb 100644
--- a/lib/ssl/src/ssl_certificate.erl
+++ b/lib/ssl/src/ssl_certificate.erl
@@ -334,6 +334,12 @@ public_key(#'OTPSubjectPublicKeyInfo'{algorithm = #'PublicKeyAlgorithm'{algorith
 									parameters = Params},
 				      subjectPublicKey = Point}) ->
     {Point, Params};
+public_key(#'OTPSubjectPublicKeyInfo'{algorithm = #'PublicKeyAlgorithm'{algorithm = ?'id-Ed25519'},
+				      subjectPublicKey = Point}) ->
+    {Point, {namedCurve, ?'id-Ed25519'}};
+public_key(#'OTPSubjectPublicKeyInfo'{algorithm = #'PublicKeyAlgorithm'{algorithm = ?'id-Ed448'},
+				      subjectPublicKey = Point}) ->
+    {Point, {namedCurve, ?'id-Ed448'}};
 public_key(#'OTPSubjectPublicKeyInfo'{algorithm = #'PublicKeyAlgorithm'{algorithm = ?'rsaEncryption'}, 
 				      subjectPublicKey = Key}) ->
     Key;
diff --git a/lib/ssl/src/ssl_cipher.erl b/lib/ssl/src/ssl_cipher.erl
index 85042e8612..8e08fb2a4e 100644
--- a/lib/ssl/src/ssl_cipher.erl
+++ b/lib/ssl/src/ssl_cipher.erl
@@ -941,8 +941,8 @@ signature_scheme(ecdsa_secp521r1_sha512) -> ?ECDSA_SECP521R1_SHA512;
 signature_scheme(rsa_pss_rsae_sha256) -> ?RSA_PSS_RSAE_SHA256;
 signature_scheme(rsa_pss_rsae_sha384) -> ?RSA_PSS_RSAE_SHA384;
 signature_scheme(rsa_pss_rsae_sha512) -> ?RSA_PSS_RSAE_SHA512;
-signature_scheme(ed25519) -> ?ED25519;
-signature_scheme(ed448) -> ?ED448;
+signature_scheme(eddsa_ed25519) -> ?ED25519;
+signature_scheme(eddsa_ed448) -> ?ED448;
 signature_scheme(rsa_pss_pss_sha256) -> ?RSA_PSS_PSS_SHA256;
 signature_scheme(rsa_pss_pss_sha384) -> ?RSA_PSS_PSS_SHA384;
 signature_scheme(rsa_pss_pss_sha512) -> ?RSA_PSS_PSS_SHA512;
@@ -963,8 +963,8 @@ signature_scheme(?ECDSA_SECP521R1_SHA512) -> ecdsa_secp521r1_sha512;
 signature_scheme(?RSA_PSS_RSAE_SHA256) -> rsa_pss_rsae_sha256;
 signature_scheme(?RSA_PSS_RSAE_SHA384) -> rsa_pss_rsae_sha384;
 signature_scheme(?RSA_PSS_RSAE_SHA512) -> rsa_pss_rsae_sha512;
-signature_scheme(?ED25519) -> ed25519;
-signature_scheme(?ED448) -> ed448;
+signature_scheme(?ED25519) -> eddsa_ed25519;
+signature_scheme(?ED448) -> eddsa_ed448;
 signature_scheme(?RSA_PSS_PSS_SHA256) -> rsa_pss_pss_sha256;
 signature_scheme(?RSA_PSS_PSS_SHA384) -> rsa_pss_pss_sha384;
 signature_scheme(?RSA_PSS_PSS_SHA512) -> rsa_pss_pss_sha512;
@@ -987,8 +987,8 @@ scheme_to_components(ecdsa_secp521r1_sha512) -> {sha512, ecdsa, secp521r1};
 scheme_to_components(rsa_pss_rsae_sha256) -> {sha256, rsa_pss_rsae, undefined};
 scheme_to_components(rsa_pss_rsae_sha384) -> {sha384, rsa_pss_rsae, undefined};
 scheme_to_components(rsa_pss_rsae_sha512) -> {sha512, rsa_pss_rsae, undefined};
-scheme_to_components(ed25519) -> {undefined, undefined, undefined};
-scheme_to_components(ed448) -> {undefined, undefined, undefined};
+scheme_to_components(eddsa_ed25519) -> {none, eddsa, ed25519};
+scheme_to_components(eddsa_ed448) -> {none, eddsa, ed448};
 scheme_to_components(rsa_pss_pss_sha256) -> {sha256, rsa_pss_pss, undefined};
 scheme_to_components(rsa_pss_pss_sha384) -> {sha384, rsa_pss_pss, undefined};
 scheme_to_components(rsa_pss_pss_sha512) -> {sha512, rsa_pss_pss, undefined};
diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl
index aac4c28a5f..6bc18291a0 100644
--- a/lib/ssl/src/ssl_handshake.erl
+++ b/lib/ssl/src/ssl_handshake.erl
@@ -417,6 +417,10 @@ verify_signature({3, Minor}, Hash, _HashAlgo, Signature, {?rsaEncryption, PubKey
     end;
 verify_signature({3, 4}, Hash, {HashAlgo, _SignAlgo}, Signature, {?'id-ecPublicKey', PubKey, PubKeyParams}) ->
     public_key:verify(Hash, HashAlgo, Signature, {PubKey, PubKeyParams});
+verify_signature({3, 4}, Msg, {_, eddsa}, Signature, {?'id-Ed25519', PubKey, PubKeyParams}) ->
+    public_key:verify(Msg, none, Signature, {PubKey, PubKeyParams});
+verify_signature({3, 4}, Msg, {_, eddsa}, Signature, {?'id-Ed448', PubKey, PubKeyParams}) ->
+    public_key:verify(Msg, none, Signature, {PubKey, PubKeyParams});
 verify_signature(_, Hash, {HashAlgo, _SignAlg}, Signature,
 		 {?'id-ecPublicKey', PublicKey, PublicKeyParams}) ->
     public_key:verify({digest, Hash}, HashAlgo, Signature, {PublicKey, PublicKeyParams});
diff --git a/lib/ssl/src/tls_handshake_1_3.erl b/lib/ssl/src/tls_handshake_1_3.erl
index cd9beecb3f..9840d15982 100644
--- a/lib/ssl/src/tls_handshake_1_3.erl
+++ b/lib/ssl/src/tls_handshake_1_3.erl
@@ -2337,7 +2337,9 @@ select_sign_algo(PublicKeyAlgo, RSAKeySize, [PeerSignAlg|PeerSignAlgs], OwnSignA
     %% it MUST use the RSASSA-PSS OID.
     case ((PublicKeyAlgo =:= rsa andalso S =:= rsa_pss_rsae)
           orelse (PublicKeyAlgo =:= rsa_pss_pss andalso S =:= rsa_pss_pss)
-          orelse (PublicKeyAlgo =:= ecdsa andalso S =:= ecdsa))
+          orelse (PublicKeyAlgo =:= ecdsa andalso S =:= ecdsa)
+          orelse (PublicKeyAlgo =:= eddsa andalso S =:= eddsa)
+         )
         andalso
         lists:member(PeerSignAlg, OwnSignAlgs) of
         true ->
@@ -2431,6 +2433,10 @@ public_key_algo(?rsaEncryption) ->
     rsa;
 public_key_algo(?'id-ecPublicKey') ->
     ecdsa;
+public_key_algo(?'id-Ed25519') ->
+    eddsa;
+public_key_algo(?'id-Ed448') ->
+    eddsa;
 public_key_algo(?'id-dsa') ->
     dsa.
 
diff --git a/lib/ssl/src/tls_v1.erl b/lib/ssl/src/tls_v1.erl
index 59c425ecbe..1253a960c2 100644
--- a/lib/ssl/src/tls_v1.erl
+++ b/lib/ssl/src/tls_v1.erl
@@ -657,10 +657,14 @@ signature_schemes(Version, SignatureSchemes) when is_tuple(Version)
                              H -> H
                          end,
                   case proplists:get_bool(Sign, PubKeys)
-                      andalso proplists:get_bool(Hash, Hashes)
-                      andalso (Curve =:= undefined orelse
-                               proplists:get_bool(Curve, Curves))
-                      andalso is_pair(Hash, Sign, Hashes)
+                      andalso
+                      (proplists:get_bool(Hash, Hashes)
+                       andalso (Curve =:= undefined orelse
+                                proplists:get_bool(Curve, Curves))
+                       andalso is_pair(Hash, Sign, Hashes)) orelse
+                      ((Sign == eddsa) andalso ((Curve == ed448)
+                                                orelse
+                                                (Curve == ed25519)))
                   of
                       true ->
                           [Scheme | Acc];
@@ -705,8 +709,8 @@ default_signature_schemes(Version) ->
                rsa_pss_rsae_sha512,
                rsa_pss_rsae_sha384,
                rsa_pss_rsae_sha256,
-               %% ed25519,
-               %% ed448,
+               eddsa_ed25519,
+               eddsa_ed448,
 
                %% These values refer solely to signatures
                %% which appear in certificates (see Section 4.4.2.2) and are not
@@ -825,7 +829,9 @@ is_pair(Hash, ecdsa, Hashs) ->
     lists:member(Hash, AtLeastSha);
 is_pair(Hash, rsa, Hashs) ->
     AtLeastMd5 = Hashs -- [md2,md4],
-    lists:member(Hash, AtLeastMd5).
+    lists:member(Hash, AtLeastMd5);
+is_pair(_,_,_) ->
+    false.
 
 %% list ECC curves in preferred order
 -spec ecc_curves(1..3 | all) -> [named_curve()].
diff --git a/lib/ssl/test/openssl_client_cert_SUITE.erl b/lib/ssl/test/openssl_client_cert_SUITE.erl
index 0248956056..ad00f2da1f 100644
--- a/lib/ssl/test/openssl_client_cert_SUITE.erl
+++ b/lib/ssl/test/openssl_client_cert_SUITE.erl
@@ -94,7 +94,8 @@ groups() ->
                                                               unsupported_sign_algo_cert_client_auth]},
      {rsa_pss_rsae, [], all_version_tests() ++ tls_1_3_tests()},
      {rsa_pss_pss, [], all_version_tests() ++ tls_1_3_tests()},
-     {ecdsa_1_3, [], all_version_tests() ++ tls_1_3_tests()}
+     {ecdsa_1_3, [], all_version_tests() ++ tls_1_3_tests()},
+     {eddsa_1_3, [], all_version_tests() ++ tls_1_3_tests()}
     ].
 
 protocol_groups() ->
@@ -114,10 +115,6 @@ protocol_groups() ->
             ]
      end. 
 
-ssl_protocol_groups() ->
-    [{group, rsa},
-     {group, dsa}].
-
 pre_tls_1_3_protocol_groups() ->
     [{group, rsa},
      {group, ecdsa},
@@ -127,7 +124,9 @@ tls_1_3_protocol_groups() ->
     [{group, rsa_1_3},
      {group, rsa_pss_rsae},
      {group, rsa_pss_pss},
-     {group, ecdsa_1_3}].
+     {group, ecdsa_1_3},
+     {group, eddsa_1_3}
+    ].
 
 tls_1_3_tests() ->
     [
@@ -149,7 +148,6 @@ all_version_tests() ->
      client_auth_do_not_allow_partial_chain,
      client_auth_partial_chain_fun_fail,
      missing_root_cert_no_auth
-     %%invalid_signature_client
     ].
 
 init_per_suite(Config) ->
@@ -257,6 +255,35 @@ init_per_group(Group, Config0) when Group == ecdsa;
         false ->
             {skip, "Missing EC crypto support"}
     end;
+init_per_group(eddsa_1_3, Config0) ->
+    PKAlg = crypto:supports(public_keys),
+    PrivDir = proplists:get_value(priv_dir, Config0),
+    case lists:member(eddsa, PKAlg) andalso
+        (lists:member(ecdh, PKAlg) andalso
+         lists:member(ecdsa, PKAlg)) of
+        true ->
+            Conf = public_key:pkix_test_data(#{server_chain => #{root => ssl_test_lib:eddsa_conf(),
+                                                                 intermediates => [ssl_test_lib:eddsa_conf()],
+                                                                 peer =>  ssl_test_lib:eddsa_conf()},
+                                               %% OpenSSL does currently not support EDDSA private key files
+                                               client_chain => #{root => ssl_test_lib:ecdsa_conf(),
+                                                                 intermediates => [ssl_test_lib:ecdsa_conf()],
+                                                                 peer =>  ssl_test_lib:ecdsa_conf()}}),
+            [{server_config, SOpts},
+             {client_config, COpts}] = x509_test:gen_pem_config_files(Conf, filename:join(PrivDir,
+                                                                                          "client_ecdsa_missing_eddsa"),
+                                                                      filename:join(PrivDir, "server_eddsa")),
+
+            [{cert_key_alg, eddsa} |
+             lists:delete(cert_key_alg,
+                          [{client_cert_opts, COpts},
+                           {server_cert_opts, SOpts} |
+                           lists:delete(server_cert_opts,
+                                        lists:delete(client_cert_opts, Config0))]
+                         )];
+        false ->
+            {skip, "Missing EC crypto support"}
+    end;
 init_per_group(Group, Config0) when Group == dsa ->
     PKAlg = crypto:supports(public_keys),
     case lists:member(dss, PKAlg) andalso lists:member(dh, PKAlg) 
@@ -371,17 +398,6 @@ missing_root_cert_no_auth() ->
 missing_root_cert_no_auth(Config) when is_list(Config) ->
     ssl_cert_tests:missing_root_cert_no_auth(Config).
 
-%%--------------------------------------------------------------------
-invalid_signature_client() ->
-    ssl_cert_tests:invalid_signature_client().
-invalid_signature_client(Config) when is_list(Config) ->
-    ssl_cert_tests:invalid_signature_client(Config).
-%%--------------------------------------------------------------------
-invalid_signature_server() ->
-    ssl_cert_tests:invalid_signature_client().
-invalid_signature_server(Config) when is_list(Config) ->
-    ssl_cert_tests:invalid_signature_client(Config).
-
 %%--------------------------------------------------------------------
 %% TLS 1.3 Test Cases ------------------------------------------------
 %%--------------------------------------------------------------------
diff --git a/lib/ssl/test/openssl_server_cert_SUITE.erl b/lib/ssl/test/openssl_server_cert_SUITE.erl
index e71bfc8e5c..4766fec34c 100644
--- a/lib/ssl/test/openssl_server_cert_SUITE.erl
+++ b/lib/ssl/test/openssl_server_cert_SUITE.erl
@@ -97,6 +97,9 @@ groups() ->
      {rsa_pss_rsae, [], all_version_tests() ++ tls_1_3_tests()},
      {rsa_pss_pss, [], all_version_tests() ++ tls_1_3_tests()},
      {ecdsa_1_3, [], all_version_tests() ++ tls_1_3_tests()}
+     %% Enable test later when we have OpenSSL version that
+     %% is able to read EDDSA private key files
+     %%{eddsa_1_3, [], all_version_tests() ++ tls_1_3_tests()}
     ].
 
 protocol_groups() ->
@@ -116,10 +119,6 @@ protocol_groups() ->
             ]
     end. 
 
-ssl_protocol_groups() ->
-    [{group, rsa},
-     {group, dsa}].
-
 pre_tls_1_3_protocol_groups() ->
     [{group, rsa},
      {group, ecdsa},
@@ -129,7 +128,9 @@ tls_1_3_protocol_groups() ->
     [{group, rsa_1_3},
      {group, rsa_pss_rsae},
      {group, rsa_pss_pss},
-     {group, ecdsa_1_3}].
+     {group, ecdsa_1_3}
+     %%{group, eddsa_1_3}
+    ].
 
 tls_1_3_tests() ->
     [
@@ -145,7 +146,6 @@ all_version_tests() ->
      no_auth,
      auth,
      missing_root_cert_no_auth
-     %%invalid_signature_client
     ].
 
 init_per_suite(Config) ->
@@ -292,7 +292,33 @@ init_per_group(ecdsa_1_3 = Group, Config0) ->
         false ->
             {skip, "Missing EC crypto support"}
     end;
-init_per_group(Group, Config0) when Group == dsa ->
+
+init_per_group(eddsa_1_3, Config0) ->
+    PKAlg = crypto:supports(public_keys),
+    PrivDir = proplists:get_value(priv_dir, Config0),
+    case lists:member(eddsa, PKAlg) andalso (lists:member(ecdh, PKAlg)) of
+        true ->
+            Conf = public_key:pkix_test_data(#{server_chain => #{root => ssl_test_lib:eddsa_conf(),
+                                                                 intermediates => [ssl_test_lib:eddsa_conf()],
+                                                                 peer =>  ssl_test_lib:eddsa_conf()},
+                                               client_chain => #{root => ssl_test_lib:eddsa_conf(),
+                                                                 intermediates => [ssl_test_lib:eddsa_conf()],
+                                                                 peer =>  ssl_test_lib:eddsa_conf()}}),
+            [{server_config, SOpts},
+             {client_config, COpts}] = x509_test:gen_pem_config_files(Conf, filename:join(PrivDir, "client_eddsa"),
+                                                                      filename:join(PrivDir, "server_eddsa")),
+
+            [{cert_key_alg, eddsa} |
+             lists:delete(cert_key_alg,
+                          [{client_cert_opts, COpts},
+                           {server_cert_opts, SOpts} |
+                           lists:delete(server_cert_opts,
+                                        lists:delete(client_cert_opts, Config0))]
+                         )];
+        false ->
+            {skip, "Missing EC crypto support"}
+    end;
+init_per_group(dsa = Group, Config0) ->
     PKAlg = crypto:supports(public_keys),
     case lists:member(dss, PKAlg) andalso lists:member(dh, PKAlg)  andalso 
         (ssl_test_lib:openssl_dsa_suites() =/= [])  of
@@ -390,16 +416,6 @@ missing_root_cert_no_auth() ->
 missing_root_cert_no_auth(Config) when is_list(Config) ->
     ssl_cert_tests:missing_root_cert_no_auth(Config).
 
-%%--------------------------------------------------------------------
-invalid_signature_client() ->
-    ssl_cert_tests:invalid_signature_client().
-invalid_signature_client(Config) when is_list(Config) ->
-    ssl_cert_tests:invalid_signature_client(Config).
-%%--------------------------------------------------------------------
-invalid_signature_server() ->
-    ssl_cert_tests:invalid_signature_client().
-invalid_signature_server(Config) when is_list(Config) ->
-    ssl_cert_tests:invalid_signature_client(Config).
 
 %%--------------------------------------------------------------------
 %% TLS 1.3 Test Cases ------------------------------------------------
diff --git a/lib/ssl/test/ssl_cert_SUITE.erl b/lib/ssl/test/ssl_cert_SUITE.erl
index a142115b55..562d12a7ab 100644
--- a/lib/ssl/test/ssl_cert_SUITE.erl
+++ b/lib/ssl/test/ssl_cert_SUITE.erl
@@ -147,7 +147,8 @@ groups() ->
      {ecdsa_1_3, [], all_version_tests() ++ tls_1_3_tests() ++
           [signature_algorithms_bad_curve_secp256r1,
            signature_algorithms_bad_curve_secp384r1,
-           signature_algorithms_bad_curve_secp521r1]}
+           signature_algorithms_bad_curve_secp521r1]},
+     {eddsa_1_3, [], all_version_tests() ++ tls_1_3_tests()}
     ].
 
 ssl_protocol_groups() ->
@@ -165,6 +166,7 @@ tls_1_2_protocol_groups() ->
 tls_1_3_protocol_groups() ->
     [{group, rsa_1_3},
      {group, ecdsa_1_3},
+     {group, eddsa_1_3},
      {group, rsa_pss_rsae_1_3},
      {group, rsa_pss_pss_1_3}
     ].
@@ -229,7 +231,6 @@ init_per_suite(Config) ->
     catch crypto:stop(),
     try crypto:start() of
 	ok ->
-	    ssl_test_lib:clean_start(),
             Config
     catch _:_ ->
 	    {skip, "Crypto did not start"}
@@ -244,6 +245,7 @@ end_per_suite(_Config) ->
 init_per_group(GroupName, Config) ->
     case ssl_test_lib:is_protocol_version(GroupName) of
         true  ->
+            ssl_test_lib:clean_start(),
             ssl_test_lib:init_per_group(GroupName, 
                                         [{client_type, erlang},
                                          {server_type, erlang},
@@ -289,7 +291,7 @@ do_init_per_group(Alg, Config) when Alg == rsa_pss_rsae;
             {skip, "Missing EC crypto support"}
     end;
 do_init_per_group(Group, Config0) when Group == ecdsa;
-                                    Group == ecdsa_1_3 ->
+                                       Group == ecdsa_1_3 ->
 
     PKAlg = crypto:supports(public_keys),
     case lists:member(ecdsa, PKAlg) andalso (lists:member(ecdh, PKAlg) orelse lists:member(dh, PKAlg)) of
@@ -307,12 +309,36 @@ do_init_per_group(Group, Config0) when Group == ecdsa;
         false ->
             {skip, "Missing EC crypto support"}
     end;
-
-do_init_per_group(Group, Config0) when Group == dsa ->
+do_init_per_group(eddsa_1_3, Config0) ->
+    PKAlg = crypto:supports(public_keys),
+    PrivDir = proplists:get_value(priv_dir, Config0),
+    case lists:member(eddsa, PKAlg) andalso (lists:member(ecdh, PKAlg)) of
+        true ->
+            Conf = public_key:pkix_test_data(#{server_chain => #{root => ssl_test_lib:eddsa_conf(),
+                                                                 intermediates => [ssl_test_lib:eddsa_conf()],
+                                                                 peer =>  ssl_test_lib:eddsa_conf()},
+                                               client_chain => #{root => ssl_test_lib:eddsa_conf(),
+                                                                 intermediates => [ssl_test_lib:eddsa_conf()],
+                                                                 peer =>  ssl_test_lib:eddsa_conf()}}),
+            [{server_config, SOpts},
+             {client_config, COpts}] = x509_test:gen_pem_config_files(Conf, filename:join(PrivDir, "client_eddsa"),
+                                                                      filename:join(PrivDir, "server_eddsa")),
+
+            [{cert_key_alg, eddsa} |
+             lists:delete(cert_key_alg,
+                          [{client_cert_opts, COpts},
+                           {server_cert_opts, SOpts} |
+                           lists:delete(server_cert_opts,
+                                        lists:delete(client_cert_opts, Config0))]
+                         )];
+        false ->
+            {skip, "Missing EC crypto support"}
+    end;
+do_init_per_group(dsa, Config0) ->
     PKAlg = crypto:supports(public_keys),
     case lists:member(dss, PKAlg) andalso lists:member(dh, PKAlg) of
         true ->
-            Config = ssl_test_lib:make_dsa_cert(Config0),    
+            Config = ssl_test_lib:make_dsa_cert(Config0),
             COpts = proplists:get_value(client_dsa_opts, Config),
             SOpts = proplists:get_value(server_dsa_opts, Config),
             [{cert_key_alg, dsa} |
@@ -324,7 +350,7 @@ do_init_per_group(Group, Config0) when Group == dsa ->
         false ->
             {skip, "Missing DSS crypto support"}
     end;
-do_init_per_group(Group, Config) ->
+do_init_per_group(_Group, Config) ->
     Config.
 
 end_per_group(GroupName, Config) ->
@@ -491,7 +517,9 @@ missing_root_cert_auth_user_verify_fun_reject(Config) ->
 incomplete_chain_auth() ->
     [{doc,"Test that we can verify an incompleat chain when we have the certs to rebuild it"}].
 incomplete_chain_auth(Config) when is_list(Config) ->
-    DefaultCertConf = ssl_test_lib:default_cert_chain_conf(),
+    Prop = proplists:get_value(tc_group_properties, Config),
+    Group = proplists:get_value(name, Prop),
+    DefaultCertConf = ssl_test_lib:default_ecc_cert_chain_conf(Group),
     #{client_config := ClientOpts0,
       server_config := ServerOpts0} = ssl_test_lib:make_cert_chains_der(proplists:get_value(cert_key_alg, Config),
                                                                         [{server_chain, DefaultCertConf},
@@ -608,7 +636,8 @@ critical_extension_auth() ->
     [{doc,"Test cert that has a critical unknown extension in verify_peer mode"}].
 
 critical_extension_auth(Config) when is_list(Config) ->
-    DefaultCertConf = ssl_test_lib:default_cert_chain_conf(),
+    Prop = proplists:get_value(tc_group_properties, Config),
+    DefaultCertConf = ssl_test_lib:default_ecc_cert_chain_conf(proplists:get_value(name, Prop)),
     Ext = x509_test:extensions([{{2,16,840,1,113730,1,1}, <<3,2,6,192>>, true}]),
     #{client_config := ClientOpts0,
       server_config := ServerOpts0}  = ssl_test_lib:make_cert_chains_der(proplists:get_value(cert_key_alg, Config),
@@ -674,7 +703,8 @@ critical_extension_no_auth() ->
     [{doc,"Test cert that has a critical unknown extension in verify_none mode"}].
 
 critical_extension_no_auth(Config) when is_list(Config) ->
-    DefaultCertConf = ssl_test_lib:default_cert_chain_conf(),
+    Prop = proplists:get_value(tc_group_properties, Config),
+    DefaultCertConf = ssl_test_lib:default_ecc_cert_chain_conf(proplists:get_value(name, Prop)),
     Ext = x509_test:extensions([{{2,16,840,1,113730,1,1}, <<3,2,6,192>>, true}]),
     #{client_config := ClientOpts0,
       server_config := ServerOpts0}  = ssl_test_lib:make_cert_chains_der(proplists:get_value(cert_key_alg, Config),
@@ -692,7 +722,8 @@ extended_key_usage_auth() ->
     [{doc,"Test cert that has a critical extended_key_usage extension in server cert"}].
 
 extended_key_usage_auth(Config) when is_list(Config) -> 
-    DefaultCertConf = ssl_test_lib:default_cert_chain_conf(),
+    Prop = proplists:get_value(tc_group_properties, Config),
+    DefaultCertConf = ssl_test_lib:default_ecc_cert_chain_conf(proplists:get_value(name, Prop)),
     Ext = x509_test:extensions([{?'id-ce-extKeyUsage',
                                  [?'id-kp-serverAuth'], true}]),
     #{client_config := ClientOpts0,
@@ -762,7 +793,8 @@ cert_expired() ->
     [{doc,"Test server with expired certificate"}].
 
 cert_expired(Config) when is_list(Config) ->
-    DefaultCertConf = ssl_test_lib:default_cert_chain_conf(),
+    Prop = proplists:get_value(tc_group_properties, Config),
+    DefaultCertConf = ssl_test_lib:default_ecc_cert_chain_conf(proplists:get_value(name, Prop)),
     {Year, Month, Day} = date(),
     #{client_config := ClientOpts0,
       server_config := ServerOpts0} = ssl_test_lib:make_cert_chains_der(proplists:get_value(cert_key_alg, Config),
diff --git a/lib/ssl/test/ssl_test_lib.erl b/lib/ssl/test/ssl_test_lib.erl
index ea2ad41c7a..978106aef3 100644
--- a/lib/ssl/test/ssl_test_lib.erl
+++ b/lib/ssl/test/ssl_test_lib.erl
@@ -178,7 +178,10 @@
          pem_to_der/1,
          appropriate_sha/1,
          format_certs/1,
-         format_cert/1
+         format_cert/1,
+         ecdsa_conf/0,
+         eddsa_conf/0,
+         default_ecc_cert_chain_conf/1
         ]).
 
 -export([maybe_force_ipv4/1,
@@ -374,6 +377,18 @@ openssl_support_rsa_kex() ->
             true
     end.
 
+ecdsa_conf() ->
+    [{key, {namedCurve, ?DEFAULT_CURVE}},
+     {digest, appropriate_sha(crypto:supports())}].
+
+eddsa_conf() ->
+    [{key, {namedCurve, ed25519}}].
+
+default_ecc_cert_chain_conf(eddsa_1_3) ->
+    lists:map(fun(L) -> [{key, {namedCurve, ed25519}} | L] end, default_cert_chain_conf());
+default_ecc_cert_chain_conf(_) ->
+    default_cert_chain_conf().
+
 %%====================================================================
 %% Internal functions
 %%====================================================================
@@ -1385,7 +1400,7 @@ make_dsa_cert(Config) ->
 make_cert_chains_der(Alg, UserConf) ->
     ClientChain = proplists:get_value(client_chain, UserConf, default_cert_chain_conf()),
     ServerChain = proplists:get_value(server_chain, UserConf, default_cert_chain_conf()),
-    CertChainConf = gen_conf(Alg, Alg, ClientChain, ServerChain),
+    CertChainConf = gen_conf(Alg, Alg, ClientChain, ServerChain, curve_default(Alg)),
     public_key:pkix_test_data(CertChainConf).
 
 make_cert_chains_pem(Alg, UserConf, Config, Suffix) ->
@@ -1555,6 +1570,12 @@ chain_spec(_Role, ecdsa, Curve) ->
     [[Digest, {key, {namedCurve, CurveOid}}],
      [Digest, {key, {namedCurve, CurveOid}}],
      [Digest, {key, {namedCurve, CurveOid}}]];
+chain_spec(_Role, eddsa, Curve) ->
+    Digest = {digest, appropriate_sha(crypto:supports())},
+    CurveOid = pubkey_cert_records:namedCurves(Curve),
+    [[Digest, {key, {namedCurve, CurveOid}}],
+     [Digest, {key, {namedCurve, CurveOid}}],
+     [Digest, {key, {namedCurve, CurveOid}}]];
 chain_spec(_Role, rsa, _) ->
     Digest = {digest, appropriate_sha(crypto:supports())},
     [[Digest, {key, hardcode_rsa_key(1)}],
@@ -3808,3 +3829,7 @@ verify_early_data(Atom) ->
             Other
     end.
 
+curve_default(eddsa) ->
+    ed25519;
+curve_default(_) ->
+    ?DEFAULT_CURVE.
-- 
2.26.2

openSUSE Build Service is sponsored by