aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssl/src/tls_connection.erl
diff options
context:
space:
mode:
authorQijiang Fan <[email protected]>2014-12-30 22:40:28 +0800
committerIngela Anderton Andin <[email protected]>2015-05-12 13:57:25 +0200
commit4fe38c4b8b2c8024afb60990e598ff823743fd54 (patch)
treeea9c593b1a6ac3e76913c77dfce1caae97c41bf0 /lib/ssl/src/tls_connection.erl
parent996380765561b1a0e3d215437d4560d2e7a72cfb (diff)
downloadotp-4fe38c4b8b2c8024afb60990e598ff823743fd54.tar.gz
otp-4fe38c4b8b2c8024afb60990e598ff823743fd54.tar.bz2
otp-4fe38c4b8b2c8024afb60990e598ff823743fd54.zip
ssl: add SNI server support
Diffstat (limited to 'lib/ssl/src/tls_connection.erl')
-rw-r--r--lib/ssl/src/tls_connection.erl42
1 files changed, 41 insertions, 1 deletions
diff --git a/lib/ssl/src/tls_connection.erl b/lib/ssl/src/tls_connection.erl
index 0577222980..d804d7ad37 100644
--- a/lib/ssl/src/tls_connection.erl
+++ b/lib/ssl/src/tls_connection.erl
@@ -398,6 +398,15 @@ initial_state(Role, Host, Port, Socket, {SSLOptions, SocketOptions, Tracker}, Us
tracker = Tracker
}.
+
+update_ssl_options_from_sni(OrigSSLOptions, SNIHostname) ->
+ case proplists:get_value(SNIHostname, OrigSSLOptions#ssl_options.sni_hosts) of
+ undefined ->
+ undefined;
+ SSLOption ->
+ ssl:handle_options(SSLOption, OrigSSLOptions)
+ end.
+
next_state(Current,_, #alert{} = Alert, #state{negotiated_version = Version} = State) ->
handle_own_alert(Alert, Version, Current, State);
@@ -439,7 +448,38 @@ next_state(Current, Next, #ssl_tls{type = ?HANDSHAKE, fragment = Data},
end,
try
{Packets, Buf} = tls_handshake:get_tls_handshake(Version,Data,Buf0),
- State = State0#state{protocol_buffers =
+ State1 = case Packets of
+ [{#client_hello{extensions=HelloExtensions} = ClientHello, _}] ->
+ case HelloExtensions#hello_extensions.sni of
+ undefined ->
+ State0;
+ #sni{hostname = Hostname} ->
+ OrigSSLOptions = State0#state.ssl_options,
+ NewOptions = update_ssl_options_from_sni(State0#state.ssl_options, Hostname),
+ case NewOptions of
+ undefined ->
+ State0;
+ _ ->
+ {ok, Ref, CertDbHandle, FileRefHandle, CacheHandle, CRLDbHandle, OwnCert, Key, DHParams} =
+ ssl_config:init(NewOptions, State0#state.role),
+ State0#state{
+ session = State0#state.session#session{own_certificate = OwnCert},
+ file_ref_db = FileRefHandle,
+ cert_db_ref = Ref,
+ cert_db = CertDbHandle,
+ crl_db = CRLDbHandle,
+ session_cache = CacheHandle,
+ private_key = Key,
+ diffie_hellman_params = DHParams,
+ ssl_options = NewOptions,
+ sni_hostname = Hostname
+ }
+ end
+ end;
+ _ ->
+ State0
+ end,
+ State = State1#state{protocol_buffers =
Buffers#protocol_buffers{tls_packets = Packets,
tls_handshake_buffer = Buf}},
handle_tls_handshake(Handle, Next, State)