aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulien Barbot <[email protected]>2013-11-03 21:30:03 +0100
committerFredrik Gustafsson <[email protected]>2013-11-06 11:13:59 +0100
commitd370fe05f5884691a89784aa73bfb4eb2176edab (patch)
treee7f1fcff06fa24a17a904159def346506765822e
parentbc8b6bf58c96f8d5a07146ddea145f71fe8c8956 (diff)
downloadotp-d370fe05f5884691a89784aa73bfb4eb2176edab.tar.gz
otp-d370fe05f5884691a89784aa73bfb4eb2176edab.tar.bz2
otp-d370fe05f5884691a89784aa73bfb4eb2176edab.zip
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.
-rw-r--r--lib/ssl/doc/src/ssl.xml10
-rw-r--r--lib/ssl/src/ssl_handshake.erl18
-rw-r--r--lib/ssl/src/ssl_internal.hrl3
-rw-r--r--lib/ssl/src/tls.erl9
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}
</c></p>
<p><c>transportoption() = {cb_info, {CallbackModule::atom(), DataTag::atom(), ClosedTag::atom(), ErrTag:atom()}}
@@ -384,6 +384,14 @@ fun(srp, Username :: string(), UserState :: term()) ->
<tag>{srp_identity, {Username :: string(), Password :: string()}</tag>
<item>Specifies the Username and Password to use to authenticate to the server.
</item>
+ <tag>{server_name_indication, hostname()}</tag>
+ <tag>{server_name_indication, disable}</tag>
+ <item>
+ <p>This option can be specified when upgrading a tcp socket to a tls
+ socket to use the TLS Server Name Indication extension.</p>
+ <p>This option can also be set to disable to explicitly disable usage of
+ the Server Name Indication extension.</p>
+ </item>
</taglist>
</section>
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}}}).