diff options
author | Ingela Anderton Andin <[email protected]> | 2019-01-29 19:22:26 +0100 |
---|---|---|
committer | Ingela Anderton Andin <[email protected]> | 2019-02-08 09:22:26 +0100 |
commit | d689e8a2ea3557a6b7fed2f109a3a4554806a699 (patch) | |
tree | 3cad0ef3c034d34f2e93e5781c3af0c39ff964f3 /lib | |
parent | e8ccff6724b8bd82f4eddb6255a059b10a787722 (diff) | |
download | otp-d689e8a2ea3557a6b7fed2f109a3a4554806a699.tar.gz otp-d689e8a2ea3557a6b7fed2f109a3a4554806a699.tar.bz2 otp-d689e8a2ea3557a6b7fed2f109a3a4554806a699.zip |
ssl: Add negotiated_version to connection_env
Diffstat (limited to 'lib')
-rw-r--r-- | lib/ssl/src/dtls_connection.erl | 66 | ||||
-rw-r--r-- | lib/ssl/src/ssl_connection.erl | 141 | ||||
-rw-r--r-- | lib/ssl/src/ssl_connection.hrl | 6 | ||||
-rw-r--r-- | lib/ssl/src/tls_connection.erl | 56 |
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 |