diff options
author | Ingela Anderton Andin <[email protected]> | 2018-12-18 12:30:46 +0100 |
---|---|---|
committer | Ingela Anderton Andin <[email protected]> | 2018-12-20 12:00:23 +0100 |
commit | d6b4f6dd29adc82bc3cedd143e30bef997db9b0c (patch) | |
tree | 44797953f66b429a72eaffe8a1394e7068c841ef | |
parent | d82e39db62513c81a12ee015ba44aae1837662ff (diff) | |
download | otp-d6b4f6dd29adc82bc3cedd143e30bef997db9b0c.tar.gz otp-d6b4f6dd29adc82bc3cedd143e30bef997db9b0c.tar.bz2 otp-d6b4f6dd29adc82bc3cedd143e30bef997db9b0c.zip |
ssl: Fix renegotiation with new TLS sender
Wtite connection state was not synchronized when peer initiated renegotiation
-rw-r--r-- | lib/ssl/src/ssl_connection.erl | 2 | ||||
-rw-r--r-- | lib/ssl/src/tls_connection.erl | 27 | ||||
-rw-r--r-- | lib/ssl/src/tls_sender.erl | 11 |
3 files changed, 36 insertions, 4 deletions
diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl index 619824a7f2..390bdf0810 100644 --- a/lib/ssl/src/ssl_connection.erl +++ b/lib/ssl/src/ssl_connection.erl @@ -1131,7 +1131,7 @@ handle_common_event(internal, {handshake, {#hello_request{} = Handshake, _}}, co handle_common_event(internal, {handshake, {#hello_request{}, _}}, StateName, #state{static_env = #static_env{role = client}}, _) when StateName =/= connection -> - {keep_state_and_data}; + keep_state_and_data; handle_common_event(internal, {handshake, {Handshake, Raw}}, StateName, #state{tls_handshake_history = Hs0} = State0, Connection) -> diff --git a/lib/ssl/src/tls_connection.erl b/lib/ssl/src/tls_connection.erl index 9aeca8c589..798b853026 100644 --- a/lib/ssl/src/tls_connection.erl +++ b/lib/ssl/src/tls_connection.erl @@ -620,12 +620,34 @@ connection(internal, #hello_request{}, port = Port, session_cache = Cache, session_cache_cb = CacheCb}, + renegotiation = {Renegotiation, peer}, + session = #session{own_certificate = Cert} = Session0, + ssl_options = SslOpts, + protocol_specific = #{sender := Pid}, + connection_states = ConnectionStates} = State0) -> + try tls_sender:peer_renegotiate(Pid) of + {ok, Write} -> + Hello = tls_handshake:client_hello(Host, Port, ConnectionStates, SslOpts, + Cache, CacheCb, Renegotiation, Cert), + {State, Actions} = send_handshake(Hello, State0#state{connection_states = ConnectionStates#{current_write => Write}}), + next_event(hello, no_record, State#state{session = Session0#session{session_id + = Hello#client_hello.session_id}}, Actions) + catch + _:_ -> + {stop, {shutdown, sender_blocked}, State0} + end; +connection(internal, #hello_request{}, + #state{static_env = #static_env{role = client, + host = Host, + port = Port, + session_cache = Cache, + session_cache_cb = CacheCb}, renegotiation = {Renegotiation, _}, session = #session{own_certificate = Cert} = Session0, - ssl_options = SslOpts, + ssl_options = SslOpts, connection_states = ConnectionStates} = State0) -> Hello = tls_handshake:client_hello(Host, Port, ConnectionStates, SslOpts, - Cache, CacheCb, Renegotiation, Cert), + Cache, CacheCb, Renegotiation, Cert), {State, Actions} = send_handshake(Hello, State0), next_event(hello, no_record, State#state{session = Session0#session{session_id = Hello#client_hello.session_id}}, Actions); @@ -655,6 +677,7 @@ connection(internal, #client_hello{}, send_alert_in_connection(Alert, State0), State = Connection:reinit_handshake_data(State0), next_event(?FUNCTION_NAME, no_record, State); + connection(Type, Event, State) -> ssl_connection:?FUNCTION_NAME(Type, Event, State, ?MODULE). diff --git a/lib/ssl/src/tls_sender.erl b/lib/ssl/src/tls_sender.erl index 7520832f39..11fcc6def0 100644 --- a/lib/ssl/src/tls_sender.erl +++ b/lib/ssl/src/tls_sender.erl @@ -29,7 +29,7 @@ %% API -export([start/0, start/1, initialize/2, send_data/2, send_alert/2, - send_and_ack_alert/2, setopts/2, renegotiate/1, downgrade/2, + send_and_ack_alert/2, setopts/2, renegotiate/1, peer_renegotiate/1, downgrade/2, update_connection_state/3, dist_tls_socket/1, dist_handshake_complete/3]). %% gen_statem callbacks @@ -118,6 +118,15 @@ setopts(Pid, Opts) -> renegotiate(Pid) -> %% Needs error handling for external API call(Pid, renegotiate). + +%%-------------------------------------------------------------------- +-spec peer_renegotiate(pid()) -> {ok, WriteState::map()} | {error, term()}. +%% Description: So TLS connection process can synchronize the +%% encryption state to be used when handshaking. +%%-------------------------------------------------------------------- +peer_renegotiate(Pid) -> + gen_statem:call(Pid, renegotiate, ?DEFAULT_TIMEOUT). + %%-------------------------------------------------------------------- -spec update_connection_state(pid(), WriteState::map(), tls_record:tls_version()) -> ok. %% Description: So TLS connection process can synchronize the |