aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPéter Dimitrov <[email protected]>2019-02-22 09:13:05 +0100
committerPéter Dimitrov <[email protected]>2019-02-22 09:13:05 +0100
commit4327304462128ce983de8e962f683e702a80f64e (patch)
tree5617c314320d146b34da17f90afb07d17a551563
parent6cfe2e6b8cff310a6a87cea2d6366457c9e8b415 (diff)
parenta7c2d09f1f3e2aa1db6c2b83baf5267655507ce1 (diff)
downloadotp-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.erl36
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 =