1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2007-2020. All Rights Reserved.
5%%
6%% Licensed under the Apache License, Version 2.0 (the "License");
7%% you may not use this file except in compliance with the License.
8%% You may obtain a copy of the License at
9%%
10%%     http://www.apache.org/licenses/LICENSE-2.0
11%%
12%% Unless required by applicable law or agreed to in writing, software
13%% distributed under the License is distributed on an "AS IS" BASIS,
14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15%% See the License for the specific language governing permissions and
16%% limitations under the License.
17%%
18%% %CopyrightEnd%
19%%
20
21%%
22%%----------------------------------------------------------------------
23%% Purpose: TLS-1.3 FSM
24%%----------------------------------------------------------------------
25%%                                 INITIAL_HELLO
26%%                                  Client send
27%%                                  first ClientHello
28%%                                  |                     ---> CONFIG_ERROR
29%%                                  |                     Send error to user
30%%                                  |                     and shutdown
31%%                                  |
32%%                                  V
33%% RFC 8446
34%% A.1.  Client
35%%
36%%                               START <----+
37%%                Send ClientHello |        | Recv HelloRetryRequest
38%%           [K_send = early data] |        |
39%%                                 v        |
40%%            /                 WAIT_SH ----+
41%%            |                    | Recv ServerHello
42%%            |                    | K_recv = handshake
43%%        Can |                    V
44%%       send |                 WAIT_EE
45%%      early |                    | Recv EncryptedExtensions
46%%       data |           +--------+--------+
47%%            |     Using |                 | Using certificate
48%%            |       PSK |                 v
49%%            |           |            WAIT_CERT_CR
50%%            |           |        Recv |       | Recv CertificateRequest
51%%            |           | Certificate |       v
52%%            |           |             |    WAIT_CERT
53%%            |           |             |       | Recv Certificate
54%%            |           |             v       v
55%%            |           |              WAIT_CV
56%%            |           |                 | Recv CertificateVerify
57%%            |           +> WAIT_FINISHED <+
58%%            |                  | Recv Finished
59%%            \                  | [Send EndOfEarlyData]
60%%                               | K_send = handshake
61%%                               | [Send Certificate [+ CertificateVerify]]
62%%     Can send                  | Send Finished
63%%     app data   -->            | K_send = K_recv = application
64%%     after here                v
65%%                           CONNECTED
66%%
67%% A.2.  Server
68%%
69%%                               START <-----+
70%%                Recv ClientHello |         | Send HelloRetryRequest
71%%                                 v         |
72%%                              RECVD_CH ----+
73%%                                 | Select parameters
74%%                                 v
75%%                              NEGOTIATED
76%%                                 | Send ServerHello
77%%                                 | K_send = handshake
78%%                                 | Send EncryptedExtensions
79%%                                 | [Send CertificateRequest]
80%%  Can send                       | [Send Certificate + CertificateVerify]
81%%  app data                       | Send Finished
82%%  after   -->                    | K_send = application
83%%  here                  +--------+--------+
84%%               No 0-RTT |                 | 0-RTT
85%%                        |                 |
86%%    K_recv = handshake  |                 | K_recv = early data
87%%  [Skip decrypt errors] |    +------> WAIT_EOED -+
88%%                        |    |       Recv |      | Recv EndOfEarlyData
89%%                        |    | early data |      | K_recv = handshake
90%%                        |    +------------+      |
91%%                        |                        |
92%%                        +> WAIT_FLIGHT2 <--------+
93%%                                 |
94%%                        +--------+--------+
95%%                No auth |                 | Client auth
96%%                        |                 |
97%%                        |                 v
98%%                        |             WAIT_CERT
99%%                        |        Recv |       | Recv Certificate
100%%                        |       empty |       v
101%%                        | Certificate |    WAIT_CV
102%%                        |             |       | Recv
103%%                        |             v       | CertificateVerify
104%%                        +-> WAIT_FINISHED <---+
105%%                                 | Recv Finished
106%%                                 | K_recv = application
107%%                                 v
108%%                             CONNECTED
109
110-module(tls_connection_1_3).
111
112-include("ssl_alert.hrl").
113-include("ssl_connection.hrl").
114-include("tls_connection.hrl").
115-include("tls_handshake.hrl").
116-include("tls_handshake_1_3.hrl").
117
118-behaviour(gen_statem).
119
120%% gen_statem callbacks
121-export([init/1, callback_mode/0, terminate/3, code_change/4, format_status/2]).
122
123%% gen_statem state functions
124-export([initial_hello/3,
125         config_error/3,
126         user_hello/3,
127         start/3,
128         negotiated/3,
129         wait_cert/3,
130         wait_cv/3,
131         wait_finished/3,
132         wait_sh/3,
133         wait_ee/3,
134         wait_cert_cr/3,
135         wait_eoed/3,
136         connection/3,
137         downgrade/3
138        ]).
139
140%% Internal API
141-export([setopts/3,
142         getopts/3,
143         send_key_update/2,
144         update_cipher_key/2]).
145
146%%====================================================================
147%% Internal API
148%%====================================================================
149
150setopts(Transport, Socket, Other) ->
151    tls_socket:setopts(Transport, Socket, Other).
152
153getopts(Transport, Socket, Tag) ->
154    tls_socket:getopts(Transport, Socket, Tag).
155
156send_key_update(Sender, Type) ->
157    KeyUpdate = tls_handshake_1_3:key_update(Type),
158    tls_sender:send_post_handshake(Sender, KeyUpdate).
159
160update_cipher_key(ConnStateName, #state{connection_states = CS0} = State0) ->
161    CS = update_cipher_key(ConnStateName, CS0),
162    State0#state{connection_states = CS};
163update_cipher_key(ConnStateName, CS0) ->
164    #{security_parameters := SecParams0,
165      cipher_state := CipherState0} = ConnState0 = maps:get(ConnStateName, CS0),
166    HKDF = SecParams0#security_parameters.prf_algorithm,
167    CipherSuite = SecParams0#security_parameters.cipher_suite,
168    ApplicationTrafficSecret0 = SecParams0#security_parameters.application_traffic_secret,
169    ApplicationTrafficSecret = tls_v1:update_traffic_secret(HKDF, ApplicationTrafficSecret0),
170
171    %% Calculate traffic keys
172    KeyLength = tls_v1:key_length(CipherSuite),
173    {Key, IV} = tls_v1:calculate_traffic_keys(HKDF, KeyLength, ApplicationTrafficSecret),
174
175    SecParams = SecParams0#security_parameters{application_traffic_secret = ApplicationTrafficSecret},
176    CipherState = CipherState0#cipher_state{key = Key, iv = IV},
177    ConnState = ConnState0#{security_parameters => SecParams,
178                            cipher_state => CipherState,
179                            sequence_number => 0},
180    CS0#{ConnStateName => ConnState}.
181
182%--------------------------------------------------------------------
183%% gen_statem callbacks
184%%--------------------------------------------------------------------
185callback_mode() ->
186    state_functions.
187
188init([Role, Sender, Host, Port, Socket, Options,  User, CbInfo]) ->
189    State0 = #state{protocol_specific = Map} = initial_state(Role, Sender,
190                                                             Host, Port, Socket, Options, User, CbInfo),
191    try
192	State = ssl_gen_statem:ssl_config(State0#state.ssl_options, Role, State0),
193        tls_gen_connection:initialize_tls_sender(State),
194        gen_statem:enter_loop(?MODULE, [], initial_hello, State)
195    catch throw:Error ->
196            EState = State0#state{protocol_specific = Map#{error => Error}},
197            gen_statem:enter_loop(?MODULE, [], config_error, EState)
198    end.
199
200terminate({shutdown, {sender_died, Reason}}, _StateName,
201          #state{static_env = #static_env{socket = Socket,
202                                          transport_cb = Transport}}
203          = State) ->
204    ssl_gen_statem:handle_trusted_certs_db(State),
205    tls_gen_connection:close(Reason, Socket, Transport, undefined, undefined);
206terminate(Reason, StateName, State) ->
207    ssl_gen_statem:terminate(Reason, StateName, State).
208
209format_status(Type, Data) ->
210    ssl_gen_statem:format_status(Type, Data).
211
212code_change(_OldVsn, StateName, State, _) ->
213    {ok, StateName, State}.
214
215%--------------------------------------------------------------------
216%% state callbacks
217%%--------------------------------------------------------------------
218%%--------------------------------------------------------------------
219-spec initial_hello(gen_statem:event_type(),
220	   {start, timeout()} | term(), #state{}) ->
221		   gen_statem:state_function_result().
222%%--------------------------------------------------------------------
223initial_hello(Type, Event, State) ->
224    ssl_gen_statem:?FUNCTION_NAME(Type, Event, State).
225
226%%--------------------------------------------------------------------
227-spec config_error(gen_statem:event_type(),
228	   {start, timeout()} | term(), #state{}) ->
229		   gen_statem:state_function_result().
230%%--------------------------------------------------------------------
231config_error(Type, Event, State) ->
232    ssl_gen_statem:?FUNCTION_NAME(Type, Event, State).
233
234
235user_hello({call, From}, cancel, #state{connection_env = #connection_env{negotiated_version = Version}}
236           = State) ->
237    gen_statem:reply(From, ok),
238    ssl_gen_statem:handle_own_alert(?ALERT_REC(?FATAL, ?USER_CANCELED, user_canceled),
239                     Version, ?FUNCTION_NAME, State);
240user_hello({call, From}, {handshake_continue, NewOptions, Timeout},
241           #state{static_env = #static_env{role = Role},
242                  handshake_env = #handshake_env{hello = Hello},
243                  ssl_options = Options0} = State0) ->
244    Options = ssl:handle_options(NewOptions, Role, Options0#{handshake => full}),
245    State = ssl_gen_statem:ssl_config(Options, Role, State0),
246    Next = case Role of
247               client ->
248                   wait_sh;
249               server ->
250                   start
251           end,
252    {next_state, Next, State#state{start_or_recv_from = From},
253     [{next_event, internal, Hello}, {{timeout, handshake}, Timeout, close}]};
254user_hello(info, {'DOWN', _, _, _, _} = Event, State) ->
255    ssl_gen_statem:handle_info(Event, ?FUNCTION_NAME, State);
256user_hello(_, _, _) ->
257    {keep_state_and_data, [postpone]}.
258
259start(internal, #change_cipher_spec{}, State) ->
260    tls_gen_connection:next_event(?FUNCTION_NAME, no_record, State);
261start(internal, #client_hello{extensions = Extensions} = Hello,
262      #state{ssl_options = #{handshake := hello},
263             start_or_recv_from = From,
264             handshake_env = HsEnv} = State) ->
265    {next_state, user_hello,
266     State#state{start_or_recv_from = undefined,
267                 handshake_env = HsEnv#handshake_env{
268                                   hello = Hello}}, [{reply, From, {ok, Extensions}}]};
269start(internal, #client_hello{} = Hello, State0) ->
270    case tls_handshake_1_3:do_start(Hello, State0) of
271        #alert{} = Alert ->
272            ssl_gen_statem:handle_own_alert(Alert, {3,4}, start, State0);
273        {State, start} ->
274            {next_state, start, State, []};
275        {State, negotiated} ->
276            {next_state, negotiated, State, [{next_event, internal, {start_handshake, undefined}}]};
277        {State, negotiated, PSK} ->  %% Session Resumption with PSK
278            {next_state, negotiated, State, [{next_event, internal, {start_handshake, PSK}}]}
279    end;
280start(internal, #server_hello{extensions = Extensions} = ServerHello,
281      #state{ssl_options = #{handshake := hello},
282             handshake_env = HsEnv,
283             start_or_recv_from = From}
284      = State) ->
285     {next_state, user_hello,
286      State#state{start_or_recv_from = undefined,
287                  handshake_env = HsEnv#handshake_env{
288                                    hello = ServerHello}}, [{reply, From, {ok, Extensions}}]};
289start(internal, #server_hello{} = ServerHello, State0) ->
290    case tls_handshake_1_3:do_start(ServerHello, State0) of
291        #alert{} = Alert ->
292            ssl_gen_statem:handle_own_alert(Alert, {3,4}, start, State0);
293        {State, NextState} ->
294            {next_state, NextState, State, []}
295    end;
296start(info, Msg, State) ->
297    tls_gen_connection:handle_info(Msg, ?FUNCTION_NAME, State);
298start(Type, Msg, State) ->
299    ssl_gen_statem:handle_common_event(Type, Msg, ?FUNCTION_NAME, State).
300
301negotiated(internal, #change_cipher_spec{}, State) ->
302    tls_gen_connection:next_event(?FUNCTION_NAME, no_record, State);
303negotiated(internal, Message, State0) ->
304    case tls_handshake_1_3:do_negotiated(Message, State0) of
305        #alert{} = Alert ->
306            ssl_gen_statem:handle_own_alert(Alert, {3,4}, negotiated, State0);
307        {State, NextState} ->
308            {next_state, NextState, State, []}
309    end;
310negotiated(info, Msg, State) ->
311    tls_gen_connection:handle_info(Msg, ?FUNCTION_NAME, State).
312
313wait_cert(internal, #change_cipher_spec{}, State0) ->
314    tls_gen_connection:next_event(?FUNCTION_NAME, no_record, State0);
315wait_cert(internal,
316          #certificate_1_3{} = Certificate, State0) ->
317    case tls_handshake_1_3:do_wait_cert(Certificate, State0) of
318        {#alert{} = Alert, State} ->
319            ssl_gen_statem:handle_own_alert(Alert, {3,4}, wait_cert, State);
320        {State, NextState} ->
321            tls_gen_connection:next_event(NextState, no_record, State)
322    end;
323wait_cert(info, Msg, State) ->
324    tls_gen_connection:handle_info(Msg, ?FUNCTION_NAME, State);
325wait_cert(Type, Msg, State) ->
326    ssl_gen_statem:handle_common_event(Type, Msg, ?FUNCTION_NAME, State).
327
328wait_cv(internal, #change_cipher_spec{}, State) ->
329    tls_gen_connection:next_event(?FUNCTION_NAME, no_record, State);
330wait_cv(internal,
331          #certificate_verify_1_3{} = CertificateVerify, State0) ->
332    case tls_handshake_1_3:do_wait_cv(CertificateVerify, State0) of
333        {#alert{} = Alert, State} ->
334            ssl_gen_statem:handle_own_alert(Alert, {3,4}, wait_cv, State);
335        {State, NextState} ->
336            tls_gen_connection:next_event(NextState, no_record, State)
337    end;
338wait_cv(info, Msg, State) ->
339    tls_gen_connection:handle_info(Msg, ?FUNCTION_NAME, State);
340wait_cv(Type, Msg, State) ->
341    ssl_gen_statem:handle_common_event(Type, Msg, ?FUNCTION_NAME, State).
342
343wait_finished(internal, #change_cipher_spec{}, State0) ->
344    tls_gen_connection:next_event(?FUNCTION_NAME, no_record, State0);
345wait_finished(internal,
346             #finished{} = Finished, State0) ->
347    case tls_handshake_1_3:do_wait_finished(Finished, State0) of
348        #alert{} = Alert ->
349            ssl_gen_statem:handle_own_alert(Alert, {3,4}, finished, State0);
350        State1 ->
351            {Record, State} = ssl_gen_statem:prepare_connection(State1, tls_gen_connection),
352            tls_gen_connection:next_event(connection, Record, State,
353                                      [{{timeout, handshake}, cancel}])
354    end;
355wait_finished(info, Msg, State) ->
356    tls_gen_connection:handle_info(Msg, ?FUNCTION_NAME, State);
357wait_finished(Type, Msg, State) ->
358    ssl_gen_statem:handle_common_event(Type, Msg, ?FUNCTION_NAME, State).
359
360
361wait_sh(internal, #change_cipher_spec{}, State) ->
362    tls_gen_connection:next_event(?FUNCTION_NAME, no_record, State);
363wait_sh(internal, #server_hello{extensions = Extensions} = Hello,  #state{ssl_options = #{handshake := hello},
364                                                                          start_or_recv_from = From,
365                                                                          handshake_env = HsEnv} = State) ->
366    {next_state, user_hello,
367     State#state{start_or_recv_from = undefined,
368                 handshake_env = HsEnv#handshake_env{
369                                   hello = Hello}}, [{reply, From, {ok, Extensions}}]};
370wait_sh(internal, #server_hello{} = Hello, State0) ->
371    case tls_handshake_1_3:do_wait_sh(Hello, State0) of
372        #alert{} = Alert ->
373            ssl_gen_statem:handle_own_alert(Alert, {3,4}, wait_sh, State0);
374        {State1, start, ServerHello} ->
375            %% hello_retry_request: go to start
376            {next_state, start, State1, [{next_event, internal, ServerHello}]};
377        {State1, wait_ee} ->
378            tls_gen_connection:next_event(wait_ee, no_record, State1)
379    end;
380wait_sh(info, Msg, State) ->
381    tls_gen_connection:handle_info(Msg, ?FUNCTION_NAME, State);
382wait_sh(Type, Msg, State) ->
383    ssl_gen_statem:handle_common_event(Type, Msg, ?FUNCTION_NAME, State).
384
385
386wait_ee(internal, #change_cipher_spec{}, State) ->
387    tls_gen_connection:next_event(?FUNCTION_NAME, no_record, State);
388wait_ee(internal, #encrypted_extensions{} = EE, State0) ->
389    case tls_handshake_1_3:do_wait_ee(EE, State0) of
390        #alert{} = Alert ->
391            ssl_gen_statem:handle_own_alert(Alert, {3,4}, wait_ee, State0);
392        {State1, NextState} ->
393            tls_gen_connection:next_event(NextState, no_record, State1)
394    end;
395wait_ee(info, Msg, State) ->
396    tls_gen_connection:handle_info(Msg, ?FUNCTION_NAME, State);
397wait_ee(Type, Msg, State) ->
398    ssl_gen_statem:handle_common_event(Type, Msg, ?FUNCTION_NAME, State).
399
400
401wait_cert_cr(internal, #change_cipher_spec{}, State) ->
402    tls_gen_connection:next_event(?FUNCTION_NAME, no_record, State);
403wait_cert_cr(internal, #certificate_1_3{} = Certificate, State0) ->
404    case tls_handshake_1_3:do_wait_cert_cr(Certificate, State0) of
405        {#alert{} = Alert, State} ->
406            ssl_gen_statem:handle_own_alert(Alert, {3,4}, wait_cert_cr, State);
407        {State1, NextState} ->
408            tls_gen_connection:next_event(NextState, no_record, State1)
409    end;
410wait_cert_cr(internal, #certificate_request_1_3{} = CertificateRequest, State0) ->
411    case tls_handshake_1_3:do_wait_cert_cr(CertificateRequest, State0) of
412        #alert{} = Alert ->
413            ssl_gen_statem:handle_own_alert(Alert, {3,4}, wait_cert_cr, State0);
414        {State1, NextState} ->
415            tls_gen_connection:next_event(NextState, no_record, State1)
416    end;
417wait_cert_cr(info, Msg, State) ->
418    tls_gen_connection:handle_info(Msg, ?FUNCTION_NAME, State);
419wait_cert_cr(Type, Msg, State) ->
420    ssl_gen_statem:handle_common_event(Type, Msg, ?FUNCTION_NAME, State).
421
422wait_eoed(internal, #change_cipher_spec{}, State) ->
423    tls_gen_connection:next_event(?FUNCTION_NAME, no_record, State);
424wait_eoed(internal, #end_of_early_data{} = EOED, State0) ->
425    case tls_handshake_1_3:do_wait_eoed(EOED, State0) of
426        {#alert{} = Alert, State} ->
427            ssl_gen_statem:handle_own_alert(Alert, {3,4}, wait_eoed, State);
428        {State1, NextState} ->
429            tls_gen_connection:next_event(NextState, no_record, State1)
430    end;
431wait_eoed(info, Msg, State) ->
432    tls_gen_connection:handle_info(Msg, ?FUNCTION_NAME, State);
433wait_eoed(Type, Msg, State) ->
434    ssl_gen_statem:handle_common_event(Type, Msg, ?FUNCTION_NAME, State).
435
436connection(internal, #new_session_ticket{} = NewSessionTicket, State) ->
437    handle_new_session_ticket(NewSessionTicket, State),
438    tls_gen_connection:next_event(?FUNCTION_NAME, no_record, State);
439
440connection(internal, #key_update{} = KeyUpdate, State0) ->
441    case handle_key_update(KeyUpdate, State0) of
442        {ok, State} ->
443            tls_gen_connection:next_event(?FUNCTION_NAME, no_record, State);
444        {error, State, Alert} ->
445            ssl_gen_statem:handle_own_alert(Alert, {3,4}, connection, State),
446            tls_gen_connection:next_event(?FUNCTION_NAME, no_record, State)
447    end;
448connection({call, From}, negotiated_protocol,
449	   #state{handshake_env = #handshake_env{alpn = undefined}} = State) ->
450    ssl_gen_statem:hibernate_after(?FUNCTION_NAME, State, [{reply, From, {error, protocol_not_negotiated}}]);
451connection({call, From}, negotiated_protocol,
452	   #state{handshake_env = #handshake_env{alpn = SelectedProtocol,
453                                                 negotiated_protocol = undefined}} = State) ->
454    ssl_gen_statem:hibernate_after(?FUNCTION_NAME, State,
455                    [{reply, From, {ok, SelectedProtocol}}]);
456connection(Type, Event, State) ->
457    ssl_gen_statem:?FUNCTION_NAME(Type, Event, State).
458
459downgrade(internal, #new_session_ticket{} = NewSessionTicket, State) ->
460    _ = handle_new_session_ticket(NewSessionTicket, State),
461    {next_state, ?FUNCTION_NAME, State};
462downgrade(Type, Event, State) ->
463     ssl_gen_statem:?FUNCTION_NAME(Type, Event, State).
464
465%--------------------------------------------------------------------
466%% internal functions
467%%--------------------------------------------------------------------
468initial_state(Role, Sender, Host, Port, Socket, {SSLOptions, SocketOptions, Trackers}, User,
469	      {CbModule, DataTag, CloseTag, ErrorTag, PassiveTag}) ->
470    #{erl_dist := IsErlDist,
471      client_renegotiation := ClientRenegotiation} = SSLOptions,
472    MaxEarlyDataSize = init_max_early_data_size(Role),
473    ConnectionStates = tls_record:init_connection_states(Role, disabled, MaxEarlyDataSize),
474    UserMonitor = erlang:monitor(process, User),
475    InitStatEnv = #static_env{
476                     role = Role,
477                     transport_cb = CbModule,
478                     protocol_cb = tls_gen_connection,
479                     data_tag = DataTag,
480                     close_tag = CloseTag,
481                     error_tag = ErrorTag,
482                     passive_tag = PassiveTag,
483                     host = Host,
484                     port = Port,
485                     socket = Socket,
486                     trackers = Trackers
487                    },
488    #state{
489       static_env = InitStatEnv,
490       handshake_env = #handshake_env{
491                          tls_handshake_history = ssl_handshake:init_handshake_history(),
492                          renegotiation = {false, first},
493                          allow_renegotiate = ClientRenegotiation
494                         },
495       connection_env = #connection_env{user_application = {UserMonitor, User}},
496       socket_options = SocketOptions,
497       ssl_options = SSLOptions,
498       session = #session{is_resumable = false,
499                          session_id = ssl_session:legacy_session_id()},
500       connection_states = ConnectionStates,
501       protocol_buffers = #protocol_buffers{},
502       user_data_buffer = {[],0,[]},
503       start_or_recv_from = undefined,
504       flight_buffer = [],
505       protocol_specific = #{sender => Sender,
506                             active_n => internal_active_n(IsErlDist),
507                             active_n_toggle => true
508                            }
509      }.
510
511internal_active_n(true) ->
512    %% Start with a random number between 1 and ?INTERNAL_ACTIVE_N
513    %% In most cases distribution connections are established all at
514    %%  the same time, and flow control engages with ?INTERNAL_ACTIVE_N for
515    %%  all connections. Which creates a wave of "passive" messages, leading
516    %%  to significant bump of memory & scheduler utilisation. Starting with
517    %%  a random number between 1 and ?INTERNAL_ACTIVE_N helps to spread the
518    %%  spike.
519    erlang:system_time() rem ?INTERNAL_ACTIVE_N + 1;
520internal_active_n(false) ->
521    case application:get_env(ssl, internal_active_n) of
522        {ok, N} when is_integer(N) ->
523            N;
524        _  ->
525            ?INTERNAL_ACTIVE_N
526    end.
527
528handle_new_session_ticket(_, #state{ssl_options = #{session_tickets := disabled}}) ->
529    ok;
530handle_new_session_ticket(#new_session_ticket{ticket_nonce = Nonce} = NewSessionTicket,
531                          #state{connection_states = ConnectionStates,
532                                 ssl_options = #{session_tickets := SessionTickets,
533                                                 server_name_indication := SNI},
534                                 connection_env = #connection_env{user_application = {_, User}}})
535  when SessionTickets =:= manual ->
536    #{security_parameters := SecParams} =
537	ssl_record:current_connection_state(ConnectionStates, read),
538    CipherSuite = SecParams#security_parameters.cipher_suite,
539    #{cipher := Cipher} = ssl_cipher_format:suite_bin_to_map(CipherSuite),
540    HKDF = SecParams#security_parameters.prf_algorithm,
541    RMS = SecParams#security_parameters.resumption_master_secret,
542    PSK = tls_v1:pre_shared_key(RMS, Nonce, HKDF),
543    send_ticket_data(User, NewSessionTicket, {Cipher, HKDF}, SNI, PSK);
544handle_new_session_ticket(#new_session_ticket{ticket_nonce = Nonce} = NewSessionTicket,
545                          #state{connection_states = ConnectionStates,
546                                 ssl_options = #{session_tickets := SessionTickets,
547                                                 server_name_indication := SNI}})
548  when SessionTickets =:= auto ->
549    #{security_parameters := SecParams} =
550	ssl_record:current_connection_state(ConnectionStates, read),
551    CipherSuite = SecParams#security_parameters.cipher_suite,
552    #{cipher := Cipher} = ssl_cipher_format:suite_bin_to_map(CipherSuite),
553    HKDF = SecParams#security_parameters.prf_algorithm,
554    RMS = SecParams#security_parameters.resumption_master_secret,
555    PSK = tls_v1:pre_shared_key(RMS, Nonce, HKDF),
556    tls_client_ticket_store:store_ticket(NewSessionTicket, {Cipher, HKDF}, SNI, PSK).
557
558send_ticket_data(User, NewSessionTicket, CipherSuite, SNI, PSK) ->
559    Timestamp = erlang:system_time(seconds),
560    TicketData = #{cipher_suite => CipherSuite,
561                   sni => SNI,
562                   psk => PSK,
563                   timestamp => Timestamp,
564                   ticket => NewSessionTicket},
565    User ! {ssl, session_ticket, TicketData}.
566
567handle_key_update(#key_update{request_update = update_not_requested}, State0) ->
568    %% Update read key in connection
569    {ok, update_cipher_key(current_read, State0)};
570handle_key_update(#key_update{request_update = update_requested},
571                  #state{protocol_specific = #{sender := Sender}} = State0) ->
572    %% Update read key in connection
573    State1 = update_cipher_key(current_read, State0),
574    %% Send key_update and update sender's write key
575    case send_key_update(Sender, update_not_requested) of
576        ok ->
577            {ok, State1};
578        {error, Reason} ->
579            {error, State1, ?ALERT_REC(?FATAL, ?INTERNAL_ERROR, Reason)}
580    end.
581
582init_max_early_data_size(client) ->
583    %% Disable trial decryption on the client side
584    %% Servers do trial decryption of max_early_data bytes of plain text.
585    %% Setting it to 0 means that a decryption error will result in an Alert.
586    0;
587init_max_early_data_size(server) ->
588    ssl_config:get_max_early_data_size().
589
590