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%% Purpose: Help funtions for handling the TLS 1.3 (specific parts of)
23%%% TLS handshake protocol
24%%----------------------------------------------------------------------
25
26-module(tls_handshake_1_3).
27
28-include("tls_handshake_1_3.hrl").
29-include("ssl_alert.hrl").
30-include("ssl_cipher.hrl").
31-include("ssl_connection.hrl").
32-include("ssl_internal.hrl").
33-include("ssl_record.hrl").
34-include_lib("public_key/include/public_key.hrl").
35
36%% Encode
37-export([encode_handshake/1, decode_handshake/2]).
38
39%% Create handshake messages
40-export([certificate/5,
41         certificate_verify/4,
42         encrypted_extensions/1,
43         key_update/1]).
44
45-export([do_start/2,
46         do_negotiated/2,
47         do_wait_cert/2,
48         do_wait_cv/2,
49         do_wait_finished/2,
50         do_wait_sh/2,
51         do_wait_ee/2,
52         do_wait_cert_cr/2,
53         get_ticket_data/3,
54         maybe_add_binders/3,
55         maybe_add_binders/4,
56         maybe_automatic_session_resumption/1]).
57
58-export([is_valid_binder/4]).
59
60%% crypto:hash(sha256, "HelloRetryRequest").
61-define(HELLO_RETRY_REQUEST_RANDOM, <<207,33,173,116,229,154,97,17,
62                                      190,29,140,2,30,101,184,145,
63                                      194,162,17,22,122,187,140,94,
64                                      7,158,9,226,200,168,51,156>>).
65
66%%====================================================================
67%% Create handshake messages
68%%====================================================================
69
70server_hello(MsgType, SessionId, KeyShare, PSK, ConnectionStates) ->
71    #{security_parameters := SecParams} =
72	ssl_record:pending_connection_state(ConnectionStates, read),
73    Extensions = server_hello_extensions(MsgType, KeyShare, PSK),
74    #server_hello{server_version = {3,3}, %% legacy_version
75		  cipher_suite = SecParams#security_parameters.cipher_suite,
76                  compression_method = 0, %% legacy attribute
77		  random = server_hello_random(MsgType, SecParams),
78		  session_id = SessionId,
79		  extensions = Extensions
80		 }.
81
82
83%% The server's extensions MUST contain "supported_versions".
84%% Additionally, it SHOULD contain the minimal set of extensions
85%% necessary for the client to generate a correct ClientHello pair.  As
86%% with the ServerHello, a HelloRetryRequest MUST NOT contain any
87%% extensions that were not first offered by the client in its
88%% ClientHello, with the exception of optionally the "cookie" (see
89%% Section 4.2.2) extension.
90server_hello_extensions(hello_retry_request = MsgType, KeyShare, _) ->
91    SupportedVersions = #server_hello_selected_version{selected_version = {3,4}},
92    Extensions = #{server_hello_selected_version => SupportedVersions},
93    ssl_handshake:add_server_share(MsgType, Extensions, KeyShare);
94server_hello_extensions(MsgType, KeyShare, undefined) ->
95    SupportedVersions = #server_hello_selected_version{selected_version = {3,4}},
96    Extensions = #{server_hello_selected_version => SupportedVersions},
97    ssl_handshake:add_server_share(MsgType, Extensions, KeyShare);
98server_hello_extensions(MsgType, KeyShare, {SelectedIdentity, _}) ->
99    SupportedVersions = #server_hello_selected_version{selected_version = {3,4}},
100    PreSharedKey = #pre_shared_key_server_hello{selected_identity = SelectedIdentity},
101    Extensions = #{server_hello_selected_version => SupportedVersions,
102                   pre_shared_key => PreSharedKey},
103    ssl_handshake:add_server_share(MsgType, Extensions, KeyShare).
104
105
106server_hello_random(server_hello, #security_parameters{server_random = Random}) ->
107    Random;
108%% For reasons of backward compatibility with middleboxes (see
109%% Appendix D.4), the HelloRetryRequest message uses the same structure
110%% as the ServerHello, but with Random set to the special value of the
111%% SHA-256 of "HelloRetryRequest":
112%%
113%%   CF 21 AD 74 E5 9A 61 11 BE 1D 8C 02 1E 65 B8 91
114%%   C2 A2 11 16 7A BB 8C 5E 07 9E 09 E2 C8 A8 33 9C
115server_hello_random(hello_retry_request, _) ->
116    ?HELLO_RETRY_REQUEST_RANDOM.
117
118
119encrypted_extensions(#state{handshake_env = #handshake_env{alpn = undefined}}) ->
120    #encrypted_extensions{
121       extensions = #{}
122      };
123encrypted_extensions(#state{handshake_env = #handshake_env{alpn = ALPNProtocol}}) ->
124    Extensions = ssl_handshake:add_alpn(#{}, ALPNProtocol),
125    #encrypted_extensions{
126       extensions = Extensions
127      }.
128
129
130certificate_request(SignAlgs0, SignAlgsCert0) ->
131    %% Input arguments contain TLS 1.2 algorithms due to backward compatibility
132    %% reasons. These {Hash, Algo} tuples must be filtered before creating the
133    %% the extensions.
134    SignAlgs = filter_tls13_algs(SignAlgs0),
135    SignAlgsCert = filter_tls13_algs(SignAlgsCert0),
136    Extensions0 = add_signature_algorithms(#{}, SignAlgs),
137    Extensions = add_signature_algorithms_cert(Extensions0, SignAlgsCert),
138    #certificate_request_1_3{
139      certificate_request_context = <<>>,
140      extensions = Extensions}.
141
142
143add_signature_algorithms(Extensions, SignAlgs) ->
144    Extensions#{signature_algorithms =>
145                    #signature_algorithms{signature_scheme_list = SignAlgs}}.
146
147
148add_signature_algorithms_cert(Extensions, undefined) ->
149    Extensions;
150add_signature_algorithms_cert(Extensions, SignAlgsCert) ->
151    Extensions#{signature_algorithms_cert =>
152                    #signature_algorithms_cert{signature_scheme_list = SignAlgsCert}}.
153
154
155filter_tls13_algs(undefined) -> undefined;
156filter_tls13_algs(Algo) ->
157    lists:filter(fun is_atom/1, Algo).
158
159
160%% enum {
161%%     X509(0),
162%%     RawPublicKey(2),
163%%     (255)
164%% } CertificateType;
165%%
166%% struct {
167%%     select (certificate_type) {
168%%         case RawPublicKey:
169%%           /* From RFC 7250 ASN.1_subjectPublicKeyInfo */
170%%           opaque ASN1_subjectPublicKeyInfo<1..2^24-1>;
171%%
172%%         case X509:
173%%           opaque cert_data<1..2^24-1>;
174%%     };
175%%     Extension extensions<0..2^16-1>;
176%% } CertificateEntry;
177%%
178%% struct {
179%%     opaque certificate_request_context<0..2^8-1>;
180%%     CertificateEntry certificate_list<0..2^24-1>;
181%% } Certificate;
182certificate(OwnCert, CertDbHandle, CertDbRef, _CRContext, Role) ->
183    case ssl_certificate:certificate_chain(OwnCert, CertDbHandle, CertDbRef) of
184	{ok, _, Chain} ->
185            CertList = chain_to_cert_list(Chain),
186            %% If this message is in response to a CertificateRequest, the value of
187            %% certificate_request_context in that message. Otherwise (in the case
188            %%of server authentication), this field SHALL be zero length.
189	    {ok, #certificate_1_3{
190                    certificate_request_context = <<>>,
191                    certificate_list = CertList}};
192	{error, Error} when Role =:= server ->
193            {error, ?ALERT_REC(?FATAL, ?INTERNAL_ERROR, {no_suitable_certificates, Error})};
194	{error, _Error} when Role =:= client ->
195            %% The client MUST send a Certificate message if and only if the server
196            %% has requested client authentication via a CertificateRequest message
197            %% (Section 4.3.2).  If the server requests client authentication but no
198            %% suitable certificate is available, the client MUST send a Certificate
199            %% message containing no certificates (i.e., with the "certificate_list"
200            %% field having length 0).
201            {ok, #certificate_1_3{
202                    certificate_request_context = <<>>,
203                    certificate_list = []}}
204    end.
205
206
207certificate_verify(PrivateKey, SignatureScheme,
208                   #state{connection_states = ConnectionStates,
209                          handshake_env =
210                              #handshake_env{
211                                 tls_handshake_history = {Messages, _}}}, Role) ->
212    #{security_parameters := SecParamsR} =
213        ssl_record:pending_connection_state(ConnectionStates, write),
214    #security_parameters{prf_algorithm = HKDFAlgo} = SecParamsR,
215
216    {HashAlgo, _, _} =
217        ssl_cipher:scheme_to_components(SignatureScheme),
218
219    Context = lists:reverse(Messages),
220
221    %% Transcript-Hash uses the HKDF hash function defined by the cipher suite.
222    THash = tls_v1:transcript_hash(Context, HKDFAlgo),
223    ContextString = context_string(Role),
224
225    %% Digital signatures use the hash function defined by the selected signature
226    %% scheme.
227    case sign(THash, ContextString, HashAlgo, PrivateKey) of
228        {ok, Signature} ->
229            {ok, #certificate_verify_1_3{
230                    algorithm = SignatureScheme,
231                    signature = Signature
232                   }};
233        {error, #alert{} = Alert} ->
234            {error, Alert}
235    end.
236
237
238finished(#state{connection_states = ConnectionStates,
239                handshake_env =
240                    #handshake_env{
241                       tls_handshake_history = {Messages, _}}}) ->
242    #{security_parameters := SecParamsR,
243     cipher_state := #cipher_state{finished_key = FinishedKey}} =
244        ssl_record:current_connection_state(ConnectionStates, write),
245    #security_parameters{prf_algorithm = HKDFAlgo} = SecParamsR,
246
247    VerifyData = tls_v1:finished_verify_data(FinishedKey, HKDFAlgo, Messages),
248
249    #finished{
250       verify_data = VerifyData
251      }.
252
253
254key_update(Type) ->
255    #key_update{request_update = Type}.
256
257
258%%====================================================================
259%% Encode handshake
260%%====================================================================
261
262encode_handshake(#certificate_request_1_3{
263                    certificate_request_context = Context,
264                    extensions = Exts})->
265    EncContext = encode_cert_req_context(Context),
266    BinExts = encode_extensions(Exts),
267    {?CERTIFICATE_REQUEST, <<EncContext/binary, BinExts/binary>>};
268encode_handshake(#certificate_1_3{
269                    certificate_request_context = Context,
270                    certificate_list = Entries}) ->
271    EncContext = encode_cert_req_context(Context),
272    EncEntries = encode_cert_entries(Entries),
273    {?CERTIFICATE, <<EncContext/binary, EncEntries/binary>>};
274encode_handshake(#certificate_verify_1_3{
275                    algorithm = Algorithm,
276                    signature = Signature}) ->
277    EncAlgo = encode_algorithm(Algorithm),
278    EncSign = encode_signature(Signature),
279    {?CERTIFICATE_VERIFY, <<EncAlgo/binary, EncSign/binary>>};
280encode_handshake(#encrypted_extensions{extensions = Exts})->
281    {?ENCRYPTED_EXTENSIONS, encode_extensions(Exts)};
282encode_handshake(#new_session_ticket{
283                    ticket_lifetime = LifeTime,
284                    ticket_age_add = Age,
285                    ticket_nonce = Nonce,
286                    ticket = Ticket,
287                    extensions = Exts}) ->
288    TicketSize = byte_size(Ticket),
289    NonceSize = byte_size(Nonce),
290    BinExts = encode_extensions(Exts),
291    {?NEW_SESSION_TICKET, <<?UINT32(LifeTime), ?UINT32(Age),
292                            ?BYTE(NonceSize), Nonce/binary,
293                            ?UINT16(TicketSize), Ticket/binary,
294                            BinExts/binary>>};
295encode_handshake(#end_of_early_data{}) ->
296    {?END_OF_EARLY_DATA, <<>>};
297encode_handshake(#key_update{request_update = Update}) ->
298    EncUpdate = encode_key_update(Update),
299    {?KEY_UPDATE, <<EncUpdate/binary>>};
300encode_handshake(HandshakeMsg) ->
301    ssl_handshake:encode_handshake(HandshakeMsg, {3,4}).
302
303
304%%====================================================================
305%% Decode handshake
306%%====================================================================
307
308
309decode_handshake(?SERVER_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary,
310                                  ?BYTE(SID_length), Session_ID:SID_length/binary,
311                                  Cipher_suite:2/binary, ?BYTE(Comp_method),
312                                  ?UINT16(ExtLen), Extensions:ExtLen/binary>>)
313  when Random =:= ?HELLO_RETRY_REQUEST_RANDOM ->
314    HelloExtensions = ssl_handshake:decode_hello_extensions(Extensions, {3,4}, {Major, Minor},
315                                                            hello_retry_request),
316    #server_hello{
317       server_version = {Major,Minor},
318       random = Random,
319       session_id = Session_ID,
320       cipher_suite = Cipher_suite,
321       compression_method = Comp_method,
322       extensions = HelloExtensions};
323decode_handshake(?CERTIFICATE_REQUEST, <<?BYTE(0), ?UINT16(Size), EncExts:Size/binary>>) ->
324    Exts = decode_extensions(EncExts, certificate_request),
325    #certificate_request_1_3{
326       certificate_request_context = <<>>,
327       extensions = Exts};
328decode_handshake(?CERTIFICATE_REQUEST, <<?BYTE(CSize), Context:CSize/binary,
329                                         ?UINT16(Size), EncExts:Size/binary>>) ->
330    Exts = decode_extensions(EncExts, certificate_request),
331    #certificate_request_1_3{
332       certificate_request_context = Context,
333       extensions = Exts};
334decode_handshake(?CERTIFICATE, <<?BYTE(0), ?UINT24(Size), Certs:Size/binary>>) ->
335    CertList = decode_cert_entries(Certs),
336    #certificate_1_3{
337       certificate_request_context = <<>>,
338       certificate_list = CertList
339      };
340decode_handshake(?CERTIFICATE, <<?BYTE(CSize), Context:CSize/binary,
341                                 ?UINT24(Size), Certs:Size/binary>>) ->
342    CertList = decode_cert_entries(Certs),
343    #certificate_1_3{
344       certificate_request_context = Context,
345       certificate_list = CertList
346      };
347decode_handshake(?CERTIFICATE_VERIFY, <<?UINT16(EncAlgo), ?UINT16(Size), Signature:Size/binary>>) ->
348    Algorithm = ssl_cipher:signature_scheme(EncAlgo),
349    #certificate_verify_1_3{
350       algorithm = Algorithm,
351       signature = Signature};
352decode_handshake(?ENCRYPTED_EXTENSIONS, <<?UINT16(Size), EncExts:Size/binary>>) ->
353    #encrypted_extensions{
354       extensions = decode_extensions(EncExts, encrypted_extensions)
355      };
356decode_handshake(?NEW_SESSION_TICKET, <<?UINT32(LifeTime), ?UINT32(Age),
357                                        ?BYTE(NonceSize), Nonce:NonceSize/binary,
358                                        ?UINT16(TicketSize), Ticket:TicketSize/binary,
359                                        ?UINT16(BinExtSize), BinExts:BinExtSize/binary>>) ->
360    Exts = decode_extensions(BinExts, encrypted_extensions),
361    #new_session_ticket{ticket_lifetime = LifeTime,
362                        ticket_age_add = Age,
363                        ticket_nonce = Nonce,
364                        ticket = Ticket,
365                        extensions = Exts};
366decode_handshake(?END_OF_EARLY_DATA, _) ->
367    #end_of_early_data{};
368decode_handshake(?KEY_UPDATE, <<?BYTE(Update)>>) ->
369    #key_update{request_update = decode_key_update(Update)};
370decode_handshake(Tag, HandshakeMsg) ->
371    ssl_handshake:decode_handshake({3,4}, Tag, HandshakeMsg).
372
373is_valid_binder(Binder, HHistory, PSK, Hash) ->
374    case HHistory of
375        [ClientHello2, HRR, MessageHash|_] ->
376            Truncated = truncate_client_hello(ClientHello2),
377            FinishedKey = calculate_finished_key(PSK, Hash),
378            Binder == calculate_binder(FinishedKey, Hash, [MessageHash, HRR, Truncated]);
379        [ClientHello1|_] ->
380            Truncated = truncate_client_hello(ClientHello1),
381            FinishedKey = calculate_finished_key(PSK, Hash),
382            Binder == calculate_binder(FinishedKey, Hash, Truncated)
383    end.
384
385%%--------------------------------------------------------------------
386%%% Internal functions
387%%--------------------------------------------------------------------
388encode_cert_req_context(<<>>) ->
389    <<?BYTE(0)>>;
390encode_cert_req_context(Bin) ->
391    Size = byte_size(Bin),
392    <<?BYTE(Size), Bin/binary>>.
393
394encode_cert_entries(Entries) ->
395    CertEntryList = encode_cert_entries(Entries, []),
396    Size = byte_size(CertEntryList),
397    <<?UINT24(Size), CertEntryList/binary>>.
398
399encode_cert_entries([], Acc) ->
400    iolist_to_binary(lists:reverse(Acc));
401encode_cert_entries([#certificate_entry{data = Data,
402                                        extensions = Exts} | Rest], Acc) ->
403    DSize = byte_size(Data),
404    BinExts = encode_extensions(Exts),
405    encode_cert_entries(Rest,
406                        [<<?UINT24(DSize), Data/binary, BinExts/binary>> | Acc]).
407
408encode_algorithm(Algo) ->
409    Scheme = ssl_cipher:signature_scheme(Algo),
410    <<?UINT16(Scheme)>>.
411
412encode_signature(Signature) ->
413    Size = byte_size(Signature),
414    <<?UINT16(Size), Signature/binary>>.
415
416encode_key_update(update_not_requested) ->
417    <<?BYTE(0)>>;
418encode_key_update(update_requested) ->
419    <<?BYTE(1)>>.
420
421%% enum {
422%%     update_not_requested(0), update_requested(1), (255)
423%% } KeyUpdateRequest;
424%%
425%% request_update:  Indicates whether the recipient of the KeyUpdate
426%%    should respond with its own KeyUpdate.  If an implementation
427%%    receives any other value, it MUST terminate the connection with an
428%%    "illegal_parameter" alert.
429decode_key_update(0) ->
430    update_not_requested;
431decode_key_update(1) ->
432    update_requested;
433decode_key_update(N) ->
434    throw(?ALERT_REC(?FATAL, ?ILLEGAL_PARAMETER, {request_update,N})).
435
436decode_cert_entries(Entries) ->
437    decode_cert_entries(Entries, []).
438
439decode_cert_entries(<<>>, Acc) ->
440    lists:reverse(Acc);
441decode_cert_entries(<<?UINT24(DSize), Data:DSize/binary, ?UINT16(Esize), BinExts:Esize/binary,
442                      Rest/binary>>, Acc) ->
443    Exts = decode_extensions(BinExts, certificate_request),
444    decode_cert_entries(Rest, [#certificate_entry{data = Data,
445                                                  extensions = Exts} | Acc]).
446
447encode_extensions(Exts)->
448    ssl_handshake:encode_extensions(extensions_list(Exts)).
449
450decode_extensions(Exts, MessageType) ->
451    ssl_handshake:decode_extensions(Exts, {3,4}, MessageType).
452
453extensions_list(HelloExtensions) ->
454    [Ext || {_, Ext} <- maps:to_list(HelloExtensions)].
455
456
457%% TODO: add extensions!
458chain_to_cert_list(L) ->
459    chain_to_cert_list(L, []).
460%%
461chain_to_cert_list([], Acc) ->
462    lists:reverse(Acc);
463chain_to_cert_list([H|T], Acc) ->
464    chain_to_cert_list(T, [certificate_entry(H)|Acc]).
465
466
467certificate_entry(DER) ->
468    #certificate_entry{
469       data = DER,
470       extensions = #{} %% Extensions not supported.
471      }.
472
473%% The digital signature is then computed over the concatenation of:
474%%   -  A string that consists of octet 32 (0x20) repeated 64 times
475%%   -  The context string
476%%   -  A single 0 byte which serves as the separator
477%%   -  The content to be signed
478%%
479%% For example, if the transcript hash was 32 bytes of 01 (this length
480%% would make sense for SHA-256), the content covered by the digital
481%% signature for a server CertificateVerify would be:
482%%
483%%    2020202020202020202020202020202020202020202020202020202020202020
484%%    2020202020202020202020202020202020202020202020202020202020202020
485%%    544c5320312e332c207365727665722043657274696669636174655665726966
486%%    79
487%%    00
488%%    0101010101010101010101010101010101010101010101010101010101010101
489sign(THash, Context, HashAlgo, #'ECPrivateKey'{} = PrivateKey) ->
490    Content = build_content(Context, THash),
491    try public_key:sign(Content, HashAlgo, PrivateKey) of
492        Signature ->
493            {ok, Signature}
494    catch
495        error:badarg ->
496            {error, ?ALERT_REC(?FATAL, ?INTERNAL_ERROR, badarg)}
497    end;
498sign(THash, Context, HashAlgo, PrivateKey) ->
499    Content = build_content(Context, THash),
500
501    %% The length of the Salt MUST be equal to the length of the output
502    %% of the digest algorithm: rsa_pss_saltlen = -1
503    try public_key:sign(Content, HashAlgo, PrivateKey,
504                    [{rsa_padding, rsa_pkcs1_pss_padding},
505                     {rsa_pss_saltlen, -1},
506                     {rsa_mgf1_md, HashAlgo}]) of
507        Signature ->
508            {ok, Signature}
509    catch
510        error:badarg ->
511            {error, ?ALERT_REC(?FATAL, ?INTERNAL_ERROR, badarg)}
512    end.
513
514
515verify(THash, Context, HashAlgo, Signature, {?'id-ecPublicKey', PublicKey, PublicKeyParams}) ->
516    Content = build_content(Context, THash),
517    try public_key:verify(Content, HashAlgo, Signature, {PublicKey, PublicKeyParams}) of
518        Result ->
519            {ok, Result}
520    catch
521        error:badarg ->
522            {error, ?ALERT_REC(?FATAL, ?INTERNAL_ERROR, badarg)}
523    end;
524verify(THash, Context, HashAlgo, Signature, {?rsaEncryption, PublicKey, _PubKeyParams}) ->
525    Content = build_content(Context, THash),
526
527    %% The length of the Salt MUST be equal to the length of the output
528    %% of the digest algorithm: rsa_pss_saltlen = -1
529    try public_key:verify(Content, HashAlgo, Signature, PublicKey,
530                    [{rsa_padding, rsa_pkcs1_pss_padding},
531                     {rsa_pss_saltlen, -1},
532                     {rsa_mgf1_md, HashAlgo}]) of
533        Result ->
534            {ok, Result}
535    catch
536        error:badarg ->
537            {error, ?ALERT_REC(?FATAL, ?INTERNAL_ERROR, badarg)}
538    end.
539
540
541build_content(Context, THash) ->
542    Prefix = binary:copy(<<32>>, 64),
543    <<Prefix/binary,Context/binary,?BYTE(0),THash/binary>>.
544
545
546%%====================================================================
547%% Handle handshake messages
548%%====================================================================
549
550
551%% TLS Server
552do_start(#client_hello{cipher_suites = ClientCiphers,
553                       session_id = SessionId,
554                       extensions = Extensions} = _Hello,
555         #state{connection_states = _ConnectionStates0,
556                ssl_options = #{ciphers := ServerCiphers,
557                                signature_algs := ServerSignAlgs,
558                                supported_groups := ServerGroups0,
559                                alpn_preferred_protocols := ALPNPreferredProtocols,
560                                honor_cipher_order := HonorCipherOrder},
561                session = #session{own_certificate = Cert}} = State0) ->
562    ClientGroups0 = maps:get(elliptic_curves, Extensions, undefined),
563    ClientGroups = get_supported_groups(ClientGroups0),
564    ServerGroups = get_supported_groups(ServerGroups0),
565
566    ClientShares0 = maps:get(key_share, Extensions, undefined),
567    ClientShares = get_key_shares(ClientShares0),
568
569    OfferedPSKs = get_offered_psks(Extensions),
570
571    ClientALPN0 = maps:get(alpn, Extensions, undefined),
572    ClientALPN = ssl_handshake:decode_alpn(ClientALPN0),
573
574    ClientSignAlgs = get_signature_scheme_list(
575                       maps:get(signature_algs, Extensions, undefined)),
576    ClientSignAlgsCert = get_signature_scheme_list(
577                           maps:get(signature_algs_cert, Extensions, undefined)),
578
579    {Ref,Maybe} = maybe(),
580
581    try
582        %% Handle ALPN extension if ALPN is configured
583        ALPNProtocol = Maybe(handle_alpn(ALPNPreferredProtocols, ClientALPN)),
584
585        %% If the server does not select a PSK, then the server independently selects a
586        %% cipher suite, an (EC)DHE group and key share for key establishment,
587        %% and a signature algorithm/certificate pair to authenticate itself to
588        %% the client.
589        Cipher = Maybe(select_cipher_suite(HonorCipherOrder, ClientCiphers, ServerCiphers)),
590
591        Groups = Maybe(select_common_groups(ServerGroups, ClientGroups)),
592        Maybe(validate_client_key_share(ClientGroups, ClientShares)),
593
594        {PublicKeyAlgo, SignAlgo, SignHash} = get_certificate_params(Cert),
595
596        %% Check if client supports signature algorithm of server certificate
597        Maybe(check_cert_sign_algo(SignAlgo, SignHash, ClientSignAlgs, ClientSignAlgsCert)),
598
599        %% Select signature algorithm (used in CertificateVerify message).
600        SelectedSignAlg = Maybe(select_sign_algo(PublicKeyAlgo, ClientSignAlgs, ServerSignAlgs)),
601
602        %% Select client public key. If no public key found in ClientShares or
603        %% ClientShares is empty, trigger HelloRetryRequest as we were able
604        %% to find an acceptable set of parameters but the ClientHello does not
605        %% contain sufficient information.
606        {Group, ClientPubKey} = get_client_public_key(Groups, ClientShares),
607
608        %% Generate server_share
609        KeyShare = ssl_cipher:generate_server_share(Group),
610
611        State1 = update_start_state(State0,
612                                    #{cipher => Cipher,
613                                      key_share => KeyShare,
614                                      session_id => SessionId,
615                                      group => Group,
616                                      sign_alg => SelectedSignAlg,
617                                      peer_public_key => ClientPubKey,
618                                      alpn => ALPNProtocol}),
619
620        %% 4.1.4.  Hello Retry Request
621        %%
622        %% The server will send this message in response to a ClientHello
623        %% message if it is able to find an acceptable set of parameters but the
624        %% ClientHello does not contain sufficient information to proceed with
625        %% the handshake.
626        case Maybe(send_hello_retry_request(State1, ClientPubKey, KeyShare, SessionId)) of
627            {_, start} = NextStateTuple ->
628                NextStateTuple;
629            {_, negotiated} = NextStateTuple ->
630                %% Exclude any incompatible PSKs.
631                PSK = Maybe(handle_pre_shared_key(State1, OfferedPSKs, Cipher)),
632                Maybe(session_resumption(NextStateTuple, PSK))
633        end
634    catch
635        {Ref, #alert{} = Alert} ->
636            Alert
637    end;
638%% TLS Client
639do_start(#server_hello{cipher_suite = SelectedCipherSuite,
640                       session_id = SessionId,
641                       extensions = Extensions},
642         #state{static_env = #static_env{role = client,
643                                         host = Host,
644                                         port = Port,
645                                         transport_cb = Transport,
646                                         socket = Socket},
647                handshake_env = #handshake_env{renegotiation = {Renegotiation, _}} = HsEnv,
648                connection_env = #connection_env{negotiated_version = NegotiatedVersion},
649                ssl_options = #{ciphers := ClientCiphers,
650                                supported_groups := ClientGroups0,
651                                use_ticket := UseTicket,
652                                session_tickets := SessionTickets,
653                                log_level := LogLevel} = SslOpts,
654                session = #session{own_certificate = Cert} = Session0,
655                connection_states = ConnectionStates0
656               } = State0) ->
657    ClientGroups = get_supported_groups(ClientGroups0),
658
659    {Ref,Maybe} = maybe(),
660    try
661        ServerKeyShare = maps:get(key_share, Extensions, undefined),
662        SelectedGroup = get_selected_group(ServerKeyShare),
663
664        %% Upon receipt of this extension in a HelloRetryRequest, the client
665        %% MUST verify that (1) the selected_group field corresponds to a group
666        %% which was provided in the "supported_groups" extension in the
667        %% original ClientHello and (2) the selected_group field does not
668        %% correspond to a group which was provided in the "key_share" extension
669        %% in the original ClientHello.  If either of these checks fails, then
670        %% the client MUST abort the handshake with an "illegal_parameter"
671        %% alert.
672        Maybe(validate_selected_group(SelectedGroup, ClientGroups)),
673
674        Maybe(validate_cipher_suite(SelectedCipherSuite, ClientCiphers)),
675
676        %% Otherwise, when sending the new ClientHello, the client MUST
677        %% replace the original "key_share" extension with one containing only a
678        %% new KeyShareEntry for the group indicated in the selected_group field
679        %% of the triggering HelloRetryRequest.
680        ClientKeyShare = ssl_cipher:generate_client_shares([SelectedGroup]),
681        TicketData = get_ticket_data(self(), SessionTickets, UseTicket),
682        Hello0 = tls_handshake:client_hello(Host, Port, ConnectionStates0, SslOpts,
683                                           SessionId, Renegotiation, Cert, ClientKeyShare,
684                                           TicketData),
685
686        %% Update state
687        State1 = update_start_state(State0,
688                                    #{cipher => SelectedCipherSuite,
689                                      key_share => ClientKeyShare,
690                                      session_id => SessionId,
691                                      group => SelectedGroup}),
692
693        %% Replace ClientHello1 with a special synthetic handshake message
694        State2 = replace_ch1_with_message_hash(State1),
695        #state{handshake_env = #handshake_env{tls_handshake_history = HHistory0}} = State2,
696
697        %% Update pre_shared_key extension with binders (TLS 1.3)
698        Hello = tls_handshake_1_3:maybe_add_binders(Hello0, HHistory0, TicketData, NegotiatedVersion),
699
700        {BinMsg, ConnectionStates, HHistory} =
701            tls_connection:encode_handshake(Hello,  NegotiatedVersion, ConnectionStates0, HHistory0),
702        tls_socket:send(Transport, Socket, BinMsg),
703        ssl_logger:debug(LogLevel, outbound, 'handshake', Hello),
704        ssl_logger:debug(LogLevel, outbound, 'record', BinMsg),
705
706        State = State2#state{
707                  connection_states = ConnectionStates,
708                  session = Session0#session{session_id = Hello#client_hello.session_id},
709                  handshake_env = HsEnv#handshake_env{tls_handshake_history = HHistory},
710                  key_share = ClientKeyShare},
711
712        {State, wait_sh}
713
714    catch
715        {Ref, #alert{} = Alert} ->
716            Alert
717    end.
718
719
720do_negotiated({start_handshake, PSK0},
721              #state{connection_states = ConnectionStates0,
722                     session = #session{session_id = SessionId,
723                                        ecc = SelectedGroup,
724                                        dh_public_value = ClientPublicKey},
725                     ssl_options = #{} = SslOpts,
726                     key_share = KeyShare} = State0) ->
727    ServerPrivateKey = get_server_private_key(KeyShare),
728
729    #{security_parameters := SecParamsR} =
730        ssl_record:pending_connection_state(ConnectionStates0, read),
731    #security_parameters{prf_algorithm = HKDF} = SecParamsR,
732
733
734    {Ref,Maybe} = maybe(),
735    try
736        %% Create server_hello
737        ServerHello = server_hello(server_hello, SessionId, KeyShare, PSK0, ConnectionStates0),
738
739        {State1, _} = tls_connection:send_handshake(ServerHello, State0),
740
741        PSK = get_pre_shared_key(PSK0, HKDF),
742
743        State2 =
744            calculate_handshake_secrets(ClientPublicKey, ServerPrivateKey, SelectedGroup,
745                                        PSK, State1),
746
747        State3 = ssl_record:step_encryption_state(State2),
748
749        %% Create EncryptedExtensions
750        EncryptedExtensions = encrypted_extensions(State2),
751
752        %% Encode EncryptedExtensions
753        State4 = tls_connection:queue_handshake(EncryptedExtensions, State3),
754
755        %% Create and send CertificateRequest ({verify, verify_peer})
756        {State5, NextState} = maybe_send_certificate_request(State4, SslOpts, PSK0),
757
758        %% Create and send Certificate (if PSK is undefined)
759        State6 = Maybe(maybe_send_certificate(State5, PSK0)),
760
761        %% Create and send CertificateVerify (if PSK is undefined)
762        State7 = Maybe(maybe_send_certificate_verify(State6, PSK0)),
763
764        %% Create Finished
765        Finished = finished(State7),
766
767        %% Encode Finished
768        State8 = tls_connection:queue_handshake(Finished, State7),
769
770        %% Send first flight
771        {State9, _} = tls_connection:send_handshake_flight(State8),
772
773        {State9, NextState}
774
775    catch
776        {Ref, #alert{} = Alert} ->
777            Alert
778    end.
779
780
781do_wait_cert(#certificate_1_3{} = Certificate, State0) ->
782    {Ref,Maybe} = maybe(),
783    try
784        Maybe(process_certificate(Certificate, State0))
785    catch
786        {Ref, #alert{} = Alert} ->
787            {Alert, State0};
788        {Ref, {#alert{} = Alert, State}} ->
789            {Alert, State}
790    end.
791
792
793do_wait_cv(#certificate_verify_1_3{} = CertificateVerify, State0) ->
794    {Ref,Maybe} = maybe(),
795    try
796        State1 = Maybe(verify_signature_algorithm(State0, CertificateVerify)),
797        Maybe(verify_certificate_verify(State1, CertificateVerify))
798    catch
799        {Ref, {#alert{} = Alert, State}} ->
800            {Alert, State}
801    end.
802
803%% TLS Server
804do_wait_finished(#finished{verify_data = VerifyData},
805                 #state{static_env = #static_env{role = server}} = State0) ->
806    {Ref,Maybe} = maybe(),
807
808    try
809        Maybe(validate_finished(State0, VerifyData)),
810
811        State1 = calculate_traffic_secrets(State0),
812        State2 = maybe_calculate_resumption_master_secret(State1),
813        State3 = forget_master_secret(State2),
814
815        %% Configure traffic keys
816        State4 = ssl_record:step_encryption_state(State3),
817
818        %% Send session ticket
819        maybe_send_session_ticket(State4)
820
821    catch
822        {Ref, #alert{} = Alert} ->
823            Alert
824    end;
825%% TLS Client
826do_wait_finished(#finished{verify_data = VerifyData},
827                 #state{static_env = #static_env{role = client}} = State0) ->
828
829    {Ref,Maybe} = maybe(),
830
831    try
832        Maybe(validate_finished(State0, VerifyData)),
833
834        %% Maybe send Certificate + CertificateVerify
835        State1 = Maybe(maybe_queue_cert_cert_cv(State0)),
836
837        Finished = finished(State1),
838
839        %% Encode Finished
840        State2 = tls_connection:queue_handshake(Finished, State1),
841
842        %% Send first flight
843        {State3, _} = tls_connection:send_handshake_flight(State2),
844
845        State4 = calculate_traffic_secrets(State3),
846        State5 = maybe_calculate_resumption_master_secret(State4),
847        State6 = forget_master_secret(State5),
848
849        %% Configure traffic keys
850        ssl_record:step_encryption_state(State6)
851
852    catch
853        {Ref, #alert{} = Alert} ->
854            Alert
855    end.
856
857
858do_wait_sh(#server_hello{cipher_suite = SelectedCipherSuite,
859                         session_id = SessionId,
860                         extensions = Extensions} = ServerHello,
861           #state{key_share = ClientKeyShare0,
862                  ssl_options = #{ciphers := ClientCiphers,
863                                  supported_groups := ClientGroups0,
864                                  session_tickets := SessionTickets,
865                                  use_ticket := UseTicket}} = State0) ->
866    ClientGroups = get_supported_groups(ClientGroups0),
867    ServerKeyShare0 = maps:get(key_share, Extensions, undefined),
868    ServerPreSharedKey = maps:get(pre_shared_key, Extensions, undefined),
869    SelectedIdentity = get_selected_identity(ServerPreSharedKey),
870    ClientKeyShare = get_key_shares(ClientKeyShare0),
871
872    {Ref,Maybe} = maybe(),
873    try
874        %% Go to state 'start' if server replies with 'HelloRetryRequest'.
875        Maybe(maybe_hello_retry_request(ServerHello, State0)),
876
877        %% Resumption and PSK
878        State1 = handle_resumption(State0, SelectedIdentity),
879        ServerKeyShare = get_key_shares(ServerKeyShare0),
880
881        Maybe(validate_cipher_suite(SelectedCipherSuite, ClientCiphers)),
882        Maybe(validate_server_key_share(ClientGroups, ServerKeyShare)),
883
884        %% Get server public key
885        {SelectedGroup, ServerPublicKey} = get_server_public_key(ServerKeyShare),
886
887        {_, ClientPrivateKey} = get_client_private_key([SelectedGroup], ClientKeyShare),
888
889        %% Update state
890        State2 = update_start_state(State1,
891                                    #{cipher => SelectedCipherSuite,
892                                     key_share => ClientKeyShare0,
893                                     session_id => SessionId,
894                                     group => SelectedGroup,
895                                     peer_public_key => ServerPublicKey}),
896
897        #state{connection_states = ConnectionStates} = State2,
898        #{security_parameters := SecParamsR} =
899        ssl_record:pending_connection_state(ConnectionStates, read),
900        #security_parameters{prf_algorithm = HKDFAlgo} = SecParamsR,
901
902        PSK = Maybe(get_pre_shared_key(SessionTickets, UseTicket, HKDFAlgo, SelectedIdentity)),
903        State3 = calculate_handshake_secrets(ServerPublicKey, ClientPrivateKey, SelectedGroup,
904                                             PSK, State2),
905        State4 = ssl_record:step_encryption_state(State3),
906
907        {State4, wait_ee}
908
909    catch
910        {Ref, {State, StateName, ServerHello}} ->
911            {State, StateName, ServerHello};
912        {Ref, #alert{} = Alert} ->
913            Alert
914    end.
915
916
917do_wait_ee(#encrypted_extensions{extensions = Extensions}, State0) ->
918
919    ALPNProtocol0 = maps:get(alpn, Extensions, undefined),
920    ALPNProtocol = get_alpn(ALPNProtocol0),
921
922    {Ref, Maybe} = maybe(),
923
924    try
925        %% Go to state 'wait_finished' if using PSK.
926        Maybe(maybe_resumption(State0)),
927
928        %% Update state
929        #state{handshake_env = HsEnv} = State0,
930        State1 = State0#state{handshake_env = HsEnv#handshake_env{alpn = ALPNProtocol}},
931
932        {State1, wait_cert_cr}
933    catch
934        {Ref, {State, StateName}} ->
935            {State, StateName}
936    end.
937
938
939do_wait_cert_cr(#certificate_1_3{} = Certificate, State0) ->
940    {Ref,Maybe} = maybe(),
941    try
942        Maybe(process_certificate(Certificate, State0))
943    catch
944        {Ref, #alert{} = Alert} ->
945            {Alert, State0};
946        {Ref, {#alert{} = Alert, State}} ->
947            {Alert, State}
948    end;
949do_wait_cert_cr(#certificate_request_1_3{} = CertificateRequest, State0) ->
950    {Ref,Maybe} = maybe(),
951    try
952        Maybe(process_certificate_request(CertificateRequest, State0))
953    catch
954        {Ref, #alert{} = Alert} ->
955            {Alert, State0}
956    end.
957
958
959%% For reasons of backward compatibility with middleboxes (see
960%% Appendix D.4), the HelloRetryRequest message uses the same structure
961%% as the ServerHello, but with Random set to the special value of the
962%% SHA-256 of "HelloRetryRequest":
963%%
964%%   CF 21 AD 74 E5 9A 61 11 BE 1D 8C 02 1E 65 B8 91
965%%   C2 A2 11 16 7A BB 8C 5E 07 9E 09 E2 C8 A8 33 9C
966%%
967%% Upon receiving a message with type server_hello, implementations MUST
968%% first examine the Random value and, if it matches this value, process
969%% it as described in Section 4.1.4).
970maybe_hello_retry_request(#server_hello{random = ?HELLO_RETRY_REQUEST_RANDOM} = ServerHello, State0) ->
971    {error, {State0, start, ServerHello}};
972maybe_hello_retry_request(_, _) ->
973    ok.
974
975
976maybe_resumption(#state{handshake_env = #handshake_env{resumption = true}} = State) ->
977    {error, {State, wait_finished}};
978maybe_resumption(_) ->
979    ok.
980
981
982handle_resumption(State, undefined) ->
983    State;
984handle_resumption(#state{handshake_env = HSEnv0} = State, _) ->
985    HSEnv = HSEnv0#handshake_env{resumption = true},
986    State#state{handshake_env = HSEnv}.
987
988
989maybe_queue_cert_cert_cv(#state{client_certificate_requested = false} = State) ->
990    {ok, State};
991maybe_queue_cert_cert_cv(#state{connection_states = _ConnectionStates0,
992                                session = #session{session_id = _SessionId,
993                                                   own_certificate = OwnCert},
994                                ssl_options = #{} = _SslOpts,
995                                key_share = _KeyShare,
996                                handshake_env = #handshake_env{tls_handshake_history = _HHistory0},
997                                static_env = #static_env{
998                                                role = client,
999                                                cert_db = CertDbHandle,
1000                                                cert_db_ref = CertDbRef,
1001                                                socket = _Socket,
1002                                                transport_cb = _Transport}
1003                               } = State0) ->
1004    {Ref,Maybe} = maybe(),
1005    try
1006        %% Create Certificate
1007        Certificate = Maybe(certificate(OwnCert, CertDbHandle, CertDbRef, <<>>, client)),
1008
1009        %% Encode Certificate
1010        State1 = tls_connection:queue_handshake(Certificate, State0),
1011
1012        %% Maybe create and queue CertificateVerify
1013        State = Maybe(maybe_queue_cert_verify(Certificate, State1)),
1014        {ok, State}
1015    catch
1016        {Ref, #alert{} = Alert} ->
1017            {error, Alert}
1018    end.
1019
1020
1021%% Clients MUST send this message whenever authenticating via a certificate
1022%% (i.e., when the Certificate message is non-empty).
1023maybe_queue_cert_verify(#certificate_1_3{certificate_list = []}, State) ->
1024    {ok, State};
1025maybe_queue_cert_verify(_Certificate,
1026                        #state{connection_states = _ConnectionStates0,
1027                               session = #session{sign_alg = SignatureScheme},
1028                               connection_env = #connection_env{private_key = CertPrivateKey},
1029                               static_env = #static_env{role = client}
1030                              } = State) ->
1031    {Ref,Maybe} = maybe(),
1032    try
1033        CertificateVerify = Maybe(certificate_verify(CertPrivateKey, SignatureScheme, State, client)),
1034        {ok, tls_connection:queue_handshake(CertificateVerify, State)}
1035    catch
1036        {Ref, #alert{} = Alert} ->
1037            {error, Alert}
1038    end.
1039
1040
1041%% Recipients of Finished messages MUST verify that the contents are
1042%% correct and if incorrect MUST terminate the connection with a
1043%% "decrypt_error" alert.
1044validate_finished(#state{connection_states = ConnectionStates,
1045                         handshake_env =
1046                             #handshake_env{
1047                                tls_handshake_history = {Messages0, _}}}, VerifyData) ->
1048    #{security_parameters := SecParamsR,
1049      cipher_state := #cipher_state{finished_key = FinishedKey}} =
1050        ssl_record:current_connection_state(ConnectionStates, read),
1051    #security_parameters{prf_algorithm = HKDFAlgo} = SecParamsR,
1052
1053    %% Drop the peer's finished message, it is not part of the handshake context
1054    %% when the client/server calculates its finished message.
1055    [_|Messages] = Messages0,
1056
1057    ControlData = tls_v1:finished_verify_data(FinishedKey, HKDFAlgo, Messages),
1058    compare_verify_data(ControlData, VerifyData).
1059
1060
1061compare_verify_data(Data, Data) ->
1062    ok;
1063compare_verify_data(_, _) ->
1064    {error, ?ALERT_REC(?FATAL, ?DECRYPT_ERROR, decrypt_error)}.
1065
1066
1067send_hello_retry_request(#state{connection_states = ConnectionStates0} = State0,
1068                         no_suitable_key, KeyShare, SessionId) ->
1069    ServerHello = server_hello(hello_retry_request, SessionId, KeyShare, undefined, ConnectionStates0),
1070    {State1, _} = tls_connection:send_handshake(ServerHello, State0),
1071
1072    %% Update handshake history
1073    State2 = replace_ch1_with_message_hash(State1),
1074
1075    {ok, {State2, start}};
1076send_hello_retry_request(State0, _, _, _) ->
1077    %% Suitable key found.
1078    {ok, {State0, negotiated}}.
1079
1080session_resumption({#state{ssl_options = #{session_tickets := disabled}} = State, negotiated}, _) ->
1081    {ok, {State, negotiated}};
1082session_resumption({#state{ssl_options = #{session_tickets := Tickets}} = State, negotiated}, undefined)
1083  when Tickets =/= disabled ->
1084    {ok, {State, negotiated}};
1085session_resumption({#state{ssl_options = #{session_tickets := Tickets}} = State0, negotiated}, PSK)
1086  when Tickets =/= disabled ->
1087    State = handle_resumption(State0, ok),
1088    {ok, {State, negotiated, PSK}}.
1089
1090
1091%% Do not send CR during session resumption
1092maybe_send_certificate_request(State, _, PSK) when PSK =/= undefined ->
1093    {State, wait_finished};
1094maybe_send_certificate_request(State, #{verify := verify_none}, _) ->
1095    {State, wait_finished};
1096maybe_send_certificate_request(State, #{verify := verify_peer,
1097                                        signature_algs := SignAlgs,
1098                                        signature_algs_cert := SignAlgsCert}, _) ->
1099    CertificateRequest = certificate_request(SignAlgs, SignAlgsCert),
1100    {tls_connection:queue_handshake(CertificateRequest, State), wait_cert}.
1101
1102
1103maybe_send_certificate(State, PSK) when  PSK =/= undefined ->
1104    {ok, State};
1105maybe_send_certificate(#state{session = #session{own_certificate = OwnCert},
1106                              static_env = #static_env{
1107                                              cert_db = CertDbHandle,
1108                                              cert_db_ref = CertDbRef}} = State, _) ->
1109    case certificate(OwnCert, CertDbHandle, CertDbRef, <<>>, server) of
1110        {ok, Certificate} ->
1111            {ok, tls_connection:queue_handshake(Certificate, State)};
1112        Error ->
1113            Error
1114    end.
1115
1116
1117maybe_send_certificate_verify(State, PSK) when  PSK =/= undefined ->
1118    {ok, State};
1119maybe_send_certificate_verify(#state{session = #session{sign_alg = SignatureScheme},
1120                                     connection_env = #connection_env{
1121                                                         private_key = CertPrivateKey}} = State, _) ->
1122    case certificate_verify(CertPrivateKey, SignatureScheme, State, server) of
1123        {ok, CertificateVerify} ->
1124            {ok, tls_connection:queue_handshake(CertificateVerify, State)};
1125        Error ->
1126            Error
1127    end.
1128
1129
1130maybe_send_session_ticket(State) ->
1131    Number = case application:get_env(ssl, server_session_tickets_amount) of
1132                 {ok, Size} when is_integer(Size) andalso
1133                                 Size > 0 ->
1134                     Size;
1135                 _  ->
1136                     3
1137             end,
1138    maybe_send_session_ticket(State, Number).
1139%%
1140maybe_send_session_ticket(#state{ssl_options = #{session_tickets := disabled}} = State, _) ->
1141    %% Do nothing!
1142    State;
1143maybe_send_session_ticket(State, 0) ->
1144    State;
1145maybe_send_session_ticket(#state{connection_states = ConnectionStates,
1146                                 static_env = #static_env{trackers = Trackers}} = State0, N) ->
1147    Tracker = proplists:get_value(session_tickets_tracker, Trackers),
1148    #{security_parameters := SecParamsR} =
1149        ssl_record:current_connection_state(ConnectionStates, read),
1150    #security_parameters{prf_algorithm = HKDF,
1151                         resumption_master_secret = RMS} = SecParamsR,
1152    Ticket = tls_server_session_ticket:new(Tracker, HKDF, RMS),
1153    {State, _} = tls_connection:send_handshake(Ticket, State0),
1154    maybe_send_session_ticket(State, N - 1).
1155
1156process_certificate_request(#certificate_request_1_3{},
1157                            #state{session = #session{own_certificate = undefined}} = State) ->
1158    {ok, {State#state{client_certificate_requested = true}, wait_cert}};
1159
1160process_certificate_request(#certificate_request_1_3{
1161                              extensions = Extensions},
1162                            #state{session = #session{own_certificate = Cert} = Session} = State) ->
1163    ServerSignAlgs = get_signature_scheme_list(
1164                       maps:get(signature_algs, Extensions, undefined)),
1165    ServerSignAlgsCert = get_signature_scheme_list(
1166                           maps:get(signature_algs_cert, Extensions, undefined)),
1167
1168    {_PublicKeyAlgo, SignAlgo, SignHash} = get_certificate_params(Cert),
1169
1170    %% Check if server supports signature algorithm of client certificate
1171    case check_cert_sign_algo(SignAlgo, SignHash, ServerSignAlgs, ServerSignAlgsCert) of
1172        ok ->
1173            {ok, {State#state{client_certificate_requested = true}, wait_cert}};
1174        {error, _} ->
1175            %% Certificate not supported: send empty certificate in state 'wait_finished'
1176            {ok, {State#state{client_certificate_requested = true,
1177                              session = Session#session{own_certificate = undefined}}, wait_cert}}
1178    end.
1179
1180
1181process_certificate(#certificate_1_3{
1182                       certificate_request_context = <<>>,
1183                       certificate_list = []},
1184                    #state{ssl_options =
1185                               #{fail_if_no_peer_cert := false}} = State) ->
1186    {ok, {State, wait_finished}};
1187process_certificate(#certificate_1_3{
1188                       certificate_request_context = <<>>,
1189                       certificate_list = []},
1190                    #state{ssl_options =
1191                               #{fail_if_no_peer_cert := true}} = State0) ->
1192
1193    %% At this point the client believes that the connection is up and starts using
1194    %% its traffic secrets. In order to be able send an proper Alert to the client
1195    %% the server should also change its connection state and use the traffic
1196    %% secrets.
1197    State1 = calculate_traffic_secrets(State0),
1198    State = ssl_record:step_encryption_state(State1),
1199    {error, {?ALERT_REC(?FATAL, ?CERTIFICATE_REQUIRED, certificate_required), State}};
1200process_certificate(#certificate_1_3{certificate_list = Certs0},
1201                    #state{ssl_options =
1202                               #{signature_algs := SignAlgs,
1203                                 signature_algs_cert := SignAlgsCert} = SslOptions,
1204                           static_env =
1205                               #static_env{
1206                                  role = Role,
1207                                  host = Host,
1208                                  cert_db = CertDbHandle,
1209                                  cert_db_ref = CertDbRef,
1210                                  crl_db = CRLDbHandle}} = State0) ->
1211    %% TODO: handle extensions!
1212    %% Remove extensions from list of certificates!
1213    Certs = convert_certificate_chain(Certs0),
1214    case is_supported_signature_algorithm(Certs, SignAlgs, SignAlgsCert) of
1215        true ->
1216            case validate_certificate_chain(Certs, CertDbHandle, CertDbRef,
1217                                            SslOptions, CRLDbHandle, Role, Host) of
1218                {ok, {PeerCert, PublicKeyInfo}} ->
1219                    State = store_peer_cert(State0, PeerCert, PublicKeyInfo),
1220                    {ok, {State, wait_cv}};
1221                {error, Reason} ->
1222                    State = update_encryption_state(Role, State0),
1223                    {error, {Reason, State}};
1224                {ok, #alert{} = Alert} ->
1225                    State = update_encryption_state(Role, State0),
1226                    {error, {Alert, State}}
1227            end;
1228        false ->
1229            State1 = calculate_traffic_secrets(State0),
1230            State = ssl_record:step_encryption_state(State1),
1231            {error, {?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE,
1232                                "Client certificate uses unsupported signature algorithm"), State}}
1233    end.
1234
1235
1236%% TODO: check whole chain!
1237is_supported_signature_algorithm(Certs, SignAlgs, undefined) ->
1238    is_supported_signature_algorithm(Certs, SignAlgs);
1239is_supported_signature_algorithm(Certs, _, SignAlgsCert) ->
1240    is_supported_signature_algorithm(Certs, SignAlgsCert).
1241%%
1242is_supported_signature_algorithm([BinCert|_], SignAlgs0) ->
1243    #'OTPCertificate'{signatureAlgorithm = SignAlg} =
1244        public_key:pkix_decode_cert(BinCert, otp),
1245    SignAlgs = filter_tls13_algs(SignAlgs0),
1246    Scheme = ssl_cipher:signature_algorithm_to_scheme(SignAlg),
1247    lists:member(Scheme, SignAlgs).
1248
1249
1250%% Sets correct encryption state when sending Alerts in shared states that use different secrets.
1251%% - If client: use handshake secrets.
1252%% - If server: use traffic secrets as by this time the client's state machine
1253%%              already stepped into the 'connection' state.
1254update_encryption_state(server, State0) ->
1255    State1 = calculate_traffic_secrets(State0),
1256    ssl_record:step_encryption_state(State1);
1257update_encryption_state(client, State) ->
1258    State.
1259
1260
1261validate_certificate_chain(Certs, CertDbHandle, CertDbRef,
1262                           #{server_name_indication := ServerNameIndication,
1263                             partial_chain := PartialChain,
1264                             verify_fun := VerifyFun,
1265                             customize_hostname_check := CustomizeHostnameCheck,
1266                             crl_check := CrlCheck,
1267                             log_level := LogLevel,
1268                             depth := Depth} = SslOptions,
1269                           CRLDbHandle, Role, Host) ->
1270    ServerName = ssl_handshake:server_name(ServerNameIndication, Host, Role),
1271    [PeerCert | ChainCerts ] = Certs,
1272    try
1273	{TrustedCert, CertPath}  =
1274	    ssl_certificate:trusted_cert_and_path(Certs, CertDbHandle, CertDbRef,
1275                                                  PartialChain),
1276        ValidationFunAndState =
1277            ssl_handshake:validation_fun_and_state(VerifyFun, Role,
1278                                     CertDbHandle, CertDbRef, ServerName,
1279                                     CustomizeHostnameCheck,
1280                                     CrlCheck, CRLDbHandle, CertPath, LogLevel),
1281        Options = [{max_path_length, Depth},
1282                   {verify_fun, ValidationFunAndState}],
1283        %% TODO: Validate if Certificate is using a supported signature algorithm
1284        %% (signature_algs_cert)!
1285        case public_key:pkix_path_validation(TrustedCert, CertPath, Options) of
1286            {ok, {PublicKeyInfo,_}} ->
1287                {ok, {PeerCert, PublicKeyInfo}};
1288            {error, Reason} ->
1289                {ok, ssl_handshake:handle_path_validation_error(Reason, PeerCert, ChainCerts,
1290                                                                SslOptions, Options,
1291                                                                CertDbHandle, CertDbRef)}
1292        end
1293    catch
1294        error:{badmatch,{error, {asn1, Asn1Reason}}} ->
1295            %% ASN-1 decode of certificate somehow failed
1296            {error, ?ALERT_REC(?FATAL, ?CERTIFICATE_UNKNOWN, {failed_to_decode_certificate, Asn1Reason})};
1297        error:OtherReason ->
1298            {error, ?ALERT_REC(?FATAL, ?INTERNAL_ERROR, {unexpected_error, OtherReason})}
1299    end.
1300
1301
1302store_peer_cert(#state{session = Session,
1303                       handshake_env = HsEnv} = State, PeerCert, PublicKeyInfo) ->
1304    State#state{session = Session#session{peer_certificate = PeerCert},
1305                handshake_env = HsEnv#handshake_env{public_key_info = PublicKeyInfo}}.
1306
1307
1308convert_certificate_chain(Certs) ->
1309    Fun = fun(#certificate_entry{data = Data}) ->
1310                  {true, Data};
1311             (_) ->
1312                  false
1313          end,
1314    lists:filtermap(Fun, Certs).
1315
1316
1317%% 4.4.1.  The Transcript Hash
1318%%
1319%% As an exception to this general rule, when the server responds to a
1320%% ClientHello with a HelloRetryRequest, the value of ClientHello1 is
1321%% replaced with a special synthetic handshake message of handshake type
1322%% "message_hash" containing Hash(ClientHello1).  I.e.,
1323%%
1324%% Transcript-Hash(ClientHello1, HelloRetryRequest, ... Mn) =
1325%%    Hash(message_hash ||        /* Handshake type */
1326%%         00 00 Hash.length  ||  /* Handshake message length (bytes) */
1327%%         Hash(ClientHello1) ||  /* Hash of ClientHello1 */
1328%%         HelloRetryRequest  || ... || Mn)
1329%%
1330%% NOTE: Hash.length is used in practice (openssl) and not message length!
1331%%       It is most probably a fault in the RFC.
1332replace_ch1_with_message_hash(#state{connection_states = ConnectionStates,
1333                                     handshake_env =
1334                                         #handshake_env{
1335                                            tls_handshake_history =
1336                                                {[HRR,CH1|HHistory], LM}} = HSEnv}  = State0) ->
1337    #{security_parameters := SecParamsR} =
1338        ssl_record:pending_connection_state(ConnectionStates, read),
1339    #security_parameters{prf_algorithm = HKDFAlgo} = SecParamsR,
1340    MessageHash = message_hash(CH1, HKDFAlgo),
1341    State0#state{handshake_env =
1342                     HSEnv#handshake_env{
1343                        tls_handshake_history =
1344                            {[HRR,MessageHash|HHistory], LM}}}.
1345
1346
1347message_hash(ClientHello1, HKDFAlgo) ->
1348    [?MESSAGE_HASH,
1349     0,0,ssl_cipher:hash_size(HKDFAlgo),
1350     crypto:hash(HKDFAlgo, ClientHello1)].
1351
1352
1353calculate_handshake_secrets(PublicKey, PrivateKey, SelectedGroup, PSK,
1354                              #state{connection_states = ConnectionStates,
1355                                     handshake_env =
1356                                         #handshake_env{
1357                                            tls_handshake_history = HHistory}} = State0) ->
1358    #{security_parameters := SecParamsR} =
1359        ssl_record:pending_connection_state(ConnectionStates, read),
1360    #security_parameters{prf_algorithm = HKDFAlgo,
1361                         cipher_suite = CipherSuite} = SecParamsR,
1362    EarlySecret = tls_v1:key_schedule(early_secret, HKDFAlgo , {psk, PSK}),
1363
1364    IKM = calculate_shared_secret(PublicKey, PrivateKey, SelectedGroup),
1365    HandshakeSecret = tls_v1:key_schedule(handshake_secret, HKDFAlgo, IKM, EarlySecret),
1366
1367    %% Calculate [sender]_handshake_traffic_secret
1368    {Messages, _} =  HHistory,
1369
1370    ClientHSTrafficSecret =
1371        tls_v1:client_handshake_traffic_secret(HKDFAlgo, HandshakeSecret, lists:reverse(Messages)),
1372    ServerHSTrafficSecret =
1373        tls_v1:server_handshake_traffic_secret(HKDFAlgo, HandshakeSecret, lists:reverse(Messages)),
1374
1375    %% Calculate traffic keys
1376    #{cipher := Cipher} = ssl_cipher_format:suite_bin_to_map(CipherSuite),
1377    {ReadKey, ReadIV} = tls_v1:calculate_traffic_keys(HKDFAlgo, Cipher, ClientHSTrafficSecret),
1378    {WriteKey, WriteIV} = tls_v1:calculate_traffic_keys(HKDFAlgo, Cipher, ServerHSTrafficSecret),
1379
1380    %% Calculate Finished Keys
1381    ReadFinishedKey = tls_v1:finished_key(ClientHSTrafficSecret, HKDFAlgo),
1382    WriteFinishedKey = tls_v1:finished_key(ServerHSTrafficSecret, HKDFAlgo),
1383
1384    update_pending_connection_states(State0, HandshakeSecret, undefined,
1385                                     undefined, undefined,
1386                                     ReadKey, ReadIV, ReadFinishedKey,
1387                                     WriteKey, WriteIV, WriteFinishedKey).
1388
1389
1390%% Server
1391get_pre_shared_key(undefined, HKDFAlgo) ->
1392    binary:copy(<<0>>, ssl_cipher:hash_size(HKDFAlgo));
1393get_pre_shared_key({_, PSK}, _) ->
1394    PSK.
1395%%
1396%% Client
1397%% Server initiates a full handshake
1398get_pre_shared_key(_, _, HKDFAlgo, undefined) ->
1399    {ok, binary:copy(<<0>>, ssl_cipher:hash_size(HKDFAlgo))};
1400%% Session resumption not configured
1401get_pre_shared_key(undefined, _, HKDFAlgo, _) ->
1402    {ok, binary:copy(<<0>>, ssl_cipher:hash_size(HKDFAlgo))};
1403get_pre_shared_key(_, undefined, HKDFAlgo, _) ->
1404    {ok, binary:copy(<<0>>, ssl_cipher:hash_size(HKDFAlgo))};
1405%% Session resumption
1406get_pre_shared_key(manual = SessionTickets, UseTicket, HKDFAlgo, SelectedIdentity) ->
1407    TicketData = get_ticket_data(self(), SessionTickets, UseTicket),
1408    case choose_psk(TicketData, SelectedIdentity) of
1409        undefined -> %% full handshake, default PSK
1410            {ok, binary:copy(<<0>>, ssl_cipher:hash_size(HKDFAlgo))};
1411        illegal_parameter ->
1412            {error, ?ALERT_REC(?FATAL, ?ILLEGAL_PARAMETER)};
1413        {_, PSK} ->
1414            {ok, PSK}
1415    end;
1416get_pre_shared_key(auto = SessionTickets, UseTicket, HKDFAlgo, SelectedIdentity) ->
1417    TicketData = get_ticket_data(self(), SessionTickets, UseTicket),
1418    case choose_psk(TicketData, SelectedIdentity) of
1419        undefined -> %% full handshake, default PSK
1420            tls_client_ticket_store:unlock_tickets(self(), UseTicket),
1421            {ok, binary:copy(<<0>>, ssl_cipher:hash_size(HKDFAlgo))};
1422        illegal_parameter ->
1423            tls_client_ticket_store:unlock_tickets(self(), UseTicket),
1424            {error, ?ALERT_REC(?FATAL, ?ILLEGAL_PARAMETER)};
1425        {Key, PSK} ->
1426            tls_client_ticket_store:remove_tickets([Key]),  %% Remove single-use ticket
1427            tls_client_ticket_store:unlock_tickets(self(), UseTicket -- [Key]),
1428            {ok, PSK}
1429    end.
1430
1431
1432choose_psk(undefined, _) ->
1433    undefined;
1434choose_psk([], _) ->
1435    illegal_parameter;
1436choose_psk([{Key, SelectedIdentity, _, PSK, _, _}|_], SelectedIdentity) ->
1437    {Key, PSK};
1438choose_psk([_|T], SelectedIdentity) ->
1439    choose_psk(T, SelectedIdentity).
1440
1441
1442calculate_traffic_secrets(#state{
1443                             static_env = #static_env{role = Role},
1444                             connection_states = ConnectionStates,
1445                             handshake_env =
1446                                 #handshake_env{
1447                                    tls_handshake_history = HHistory}} = State0) ->
1448    #{security_parameters := SecParamsR} =
1449        ssl_record:pending_connection_state(ConnectionStates, read),
1450    #security_parameters{prf_algorithm = HKDFAlgo,
1451                         cipher_suite = CipherSuite,
1452                         master_secret = HandshakeSecret} = SecParamsR,
1453
1454    MasterSecret =
1455        tls_v1:key_schedule(master_secret, HKDFAlgo, HandshakeSecret),
1456
1457    %% Get the correct list messages for the handshake context.
1458    Messages = get_handshake_context(Role, HHistory),
1459
1460    %% Calculate [sender]_application_traffic_secret_0
1461    ClientAppTrafficSecret0 =
1462        tls_v1:client_application_traffic_secret_0(HKDFAlgo, MasterSecret, lists:reverse(Messages)),
1463    ServerAppTrafficSecret0 =
1464        tls_v1:server_application_traffic_secret_0(HKDFAlgo, MasterSecret, lists:reverse(Messages)),
1465
1466    %% Calculate traffic keys
1467    #{cipher := Cipher} = ssl_cipher_format:suite_bin_to_map(CipherSuite),
1468    {ReadKey, ReadIV} = tls_v1:calculate_traffic_keys(HKDFAlgo, Cipher, ClientAppTrafficSecret0),
1469    {WriteKey, WriteIV} = tls_v1:calculate_traffic_keys(HKDFAlgo, Cipher, ServerAppTrafficSecret0),
1470
1471    update_pending_connection_states(State0, MasterSecret, undefined,
1472                                     ClientAppTrafficSecret0, ServerAppTrafficSecret0,
1473                                     ReadKey, ReadIV, undefined,
1474                                     WriteKey, WriteIV, undefined).
1475
1476
1477get_server_private_key(#key_share_server_hello{server_share = ServerShare}) ->
1478    get_private_key(ServerShare).
1479
1480get_private_key(#key_share_entry{
1481                   key_exchange = #'ECPrivateKey'{} = PrivateKey}) ->
1482    PrivateKey;
1483get_private_key(#key_share_entry{
1484                      key_exchange =
1485                          {_, PrivateKey}}) ->
1486    PrivateKey.
1487
1488%% X25519, X448
1489calculate_shared_secret(OthersKey, MyKey, Group)
1490  when is_binary(OthersKey) andalso is_binary(MyKey) andalso
1491       (Group =:= x25519 orelse Group =:= x448)->
1492    crypto:compute_key(ecdh, OthersKey, MyKey, Group);
1493%% FFDHE
1494calculate_shared_secret(OthersKey, MyKey, Group)
1495  when is_binary(OthersKey) andalso is_binary(MyKey) ->
1496    Params = #'DHParameter'{prime = P} = ssl_dh_groups:dh_params(Group),
1497    S = public_key:compute_key(OthersKey, MyKey, Params),
1498    Size = byte_size(binary:encode_unsigned(P)),
1499    ssl_cipher:add_zero_padding(S, Size);
1500%% ECDHE
1501calculate_shared_secret(OthersKey, MyKey = #'ECPrivateKey'{}, _Group)
1502  when is_binary(OthersKey) ->
1503    Point = #'ECPoint'{point = OthersKey},
1504    public_key:compute_key(Point, MyKey).
1505
1506
1507maybe_calculate_resumption_master_secret(#state{ssl_options = #{session_tickets := disabled}} = State) ->
1508    State;
1509maybe_calculate_resumption_master_secret(#state{
1510                             ssl_options = #{session_tickets := SessionTickets},
1511                             connection_states = ConnectionStates,
1512                             handshake_env =
1513                                 #handshake_env{
1514                                    tls_handshake_history = HHistory}} = State)
1515  when SessionTickets =/= disabled  ->
1516    #{security_parameters := SecParamsR} =
1517        ssl_record:pending_connection_state(ConnectionStates, read),
1518    #security_parameters{master_secret = MasterSecret,
1519                         prf_algorithm = HKDFAlgo} = SecParamsR,
1520    {Messages0, _} = HHistory,
1521    RMS = tls_v1:resumption_master_secret(HKDFAlgo, MasterSecret, lists:reverse(Messages0)),
1522    update_resumption_master_secret(State, RMS).
1523
1524
1525forget_master_secret(#state{connection_states =
1526                                #{pending_read := PendingRead,
1527                                  pending_write := PendingWrite,
1528                                  current_read := CurrentRead,
1529                                  current_write := CurrentWrite} = CS} = State) ->
1530    State#state{connection_states = CS#{pending_read => overwrite_master_secret(PendingRead),
1531                                        pending_write => overwrite_master_secret(PendingWrite),
1532                                        current_read => overwrite_master_secret(CurrentRead),
1533                                        current_write => overwrite_master_secret(CurrentWrite)}}.
1534
1535
1536overwrite_master_secret(ConnectionState = #{security_parameters := SecurityParameters0}) ->
1537    SecurityParameters = SecurityParameters0#security_parameters{master_secret = {master_secret, <<0>>}},
1538    ConnectionState#{security_parameters => SecurityParameters}.
1539
1540
1541update_pending_connection_states(#state{
1542                                    static_env = #static_env{role = server},
1543                                    connection_states =
1544                                        CS = #{pending_read := PendingRead0,
1545                                               pending_write := PendingWrite0}} = State,
1546                                 HandshakeSecret, ResumptionMasterSecret,
1547                                 ClientAppTrafficSecret, ServerAppTrafficSecret,
1548                                 ReadKey, ReadIV, ReadFinishedKey,
1549                                 WriteKey, WriteIV, WriteFinishedKey) ->
1550    PendingRead = update_connection_state(PendingRead0, HandshakeSecret, ResumptionMasterSecret,
1551                                          ClientAppTrafficSecret,
1552                                          ReadKey, ReadIV, ReadFinishedKey),
1553    PendingWrite = update_connection_state(PendingWrite0, HandshakeSecret, ResumptionMasterSecret,
1554                                           ServerAppTrafficSecret,
1555                                           WriteKey, WriteIV, WriteFinishedKey),
1556    State#state{connection_states = CS#{pending_read => PendingRead,
1557                                        pending_write => PendingWrite}};
1558update_pending_connection_states(#state{
1559                                    static_env = #static_env{role = client},
1560                                    connection_states =
1561                                        CS = #{pending_read := PendingRead0,
1562                                               pending_write := PendingWrite0}} = State,
1563                                 HandshakeSecret, ResumptionMasterSecret,
1564                                 ClientAppTrafficSecret, ServerAppTrafficSecret,
1565                                 ReadKey, ReadIV, ReadFinishedKey,
1566                                 WriteKey, WriteIV, WriteFinishedKey) ->
1567    PendingRead = update_connection_state(PendingRead0, HandshakeSecret, ResumptionMasterSecret,
1568                                          ServerAppTrafficSecret,
1569                                          WriteKey, WriteIV, WriteFinishedKey),
1570    PendingWrite = update_connection_state(PendingWrite0, HandshakeSecret, ResumptionMasterSecret,
1571                                           ClientAppTrafficSecret,
1572                                           ReadKey, ReadIV, ReadFinishedKey),
1573    State#state{connection_states = CS#{pending_read => PendingRead,
1574                                        pending_write => PendingWrite}}.
1575
1576
1577update_connection_state(ConnectionState = #{security_parameters := SecurityParameters0},
1578                        HandshakeSecret, ResumptionMasterSecret,
1579                        ApplicationTrafficSecret, Key, IV, FinishedKey) ->
1580    %% Store secret
1581    SecurityParameters = SecurityParameters0#security_parameters{
1582                           master_secret = HandshakeSecret,
1583                           resumption_master_secret = ResumptionMasterSecret,
1584                           application_traffic_secret = ApplicationTrafficSecret},
1585    ConnectionState#{security_parameters => SecurityParameters,
1586                     cipher_state => cipher_init(Key, IV, FinishedKey)}.
1587
1588
1589update_start_state(State, Map) ->
1590    Cipher = maps:get(cipher, Map, undefined),
1591    KeyShare = maps:get(key_share, Map, undefined),
1592    SessionId = maps:get(session_id, Map, undefined),
1593    Group = maps:get(group, Map, undefined),
1594    SelectedSignAlg = maps:get(sign_alg, Map, undefined),
1595    PeerPublicKey = maps:get(peer_public_key, Map, undefined),
1596    ALPNProtocol = maps:get(alpn, Map, undefined),
1597    update_start_state(State, Cipher, KeyShare, SessionId,
1598                       Group, SelectedSignAlg, PeerPublicKey,
1599                       ALPNProtocol).
1600%%
1601update_start_state(#state{connection_states = ConnectionStates0,
1602                          handshake_env = #handshake_env{} = HsEnv,
1603                          connection_env = CEnv,
1604                          session = Session} = State,
1605                   Cipher, KeyShare, SessionId,
1606                   Group, SelectedSignAlg, PeerPublicKey, ALPNProtocol) ->
1607    #{security_parameters := SecParamsR0} = PendingRead =
1608        maps:get(pending_read, ConnectionStates0),
1609    #{security_parameters := SecParamsW0} = PendingWrite =
1610        maps:get(pending_write, ConnectionStates0),
1611    SecParamsR = ssl_cipher:security_parameters_1_3(SecParamsR0, Cipher),
1612    SecParamsW = ssl_cipher:security_parameters_1_3(SecParamsW0, Cipher),
1613    ConnectionStates =
1614        ConnectionStates0#{pending_read => PendingRead#{security_parameters => SecParamsR},
1615                           pending_write => PendingWrite#{security_parameters => SecParamsW}},
1616    State#state{connection_states = ConnectionStates,
1617                handshake_env = HsEnv#handshake_env{alpn = ALPNProtocol},
1618                key_share = KeyShare,
1619                session = Session#session{session_id = SessionId,
1620                                          ecc = Group,
1621                                          sign_alg = SelectedSignAlg,
1622                                          dh_public_value = PeerPublicKey,
1623                                          cipher_suite = Cipher},
1624                connection_env = CEnv#connection_env{negotiated_version = {3,4}}}.
1625
1626
1627update_resumption_master_secret(#state{connection_states = ConnectionStates0} = State,
1628                                ResumptionMasterSecret) ->
1629    #{security_parameters := SecParamsR0} = PendingRead =
1630        maps:get(pending_read, ConnectionStates0),
1631    #{security_parameters := SecParamsW0} = PendingWrite =
1632        maps:get(pending_write, ConnectionStates0),
1633
1634    SecParamsR = SecParamsR0#security_parameters{resumption_master_secret = ResumptionMasterSecret},
1635    SecParamsW = SecParamsW0#security_parameters{resumption_master_secret = ResumptionMasterSecret},
1636    ConnectionStates =
1637        ConnectionStates0#{pending_read => PendingRead#{security_parameters => SecParamsR},
1638                           pending_write => PendingWrite#{security_parameters => SecParamsW}},
1639    State#state{connection_states = ConnectionStates}.
1640
1641
1642cipher_init(Key, IV, FinishedKey) ->
1643    #cipher_state{key = Key,
1644                  iv = IV,
1645                  finished_key = FinishedKey,
1646                  tag_len = 16}.
1647
1648
1649%% Get handshake context for verification of CertificateVerify.
1650%%
1651%% Verify CertificateVerify:
1652%%    ClientHello         (client) (1)
1653%%    ServerHello         (server) (2)
1654%%    EncryptedExtensions (server) (8)
1655%%    CertificateRequest  (server) (13)
1656%%    Certificate         (server) (11)
1657%%    CertificateVerify   (server) (15)
1658%%    Finished            (server) (20)
1659%%    Certificate         (client) (11)
1660%%    CertificateVerify   (client) (15) - Drop! Not included in calculations!
1661get_handshake_context_cv({[<<15,_/binary>>|Messages], _}) ->
1662    Messages.
1663
1664
1665%% Get handshake context for traffic key calculation.
1666%%
1667%% Client is authenticated with certificate:
1668%%    ClientHello         (client) (1)
1669%%    ServerHello         (server) (2)
1670%%    EncryptedExtensions (server) (8)
1671%%    CertificateRequest  (server) (13)
1672%%    Certificate         (server) (11)
1673%%    CertificateVerify   (server) (15)
1674%%    Finished            (server) (20)
1675%%    Certificate         (client) (11) - Drop! Not included in calculations!
1676%%    CertificateVerify   (client) (15) - Drop! Not included in calculations!
1677%%    Finished            (client) (20) - Drop! Not included in calculations!
1678%%
1679%% Client is authenticated but sends empty certificate:
1680%%    ClientHello         (client) (1)
1681%%    ServerHello         (server) (2)
1682%%    EncryptedExtensions (server) (8)
1683%%    CertificateRequest  (server) (13)
1684%%    Certificate         (server) (11)
1685%%    CertificateVerify   (server) (15)
1686%%    Finished            (server) (20)
1687%%    Certificate         (client) (11) - Drop! Not included in calculations!
1688%%    Finished            (client) (20) - Drop! Not included in calculations!
1689%%
1690%% Client is not authenticated:
1691%%    ClientHello         (client) (1)
1692%%    ServerHello         (server) (2)
1693%%    EncryptedExtensions (server) (8)
1694%%    Certificate         (server) (11)
1695%%    CertificateVerify   (server) (15)
1696%%    Finished            (server) (20)
1697%%    Finished            (client) (20) - Drop! Not included in calculations!
1698%%
1699%% Drop all client messages from the front of the iolist using the property that
1700%% incoming messages are binaries.
1701get_handshake_context(server, {Messages, _}) ->
1702    get_handshake_context_server(Messages);
1703get_handshake_context(client, {Messages, _}) ->
1704    get_handshake_context_client(Messages).
1705
1706get_handshake_context_server([H|T]) when is_binary(H) ->
1707    get_handshake_context_server(T);
1708get_handshake_context_server(L) ->
1709    L.
1710
1711
1712get_handshake_context_client([H|T]) when is_list(H) ->
1713    get_handshake_context_client(T);
1714get_handshake_context_client(L) ->
1715    L.
1716
1717
1718%% If the CertificateVerify message is sent by a server, the signature
1719%% algorithm MUST be one offered in the client's "signature_algorithms"
1720%% extension unless no valid certificate chain can be produced without
1721%% unsupported algorithms
1722%%
1723%% If sent by a client, the signature algorithm used in the signature
1724%% MUST be one of those present in the supported_signature_algorithms
1725%% field of the "signature_algorithms" extension in the
1726%% CertificateRequest message.
1727verify_signature_algorithm(#state{
1728                              static_env = #static_env{role = Role},
1729                              ssl_options = #{signature_algs := LocalSignAlgs}} = State0,
1730                           #certificate_verify_1_3{algorithm = PeerSignAlg}) ->
1731    case lists:member(PeerSignAlg, LocalSignAlgs) of
1732        true ->
1733            {ok, maybe_update_selected_sign_alg(State0, PeerSignAlg, Role)};
1734        false ->
1735            State1 = calculate_traffic_secrets(State0),
1736            State = ssl_record:step_encryption_state(State1),
1737            {error, {?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE,
1738                                "CertificateVerify uses unsupported signature algorithm"), State}}
1739    end.
1740
1741
1742maybe_update_selected_sign_alg(#state{session = Session} = State, SignAlg, client) ->
1743    State#state{session = Session#session{sign_alg = SignAlg}};
1744maybe_update_selected_sign_alg(State, _, _) ->
1745    State.
1746
1747
1748verify_certificate_verify(#state{
1749                             static_env = #static_env{role = Role},
1750                             connection_states = ConnectionStates,
1751                             handshake_env =
1752                                 #handshake_env{
1753                                    public_key_info = PublicKeyInfo,
1754                                    tls_handshake_history = HHistory}} = State0,
1755                          #certificate_verify_1_3{
1756                             algorithm = SignatureScheme,
1757                             signature = Signature}) ->
1758    #{security_parameters := SecParamsR} =
1759        ssl_record:pending_connection_state(ConnectionStates, write),
1760    #security_parameters{prf_algorithm = HKDFAlgo} = SecParamsR,
1761
1762    {HashAlgo, _, _} =
1763        ssl_cipher:scheme_to_components(SignatureScheme),
1764
1765    Messages = get_handshake_context_cv(HHistory),
1766
1767    Context = lists:reverse(Messages),
1768
1769    %% Transcript-Hash uses the HKDF hash function defined by the cipher suite.
1770    THash = tls_v1:transcript_hash(Context, HKDFAlgo),
1771
1772    ContextString = peer_context_string(Role),
1773
1774    %% Digital signatures use the hash function defined by the selected signature
1775    %% scheme.
1776    case verify(THash, ContextString, HashAlgo, Signature, PublicKeyInfo) of
1777        {ok, true} ->
1778            {ok, {State0, wait_finished}};
1779        {ok, false} ->
1780            State1 = calculate_traffic_secrets(State0),
1781            State = ssl_record:step_encryption_state(State1),
1782            {error, {?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE,
1783                                "Failed to verify CertificateVerify"), State}};
1784        {error, #alert{} = Alert} ->
1785            State1 = calculate_traffic_secrets(State0),
1786            State = ssl_record:step_encryption_state(State1),
1787            {error, {Alert, State}}
1788    end.
1789
1790
1791context_string(server) ->
1792    <<"TLS 1.3, server CertificateVerify">>;
1793context_string(client) ->
1794    <<"TLS 1.3, client CertificateVerify">>.
1795
1796
1797%% Return context string for verifing peer signature
1798peer_context_string(server) ->
1799    <<"TLS 1.3, client CertificateVerify">>;
1800peer_context_string(client) ->
1801    <<"TLS 1.3, server CertificateVerify">>.
1802
1803
1804%% If there is no overlap between the received
1805%% "supported_groups" and the groups supported by the server, then the
1806%% server MUST abort the handshake with a "handshake_failure" or an
1807%% "insufficient_security" alert.
1808select_common_groups(_, []) ->
1809    {error, ?ALERT_REC(?FATAL, ?INSUFFICIENT_SECURITY, no_suitable_groups)};
1810select_common_groups(ServerGroups, ClientGroups) ->
1811    Fun = fun(E) -> lists:member(E, ClientGroups) end,
1812    case lists:filter(Fun, ServerGroups) of
1813        [] ->
1814            {error, {insufficient_security, no_suitable_groups}};
1815        L ->
1816            {ok, L}
1817    end.
1818
1819
1820%% RFC 8446 - 4.2.8.  Key Share
1821%% This vector MAY be empty if the client is requesting a
1822%% HelloRetryRequest.  Each KeyShareEntry value MUST correspond to a
1823%% group offered in the "supported_groups" extension and MUST appear in
1824%% the same order.  However, the values MAY be a non-contiguous subset
1825%% of the "supported_groups" extension and MAY omit the most preferred
1826%% groups.
1827%%
1828%% Clients can offer as many KeyShareEntry values as the number of
1829%% supported groups it is offering, each representing a single set of
1830%% key exchange parameters.
1831%%
1832%% Clients MUST NOT offer multiple KeyShareEntry values
1833%% for the same group.  Clients MUST NOT offer any KeyShareEntry values
1834%% for groups not listed in the client's "supported_groups" extension.
1835%% Servers MAY check for violations of these rules and abort the
1836%% handshake with an "illegal_parameter" alert if one is violated.
1837validate_client_key_share(_ ,[]) ->
1838    ok;
1839validate_client_key_share([], _) ->
1840    {error, ?ALERT_REC(?FATAL, ?ILLEGAL_PARAMETER)};
1841validate_client_key_share([G|ClientGroups], [{_, G, _}|ClientShares]) ->
1842    validate_client_key_share(ClientGroups, ClientShares);
1843validate_client_key_share([_|ClientGroups], [_|_] = ClientShares) ->
1844    validate_client_key_share(ClientGroups, ClientShares).
1845
1846
1847%% Verify that selected group is offered by the client.
1848validate_server_key_share([], _) ->
1849    {error, ?ALERT_REC(?FATAL, ?ILLEGAL_PARAMETER)};
1850validate_server_key_share([G|_ClientGroups], {_, G, _}) ->
1851    ok;
1852validate_server_key_share([_|ClientGroups], {_, _, _} = ServerKeyShare) ->
1853    validate_server_key_share(ClientGroups, ServerKeyShare).
1854
1855
1856validate_selected_group(SelectedGroup, [SelectedGroup|_]) ->
1857    {error, ?ALERT_REC(?FATAL, ?ILLEGAL_PARAMETER,
1858                       "Selected group sent by the server shall not correspond to a group"
1859                       " which was provided in the key_share extension")};
1860validate_selected_group(SelectedGroup, ClientGroups) ->
1861    case lists:member(SelectedGroup, ClientGroups) of
1862        true ->
1863            ok;
1864        false ->
1865            {error, ?ALERT_REC(?FATAL, ?ILLEGAL_PARAMETER,
1866                               "Selected group sent by the server shall correspond to a group"
1867                               " which was provided in the supported_groups extension")}
1868    end.
1869
1870
1871get_client_public_key([Group|_] = Groups, ClientShares) ->
1872    get_client_public_key(Groups, ClientShares, Group).
1873%%
1874get_client_public_key(_, [], PreferredGroup) ->
1875    {PreferredGroup, no_suitable_key};
1876get_client_public_key([], _, PreferredGroup) ->
1877    {PreferredGroup, no_suitable_key};
1878get_client_public_key([Group|Groups], ClientShares, PreferredGroup) ->
1879     case lists:keysearch(Group, 2, ClientShares) of
1880         {value, {_, _, ClientPublicKey}} ->
1881             {Group, ClientPublicKey};
1882         false ->
1883             get_client_public_key(Groups, ClientShares, PreferredGroup)
1884     end.
1885
1886get_client_private_key([Group|_] = Groups, ClientShares) ->
1887    get_client_private_key(Groups, ClientShares, Group).
1888%%
1889get_client_private_key(_, [], PreferredGroup) ->
1890    {PreferredGroup, no_suitable_key};
1891get_client_private_key([], _, PreferredGroup) ->
1892    {PreferredGroup, no_suitable_key};
1893get_client_private_key([Group|Groups], ClientShares, PreferredGroup) ->
1894     case lists:keysearch(Group, 2, ClientShares) of
1895         {value, {_, _, {_, ClientPrivateKey}}} ->
1896             {Group, ClientPrivateKey};
1897         {value, {_, _, #'ECPrivateKey'{} = ClientPrivateKey}} ->
1898             {Group, ClientPrivateKey};
1899         false ->
1900             get_client_private_key(Groups, ClientShares, PreferredGroup)
1901     end.
1902
1903
1904get_server_public_key({key_share_entry, Group, PublicKey}) ->
1905                             {Group, PublicKey}.
1906
1907
1908%% RFC 7301 - Application-Layer Protocol Negotiation Extension
1909%% It is expected that a server will have a list of protocols that it
1910%% supports, in preference order, and will only select a protocol if the
1911%% client supports it.  In that case, the server SHOULD select the most
1912%% highly preferred protocol that it supports and that is also
1913%% advertised by the client.  In the event that the server supports no
1914%% protocols that the client advertises, then the server SHALL respond
1915%% with a fatal "no_application_protocol" alert.
1916handle_alpn(undefined, _) ->
1917    {ok, undefined};
1918handle_alpn([], _) ->
1919    {error,  ?ALERT_REC(?FATAL, ?NO_APPLICATION_PROTOCOL)};
1920handle_alpn([_|_], undefined) ->
1921    {ok, undefined};
1922handle_alpn([ServerProtocol|T], ClientProtocols) ->
1923    case lists:member(ServerProtocol, ClientProtocols) of
1924        true ->
1925            {ok, ServerProtocol};
1926        false ->
1927            handle_alpn(T, ClientProtocols)
1928    end.
1929
1930
1931select_cipher_suite(_, [], _) ->
1932    {error, ?ALERT_REC(?FATAL, ?INSUFFICIENT_SECURITY, no_suitable_cipher)};
1933%% If honor_cipher_order is set to true, use the server's preference for
1934%% cipher suite selection.
1935select_cipher_suite(true, ClientCiphers, ServerCiphers) ->
1936    select_cipher_suite(false, ServerCiphers, ClientCiphers);
1937select_cipher_suite(false, [Cipher|ClientCiphers], ServerCiphers) ->
1938    case lists:member(Cipher, tls_v1:suites('TLS_v1.3')) andalso
1939        lists:member(Cipher, ServerCiphers) of
1940        true ->
1941            {ok, Cipher};
1942        false ->
1943            select_cipher_suite(false, ClientCiphers, ServerCiphers)
1944    end.
1945
1946
1947%% RFC 8446 4.1.3 ServerHello
1948%% A client which receives a cipher suite that was not offered MUST abort the
1949%% handshake with an "illegal_parameter" alert.
1950validate_cipher_suite(Cipher, ClientCiphers) ->
1951    case lists:member(Cipher, ClientCiphers) of
1952        true ->
1953            ok;
1954        false ->
1955            {error, ?ALERT_REC(?FATAL, ?ILLEGAL_PARAMETER)}
1956    end.
1957
1958
1959%% RFC 8446 (TLS 1.3)
1960%% TLS 1.3 provides two extensions for indicating which signature
1961%% algorithms may be used in digital signatures.  The
1962%% "signature_algorithms_cert" extension applies to signatures in
1963%% certificates and the "signature_algorithms" extension, which
1964%% originally appeared in TLS 1.2, applies to signatures in
1965%% CertificateVerify messages.
1966%%
1967%% If no "signature_algorithms_cert" extension is
1968%% present, then the "signature_algorithms" extension also applies to
1969%% signatures appearing in certificates.
1970
1971%% Check if the signature algorithm of the server certificate is supported
1972%% by the client.
1973check_cert_sign_algo(SignAlgo, SignHash, ClientSignAlgs, undefined) ->
1974    do_check_cert_sign_algo(SignAlgo, SignHash, ClientSignAlgs);
1975check_cert_sign_algo(SignAlgo, SignHash, _, ClientSignAlgsCert) ->
1976    do_check_cert_sign_algo(SignAlgo, SignHash, ClientSignAlgsCert).
1977
1978
1979%% DSA keys are not supported by TLS 1.3
1980select_sign_algo(dsa, _ClientSignAlgs, _ServerSignAlgs) ->
1981    {error, ?ALERT_REC(?FATAL, ?INSUFFICIENT_SECURITY, no_suitable_public_key)};
1982select_sign_algo(_, [], _) ->
1983    {error, ?ALERT_REC(?FATAL, ?INSUFFICIENT_SECURITY, no_suitable_signature_algorithm)};
1984select_sign_algo(PublicKeyAlgo, [C|ClientSignAlgs], ServerSignAlgs) ->
1985    {_, S, _} = ssl_cipher:scheme_to_components(C),
1986    %% RSASSA-PKCS1-v1_5 and Legacy algorithms are not defined for use in signed
1987    %% TLS handshake messages: filter sha-1 and rsa_pkcs1.
1988    %%
1989    %% RSASSA-PSS RSAE algorithms: If the public key is carried in an X.509
1990    %% certificate, it MUST use the rsaEncryption OID.
1991    %% RSASSA-PSS PSS algorithms: If the public key is carried in an X.509 certificate,
1992    %% it MUST use the RSASSA-PSS OID.
1993    case ((PublicKeyAlgo =:= rsa andalso S =:= rsa_pss_rsae)
1994          orelse (PublicKeyAlgo =:= rsa_pss andalso S =:= rsa_pss_pss)
1995          orelse (PublicKeyAlgo =:= ecdsa andalso S =:= ecdsa))
1996        andalso
1997        lists:member(C, ServerSignAlgs) of
1998        true ->
1999            {ok, C};
2000        false ->
2001            select_sign_algo(PublicKeyAlgo, ClientSignAlgs, ServerSignAlgs)
2002    end.
2003
2004
2005do_check_cert_sign_algo(_, _, []) ->
2006    {error, ?ALERT_REC(?FATAL, ?INSUFFICIENT_SECURITY, no_suitable_signature_algorithm)};
2007do_check_cert_sign_algo(SignAlgo, SignHash, [Scheme|T]) ->
2008    {Hash, Sign, _Curve} = ssl_cipher:scheme_to_components(Scheme),
2009    case compare_sign_algos(SignAlgo, SignHash, Sign, Hash) of
2010        true ->
2011            ok;
2012        _Else ->
2013            do_check_cert_sign_algo(SignAlgo, SignHash, T)
2014    end.
2015
2016
2017%% id-RSASSA-PSS (rsa_pss) indicates that the key may only be used for PSS signatures.
2018%% TODO: Uncomment when rsa_pss signatures are supported in certificates
2019%% compare_sign_algos(rsa_pss, Hash, Algo, Hash)
2020%%   when Algo =:= rsa_pss_pss ->
2021%%     true;
2022%% rsaEncryption (rsa) allows the key to be used for any of the standard encryption or
2023%% signature schemes.
2024compare_sign_algos(rsa, Hash, Algo, Hash)
2025  when Algo =:= rsa_pss_rsae orelse
2026       Algo =:= rsa_pkcs1 ->
2027    true;
2028compare_sign_algos(Algo, Hash, Algo, Hash) ->
2029    true;
2030compare_sign_algos(_, _, _, _) ->
2031    false.
2032
2033
2034get_certificate_params(Cert) ->
2035    {SignAlgo0, _Param, PublicKeyAlgo0} = ssl_handshake:get_cert_params(Cert),
2036    {SignHash0, SignAlgo} = public_key:pkix_sign_types(SignAlgo0),
2037    %% Convert hash to new format
2038    SignHash = case SignHash0 of
2039                   sha ->
2040                       sha1;
2041                   H -> H
2042               end,
2043    PublicKeyAlgo = public_key_algo(PublicKeyAlgo0),
2044    {PublicKeyAlgo, SignAlgo, SignHash}.
2045
2046
2047%% Note: copied from ssl_handshake
2048public_key_algo(?'id-RSASSA-PSS') ->
2049    rsa_pss;
2050public_key_algo(?rsaEncryption) ->
2051    rsa;
2052public_key_algo(?'id-ecPublicKey') ->
2053    ecdsa;
2054public_key_algo(?'id-dsa') ->
2055    dsa.
2056
2057get_signature_scheme_list(undefined) ->
2058    undefined;
2059get_signature_scheme_list(#signature_algorithms_cert{
2060                        signature_scheme_list = ClientSignatureSchemes}) ->
2061    ClientSignatureSchemes;
2062get_signature_scheme_list(#signature_algorithms{
2063                        signature_scheme_list = ClientSignatureSchemes}) ->
2064    %% Filter unassigned and legacy elements
2065    lists:filter(fun (E) -> is_atom(E) andalso E =/= unassigned end,
2066                 ClientSignatureSchemes).
2067
2068get_supported_groups(#supported_groups{supported_groups = Groups}) ->
2069    Groups.
2070
2071get_key_shares(#key_share_client_hello{client_shares = ClientShares}) ->
2072    ClientShares;
2073get_key_shares(#key_share_server_hello{server_share = ServerShare}) ->
2074    ServerShare.
2075
2076get_selected_identity(undefined) ->
2077    undefined;
2078get_selected_identity(#pre_shared_key_server_hello{selected_identity = SelectedIdentity}) ->
2079    SelectedIdentity.
2080
2081get_offered_psks(Extensions) ->
2082    PSK = maps:get(pre_shared_key, Extensions, undefined),
2083    case PSK of
2084        undefined ->
2085            undefined;
2086        #pre_shared_key_client_hello{offered_psks = OfferedPSKs} ->
2087            OfferedPSKs
2088    end.
2089
2090
2091%% Prior to accepting PSK key establishment, the server MUST validate
2092%% the corresponding binder value (see Section 4.2.11.2 below).  If this
2093%% value is not present or does not validate, the server MUST abort the
2094%% handshake.  Servers SHOULD NOT attempt to validate multiple binders;
2095%% rather, they SHOULD select a single PSK and validate solely the
2096%% binder that corresponds to that PSK.
2097%%
2098%% If no acceptable PSKs are found, the server SHOULD perform a non-PSK
2099%% handshake if possible.
2100handle_pre_shared_key(_, undefined, _) ->
2101    {ok, undefined};
2102handle_pre_shared_key(#state{ssl_options = #{session_tickets := disabled}}, _, _) ->
2103    {ok, undefined};
2104handle_pre_shared_key(#state{ssl_options = #{session_tickets := Tickets},
2105                             handshake_env = #handshake_env{tls_handshake_history =  {HHistory, _}},
2106                             static_env = #static_env{trackers = Trackers}},
2107                      OfferedPreSharedKeys, Cipher) when Tickets =/= disabled ->
2108    Tracker = proplists:get_value(session_tickets_tracker, Trackers),
2109    #{prf := CipherHash} = ssl_cipher_format:suite_bin_to_map(Cipher),
2110    tls_server_session_ticket:use(Tracker, OfferedPreSharedKeys, CipherHash, HHistory).
2111
2112get_selected_group(#key_share_hello_retry_request{selected_group = SelectedGroup}) ->
2113    SelectedGroup.
2114
2115get_alpn(ALPNProtocol0) ->
2116    case ssl_handshake:decode_alpn(ALPNProtocol0) of
2117        undefined ->
2118            undefined;
2119        [ALPNProtocol] ->
2120            ALPNProtocol
2121    end.
2122
2123maybe() ->
2124    Ref = erlang:make_ref(),
2125    Ok = fun(ok) -> ok;
2126            ({ok,R}) -> R;
2127            ({error,Reason}) ->
2128                 throw({Ref,Reason})
2129         end,
2130    {Ref,Ok}.
2131
2132
2133%% If the handshake includes a HelloRetryRequest, the initial
2134%% ClientHello and HelloRetryRequest are included in the transcript
2135%% along with the new ClientHello.  For instance, if the client sends
2136%% ClientHello1, its binder will be computed over:
2137%%
2138%%    Transcript-Hash(Truncate(ClientHello1))
2139%%
2140%% Where Truncate() removes the binders list from the ClientHello.
2141%%
2142%% If the server responds with a HelloRetryRequest and the client then
2143%% sends ClientHello2, its binder will be computed over:
2144%%
2145%%    Transcript-Hash(ClientHello1,
2146%%                    HelloRetryRequest,
2147%%                    Truncate(ClientHello2))
2148%%
2149%% The full ClientHello1/ClientHello2 is included in all other handshake
2150%% hash computations.  Note that in the first flight,
2151%% Truncate(ClientHello1) is hashed directly, but in the second flight,
2152%% ClientHello1 is hashed and then reinjected as a "message_hash"
2153%% message, as described in Section 4.4.1.
2154maybe_add_binders(Hello, undefined, _) ->
2155    Hello;
2156maybe_add_binders(Hello0, TicketData, Version) when Version =:= {3,4} ->
2157    HelloBin0 = tls_handshake:encode_handshake(Hello0, Version),
2158    HelloBin1 = iolist_to_binary(HelloBin0),
2159    Truncated = truncate_client_hello(HelloBin1),
2160    Binders = create_binders([Truncated], TicketData),
2161    update_binders(Hello0, Binders);
2162maybe_add_binders(Hello, _, Version) when Version =< {3,3} ->
2163    Hello.
2164%%
2165%% HelloRetryRequest
2166maybe_add_binders(Hello, _, undefined, _) ->
2167    Hello;
2168maybe_add_binders(Hello0, {[HRR,MessageHash|_], _}, TicketData, Version) when Version =:= {3,4} ->
2169    HelloBin0 = tls_handshake:encode_handshake(Hello0, Version),
2170    HelloBin1 = iolist_to_binary(HelloBin0),
2171    Truncated = truncate_client_hello(HelloBin1),
2172    Binders = create_binders([MessageHash,HRR,Truncated], TicketData),
2173    update_binders(Hello0, Binders);
2174maybe_add_binders(Hello, _, _, Version) when Version =< {3,3} ->
2175    Hello.
2176
2177
2178create_binders(Context, TicketData) ->
2179    create_binders(Context, TicketData, []).
2180%%
2181create_binders(_, [], Acc) ->
2182    lists:reverse(Acc);
2183create_binders(Context, [{_, _, _, PSK, _, HKDF}|T], Acc) ->
2184    FinishedKey = calculate_finished_key(PSK, HKDF),
2185    Binder = calculate_binder(FinishedKey, HKDF, Context),
2186    create_binders(Context, T, [Binder|Acc]).
2187
2188
2189%% Removes the binders list from the ClientHello.
2190%% opaque PskBinderEntry<32..255>;
2191%%
2192%% struct {
2193%%     PskIdentity identities<7..2^16-1>;
2194%%     PskBinderEntry binders<33..2^16-1>;
2195%% } OfferedPsks;
2196truncate_client_hello(HelloBin0) ->
2197    <<?BYTE(Type), ?UINT24(_Length), Body/binary>> = HelloBin0,
2198    CH0 = #client_hello{
2199             extensions = #{pre_shared_key := PSK0} = Extensions0} =
2200        tls_handshake:decode_handshake({3,4}, Type, Body),
2201    #pre_shared_key_client_hello{offered_psks = OfferedPsks0} = PSK0,
2202    OfferedPsks = OfferedPsks0#offered_psks{binders = []},
2203    PSK = PSK0#pre_shared_key_client_hello{offered_psks = OfferedPsks},
2204    Extensions = Extensions0#{pre_shared_key => PSK},
2205    CH = CH0#client_hello{extensions = Extensions},
2206
2207    %% Decoding a ClientHello from an another TLS implementation can contain
2208    %% unsupported extensions and thus executing decoding and encoding on
2209    %% the input can result in a different handshake binary.
2210    %% The original length of the binders can still be determined by
2211    %% re-encoding the original ClientHello and using its size as reference
2212    %% when we substract the size of the truncated binary.
2213    TruncatedSize = iolist_size(tls_handshake:encode_handshake(CH, {3,4})),
2214    RefSize = iolist_size(tls_handshake:encode_handshake(CH0, {3,4})),
2215    BindersSize = RefSize - TruncatedSize,
2216
2217    %% Return the truncated ClientHello by cutting of the binders from the original
2218    %% ClientHello binary.
2219    {Truncated, _} = split_binary(HelloBin0, size(HelloBin0) - BindersSize - 2),
2220    Truncated.
2221
2222
2223%% The PskBinderEntry is computed in the same way as the Finished
2224%% message (Section 4.4.4) but with the BaseKey being the binder_key
2225%% derived via the key schedule from the corresponding PSK which is
2226%% being offered (see Section 7.1).
2227calculate_finished_key(PSK, HKDFAlgo) ->
2228    EarlySecret = tls_v1:key_schedule(early_secret, HKDFAlgo , {psk, PSK}),
2229    PRK = tls_v1:resumption_binder_key(HKDFAlgo, EarlySecret),
2230    tls_v1:finished_key(PRK, HKDFAlgo).
2231
2232
2233calculate_binder(BinderKey, HKDF, Truncated) ->
2234  tls_v1:finished_verify_data(BinderKey, HKDF, [Truncated]).
2235
2236
2237update_binders(#client_hello{extensions =
2238                                #{pre_shared_key := PreSharedKey0} = Extensions0} = Hello, Binders) ->
2239    #pre_shared_key_client_hello{
2240       offered_psks =
2241           #offered_psks{identities = Identities}} = PreSharedKey0,
2242
2243    PreSharedKey =
2244        #pre_shared_key_client_hello{
2245           offered_psks =
2246               #offered_psks{identities = Identities,
2247                             binders = Binders}},
2248
2249    Extensions = Extensions0#{pre_shared_key => PreSharedKey},
2250    Hello#client_hello{extensions = Extensions}.
2251
2252%% Configure a suitable session ticket
2253maybe_automatic_session_resumption(#state{
2254                                      ssl_options = #{versions := [Version|_],
2255                                                      ciphers := UserSuites,
2256                                                      session_tickets := SessionTickets} = SslOpts0
2257                                     } = State0)
2258  when Version >= {3,4} andalso
2259       SessionTickets =:= auto ->
2260    AvailableCipherSuites = ssl_handshake:available_suites(UserSuites, Version),
2261    HashAlgos = cipher_hash_algos(AvailableCipherSuites),
2262    UseTicket = tls_client_ticket_store:find_ticket(self(), HashAlgos),
2263    tls_client_ticket_store:lock_tickets(self(), [UseTicket]),
2264    State = State0#state{ssl_options = SslOpts0#{use_ticket => [UseTicket]}},
2265    {[UseTicket], State};
2266maybe_automatic_session_resumption(#state{
2267                                      ssl_options = #{use_ticket := UseTicket}
2268                                     } = State) ->
2269    {UseTicket, State}.
2270
2271
2272cipher_hash_algos(Ciphers) ->
2273    Fun = fun(Cipher) ->
2274                  #{prf := Hash} = ssl_cipher_format:suite_bin_to_map(Cipher),
2275                  Hash
2276          end,
2277    lists:map(Fun, Ciphers).
2278
2279
2280get_ticket_data(_, undefined, _) ->
2281    undefined;
2282get_ticket_data(_, _, undefined) ->
2283    undefined;
2284get_ticket_data(_, manual, UseTicket) ->
2285    process_user_tickets(UseTicket);
2286get_ticket_data(Pid, auto, UseTicket) ->
2287    tls_client_ticket_store:get_tickets(Pid, UseTicket).
2288
2289
2290process_user_tickets(UseTicket) ->
2291    process_user_tickets(UseTicket, [], 0).
2292%%
2293process_user_tickets([], Acc, _) ->
2294    lists:reverse(Acc);
2295process_user_tickets([H|T], Acc, N) ->
2296    #{hkdf := HKDF,
2297      sni := _SNI,
2298      psk := PSK,
2299      timestamp := Timestamp,
2300      ticket := NewSessionTicket} = erlang:binary_to_term(H),
2301    #new_session_ticket{
2302       ticket_lifetime = _LifeTime,
2303       ticket_age_add = AgeAdd,
2304       ticket_nonce = Nonce,
2305       ticket = Ticket,
2306       extensions = _Extensions
2307      } = NewSessionTicket,
2308    TicketAge =  erlang:system_time(seconds) - Timestamp,
2309    ObfuscatedTicketAge = obfuscate_ticket_age(TicketAge, AgeAdd),
2310    Identity = #psk_identity{
2311                  identity = Ticket,
2312                  obfuscated_ticket_age = ObfuscatedTicketAge},
2313    process_user_tickets(T, [{undefined, N, Identity, PSK, Nonce, HKDF}|Acc], N + 1).
2314
2315
2316%% The "obfuscated_ticket_age"
2317%% field of each PskIdentity contains an obfuscated version of the
2318%% ticket age formed by taking the age in milliseconds and adding the
2319%% "ticket_age_add" value that was included with the ticket
2320%% (see Section 4.6.1), modulo 2^32.
2321obfuscate_ticket_age(TicketAge, AgeAdd) ->
2322    (TicketAge + AgeAdd) rem round(math:pow(2,32)).
2323