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