aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssl/src/ssl_cipher.erl
diff options
context:
space:
mode:
authorIngela Anderton Andin <[email protected]>2016-02-18 11:09:32 +0100
committerIngela Anderton Andin <[email protected]>2016-02-22 10:44:07 +0100
commitb254f5a83145b348def5950d46628d3f4549585e (patch)
treeaac3de6f53cc3e956e0766fb2884d9b556e4ead4 /lib/ssl/src/ssl_cipher.erl
parent88021d58ff1c5b92689b100d1288ef7d3185233f (diff)
downloadotp-b254f5a83145b348def5950d46628d3f4549585e.tar.gz
otp-b254f5a83145b348def5950d46628d3f4549585e.tar.bz2
otp-b254f5a83145b348def5950d46628d3f4549585e.zip
ssl: Newer cipher suites now presented correctly
Older SSL/TLS versions have cipher suites that look like {key_exchange(), cipher(), MAC::hash()} and the hash function used by the PRF (Pseudo Random function) is implicit and always the same for that protocol version. In TLS 1.2 a cipher suite is {key_exchange(), cipher(), MAC::hash(), PRF::hash()}. Internally a cipher suite is always a four tuple but for backwards compatibility older cipher suites will be presented as a three tuples, however new cipher suites should be presented as four tuples.
Diffstat (limited to 'lib/ssl/src/ssl_cipher.erl')
-rw-r--r--lib/ssl/src/ssl_cipher.erl31
1 files changed, 17 insertions, 14 deletions
diff --git a/lib/ssl/src/ssl_cipher.erl b/lib/ssl/src/ssl_cipher.erl
index 80c4e5fdcd..974a6ec6b5 100644
--- a/lib/ssl/src/ssl_cipher.erl
+++ b/lib/ssl/src/ssl_cipher.erl
@@ -49,8 +49,11 @@
| aes_128_cbc | aes_256_cbc | aes_128_gcm | aes_256_gcm | chacha20_poly1305.
-type hash() :: null | sha | md5 | sha224 | sha256 | sha384 | sha512.
-type key_algo() :: null | rsa | dhe_rsa | dhe_dss | ecdhe_ecdsa| ecdh_ecdsa | ecdh_rsa| srp_rsa| srp_dss | psk | dhe_psk | rsa_psk | dh_anon | ecdh_anon | srp_anon.
--type erl_cipher_suite() :: {key_algo(), cipher(), hash()}.
--type int_cipher_suite() :: {key_algo(), cipher(), hash(), hash() | default_prf}.
+-type erl_cipher_suite() :: {key_algo(), cipher(), hash()} % Pre TLS 1.2
+ %% TLS 1.2, internally PRE TLS 1.2 will use default_prf
+ | {key_algo(), cipher(), hash(), hash() | default_prf}.
+
+
-type cipher_suite() :: binary().
-type cipher_enum() :: integer().
-type openssl_cipher_suite() :: string().
@@ -418,7 +421,7 @@ rc4_suites({3, N}) when N =< 3 ->
?TLS_ECDH_RSA_WITH_RC4_128_SHA].
%%--------------------------------------------------------------------
--spec suite_definition(cipher_suite()) -> int_cipher_suite().
+-spec suite_definition(cipher_suite()) -> erl_cipher_suite().
%%
%% Description: Return erlang cipher suite definition.
%% Note: Currently not supported suites are commented away.
@@ -723,14 +726,18 @@ suite_definition(?TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256) ->
{dhe_rsa, chacha20_poly1305, null, sha256}.
%%--------------------------------------------------------------------
--spec erl_suite_definition(ssl_cipher:cipher_suite()) -> ssl_cipher:erl_cipher_suite().
+-spec erl_suite_definition(cipher_suite()) -> erl_cipher_suite().
%%
%% Description: Return erlang cipher suite definition. Filters last value
%% for now (compatibility reasons).
%%--------------------------------------------------------------------
erl_suite_definition(S) ->
- {KeyExchange, Cipher, Hash, _} = ssl_cipher:suite_definition(S),
- {KeyExchange, Cipher, Hash}.
+ case suite_definition(S) of
+ {KeyExchange, Cipher, Hash, default_prf} ->
+ {KeyExchange, Cipher, Hash};
+ Suite ->
+ Suite
+ end.
%%--------------------------------------------------------------------
-spec suite(erl_cipher_suite()) -> cipher_suite().
@@ -1395,18 +1402,14 @@ filter(DerCert, Ciphers) ->
%%
%% Description: Filter suites for algorithms supported by crypto.
%%-------------------------------------------------------------------
-filter_suites(Suites = [{_,_,_}|_]) ->
+filter_suites(Suites = [Value|_]) when is_tuple(Value) ->
Algos = crypto:supports(),
+ Hashs = proplists:get_value(hashs, Algos),
lists:filter(fun({KeyExchange, Cipher, Hash}) ->
is_acceptable_keyexchange(KeyExchange, proplists:get_value(public_keys, Algos)) andalso
is_acceptable_cipher(Cipher, proplists:get_value(ciphers, Algos)) andalso
- is_acceptable_hash(Hash, proplists:get_value(hashs, Algos))
- end, Suites);
-
-filter_suites(Suites = [{_,_,_,_}|_]) ->
- Algos = crypto:supports(),
- Hashs = proplists:get_value(hashs, Algos),
- lists:filter(fun({KeyExchange, Cipher, Hash, Prf}) ->
+ is_acceptable_hash(Hash, proplists:get_value(hashs, Algos));
+ ({KeyExchange, Cipher, Hash, Prf}) ->
is_acceptable_keyexchange(KeyExchange, proplists:get_value(public_keys, Algos)) andalso
is_acceptable_cipher(Cipher, proplists:get_value(ciphers, Algos)) andalso
is_acceptable_hash(Hash, Hashs) andalso