diff options
author | Ingela Andin <ingela@erlang.org> | 2021-08-30 15:00:53 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-30 15:00:53 +0200 |
commit | 175fb04cf23713ba5fc82a0873d9fe018c113bfe (patch) | |
tree | db1da318564cb7f2fb1b2eb0d3b8903940fa9026 | |
parent | eec966bbd28a5ae200796ad7b96e2f6a6922bde0 (diff) | |
parent | 7f533c862951efc2072d2738362241f2411e1ebc (diff) | |
download | erlang-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.xml | 17 | ||||
-rw-r--r-- | lib/ssl/src/dtls_v1.erl | 29 | ||||
-rw-r--r-- | lib/ssl/src/ssl.erl | 27 | ||||
-rw-r--r-- | lib/ssl/src/ssl_cipher.erl | 234 | ||||
-rw-r--r-- | lib/ssl/src/tls_v1.erl | 251 | ||||
-rw-r--r-- | lib/ssl/test/ssl_api_SUITE.erl | 8 | ||||
-rw-r--r-- | lib/ssl/test/ssl_basic_SUITE.erl | 138 |
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. |