Skip to content

Commit c0c09a1

Browse files
committed
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.
1 parent 1cfc4ed commit c0c09a1

File tree

1 file changed

+19
-1
lines changed

1 file changed

+19
-1
lines changed

src/ranch_ssl.erl

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,10 +136,11 @@ listen(Opts) ->
136136
true = lists:keymember(cert, 1, Opts)
137137
orelse lists:keymember(certfile, 1, Opts),
138138
Opts2 = ranch:set_option_default(Opts, backlog, 1024),
139+
Opts3 = ranch:set_option_default(Opts2, ciphers, unbroken_cipher_suites()),
139140
%% We set the port to 0 because it is given in the Opts directly.
140141
%% The port in the options takes precedence over the one in the
141142
%% first argument.
142-
ssl:listen(0, ranch:filter_options(Opts2,
143+
ssl:listen(0, ranch:filter_options(Opts3,
143144
[backlog, cacertfile, cacerts, cert, certfile, ciphers,
144145
fail_if_no_peer_cert, ip, key, keyfile, next_protocols_advertised,
145146
nodelay, password, port, raw, reuse_session, reuse_sessions,
@@ -269,3 +270,20 @@ ssl_accept(Socket, Timeout) ->
269270
{error, Reason} ->
270271
{error, {ssl_accept, Reason}}
271272
end.
273+
274+
%% Unfortunately the implementation of elliptic-curve ciphers that has
275+
%% been introduced in R16B01 is incomplete. Depending on the particular
276+
%% client, this can cause the TLS handshake to break during key
277+
%% agreement. Depending on the ssl application version, this function
278+
%% returns a list of all cipher suites that are supported by default,
279+
%% minus the elliptic-curve ones.
280+
-spec unbroken_cipher_suites() -> [ssl:erl_cipher_suite()].
281+
unbroken_cipher_suites() ->
282+
case proplists:get_value(ssl_app, ssl:versions()) of
283+
"5.3" ->
284+
lists:filter(fun(Suite) ->
285+
string:left(atom_to_list(element(1, Suite)), 4) =/= "ecdh"
286+
end, ssl:cipher_suites());
287+
_ ->
288+
ssl:cipher_suites()
289+
end.

0 commit comments

Comments
 (0)