aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssl
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
parent147ed05c7fb3a8c4176d8f19fd86454ea9bf9603 (diff)
downloadotp-c694ef2b5e96a69eefd215a65667a03fade1e32e.tar.gz
otp-c694ef2b5e96a69eefd215a65667a03fade1e32e.tar.bz2
otp-c694ef2b5e96a69eefd215a65667a03fade1e32e.zip
ssl, dtls: Refactor sni handling
Diffstat (limited to 'lib/ssl')
-rw-r--r--lib/ssl/src/dtls_connection.erl8
-rw-r--r--lib/ssl/src/ssl_connection.erl44
-rw-r--r--lib/ssl/src/tls_connection.erl68
3 files changed, 67 insertions, 53 deletions
diff --git a/lib/ssl/src/dtls_connection.erl b/lib/ssl/src/dtls_connection.erl
index da7c61cef0..c02cf51a9a 100644
--- a/lib/ssl/src/dtls_connection.erl
+++ b/lib/ssl/src/dtls_connection.erl
@@ -44,7 +44,8 @@
%% Handshake handling
-export([renegotiate/2,
reinit_handshake_data/1,
- send_handshake/2, queue_handshake/2, queue_change_cipher/2]).
+ send_handshake/2, queue_handshake/2, queue_change_cipher/2,
+ select_sni_extension/1]).
%% Alert and close handling
-export([send_alert/2, close/5]).
@@ -147,6 +148,11 @@ reinit_handshake_data(#state{protocol_buffers = Buffers} = State) ->
Buffers#protocol_buffers{dtls_fragment_state =
dtls_handshake:dtls_handshake_new_flight(0)}}.
+select_sni_extension(#client_hello{extensions = HelloExtensions}) ->
+ HelloExtensions#hello_extensions.sni;
+select_sni_extension(_) ->
+ undefined.
+
%%====================================================================
%% tls_connection_sup API
%%====================================================================
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.
diff --git a/lib/ssl/src/tls_connection.erl b/lib/ssl/src/tls_connection.erl
index 7e02021dae..c64a00c7bf 100644
--- a/lib/ssl/src/tls_connection.erl
+++ b/lib/ssl/src/tls_connection.erl
@@ -51,7 +51,7 @@
%% Handshake handling
-export([renegotiate/2, send_handshake/2,
queue_handshake/2, queue_change_cipher/2,
- reinit_handshake_data/1, handle_sni_extension/2]).
+ reinit_handshake_data/1, select_sni_extension/1]).
%% Alert and close handling
-export([send_alert/2, close/5]).
@@ -144,6 +144,11 @@ reinit_handshake_data(State) ->
tls_handshake_history = ssl_handshake:init_handshake_history()
}.
+select_sni_extension(#client_hello{extensions = HelloExtensions}) ->
+ HelloExtensions#hello_extensions.sni;
+select_sni_extension(_) ->
+ undefined.
+
%%====================================================================
%% tls_connection_sup API
%%====================================================================
@@ -521,23 +526,6 @@ initial_state(Role, Host, Port, Socket, {SSLOptions, SocketOptions, Tracker}, Us
flight_buffer = []
}.
-
-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.
-
next_tls_record(Data, #state{protocol_buffers = #protocol_buffers{tls_record_buffer = Buf0,
tls_cipher_texts = CT0} = Buffers} = State0) ->
case tls_record:get_tls_records(Data, Buf0) of
@@ -690,42 +678,16 @@ convert_options_partial_chain(Options, up) ->
convert_options_partial_chain(Options, down) ->
list_to_tuple(proplists:delete(partial_chain, tuple_to_list(Options))).
-handle_sni_extension(#client_hello{extensions = HelloExtensions}, State0) ->
- case HelloExtensions#hello_extensions.sni of
- undefined ->
- State0;
- #sni{hostname = Hostname} ->
- 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;
-handle_sni_extension(_, State) ->
- State.
-
-gen_handshake(GenConnection, StateName, Type, Event, #state{negotiated_version = Version} = State) ->
+gen_handshake(GenConnection, StateName, Type, Event,
+ #state{negotiated_version = Version} = State) ->
try GenConnection:StateName(Type, Event, State, ?MODULE) of
Result ->
Result
catch
_:_ ->
- handle_own_alert(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE, malformed_handshake_data), Version, StateName, State)
+ ssl_connection:handle_own_alert(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE,
+ malformed_handshake_data),
+ Version, StateName, State)
end.
gen_info(Event, connection = StateName, #state{negotiated_version = Version} = State) ->
@@ -734,7 +696,9 @@ gen_info(Event, connection = StateName, #state{negotiated_version = Version} =
Result
catch
_:_ ->
- handle_own_alert(?ALERT_REC(?FATAL, ?INTERNAL_ERROR, malformed_data), Version, StateName, State)
+ ssl_connection:handle_own_alert(?ALERT_REC(?FATAL, ?INTERNAL_ERROR,
+ malformed_data),
+ Version, StateName, State)
end;
gen_info(Event, StateName, #state{negotiated_version = Version} = State) ->
@@ -743,6 +707,8 @@ gen_info(Event, StateName, #state{negotiated_version = Version} = State) ->
Result
catch
_:_ ->
- handle_own_alert(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE, malformed_handshake_data), Version, StateName, State)
+ ssl_connection:handle_own_alert(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE,
+ malformed_handshake_data),
+ Version, StateName, State)
end.