diff options
-rw-r--r-- | src/ranch_ssl.erl | 20 |
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. |