aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssl
diff options
context:
space:
mode:
authorAndreas Schultz <[email protected]>2013-02-19 18:06:26 +0100
committerIngela Anderton Andin <[email protected]>2013-05-08 10:39:16 +0200
commit432d3c39ad28fb4033b9e9c2c6aa4474dbfad03c (patch)
treeaa89dcf32103b310160b491217eeb4d0d58523e4 /lib/ssl
parent709d0482af92ca52d26296f008b495a36161ca00 (diff)
downloadotp-432d3c39ad28fb4033b9e9c2c6aa4474dbfad03c.tar.gz
otp-432d3c39ad28fb4033b9e9c2c6aa4474dbfad03c.tar.bz2
otp-432d3c39ad28fb4033b9e9c2c6aa4474dbfad03c.zip
SSL: filter TLS cipher suites for supported algorithms
Diffstat (limited to 'lib/ssl')
-rw-r--r--lib/ssl/src/ssl.erl17
-rw-r--r--lib/ssl/src/ssl_cipher.erl48
-rw-r--r--lib/ssl/test/ssl_test_lib.erl59
3 files changed, 90 insertions, 34 deletions
diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl
index 70f3b4f050..742889d8f8 100644
--- a/lib/ssl/src/ssl.erl
+++ b/lib/ssl/src/ssl.erl
@@ -364,11 +364,11 @@ cipher_suites() ->
cipher_suites(erlang) ->
Version = ssl_record:highest_protocol_version([]),
- [suite_definition(S) || S <- ssl_cipher:suites(Version)];
+ [suite_definition(S) || S <- cipher_suites(Version, [])];
cipher_suites(openssl) ->
Version = ssl_record:highest_protocol_version([]),
- [ssl_cipher:openssl_suite_name(S) || S <- ssl_cipher:suites(Version)];
+ [ssl_cipher:openssl_suite_name(S) || S <- cipher_suites(Version, [])];
cipher_suites(all) ->
Version = ssl_record:highest_protocol_version([]),
@@ -947,21 +947,22 @@ emulated_options([], Inet,Emulated) ->
{Inet, Emulated}.
cipher_suites(Version, []) ->
- ssl_cipher:suites(Version);
+ ssl_cipher:filter_suites(ssl_cipher:suites(Version));
cipher_suites(Version, [{_,_,_,_}| _] = Ciphers0) -> %% Backwards compatibility
Ciphers = [{KeyExchange, Cipher, Hash} || {KeyExchange, Cipher, Hash, _} <- Ciphers0],
- cipher_suites(Version, Ciphers);
+ ssl_cipher:filter_suites(cipher_suites(Version, Ciphers));
cipher_suites(Version, [{_,_,_}| _] = Ciphers0) ->
Ciphers = [ssl_cipher:suite(C) || C <- Ciphers0],
- cipher_suites(Version, Ciphers);
+ ssl_cipher:filter_suites(cipher_suites(Version, Ciphers));
cipher_suites(Version, [Cipher0 | _] = Ciphers0) when is_binary(Cipher0) ->
- Supported = ssl_cipher:suites(Version)
+ Supported0 = ssl_cipher:suites(Version)
++ ssl_cipher:anonymous_suites()
++ ssl_cipher:psk_suites(Version)
++ ssl_cipher:srp_suites(),
- case [Cipher || Cipher <- Ciphers0, lists:member(Cipher, Supported)] of
+ Supported1 = ssl_cipher:filter_suites(Supported0),
+ case [Cipher || Cipher <- Ciphers0, lists:member(Cipher, Supported1)] of
[] ->
- Supported;
+ Supported1;
Ciphers ->
Ciphers
end;
diff --git a/lib/ssl/src/ssl_cipher.erl b/lib/ssl/src/ssl_cipher.erl
index 173c53709b..a7622c156c 100644
--- a/lib/ssl/src/ssl_cipher.erl
+++ b/lib/ssl/src/ssl_cipher.erl
@@ -35,7 +35,7 @@
-export([security_parameters/3, suite_definition/1,
decipher/5, cipher/5,
suite/1, suites/1, anonymous_suites/0, psk_suites/1, srp_suites/0,
- openssl_suite/1, openssl_suite_name/1, filter/2,
+ openssl_suite/1, openssl_suite_name/1, filter/2, filter_suites/1,
hash_algorithm/1, sign_algorithm/1]).
-compile(inline).
@@ -738,6 +738,52 @@ filter(DerCert, Ciphers) ->
end.
%%--------------------------------------------------------------------
+-spec filter_suites([cipher_suite()]) -> [cipher_suite()].
+%%
+%% Description: filter suites for algorithms
+%%-------------------------------------------------------------------
+filter_suites(Suites = [{_,_,_}|_]) ->
+ Algos = crypto:algorithms(),
+ lists:filter(fun({KeyExchange, Cipher, Hash}) ->
+ is_acceptable_keyexchange(KeyExchange, Algos) andalso
+ is_acceptable_cipher(Cipher, Algos) andalso
+ is_acceptable_hash(Hash, Algos)
+ end, Suites);
+
+filter_suites(Suites = [{_,_,_,_}|_]) ->
+ Algos = crypto:algorithms(),
+ lists:filter(fun({KeyExchange, Cipher, Hash, Prf}) ->
+ is_acceptable_keyexchange(KeyExchange, Algos) andalso
+ is_acceptable_cipher(Cipher, Algos) andalso
+ is_acceptable_hash(Hash, Algos) andalso
+ is_acceptable_prf(Prf, Algos)
+ end, Suites);
+
+filter_suites(Suites) ->
+ Algos = crypto:algorithms(),
+ lists:filter(fun(Suite) ->
+ {KeyExchange, Cipher, Hash, Prf} = ssl_cipher:suite_definition(Suite),
+ is_acceptable_keyexchange(KeyExchange, Algos) andalso
+ is_acceptable_cipher(Cipher, Algos) andalso
+ is_acceptable_hash(Hash, Algos) andalso
+ is_acceptable_prf(Prf, Algos)
+ end, Suites).
+
+is_acceptable_keyexchange(_, _) ->
+ true.
+
+is_acceptable_cipher(_, _) ->
+ true.
+
+is_acceptable_hash(Hash, Algos) ->
+ proplists:get_bool(Hash, Algos).
+
+is_acceptable_prf(default_prf, _) ->
+ true;
+is_acceptable_prf(Prf, Algos) ->
+ proplists:get_bool(Prf, Algos).
+
+%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
diff --git a/lib/ssl/test/ssl_test_lib.erl b/lib/ssl/test/ssl_test_lib.erl
index e4fedcd118..50afad95a5 100644
--- a/lib/ssl/test/ssl_test_lib.erl
+++ b/lib/ssl/test/ssl_test_lib.erl
@@ -714,32 +714,39 @@ openssl_dsa_suites() ->
end, Ciphers).
anonymous_suites() ->
- [{dh_anon, rc4_128, md5},
- {dh_anon, des_cbc, sha},
- {dh_anon, '3des_ede_cbc', sha},
- {dh_anon, aes_128_cbc, sha},
- {dh_anon, aes_256_cbc, sha}].
+ Suites =
+ [{dh_anon, rc4_128, md5},
+ {dh_anon, des_cbc, sha},
+ {dh_anon, '3des_ede_cbc', sha},
+ {dh_anon, aes_128_cbc, sha},
+ {dh_anon, aes_256_cbc, sha}],
+ ssl_cipher:filter_suites(Suites).
psk_suites() ->
- [{rsa_psk, rc4_128, sha},
- {rsa_psk, '3des_ede_cbc', sha},
- {rsa_psk, aes_128_cbc, sha},
- {rsa_psk, aes_256_cbc, sha}].
-
-psk_anon_suites() ->
- [{psk, rc4_128, sha},
- {psk, '3des_ede_cbc', sha},
- {psk, aes_128_cbc, sha},
- {psk, aes_256_cbc, sha},
- {dhe_psk, rc4_128, sha},
- {dhe_psk, '3des_ede_cbc', sha},
- {dhe_psk, aes_128_cbc, sha},
- {dhe_psk, aes_256_cbc, sha}].
+ Suites =
+ [{psk, rc4_128, sha},
+ {psk, '3des_ede_cbc', sha},
+ {psk, aes_128_cbc, sha},
+ {psk, aes_256_cbc, sha},
+ {dhe_psk, rc4_128, sha},
+ {dhe_psk, '3des_ede_cbc', sha},
+ {dhe_psk, aes_128_cbc, sha},
+ {dhe_psk, aes_256_cbc, sha},
+ {rsa_psk, rc4_128, sha},
+ {rsa_psk, '3des_ede_cbc', sha},
+ {rsa_psk, aes_128_cbc, sha},
+ {rsa_psk, aes_256_cbc, sha}],
+ ssl_cipher:filter_suites(Suites).
srp_suites() ->
- [{srp_rsa, '3des_ede_cbc', sha},
- {srp_rsa, aes_128_cbc, sha},
- {srp_rsa, aes_256_cbc, sha}].
+ Suites =
+ [{srp_anon, '3des_ede_cbc', sha},
+ {srp_rsa, '3des_ede_cbc', sha},
+ {srp_anon, aes_128_cbc, sha},
+ {srp_rsa, aes_128_cbc, sha},
+ {srp_anon, aes_256_cbc, sha},
+ {srp_rsa, aes_256_cbc, sha}],
+ ssl_cipher:filter_suites(Suites).
srp_anon_suites() ->
[{srp_anon, '3des_ede_cbc', sha},
@@ -747,9 +754,11 @@ srp_anon_suites() ->
{srp_anon, aes_256_cbc, sha}].
srp_dss_suites() ->
- [{srp_dss, '3des_ede_cbc', sha},
- {srp_dss, aes_128_cbc, sha},
- {srp_dss, aes_256_cbc, sha}].
+ Suites =
+ [{srp_dss, '3des_ede_cbc', sha},
+ {srp_dss, aes_128_cbc, sha},
+ {srp_dss, aes_256_cbc, sha}],
+ ssl_cipher:filter_suites(Suites).
pem_to_der(File) ->
{ok, PemBin} = file:read_file(File),