From d370fe05f5884691a89784aa73bfb4eb2176edab Mon Sep 17 00:00:00 2001 From: Julien Barbot Date: Sun, 3 Nov 2013 21:30:03 +0100 Subject: Add a new server_name_indication option to ssl:connect - Set to disable to explicitly disable SNI support. - Set to a hostname when upgrading from TCP to TLS. --- lib/ssl/doc/src/ssl.xml | 10 +++++++++- lib/ssl/src/ssl_handshake.erl | 18 ++++++++++++------ lib/ssl/src/ssl_internal.hrl | 3 ++- lib/ssl/src/tls.erl | 9 ++++++++- 4 files changed, 31 insertions(+), 9 deletions(-) diff --git a/lib/ssl/doc/src/ssl.xml b/lib/ssl/doc/src/ssl.xml index aac04095b4..b4182e6d61 100644 --- a/lib/ssl/doc/src/ssl.xml +++ b/lib/ssl/doc/src/ssl.xml @@ -89,7 +89,7 @@ {ssl_imp, ssl_imp()} | {reuse_sessions, boolean()} | {reuse_session, fun()} {next_protocols_advertised, [binary()]} | {client_preferred_next_protocols, {client | server, [binary()]} | {client | server, [binary()], binary()}} | - {log_alert, boolean()} + {log_alert, boolean()} | {server_name_indication, hostname() | disable}

transportoption() = {cb_info, {CallbackModule::atom(), DataTag::atom(), ClosedTag::atom(), ErrTag:atom()}} @@ -384,6 +384,14 @@ fun(srp, Username :: string(), UserState :: term()) -> {srp_identity, {Username :: string(), Password :: string()} Specifies the Username and Password to use to authenticate to the server. + {server_name_indication, hostname()} + {server_name_indication, disable} + +

This option can be specified when upgrading a tcp socket to a tls + socket to use the TLS Server Name Indication extension.

+

This option can also be set to disable to explicitly disable usage of + the Server Name Indication extension.

+ diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl index e1fd6970cc..9142a260b1 100644 --- a/lib/ssl/src/ssl_handshake.erl +++ b/lib/ssl/src/ssl_handshake.erl @@ -105,7 +105,7 @@ client_hello_extensions(Host, Version, CipherSuites, SslOpts, ConnectionStates, next_protocol_negotiation = encode_client_protocol_negotiation(SslOpts#ssl_options.next_protocol_selector, Renegotiation), - sni = sni(Host)}. + sni = sni(Host, SslOpts#ssl_options.server_name_indication)}. %%-------------------------------------------------------------------- -spec certificate(der_cert(), db_handle(), certdb_ref(), client | server) -> #certificate{} | #alert{}. @@ -1159,13 +1159,19 @@ select_curve(Curves, [Curve| Rest]) -> false -> select_curve(Curves, Rest) end. +%% RFC 6066, Section 3: Currently, the only server names supported are +%% DNS hostnames +sni(_, disable) -> + undefined; +sni(Host, undefined) -> + sni1(Host); +sni(_Host, SNIOption) -> + sni1(SNIOption). -sni(Host) -> - %% RFC 6066, Section 3: Currently, the only server names supported are - %% DNS hostnames - case inet_parse:domain(Host) of +sni1(Hostname) -> + case inet_parse:domain(Hostname) of false -> undefined; - true -> #sni{hostname = Host} + true -> #sni{hostname = Hostname} end. %%-------------------------------------------------------------------- %%% Internal functions diff --git a/lib/ssl/src/ssl_internal.hrl b/lib/ssl/src/ssl_internal.hrl index 96e3280fb5..a582b8c290 100644 --- a/lib/ssl/src/ssl_internal.hrl +++ b/lib/ssl/src/ssl_internal.hrl @@ -115,7 +115,8 @@ erl_dist = false, next_protocols_advertised = undefined, %% [binary()], next_protocol_selector = undefined, %% fun([binary()]) -> binary()) - log_alert + log_alert, + server_name_indication = undefined }). -record(socket_options, diff --git a/lib/ssl/src/tls.erl b/lib/ssl/src/tls.erl index b220a48f73..f1747dc69e 100644 --- a/lib/ssl/src/tls.erl +++ b/lib/ssl/src/tls.erl @@ -664,7 +664,8 @@ handle_options(Opts0, _Role) -> next_protocol_selector = make_next_protocol_selector( handle_option(client_preferred_next_protocols, Opts, undefined)), - log_alert = handle_option(log_alert, Opts, true) + log_alert = handle_option(log_alert, Opts, true), + server_name_indication = handle_option(server_name_indication, Opts, undefined) }, CbInfo = proplists:get_value(cb_info, Opts, {gen_tcp, tcp, tcp_closed, tcp_error}), @@ -855,6 +856,12 @@ validate_option(next_protocols_advertised = Opt, Value) when is_list(Value) -> validate_option(next_protocols_advertised, undefined) -> undefined; +validate_option(server_name_indication, Value) when is_list(Value) -> + Value; +validate_option(server_name_indication, disable) -> + disable; +validate_option(server_name_indication, undefined) -> + undefined; validate_option(Opt, Value) -> throw({error, {options, {Opt, Value}}}). -- cgit v1.2.3