diff options
author | Péter Dimitrov <[email protected]> | 2019-02-22 09:13:05 +0100 |
---|---|---|
committer | Péter Dimitrov <[email protected]> | 2019-02-22 09:13:05 +0100 |
commit | 4327304462128ce983de8e962f683e702a80f64e (patch) | |
tree | 5617c314320d146b34da17f90afb07d17a551563 | |
parent | 6cfe2e6b8cff310a6a87cea2d6366457c9e8b415 (diff) | |
parent | a7c2d09f1f3e2aa1db6c2b83baf5267655507ce1 (diff) | |
download | otp-4327304462128ce983de8e962f683e702a80f64e.tar.gz otp-4327304462128ce983de8e962f683e702a80f64e.tar.bz2 otp-4327304462128ce983de8e962f683e702a80f64e.zip |
Merge branch 'peterdmv/ssl/validate_client_finished'
* peterdmv/ssl/validate_client_finished:
ssl: Validate Client Finished
Change-Id: I495c0d998423dc5a760d1ca0109c4107c5919f54
-rw-r--r-- | lib/ssl/src/tls_handshake_1_3.erl | 36 |
1 files changed, 32 insertions, 4 deletions
diff --git a/lib/ssl/src/tls_handshake_1_3.erl b/lib/ssl/src/tls_handshake_1_3.erl index c099e3f276..6a6de4b988 100644 --- a/lib/ssl/src/tls_handshake_1_3.erl +++ b/lib/ssl/src/tls_handshake_1_3.erl @@ -532,7 +532,7 @@ do_wait_finished(#change_cipher_spec{}, {_Ref, {state_not_implemented, State}} -> ?ALERT_REC(?FATAL, ?INTERNAL_ERROR, {state_not_implemented, State}) end; -do_wait_finished(#finished{}, +do_wait_finished(#finished{verify_data = VerifyData}, #state{connection_states = _ConnectionStates0, session = #session{session_id = _SessionId, own_certificate = _OwnCert}, @@ -546,10 +546,10 @@ do_wait_finished(#finished{}, transport_cb = _Transport} } = State0) -> - %% {Ref,Maybe} = maybe(), + {Ref,Maybe} = maybe(), try - %% TODO: validate client Finished + Maybe(validate_client_finished(State0, VerifyData)), State1 = calculate_traffic_secrets(State0), @@ -558,7 +558,9 @@ do_wait_finished(#finished{}, catch - {_Ref, {state_not_implemented, State}} -> + {Ref, decrypt_error} -> + ?ALERT_REC(?FATAL, ?DECRYPT_ERROR, decrypt_error); + {_, {state_not_implemented, State}} -> %% TODO ?ALERT_REC(?FATAL, ?INTERNAL_ERROR, {state_not_implemented, State}) end. @@ -569,6 +571,32 @@ do_wait_finished(#finished{}, %% {error, {state_not_implemented, State}}. +%% Recipients of Finished messages MUST verify that the contents are +%% correct and if incorrect MUST terminate the connection with a +%% "decrypt_error" alert. +validate_client_finished(#state{connection_states = ConnectionStates, + handshake_env = + #handshake_env{ + tls_handshake_history = {Messages0, _}}}, VerifyData) -> + #{security_parameters := SecParamsR, + cipher_state := #cipher_state{finished_key = FinishedKey}} = + ssl_record:current_connection_state(ConnectionStates, read), + #security_parameters{prf_algorithm = HKDFAlgo} = SecParamsR, + + %% Drop the client's finished message, it is not part of the handshake context + %% when the client calculates its finished message. + [_|Messages] = Messages0, + + ControlData = tls_v1:finished_verify_data(FinishedKey, HKDFAlgo, Messages), + compare_verify_data(ControlData, VerifyData). + + +compare_verify_data(Data, Data) -> + ok; +compare_verify_data(_, _) -> + {error, decrypt_error}. + + calculate_handshake_secrets(ClientKey, SelectedGroup, KeyShare, #state{connection_states = ConnectionStates, handshake_env = |