From c3e98b376063718cae7937784a8bada230ff2429 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A9ter=20Dimitrov?= <peterdmv@erlang.org>
Date: Wed, 30 Jan 2019 17:03:00 +0100
Subject: ssl: Improve TLS 1.3 statem

- Store FinishedKey in cipher_state.
- Implement state 'wait_finished'.
- Calculate traffic secrets in 'wait_finished' after Finished
  received from client and go to state 'Connection'.
- Drop 'change_cipher_spec' messages (middlebox compatibility mode).
- Extend tests of 1-RTT.

Change-Id: Id69619ec5da053ffaaef75378678a27afeef6916
---
 lib/ssl/src/tls_connection_1_3.erl | 33 ++++++++++++++++++++++++++-------
 1 file changed, 26 insertions(+), 7 deletions(-)

(limited to 'lib/ssl/src/tls_connection_1_3.erl')

diff --git a/lib/ssl/src/tls_connection_1_3.erl b/lib/ssl/src/tls_connection_1_3.erl
index 48b3ff0d97..621e86f4b5 100644
--- a/lib/ssl/src/tls_connection_1_3.erl
+++ b/lib/ssl/src/tls_connection_1_3.erl
@@ -109,7 +109,8 @@
 
 %% gen_statem helper functions
 -export([start/4,
-         negotiated/4
+         negotiated/4,
+         wait_finished/4
         ]).
 
 start(internal,
@@ -135,20 +136,38 @@ start(internal,
     end.
 
 
-%% TODO: remove suppression when function implemented!
--dialyzer([{nowarn_function, [negotiated/4]}, no_match]).
 negotiated(internal, Map, State0, _Module) ->
     case tls_handshake_1_3:do_negotiated(Map, State0) of
         #alert{} = Alert ->
             ssl_connection:handle_own_alert(Alert, {3,4}, negotiated, State0);
-        M ->
-            %% TODO: implement update_state
-            %% State = update_state(State0, M),
-            {next_state, wait_flight2, State0, [{next_event, internal, M}]}
+        State ->
+            {next_state, wait_finished, State, []}
 
     end.
 
 
+wait_finished(internal,
+             #change_cipher_spec{} = ChangeCipherSpec, State0, _Module) ->
+    case tls_handshake_1_3:do_wait_finished(ChangeCipherSpec, State0) of
+        #alert{} = Alert ->
+            ssl_connection:handle_own_alert(Alert, {3,4}, wait_finished, State0);
+        State1 ->
+            {Record, State} = tls_connection:next_record(State1),
+            tls_connection:next_event(?FUNCTION_NAME, Record, State)
+    end;
+wait_finished(internal,
+             #finished{} = Finished, State0, Module) ->
+    case tls_handshake_1_3:do_wait_finished(Finished, State0) of
+        #alert{} = Alert ->
+            ssl_connection:handle_own_alert(Alert, {3,4}, finished, State0);
+        State1 ->
+            {Record, State} = ssl_connection:prepare_connection(State1, Module),
+            tls_connection:next_event(connection, Record, State)
+    end;
+wait_finished(Type, Msg, State, Connection) ->
+    ssl_connection:handle_common_event(Type, Msg, ?FUNCTION_NAME, State, Connection).
+
+
 update_state(#state{connection_states = ConnectionStates0,
                     session = Session} = State,
              #{cipher := Cipher,
-- 
cgit v1.2.3