aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPéter Dimitrov <[email protected]>2019-07-24 11:11:07 +0200
committerPéter Dimitrov <[email protected]>2019-07-25 14:55:37 +0200
commit73b526ce765dc7ac71fdae349da44941d8201d9c (patch)
tree38804420f8fee583de943296a25de99433f6de3a
parentb4fddea062fc13b0562bf8bf2f4cc3dc02cd193c (diff)
downloadotp-73b526ce765dc7ac71fdae349da44941d8201d9c.tar.gz
otp-73b526ce765dc7ac71fdae349da44941d8201d9c.tar.bz2
otp-73b526ce765dc7ac71fdae349da44941d8201d9c.zip
ssl: Implement option honor_cipher_order in TLS 1.3
-rw-r--r--lib/ssl/src/tls_handshake_1_3.erl15
-rw-r--r--lib/ssl/test/ssl_api_SUITE.erl64
2 files changed, 67 insertions, 12 deletions
diff --git a/lib/ssl/src/tls_handshake_1_3.erl b/lib/ssl/src/tls_handshake_1_3.erl
index 6aeb9f5663..c29366e717 100644
--- a/lib/ssl/src/tls_handshake_1_3.erl
+++ b/lib/ssl/src/tls_handshake_1_3.erl
@@ -504,7 +504,8 @@ do_start(#client_hello{cipher_suites = ClientCiphers,
ssl_options = #ssl_options{ciphers = ServerCiphers,
signature_algs = ServerSignAlgs,
supported_groups = ServerGroups0,
- alpn_preferred_protocols = ALPNPreferredProtocols},
+ alpn_preferred_protocols = ALPNPreferredProtocols,
+ honor_cipher_order = HonorCipherOrder},
session = #session{own_certificate = Cert}} = State0) ->
ClientGroups0 = maps:get(elliptic_curves, Extensions, undefined),
ClientGroups = get_supported_groups(ClientGroups0),
@@ -531,7 +532,7 @@ do_start(#client_hello{cipher_suites = ClientCiphers,
%% cipher suite, an (EC)DHE group and key share for key establishment,
%% and a signature algorithm/certificate pair to authenticate itself to
%% the client.
- Cipher = Maybe(select_cipher_suite(ClientCiphers, ServerCiphers)),
+ Cipher = Maybe(select_cipher_suite(HonorCipherOrder, ClientCiphers, ServerCiphers)),
Groups = Maybe(select_common_groups(ServerGroups, ClientGroups)),
Maybe(validate_client_key_share(ClientGroups, ClientShares)),
@@ -1731,15 +1732,19 @@ handle_alpn([ServerProtocol|T], ClientProtocols) ->
end.
-select_cipher_suite([], _) ->
+select_cipher_suite(_, [], _) ->
{error, no_suitable_cipher};
-select_cipher_suite([Cipher|ClientCiphers], ServerCiphers) ->
+%% If honor_cipher_order is set to true, use the server's preference for
+%% cipher suite selection.
+select_cipher_suite(true, ClientCiphers, ServerCiphers) ->
+ select_cipher_suite(false, ServerCiphers, ClientCiphers);
+select_cipher_suite(false, [Cipher|ClientCiphers], ServerCiphers) ->
case lists:member(Cipher, tls_v1:suites('TLS_v1.3')) andalso
lists:member(Cipher, ServerCiphers) of
true ->
{ok, Cipher};
false ->
- select_cipher_suite(ClientCiphers, ServerCiphers)
+ select_cipher_suite(false, ClientCiphers, ServerCiphers)
end.
diff --git a/lib/ssl/test/ssl_api_SUITE.erl b/lib/ssl/test/ssl_api_SUITE.erl
index a7b2a71690..4b44b4dc3e 100644
--- a/lib/ssl/test/ssl_api_SUITE.erl
+++ b/lib/ssl/test/ssl_api_SUITE.erl
@@ -127,7 +127,9 @@ beast_mitigation_test() ->
tls13_group() ->
[
- supported_groups
+ supported_groups,
+ honor_server_cipher_order_tls13,
+ honor_client_cipher_order_tls13
].
@@ -1198,11 +1200,35 @@ honor_server_cipher_order(Config) when is_list(Config) ->
cipher => aes_128_cbc,
mac => sha,
prf => default_prf}],
- honor_cipher_order(Config, true, ServerCiphers, ClientCiphers, #{key_exchange => dhe_rsa,
- cipher => aes_256_cbc,
+ honor_cipher_order(Config, true, ServerCiphers, ClientCiphers, #{key_exchange => dhe_rsa,
+ cipher => aes_256_cbc,
mac => sha,
prf => default_prf}).
%%--------------------------------------------------------------------
+honor_server_cipher_order_tls13() ->
+ [{doc,"Test API honor server cipher order in TLS 1.3."}].
+honor_server_cipher_order_tls13(Config) when is_list(Config) ->
+ ClientCiphers = [#{key_exchange => any,
+ cipher => aes_256_gcm,
+ mac => aead,
+ prf => sha384},
+ #{key_exchange => any,
+ cipher => aes_128_gcm,
+ mac => aead,
+ prf => sha256}],
+ ServerCiphers = [#{key_exchange => any,
+ cipher => aes_128_gcm,
+ mac => aead,
+ prf => sha256},
+ #{key_exchange => any,
+ cipher => aes_256_gcm,
+ mac => aead,
+ prf => sha384}],
+ honor_cipher_order(Config, true, ServerCiphers, ClientCiphers, #{key_exchange => any,
+ cipher => aes_128_gcm,
+ mac => aead,
+ prf => sha256}).
+%%--------------------------------------------------------------------
honor_client_cipher_order() ->
[{doc,"Test API honor server cipher order."}].
honor_client_cipher_order(Config) when is_list(Config) ->
@@ -1222,10 +1248,34 @@ honor_client_cipher_order(Config) when is_list(Config) ->
cipher => aes_128_cbc,
mac => sha,
prf => default_prf}],
-honor_cipher_order(Config, false, ServerCiphers, ClientCiphers, #{key_exchange => dhe_rsa,
- cipher => aes_128_cbc,
- mac => sha,
- prf => default_prf}).
+ honor_cipher_order(Config, false, ServerCiphers, ClientCiphers, #{key_exchange => dhe_rsa,
+ cipher => aes_128_cbc,
+ mac => sha,
+ prf => default_prf}).
+%%--------------------------------------------------------------------
+honor_client_cipher_order_tls13() ->
+ [{doc,"Test API honor server cipher order in TLS 1.3."}].
+honor_client_cipher_order_tls13(Config) when is_list(Config) ->
+ ClientCiphers = [#{key_exchange => any,
+ cipher => aes_256_gcm,
+ mac => aead,
+ prf => sha384},
+ #{key_exchange => any,
+ cipher => aes_128_gcm,
+ mac => aead,
+ prf => sha256}],
+ ServerCiphers = [#{key_exchange => any,
+ cipher => aes_128_gcm,
+ mac => aead,
+ prf => sha256},
+ #{key_exchange => any,
+ cipher => aes_256_gcm,
+ mac => aead,
+ prf => sha384}],
+ honor_cipher_order(Config, false, ServerCiphers, ClientCiphers, #{key_exchange => any,
+ cipher => aes_256_gcm,
+ mac => aead,
+ prf => sha384}).
%%--------------------------------------------------------------------
ipv6() ->
[{require, ipv6_hosts},