aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssl/src/tls_connection.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ssl/src/tls_connection.erl')
-rw-r--r--lib/ssl/src/tls_connection.erl70
1 files changed, 54 insertions, 16 deletions
diff --git a/lib/ssl/src/tls_connection.erl b/lib/ssl/src/tls_connection.erl
index adb4f6d9ea..8ded2cbff7 100644
--- a/lib/ssl/src/tls_connection.erl
+++ b/lib/ssl/src/tls_connection.erl
@@ -38,7 +38,8 @@
-include("ssl_api.hrl").
-include("ssl_internal.hrl").
-include("ssl_srp.hrl").
--include_lib("public_key/include/public_key.hrl").
+-include_lib("public_key/include/public_key.hrl").
+-include_lib("kernel/include/logger.hrl").
%% Internal application API
@@ -152,6 +153,7 @@ next_record(#state{protocol_buffers =
= Buffers,
connection_states = ConnStates0,
ssl_options = #ssl_options{padding_check = Check}} = State) ->
+
case tls_record:decode_cipher_text(CT, ConnStates0, Check) of
{Plain, ConnStates} ->
{Plain, State#state{protocol_buffers =
@@ -289,9 +291,19 @@ send_handshake(Handshake, State) ->
queue_handshake(Handshake, #state{negotiated_version = Version,
tls_handshake_history = Hist0,
flight_buffer = Flight0,
- connection_states = ConnectionStates0} = State0) ->
+ connection_states = ConnectionStates0,
+ ssl_options = SslOpts} = State0) ->
{BinHandshake, ConnectionStates, Hist} =
encode_handshake(Handshake, Version, ConnectionStates0, Hist0),
+ Report = #{direction => outbound,
+ protocol => 'tls_record',
+ message => BinHandshake},
+ HandshakeMsg = #{direction => outbound,
+ protocol => 'handshake',
+ message => Handshake},
+ ssl_logger:debug(SslOpts#ssl_options.log_level, HandshakeMsg, #{domain => [otp,ssl,handshake]}),
+ ssl_logger:debug(SslOpts#ssl_options.log_level, Report, #{domain => [otp,ssl,tls_record]}),
+
State0#state{connection_states = ConnectionStates,
tls_handshake_history = Hist,
flight_buffer = Flight0 ++ [BinHandshake]}.
@@ -303,10 +315,15 @@ send_handshake_flight(#state{socket = Socket,
{State0#state{flight_buffer = []}, []}.
queue_change_cipher(Msg, #state{negotiated_version = Version,
- flight_buffer = Flight0,
- connection_states = ConnectionStates0} = State0) ->
+ flight_buffer = Flight0,
+ connection_states = ConnectionStates0,
+ ssl_options = SslOpts} = State0) ->
{BinChangeCipher, ConnectionStates} =
encode_change_cipher(Msg, Version, ConnectionStates0),
+ Report = #{direction => outbound,
+ protocol => 'tls_record',
+ message => BinChangeCipher},
+ ssl_logger:debug(SslOpts#ssl_options.log_level, Report, #{domain => [otp,ssl,tls_record]}),
State0#state{connection_states = ConnectionStates,
flight_buffer = Flight0 ++ [BinChangeCipher]}.
@@ -326,8 +343,8 @@ 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(#client_hello{extensions = #{sni := SNI}}) ->
+ SNI;
select_sni_extension(_) ->
undefined.
@@ -337,6 +354,7 @@ empty_connection_state(ConnectionEnd, BeastMitigation) ->
%%====================================================================
%% Alert and close handling
%%====================================================================
+
%%--------------------------------------------------------------------
-spec encode_alert(#alert{}, ssl_record:ssl_version(), ssl_record:connection_states()) ->
{iolist(), ssl_record:connection_states()}.
@@ -349,10 +367,14 @@ encode_alert(#alert{} = Alert, Version, ConnectionStates) ->
send_alert(Alert, #state{negotiated_version = Version,
socket = Socket,
transport_cb = Transport,
- connection_states = ConnectionStates0} = StateData0) ->
- {BinMsg, ConnectionStates} =
- encode_alert(Alert, Version, ConnectionStates0),
+ connection_states = ConnectionStates0,
+ ssl_options = SslOpts} = StateData0) ->
+ {BinMsg, ConnectionStates} = encode_alert(Alert, Version, ConnectionStates0),
send(Transport, Socket, BinMsg),
+ Report = #{direction => outbound,
+ protocol => 'tls_record',
+ message => BinMsg},
+ ssl_logger:debug(SslOpts#ssl_options.log_level, Report, #{domain => [otp,ssl,tls_record]}),
StateData0#state{connection_states = ConnectionStates}.
%% If an ALERT sent in the connection state, should cause the TLS
@@ -469,6 +491,14 @@ init({call, From}, {start, Timeout},
{BinMsg, ConnectionStates, Handshake} =
encode_handshake(Hello, HelloVersion, ConnectionStates0, Handshake0),
send(Transport, Socket, BinMsg),
+ Report = #{direction => outbound,
+ protocol => 'tls_record',
+ message => BinMsg},
+ HelloMsg = #{direction => outbound,
+ protocol => 'handshake',
+ message => Hello},
+ ssl_logger:debug(SslOpts#ssl_options.log_level, HelloMsg, #{domain => [otp,ssl,handshake]}),
+ ssl_logger:debug(SslOpts#ssl_options.log_level, Report, #{domain => [otp,ssl,tls_record]}),
State1 = State0#state{connection_states = ConnectionStates,
negotiated_version = Version, %% Requested version
session =
@@ -506,13 +536,13 @@ hello(internal, #client_hello{extensions = Extensions} = Hello,
start_or_recv_from = From} = State) ->
{next_state, user_hello, State#state{start_or_recv_from = undefined,
hello = Hello},
- [{reply, From, {ok, ssl_connection:map_extensions(Extensions)}}]};
+ [{reply, From, {ok, Extensions}}]};
hello(internal, #server_hello{extensions = Extensions} = Hello,
#state{ssl_options = #ssl_options{handshake = hello},
start_or_recv_from = From} = State) ->
{next_state, user_hello, State#state{start_or_recv_from = undefined,
hello = Hello},
- [{reply, From, {ok, ssl_connection:map_extensions(Extensions)}}]};
+ [{reply, From, {ok, Extensions}}]};
hello(internal, #client_hello{client_version = ClientVersion} = Hello,
#state{connection_states = ConnectionStates0,
port = Port, session = #session{own_certificate = Cert} = Session0,
@@ -742,11 +772,11 @@ initialize_tls_sender(#state{role = Role,
next_tls_record(Data, StateName, #state{protocol_buffers =
#protocol_buffers{tls_record_buffer = Buf0,
- tls_cipher_texts = CT0} = Buffers}
- = State0) ->
- case tls_record:get_tls_records(Data,
+ tls_cipher_texts = CT0} = Buffers,
+ ssl_options = SslOpts} = State0) ->
+ case tls_record:get_tls_records(Data,
acceptable_record_versions(StateName, State0),
- Buf0) of
+ Buf0, SslOpts) of
{Records, Buf1} ->
CT1 = CT0 ++ Records,
next_record(State0#state{protocol_buffers =
@@ -757,10 +787,18 @@ next_tls_record(Data, StateName, #state{protocol_buffers =
end.
+%% TLS 1.3 Client/Server
+%% - Ignore TLSPlaintext.legacy_record_version
+%% - Verify that TLSCiphertext.legacy_record_version is set to 0x0303 for all records
+%% other than an initial ClientHello, where it MAY also be 0x0301.
acceptable_record_versions(hello, _) ->
- [tls_record:protocol_version(Vsn) || Vsn <- ?ALL_AVAILABLE_VERSIONS];
+ [tls_record:protocol_version(Vsn) || Vsn <- ?ALL_TLS_RECORD_VERSIONS];
+acceptable_record_versions(_, #state{negotiated_version = {Major, Minor}})
+ when Major > 3; Major =:= 3, Minor >= 4 ->
+ [{3, 3}];
acceptable_record_versions(_, #state{negotiated_version = Version}) ->
[Version].
+
handle_record_alert(Alert, _) ->
Alert.