aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssl/src/ssl_connection.erl
diff options
context:
space:
mode:
authorIngela Anderton Andin <[email protected]>2016-08-19 10:47:21 +0200
committerIngela Anderton Andin <[email protected]>2016-09-05 14:37:27 +0200
commitc694ef2b5e96a69eefd215a65667a03fade1e32e (patch)
treed317ae3bbd4d548ea35e86fc3a605095e48784d3 /lib/ssl/src/ssl_connection.erl
parent147ed05c7fb3a8c4176d8f19fd86454ea9bf9603 (diff)
downloadotp-c694ef2b5e96a69eefd215a65667a03fade1e32e.tar.gz
otp-c694ef2b5e96a69eefd215a65667a03fade1e32e.tar.bz2
otp-c694ef2b5e96a69eefd215a65667a03fade1e32e.zip
ssl, dtls: Refactor sni handling
Diffstat (limited to 'lib/ssl/src/ssl_connection.erl')
-rw-r--r--lib/ssl/src/ssl_connection.erl44
1 files changed, 43 insertions, 1 deletions
diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl
index 3fe64ea6b0..f0f5982de4 100644
--- a/lib/ssl/src/ssl_connection.erl
+++ b/lib/ssl/src/ssl_connection.erl
@@ -813,10 +813,12 @@ handle_common_event(internal, {handshake, {Handshake, Raw}}, StateName,
#state{tls_handshake_history = Hs0,
ssl_options = #ssl_options{v2_hello_compatible = V2HComp}} = State0,
Connection) ->
+
+ PossibleSNI = Connection:select_sni_extension(Handshake),
%% This function handles client SNI hello extension when Handshake is
%% a client_hello, which needs to be determined by the connection callback.
%% In other cases this is a noop
- State = Connection:handle_sni_extension(Handshake, State0),
+ State = handle_sni_extension(PossibleSNI, State0),
HsHist = ssl_handshake:update_handshake_history(Hs0, Raw, V2HComp),
{next_state, StateName, State#state{tls_handshake_history = HsHist},
[{next_event, internal, Handshake}]};
@@ -2404,3 +2406,43 @@ invalidate_session(client, Host, Port, Session) ->
ssl_manager:invalidate_session(Host, Port, Session);
invalidate_session(server, _, Port, Session) ->
ssl_manager:invalidate_session(Port, Session).
+
+handle_sni_extension(undefined, State) ->
+ State;
+handle_sni_extension(#sni{hostname = Hostname}, State0) ->
+ 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.
+
+update_ssl_options_from_sni(OrigSSLOptions, SNIHostname) ->
+ SSLOption =
+ case OrigSSLOptions#ssl_options.sni_fun of
+ undefined ->
+ proplists:get_value(SNIHostname,
+ OrigSSLOptions#ssl_options.sni_hosts);
+ SNIFun ->
+ SNIFun(SNIHostname)
+ end,
+ case SSLOption of
+ undefined ->
+ undefined;
+ _ ->
+ ssl:handle_options(SSLOption, OrigSSLOptions)
+ end.