aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKlaus Trainer <[email protected]>2013-07-17 22:15:31 +0200
committerKlaus Trainer <[email protected]>2013-07-24 14:58:10 +0200
commitc0c09a13112f21cde05f2c4b0fff641addd15bb6 (patch)
tree74661387a5e21ecca336b0a689b8fbceb0d6045d
parent1cfc4ed0acab89b9531ac36f5ff06eaa862c6cd2 (diff)
downloadranch-c0c09a13112f21cde05f2c4b0fff641addd15bb6.tar.gz
ranch-c0c09a13112f21cde05f2c4b0fff641addd15bb6.tar.bz2
ranch-c0c09a13112f21cde05f2c4b0fff641addd15bb6.zip
Work around broken elliptic-curve cipher suites
Unfortunately the implementation of elliptic-curve ciphers that has been introduced in R16B01 is incomplete. Depending on the particular client, this can cause the TLS handshake to break during key agreement. As it turns out that most popular browsers (e.g. Firefox, Chromium, and Safari) are affected by this bug, we provide this workaround. This workaround makes sure that only cipher suite implementations that are not known to be broken are supported by default.
-rw-r--r--src/ranch_ssl.erl20
1 files changed, 19 insertions, 1 deletions
diff --git a/src/ranch_ssl.erl b/src/ranch_ssl.erl
index 512f3b4..98b2f5e 100644
--- a/src/ranch_ssl.erl
+++ b/src/ranch_ssl.erl
@@ -136,10 +136,11 @@ listen(Opts) ->
true = lists:keymember(cert, 1, Opts)
orelse lists:keymember(certfile, 1, Opts),
Opts2 = ranch:set_option_default(Opts, backlog, 1024),
+ Opts3 = ranch:set_option_default(Opts2, ciphers, unbroken_cipher_suites()),
%% We set the port to 0 because it is given in the Opts directly.
%% The port in the options takes precedence over the one in the
%% first argument.
- ssl:listen(0, ranch:filter_options(Opts2,
+ ssl:listen(0, ranch:filter_options(Opts3,
[backlog, cacertfile, cacerts, cert, certfile, ciphers,
fail_if_no_peer_cert, ip, key, keyfile, next_protocols_advertised,
nodelay, password, port, raw, reuse_session, reuse_sessions,
@@ -269,3 +270,20 @@ ssl_accept(Socket, Timeout) ->
{error, Reason} ->
{error, {ssl_accept, Reason}}
end.
+
+%% Unfortunately the implementation of elliptic-curve ciphers that has
+%% been introduced in R16B01 is incomplete. Depending on the particular
+%% client, this can cause the TLS handshake to break during key
+%% agreement. Depending on the ssl application version, this function
+%% returns a list of all cipher suites that are supported by default,
+%% minus the elliptic-curve ones.
+-spec unbroken_cipher_suites() -> [ssl:erl_cipher_suite()].
+unbroken_cipher_suites() ->
+ case proplists:get_value(ssl_app, ssl:versions()) of
+ "5.3" ->
+ lists:filter(fun(Suite) ->
+ string:left(atom_to_list(element(1, Suite)), 4) =/= "ecdh"
+ end, ssl:cipher_suites());
+ _ ->
+ ssl:cipher_suites()
+ end.