aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssl/src
diff options
context:
space:
mode:
authorIngela Anderton Andin <[email protected]>2019-01-29 19:22:26 +0100
committerIngela Anderton Andin <[email protected]>2019-02-08 09:22:26 +0100
commitd689e8a2ea3557a6b7fed2f109a3a4554806a699 (patch)
tree3cad0ef3c034d34f2e93e5781c3af0c39ff964f3 /lib/ssl/src
parente8ccff6724b8bd82f4eddb6255a059b10a787722 (diff)
downloadotp-d689e8a2ea3557a6b7fed2f109a3a4554806a699.tar.gz
otp-d689e8a2ea3557a6b7fed2f109a3a4554806a699.tar.bz2
otp-d689e8a2ea3557a6b7fed2f109a3a4554806a699.zip
ssl: Add negotiated_version to connection_env
Diffstat (limited to 'lib/ssl/src')
-rw-r--r--lib/ssl/src/dtls_connection.erl66
-rw-r--r--lib/ssl/src/ssl_connection.erl141
-rw-r--r--lib/ssl/src/ssl_connection.hrl6
-rw-r--r--lib/ssl/src/tls_connection.erl56
4 files changed, 136 insertions, 133 deletions
diff --git a/lib/ssl/src/dtls_connection.erl b/lib/ssl/src/dtls_connection.erl
index a11e0a0ac6..88c4d92bab 100644
--- a/lib/ssl/src/dtls_connection.erl
+++ b/lib/ssl/src/dtls_connection.erl
@@ -251,7 +251,7 @@ handle_protocol_record(#ssl_tls{type = ?HANDSHAKE,
fragment = Data},
StateName,
#state{protocol_buffers = Buffers0,
- negotiated_version = Version} = State) ->
+ connection_env = #connection_env{negotiated_version = Version}} = State) ->
try
case dtls_handshake:get_dtls_handshake(Version, Data, Buffers0) of
{[], Buffers} ->
@@ -273,7 +273,7 @@ handle_protocol_record(#ssl_tls{type = ?CHANGE_CIPHER_SPEC, fragment = Data}, St
{next_state, StateName, State, [{next_event, internal, #change_cipher_spec{type = Data}}]};
%%% DTLS record protocol level Alert messages
handle_protocol_record(#ssl_tls{type = ?ALERT, fragment = EncAlerts}, StateName,
- #state{negotiated_version = Version} = State) ->
+ #state{connection_env = #connection_env{negotiated_version = Version}} = State) ->
case decode_alerts(EncAlerts) of
Alerts = [_|_] ->
handle_alerts(Alerts, {next_state, StateName, State});
@@ -305,7 +305,7 @@ send_handshake(Handshake, #state{connection_states = ConnectionStates} = State)
send_handshake_flight(queue_handshake(Handshake, State), Epoch).
queue_handshake(Handshake0, #state{handshake_env = #handshake_env{tls_handshake_history = Hist0} = HsEnv,
- negotiated_version = Version,
+ connection_env = #connection_env{negotiated_version = Version},
flight_buffer = #{handshakes := HsBuffer0,
change_cipher_spec := undefined,
next_sequence := Seq} = Flight0} = State) ->
@@ -316,7 +316,7 @@ queue_handshake(Handshake0, #state{handshake_env = #handshake_env{tls_handshake_
handshake_env = HsEnv#handshake_env{tls_handshake_history = Hist}};
queue_handshake(Handshake0, #state{handshake_env = #handshake_env{tls_handshake_history = Hist0} = HsEnv,
- negotiated_version = Version,
+ connection_env = #connection_env{negotiated_version = Version},
flight_buffer = #{handshakes_after_change_cipher_spec := Buffer0,
next_sequence := Seq} = Flight0} = State) ->
Handshake = dtls_handshake:encode_handshake(Handshake0, Version, Seq),
@@ -364,9 +364,9 @@ empty_connection_state(ConnectionEnd, BeastMitigation) ->
encode_alert(#alert{} = Alert, Version, ConnectionStates) ->
dtls_record:encode_alert_record(Alert, Version, ConnectionStates).
-send_alert(Alert, #state{negotiated_version = Version,
- static_env = #static_env{socket = Socket,
+send_alert(Alert, #state{static_env = #static_env{socket = Socket,
transport_cb = Transport},
+ connection_env = #connection_env{negotiated_version = Version},
connection_states = ConnectionStates0} = State0) ->
{BinMsg, ConnectionStates} =
encode_alert(Alert, Version, ConnectionStates0),
@@ -424,6 +424,7 @@ init({call, From}, {start, Timeout},
session_cache = Cache,
session_cache_cb = CacheCb},
handshake_env = #handshake_env{renegotiation = {Renegotiation, _}},
+ connection_env = CEnv,
ssl_options = SslOpts,
session = #session{own_certificate = Cert} = Session0,
connection_states = ConnectionStates0
@@ -434,15 +435,14 @@ init({call, From}, {start, Timeout},
Version = Hello#client_hello.client_version,
HelloVersion = dtls_record:hello_version(Version, SslOpts#ssl_options.versions),
- State1 = prepare_flight(State0#state{negotiated_version = Version}),
- {State2, Actions} = send_handshake(Hello, State1#state{negotiated_version = HelloVersion}),
- State3 = State2#state{negotiated_version = Version, %% Requested version
+ State1 = prepare_flight(State0#state{connection_env = CEnv#connection_env{negotiated_version = Version}}),
+ {State2, Actions} = send_handshake(Hello, State1#state{connection_env = CEnv#connection_env{negotiated_version = HelloVersion}}),
+ State3 = State2#state{connection_env = CEnv#connection_env{negotiated_version = Version}, %% RequestedVersion
session =
Session0#session{session_id = Hello#client_hello.session_id},
start_or_recv_from = From,
timer = Timer,
- flight_state = {retransmit, ?INITIAL_RETRANSMIT_TIMEOUT}
- },
+ flight_state = {retransmit, ?INITIAL_RETRANSMIT_TIMEOUT}},
{Record, State} = next_record(State3),
next_event(hello, Record, State, Actions);
init({call, _} = Type, Event, #state{static_env = #static_env{role = server,
@@ -494,6 +494,7 @@ hello(internal, #client_hello{cookie = <<>>,
transport_cb = Transport,
socket = Socket},
handshake_env = HsEnv,
+ connection_env = CEnv,
protocol_specific = #{current_cookie_secret := Secret}} = State0) ->
{ok, {IP, Port}} = dtls_socket:peername(Transport, Socket),
Cookie = dtls_handshake:cookie(Secret, IP, Port, Hello),
@@ -504,7 +505,7 @@ hello(internal, #client_hello{cookie = <<>>,
%% version 1.0 regardless of the version of TLS that is expected to be
%% negotiated.
VerifyRequest = dtls_handshake:hello_verify_request(Cookie, ?HELLO_VERIFY_REQUEST_VERSION),
- State1 = prepare_flight(State0#state{negotiated_version = Version}),
+ State1 = prepare_flight(State0#state{connection_env = CEnv#connection_env{negotiated_version = Version}}),
{State2, Actions} = send_handshake(VerifyRequest, State1),
{Record, State} = next_record(State2),
next_event(?FUNCTION_NAME, Record,
@@ -518,6 +519,7 @@ hello(internal, #hello_verify_request{cookie = Cookie}, #state{static_env = #sta
session_cache = Cache,
session_cache_cb = CacheCb},
handshake_env = #handshake_env{renegotiation = {Renegotiation, _}} = HsEnv,
+ connection_env = CEnv,
ssl_options = SslOpts,
session = #session{own_certificate = OwnCert}
= Session0,
@@ -533,7 +535,7 @@ hello(internal, #hello_verify_request{cookie = Cookie}, #state{static_env = #sta
= ssl_handshake:init_handshake_history()}}),
{State2, Actions} = send_handshake(Hello, State1),
- State = State2#state{negotiated_version = Version, %% Requested version
+ State = State2#state{connection_env = CEnv#connection_env{negotiated_version = Version}, %% Requested version
session =
Session0#session{session_id =
Hello#client_hello.session_id}},
@@ -576,8 +578,8 @@ hello(internal, #server_hello{} = Hello,
#state{
static_env = #static_env{role = client},
handshake_env = #handshake_env{renegotiation = {Renegotiation, _}},
+ connection_env = #connection_env{negotiated_version = ReqVersion},
connection_states = ConnectionStates0,
- negotiated_version = ReqVersion,
ssl_options = SslOptions} = State) ->
case dtls_handshake:hello(Hello, SslOptions, ConnectionStates0, Renegotiation) of
#alert{} = Alert ->
@@ -692,8 +694,8 @@ connection(internal, #hello_request{}, #state{static_env = #static_env{host = Ho
session_cache_cb = CacheCb
},
handshake_env = #handshake_env{ renegotiation = {Renegotiation, _}},
+ connection_env = CEnv,
session = #session{own_certificate = Cert} = Session0,
-
ssl_options = SslOpts,
connection_states = ConnectionStates0
} = State0) ->
@@ -703,7 +705,7 @@ connection(internal, #hello_request{}, #state{static_env = #static_env{host = Ho
Version = Hello#client_hello.client_version,
HelloVersion = dtls_record:hello_version(Version, SslOpts#ssl_options.versions),
State1 = prepare_flight(State0),
- {State2, Actions} = send_handshake(Hello, State1#state{negotiated_version = HelloVersion}),
+ {State2, Actions} = send_handshake(Hello, State1#state{connection_env = CEnv#connection_env{negotiated_version = HelloVersion}}),
{Record, State} =
next_record(
State2#state{flight_state = {retransmit, ?INITIAL_RETRANSMIT_TIMEOUT},
@@ -827,7 +829,7 @@ next_dtls_record(Data, StateName, #state{protocol_buffers = #protocol_buffers{
acceptable_record_versions(hello, _) ->
[dtls_record:protocol_version(Vsn) || Vsn <- ?ALL_DATAGRAM_SUPPORTED_VERSIONS];
-acceptable_record_versions(_, #state{negotiated_version = Version}) ->
+acceptable_record_versions(_, #state{connection_env = #connection_env{negotiated_version = Version}}) ->
[Version].
dtls_handshake_events(Packets) ->
@@ -846,8 +848,9 @@ decode_cipher_text(#state{protocol_buffers = #protocol_buffers{dtls_cipher_texts
{Alert, State}
end.
-dtls_version(hello, Version, #state{static_env = #static_env{role = server}} = State) ->
- State#state{negotiated_version = Version}; %%Inital version
+dtls_version(hello, Version, #state{static_env = #static_env{role = server},
+ connection_env = CEnv} = State) ->
+ State#state{connection_env = CEnv#connection_env{negotiated_version = Version}}; %%Inital version
dtls_version(_,_, State) ->
State.
@@ -858,6 +861,7 @@ handle_client_hello(#client_hello{client_version = ClientVersion} = Hello,
session_cache_cb = CacheCb},
handshake_env = #handshake_env{renegotiation = {Renegotiation, _},
negotiated_protocol = CurrentProtocol} = HsEnv,
+ connection_env = CEnv,
session = #session{own_certificate = Cert} = Session0,
key_algorithm = KeyExAlg,
ssl_options = SslOpts} = State0) ->
@@ -874,7 +878,7 @@ handle_client_hello(#client_hello{client_version = ClientVersion} = Hello,
end,
State = prepare_flight(State0#state{connection_states = ConnectionStates,
- negotiated_version = Version,
+ connection_env = CEnv#connection_env{negotiated_version = Version},
handshake_env = HsEnv#handshake_env{
hashsign_algorithm = HashSign,
client_hello_version = ClientVersion,
@@ -899,9 +903,9 @@ handle_info({Protocol, _, _, _, Data}, StateName,
handle_info({CloseTag, Socket}, StateName,
#state{static_env = #static_env{socket = Socket,
close_tag = CloseTag},
+ connection_env = #connection_env{negotiated_version = Version},
socket_options = #socket_options{active = Active},
- protocol_buffers = #protocol_buffers{dtls_cipher_texts = CTs},
- negotiated_version = Version} = State) ->
+ protocol_buffers = #protocol_buffers{dtls_cipher_texts = CTs}} = State) ->
%% Note that as of DTLS 1.2 (TLS 1.1),
%% failure to properly close a connection no longer requires that a
%% session not be resumed. This is a change from DTLS 1.0 to conform
@@ -979,7 +983,7 @@ decode_alerts(Bin) ->
ssl_alert:decode(Bin).
gen_handshake(StateName, Type, Event,
- #state{negotiated_version = Version} = State) ->
+ #state{connection_env = #connection_env{negotiated_version = Version}} = State) ->
try ssl_connection:StateName(Type, Event, State, ?MODULE) of
Result ->
Result
@@ -990,7 +994,7 @@ gen_handshake(StateName, Type, Event,
Version, StateName, State)
end.
-gen_info(Event, connection = StateName, #state{negotiated_version = Version} = State) ->
+gen_info(Event, connection = StateName, #state{connection_env = #connection_env{negotiated_version = Version}} = State) ->
try handle_info(Event, StateName, State) of
Result ->
Result
@@ -1001,7 +1005,7 @@ gen_info(Event, connection = StateName, #state{negotiated_version = Version} =
Version, StateName, State)
end;
-gen_info(Event, StateName, #state{negotiated_version = Version} = State) ->
+gen_info(Event, StateName, #state{connection_env = #connection_env{negotiated_version = Version}} = State) ->
try handle_info(Event, StateName, State) of
Result ->
Result
@@ -1065,9 +1069,9 @@ new_timeout(_) ->
send_handshake_flight(#state{static_env = #static_env{socket = Socket,
transport_cb = Transport},
- flight_buffer = #{handshakes := Flight,
+ connection_env = #connection_env{negotiated_version = Version},
+ flight_buffer = #{handshakes := Flight,
change_cipher_spec := undefined},
- negotiated_version = Version,
connection_states = ConnectionStates0} = State0, Epoch) ->
%% TODO remove hardcoded Max size
{Encoded, ConnectionStates} =
@@ -1077,10 +1081,10 @@ send_handshake_flight(#state{static_env = #static_env{socket = Socket,
send_handshake_flight(#state{static_env = #static_env{socket = Socket,
transport_cb = Transport},
+ connection_env = #connection_env{negotiated_version = Version},
flight_buffer = #{handshakes := [_|_] = Flight0,
change_cipher_spec := ChangeCipher,
handshakes_after_change_cipher_spec := []},
- negotiated_version = Version,
connection_states = ConnectionStates0} = State0, Epoch) ->
{HsBefore, ConnectionStates1} =
encode_handshake_flight(lists:reverse(Flight0), Version, 1400, Epoch, ConnectionStates0),
@@ -1091,10 +1095,10 @@ send_handshake_flight(#state{static_env = #static_env{socket = Socket,
send_handshake_flight(#state{static_env = #static_env{socket = Socket,
transport_cb = Transport},
+ connection_env = #connection_env{negotiated_version = Version},
flight_buffer = #{handshakes := [_|_] = Flight0,
change_cipher_spec := ChangeCipher,
handshakes_after_change_cipher_spec := Flight1},
- negotiated_version = Version,
connection_states = ConnectionStates0} = State0, Epoch) ->
{HsBefore, ConnectionStates1} =
encode_handshake_flight(lists:reverse(Flight0), Version, 1400, Epoch-1, ConnectionStates0),
@@ -1107,10 +1111,10 @@ send_handshake_flight(#state{static_env = #static_env{socket = Socket,
send_handshake_flight(#state{static_env = #static_env{socket = Socket,
transport_cb = Transport},
+ connection_env = #connection_env{negotiated_version = Version},
flight_buffer = #{handshakes := [],
change_cipher_spec := ChangeCipher,
handshakes_after_change_cipher_spec := Flight1},
- negotiated_version = Version,
connection_states = ConnectionStates0} = State0, Epoch) ->
{EncChangeCipher, ConnectionStates1} =
encode_change_cipher(ChangeCipher, Version, Epoch-1, ConnectionStates0),
@@ -1166,8 +1170,8 @@ send_application_data(Data, From, _StateName,
#state{static_env = #static_env{socket = Socket,
protocol_cb = Connection,
transport_cb = Transport},
+ connection_env = #connection_env{negotiated_version = Version},
handshake_env = HsEnv,
- negotiated_version = Version,
connection_states = ConnectionStates0,
ssl_options = #ssl_options{renegotiate_at = RenegotiateAt}} = State0) ->
diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl
index ea6c6f3461..99d429511a 100644
--- a/lib/ssl/src/ssl_connection.erl
+++ b/lib/ssl/src/ssl_connection.erl
@@ -574,8 +574,8 @@ handle_session(#server_hello{cipher_suite = CipherSuite,
compression_method = Compression},
Version, NewId, ConnectionStates, ProtoExt, Protocol0,
#state{session = #session{session_id = OldId},
- negotiated_version = ReqVersion,
- handshake_env = #handshake_env{negotiated_protocol = CurrentProtocol} = HsEnv} = State0) ->
+ handshake_env = #handshake_env{negotiated_protocol = CurrentProtocol} = HsEnv,
+ connection_env = #connection_env{negotiated_version = ReqVersion} = CEnv} = State0) ->
#{key_exchange := KeyAlgorithm} =
ssl_cipher_format:suite_definition(CipherSuite),
@@ -589,11 +589,11 @@ handle_session(#server_hello{cipher_suite = CipherSuite,
end,
State = State0#state{key_algorithm = KeyAlgorithm,
- negotiated_version = Version,
connection_states = ConnectionStates,
premaster_secret = PremasterSecret,
handshake_env = HsEnv#handshake_env{expecting_next_protocol_negotiation = ExpectNPN,
- negotiated_protocol = Protocol}},
+ negotiated_protocol = Protocol},
+ connection_env = CEnv#connection_env{negotiated_version = Version}},
case ssl_session:is_new(OldId, NewId) of
true ->
@@ -692,7 +692,7 @@ hello(info, Msg, State, _) ->
hello(Type, Msg, State, Connection) ->
handle_common_event(Type, Msg, ?FUNCTION_NAME, State, Connection).
-user_hello({call, From}, cancel, #state{negotiated_version = Version} = State, _) ->
+user_hello({call, From}, cancel, #state{connection_env = #connection_env{negotiated_version = Version}} = State, _) ->
gen_statem:reply(From, ok),
handle_own_alert(?ALERT_REC(?FATAL, ?USER_CANCELED, user_canceled),
Version, ?FUNCTION_NAME, State);
@@ -722,7 +722,7 @@ abbreviated(internal, #finished{verify_data = Data} = Finished,
#state{static_env = #static_env{role = server},
handshake_env = #handshake_env{tls_handshake_history = Hist,
expecting_finished = true} = HsEnv,
- negotiated_version = Version,
+ connection_env = #connection_env{negotiated_version = Version},
session = #session{master_secret = MasterSecret},
connection_states = ConnectionStates0} =
State0, Connection) ->
@@ -741,8 +741,8 @@ abbreviated(internal, #finished{verify_data = Data} = Finished,
abbreviated(internal, #finished{verify_data = Data} = Finished,
#state{static_env = #static_env{role = client},
handshake_env = #handshake_env{tls_handshake_history = Hist0},
+ connection_env = #connection_env{negotiated_version = Version},
session = #session{master_secret = MasterSecret},
- negotiated_version = Version,
connection_states = ConnectionStates0} = State0, Connection) ->
case ssl_handshake:verify_connection(ssl:tls_version(Version), Finished, server,
get_pending_prf(ConnectionStates0, write),
@@ -794,7 +794,7 @@ certify(info, Msg, State, _) ->
handle_info(Msg, ?FUNCTION_NAME, State);
certify(internal, #certificate{asn1_certificates = []},
#state{static_env = #static_env{role = server},
- negotiated_version = Version,
+ connection_env = #connection_env{negotiated_version = Version},
ssl_options = #ssl_options{verify = verify_peer,
fail_if_no_peer_cert = true}} =
State, _) ->
@@ -808,7 +808,7 @@ certify(internal, #certificate{asn1_certificates = []},
Connection:next_event(?FUNCTION_NAME, no_record, State0#state{client_certificate_requested = false});
certify(internal, #certificate{},
#state{static_env = #static_env{role = server},
- negotiated_version = Version,
+ connection_env = #connection_env{negotiated_version = Version},
ssl_options = #ssl_options{verify = verify_none}} =
State, _) ->
Alert = ?ALERT_REC(?FATAL,?UNEXPECTED_MESSAGE, unrequested_certificate),
@@ -820,7 +820,7 @@ certify(internal, #certificate{} = Cert,
cert_db = CertDbHandle,
cert_db_ref = CertDbRef,
crl_db = CRLDbInfo},
- negotiated_version = Version,
+ connection_env = #connection_env{negotiated_version = Version},
ssl_options = Opts} = State, Connection) ->
case ssl_handshake:certify(Cert, CertDbHandle, CertDbRef,
Opts, CRLDbInfo, Role, Host) of
@@ -833,7 +833,7 @@ certify(internal, #certificate{} = Cert,
certify(internal, #server_key_exchange{exchange_keys = Keys},
#state{static_env = #static_env{role = client},
handshake_env = #handshake_env{public_key_info = PubKeyInfo} = HsEnv,
- negotiated_version = Version,
+ connection_env = #connection_env{negotiated_version = Version},
key_algorithm = Alg,
session = Session,
connection_states = ConnectionStates} = State, Connection)
@@ -867,7 +867,7 @@ certify(internal, #server_key_exchange{exchange_keys = Keys},
end;
certify(internal, #certificate_request{},
#state{static_env = #static_env{role = client},
- negotiated_version = Version,
+ connection_env = #connection_env{negotiated_version = Version},
key_algorithm = Alg} = State, _)
when Alg == dh_anon; Alg == ecdh_anon;
Alg == psk; Alg == dhe_psk; Alg == ecdhe_psk; Alg == rsa_psk;
@@ -884,9 +884,9 @@ certify(internal, #certificate_request{},
certify(internal, #certificate_request{} = CertRequest,
#state{static_env = #static_env{role = client},
handshake_env = HsEnv,
+ connection_env = #connection_env{negotiated_version = Version},
session = #session{own_certificate = Cert},
- ssl_options = #ssl_options{signature_algs = SupportedHashSigns},
- negotiated_version = Version} = State, Connection) ->
+ ssl_options = #ssl_options{signature_algs = SupportedHashSigns}} = State, Connection) ->
case ssl_handshake:select_hashsign(CertRequest, Cert, SupportedHashSigns, ssl:tls_version(Version)) of
#alert {} = Alert ->
handle_own_alert(Alert, Version, ?FUNCTION_NAME, State);
@@ -899,7 +899,7 @@ certify(internal, #certificate_request{} = CertRequest,
certify(internal, #server_hello_done{},
#state{static_env = #static_env{role = client},
session = #session{master_secret = undefined},
- negotiated_version = Version,
+ connection_env = #connection_env{negotiated_version = Version},
psk_identity = PSKIdentity,
ssl_options = #ssl_options{user_lookup_fun = PSKLookup},
premaster_secret = undefined,
@@ -915,12 +915,12 @@ certify(internal, #server_hello_done{},
end;
certify(internal, #server_hello_done{},
#state{static_env = #static_env{role = client},
+ connection_env = #connection_env{negotiated_version = {Major, Minor}} = Version,
session = #session{master_secret = undefined},
ssl_options = #ssl_options{user_lookup_fun = PSKLookup},
- negotiated_version = {Major, Minor} = Version,
- psk_identity = PSKIdentity,
- premaster_secret = undefined,
- key_algorithm = Alg} = State0, Connection)
+ psk_identity = PSKIdentity,
+ premaster_secret = undefined,
+ key_algorithm = Alg} = State0, Connection)
when Alg == rsa_psk ->
Rand = ssl_cipher:random_bytes(?NUM_OF_PREMASTERSECRET_BYTES-2),
RSAPremasterSecret = <<?BYTE(Major), ?BYTE(Minor), Rand/binary>>,
@@ -936,9 +936,9 @@ certify(internal, #server_hello_done{},
%% Master secret was determined with help of server-key exchange msg
certify(internal, #server_hello_done{},
#state{static_env = #static_env{role = client},
- session = #session{master_secret = MasterSecret} = Session,
+ connection_env = #connection_env{negotiated_version = Version},
+ session = #session{master_secret = MasterSecret} = Session,
connection_states = ConnectionStates0,
- negotiated_version = Version,
premaster_secret = undefined} = State0, Connection) ->
case ssl_handshake:master_secret(ssl:tls_version(Version), Session,
ConnectionStates0, client) of
@@ -951,9 +951,9 @@ certify(internal, #server_hello_done{},
%% Master secret is calculated from premaster_secret
certify(internal, #server_hello_done{},
#state{static_env = #static_env{role = client},
+ connection_env = #connection_env{negotiated_version = Version},
session = Session0,
connection_states = ConnectionStates0,
- negotiated_version = Version,
premaster_secret = PremasterSecret} = State0, Connection) ->
case ssl_handshake:master_secret(ssl:tls_version(Version), PremasterSecret,
ConnectionStates0, client) of
@@ -973,7 +973,8 @@ certify(internal = Type, #client_key_exchange{} = Msg,
%% We expect a certificate here
handle_common_event(Type, Msg, ?FUNCTION_NAME, State, Connection);
certify(internal, #client_key_exchange{exchange_keys = Keys},
- State = #state{key_algorithm = KeyAlg, negotiated_version = Version}, Connection) ->
+ State = #state{key_algorithm = KeyAlg,
+ connection_env = #connection_env{negotiated_version = Version}}, Connection) ->
try
certify_client_key_exchange(ssl_handshake:decode_client_key(Keys, KeyAlg, ssl:tls_version(Version)),
State, Connection)
@@ -999,8 +1000,8 @@ cipher(internal, #certificate_verify{signature = Signature,
#state{static_env = #static_env{role = server},
handshake_env = #handshake_env{tls_handshake_history = Hist,
public_key_info = PubKeyInfo} = HsEnv,
+ connection_env = #connection_env{negotiated_version = Version},
key_algorithm = KexAlg,
- negotiated_version = Version,
session = #session{master_secret = MasterSecret}
} = State, Connection) ->
@@ -1020,7 +1021,7 @@ cipher(internal, #finished{},
#state{static_env = #static_env{role = server},
handshake_env = #handshake_env{expecting_next_protocol_negotiation = true,
negotiated_protocol = undefined},
- negotiated_version = Version} = State0,
+ connection_env = #connection_env{negotiated_version = Version}} = State0,
_Connection) ->
handle_own_alert(?ALERT_REC(?FATAL,?UNEXPECTED_MESSAGE), Version, ?FUNCTION_NAME, State0);
cipher(internal, #finished{verify_data = Data} = Finished,
@@ -1029,7 +1030,7 @@ cipher(internal, #finished{verify_data = Data} = Finished,
port = Port},
handshake_env = #handshake_env{tls_handshake_history = Hist,
expecting_finished = true} = HsEnv,
- negotiated_version = Version,
+ connection_env = #connection_env{negotiated_version = Version},
session = #session{master_secret = MasterSecret}
= Session0,
ssl_options = SslOpts,
@@ -1165,10 +1166,10 @@ handle_common_event(internal, {protocol_record, TLSorDTLSRecord}, StateName, Sta
handle_common_event(timeout, hibernate, _, _, _) ->
{keep_state_and_data, [hibernate]};
handle_common_event(internal, #change_cipher_spec{type = <<1>>}, StateName,
- #state{negotiated_version = Version} = State, _) ->
+ #state{connection_env = #connection_env{negotiated_version = Version}} = State, _) ->
handle_own_alert(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE), Version,
StateName, State);
-handle_common_event(_Type, Msg, StateName, #state{negotiated_version = Version} = State,
+handle_common_event(_Type, Msg, StateName, #state{connection_env = #connection_env{negotiated_version = Version}} = State,
_) ->
Alert = ?ALERT_REC(?FATAL,?UNEXPECTED_MESSAGE, {unexpected_msg, Msg}),
handle_own_alert(Alert, Version, StateName, State).
@@ -1253,7 +1254,7 @@ handle_call(get_sslsocket, From, _StateName, State, Connection) ->
handle_call({prf, Secret, Label, Seed, WantedLength}, From, _,
#state{connection_states = ConnectionStates,
- negotiated_version = Version}, _) ->
+ connection_env = #connection_env{negotiated_version = Version}}, _) ->
#{security_parameters := SecParams} =
ssl_record:current_connection_state(ConnectionStates, read),
#security_parameters{master_secret = MasterSecret,
@@ -1434,7 +1435,7 @@ connection_info(#state{static_env = #static_env{protocol_cb = Connection},
handshake_env = #handshake_env{sni_hostname = SNIHostname},
session = #session{session_id = SessionId,
cipher_suite = CipherSuite, ecc = ECCCurve},
- negotiated_version = {_,_} = Version,
+ connection_env = #connection_env{negotiated_version = {_,_} = Version},
ssl_options = Opts}) ->
RecordCB = record_cb(Connection),
CipherSuiteDef = #{key_exchange := KexAlg} = ssl_cipher_format:suite_definition(CipherSuite),
@@ -1462,7 +1463,7 @@ security_info(#state{connection_states = ConnectionStates}) ->
do_server_hello(Type, #hello_extensions{next_protocol_negotiation = NextProtocols} =
ServerHelloExt,
- #state{negotiated_version = Version,
+ #state{connection_env = #connection_env{negotiated_version = Version},
handshake_env = HsEnv,
session = #session{session_id = SessId},
connection_states = ConnectionStates0}
@@ -1483,8 +1484,8 @@ do_server_hello(Type, #hello_extensions{next_protocol_negotiation = NextProtocol
new_server_hello(#server_hello{cipher_suite = CipherSuite,
compression_method = Compression,
session_id = SessionId},
- #state{session = Session0,
- negotiated_version = Version} = State0, Connection) ->
+ #state{session = Session0,
+ connection_env = #connection_env{negotiated_version = Version}} = State0, Connection) ->
try server_certify_and_key_exchange(State0, Connection) of
#state{} = State1 ->
{State, Actions} = server_hello_done(State1, Connection),
@@ -1500,7 +1501,7 @@ new_server_hello(#server_hello{cipher_suite = CipherSuite,
resumed_server_hello(#state{session = Session,
connection_states = ConnectionStates0,
- negotiated_version = Version} = State0, Connection) ->
+ connection_env = #connection_env{negotiated_version = Version}} = State0, Connection) ->
case ssl_handshake:master_secret(ssl:tls_version(Version), Session,
ConnectionStates0, server) of
@@ -1570,8 +1571,8 @@ certify_client(#state{client_certificate_requested = false} = State, _) ->
verify_client_cert(#state{static_env = #static_env{role = client},
handshake_env = #handshake_env{tls_handshake_history = Hist,
cert_hashsign_algorithm = HashSign},
+ connection_env = #connection_env{negotiated_version = Version},
client_certificate_requested = true,
- negotiated_version = Version,
private_key = PrivateKey,
session = #session{master_secret = MasterSecret,
own_certificate = OwnCert}} = State, Connection) ->
@@ -1588,7 +1589,7 @@ verify_client_cert(#state{static_env = #static_env{role = client},
verify_client_cert(#state{client_certificate_requested = false} = State, _) ->
State.
-client_certify_and_key_exchange(#state{negotiated_version = Version} =
+client_certify_and_key_exchange(#state{connection_env = #connection_env{negotiated_version = Version}} =
State0, Connection) ->
try do_client_certify_and_key_exchange(State0, Connection) of
State1 = #state{} ->
@@ -1704,11 +1705,10 @@ key_exchange(#state{static_env = #static_env{role = server}, key_algorithm = rsa
State;
key_exchange(#state{static_env = #static_env{role = server}, key_algorithm = Algo,
handshake_env = #handshake_env{hashsign_algorithm = HashSignAlgo},
+ connection_env = #connection_env{negotiated_version = Version},
diffie_hellman_params = #'DHParameter'{} = Params,
private_key = PrivateKey,
- connection_states = ConnectionStates0,
- negotiated_version = Version
- } = State0, Connection)
+ connection_states = ConnectionStates0} = State0, Connection)
when Algo == dhe_dss;
Algo == dhe_rsa;
Algo == dh_anon ->
@@ -1732,11 +1732,10 @@ key_exchange(#state{static_env = #static_env{role = server},
session = Session#session{ecc = ECCurve}};
key_exchange(#state{static_env = #static_env{role = server}, key_algorithm = Algo,
handshake_env = #handshake_env{hashsign_algorithm = HashSignAlgo},
+ connection_env = #connection_env{negotiated_version = Version},
private_key = PrivateKey,
session = #session{ecc = ECCCurve},
- connection_states = ConnectionStates0,
- negotiated_version = Version
- } = State0, Connection)
+ connection_states = ConnectionStates0} = State0, Connection)
when Algo == ecdhe_ecdsa; Algo == ecdhe_rsa;
Algo == ecdh_anon ->
@@ -1758,10 +1757,9 @@ key_exchange(#state{static_env = #static_env{role = server}, key_algorithm = psk
key_exchange(#state{static_env = #static_env{role = server}, key_algorithm = psk,
ssl_options = #ssl_options{psk_identity = PskIdentityHint},
handshake_env = #handshake_env{hashsign_algorithm = HashSignAlgo},
+ connection_env = #connection_env{negotiated_version = Version},
private_key = PrivateKey,
- connection_states = ConnectionStates0,
- negotiated_version = Version
- } = State0, Connection) ->
+ connection_states = ConnectionStates0} = State0, Connection) ->
#{security_parameters := SecParams} =
ssl_record:pending_connection_state(ConnectionStates0, read),
#security_parameters{client_random = ClientRandom,
@@ -1775,10 +1773,10 @@ key_exchange(#state{static_env = #static_env{role = server}, key_algorithm = psk
key_exchange(#state{static_env = #static_env{role = server}, key_algorithm = dhe_psk,
ssl_options = #ssl_options{psk_identity = PskIdentityHint},
handshake_env = #handshake_env{hashsign_algorithm = HashSignAlgo},
+ connection_env = #connection_env{negotiated_version = Version},
diffie_hellman_params = #'DHParameter'{} = Params,
private_key = PrivateKey,
- connection_states = ConnectionStates0,
- negotiated_version = Version
+ connection_states = ConnectionStates0
} = State0, Connection) ->
DHKeys = public_key:generate_key(Params),
#{security_parameters := SecParams} =
@@ -1796,10 +1794,10 @@ key_exchange(#state{static_env = #static_env{role = server}, key_algorithm = dhe
key_exchange(#state{static_env = #static_env{role = server}, key_algorithm = ecdhe_psk,
ssl_options = #ssl_options{psk_identity = PskIdentityHint},
handshake_env = #handshake_env{hashsign_algorithm = HashSignAlgo},
+ connection_env = #connection_env{negotiated_version = Version},
private_key = PrivateKey,
session = #session{ecc = ECCCurve},
- connection_states = ConnectionStates0,
- negotiated_version = Version
+ connection_states = ConnectionStates0
} = State0, Connection) ->
ECDHKeys = public_key:generate_key(ECCCurve),
#{security_parameters := SecParams} =
@@ -1820,9 +1818,9 @@ key_exchange(#state{static_env = #static_env{role = server}, key_algorithm = rsa
key_exchange(#state{static_env = #static_env{role = server}, key_algorithm = rsa_psk,
ssl_options = #ssl_options{psk_identity = PskIdentityHint},
handshake_env = #handshake_env{hashsign_algorithm = HashSignAlgo},
+ connection_env = #connection_env{negotiated_version = Version},
private_key = PrivateKey,
- connection_states = ConnectionStates0,
- negotiated_version = Version
+ connection_states = ConnectionStates0
} = State0, Connection) ->
#{security_parameters := SecParams} =
ssl_record:pending_connection_state(ConnectionStates0, read),
@@ -1837,10 +1835,10 @@ key_exchange(#state{static_env = #static_env{role = server}, key_algorithm = rsa
key_exchange(#state{static_env = #static_env{role = server}, key_algorithm = Algo,
ssl_options = #ssl_options{user_lookup_fun = LookupFun},
handshake_env = #handshake_env{hashsign_algorithm = HashSignAlgo},
+ connection_env = #connection_env{negotiated_version = Version},
session = #session{srp_username = Username},
private_key = PrivateKey,
- connection_states = ConnectionStates0,
- negotiated_version = Version
+ connection_states = ConnectionStates0
} = State0, Connection)
when Algo == srp_dss;
Algo == srp_rsa;
@@ -1866,14 +1864,14 @@ key_exchange(#state{static_env = #static_env{role = server}, key_algorithm = Alg
srp_keys = Keys};
key_exchange(#state{static_env = #static_env{role = client},
handshake_env = #handshake_env{public_key_info = PublicKeyInfo},
- key_algorithm = rsa,
- negotiated_version = Version,
+ connection_env = #connection_env{negotiated_version = Version},
+ key_algorithm = rsa,
premaster_secret = PremasterSecret} = State0, Connection) ->
Msg = rsa_key_exchange(ssl:tls_version(Version), PremasterSecret, PublicKeyInfo),
Connection:queue_handshake(Msg, State0);
key_exchange(#state{static_env = #static_env{role = client},
- key_algorithm = Algorithm,
- negotiated_version = Version,
+ connection_env = #connection_env{negotiated_version = Version},
+ key_algorithm = Algorithm,
diffie_hellman_keys = {DhPubKey, _}
} = State0, Connection)
when Algorithm == dhe_dss;
@@ -1883,8 +1881,8 @@ key_exchange(#state{static_env = #static_env{role = client},
Connection:queue_handshake(Msg, State0);
key_exchange(#state{static_env = #static_env{role = client},
+ connection_env = #connection_env{negotiated_version = Version},
key_algorithm = Algorithm,
- negotiated_version = Version,
session = Session,
diffie_hellman_keys = #'ECPrivateKey'{parameters = ECCurve} = Key} = State0, Connection)
when Algorithm == ecdhe_ecdsa; Algorithm == ecdhe_rsa;
@@ -1893,16 +1891,16 @@ key_exchange(#state{static_env = #static_env{role = client},
Msg = ssl_handshake:key_exchange(client, ssl:tls_version(Version), {ecdh, Key}),
Connection:queue_handshake(Msg, State0#state{session = Session#session{ecc = ECCurve}});
key_exchange(#state{static_env = #static_env{role = client},
+ connection_env = #connection_env{negotiated_version = Version},
ssl_options = SslOpts,
- key_algorithm = psk,
- negotiated_version = Version} = State0, Connection) ->
+ key_algorithm = psk} = State0, Connection) ->
Msg = ssl_handshake:key_exchange(client, ssl:tls_version(Version),
{psk, SslOpts#ssl_options.psk_identity}),
Connection:queue_handshake(Msg, State0);
key_exchange(#state{static_env = #static_env{role = client},
+ connection_env = #connection_env{negotiated_version = Version},
ssl_options = SslOpts,
key_algorithm = dhe_psk,
- negotiated_version = Version,
diffie_hellman_keys = {DhPubKey, _}} = State0, Connection) ->
Msg = ssl_handshake:key_exchange(client, ssl:tls_version(Version),
{dhe_psk,
@@ -1910,9 +1908,9 @@ key_exchange(#state{static_env = #static_env{role = client},
Connection:queue_handshake(Msg, State0);
key_exchange(#state{static_env = #static_env{role = client},
+ connection_env = #connection_env{negotiated_version = Version},
ssl_options = SslOpts,
key_algorithm = ecdhe_psk,
- negotiated_version = Version,
diffie_hellman_keys = ECDHKeys} = State0, Connection) ->
Msg = ssl_handshake:key_exchange(client, ssl:tls_version(Version),
{ecdhe_psk,
@@ -1921,17 +1919,17 @@ key_exchange(#state{static_env = #static_env{role = client},
key_exchange(#state{static_env = #static_env{role = client},
handshake_env = #handshake_env{public_key_info = PublicKeyInfo},
+ connection_env = #connection_env{negotiated_version = Version},
ssl_options = SslOpts,
key_algorithm = rsa_psk,
- negotiated_version = Version,
premaster_secret = PremasterSecret}
= State0, Connection) ->
Msg = rsa_psk_key_exchange(ssl:tls_version(Version), SslOpts#ssl_options.psk_identity,
PremasterSecret, PublicKeyInfo),
Connection:queue_handshake(Msg, State0);
key_exchange(#state{static_env = #static_env{role = client},
+ connection_env = #connection_env{negotiated_version = Version},
key_algorithm = Algorithm,
- negotiated_version = Version,
srp_keys = {ClientPubKey, _}}
= State0, Connection)
when Algorithm == srp_dss;
@@ -1981,10 +1979,10 @@ request_client_cert(#state{key_algorithm = Alg} = State, _)
request_client_cert(#state{static_env = #static_env{cert_db = CertDbHandle,
cert_db_ref = CertDbRef},
+ connection_env = #connection_env{negotiated_version = Version},
ssl_options = #ssl_options{verify = verify_peer,
signature_algs = SupportedHashSigns},
- connection_states = ConnectionStates0,
- negotiated_version = Version} = State0, Connection) ->
+ connection_states = ConnectionStates0} = State0, Connection) ->
#{security_parameters :=
#security_parameters{cipher_suite = CipherSuite}} =
ssl_record:pending_connection_state(ConnectionStates0, read),
@@ -2001,7 +1999,7 @@ request_client_cert(#state{ssl_options = #ssl_options{verify = verify_none}} =
State.
calculate_master_secret(PremasterSecret,
- #state{negotiated_version = Version,
+ #state{connection_env = #connection_env{negotiated_version = Version},
connection_states = ConnectionStates0,
session = Session0} = State0, Connection,
_Current, Next) ->
@@ -2043,7 +2041,7 @@ cipher_protocol(State, Connection) ->
finished(#state{static_env = #static_env{role = Role},
handshake_env = #handshake_env{tls_handshake_history = Hist},
- negotiated_version = Version,
+ connection_env = #connection_env{negotiated_version = Version},
session = Session,
connection_states = ConnectionStates0} = State0,
StateName, Connection) ->
@@ -2123,8 +2121,8 @@ calculate_secret(#server_srp_params{srp_n = Prime, srp_g = Generator} = ServerKe
master_secret(#alert{} = Alert, _) ->
Alert;
master_secret(PremasterSecret, #state{static_env = #static_env{role = Role},
+ connection_env = #connection_env{negotiated_version = Version},
session = Session,
- negotiated_version = Version,
connection_states = ConnectionStates0} = State) ->
case ssl_handshake:master_secret(ssl:tls_version(Version), PremasterSecret,
ConnectionStates0, Role) of
@@ -2465,9 +2463,8 @@ handle_resumed_session(SessId, #state{static_env = #static_env{host = Host,
protocol_cb = Connection,
session_cache = Cache,
session_cache_cb = CacheCb},
- connection_states = ConnectionStates0,
- negotiated_version = Version
- } = State) ->
+ connection_env = #connection_env{negotiated_version = Version},
+ connection_states = ConnectionStates0} = State) ->
Session = CacheCb:lookup(Cache, {{Host, Port}, SessId}),
case ssl_handshake:master_secret(ssl:tls_version(Version), Session,
ConnectionStates0, client) of
diff --git a/lib/ssl/src/ssl_connection.hrl b/lib/ssl/src/ssl_connection.hrl
index 6610d79c60..f5fc8dde04 100644
--- a/lib/ssl/src/ssl_connection.hrl
+++ b/lib/ssl/src/ssl_connection.hrl
@@ -75,13 +75,14 @@
-record(connection_env, {
user_application :: {Monitor::reference(), User::pid()},
downgrade,
- terminated = false ::boolean() | closed
+ terminated = false ::boolean() | closed,
+ negotiated_version :: ssl_record:ssl_version() | 'undefined'
}).
-record(state, {
static_env :: #static_env{},
handshake_env :: #handshake_env{} | secret_printout(),
- connection_env :: #connection_env{},
+ connection_env :: #connection_env{} | secret_printout(),
%% Changed often
connection_states :: ssl_record:connection_states() | secret_printout(),
@@ -95,7 +96,6 @@
ssl_options :: #ssl_options{},
socket_options :: #socket_options{},
session :: #session{} | secret_printout(),
- negotiated_version :: ssl_record:ssl_version() | 'undefined',
%% Used only in HS
client_certificate_requested = false :: boolean(),
diff --git a/lib/ssl/src/tls_connection.erl b/lib/ssl/src/tls_connection.erl
index fd60ca0cf8..c46c371a0e 100644
--- a/lib/ssl/src/tls_connection.erl
+++ b/lib/ssl/src/tls_connection.erl
@@ -228,7 +228,7 @@ handle_protocol_record(#ssl_tls{type = ?APPLICATION_DATA, fragment = Data}, Stat
handle_protocol_record(#ssl_tls{type = ?HANDSHAKE, fragment = Data},
StateName, #state{protocol_buffers =
#protocol_buffers{tls_handshake_buffer = Buf0} = Buffers,
- negotiated_version = Version,
+ connection_env = #connection_env{negotiated_version = Version},
ssl_options = Options} = State0) ->
try
{Packets, Buf} = tls_handshake:get_tls_handshake(Version,Data,Buf0, Options),
@@ -261,7 +261,7 @@ handle_protocol_record(#ssl_tls{type = ?CHANGE_CIPHER_SPEC, fragment = Data}, St
{next_state, StateName, State, [{next_event, internal, #change_cipher_spec{type = Data}}]};
%%% TLS record protocol level Alert messages
handle_protocol_record(#ssl_tls{type = ?ALERT, fragment = EncAlerts}, StateName,
- #state{negotiated_version = Version} = State) ->
+ #state{connection_env = #connection_env{negotiated_version = Version}} = State) ->
try decode_alerts(EncAlerts) of
Alerts = [_|_] ->
handle_alerts(Alerts, {next_state, StateName, State});
@@ -296,7 +296,7 @@ renegotiate(#state{static_env = #static_env{role = server,
socket = Socket,
transport_cb = Transport},
handshake_env = HsEnv,
- negotiated_version = Version,
+ connection_env = #connection_env{negotiated_version = Version},
connection_states = ConnectionStates0} = State0, Actions) ->
HelloRequest = ssl_handshake:hello_request(),
Frag = tls_handshake:encode_handshake(HelloRequest, Version),
@@ -312,9 +312,9 @@ renegotiate(#state{static_env = #static_env{role = server,
send_handshake(Handshake, State) ->
send_handshake_flight(queue_handshake(Handshake, State)).
-queue_handshake(Handshake, #state{negotiated_version = Version,
- handshake_env = #handshake_env{tls_handshake_history = Hist0} = HsEnv,
- flight_buffer = Flight0,
+queue_handshake(Handshake, #state{handshake_env = #handshake_env{tls_handshake_history = Hist0} = HsEnv,
+ connection_env = #connection_env{negotiated_version = Version},
+ flight_buffer = Flight0,
connection_states = ConnectionStates0} = State0) ->
{BinHandshake, ConnectionStates, Hist} =
encode_handshake(Handshake, Version, ConnectionStates0, Hist0),
@@ -328,16 +328,16 @@ send_handshake_flight(#state{static_env = #static_env{socket = Socket,
send(Transport, Socket, Flight),
{State0#state{flight_buffer = []}, []}.
-queue_change_cipher(Msg, #state{negotiated_version = Version,
- flight_buffer = Flight0,
- connection_states = ConnectionStates0} = State0) ->
+queue_change_cipher(Msg, #state{connection_env = #connection_env{negotiated_version = Version},
+ flight_buffer = Flight0,
+ connection_states = ConnectionStates0} = State0) ->
{BinChangeCipher, ConnectionStates} =
encode_change_cipher(Msg, Version, ConnectionStates0),
State0#state{connection_states = ConnectionStates,
flight_buffer = Flight0 ++ [BinChangeCipher]}.
reinit(#state{protocol_specific = #{sender := Sender},
- negotiated_version = Version,
+ connection_env = #connection_env{negotiated_version = Version},
connection_states = #{current_write := Write}} = State) ->
tls_sender:update_connection_state(Sender, Write, Version),
reinit_handshake_data(State).
@@ -372,9 +372,9 @@ empty_connection_state(ConnectionEnd, BeastMitigation) ->
encode_alert(#alert{} = Alert, Version, ConnectionStates) ->
tls_record:encode_alert_record(Alert, Version, ConnectionStates).
-send_alert(Alert, #state{negotiated_version = Version,
- static_env = #static_env{socket = Socket,
+send_alert(Alert, #state{static_env = #static_env{socket = Socket,
transport_cb = Transport},
+ connection_env = #connection_env{negotiated_version = Version},
connection_states = ConnectionStates0} = StateData0) ->
{BinMsg, ConnectionStates} =
encode_alert(Alert, Version, ConnectionStates0),
@@ -465,6 +465,7 @@ init({call, From}, {start, Timeout},
session_cache = Cache,
session_cache_cb = CacheCb},
handshake_env = #handshake_env{renegotiation = {Renegotiation, _}} = HsEnv,
+ connection_env = CEnv,
ssl_options = SslOpts,
session = #session{own_certificate = Cert} = Session0,
connection_states = ConnectionStates0
@@ -480,7 +481,7 @@ init({call, From}, {start, Timeout},
encode_handshake(Hello, HelloVersion, ConnectionStates0, Handshake0),
send(Transport, Socket, BinMsg),
State = State0#state{connection_states = ConnectionStates,
- negotiated_version = Version, %% Requested version
+ connection_env = CEnv#connection_env{negotiated_version = Version}, %% Requested version
session =
Session0#session{session_id = Hello#client_hello.session_id},
handshake_env = HsEnv#handshake_env{tls_handshake_history = Handshake},
@@ -533,6 +534,7 @@ hello(internal, #client_hello{client_version = ClientVersion} = Hello,
session_cache_cb = CacheCb},
handshake_env = #handshake_env{renegotiation = {Renegotiation, _},
negotiated_protocol = CurrentProtocol} = HsEnv,
+ connection_env = CEnv,
session = #session{own_certificate = Cert} = Session0,
key_algorithm = KeyExAlg,
ssl_options = SslOpts} = State) ->
@@ -540,8 +542,8 @@ hello(internal, #client_hello{client_version = ClientVersion} = Hello,
ConnectionStates0, Cert, KeyExAlg}, Renegotiation) of
#alert{} = Alert ->
ssl_connection:handle_own_alert(Alert, ClientVersion, hello,
- State#state{negotiated_version
- = ClientVersion});
+ State#state{connection_env =
+ CEnv#connection_env{negotiated_version = ClientVersion}});
{Version, {Type, Session},
ConnectionStates, Protocol0, ServerHelloExt, HashSign} ->
Protocol = case Protocol0 of
@@ -550,7 +552,7 @@ hello(internal, #client_hello{client_version = ClientVersion} = Hello,
end,
gen_handshake(?FUNCTION_NAME, internal, {common_client_hello, Type, ServerHelloExt},
State#state{connection_states = ConnectionStates,
- negotiated_version = Version,
+ connection_env = CEnv#connection_env{negotiated_version = Version},
handshake_env = HsEnv#handshake_env{
hashsign_algorithm = HashSign,
client_hello_version = ClientVersion,
@@ -560,14 +562,14 @@ hello(internal, #client_hello{client_version = ClientVersion} = Hello,
end;
hello(internal, #server_hello{} = Hello,
#state{connection_states = ConnectionStates0,
- negotiated_version = ReqVersion,
+ connection_env = #connection_env{negotiated_version = ReqVersion} = CEnv,
static_env = #static_env{role = client},
handshake_env = #handshake_env{renegotiation = {Renegotiation, _}},
ssl_options = SslOptions} = State) ->
case tls_handshake:hello(Hello, SslOptions, ConnectionStates0, Renegotiation) of
- #alert{} = Alert ->
+ #alert{} = Alert -> %%TODO
ssl_connection:handle_own_alert(Alert, ReqVersion, hello,
- State#state{negotiated_version = ReqVersion});
+ State#state{connection_env = CEnv#connection_env{negotiated_version = ReqVersion}});
{Version, NewId, ConnectionStates, ProtoExt, Protocol} ->
ssl_connection:handle_session(Hello,
Version, NewId, ConnectionStates, ProtoExt, Protocol, State)
@@ -823,8 +825,8 @@ initialize_tls_sender(#state{static_env = #static_env{
socket = Socket,
tracker = Tracker
},
- socket_options = SockOpts,
- negotiated_version = Version,
+ connection_env = #connection_env{negotiated_version = Version},
+ socket_options = SockOpts,
ssl_options = #ssl_options{renegotiate_at = RenegotiateAt},
connection_states = #{current_write := ConnectionWriteState},
protocol_specific = #{sender := Sender}}) ->
@@ -856,7 +858,7 @@ next_tls_record(Data, StateName, #state{protocol_buffers =
end.
-acceptable_record_versions(StateName, #state{negotiated_version = Version}) when StateName =/= hello->
+acceptable_record_versions(StateName, #state{connection_env = #connection_env{negotiated_version = Version}}) when StateName =/= hello->
Version;
acceptable_record_versions(hello, _) ->
[tls_record:protocol_version(Vsn) || Vsn <- ?ALL_AVAILABLE_VERSIONS].
@@ -887,11 +889,11 @@ handle_info({tcp_passive, Socket}, StateName,
State#state{protocol_specific = PS#{active_n_toggle => true}});
handle_info({CloseTag, Socket}, StateName,
#state{static_env = #static_env{socket = Socket, close_tag = CloseTag},
+ connection_env = #connection_env{negotiated_version = Version},
socket_options = #socket_options{active = Active},
protocol_buffers = #protocol_buffers{tls_cipher_texts = CTs},
user_data_buffer = Buffer,
- protocol_specific = PS,
- negotiated_version = Version} = State) ->
+ protocol_specific = PS} = State) ->
%% Note that as of TLS 1.1,
%% failure to properly close a connection no longer requires that a
@@ -957,7 +959,7 @@ decode_alerts(Bin) ->
ssl_alert:decode(Bin).
gen_handshake(StateName, Type, Event,
- #state{negotiated_version = Version} = State) ->
+ #state{connection_env = #connection_env{negotiated_version = Version}} = State) ->
try ssl_connection:StateName(Type, Event, State, ?MODULE) of
Result ->
Result
@@ -968,7 +970,7 @@ gen_handshake(StateName, Type, Event,
Version, StateName, State)
end.
-gen_info(Event, connection = StateName, #state{negotiated_version = Version} = State) ->
+gen_info(Event, connection = StateName, #state{connection_env = #connection_env{negotiated_version = Version}} = State) ->
try handle_info(Event, StateName, State) of
Result ->
Result
@@ -979,7 +981,7 @@ gen_info(Event, connection = StateName, #state{negotiated_version = Version} =
Version, StateName, State)
end;
-gen_info(Event, StateName, #state{negotiated_version = Version} = State) ->
+gen_info(Event, StateName, #state{connection_env = #connection_env{negotiated_version = Version}} = State) ->
try handle_info(Event, StateName, State) of
Result ->
Result