summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIngela Andin <ingela@erlang.org>2021-08-30 15:00:53 +0200
committerGitHub <noreply@github.com>2021-08-30 15:00:53 +0200
commit175fb04cf23713ba5fc82a0873d9fe018c113bfe (patch)
treedb1da318564cb7f2fb1b2eb0d3b8903940fa9026
parenteec966bbd28a5ae200796ad7b96e2f6a6922bde0 (diff)
parent7f533c862951efc2072d2738362241f2411e1ebc (diff)
downloaderlang-175fb04cf23713ba5fc82a0873d9fe018c113bfe.tar.gz
Merge pull request #4983 from IngelaAndin/ingela/ssl/psk/GH-4978/OTP-17501
Ingela/ssl/psk/gh 4978/otp 17501
-rw-r--r--lib/ssl/doc/src/ssl.xml17
-rw-r--r--lib/ssl/src/dtls_v1.erl29
-rw-r--r--lib/ssl/src/ssl.erl27
-rw-r--r--lib/ssl/src/ssl_cipher.erl234
-rw-r--r--lib/ssl/src/tls_v1.erl251
-rw-r--r--lib/ssl/test/ssl_api_SUITE.erl8
-rw-r--r--lib/ssl/test/ssl_basic_SUITE.erl138
7 files changed, 411 insertions, 293 deletions
diff --git a/lib/ssl/doc/src/ssl.xml b/lib/ssl/doc/src/ssl.xml
index 2bda3c538c..bd676c0af5 100644
--- a/lib/ssl/doc/src/ssl.xml
+++ b/lib/ssl/doc/src/ssl.xml
@@ -388,8 +388,10 @@
<note><p>Note that TLS-1.3 and TLS-1.2 cipher suites are not overlapping
sets of cipher suites so to support both these versions cipher
- suites from both versions need to be included. If supporting
- TLS-1.3 versions prior to TLS-1.2 can not be supported. </p></note>
+ suites from both versions need to be included. Also if the supplied list does
+ not comply with the configured versions or cryptolib so that the list becomes empty,
+ this option will fallback on its appropriate default value for the configured versions.
+ </p></note>
<p>Non-default cipher suites including anonymous cipher suites (PRE TLS-1.3) are supported for
interop/testing purposes and may be used by adding them to your cipher suite list.
@@ -1485,19 +1487,20 @@ fun(srp, Username :: binary(), UserState :: term()) ->
<fsummary>Returns a list of cipher suites.</fsummary>
<desc><p>Lists all possible cipher suites corresponding to
<c>Description</c> that are available. The
- <c>exclusive</c> option will exclusively list cipher suites
- introduced in <c>Version</c> whereas the other options
+ <c>exclusive</c> and <c>exclusive_anonymous</c> option will exclusively list cipher suites
+ first supported in <c>Version</c> whereas the other options
are inclusive from the lowest possible version to
<c>Version</c>. The <c>all</c> options includes all suites
- except the anonymous.
+ except the anonymous and no anonymous suites are supported by default.
</p>
<note><p>TLS-1.3 has no overlapping cipher suites with previous
TLS versions, that is the result of
<c>cipher_suites(all, 'tlsv1.3').</c> contains a separate set of
suites that can be used with TLS-1.3 an other set that can be used
- if a lower version is negotiated. No anonymous suites are
- supported by TLS-1.3.</p>
+ if a lower version is negotiated. PRE TLS-1.3 so called <c>PSK</c> and <c>SRP</c> suites
+ need extra configuration to work see <seetype marker="#custom_user_lookup">user lookup function</seetype>.
+ No anonymous suites are supported by TLS-1.3.</p>
<p>Also note that the cipher suites returned
by this function are the cipher suites that the OTP ssl
diff --git a/lib/ssl/src/dtls_v1.erl b/lib/ssl/src/dtls_v1.erl
index a4ca4cc3b1..100dba2e4c 100644
--- a/lib/ssl/src/dtls_v1.erl
+++ b/lib/ssl/src/dtls_v1.erl
@@ -21,9 +21,17 @@
-include("ssl_cipher.hrl").
--export([suites/1, all_suites/1, anonymous_suites/1,hmac_hash/3, ecc_curves/1,
- corresponding_tls_version/1, corresponding_dtls_version/1,
- cookie_secret/0, cookie_timeout/0]).
+-export([suites/1,
+ all_suites/1,
+ anonymous_suites/1,
+ exclusive_suites/1,
+ exclusive_anonymous_suites/1,
+ hmac_hash/3,
+ ecc_curves/1,
+ corresponding_tls_version/1,
+ corresponding_dtls_version/1,
+ cookie_secret/0,
+ cookie_timeout/0]).
-define(COOKIE_BASE_TIMEOUT, 30000).
@@ -45,7 +53,20 @@ anonymous_suites(Version) ->
is_acceptable_cipher(ssl_cipher_format:suite_bin_to_map(Cipher))
end,
ssl_cipher:anonymous_suites(corresponding_tls_version(Version))).
-
+
+exclusive_suites(Minor) ->
+ lists:filter(fun(Cipher) ->
+ is_acceptable_cipher(ssl_cipher_format:suite_bin_to_map(Cipher))
+ end,
+ tls_v1:exclusive_suites(corresponding_minor_tls_version(Minor))).
+
+exclusive_anonymous_suites(Minor) ->
+ lists:filter(fun(Cipher) ->
+ is_acceptable_cipher(ssl_cipher_format:suite_bin_to_map(Cipher))
+ end,
+ tls_v1:exclusive_anonymous_suites(corresponding_minor_tls_version(Minor))).
+
+
hmac_hash(MacAlg, MacSecret, Value) ->
tls_v1:hmac_hash(MacAlg, MacSecret, Value).
diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl
index 17e6b7fcb2..b05943e53e 100644
--- a/lib/ssl/src/ssl.erl
+++ b/lib/ssl/src/ssl.erl
@@ -989,7 +989,7 @@ negotiated_protocol(#sslsocket{pid = [Pid|_]}) when is_pid(Pid) ->
%%--------------------------------------------------------------------
-spec cipher_suites(Description, Version) -> ciphers() when
- Description :: default | all | exclusive | anonymous,
+ Description :: default | all | exclusive | anonymous | exclusive_anonymous,
Version :: protocol_version().
%% Description: Returns all default and all supported cipher suites for a
@@ -1486,12 +1486,18 @@ str_to_suite(CipherSuiteName) ->
%%%--------------------------------------------------------------------
supported_suites(exclusive, {3,Minor}) ->
tls_v1:exclusive_suites(Minor);
+supported_suites(exclusive, {254, Minor}) ->
+ dtls_v1:exclusive_suites(Minor);
supported_suites(default, Version) ->
ssl_cipher:suites(Version);
supported_suites(all, Version) ->
ssl_cipher:all_suites(Version);
-supported_suites(anonymous, Version) ->
- ssl_cipher:anonymous_suites(Version).
+supported_suites(anonymous, Version) ->
+ ssl_cipher:anonymous_suites(Version);
+supported_suites(exclusive_anonymous, {3, Minor}) ->
+ tls_v1:exclusive_anonymous_suites(Minor);
+supported_suites(exclusive_anonymous, {254, Minor}) ->
+ dtls_v1:exclusive_anonymous_suites(Minor).
do_listen(Port, #config{transport_info = {Transport, _, _, _,_}} = Config, tls_gen_connection) ->
tls_socket:listen(Transport, Port, Config);
@@ -2582,9 +2588,8 @@ binary_cipher_suites(Versions, [Map|_] = Ciphers0) when is_map(Map) ->
binary_cipher_suites(Versions, [Tuple|_] = Ciphers0) when is_tuple(Tuple) ->
Ciphers = [ssl_cipher_format:suite_map_to_bin(tuple_to_map(C)) || C <- Ciphers0],
binary_cipher_suites(Versions, Ciphers);
-binary_cipher_suites([Version |_] = Versions, [Cipher0 | _] = Ciphers0) when is_binary(Cipher0) ->
- All = ssl_cipher:all_suites(Version) ++
- ssl_cipher:anonymous_suites(Version),
+binary_cipher_suites(Versions, [Cipher0 | _] = Ciphers0) when is_binary(Cipher0) ->
+ All = all_suites(Versions),
case [Cipher || Cipher <- Ciphers0, lists:member(Cipher, All)] of
[] ->
%% Defaults to all supported suites that does
@@ -2607,6 +2612,16 @@ default_binary_suites(exclusive, {_, Minor}) ->
default_binary_suites(default, Version) ->
ssl_cipher:filter_suites(ssl_cipher:suites(Version)).
+all_suites([{3, 4 = Minor}]) ->
+ tls_v1:exclusive_suites(Minor);
+all_suites([{3, 4} = Version0, Version1 |_]) ->
+ all_suites([Version0]) ++
+ ssl_cipher:all_suites(Version1) ++
+ ssl_cipher:anonymous_suites(Version1);
+all_suites([Version|_]) ->
+ ssl_cipher:all_suites(Version) ++
+ ssl_cipher:anonymous_suites(Version).
+
tuple_to_map({Kex, Cipher, Mac}) ->
#{key_exchange => Kex,
cipher => Cipher,
diff --git a/lib/ssl/src/ssl_cipher.erl b/lib/ssl/src/ssl_cipher.erl
index 93d077a0a4..35b2da773b 100644
--- a/lib/ssl/src/ssl_cipher.erl
+++ b/lib/ssl/src/ssl_cipher.erl
@@ -44,18 +44,11 @@
aead_encrypt/6,
aead_decrypt/6,
suites/1,
- all_suites/1,
+ all_suites/1,
crypto_support_filters/0,
- anonymous_suites/1,
- psk_suites/1,
- psk_suites_anon/1,
- srp_suites/1,
- srp_suites_anon/1,
- rc4_suites/1,
- des_suites/1,
- rsa_suites/1,
- filter/3,
- filter_suites/1,
+ anonymous_suites/1,
+ filter/3,
+ filter_suites/1,
filter_suites/2,
hash_algorithm/1,
sign_algorithm/1,
@@ -328,15 +321,20 @@ suites({3, Minor}) ->
tls_v1:suites(Minor);
suites({_, Minor}) ->
dtls_v1:suites(Minor).
-
+all_suites({3, 4} = Version) ->
+ suites(Version)
+ ++ tls_v1:psk_suites({3,3})
+ ++ tls_v1:srp_suites({3,3})
+ ++ tls_v1:rsa_suites({3,3})
+ ++ tls_v1:des_suites({3,3})
+ ++ tls_v1:rc4_suites({3,3});
all_suites({3, _} = Version) ->
suites(Version)
- ++ psk_suites(Version)
- ++ srp_suites(Version)
- ++ rsa_suites(Version)
- ++ des_suites(Version)
- ++ rc4_suites(Version);
-
+ ++ tls_v1:psk_suites(Version)
+ ++ tls_v1:srp_suites(Version)
+ ++ tls_v1:rsa_suites(Version)
+ ++ tls_v1:des_suites(Version)
+ ++ tls_v1:rc4_suites(Version);
all_suites(Version) ->
dtls_v1:all_suites(Version).
@@ -347,202 +345,20 @@ all_suites(Version) ->
%% Description: Returns a list of the anonymous cipher suites, only supported
%% if explicitly set by user. Intended only for testing.
%%--------------------------------------------------------------------
-anonymous_suites({3, N} = Version) ->
- srp_suites_anon(Version) ++ anonymous_suites(N);
+anonymous_suites({3, N}) ->
+ anonymous_suites(N);
anonymous_suites({254, _} = Version) ->
dtls_v1:anonymous_suites(Version);
-anonymous_suites(4) ->
- []; %% Raw public key negotiation may be used instead
-anonymous_suites( 3 = N) ->
- psk_suites_anon(N) ++
- [?TLS_DH_anon_WITH_AES_128_GCM_SHA256,
- ?TLS_DH_anon_WITH_AES_256_GCM_SHA384,
- ?TLS_DH_anon_WITH_AES_128_CBC_SHA256,
- ?TLS_DH_anon_WITH_AES_256_CBC_SHA256,
- ?TLS_ECDH_anon_WITH_AES_128_CBC_SHA,
- ?TLS_ECDH_anon_WITH_AES_256_CBC_SHA,
- ?TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA,
- ?TLS_DH_anon_WITH_RC4_128_MD5];
-anonymous_suites(2 = N) ->
- psk_suites_anon(N) ++
- [?TLS_ECDH_anon_WITH_AES_128_CBC_SHA,
- ?TLS_ECDH_anon_WITH_AES_256_CBC_SHA,
- ?TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA,
- ?TLS_DH_anon_WITH_DES_CBC_SHA,
- ?TLS_DH_anon_WITH_RC4_128_MD5];
-anonymous_suites(N) when N == 0;
- N == 1 ->
- psk_suites_anon(N) ++
- [?TLS_DH_anon_WITH_RC4_128_MD5,
- ?TLS_DH_anon_WITH_3DES_EDE_CBC_SHA,
- ?TLS_DH_anon_WITH_DES_CBC_SHA
- ].
-
-%%--------------------------------------------------------------------
--spec psk_suites(ssl_record:ssl_version() | integer()) -> [ssl_cipher_format:cipher_suite()].
-%%
-%% Description: Returns a list of the PSK cipher suites, only supported
-%% if explicitly set by user.
-%%--------------------------------------------------------------------
-psk_suites({3, N}) ->
- psk_suites(N);
-psk_suites(4) ->
- []; %% TODO Add new PSK, PSK_(EC)DHE suites
-psk_suites(3) ->
- [
- ?TLS_RSA_PSK_WITH_AES_256_GCM_SHA384,
- ?TLS_RSA_PSK_WITH_AES_256_CBC_SHA384,
- ?TLS_RSA_PSK_WITH_AES_128_GCM_SHA256,
- ?TLS_RSA_PSK_WITH_AES_128_CBC_SHA256
- ] ++ psk_suites(0);
-psk_suites(_) ->
- [?TLS_RSA_PSK_WITH_AES_256_CBC_SHA,
- ?TLS_RSA_PSK_WITH_AES_128_CBC_SHA,
- ?TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA,
- ?TLS_RSA_PSK_WITH_RC4_128_SHA].
-%%--------------------------------------------------------------------
--spec psk_suites_anon(ssl_record:ssl_version() | integer()) -> [ssl_cipher_format:cipher_suite()].
-%%
-%% Description: Returns a list of the anonymous PSK cipher suites, only supported
-%% if explicitly set by user.
-%%--------------------------------------------------------------------
-psk_suites_anon({3, N}) ->
- psk_suites_anon(N);
-psk_suites_anon(3 = N) ->
- [
- ?TLS_DHE_PSK_WITH_AES_256_GCM_SHA384,
- ?TLS_PSK_WITH_AES_256_GCM_SHA384,
- ?TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384,
- ?TLS_DHE_PSK_WITH_AES_256_CBC_SHA384,
- ?TLS_PSK_WITH_AES_256_CBC_SHA384,
- ?TLS_DHE_PSK_WITH_AES_256_CCM,
- ?TLS_PSK_DHE_WITH_AES_256_CCM_8,
- ?TLS_PSK_WITH_AES_256_CCM,
- ?TLS_PSK_WITH_AES_256_CCM_8,
- ?TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256,
- ?TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256,
- ?TLS_ECDHE_PSK_WITH_AES_128_CCM_8_SHA256,
- ?TLS_DHE_PSK_WITH_AES_128_GCM_SHA256,
- ?TLS_PSK_WITH_AES_128_GCM_SHA256,
- ?TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256,
- ?TLS_ECDHE_PSK_WITH_AES_128_CCM_8_SHA256,
- ?TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256,
- ?TLS_DHE_PSK_WITH_AES_128_CBC_SHA256,
- ?TLS_PSK_WITH_AES_128_CBC_SHA256,
- ?TLS_DHE_PSK_WITH_AES_128_CCM,
- ?TLS_PSK_DHE_WITH_AES_128_CCM_8,
- ?TLS_PSK_WITH_AES_128_CCM,
- ?TLS_PSK_WITH_AES_128_CCM_8,
- ?TLS_ECDHE_PSK_WITH_RC4_128_SHA
- ] ++ psk_suites_anon(N-1);
-psk_suites_anon(N) when N > 0 ->
- [?TLS_DHE_PSK_WITH_AES_256_CBC_SHA,
- ?TLS_PSK_WITH_AES_256_CBC_SHA,
- ?TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA,
- ?TLS_DHE_PSK_WITH_AES_128_CBC_SHA,
- ?TLS_PSK_WITH_AES_128_CBC_SHA,
- ?TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA,
- ?TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA,
- ?TLS_PSK_WITH_3DES_EDE_CBC_SHA,
- ?TLS_ECDHE_PSK_WITH_RC4_128_SHA,
- ?TLS_DHE_PSK_WITH_RC4_128_SHA,
- ?TLS_PSK_WITH_RC4_128_SHA];
-psk_suites_anon(0) ->
- [].
-%%--------------------------------------------------------------------
--spec srp_suites(tls_record:tls_version()) -> [ssl_cipher_format:cipher_suite()].
-%%
-%% Description: Returns a list of the SRP cipher suites, only supported
-%% if explicitly set by user.
-%%--------------------------------------------------------------------
-srp_suites(_) ->
- [?TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA,
- ?TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA,
- ?TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA,
- ?TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA,
- ?TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA,
- ?TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA].
-
-%%--------------------------------------------------------------------
--spec srp_suites_anon(tls_record:tls_version()) -> [ssl_cipher_format:cipher_suite()].
-%%
-%% Description: Returns a list of the SRP anonymous cipher suites, only supported
-%% if explicitly set by user.
-%%--------------------------------------------------------------------
-srp_suites_anon(_) ->
- [?TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA,
- ?TLS_SRP_SHA_WITH_AES_128_CBC_SHA,
- ?TLS_SRP_SHA_WITH_AES_256_CBC_SHA].
-
-%%--------------------------------------------------------------------
--spec rc4_suites(Version::ssl_record:ssl_version() | integer()) ->
- [ssl_cipher_format:cipher_suite()].
-%%
-%% Description: Returns a list of the RSA|(ECDH/RSA)| (ECDH/ECDSA)
-%% with RC4 cipher suites, only supported if explicitly set by user.
-%% Are not considered secure any more. Other RC4 suites already
-%% belonged to the user configured only category.
-%%--------------------------------------------------------------------
-rc4_suites({3, 0}) ->
- rc4_suites(0);
-rc4_suites({3, Minor}) ->
- rc4_suites(Minor) ++ rc4_suites(0);
-rc4_suites(0) ->
- [?TLS_RSA_WITH_RC4_128_SHA,
- ?TLS_RSA_WITH_RC4_128_MD5];
-rc4_suites(N) when N =< 4 ->
- [?TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
- ?TLS_ECDHE_RSA_WITH_RC4_128_SHA,
- ?TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
- ?TLS_ECDH_RSA_WITH_RC4_128_SHA].
-
-%%--------------------------------------------------------------------
--spec des_suites(Version::ssl_record:ssl_version()) -> [ssl_cipher_format:cipher_suite()].
-%%
-%% Description: Returns a list of the cipher suites
-%% with DES cipher, only supported if explicitly set by user.
-%% Are not considered secure any more.
-%%--------------------------------------------------------------------
-des_suites(_)->
- [?TLS_DHE_RSA_WITH_DES_CBC_SHA,
- ?TLS_RSA_WITH_DES_CBC_SHA,
- ?TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
- ?TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
- ?TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
- ?TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
- ?TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
- ?TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
- ].
-
-%%--------------------------------------------------------------------
--spec rsa_suites(Version::ssl_record:ssl_version() | integer()) -> [ssl_cipher_format:cipher_suite()].
-%%
-%% Description: Returns a list of the RSA key exchange
-%% cipher suites, only supported if explicitly set by user.
-%% Are not considered secure any more.
-%%--------------------------------------------------------------------
-rsa_suites({3, 0}) ->
- rsa_suites(0);
-rsa_suites({3, Minor}) ->
- rsa_suites(Minor) ++ rsa_suites(0);
-rsa_suites(0) ->
- [?TLS_RSA_WITH_AES_256_CBC_SHA,
- ?TLS_RSA_WITH_AES_128_CBC_SHA,
- ?TLS_RSA_WITH_3DES_EDE_CBC_SHA
- ];
-rsa_suites(N) when N >= 3 ->
- [
- ?TLS_RSA_WITH_AES_256_GCM_SHA384,
- ?TLS_RSA_WITH_AES_256_CBC_SHA256,
- ?TLS_RSA_WITH_AES_128_GCM_SHA256,
- ?TLS_RSA_WITH_AES_128_CBC_SHA256
- ];
-rsa_suites(_) ->
- [].
+anonymous_suites(1 = N) ->
+ tls_v1:exclusive_anonymous_suites(N);
+anonymous_suites(4 = N) ->
+ tls_v1:exclusive_anonymous_suites(N);
+anonymous_suites(N) when N > 1->
+ tls_v1:exclusive_anonymous_suites(N) ++ anonymous_suites(N-1).
%%--------------------------------------------------------------------
--spec filter(undefined | binary(), [ssl_cipher_format:cipher_suite()],
+-spec filter(undefined | binary(), [ssl_cipher_format:cipher_suite()],
ssl_record:ssl_version()) -> [ssl_cipher_format:cipher_suite()].
%%
%% Description: Select the cipher suites that can be used together with the
diff --git a/lib/ssl/src/tls_v1.erl b/lib/ssl/src/tls_v1.erl
index 85fe7e5512..fdceef2977 100644
--- a/lib/ssl/src/tls_v1.erl
+++ b/lib/ssl/src/tls_v1.erl
@@ -37,6 +37,15 @@
setup_keys/8,
suites/1,
exclusive_suites/1,
+ exclusive_anonymous_suites/1,
+ psk_suites/1,
+ psk_exclusive/1,
+ psk_suites_anon/1,
+ srp_suites/1,
+ srp_suites_anon/1,
+ rc4_suites/1,
+ des_suites/1,
+ rsa_suites/1,
prf/5,
ecc_curves/1,
ecc_curves/2,
@@ -497,7 +506,7 @@ mac_hash(Method, Mac_write_secret, Seq_num, Type, {Major, Minor},
-spec suites(1|2|3|4) -> [ssl_cipher_format:cipher_suite()].
suites(Minor) when Minor == 1; Minor == 2 ->
- exclusive_suites(2);
+ exclusive_suites(1);
suites(3) ->
exclusive_suites(3) ++ suites(2);
@@ -507,7 +516,9 @@ suites(4) ->
exclusive_suites(4) ->
[?TLS_AES_256_GCM_SHA384,
?TLS_AES_128_GCM_SHA256,
+
?TLS_CHACHA20_POLY1305_SHA256,
+
?TLS_AES_128_CCM_SHA256,
?TLS_AES_128_CCM_8_SHA256
];
@@ -565,21 +576,245 @@ exclusive_suites(3) ->
%% ?TLS_DH_RSA_WITH_AES_128_GCM_SHA256,
%% ?TLS_DH_DSS_WITH_AES_128_GCM_SHA256
];
-exclusive_suites(Minor) when Minor == 1; Minor == 2 ->
+exclusive_suites(2) ->
+ [];
+exclusive_suites(1) ->
[
?TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
?TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
- ?TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
- ?TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
+
?TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
?TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
-
+
?TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
?TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
- ?TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
- ?TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
+
?TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
- ?TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
+ ?TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
+
+ ?TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
+ ?TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
+ ?TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
+ ?TLS_DHE_DSS_WITH_AES_128_CBC_SHA
+ ].
+
+%%--------------------------------------------------------------------
+-spec exclusive_anonymous_suites(Minor:: integer()) -> [ssl_cipher_format:cipher_suite()].
+%%
+%% Description: Returns a list of the anonymous cipher suites introduced
+%% in Version, only supported if explicitly set by user.
+%%--------------------------------------------------------------------
+exclusive_anonymous_suites(4) ->
+ [];
+exclusive_anonymous_suites(3 = N) ->
+ psk_anon_exclusive(N) ++
+ [?TLS_DH_anon_WITH_AES_128_GCM_SHA256,
+ ?TLS_DH_anon_WITH_AES_256_GCM_SHA384,
+ ?TLS_DH_anon_WITH_AES_128_CBC_SHA256,
+ ?TLS_DH_anon_WITH_AES_256_CBC_SHA256,
+
+ ?TLS_ECDH_anon_WITH_AES_128_CBC_SHA,
+ ?TLS_ECDH_anon_WITH_AES_256_CBC_SHA,
+ ?TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA,
+
+ ?TLS_DH_anon_WITH_RC4_128_MD5];
+exclusive_anonymous_suites(2 = N) ->
+ psk_anon_exclusive(N) ++
+ [?TLS_ECDH_anon_WITH_AES_128_CBC_SHA,
+ ?TLS_ECDH_anon_WITH_AES_256_CBC_SHA,
+ ?TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA,
+
+ ?TLS_DH_anon_WITH_DES_CBC_SHA,
+ ?TLS_DH_anon_WITH_RC4_128_MD5];
+exclusive_anonymous_suites(N = 1) ->
+ psk_anon_exclusive(N) ++
+ [?TLS_DH_anon_WITH_RC4_128_MD5,
+ ?TLS_DH_anon_WITH_3DES_EDE_CBC_SHA,
+ ?TLS_DH_anon_WITH_DES_CBC_SHA
+ ] ++ srp_suites_anon({3,1}).
+
+%%--------------------------------------------------------------------
+-spec psk_suites(ssl_record:ssl_version() | integer()) -> [ssl_cipher_format:cipher_suite()].
+%%
+%% Description: Returns a list of the PSK cipher suites, only supported
+%% if explicitly set by user.
+%%--------------------------------------------------------------------
+psk_suites({3, 3}) ->
+ psk_exclusive(3);
+psk_suites({3, N}) ->
+ psk_exclusive(N).
+
+psk_exclusive(3) ->
+ psk_exclusive(1) -- [?TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA];
+psk_exclusive(1) ->
+ [
+ ?TLS_RSA_PSK_WITH_AES_256_GCM_SHA384,
+ ?TLS_RSA_PSK_WITH_AES_256_CBC_SHA384,
+ ?TLS_RSA_PSK_WITH_AES_128_GCM_SHA256,
+ ?TLS_RSA_PSK_WITH_AES_128_CBC_SHA256,
+ ?TLS_RSA_PSK_WITH_AES_256_CBC_SHA,
+ ?TLS_RSA_PSK_WITH_AES_128_CBC_SHA,
+ ?TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA,
+ ?TLS_RSA_PSK_WITH_RC4_128_SHA];
+psk_exclusive(_) ->
+ [].
+
+%%--------------------------------------------------------------------
+-spec psk_suites_anon(ssl_record:ssl_version() | integer()) -> [ssl_cipher_format:cipher_suite()].
+%%
+%% Description: Returns a list of the anonymous PSK cipher suites, only supported
+%% if explicitly set by user.
+%%--------------------------------------------------------------------
+psk_suites_anon({3, _}) ->
+ psk_anon_exclusive(3) ++ psk_anon_exclusive(1).
+
+psk_anon_exclusive(3) ->
+ [
+ ?TLS_DHE_PSK_WITH_AES_256_GCM_SHA384,
+ ?TLS_PSK_WITH_AES_256_GCM_SHA384,
+ ?TLS_DHE_PSK_WITH_AES_256_CCM,
+ ?TLS_PSK_DHE_WITH_AES_256_CCM_8,
+ ?TLS_PSK_WITH_AES_256_CCM,
+ ?TLS_PSK_WITH_AES_256_CCM_8,
+ ?TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256,
+ ?TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256,
+ ?TLS_ECDHE_PSK_WITH_AES_128_CCM_8_SHA256,
+ ?TLS_DHE_PSK_WITH_AES_128_GCM_SHA256,
+ ?TLS_PSK_WITH_AES_128_GCM_SHA256,
+ ?TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256,
+ ?TLS_ECDHE_PSK_WITH_AES_128_CCM_8_SHA256,
+ ?TLS_DHE_PSK_WITH_AES_128_CCM,
+ ?TLS_PSK_DHE_WITH_AES_128_CCM_8,
+ ?TLS_PSK_WITH_AES_128_CCM,
+ ?TLS_PSK_WITH_AES_128_CCM_8
+ ];
+psk_anon_exclusive(1) ->
+ [
+ ?TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384,
+ ?TLS_DHE_PSK_WITH_AES_256_CBC_SHA384,
+ ?TLS_PSK_WITH_AES_256_CBC_SHA384,
+ ?TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256,
+ ?TLS_DHE_PSK_WITH_AES_128_CBC_SHA256,
+ ?TLS_PSK_WITH_AES_128_CBC_SHA256,
+ ?TLS_ECDHE_PSK_WITH_RC4_128_SHA,
+ ?TLS_DHE_PSK_WITH_AES_256_CBC_SHA,
+ ?TLS_PSK_WITH_AES_256_CBC_SHA,
+ ?TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA,
+ ?TLS_DHE_PSK_WITH_AES_128_CBC_SHA,
+ ?TLS_PSK_WITH_AES_128_CBC_SHA,
+ ?TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA,
+ ?TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA,
+ ?TLS_PSK_WITH_3DES_EDE_CBC_SHA,
+ ?TLS_ECDHE_PSK_WITH_RC4_128_SHA,
+ ?TLS_DHE_PSK_WITH_RC4_128_SHA,
+ ?TLS_PSK_WITH_RC4_128_SHA];
+psk_anon_exclusive(_) ->
+ [].
+%%--------------------------------------------------------------------
+-spec srp_suites(tls_record:tls_version()) -> [ssl_cipher_format:cipher_suite()].
+%%
+%% Description: Returns a list of the SRP cipher suites, only supported
+%% if explicitly set by user.
+%%--------------------------------------------------------------------
+srp_suites({3, 3}) ->
+ srp_exclusive(1) -- [?TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA,
+ ?TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA
+ ];
+srp_suites({3, N}) when N == 1;
+ N == 2 ->
+ srp_exclusive(1).
+
+srp_exclusive(1) ->
+ [?TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA,
+ ?TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA,
+ ?TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA,
+ ?TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA,
+ ?TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA,
+ ?TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA
+ ].
+
+%%--------------------------------------------------------------------
+-spec srp_suites_anon(tls_record:tls_version()) -> [ssl_cipher_format:cipher_suite()].
+%%
+%% Description: Returns a list of the SRP anonymous cipher suites, only supported
+%% if explicitly set by user.
+%%--------------------------------------------------------------------
+srp_suites_anon({3, 3}) ->
+ srp_exclusive_anon(1) -- [?TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA];
+srp_suites_anon({3, N}) when N == 1;
+ N == 2 ->
+ srp_exclusive_anon(1).
+srp_exclusive_anon(1) ->
+ [?TLS_SRP_SHA_WITH_AES_128_CBC_SHA,
+ ?TLS_SRP_SHA_WITH_AES_256_CBC_SHA,
+ ?TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA
+ ].
+
+%%--------------------------------------------------------------------
+-spec rc4_suites(Version::ssl_record:ssl_version() | integer()) ->
+ [ssl_cipher_format:cipher_suite()].
+%%
+%% Description: Returns a list of the RSA|(ECDH/RSA)| (ECDH/ECDSA)
+%% with RC4 cipher suites, only supported if explicitly set by user.
+%% Are not considered secure any more. Other RC4 suites already
+%% belonged to the user configured only category.
+%%--------------------------------------------------------------------
+rc4_suites({3, _}) ->
+ exclusive_rc4(1).
+
+exclusive_rc4(1) ->
+ [?TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
+ ?TLS_ECDHE_RSA_WITH_RC4_128_SHA,
+ ?TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
+ ?TLS_ECDH_RSA_WITH_RC4_128_SHA,
+ ?TLS_RSA_WITH_RC4_128_SHA,
+ ?TLS_RSA_WITH_RC4_128_MD5].
+
+%%--------------------------------------------------------------------
+-spec des_suites(Version::ssl_record:ssl_version()) -> [ssl_cipher_format:cipher_suite()].
+%%
+%% Description: Returns a list of the cipher suites
+%% with DES cipher, only supported if explicitly set by user.
+%% Are not considered secure any more.
+%%--------------------------------------------------------------------
+des_suites({3, _}) ->
+ exclusive_des_suites(1).
+
+exclusive_des_suites(1)->
+ [?TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
+ ?TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
+ ?TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
+ ?TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
+ ?TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
+ ?TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
+ ?TLS_DHE_RSA_WITH_DES_CBC_SHA,
+ ?TLS_RSA_WITH_DES_CBC_SHA].
+
+%%--------------------------------------------------------------------
+-spec rsa_suites(Version::ssl_record:ssl_version() | integer()) -> [ssl_cipher_format:cipher_suite()].
+%%
+%% Description: Returns a list of the RSA key exchange
+%% cipher suites, only supported if explicitly set by user.
+%% Are not considered secure any more.
+%%--------------------------------------------------------------------
+rsa_suites({3, 3}) ->
+ rsa_suites_exclusive(3) -- [?TLS_RSA_WITH_3DES_EDE_CBC_SHA];
+rsa_suites({3, 2}) ->
+ rsa_suites_exclusive(1);
+rsa_suites({3, 1}) ->
+ rsa_suites_exclusive(1).
+
+rsa_suites_exclusive(3) ->
+ [
+ ?TLS_RSA_WITH_AES_256_GCM_SHA384,
+ ?TLS_RSA_WITH_AES_256_CBC_SHA256,
+ ?TLS_RSA_WITH_AES_128_GCM_SHA256,
+ ?TLS_RSA_WITH_AES_128_CBC_SHA256
+ ];
+rsa_suites_exclusive(1) ->
+ [?TLS_RSA_WITH_AES_256_CBC_SHA,
+ ?TLS_RSA_WITH_AES_128_CBC_SHA,
+ ?TLS_RSA_WITH_3DES_EDE_CBC_SHA
].
signature_algs({3, 4}, HashSigns) ->
diff --git a/lib/ssl/test/ssl_api_SUITE.erl b/lib/ssl/test/ssl_api_SUITE.erl
index e53bf286da..ec831cfb90 100644
--- a/lib/ssl/test/ssl_api_SUITE.erl
+++ b/lib/ssl/test/ssl_api_SUITE.erl
@@ -1868,14 +1868,12 @@ new_options_in_handshake(Config) when is_list(Config) ->
Version = ssl_test_lib:protocol_version(Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
- [_, Cipher | _] = ssl:filter_cipher_suites(ssl:cipher_suites(all, Version),
- [{key_exchange,
+ Ciphers = [_, Cipher | _] = ssl:filter_cipher_suites(ssl:cipher_suites(all, Version),
+ [{key_exchange,
fun(dhe_rsa) ->
true;
(ecdhe_rsa) ->
true;
- (ecdh_rsa) ->
- true;
(rsa) ->
false;
(_) ->
@@ -1895,7 +1893,7 @@ new_options_in_handshake(Config) when is_list(Config) ->
{host, Hostname},
{from, self()},
{mfa, {?MODULE, connection_info_result, []}},
- {options, [{ciphers, [Cipher]} | ClientOpts]}]),
+ {options, [{ciphers, Ciphers} | ClientOpts]}]),
ct:log("Testcase ~p, Client ~p Server ~p ~n",
[self(), Client, Server]),
diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl
index a82b682526..6ba6c1552c 100644
--- a/lib/ssl/test/ssl_basic_SUITE.erl
+++ b/lib/ssl/test/ssl_basic_SUITE.erl
@@ -289,58 +289,19 @@ cipher_suites() ->
" and prepend|append_cipher_suites/2"}].
cipher_suites(Config) when is_list(Config) ->
- MandatoryCipherSuiteTLS1_0TLS1_1 = #{key_exchange => rsa,
- cipher => '3des_ede_cbc',
- mac => sha,
- prf => default_prf},
- MandatoryCipherSuiteTLS1_0TLS1_2 = #{key_exchange =>rsa,
- cipher => 'aes_128_cbc',
- mac => sha,
- prf => default_prf},
- Version = tls_record:highest_protocol_version([]),
- All = [_|_] = ssl:cipher_suites(all, Version),
- Default = [_|_] = ssl:cipher_suites(default, Version),
- Anonymous = [_|_] = ssl:cipher_suites(anonymous, Version),
- true = length(Default) < length(All),
- Filters = [{key_exchange,
- fun(dhe_rsa) ->
- true;
- (_) ->
- false
- end
- },
- {cipher,
- fun(aes_256_cbc) ->
- true;
- (_) ->
- false
- end
- },
- {mac,
- fun(sha) ->
- true;
- (_) ->
- false
- end
- }
- ],
- Cipher = #{cipher => aes_256_cbc,
- key_exchange => dhe_rsa,
- mac => sha,
- prf => default_prf},
- [Cipher] = ssl:filter_cipher_suites(All, Filters),
- [Cipher | Rest0] = ssl:prepend_cipher_suites([Cipher], Default),
- [Cipher | Rest0] = ssl:prepend_cipher_suites(Filters, Default),
- true = lists:member(Cipher, Default),
- false = lists:member(Cipher, Rest0),
- [Cipher | Rest1] = lists:reverse(ssl:append_cipher_suites([Cipher], Default)),
- [Cipher | Rest1] = lists:reverse(ssl:append_cipher_suites(Filters, Default)),
- true = lists:member(Cipher, Default),
- false = lists:member(Cipher, Rest1),
- [] = lists:dropwhile(fun(X) -> not lists:member(X, Default) end, Anonymous),
- [] = lists:dropwhile(fun(X) -> not lists:member(X, All) end, Anonymous),
- true = lists:member(MandatoryCipherSuiteTLS1_0TLS1_1, All),
- true = lists:member(MandatoryCipherSuiteTLS1_0TLS1_2, All).
+ chipher_suite_checks('tlsv1.3'),
+ chipher_suite_checks('tlsv1.2'),
+ chipher_suite_checks('tlsv1.1'),
+ chipher_suite_checks('tlsv1'),
+ chipher_suite_checks('dtlsv1.2'),
+ chipher_suite_checks('dtlsv1'),
+ anon_chipher_suite_checks('tlsv1.3'),
+ anon_chipher_suite_checks('tlsv1.2'),
+ anon_chipher_suite_checks('tlsv1.1'),
+ anon_chipher_suite_checks('tlsv1'),
+ anon_chipher_suite_checks('dtlsv1.2'),
+ anon_chipher_suite_checks('dtlsv1').
+
%%--------------------------------------------------------------------
cipher_suites_mix() ->
@@ -927,7 +888,76 @@ test_fake_root(Hostname, ServerNode, ClientNode, ServerConf, ClientConf, FakeCer
ssl_test_lib:close(FakeServer1).
+anon_chipher_suite_checks('tlsv1.3' = Version) ->
+ [] = ssl:cipher_suites(anonymous, Version),
+ [] = ssl:cipher_suites(exclusive_anonymous, Version);
+anon_chipher_suite_checks(Version) ->
+ [_|_] = ssl:cipher_suites(anonymous, Version),
+ [_|_] = ssl:cipher_suites(exclusive_anonymous, Version).
-
-
+chipher_suite_checks(Version) ->
+ MandatoryCipherSuiteTLS1_0TLS1_1 = #{key_exchange => rsa,
+ cipher => '3des_ede_cbc',
+ mac => sha,
+ prf => default_prf},
+ MandatoryCipherSuiteTLS1_0TLS1_2 = #{key_exchange =>rsa,
+ cipher => 'aes_128_cbc',
+ mac => sha,
+ prf => default_prf},
+ All = [_|_] = ssl:cipher_suites(all, Version),
+ Default = [_|_] = ssl:cipher_suites(default, Version),
+ Anonymous = ssl:cipher_suites(anonymous, Version),
+ true = length(Default) < length(All),
+ Filters = [{key_exchange,
+ fun(dhe_rsa) ->
+ true;
+ (_) ->
+ false
+ end
+ },
+ {cipher,
+ fun(aes_256_cbc) ->
+ true;
+ (_) ->
+ false
+ end
+ },
+ {mac,
+ fun(sha) ->
+ true;
+ (_) ->
+ false
+ end
+ }
+ ],
+ Cipher = #{cipher => aes_256_cbc,
+ key_exchange => dhe_rsa,
+ mac => sha,
+ prf => default_prf},
+ [Cipher] = ssl:filter_cipher_suites(All, Filters),
+ [Cipher | Rest0] = ssl:prepend_cipher_suites([Cipher], Default),
+ [Cipher | Rest0] = ssl:prepend_cipher_suites(Filters, Default),
+ true = lists:member(Cipher, Default),
+ false = lists:member(Cipher, Rest0),
+ [Cipher | Rest1] = lists:reverse(ssl:append_cipher_suites([Cipher], Default)),
+ [Cipher | Rest1] = lists:reverse(ssl:append_cipher_suites(Filters, Default)),
+ true = lists:member(Cipher, Default),
+ false = lists:member(Cipher, Rest1),
+ [] = lists:dropwhile(fun(X) -> not lists:member(X, Default) end, Anonymous),
+ [] = lists:dropwhile(fun(X) -> not lists:member(X, All) end, Anonymous),
+ case Version of
+ tlsv1 ->
+ true = lists:member(MandatoryCipherSuiteTLS1_0TLS1_1, All);
+ 'tlsv1.1' ->
+ true = lists:member(MandatoryCipherSuiteTLS1_0TLS1_1, All),
+ true = lists:member(MandatoryCipherSuiteTLS1_0TLS1_2, All);
+ 'tlsv1.2' ->
+ ok;
+ 'tlsv1.3' ->
+ ok;
+ 'dtlsv1' ->
+ true = lists:member(MandatoryCipherSuiteTLS1_0TLS1_2, All);
+ 'dtlsv1.2' ->
+ ok
+ end.