Skip to content

Commit 5c69e0b

Browse files
committed
ssl: Avoid sending internal message to client
When key_update is initiated by the TLS sender process, and not by the peer, no internal ack is needed for post_handshake_data event to the reciver process. Previously an ack message was incorrectly sent to socket user process instead of just doing nothing when that happened. closes #10273
1 parent 940ec0f commit 5c69e0b

File tree

3 files changed

+50
-25
lines changed

3 files changed

+50
-25
lines changed

lib/ssl/src/ssl_trace.erl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,7 @@ trace_profiles() ->
489489
fun(M, F, A) -> dbg:ctpl(M, F, A) end,
490490
[{tls_gen_connection_1_3, [{handle_key_update, 2}]},
491491
{tls_sender, [{init, 3}, {time_to_rekey, 6},
492-
{send_post_handshake_data, 4}]},
492+
{send_post_handshake_data, 5}]},
493493
{tls_v1, [{update_traffic_secret, 2}]}]},
494494
{rle, %% role
495495
fun(M, F, A) -> dbg:tpl(M, F, A, x) end,

lib/ssl/src/tls_sender.erl

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ connection({call, From}, {application_data, AppData},
289289
send_application_data(Data, From, connection, StateData)
290290
end;
291291
connection({call, From}, {post_handshake_data, HSData}, StateData) ->
292-
send_post_handshake_data(HSData, From, connection, StateData);
292+
send_post_handshake_data(HSData, From, connection, StateData, [{reply, From, ok}]);
293293
connection({call, From}, {ack_alert, #alert{} = Alert}, StateData0) ->
294294
StateData = send_tls_alert(Alert, StateData0),
295295
{next_state, connection, StateData,
@@ -340,7 +340,7 @@ connection({call, From}, get_application_traffic_secret, #data{env = #env{num_ke
340340
connection(internal, {application_packets, From, Data}, StateData) ->
341341
send_application_data(Data, From, connection, StateData);
342342
connection(internal, {post_handshake_data, From, HSData}, StateData) ->
343-
send_post_handshake_data(HSData, From, connection, StateData);
343+
send_post_handshake_data(HSData, From, connection, StateData, []);
344344
connection(cast, #alert{} = Alert, StateData0) ->
345345
StateData = send_tls_alert(Alert, StateData0),
346346
{next_state, connection, StateData};
@@ -439,6 +439,9 @@ death_row(_Type, _Msg, _StateData) ->
439439
keep_state_and_data.
440440

441441
%% State entry function that starts shutdown state_timeout
442+
%% distribution otherwise shuts down the sender
443+
death_row_shutdown(Reason, #data{env = #env{dist_handle = false}} = StateData) ->
444+
{stop, {shutdown, Reason}, StateData};
442445
death_row_shutdown(Reason, StateData) ->
443446
{next_state, death_row, StateData, [{state_timeout, 5000, Reason}]}.
444447

@@ -532,7 +535,7 @@ send_application_data(Data, From, StateName,
532535
case time_to_rekey(Version, DataSz, ConnectionStates0, RenegotiateAt, KeyUpdateAt, BytesSent) of
533536
key_update ->
534537
KeyUpdate = tls_handshake_1_3:key_update(update_requested),
535-
{keep_state_and_data, [{next_event, internal, {post_handshake_data, From, KeyUpdate}},
538+
{keep_state_and_data, [{next_event, internal, {post_handshake_data, undefined, KeyUpdate}},
536539
{next_event, internal, {application_packets, From, Data}}]};
537540
renegotiate ->
538541
tls_dtls_gen_connection:internal_renegotiation(Pid, ConnectionStates0),
@@ -542,8 +545,8 @@ send_application_data(Data, From, StateName,
542545
KeyUpdate = tls_handshake_1_3:key_update(update_requested),
543546
%% Prevent infinite loop of key updates
544547
{Chunk, Rest} = split_binary(iolist_to_binary(Data), KeyUpdateAt),
545-
{keep_state_and_data, [{next_event, internal, {post_handshake_data, From, KeyUpdate}},
546-
{next_event, internal, {application_packets, From, [Chunk]}},
548+
{keep_state_and_data, [{next_event, internal, {post_handshake_data, undefined, KeyUpdate}},
549+
{next_event, internal, {application_packets, undefined, [Chunk]}},
547550
{next_event, internal, {application_packets, From, [Rest]}}]};
548551
false ->
549552
{Msgs, ConnectionStates} = tls_record:encode_data(Data, Version, ConnectionStates0),
@@ -552,29 +555,29 @@ send_application_data(Data, From, StateName,
552555
ssl_logger:debug(LogLevel, outbound, 'record', Msgs),
553556
StateData1 = update_bytes_sent(Version, ConnectionStates, StateData0, DataSz),
554557
hibernate_after(StateName, StateData1, []);
555-
Reason when DistHandle =/= undefined ->
556-
StateData = StateData0#data{connection_states = ConnectionStates},
557-
death_row_shutdown(Reason, StateData);
558558
ok ->
559559
ssl_logger:debug(LogLevel, outbound, 'record', Msgs),
560560
StateData = update_bytes_sent(Version, ConnectionStates, StateData0, DataSz),
561-
gen_statem:reply(From, ok),
561+
send_reply(From, ok),
562562
hibernate_after(StateName, StateData, []);
563563
Result ->
564-
gen_statem:reply(From, Result),
564+
send_reply(From, Result),
565565
StateData = StateData0#data{connection_states = ConnectionStates},
566566
hibernate_after(StateName, StateData, [])
567567
end
568568
end.
569569

570+
send_reply(undefined, _Msg) -> ok;
571+
send_reply(From, Msg) -> gen_statem:reply(From, Msg).
572+
570573
%% TLS 1.3 Post Handshake Data
571-
send_post_handshake_data(Handshake, From, StateName,
574+
send_post_handshake_data(Handshake, _From, StateName,
572575
#data{env = #env{socket = Socket,
573-
dist_handle = DistHandle,
574-
negotiated_version = Version,
575-
transport_cb = Transport,
576-
log_level = LogLevel},
577-
connection_states = ConnectionStates0} = StateData0) ->
576+
dist_handle = DistHandle,
577+
negotiated_version = Version,
578+
transport_cb = Transport,
579+
log_level = LogLevel},
580+
connection_states = ConnectionStates0} = StateData0, AckAction) ->
578581
BinHandshake = tls_handshake:encode_handshake(Handshake, Version),
579582
{Encoded, ConnectionStates} =
580583
tls_record:encode_handshake(BinHandshake, Version, ConnectionStates0),
@@ -584,15 +587,13 @@ send_post_handshake_data(Handshake, From, StateName,
584587
ok when DistHandle =/= undefined ->
585588
ssl_logger:debug(LogLevel, outbound, 'record', Encoded),
586589
StateData = maybe_update_cipher_key(StateData1, Handshake),
587-
{next_state, StateName, StateData, []};
588-
Reason when DistHandle =/= undefined ->
589-
death_row_shutdown(Reason, StateData1);
590+
{next_state, StateName, StateData, AckAction};
590591
ok ->
591592
ssl_logger:debug(LogLevel, outbound, 'record', Encoded),
592593
StateData = maybe_update_cipher_key(StateData1, Handshake),
593-
{next_state, StateName, StateData, [{reply, From, ok}]};
594-
Result ->
595-
{next_state, StateName, StateData1, [{reply, From, Result}]}
594+
{next_state, StateName, StateData, AckAction};
595+
{error, Reason} ->
596+
death_row_shutdown(Reason, StateData1)
596597
end.
597598

598599
maybe_update_cipher_key(#data{connection_states = ConnectionStates0,

lib/ssl/test/ssl_key_update_SUITE.erl

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@
4141
keylog_client_cb/0,
4242
keylog_client_cb/1,
4343
keylog_server_cb/0,
44-
keylog_server_cb/1
44+
keylog_server_cb/1,
45+
key_update_unexpected_msg/0,
46+
key_update_unexpected_msg/1
4547
]).
4648

4749
-include("ssl_test_lib.hrl").
@@ -59,7 +61,8 @@ tls_1_3_tests() ->
5961
key_update_at_server,
6062
explicit_key_update,
6163
keylog_client_cb,
62-
keylog_server_cb].
64+
keylog_server_cb,
65+
key_update_unexpected_msg].
6366

6467
init_per_suite(Config0) ->
6568
case application:ensure_started(crypto) of
@@ -198,6 +201,27 @@ keylog_server_cb(Config) ->
198201
end,
199202
ok = traffic_secret_1_and_2([{client,1}, {client, 2}, {server,1}, {server, 2}]).
200203

204+
key_update_unexpected_msg() ->
205+
[{doc,"Test that internla sync messages are not sent to socket user"}].
206+
key_update_unexpected_msg(Config) ->
207+
Data = "123456789012345", %% 15 bytes
208+
Server = ssl_test_lib:start_server(erlang,[], Config),
209+
Port = ssl_test_lib:inet_port(Server),
210+
211+
{ok, Socket} = ssl:connect(net_adm:localhost(), Port, [{verify, verify_none}, {key_update_at, 9}]),
212+
213+
ok = ssl:send(Socket, Data),
214+
215+
receive
216+
{_, ok} = Msg ->
217+
ct:fail({unexpected_message, Msg})
218+
after 500 ->
219+
ok
220+
end.
221+
222+
%%--------------------------------------------------------------------
223+
%% Internal functions -----------------------------------------------
224+
%%--------------------------------------------------------------------
201225
traffic_secret_1_and_2([]) ->
202226
ok;
203227
traffic_secret_1_and_2([_|_] = List) ->

0 commit comments

Comments
 (0)