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