aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssl/src
diff options
context:
space:
mode:
authorPéter Dimitrov <[email protected]>2019-01-24 16:58:01 +0100
committerPéter Dimitrov <[email protected]>2019-01-28 09:51:43 +0100
commit8dd9c18629be297b0ed5178630076882dd8b8880 (patch)
treed226151229c8438ce08442db0168be11a82473af /lib/ssl/src
parent117e475be14f92c74c6e6e90d5c6c047df49c7c9 (diff)
downloadotp-8dd9c18629be297b0ed5178630076882dd8b8880.tar.gz
otp-8dd9c18629be297b0ed5178630076882dd8b8880.tar.bz2
otp-8dd9c18629be297b0ed5178630076882dd8b8880.zip
ssl: Add 'Finished'
Implement Finished message on the server side. Change-Id: Ie0d054ac80f7eb47797273e1878990335112e923
Diffstat (limited to 'lib/ssl/src')
-rw-r--r--lib/ssl/src/tls_handshake_1_3.erl30
-rw-r--r--lib/ssl/src/tls_v1.erl21
2 files changed, 46 insertions, 5 deletions
diff --git a/lib/ssl/src/tls_handshake_1_3.erl b/lib/ssl/src/tls_handshake_1_3.erl
index 8ff58b841d..453894e8b3 100644
--- a/lib/ssl/src/tls_handshake_1_3.erl
+++ b/lib/ssl/src/tls_handshake_1_3.erl
@@ -139,6 +139,23 @@ certificate_verify(PrivateKey, SignatureScheme,
signature = Signature
}.
+finished(#state{connection_states = ConnectionStates,
+ handshake_env =
+ #handshake_env{
+ tls_handshake_history = {Messages, _}}}) ->
+ #{security_parameters := SecParamsR} =
+ ssl_record:current_connection_state(ConnectionStates, write),
+ #security_parameters{prf_algorithm = HKDFAlgo,
+ master_secret = SHTS} = SecParamsR,
+
+ FinishedKey = tls_v1:finished_key(SHTS, HKDFAlgo),
+ VerifyData = tls_v1:finished_verify_data(FinishedKey, HKDFAlgo, Messages),
+
+ #finished{
+ verify_data = VerifyData
+ }.
+
+
%%====================================================================
%% Encode handshake
%%====================================================================
@@ -464,10 +481,14 @@ do_negotiated(#{client_share := ClientKey,
%% Create CertificateVerify
CertificateVerify = certificate_verify(CertPrivateKey, SignatureScheme,
State5, server),
-
%% Encode CertificateVerify
- %% Send Certificate, CertifricateVerify
- {_State6, _} = tls_connection:send_handshake(CertificateVerify, State5),
+ State6 = tls_connection:queue_handshake(CertificateVerify, State5),
+
+ %% Create Finished
+ Finished = finished(State6),
+
+ %% Encode Certificate, CertifricateVerify
+ {_State7, _} = tls_connection:send_handshake(Finished, State6),
%% Send finished
@@ -532,7 +553,8 @@ calculate_security_parameters(ClientKey, SelectedGroup, KeyShare,
{ReadKey, ReadIV} = tls_v1:calculate_traffic_keys(HKDFAlgo, Cipher, ClientHSTrafficSecret),
{WriteKey, WriteIV} = tls_v1:calculate_traffic_keys(HKDFAlgo, Cipher, ServerHSTrafficSecret),
- {HandshakeSecret, ReadKey, ReadIV, WriteKey, WriteIV}.
+ %% TODO: store all relevant secrets in state!
+ {ServerHSTrafficSecret, ReadKey, ReadIV, WriteKey, WriteIV}.
%% %% Update pending connection state
%% PendingRead0 = ssl_record:pending_connection_state(ConnectionStates, read),
diff --git a/lib/ssl/src/tls_v1.erl b/lib/ssl/src/tls_v1.erl
index d1a62696cc..5c023bd2d8 100644
--- a/lib/ssl/src/tls_v1.erl
+++ b/lib/ssl/src/tls_v1.erl
@@ -44,7 +44,7 @@
client_application_traffic_secret_0/3, server_application_traffic_secret_0/3,
exporter_master_secret/3, resumption_master_secret/3,
update_traffic_secret/2, calculate_traffic_keys/3,
- transcript_hash/2]).
+ transcript_hash/2, finished_key/2, finished_verify_data/3]).
-type named_curve() :: sect571r1 | sect571k1 | secp521r1 | brainpoolP512r1 |
sect409k1 | sect409r1 | brainpoolP384r1 | secp384r1 |
@@ -374,6 +374,25 @@ exporter_master_secret(Algo, {master_secret, Secret}, M) ->
resumption_master_secret(Algo, {master_secret, Secret}, M) ->
derive_secret(Secret, <<"res master">>, M, Algo).
+-spec finished_key(binary(), atom()) -> binary().
+finished_key(BaseKey, Algo) ->
+ %% finished_key =
+ %% HKDF-Expand-Label(BaseKey, "finished", "", Hash.length)
+ ssl_cipher:hash_size(Algo),
+ hkdf_expand_label(BaseKey, <<"finished">>, <<>>, ssl_cipher:hash_size(Algo), Algo).
+
+-spec finished_verify_data(binary(), atom(), iodata()) -> binary().
+finished_verify_data(FinishedKey, HKDFAlgo, Messages) ->
+ %% The verify_data value is computed as follows:
+ %%
+ %% verify_data =
+ %% HMAC(finished_key,
+ %% Transcript-Hash(Handshake Context,
+ %% Certificate*, CertificateVerify*))
+ Context = lists:reverse(Messages),
+ THash = tls_v1:transcript_hash(Context, HKDFAlgo),
+ tls_v1:hmac_hash(HKDFAlgo, FinishedKey, THash).
+
%% The next-generation application_traffic_secret is computed as:
%%
%% application_traffic_secret_N+1 =