From 8e661fffd7c033ac135f3549d96f13b5a1cd9427 Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin Date: Wed, 9 Aug 2023 11:22:33 +0200 Subject: [PATCH] ssl: Handle an active socket in pre TLS-1.3 renegotiation rejection Closes #7431 --- lib/ssl/src/ssl_gen_statem.erl | 9 +++++--- lib/ssl/test/ssl_renegotiate_SUITE.erl | 32 ++++++++++++++++++++++++-- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/lib/ssl/src/ssl_gen_statem.erl b/lib/ssl/src/ssl_gen_statem.erl index caa6c6742d38..44fa9c9b03f9 100644 --- a/lib/ssl/src/ssl_gen_statem.erl +++ b/lib/ssl/src/ssl_gen_statem.erl @@ -977,10 +977,11 @@ handle_normal_shutdown(Alert, StateName, #state{static_env = #static_env{role = protocol_cb = Connection, trackers = Trackers}, connection_env = #connection_env{user_application = {_Mon, Pid}}, + handshake_env = #handshake_env{renegotiation = Type}, socket_options = Opts, start_or_recv_from = RecvFrom} = State) -> Pids = Connection:pids(State), - alert_user(Pids, Transport, Trackers, Socket, StateName, Opts, Pid, RecvFrom, Alert, Role, StateName, Connection). + alert_user(Pids, Transport, Trackers, Socket, Type, Opts, Pid, RecvFrom, Alert, Role, StateName, Connection). handle_alert(#alert{level = ?FATAL} = Alert0, StateName, #state{static_env = #static_env{role = Role, @@ -1782,9 +1783,11 @@ send_user(Pid, Msg) -> Pid ! Msg, ok. -alert_user(Pids, Transport, Trackers, Socket, connection, Opts, Pid, From, Alert, Role, StateName, Connection) -> +alert_user(Pids, Transport, Trackers, Socket, _, Opts, Pid, From, Alert, Role, connection = StateName, Connection) -> alert_user(Pids, Transport, Trackers, Socket, Opts#socket_options.active, Pid, From, Alert, Role, StateName, Connection); -alert_user(Pids, Transport, Trackers, Socket,_, _, _, From, Alert, Role, StateName, Connection) -> +alert_user(Pids, Transport, Trackers, Socket, {true, internal}, Opts, Pid, From, Alert, Role, StateName, Connection) -> + alert_user(Pids, Transport, Trackers, Socket, Opts#socket_options.active, Pid, From, Alert, Role, StateName, Connection); +alert_user(Pids, Transport, Trackers, Socket, _, _, _, From, Alert, Role, StateName, Connection) -> alert_user(Pids, Transport, Trackers, Socket, From, Alert, Role, StateName, Connection). alert_user(Pids, Transport, Trackers, Socket, From, Alert, Role, StateName, Connection) -> diff --git a/lib/ssl/test/ssl_renegotiate_SUITE.erl b/lib/ssl/test/ssl_renegotiate_SUITE.erl index 4b4686341585..ab3d837676f1 100644 --- a/lib/ssl/test/ssl_renegotiate_SUITE.erl +++ b/lib/ssl/test/ssl_renegotiate_SUITE.erl @@ -60,7 +60,9 @@ renegotiate_dos_mitigate_passive/0, renegotiate_dos_mitigate_passive/1, renegotiate_dos_mitigate_absolute/0, - renegotiate_dos_mitigate_absolute/1 + renegotiate_dos_mitigate_absolute/1, + active_error_disallowed_client_renegotiate/0, + active_error_disallowed_client_renegotiate/1 ]). %% Apply export @@ -105,7 +107,8 @@ renegotiate_tests() -> server_no_wrap_sequence_number, renegotiate_dos_mitigate_active, renegotiate_dos_mitigate_passive, - renegotiate_dos_mitigate_absolute]. + renegotiate_dos_mitigate_absolute, + active_error_disallowed_client_renegotiate]. ssl3_renegotiate_tests() -> [client_renegotiate, @@ -477,6 +480,31 @@ renegotiate_dos_mitigate_absolute(Config) when is_list(Config) -> ssl_test_lib:close(Server), ssl_test_lib:close(Client). +%%-------------------------------------------------------------------- +active_error_disallowed_client_renegotiate() -> + [{doc,"Test that an active client socket gets an error when server denies client renegotiation."}]. +active_error_disallowed_client_renegotiate(Config) when is_list(Config) -> + ServerOpts = ssl_test_lib:ssl_options(server_rsa_verify_opts, Config), + ClientOpts = ssl_test_lib:ssl_options(client_rsa_verify_opts, Config), + + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + + Server = + ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, {ssl_test_lib, no_result, []}}, + {options, [{client_renegotiation, false} | ServerOpts]}]), + Port = ssl_test_lib:inet_port(Server), + + {ok, Client} = ssl:connect(Hostname, Port, [{renegotiate_at, 1}, {active, true} | ClientOpts]), + + {error, closed} = ssl:send(Client, crypto:strong_rand_bytes(20)), + + receive + {ssl_error, Client, _} -> + ok + end. + %%-------------------------------------------------------------------- %% Internal functions ------------------------------------------------ %%--------------------------------------------------------------------