diff options
author | Ingela Anderton Andin <[email protected]> | 2016-08-19 10:47:21 +0200 |
---|---|---|
committer | Ingela Anderton Andin <[email protected]> | 2016-09-05 14:37:27 +0200 |
commit | c694ef2b5e96a69eefd215a65667a03fade1e32e (patch) | |
tree | d317ae3bbd4d548ea35e86fc3a605095e48784d3 /lib/ssl/src/ssl_connection.erl | |
parent | 147ed05c7fb3a8c4176d8f19fd86454ea9bf9603 (diff) | |
download | otp-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.erl | 44 |
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. |