1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2018-2020. All Rights Reserved.
5%%
6%% The contents of this file are subject to the Erlang Public License,
7%% Version 1.1, (the "License"); you may not use this file except in
8%% compliance with the License. You should have received a copy of the
9%% Erlang Public License along with this software. If not, it can be
10%% retrieved online at http://www.erlang.org/.
11%%
12%% Software distributed under the License is distributed on an "AS IS"
13%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
14%% the License for the specific language governing rights and limitations
15%% under the License.
16%%
17%% %CopyrightEnd%
18%%
19%%
20
21-module(ssl_eqc_handshake).
22
23-compile(export_all).
24
25-proptest(eqc).
26-proptest([triq,proper]).
27
28-ifndef(EQC).
29-ifndef(PROPER).
30-ifndef(TRIQ).
31-define(EQC,true).
32-endif.
33-endif.
34-endif.
35
36-ifdef(EQC).
37-include_lib("eqc/include/eqc.hrl").
38-define(MOD_eqc,eqc).
39
40-else.
41-ifdef(PROPER).
42-include_lib("proper/include/proper.hrl").
43-define(MOD_eqc,proper).
44
45-else.
46-ifdef(TRIQ).
47-define(MOD_eqc,triq).
48-include_lib("triq/include/triq.hrl").
49
50-endif.
51-endif.
52-endif.
53
54-include_lib("kernel/include/inet.hrl").
55-include_lib("ssl/src/tls_handshake_1_3.hrl").
56-include_lib("ssl/src/tls_handshake.hrl").
57-include_lib("ssl/src/ssl_handshake.hrl").
58-include_lib("ssl/src/ssl_alert.hrl").
59-include_lib("ssl/src/ssl_internal.hrl").
60
61-define('TLS_v1.3', {3,4}).
62-define('TLS_v1.2', {3,3}).
63-define('TLS_v1.1', {3,2}).
64-define('TLS_v1',   {3,1}).
65
66%%--------------------------------------------------------------------
67%% Properties --------------------------------------------------------
68%%--------------------------------------------------------------------
69
70prop_tls_hs_encode_decode() ->
71    ?FORALL({Handshake, TLSVersion}, ?LET(Version, tls_version(), {tls_msg(Version), Version}),
72            try
73                [Type, _Length, Data] = tls_handshake:encode_handshake(Handshake, TLSVersion),
74                case tls_handshake:decode_handshake(TLSVersion, Type, Data) of
75                    Handshake ->
76                        true;
77                    _ ->
78                        false
79                end
80            catch
81                throw:#alert{} ->
82                    true
83            end
84	   ).
85
86%%--------------------------------------------------------------------
87%% Message Generators  -----------------------------------------------
88%%--------------------------------------------------------------------
89
90tls_msg(?'TLS_v1.3'= Version) ->
91    oneof([client_hello(Version),
92           server_hello(Version),
93           %%new_session_ticket()
94          #end_of_early_data{},
95           encrypted_extensions(),
96           certificate_1_3(),
97           %%certificate_request_1_3,
98           certificate_verify_1_3(),
99           finished(),
100           key_update()
101          ]);
102tls_msg(Version) ->
103    oneof([
104           #hello_request{},
105           client_hello(Version),
106           server_hello(Version),
107           certificate(),
108           %%server_key_exchange()
109           certificate_request(Version),
110           #server_hello_done{},
111           %%certificate_verify()
112           %%client_key_exchange()
113           finished()
114          ]).
115
116%%
117%% Shared messages
118%%
119client_hello(?'TLS_v1.3' = Version) ->
120    #client_hello{session_id = session_id(),
121                  client_version = ?'TLS_v1.2',
122                  cipher_suites = cipher_suites(Version),
123                  compression_methods = compressions(Version),
124                  random = client_random(Version),
125                  extensions = client_hello_extensions(Version)
126                 };
127client_hello(Version) ->
128    #client_hello{session_id = session_id(),
129		  client_version = Version,
130                  cipher_suites = cipher_suites(Version),
131		  compression_methods = compressions(Version),
132		  random = client_random(Version),
133		  extensions = client_hello_extensions(Version)
134                 }.
135
136server_hello(?'TLS_v1.3' = Version) ->
137    #server_hello{server_version = ?'TLS_v1.2',
138		  session_id = session_id(),
139                  random = server_random(Version),
140                  cipher_suite = cipher_suite(Version),
141		  compression_method = compression(Version),
142		  extensions = server_hello_extensions(Version)
143                 };
144server_hello(Version) ->
145    #server_hello{server_version = Version,
146		  session_id = session_id(),
147                  random = server_random(Version),
148                  cipher_suite = cipher_suite(Version),
149		  compression_method = compression(Version),
150		  extensions = server_hello_extensions(Version)
151                 }.
152
153certificate() ->
154    #certificate{
155       asn1_certificates = certificate_chain()
156      }.
157
158certificate_1_3() ->
159     ?LET(Certs, certificate_chain(),
160          #certificate_1_3{
161             certificate_request_context = certificate_request_context(),
162             certificate_list = certificate_entries(Certs, [])
163            }).
164
165certificate_verify_1_3() ->
166     ?LET(Certs, certificate_chain(),
167          #certificate_verify_1_3{
168             algorithm = sig_scheme(),
169             signature = signature()
170            }).
171
172finished() ->
173    ?LET(Size, digest_size(),
174         #finished{verify_data = crypto:strong_rand_bytes(Size)}).
175
176%%
177%% TLS 1.0-1.2 messages
178%%
179
180
181
182%%
183%% TLS 1.3 messages
184%%
185
186encrypted_extensions() ->
187    ?LET(Exts, extensions(?'TLS_v1.3', encrypted_extensions),
188         #encrypted_extensions{extensions = Exts}).
189
190
191key_update() ->
192    #key_update{request_update = request_update()}.
193
194
195%%--------------------------------------------------------------------
196%% Messge Data Generators  -------------------------------------------
197%%--------------------------------------------------------------------
198
199tls_version() ->
200    oneof([?'TLS_v1.3', ?'TLS_v1.2', ?'TLS_v1.1', ?'TLS_v1']).
201
202cipher_suite(Version) ->
203    oneof(cipher_suites(Version)).
204
205cipher_suites(Version) ->
206    ssl_cipher:suites(Version).
207
208session_id() ->
209    crypto:strong_rand_bytes(?NUM_OF_SESSION_ID_BYTES).
210
211compression(Version) ->
212     oneof(compressions(Version)).
213
214compressions(_) ->
215    ssl_record:compressions().
216
217client_random(_) ->
218    crypto:strong_rand_bytes(32).
219
220server_random(_) ->
221    crypto:strong_rand_bytes(32).
222
223
224client_hello_extensions(Version) ->
225    ?LET(Exts, extensions(Version, client_hello),
226         maps:merge(ssl_handshake:empty_extensions(Version, client_hello),
227                    Exts)).
228
229server_hello_extensions(Version) ->
230    ?LET(Exts, extensions(Version, server_hello),
231         maps:merge(ssl_handshake:empty_extensions(Version, server_hello),
232                    Exts)).
233
234key_share_client_hello() ->
235     oneof([undefined]).
236    %%oneof([#key_share_client_hello{}, undefined]).
237
238key_share_server_hello() ->
239     oneof([undefined]).
240    %%oneof([#key_share_server_hello{}, undefined]).
241
242pre_shared_keyextension() ->
243     oneof([undefined]).
244     %%oneof([#pre_shared_keyextension{},undefined]).
245
246%% +--------------------------------------------------+-------------+
247%% | Extension                                        |     TLS 1.3 |
248%% +--------------------------------------------------+-------------+
249%% | server_name [RFC6066]                            |      CH, EE |
250%% |                                                  |             |
251%% | max_fragment_length [RFC6066]                    |      CH, EE |
252%% |                                                  |             |
253%% | status_request [RFC6066]                         |  CH, CR, CT |
254%% |                                                  |             |
255%% | supported_groups [RFC7919]                       |      CH, EE |
256%% |                                                  |             |
257%% | signature_algorithms (RFC 8446)                  |      CH, CR |
258%% |                                                  |             |
259%% | use_srtp [RFC5764]                               |      CH, EE |
260%% |                                                  |             |
261%% | heartbeat [RFC6520]                              |      CH, EE |
262%% |                                                  |             |
263%% | application_layer_protocol_negotiation [RFC7301] |      CH, EE |
264%% |                                                  |             |
265%% | signed_certificate_timestamp [RFC6962]           |  CH, CR, CT |
266%% |                                                  |             |
267%% | client_certificate_type [RFC7250]                |      CH, EE |
268%% |                                                  |             |
269%% | server_certificate_type [RFC7250]                |      CH, EE |
270%% |                                                  |             |
271%% | padding [RFC7685]                                |          CH |
272%% |                                                  |             |
273%% | key_share (RFC 8446)                             | CH, SH, HRR |
274%% |                                                  |             |
275%% | pre_shared_key (RFC 8446)                        |      CH, SH |
276%% |                                                  |             |
277%% | psk_key_exchange_modes (RFC 8446)                |          CH |
278%% |                                                  |             |
279%% | early_data (RFC 8446)                            | CH, EE, NST |
280%% |                                                  |             |
281%% | cookie (RFC 8446)                                |     CH, HRR |
282%% |                                                  |             |
283%% | supported_versions (RFC 8446)                    | CH, SH, HRR |
284%% |                                                  |             |
285%% | certificate_authorities (RFC 8446)               |      CH, CR |
286%% |                                                  |             |
287%% | oid_filters (RFC 8446)                           |          CR |
288%% |                                                  |             |
289%% | post_handshake_auth (RFC 8446)                   |          CH |
290%% |                                                  |             |
291%% | signature_algorithms_cert (RFC 8446)             |      CH, CR |
292%% +--------------------------------------------------+-------------+
293extensions(?'TLS_v1.3' = Version, MsgType = client_hello) ->
294     ?LET({
295           ServerName,
296           %% MaxFragmentLength,
297           %% StatusRequest,
298           SupportedGroups,
299           SignatureAlgorithms,
300           %% UseSrtp,
301           %% Heartbeat,
302           ALPN,
303           %% SignedCertTimestamp,
304           %% ClientCertiticateType,
305           %% ServerCertificateType,
306           %% Padding,
307           KeyShare,
308           PreSharedKey,
309           PSKKeyExchangeModes,
310           %% EarlyData,
311           %% Cookie,
312           SupportedVersions,
313           %% CertAuthorities,
314           %% PostHandshakeAuth,
315           SignatureAlgorithmsCert
316          },
317          {
318           oneof([server_name(), undefined]),
319           %% oneof([max_fragment_length(), undefined]),
320           %% oneof([status_request(), undefined]),
321           oneof([supported_groups(Version), undefined]),
322           oneof([signature_algs(Version), undefined]),
323           %% oneof([use_srtp(), undefined]),
324           %% oneof([heartbeat(), undefined]),
325           oneof([alpn(), undefined]),
326           %% oneof([signed_cert_timestamp(), undefined]),
327           %% oneof([client_cert_type(), undefined]),
328           %% oneof([server_cert_type(), undefined]),
329           %% oneof([padding(), undefined]),
330           oneof([key_share(MsgType), undefined]),
331           oneof([pre_shared_key(MsgType), undefined]),
332           oneof([psk_key_exchange_modes(), undefined]),
333           %% oneof([early_data(), undefined]),
334           %% oneof([cookie(), undefined]),
335           oneof([client_hello_versions(Version)]),
336           %% oneof([cert_authorities(), undefined]),
337           %% oneof([post_handshake_auth(), undefined]),
338           oneof([signature_algs_cert(), undefined])
339          },
340          maps:filter(fun(_, undefined) ->
341                              false;
342                         (_,_) ->
343                              true
344                      end,
345                      #{
346                        sni => ServerName,
347                        %% max_fragment_length => MaxFragmentLength,
348                        %% status_request => StatusRequest,
349                        elliptic_curves => SupportedGroups,
350                        signature_algs => SignatureAlgorithms,
351                        %% use_srtp => UseSrtp,
352                        %% heartbeat => Heartbeat,
353                        alpn => ALPN,
354                        %% signed_cert_timestamp => SignedCertTimestamp,
355                        %% client_cert_type => ClientCertificateType,
356                        %% server_cert_type => ServerCertificateType,
357                        %% padding => Padding,
358                        key_share => KeyShare,
359                        pre_shared_key => PreSharedKey,
360                        psk_key_exchange_modes => PSKKeyExchangeModes,
361                        %% early_data => EarlyData,
362                        %% cookie => Cookie,
363                        client_hello_versions => SupportedVersions,
364                        %% cert_authorities => CertAuthorities,
365                        %% post_handshake_auth => PostHandshakeAuth,
366                        signature_algs_cert => SignatureAlgorithmsCert
367                       }));
368extensions(Version, client_hello) ->
369    ?LET({
370          SNI,
371          ECPoitF,
372          ECCurves,
373          ALPN,
374          NextP,
375          SRP
376          %% RenegotiationInfo
377         },
378         {
379          oneof([sni(), undefined]),
380          oneof([ec_point_formats(), undefined]),
381          oneof([elliptic_curves(Version), undefined]),
382          oneof([alpn(),  undefined]),
383          oneof([next_protocol_negotiation(), undefined]),
384          oneof([srp(), undefined])
385          %% oneof([renegotiation_info(), undefined])
386         },
387         maps:filter(fun(_, undefined) ->
388                             false;
389                        (_,_) ->
390                             true
391                     end,
392                     #{
393                       sni => SNI,
394                       ec_point_formats => ECPoitF,
395                       elliptic_curves => ECCurves,
396                       alpn => ALPN,
397                       next_protocol_negotiation => NextP,
398                       srp => SRP
399                       %% renegotiation_info => RenegotiationInfo
400                      }));
401extensions(?'TLS_v1.3' = Version, MsgType = server_hello) ->
402    ?LET({
403          KeyShare,
404          PreSharedKey,
405          SupportedVersions
406         },
407         {
408          oneof([key_share(MsgType), undefined]),
409          oneof([pre_shared_key(MsgType),  undefined]),
410          oneof([server_hello_selected_version()])
411         },
412         maps:filter(fun(_, undefined) ->
413                             false;
414                        (_,_) ->
415                             true
416                     end,
417                     #{
418                       key_share => KeyShare,
419                       pre_shared_key => PreSharedKey,
420                       server_hello_selected_version => SupportedVersions
421                      }));
422extensions(Version, server_hello) ->
423    ?LET({
424          ECPoitF,
425          ALPN,
426          NextP
427          %% RenegotiationInfo,
428         },
429         {
430          oneof([ec_point_formats(), undefined]),
431          oneof([alpn(),  undefined]),
432          oneof([next_protocol_negotiation(), undefined])
433          %% oneof([renegotiation_info(), undefined]),
434         },
435         maps:filter(fun(_, undefined) ->
436                             false;
437                        (_,_) ->
438                             true
439                     end,
440                     #{
441                       ec_point_formats => ECPoitF,
442                       alpn => ALPN,
443                       next_protocol_negotiation => NextP
444                       %% renegotiation_info => RenegotiationInfo
445                      }));
446extensions(?'TLS_v1.3' = Version, encrypted_extensions) ->
447     ?LET({
448           ServerName,
449           %% MaxFragmentLength,
450           SupportedGroups,
451           %% UseSrtp,
452           %% Heartbeat,
453           ALPN
454           %% ClientCertiticateType,
455           %% ServerCertificateType,
456           %% EarlyData
457          },
458          {
459           oneof([server_name(), undefined]),
460           %% oneof([max_fragment_length(), undefined]),
461           oneof([supported_groups(Version), undefined]),
462           %% oneof([use_srtp(), undefined]),
463           %% oneof([heartbeat(), undefined]),
464           oneof([alpn(), undefined])
465           %% oneof([client_cert_type(), undefined]),
466           %% oneof([server_cert_type(), undefined]),
467           %% oneof([early_data(), undefined])
468          },
469          maps:filter(fun(_, undefined) ->
470                              false;
471                         (_,_) ->
472                              true
473                      end,
474                      #{
475                        sni => ServerName,
476                        %% max_fragment_length => MaxFragmentLength,
477                        elliptic_curves => SupportedGroups,
478                        %% use_srtp => UseSrtp,
479                        %% heartbeat => Heartbeat,
480                        alpn => ALPN
481                        %% client_cert_type => ClientCertificateType,
482                        %% server_cert_type => ServerCertificateType,
483                        %% early_data => EarlyData
484                       })).
485
486server_name() ->
487  ?LET(ServerName, sni(),
488       ServerName).
489    %% sni().
490
491signature_algs_cert() ->
492    ?LET(List,  sig_scheme_list(),
493         #signature_algorithms_cert{signature_scheme_list = List}).
494
495signature_algorithms() ->
496    ?LET(List,  sig_scheme_list(),
497         #signature_algorithms{signature_scheme_list = List}).
498
499sig_scheme_list() ->
500    oneof([[rsa_pkcs1_sha256],
501           [rsa_pkcs1_sha256, ecdsa_sha1],
502           [rsa_pkcs1_sha256,
503            rsa_pkcs1_sha384,
504            rsa_pkcs1_sha512,
505            ecdsa_secp256r1_sha256,
506            ecdsa_secp384r1_sha384,
507            ecdsa_secp521r1_sha512,
508            rsa_pss_rsae_sha256,
509            rsa_pss_rsae_sha384,
510            rsa_pss_rsae_sha512,
511            rsa_pss_pss_sha256,
512            rsa_pss_pss_sha384,
513            rsa_pss_pss_sha512,
514            rsa_pkcs1_sha1,
515            ecdsa_sha1]
516          ]).
517
518sig_scheme() ->
519    oneof([rsa_pkcs1_sha256,
520            rsa_pkcs1_sha384,
521            rsa_pkcs1_sha512,
522            ecdsa_secp256r1_sha256,
523            ecdsa_secp384r1_sha384,
524            ecdsa_secp521r1_sha512,
525            rsa_pss_rsae_sha256,
526            rsa_pss_rsae_sha384,
527            rsa_pss_rsae_sha512,
528            rsa_pss_pss_sha256,
529            rsa_pss_pss_sha384,
530            rsa_pss_pss_sha512,
531            rsa_pkcs1_sha1,
532            ecdsa_sha1]).
533
534signature() ->
535    <<44,119,215,137,54,84,156,26,121,212,64,173,189,226,
536      191,46,76,89,204,2,78,79,163,228,90,21,89,179,4,198,
537      109,14,52,26,230,22,56,8,170,129,86,0,7,132,245,81,
538      181,131,62,70,79,167,112,85,14,171,175,162,110,29,
539      212,198,45,188,83,176,251,197,224,104,95,74,89,59,
540      26,60,63,79,238,196,137,65,23,199,127,145,176,184,
541      216,3,48,116,172,106,97,83,227,172,246,137,91,79,
542      173,119,169,60,67,1,177,117,9,93,38,86,232,253,73,
543      140,17,147,130,110,136,245,73,10,91,70,105,53,225,
544      158,107,60,190,30,14,26,92,147,221,60,117,104,53,70,
545      142,204,7,131,11,183,192,120,246,243,68,99,147,183,
546      49,149,48,188,8,218,17,150,220,121,2,99,194,140,35,
547      13,249,201,37,216,68,45,87,58,18,10,106,11,132,241,
548      71,170,225,216,197,212,29,107,36,80,189,184,202,56,
549      86,213,45,70,34,74,71,48,137,79,212,194,172,151,57,
550      57,30,126,24,157,198,101,220,84,162,89,105,185,245,
551      76,105,212,176,25,6,148,49,194,106,253,241,212,200,
552      37,154,227,53,49,216,72,82,163>>.
553
554client_hello_versions(?'TLS_v1.3') ->
555    ?LET(SupportedVersions,
556         oneof([[{3,4}],
557                %% This list breaks the property but can be used for negative tests
558                %% [{3,3},{3,4}],
559                [{3,4},{3,3}],
560                [{3,4},{3,3},{3,2},{3,1},{3,0}]
561               ]),
562        #client_hello_versions{versions = SupportedVersions});
563client_hello_versions(_) ->
564    ?LET(SupportedVersions,
565         oneof([[{3,3}],
566                [{3,3},{3,2}],
567                [{3,3},{3,2},{3,1},{3,0}]
568               ]),
569        #client_hello_versions{versions = SupportedVersions}).
570
571server_hello_selected_version() ->
572    #server_hello_selected_version{selected_version = {3,4}}.
573
574request_update() ->
575     oneof([update_not_requested, update_requested]).
576
577certificate_chain()->
578    Conf = cert_conf(),
579    ?LET(Chain,
580         choose_certificate_chain(Conf),
581         Chain).
582
583choose_certificate_chain(#{server_config := ServerConf,
584                           client_config := ClientConf}) ->
585    oneof([certificate_chain(ServerConf), certificate_chain(ClientConf)]).
586
587certificate_request_context() ->
588    oneof([<<>>,
589           <<1>>,
590           <<"foobar">>
591          ]).
592certificate_entries([], Acc) ->
593    lists:reverse(Acc);
594certificate_entries([Cert | Rest], Acc) ->
595    certificate_entries(Rest, [certificate_entry(Cert) | Acc]).
596
597certificate_entry(Cert) ->
598    #certificate_entry{data = Cert,
599                       extensions = certificate_entry_extensions()
600                      }.
601certificate_entry_extensions() ->
602    #{}.
603
604certificate_chain(Conf) ->
605    CAs = proplists:get_value(cacerts, Conf),
606    Cert = proplists:get_value(cert, Conf),
607    %% Middle argument are of correct type but will not be used
608    {ok, _, Chain} = ssl_certificate:certificate_chain(Cert, ets:new(foo, []), make_ref(), CAs, encoded),
609    Chain.
610
611cert_conf()->
612    Hostname = net_adm:localhost(),
613    {ok, #hostent{h_addr_list = [_IP |_]}} = inet:gethostbyname(net_adm:localhost()),
614    public_key:pkix_test_data(#{server_chain =>
615                                    #{root => [{key, ssl_test_lib:hardcode_rsa_key(1)}],
616                                      intermediates => [[{key, ssl_test_lib:hardcode_rsa_key(2)}]],
617                                      peer => [{extensions, [#'Extension'{extnID =
618                                                                              ?'id-ce-subjectAltName',
619                                                                          extnValue = [{dNSName, Hostname}],
620                                                                          critical = false}]},
621                                               {key, ssl_test_lib:hardcode_rsa_key(3)}
622                                              ]},
623                                client_chain =>
624                                    #{root => [{key, ssl_test_lib:hardcode_rsa_key(4)}],
625                                      intermediates => [[{key, ssl_test_lib:hardcode_rsa_key(5)}]],
626                                      peer => [{key, ssl_test_lib:hardcode_rsa_key(6)}]}}).
627
628certificate_request(Version) ->
629    #certificate_request{certificate_types = certificate_types(Version),
630			 hashsign_algorithms = hashsign_algorithms(Version),
631			 certificate_authorities = certificate_authorities()}.
632
633certificate_types(?'TLS_v1.3') ->
634    iolist_to_binary([<<?BYTE(?ECDSA_SIGN)>>, <<?BYTE(?RSA_SIGN)>>]);
635certificate_types(?'TLS_v1.2') ->
636    iolist_to_binary([<<?BYTE(?ECDSA_SIGN)>>, <<?BYTE(?RSA_SIGN)>>, <<?BYTE(?DSS_SIGN)>>]);
637certificate_types(_) ->
638    iolist_to_binary([<<?BYTE(?ECDSA_SIGN)>>, <<?BYTE(?RSA_SIGN)>>, <<?BYTE(?DSS_SIGN)>>]).
639
640
641
642signature_algs({3,4}) ->
643    ?LET(Algs, signature_algorithms(),
644         Algs);
645signature_algs({3,3} = Version) ->
646        #hash_sign_algos{hash_sign_algos = hash_alg_list(Version)};
647signature_algs(Version) when Version < {3,3} ->
648    undefined.
649
650
651
652hashsign_algorithms({_, N} = Version) when N >= 3 ->
653    #hash_sign_algos{hash_sign_algos = hash_alg_list(Version)};
654hashsign_algorithms(_) ->
655    undefined.
656
657hash_alg_list(Version) ->
658    ?LET(NumOf, choose(1,15),
659	 ?LET(List, [hash_alg(Version) || _ <- lists:seq(1,NumOf)],
660	      lists:usort(List)
661             )).
662
663hash_alg(Version) ->
664   ?LET(Alg, sign_algorithm(Version),
665         {hash_algorithm(Version, Alg), Alg}
666       ).
667
668hash_algorithm(?'TLS_v1.3', _) ->
669    oneof([sha, sha224, sha256, sha384, sha512]);
670hash_algorithm(?'TLS_v1.2', rsa) ->
671    oneof([sha, sha224, sha256, sha384, sha512]);
672hash_algorithm(_, rsa) ->
673    oneof([md5, sha, sha224, sha256, sha384, sha512]);
674hash_algorithm(_, ecdsa) ->
675    oneof([sha, sha224, sha256, sha384, sha512]);
676hash_algorithm(_, dsa) ->
677    sha.
678
679sign_algorithm(?'TLS_v1.3') ->
680    oneof([rsa, ecdsa]);
681sign_algorithm(_) ->
682    oneof([rsa, dsa, ecdsa]).
683
684certificate_authorities() ->
685    #{server_config := ServerConf} = cert_conf(),
686    Authorities = proplists:get_value(cacerts, ServerConf),
687    Enc = fun(#'OTPCertificate'{tbsCertificate=TBSCert}) ->
688		  OTPSubj = TBSCert#'OTPTBSCertificate'.subject,
689		  DNEncodedBin = public_key:pkix_encode('Name', OTPSubj, otp),
690		  DNEncodedLen = byte_size(DNEncodedBin),
691		  <<?UINT16(DNEncodedLen), DNEncodedBin/binary>>
692	  end,
693    list_to_binary([Enc(public_key:pkix_decode_cert(DERCert, otp)) || DERCert <- Authorities]).
694
695digest_size()->
696   oneof([160,224,256,384,512]).
697
698key_share_entry() ->
699    undefined.
700    %%#key_share_entry{}.
701
702server_hello_selected_version(Version) ->
703    #server_hello_selected_version{selected_version = Version}.
704
705sni() ->
706    #sni{hostname = net_adm:localhost()}.
707
708ec_point_formats() ->
709    #ec_point_formats{ec_point_format_list = ec_point_format_list()}.
710
711ec_point_format_list() ->
712    [?ECPOINT_UNCOMPRESSED].
713
714elliptic_curves({_, Minor}) when Minor < 4 ->
715    Curves = tls_v1:ecc_curves(Minor),
716    #elliptic_curves{elliptic_curve_list = Curves}.
717
718%% RFC 8446 (TLS 1.3) renamed the "elliptic_curve" extension.
719supported_groups({_, Minor}) when Minor >= 4 ->
720    SupportedGroups = tls_v1:groups(Minor),
721    #supported_groups{supported_groups = SupportedGroups}.
722
723
724alpn() ->
725    ?LET(ExtD,  alpn_protocols(), #alpn{extension_data = ExtD}).
726
727alpn_protocols() ->
728    oneof([<<"spdy/2">>, <<"spdy/3">>, <<"http/2">>, <<"http/1.0">>, <<"http/1.1">>]).
729
730next_protocol_negotiation() ->
731   %% Predecessor to APLN
732    ?LET(ExtD,  alpn_protocols(), #next_protocol_negotiation{extension_data = ExtD}).
733
734srp() ->
735   ?LET(Name, gen_name(),  #srp{username = list_to_binary(Name)}).
736
737renegotiation_info() ->
738    #renegotiation_info{renegotiated_connection = 0}.
739
740gen_name() ->
741    ?LET(Size, choose(1,10), gen_string(Size)).
742
743gen_char() ->
744    choose($a,$z).
745
746gen_string(N) ->
747    gen_string(N, []).
748
749gen_string(0, Acc) ->
750    Acc;
751gen_string(N, Acc) ->
752    ?LET(Char, gen_char(), gen_string(N-1, [Char | Acc])).
753
754key_share(client_hello) ->
755    ?LET(ClientShares, key_share_entry_list(),
756        #key_share_client_hello{
757          client_shares = ClientShares});
758key_share(server_hello) ->
759    ?LET([ServerShare], key_share_entry_list(1),
760        #key_share_server_hello{
761          server_share = ServerShare}).
762
763key_share_entry_list() ->
764    Max = length(ssl:groups()),
765    ?LET(Size, choose(1,Max), key_share_entry_list(Size)).
766%%
767key_share_entry_list(N) ->
768    key_share_entry_list(N, ssl:groups(), []).
769%%
770key_share_entry_list(0, _Pool, Acc) ->
771    Acc;
772key_share_entry_list(N, Pool, Acc) ->
773    R = rand:uniform(length(Pool)),
774    G = lists:nth(R, Pool),
775    P = generate_public_key(G),
776    KeyShareEntry =
777        #key_share_entry{
778          group = G,
779          key_exchange = P},
780    key_share_entry_list(N - 1, Pool -- [G], [KeyShareEntry|Acc]).
781
782%% TODO: fix curve generation
783generate_public_key(Group)
784  when Group =:= secp256r1 orelse
785       Group =:= secp384r1 orelse
786       Group =:= secp521r1 orelse
787       Group =:= x448 orelse
788       Group =:= x25519 ->
789    #'ECPrivateKey'{publicKey = PublicKey} =
790        public_key:generate_key({namedCurve, secp256r1}),
791    PublicKey;
792generate_public_key(Group) ->
793    {PublicKey, _} =
794        public_key:generate_key(ssl_dh_groups:dh_params(Group)),
795    PublicKey.
796
797groups() ->
798    Max = length(ssl:groups()),
799    ?LET(Size, choose(1,Max), group_list(Size)).
800
801group_list(N) ->
802    group_list(N, ssl:groups(), []).
803%%
804group_list(0, _Pool, Acc) ->
805    Acc;
806group_list(N, Pool, Acc) ->
807    R = rand:uniform(length(Pool)),
808    G = lists:nth(R, Pool),
809    group_list(N - 1, Pool -- [G], [G|Acc]).
810
811
812ke_modes() ->
813    oneof([[psk_ke],[psk_dhe_ke],[psk_ke,psk_dhe_ke]]).
814
815psk_key_exchange_modes() ->
816    ?LET(KEModes, ke_modes(),
817         #psk_key_exchange_modes{
818            ke_modes = KEModes}).
819
820pre_shared_key(client_hello) ->
821    ?LET(OfferedPsks, offered_psks(),
822         #pre_shared_key_client_hello{
823            offered_psks = OfferedPsks});
824pre_shared_key(server_hello) ->
825    ?LET(SelectedIdentity, selected_identity(),
826         #pre_shared_key_server_hello{
827           selected_identity = SelectedIdentity}).
828
829selected_identity() ->
830    rand:uniform(32).
831
832offered_psks() ->
833    ?LET(Size, choose(1,5),
834         #offered_psks{
835            identities = psk_identities(Size),
836            binders = psk_binders(Size)}).
837
838psk_identities(Size) ->
839    psk_identities(Size, []).
840%%
841psk_identities(0, Acc) ->
842    Acc;
843psk_identities(N, Acc) ->
844    psk_identities(N - 1, [psk_identity()|Acc]).
845
846psk_identity() ->
847    Len = 8 + rand:uniform(8),
848    Identity = crypto:strong_rand_bytes(Len),
849    <<?UINT32(Age)>> = crypto:strong_rand_bytes(4),
850    #psk_identity{
851      identity = Identity,
852      obfuscated_ticket_age = Age}.
853
854psk_binders(Size) ->
855    psk_binders(Size, []).
856%%
857psk_binders(0, Acc) ->
858    Acc;
859psk_binders(N, Acc) ->
860    psk_binders(N - 1, [psk_binder()|Acc]).
861
862psk_binder() ->
863    Len = rand:uniform(224) + 31,
864    crypto:strong_rand_bytes(Len).
865