1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 1999-2020. All Rights Reserved. 5%% 6%% Licensed under the Apache License, Version 2.0 (the "License"); 7%% you may not use this file except in compliance with the License. 8%% You may obtain a copy of the License at 9%% 10%% http://www.apache.org/licenses/LICENSE-2.0 11%% 12%% Unless required by applicable law or agreed to in writing, software 13%% distributed under the License is distributed on an "AS IS" BASIS, 14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15%% See the License for the specific language governing permissions and 16%% limitations under the License. 17%% 18%% %CopyrightEnd% 19%% 20 21%% 22 23%%% Purpose : Main API module for the SSL application that implements TLS and DTLS 24%%% SSL is a legacy name. 25 26-module(ssl). 27 28-include_lib("public_key/include/public_key.hrl"). 29 30-include("ssl_internal.hrl"). 31-include("ssl_api.hrl"). 32-include("ssl_record.hrl"). 33-include("ssl_cipher.hrl"). 34-include("ssl_handshake.hrl"). 35-include("ssl_srp.hrl"). 36 37%% Needed to make documentation rendering happy 38-ifndef(VSN). 39-define(VSN,"unknown"). 40-endif. 41 42%% Application handling 43-export([start/0, 44 start/1, 45 stop/0, 46 clear_pem_cache/0]). 47 48%% Socket handling 49-export([connect/3, 50 connect/2, 51 connect/4, 52 listen/2, 53 transport_accept/1, 54 transport_accept/2, 55 handshake/1, 56 handshake/2, 57 handshake/3, 58 handshake_continue/2, 59 handshake_continue/3, 60 handshake_cancel/1, 61 ssl_accept/1, 62 ssl_accept/2, 63 ssl_accept/3, 64 controlling_process/2, 65 peername/1, 66 peercert/1, 67 sockname/1, 68 close/1, 69 close/2, 70 shutdown/2, 71 recv/2, 72 recv/3, 73 send/2, 74 getopts/2, 75 setopts/2, 76 getstat/1, 77 getstat/2 78 ]). 79 80%% SSL/TLS protocol handling 81-export([cipher_suites/0, 82 cipher_suites/1, 83 cipher_suites/2, 84 cipher_suites/3, 85 filter_cipher_suites/2, 86 prepend_cipher_suites/2, 87 append_cipher_suites/2, 88 eccs/0, 89 eccs/1, 90 versions/0, 91 groups/0, 92 groups/1, 93 format_error/1, 94 renegotiate/1, 95 update_keys/2, 96 prf/5, 97 negotiated_protocol/1, 98 connection_information/1, 99 connection_information/2]). 100%% Misc 101-export([handle_options/2, 102 handle_options/3, 103 tls_version/1, 104 suite_to_str/1, 105 suite_to_openssl_str/1, 106 str_to_suite/1]). 107 108-deprecated({ssl_accept, '_', "use ssl_handshake/1,2,3 instead"}). 109 110-deprecated({cipher_suites, 0, "use cipher_suites/2,3 instead"}). 111-deprecated({cipher_suites, 1, "use cipher_suites/2,3 instead"}). 112 113-removed([{negotiated_next_protocol,1, 114 "use ssl:negotiated_protocol/1 instead"}]). 115-removed([{connection_info,1, 116 "use ssl:connection_information/[1,2] instead"}]). 117 118-export_type([socket/0, 119 sslsocket/0, 120 socket_option/0, 121 active_msgs/0, 122 host/0, 123 tls_option/0, 124 tls_client_option/0, 125 tls_server_option/0, 126 erl_cipher_suite/0, 127 old_cipher_suite/0, 128 ciphers/0, 129 cipher/0, 130 hash/0, 131 key/0, 132 kex_algo/0, 133 prf_random/0, 134 cipher_filters/0, 135 sign_algo/0, 136 protocol_version/0, 137 protocol_extensions/0, 138 session_id/0, 139 error_alert/0, 140 tls_alert/0, 141 srp_param_type/0, 142 named_curve/0, 143 sign_scheme/0, 144 group/0]). 145 146%% ------------------------------------------------------------------------------------------------------- 147 148-type socket() :: gen_tcp:socket(). % exported 149-type socket_option() :: gen_tcp:connect_option() | gen_tcp:listen_option() | gen_udp:option(). % exported 150-type sslsocket() :: any(). % exported 151-type tls_option() :: tls_client_option() | tls_server_option(). % exported 152-type tls_client_option() :: client_option() | common_option() | socket_option() | transport_option(). % exported 153-type tls_server_option() :: server_option() | common_option() | socket_option() | transport_option(). % exported 154-type active_msgs() :: {ssl, sslsocket(), Data::binary() | list()} | {ssl_closed, sslsocket()} | 155 {ssl_error, sslsocket(), Reason::any()} | {ssl_passive, sslsocket()}. % exported 156-type transport_option() :: {cb_info, {CallbackModule::atom(), DataTag::atom(), 157 ClosedTag::atom(), ErrTag::atom()}} | 158 {cb_info, {CallbackModule::atom(), DataTag::atom(), 159 ClosedTag::atom(), ErrTag::atom(), PassiveTag::atom()}}. 160-type host() :: hostname() | ip_address(). % exported 161-type hostname() :: string(). 162-type ip_address() :: inet:ip_address(). 163-type session_id() :: binary(). % exported 164-type protocol_version() :: tls_version() | dtls_version(). % exported 165-type tls_version() :: 'tlsv1.2' | 'tlsv1.3' | tls_legacy_version(). 166-type dtls_version() :: 'dtlsv1.2' | dtls_legacy_version(). 167-type tls_legacy_version() :: tlsv1 | 'tlsv1.1' . 168-type dtls_legacy_version() :: 'dtlsv1'. 169-type verify_type() :: verify_none | verify_peer. 170-type cipher() :: aes_128_cbc | 171 aes_256_cbc | 172 aes_128_gcm | 173 aes_256_gcm | 174 aes_128_ccm | 175 aes_256_ccm | 176 aes_128_ccm_8 | 177 aes_256_ccm_8 | 178 chacha20_poly1305 | 179 legacy_cipher(). % exported 180-type legacy_cipher() :: rc4_128 | 181 des_cbc | 182 '3des_ede_cbc'. 183 184-type hash() :: sha | 185 sha2() | 186 legacy_hash(). % exported 187 188-type sha2() :: sha224 | 189 sha256 | 190 sha384 | 191 sha512. 192 193-type legacy_hash() :: md5. 194 195-type sign_algo() :: rsa | dsa | ecdsa. % exported 196 197-type sign_scheme() :: rsa_pkcs1_sha256 198 | rsa_pkcs1_sha384 199 | rsa_pkcs1_sha512 200 | ecdsa_secp256r1_sha256 201 | ecdsa_secp384r1_sha384 202 | ecdsa_secp521r1_sha512 203 | rsa_pss_rsae_sha256 204 | rsa_pss_rsae_sha384 205 | rsa_pss_rsae_sha512 206 | rsa_pss_pss_sha256 207 | rsa_pss_pss_sha384 208 | rsa_pss_pss_sha512 209 | rsa_pkcs1_sha1 210 | ecdsa_sha1. % exported 211 212-type kex_algo() :: rsa | 213 dhe_rsa | dhe_dss | 214 ecdhe_ecdsa | ecdh_ecdsa | ecdh_rsa | 215 srp_rsa| srp_dss | 216 psk | dhe_psk | rsa_psk | 217 dh_anon | ecdh_anon | srp_anon | 218 any. %% TLS 1.3 , exported 219-type erl_cipher_suite() :: #{key_exchange := kex_algo(), 220 cipher := cipher(), 221 mac := hash() | aead, 222 prf := hash() | default_prf %% Old cipher suites, version dependent 223 }. 224 225-type old_cipher_suite() :: {kex_algo(), cipher(), hash()} % Pre TLS 1.2 226 %% TLS 1.2, internally PRE TLS 1.2 will use default_prf 227 | {kex_algo(), cipher(), hash() | aead, hash()}. 228 229-type named_curve() :: sect571r1 | 230 sect571k1 | 231 secp521r1 | 232 brainpoolP512r1 | 233 sect409k1 | 234 sect409r1 | 235 brainpoolP384r1 | 236 secp384r1 | 237 sect283k1 | 238 sect283r1 | 239 brainpoolP256r1 | 240 secp256k1 | 241 secp256r1 | 242 sect239k1 | 243 sect233k1 | 244 sect233r1 | 245 secp224k1 | 246 secp224r1 | 247 sect193r1 | 248 sect193r2 | 249 secp192k1 | 250 secp192r1 | 251 sect163k1 | 252 sect163r1 | 253 sect163r2 | 254 secp160k1 | 255 secp160r1 | 256 secp160r2. % exported 257 258-type group() :: secp256r1 | secp384r1 | secp521r1 | ffdhe2048 | 259 ffdhe3072 | ffdhe4096 | ffdhe6144 | ffdhe8192. % exported 260 261-type srp_param_type() :: srp_1024 | 262 srp_1536 | 263 srp_2048 | 264 srp_3072 | 265 srp_4096 | 266 srp_6144 | 267 srp_8192. % exported 268 269-type error_alert() :: {tls_alert, {tls_alert(), Description::string()}}. % exported 270 271-type tls_alert() :: close_notify | 272 unexpected_message | 273 bad_record_mac | 274 record_overflow | 275 handshake_failure | 276 bad_certificate | 277 unsupported_certificate | 278 certificate_revoked | 279 certificate_expired | 280 certificate_unknown | 281 illegal_parameter | 282 unknown_ca | 283 access_denied | 284 decode_error | 285 decrypt_error | 286 export_restriction| 287 protocol_version | 288 insufficient_security | 289 internal_error | 290 inappropriate_fallback | 291 user_canceled | 292 no_renegotiation | 293 unsupported_extension | 294 certificate_unobtainable | 295 unrecognized_name | 296 bad_certificate_status_response | 297 bad_certificate_hash_value | 298 unknown_psk_identity | 299 no_application_protocol. % exported 300 301%% ------------------------------------------------------------------------------------------------------- 302-type common_option() :: {protocol, protocol()} | 303 {handshake, handshake_completion()} | 304 {cert, cert() | [cert()]} | 305 {certfile, cert_pem()} | 306 {key, key()} | 307 {keyfile, key_pem()} | 308 {password, key_password()} | 309 {ciphers, cipher_suites()} | 310 {eccs, [named_curve()]} | 311 {signature_algs_cert, signature_schemes()} | 312 {supported_groups, supported_groups()} | 313 {secure_renegotiate, secure_renegotiation()} | 314 {keep_secrets, keep_secrets()} | 315 {depth, allowed_cert_chain_length()} | 316 {verify_fun, custom_verify()} | 317 {crl_check, crl_check()} | 318 {crl_cache, crl_cache_opts()} | 319 {max_handshake_size, handshake_size()} | 320 {partial_chain, root_fun()} | 321 {versions, protocol_versions()} | 322 {user_lookup_fun, custom_user_lookup()} | 323 {log_level, logging_level()} | 324 {log_alert, log_alert()} | 325 {hibernate_after, hibernate_after()} | 326 {padding_check, padding_check()} | 327 {beast_mitigation, beast_mitigation()} | 328 {ssl_imp, ssl_imp()} | 329 {session_tickets, session_tickets()} | 330 {key_update_at, key_update_at()} | 331 {middlebox_comp_mode, middlebox_comp_mode()}. 332 333-type protocol() :: tls | dtls. 334-type handshake_completion() :: hello | full. 335-type cert() :: public_key:der_encoded(). 336-type cert_pem() :: file:filename(). 337-type key() :: {'RSAPrivateKey'| 'DSAPrivateKey' | 'ECPrivateKey' |'PrivateKeyInfo', 338 public_key:der_encoded()} | 339 #{algorithm := rsa | dss | ecdsa, 340 engine := crypto:engine_ref(), 341 key_id := crypto:key_id(), 342 password => crypto:password()}. % exported 343-type key_pem() :: file:filename(). 344-type key_password() :: string(). 345-type cipher_suites() :: ciphers(). 346-type ciphers() :: [erl_cipher_suite()] | 347 string(). % (according to old API) exported 348-type cipher_filters() :: list({key_exchange | cipher | mac | prf, 349 algo_filter()}). % exported 350-type algo_filter() :: fun((kex_algo()|cipher()|hash()|aead|default_prf) -> true | false). 351-type keep_secrets() :: boolean(). 352-type secure_renegotiation() :: boolean(). 353-type allowed_cert_chain_length() :: integer(). 354 355-type custom_verify() :: {Verifyfun :: fun(), InitialUserState :: any()}. 356-type crl_check() :: boolean() | peer | best_effort. 357-type crl_cache_opts() :: {Module :: atom(), 358 {DbHandle :: internal | term(), 359 Args :: list()}}. 360-type handshake_size() :: integer(). 361-type hibernate_after() :: timeout(). 362-type root_fun() :: fun(). 363-type protocol_versions() :: [protocol_version()]. 364-type signature_algs() :: [{hash(), sign_algo()}]. 365-type signature_schemes() :: [sign_scheme()]. 366-type supported_groups() :: [group()]. 367-type custom_user_lookup() :: {Lookupfun :: fun(), UserState :: any()}. 368-type padding_check() :: boolean(). 369-type beast_mitigation() :: one_n_minus_one | zero_n | disabled. 370-type srp_identity() :: {Username :: string(), Password :: string()}. 371-type psk_identity() :: string(). 372-type log_alert() :: boolean(). 373-type logging_level() :: logger:level() | none | all. 374-type client_session_tickets() :: disabled | manual | auto. 375-type server_session_tickets() :: disabled | stateful | stateless. 376-type session_tickets() :: client_session_tickets() | server_session_tickets(). 377-type key_update_at() :: pos_integer(). 378-type bloom_filter_window_size() :: integer(). 379-type bloom_filter_hash_functions() :: integer(). 380-type bloom_filter_bits() :: integer(). 381-type anti_replay() :: '10k' | '100k' | 382 {bloom_filter_window_size(), %% number of seconds in time window 383 bloom_filter_hash_functions(), %% k - number of hash functions 384 bloom_filter_bits()}. %% m - number of bits in bit vector 385-type use_ticket() :: [binary()]. 386-type middlebox_comp_mode() :: boolean(). 387-type client_early_data() :: binary(). 388-type server_early_data() :: disabled | enabled. 389 390%% ------------------------------------------------------------------------------------------------------- 391 392-type client_option() :: {verify, client_verify_type()} | 393 {reuse_session, client_reuse_session()} | 394 {reuse_sessions, client_reuse_sessions()} | 395 {cacerts, client_cacerts()} | 396 {cacertfile, client_cafile()} | 397 {alpn_advertised_protocols, client_alpn()} | 398 {client_preferred_next_protocols, client_preferred_next_protocols()} | 399 {psk_identity, client_psk_identity()} | 400 {srp_identity, client_srp_identity()} | 401 {server_name_indication, sni()} | 402 {max_fragment_length, max_fragment_length()} | 403 {customize_hostname_check, customize_hostname_check()} | 404 {signature_algs, client_signature_algs()} | 405 {fallback, fallback()} | 406 {session_tickets, client_session_tickets()} | 407 {use_ticket, use_ticket()} | 408 {early_data, client_early_data()}. 409 %% {ocsp_stapling, ocsp_stapling()} | 410 %% {ocsp_responder_certs, ocsp_responder_certs()} | 411 %% {ocsp_nonce, ocsp_nonce()}. 412 413-type client_verify_type() :: verify_type(). 414-type client_reuse_session() :: session_id() | {session_id(), SessionData::binary()}. 415-type client_reuse_sessions() :: boolean() | save. 416-type client_cacerts() :: [public_key:der_encoded()]. 417-type client_cafile() :: file:filename(). 418-type app_level_protocol() :: binary(). 419-type client_alpn() :: [app_level_protocol()]. 420-type client_preferred_next_protocols() :: {Precedence :: server | client, 421 ClientPrefs :: [app_level_protocol()]} | 422 {Precedence :: server | client, 423 ClientPrefs :: [app_level_protocol()], 424 Default::app_level_protocol()}. 425-type client_psk_identity() :: psk_identity(). 426-type client_srp_identity() :: srp_identity(). 427-type customize_hostname_check() :: list(). 428-type sni() :: HostName :: hostname() | disable. 429-type max_fragment_length() :: undefined | 512 | 1024 | 2048 | 4096. 430-type client_signature_algs() :: signature_algs(). 431-type fallback() :: boolean(). 432-type ssl_imp() :: new | old. 433%% -type ocsp_stapling() :: boolean(). 434%% -type ocsp_responder_certs() :: [public_key:der_encoded()]. 435%% -type ocsp_nonce() :: boolean(). 436 437%% ------------------------------------------------------------------------------------------------------- 438 439-type server_option() :: {cacerts, server_cacerts()} | 440 {cacertfile, server_cafile()} | 441 {dh, dh_der()} | 442 {dhfile, dh_file()} | 443 {verify, server_verify_type()} | 444 {fail_if_no_peer_cert, fail_if_no_peer_cert()} | 445 {reuse_sessions, server_reuse_sessions()} | 446 {reuse_session, server_reuse_session()} | 447 {alpn_preferred_protocols, server_alpn()} | 448 {next_protocols_advertised, server_next_protocol()} | 449 {psk_identity, server_psk_identity()} | 450 {honor_cipher_order, boolean()} | 451 {sni_hosts, sni_hosts()} | 452 {sni_fun, sni_fun()} | 453 {honor_cipher_order, honor_cipher_order()} | 454 {honor_ecc_order, honor_ecc_order()} | 455 {client_renegotiation, client_renegotiation()}| 456 {signature_algs, server_signature_algs()} | 457 {session_tickets, server_session_tickets()} | 458 {anti_replay, anti_replay()} | 459 {cookie, cookie()} | 460 {early_data, server_early_data()}. 461 462-type server_cacerts() :: [public_key:der_encoded()]. 463-type server_cafile() :: file:filename(). 464-type server_alpn() :: [app_level_protocol()]. 465-type server_next_protocol() :: [app_level_protocol()]. 466-type server_psk_identity() :: psk_identity(). 467-type dh_der() :: binary(). 468-type dh_file() :: file:filename(). 469-type server_verify_type() :: verify_type(). 470-type fail_if_no_peer_cert() :: boolean(). 471-type server_signature_algs() :: signature_algs(). 472-type server_reuse_session() :: fun(). 473-type server_reuse_sessions() :: boolean(). 474-type sni_hosts() :: [{hostname(), [server_option() | common_option()]}]. 475-type sni_fun() :: fun(). 476-type honor_cipher_order() :: boolean(). 477-type honor_ecc_order() :: boolean(). 478-type client_renegotiation() :: boolean(). 479-type cookie() :: boolean(). 480%% ------------------------------------------------------------------------------------------------------- 481-type prf_random() :: client_random | server_random. % exported 482-type protocol_extensions() :: #{renegotiation_info => binary(), 483 signature_algs => signature_algs(), 484 alpn => app_level_protocol(), 485 srp => binary(), 486 next_protocol => app_level_protocol(), 487 max_frag_enum => 1..4, 488 ec_point_formats => [0..2], 489 elliptic_curves => [public_key:oid()], 490 sni => hostname()}. % exported 491%% ------------------------------------------------------------------------------------------------------- 492-type connection_info() :: [common_info() | curve_info() | ssl_options_info() | security_info()]. 493-type common_info() :: {protocol, protocol_version()} | 494 {session_id, session_id()} | 495 {session_resumption, boolean()} | 496 {selected_cipher_suite, erl_cipher_suite()} | 497 {sni_hostname, term()} | 498 {srp_username, term()}. 499-type curve_info() :: {ecc, {named_curve, term()}}. 500-type ssl_options_info() :: tls_option(). 501-type security_info() :: {client_random, binary()} | 502 {server_random, binary()} | 503 {master_secret, binary()}. 504-type connection_info_items() :: [connection_info_item()]. 505-type connection_info_item() :: protocol | 506 session_id | 507 session_resumption | 508 selected_cipher_suite | 509 sni_hostname | 510 srp_username | 511 ecc | 512 client_random | 513 server_random | 514 master_secret | 515 keylog | 516 tls_options_name(). 517-type tls_options_name() :: atom(). 518%% ------------------------------------------------------------------------------------------------------- 519 520%%%-------------------------------------------------------------------- 521%%% API 522%%%-------------------------------------------------------------------- 523 524%%-------------------------------------------------------------------- 525%% 526%% Description: Utility function that starts the ssl and applications 527%% that it depends on. 528%% see application(3) 529%%-------------------------------------------------------------------- 530-spec start() -> ok | {error, reason()}. 531start() -> 532 start(temporary). 533-spec start(permanent | transient | temporary) -> ok | {error, reason()}. 534start(Type) -> 535 case application:ensure_all_started(ssl, Type) of 536 {ok, _} -> 537 ok; 538 Other -> 539 Other 540 end. 541%%-------------------------------------------------------------------- 542-spec stop() -> ok. 543%% 544%% Description: Stops the ssl application. 545%%-------------------------------------------------------------------- 546stop() -> 547 application:stop(ssl). 548 549%%-------------------------------------------------------------------- 550%% 551%% Description: Connect to an ssl server. 552%%-------------------------------------------------------------------- 553 554-spec connect(TCPSocket, TLSOptions) -> 555 {ok, sslsocket()} | 556 {error, reason()} | 557 {option_not_a_key_value_tuple, any()} when 558 TCPSocket :: socket(), 559 TLSOptions :: [tls_client_option()]. 560 561connect(Socket, SslOptions) -> 562 connect(Socket, SslOptions, infinity). 563 564-spec connect(TCPSocket, TLSOptions, Timeout) -> 565 {ok, sslsocket()} | {error, reason()} when 566 TCPSocket :: socket(), 567 TLSOptions :: [tls_client_option()], 568 Timeout :: timeout(); 569 (Host, Port, TLSOptions) -> 570 {ok, sslsocket()} | 571 {ok, sslsocket(),Ext :: protocol_extensions()} | 572 {error, reason()} | 573 {option_not_a_key_value_tuple, any()} when 574 Host :: host(), 575 Port :: inet:port_number(), 576 TLSOptions :: [tls_client_option()]. 577 578connect(Socket, SslOptions0, Timeout) when is_list(SslOptions0) andalso 579 (is_integer(Timeout) andalso Timeout >= 0) or (Timeout == infinity) -> 580 581 CbInfo = handle_option_cb_info(SslOptions0, tls), 582 Transport = element(1, CbInfo), 583 try handle_options(Transport, Socket, SslOptions0, client, undefined) of 584 {ok, Config} -> 585 tls_socket:upgrade(Socket, Config, Timeout) 586 catch 587 _:{error, Reason} -> 588 {error, Reason} 589 end; 590connect(Host, Port, Options) -> 591 connect(Host, Port, Options, infinity). 592 593-spec connect(Host, Port, TLSOptions, Timeout) -> 594 {ok, sslsocket()} | 595 {ok, sslsocket(),Ext :: protocol_extensions()} | 596 {error, reason()} | 597 {option_not_a_key_value_tuple, any()} when 598 Host :: host(), 599 Port :: inet:port_number(), 600 TLSOptions :: [tls_client_option()], 601 Timeout :: timeout(). 602 603connect(Host, Port, Options, Timeout) when (is_integer(Timeout) andalso Timeout >= 0) or (Timeout == infinity) -> 604 try 605 {ok, Config} = handle_options(Options, client, Host), 606 case Config#config.connection_cb of 607 tls_gen_connection -> 608 tls_socket:connect(Host,Port,Config,Timeout); 609 dtls_gen_connection -> 610 dtls_socket:connect(Host,Port,Config,Timeout) 611 end 612 catch 613 throw:Error -> 614 Error 615 end. 616 617%%-------------------------------------------------------------------- 618-spec listen(Port, Options) -> {ok, ListenSocket} | {error, reason()} when 619 Port::inet:port_number(), 620 Options::[tls_server_option()], 621 ListenSocket :: sslsocket(). 622 623%% 624%% Description: Creates an ssl listen socket. 625%%-------------------------------------------------------------------- 626listen(_Port, []) -> 627 {error, nooptions}; 628listen(Port, Options0) -> 629 try 630 {ok, Config} = handle_options(Options0, server), 631 do_listen(Port, Config, Config#config.connection_cb) 632 catch 633 Error = {error, _} -> 634 Error 635 end. 636%%-------------------------------------------------------------------- 637%% 638%% Description: Performs transport accept on an ssl listen socket 639%%-------------------------------------------------------------------- 640-spec transport_accept(ListenSocket) -> {ok, SslSocket} | 641 {error, reason()} when 642 ListenSocket :: sslsocket(), 643 SslSocket :: sslsocket(). 644 645transport_accept(ListenSocket) -> 646 transport_accept(ListenSocket, infinity). 647 648-spec transport_accept(ListenSocket, Timeout) -> {ok, SslSocket} | 649 {error, reason()} when 650 ListenSocket :: sslsocket(), 651 Timeout :: timeout(), 652 SslSocket :: sslsocket(). 653 654transport_accept(#sslsocket{pid = {ListenSocket, 655 #config{connection_cb = ConnectionCb} = Config}}, Timeout) 656 when (is_integer(Timeout) andalso Timeout >= 0) or (Timeout == infinity) -> 657 case ConnectionCb of 658 tls_gen_connection -> 659 tls_socket:accept(ListenSocket, Config, Timeout); 660 dtls_gen_connection -> 661 dtls_socket:accept(ListenSocket, Config, Timeout) 662 end. 663 664%%-------------------------------------------------------------------- 665%% 666%% Description: Performs accept on an ssl listen socket. e.i. performs 667%% ssl handshake. 668%%-------------------------------------------------------------------- 669-spec ssl_accept(SslSocket) -> 670 ok | 671 {error, Reason} when 672 SslSocket :: sslsocket(), 673 Reason :: closed | timeout | error_alert(). 674 675ssl_accept(ListenSocket) -> 676 ssl_accept(ListenSocket, [], infinity). 677 678-spec ssl_accept(Socket, TimeoutOrOptions) -> 679 ok | 680 {ok, sslsocket()} | {error, Reason} when 681 Socket :: sslsocket() | socket(), 682 TimeoutOrOptions :: timeout() | [tls_server_option()], 683 Reason :: timeout | closed | {options, any()} | error_alert(). 684 685ssl_accept(Socket, Timeout) when (is_integer(Timeout) andalso Timeout >= 0) or (Timeout == infinity) -> 686 ssl_accept(Socket, [], Timeout); 687ssl_accept(ListenSocket, SslOptions) when is_port(ListenSocket) -> 688 ssl_accept(ListenSocket, SslOptions, infinity); 689ssl_accept(Socket, Timeout) -> 690 ssl_accept(Socket, [], Timeout). 691 692-spec ssl_accept(Socket, Options, Timeout) -> 693 ok | {ok, sslsocket()} | {error, Reason} when 694 Socket :: sslsocket() | socket(), 695 Options :: [tls_server_option()], 696 Timeout :: timeout(), 697 Reason :: timeout | closed | {options, any()} | error_alert(). 698 699ssl_accept(Socket, SslOptions, Timeout) when is_port(Socket) -> 700 handshake(Socket, SslOptions, Timeout); 701ssl_accept(Socket, SslOptions, Timeout) -> 702 case handshake(Socket, SslOptions, Timeout) of 703 {ok, _} -> 704 ok; 705 Error -> 706 Error 707 end. 708%%-------------------------------------------------------------------- 709%% 710%% Description: Performs accept on an ssl listen socket. e.i. performs 711%% ssl handshake. 712%%-------------------------------------------------------------------- 713 714%% Performs the SSL/TLS/DTLS server-side handshake. 715-spec handshake(HsSocket) -> {ok, SslSocket} | {ok, SslSocket, Ext} | {error, Reason} when 716 HsSocket :: sslsocket(), 717 SslSocket :: sslsocket(), 718 Ext :: protocol_extensions(), 719 Reason :: closed | timeout | error_alert(). 720 721handshake(ListenSocket) -> 722 handshake(ListenSocket, infinity). 723 724-spec handshake(HsSocket, Timeout) -> {ok, SslSocket} | {ok, SslSocket, Ext} | {error, Reason} when 725 HsSocket :: sslsocket(), 726 Timeout :: timeout(), 727 SslSocket :: sslsocket(), 728 Ext :: protocol_extensions(), 729 Reason :: closed | timeout | error_alert(); 730 (Socket, Options) -> {ok, SslSocket} | {ok, SslSocket, Ext} | {error, Reason} when 731 Socket :: socket() | sslsocket(), 732 SslSocket :: sslsocket(), 733 Options :: [server_option()], 734 Ext :: protocol_extensions(), 735 Reason :: closed | timeout | error_alert(). 736 737handshake(#sslsocket{} = Socket, Timeout) when (is_integer(Timeout) andalso Timeout >= 0) or 738 (Timeout == infinity) -> 739 ssl_gen_statem:handshake(Socket, Timeout); 740 741%% If Socket is a ordinary socket(): upgrades a gen_tcp, or equivalent, socket to 742%% an SSL socket, that is, performs the SSL/TLS server-side handshake and returns 743%% the SSL socket. 744%% 745%% If Socket is an sslsocket(): provides extra SSL/TLS/DTLS options to those 746%% specified in ssl:listen/2 and then performs the SSL/TLS/DTLS handshake. 747handshake(ListenSocket, SslOptions) -> 748 handshake(ListenSocket, SslOptions, infinity). 749-spec handshake(Socket, Options, Timeout) -> 750 {ok, SslSocket} | 751 {ok, SslSocket, Ext} | 752 {error, Reason} when 753 Socket :: socket() | sslsocket(), 754 SslSocket :: sslsocket(), 755 Options :: [server_option()], 756 Timeout :: timeout(), 757 Ext :: protocol_extensions(), 758 Reason :: closed | timeout | {options, any()} | error_alert(). 759 760handshake(#sslsocket{} = Socket, [], Timeout) when (is_integer(Timeout) andalso Timeout >= 0) or 761 (Timeout == infinity)-> 762 handshake(Socket, Timeout); 763handshake(#sslsocket{fd = {_, _, _, Trackers}} = Socket, SslOpts, Timeout) when 764 (is_integer(Timeout) andalso Timeout >= 0) or (Timeout == infinity)-> 765 try 766 Tracker = proplists:get_value(option_tracker, Trackers), 767 {ok, EmOpts, _} = tls_socket:get_all_opts(Tracker), 768 ssl_gen_statem:handshake(Socket, {SslOpts, 769 tls_socket:emulated_socket_options(EmOpts, #socket_options{})}, Timeout) 770 catch 771 Error = {error, _Reason} -> Error 772 end; 773handshake(#sslsocket{pid = [Pid|_], fd = {_, _, _}} = Socket, SslOpts, Timeout) when 774 (is_integer(Timeout) andalso Timeout >= 0) or (Timeout == infinity)-> 775 try 776 {ok, EmOpts, _} = dtls_packet_demux:get_all_opts(Pid), 777 ssl_gen_statem:handshake(Socket, {SslOpts, 778 tls_socket:emulated_socket_options(EmOpts, #socket_options{})}, Timeout) 779 catch 780 Error = {error, _Reason} -> Error 781 end; 782handshake(Socket, SslOptions, Timeout) when (is_integer(Timeout) andalso Timeout >= 0) or (Timeout == infinity) -> 783 CbInfo = handle_option_cb_info(SslOptions, tls), 784 Transport = element(1, CbInfo), 785 ConnetionCb = connection_cb(SslOptions), 786 try handle_options(Transport, Socket, SslOptions, server, undefined) of 787 {ok, #config{transport_info = CbInfo, ssl = SslOpts, emulated = EmOpts}} -> 788 ok = tls_socket:setopts(Transport, Socket, tls_socket:internal_inet_values()), 789 {ok, Port} = tls_socket:port(Transport, Socket), 790 {ok, SessionIdHandle} = tls_socket:session_id_tracker(ssl_unknown_listener, SslOpts), 791 ssl_gen_statem:handshake(ConnetionCb, Port, Socket, 792 {SslOpts, 793 tls_socket:emulated_socket_options(EmOpts, #socket_options{}), 794 [{session_id_tracker, SessionIdHandle}]}, 795 self(), CbInfo, Timeout) 796 catch 797 Error = {error, _Reason} -> Error 798 end. 799 800%%-------------------------------------------------------------------- 801-spec handshake_continue(HsSocket, Options) -> 802 {ok, SslSocket} | {error, Reason} when 803 HsSocket :: sslsocket(), 804 Options :: [tls_client_option() | tls_server_option()], 805 SslSocket :: sslsocket(), 806 Reason :: closed | timeout | error_alert(). 807%% 808%% 809%% Description: Continues the handshke possible with newly supplied options. 810%%-------------------------------------------------------------------- 811handshake_continue(Socket, SSLOptions) -> 812 handshake_continue(Socket, SSLOptions, infinity). 813%%-------------------------------------------------------------------- 814-spec handshake_continue(HsSocket, Options, Timeout) -> 815 {ok, SslSocket} | {error, Reason} when 816 HsSocket :: sslsocket(), 817 Options :: [tls_client_option() | tls_server_option()], 818 Timeout :: timeout(), 819 SslSocket :: sslsocket(), 820 Reason :: closed | timeout | error_alert(). 821%% 822%% 823%% Description: Continues the handshke possible with newly supplied options. 824%%-------------------------------------------------------------------- 825handshake_continue(Socket, SSLOptions, Timeout) -> 826 ssl_gen_statem:handshake_continue(Socket, SSLOptions, Timeout). 827%%-------------------------------------------------------------------- 828-spec handshake_cancel(#sslsocket{}) -> any(). 829%% 830%% Description: Cancels the handshakes sending a close alert. 831%%-------------------------------------------------------------------- 832handshake_cancel(Socket) -> 833 ssl_gen_statem:handshake_cancel(Socket). 834 835%%-------------------------------------------------------------------- 836-spec close(SslSocket) -> ok | {error, Reason} when 837 SslSocket :: sslsocket(), 838 Reason :: any(). 839%% 840%% Description: Close an ssl connection 841%%-------------------------------------------------------------------- 842close(#sslsocket{pid = [Pid|_]}) when is_pid(Pid) -> 843 ssl_gen_statem:close(Pid, {close, ?DEFAULT_TIMEOUT}); 844close(#sslsocket{pid = {dtls, #config{dtls_handler = {_, _}}}} = DTLSListen) -> 845 dtls_socket:close(DTLSListen); 846close(#sslsocket{pid = {ListenSocket, #config{transport_info={Transport,_,_,_,_}}}}) -> 847 Transport:close(ListenSocket). 848 849%%-------------------------------------------------------------------- 850-spec close(SslSocket, How) -> ok | {ok, port()} | {error,Reason} when 851 SslSocket :: sslsocket(), 852 How :: timeout() | {NewController::pid(), timeout()}, 853 Reason :: any(). 854%% 855%% Description: Close an ssl connection 856%%-------------------------------------------------------------------- 857close(#sslsocket{pid = [TLSPid|_]}, 858 {Pid, Timeout} = DownGrade) when is_pid(TLSPid), 859 is_pid(Pid), 860 (is_integer(Timeout) andalso Timeout >= 0) or (Timeout == infinity) -> 861 case ssl_gen_statem:close(TLSPid, {close, DownGrade}) of 862 ok -> %% In normal close {error, closed} is regarded as ok, as it is not interesting which side 863 %% that got to do the actual close. But in the downgrade case only {ok, Port} is a sucess. 864 {error, closed}; 865 Other -> 866 Other 867 end; 868close(#sslsocket{pid = [TLSPid|_]}, Timeout) when is_pid(TLSPid), 869 (is_integer(Timeout) andalso Timeout >= 0) or (Timeout == infinity) -> 870 ssl_gen_statem:close(TLSPid, {close, Timeout}); 871close(#sslsocket{pid = {dtls = ListenSocket, #config{transport_info={Transport,_,_,_,_}}}}, _) -> 872 dtls_socket:close(Transport, ListenSocket); 873close(#sslsocket{pid = {ListenSocket, #config{transport_info={Transport,_,_,_,_}}}}, _) -> 874 tls_socket:close(Transport, ListenSocket). 875 876%%-------------------------------------------------------------------- 877-spec send(SslSocket, Data) -> ok | {error, reason()} when 878 SslSocket :: sslsocket(), 879 Data :: iodata(). 880%% 881%% Description: Sends data over the ssl connection 882%%-------------------------------------------------------------------- 883send(#sslsocket{pid = [Pid]}, Data) when is_pid(Pid) -> 884 ssl_gen_statem:send(Pid, Data); 885send(#sslsocket{pid = [_, Pid]}, Data) when is_pid(Pid) -> 886 tls_sender:send_data(Pid, erlang:iolist_to_iovec(Data)); 887send(#sslsocket{pid = {_, #config{transport_info={_, udp, _, _}}}}, _) -> 888 {error,enotconn}; %% Emulate connection behaviour 889send(#sslsocket{pid = {dtls,_}}, _) -> 890 {error,enotconn}; %% Emulate connection behaviour 891send(#sslsocket{pid = {ListenSocket, #config{transport_info = Info}}}, Data) -> 892 Transport = element(1, Info), 893 Transport:send(ListenSocket, Data). %% {error,enotconn} 894 895%%-------------------------------------------------------------------- 896%% 897%% Description: Receives data when active = false 898%%-------------------------------------------------------------------- 899-spec recv(SslSocket, Length) -> {ok, Data} | {error, reason()} when 900 SslSocket :: sslsocket(), 901 Length :: integer(), 902 Data :: binary() | list() | HttpPacket, 903 HttpPacket :: any(). 904 905recv(Socket, Length) -> 906 recv(Socket, Length, infinity). 907 908-spec recv(SslSocket, Length, Timeout) -> {ok, Data} | {error, reason()} when 909 SslSocket :: sslsocket(), 910 Length :: integer(), 911 Data :: binary() | list() | HttpPacket, 912 Timeout :: timeout(), 913 HttpPacket :: any(). 914 915recv(#sslsocket{pid = [Pid|_]}, Length, Timeout) when is_pid(Pid), 916 (is_integer(Timeout) andalso Timeout >= 0) or (Timeout == infinity)-> 917 ssl_gen_statem:recv(Pid, Length, Timeout); 918recv(#sslsocket{pid = {dtls,_}}, _, _) -> 919 {error,enotconn}; 920recv(#sslsocket{pid = {Listen, 921 #config{transport_info = Info}}},_,_) when is_port(Listen)-> 922 Transport = element(1, Info), 923 Transport:recv(Listen, 0). %% {error,enotconn} 924 925%%-------------------------------------------------------------------- 926-spec controlling_process(SslSocket, NewOwner) -> ok | {error, Reason} when 927 SslSocket :: sslsocket(), 928 NewOwner :: pid(), 929 Reason :: any(). 930%% 931%% Description: Changes process that receives the messages when active = true 932%% or once. 933%%-------------------------------------------------------------------- 934controlling_process(#sslsocket{pid = [Pid|_]}, NewOwner) when is_pid(Pid), is_pid(NewOwner) -> 935 ssl_gen_statem:new_user(Pid, NewOwner); 936controlling_process(#sslsocket{pid = {dtls, _}}, 937 NewOwner) when is_pid(NewOwner) -> 938 ok; %% Meaningless but let it be allowed to conform with TLS 939controlling_process(#sslsocket{pid = {Listen, 940 #config{transport_info = {Transport,_,_,_,_}}}}, 941 NewOwner) when is_port(Listen), 942 is_pid(NewOwner) -> 943 %% Meaningless but let it be allowed to conform with normal sockets 944 Transport:controlling_process(Listen, NewOwner). 945 946 947%%-------------------------------------------------------------------- 948-spec connection_information(SslSocket) -> {ok, Result} | {error, reason()} when 949 SslSocket :: sslsocket(), 950 Result :: connection_info(). 951%% 952%% Description: Return SSL information for the connection 953%%-------------------------------------------------------------------- 954connection_information(#sslsocket{pid = [Pid|_]}) when is_pid(Pid) -> 955 case ssl_gen_statem:connection_information(Pid, false) of 956 {ok, Info} -> 957 {ok, [Item || Item = {_Key, Value} <- Info, Value =/= undefined]}; 958 Error -> 959 Error 960 end; 961connection_information(#sslsocket{pid = {Listen, _}}) when is_port(Listen) -> 962 {error, enotconn}; 963connection_information(#sslsocket{pid = {dtls,_}}) -> 964 {error,enotconn}. 965 966%%-------------------------------------------------------------------- 967-spec connection_information(SslSocket, Items) -> {ok, Result} | {error, reason()} when 968 SslSocket :: sslsocket(), 969 Items :: connection_info_items(), 970 Result :: connection_info(). 971%% 972%% Description: Return SSL information for the connection 973%%-------------------------------------------------------------------- 974connection_information(#sslsocket{pid = [Pid|_]}, Items) when is_pid(Pid) -> 975 case ssl_gen_statem:connection_information(Pid, include_security_info(Items)) of 976 {ok, Info} -> 977 {ok, [Item || Item = {Key, Value} <- Info, lists:member(Key, Items), 978 Value =/= undefined]}; 979 Error -> 980 Error 981 end. 982 983%%-------------------------------------------------------------------- 984-spec peername(SslSocket) -> {ok, {Address, Port}} | 985 {error, reason()} when 986 SslSocket :: sslsocket(), 987 Address :: inet:ip_address(), 988 Port :: inet:port_number(). 989%% 990%% Description: same as inet:peername/1. 991%%-------------------------------------------------------------------- 992peername(#sslsocket{pid = [Pid|_], fd = {Transport, Socket,_}}) when is_pid(Pid)-> 993 dtls_socket:peername(Transport, Socket); 994peername(#sslsocket{pid = [Pid|_], fd = {Transport, Socket,_,_}}) when is_pid(Pid)-> 995 tls_socket:peername(Transport, Socket); 996peername(#sslsocket{pid = {dtls, #config{dtls_handler = {_Pid,_}}}}) -> 997 dtls_socket:peername(dtls, undefined); 998peername(#sslsocket{pid = {ListenSocket, #config{transport_info = {Transport,_,_,_,_}}}}) -> 999 tls_socket:peername(Transport, ListenSocket); %% Will return {error, enotconn} 1000peername(#sslsocket{pid = {dtls,_}}) -> 1001 {error,enotconn}. 1002 1003%%-------------------------------------------------------------------- 1004-spec peercert(SslSocket) -> {ok, Cert} | {error, reason()} when 1005 SslSocket :: sslsocket(), 1006 Cert :: binary(). 1007%% 1008%% Description: Returns the peercert. 1009%%-------------------------------------------------------------------- 1010peercert(#sslsocket{pid = [Pid|_]}) when is_pid(Pid) -> 1011 case ssl_gen_statem:peer_certificate(Pid) of 1012 {ok, undefined} -> 1013 {error, no_peercert}; 1014 Result -> 1015 Result 1016 end; 1017peercert(#sslsocket{pid = {dtls, _}}) -> 1018 {error, enotconn}; 1019peercert(#sslsocket{pid = {Listen, _}}) when is_port(Listen) -> 1020 {error, enotconn}. 1021 1022%%-------------------------------------------------------------------- 1023-spec negotiated_protocol(SslSocket) -> {ok, Protocol} | {error, Reason} when 1024 SslSocket :: sslsocket(), 1025 Protocol :: binary(), 1026 Reason :: protocol_not_negotiated. 1027%% 1028%% Description: Returns the protocol that has been negotiated. If no 1029%% protocol has been negotiated will return {error, protocol_not_negotiated} 1030%%-------------------------------------------------------------------- 1031negotiated_protocol(#sslsocket{pid = [Pid|_]}) when is_pid(Pid) -> 1032 ssl_gen_statem:negotiated_protocol(Pid). 1033 1034%%-------------------------------------------------------------------- 1035-spec cipher_suites() -> [old_cipher_suite()] | [string()]. 1036%%-------------------------------------------------------------------- 1037cipher_suites() -> 1038 cipher_suites(erlang). 1039%%-------------------------------------------------------------------- 1040-spec cipher_suites(Type) -> [old_cipher_suite() | string()] when 1041 Type :: erlang | openssl | all. 1042 1043%% Description: Returns all supported cipher suites. 1044%%-------------------------------------------------------------------- 1045cipher_suites(erlang) -> 1046 [ssl_cipher_format:suite_legacy(Suite) || Suite <- available_suites(default)]; 1047 1048cipher_suites(openssl) -> 1049 [ssl_cipher_format:suite_map_to_openssl_str(ssl_cipher_format:suite_bin_to_map(Suite)) || 1050 Suite <- available_suites(default)]; 1051 1052cipher_suites(all) -> 1053 [ssl_cipher_format:suite_legacy(Suite) || Suite <- available_suites(all)]. 1054 1055%%-------------------------------------------------------------------- 1056-spec cipher_suites(Description, Version) -> ciphers() when 1057 Description :: default | all | exclusive | anonymous, 1058 Version :: protocol_version(). 1059 1060%% Description: Returns all default and all supported cipher suites for a 1061%% TLS/DTLS version 1062%%-------------------------------------------------------------------- 1063cipher_suites(Description, Version) when Version == 'tlsv1.3'; 1064 Version == 'tlsv1.2'; 1065 Version == 'tlsv1.1'; 1066 Version == tlsv1 -> 1067 cipher_suites(Description, tls_record:protocol_version(Version)); 1068cipher_suites(Description, Version) when Version == 'dtlsv1.2'; 1069 Version == 'dtlsv1'-> 1070 cipher_suites(Description, dtls_record:protocol_version(Version)); 1071cipher_suites(Description, Version) -> 1072 [ssl_cipher_format:suite_bin_to_map(Suite) || Suite <- supported_suites(Description, Version)]. 1073 1074%%-------------------------------------------------------------------- 1075-spec cipher_suites(Description, Version, rfc | openssl) -> [string()] when 1076 Description :: default | all | exclusive | anonymous, 1077 Version :: protocol_version(). 1078 1079%% Description: Returns all default and all supported cipher suites for a 1080%% TLS/DTLS version 1081%%-------------------------------------------------------------------- 1082cipher_suites(Description, Version, StringType) when Version == 'tlsv1.3'; 1083 Version == 'tlsv1.2'; 1084 Version == 'tlsv1.1'; 1085 Version == tlsv1 -> 1086 cipher_suites(Description, tls_record:protocol_version(Version), StringType); 1087cipher_suites(Description, Version, StringType) when Version == 'dtlsv1.2'; 1088 Version == 'dtlsv1'-> 1089 cipher_suites(Description, dtls_record:protocol_version(Version), StringType); 1090cipher_suites(Description, Version, rfc) -> 1091 [ssl_cipher_format:suite_map_to_str(ssl_cipher_format:suite_bin_to_map(Suite)) 1092 || Suite <- supported_suites(Description, Version)]; 1093cipher_suites(Description, Version, openssl) -> 1094 [ssl_cipher_format:suite_map_to_openssl_str(ssl_cipher_format:suite_bin_to_map(Suite)) 1095 || Suite <- supported_suites(Description, Version)]. 1096 1097%%-------------------------------------------------------------------- 1098-spec filter_cipher_suites(Suites, Filters) -> Ciphers when 1099 Suites :: ciphers(), 1100 Filters :: cipher_filters(), 1101 Ciphers :: ciphers(). 1102 1103%% Description: Removes cipher suites if any of the filter functions returns false 1104%% for any part of the cipher suite. This function also calls default filter functions 1105%% to make sure the cipher suite are supported by crypto. 1106%%-------------------------------------------------------------------- 1107filter_cipher_suites(Suites, Filters0) -> 1108 #{key_exchange_filters := KexF, 1109 cipher_filters := CipherF, 1110 mac_filters := MacF, 1111 prf_filters := PrfF} 1112 = ssl_cipher:crypto_support_filters(), 1113 Filters = #{key_exchange_filters => add_filter(proplists:get_value(key_exchange, Filters0), KexF), 1114 cipher_filters => add_filter(proplists:get_value(cipher, Filters0), CipherF), 1115 mac_filters => add_filter(proplists:get_value(mac, Filters0), MacF), 1116 prf_filters => add_filter(proplists:get_value(prf, Filters0), PrfF)}, 1117 ssl_cipher:filter_suites(Suites, Filters). 1118%%-------------------------------------------------------------------- 1119-spec prepend_cipher_suites(Preferred, Suites) -> ciphers() when 1120 Preferred :: ciphers() | cipher_filters(), 1121 Suites :: ciphers(). 1122 1123%% Description: Make <Preferred> suites become the most prefered 1124%% suites that is put them at the head of the cipher suite list 1125%% and remove them from <Suites> if present. <Preferred> may be a 1126%% list of cipher suites or a list of filters in which case the 1127%% filters are use on Suites to extract the the preferred 1128%% cipher list. 1129%% -------------------------------------------------------------------- 1130prepend_cipher_suites([First | _] = Preferred, Suites0) when is_map(First) -> 1131 Suites = Preferred ++ (Suites0 -- Preferred), 1132 Suites; 1133prepend_cipher_suites(Filters, Suites) -> 1134 Preferred = filter_cipher_suites(Suites, Filters), 1135 Preferred ++ (Suites -- Preferred). 1136%%-------------------------------------------------------------------- 1137-spec append_cipher_suites(Deferred, Suites) -> ciphers() when 1138 Deferred :: ciphers() | cipher_filters(), 1139 Suites :: ciphers(). 1140 1141%% Description: Make <Deferred> suites suites become the 1142%% least prefered suites that is put them at the end of the cipher suite list 1143%% and removed them from <Suites> if present. 1144%% 1145%%-------------------------------------------------------------------- 1146append_cipher_suites([First | _] = Deferred, Suites0) when is_map(First)-> 1147 Suites = (Suites0 -- Deferred) ++ Deferred, 1148 Suites; 1149append_cipher_suites(Filters, Suites) -> 1150 Deferred = filter_cipher_suites(Suites, Filters), 1151 (Suites -- Deferred) ++ Deferred. 1152 1153%%-------------------------------------------------------------------- 1154-spec eccs() -> NamedCurves when 1155 NamedCurves :: [named_curve()]. 1156 1157%% Description: returns all supported curves across all versions 1158%%-------------------------------------------------------------------- 1159eccs() -> 1160 Curves = tls_v1:ecc_curves(all), % only tls_v1 has named curves right now 1161 eccs_filter_supported(Curves). 1162 1163%%-------------------------------------------------------------------- 1164-spec eccs(Version) -> NamedCurves when 1165 Version :: protocol_version(), 1166 NamedCurves :: [named_curve()]. 1167 1168%% Description: returns the curves supported for a given version of 1169%% ssl/tls. 1170%%-------------------------------------------------------------------- 1171eccs('dtlsv1') -> 1172 eccs('tlsv1.1'); 1173eccs('dtlsv1.2') -> 1174 eccs('tlsv1.2'); 1175eccs(Version) when Version == 'tlsv1.2'; 1176 Version == 'tlsv1.1'; 1177 Version == tlsv1 -> 1178 Curves = tls_v1:ecc_curves(all), 1179 eccs_filter_supported(Curves). 1180 1181eccs_filter_supported(Curves) -> 1182 CryptoCurves = crypto:ec_curves(), 1183 lists:filter(fun(Curve) -> proplists:get_bool(Curve, CryptoCurves) end, 1184 Curves). 1185 1186%%-------------------------------------------------------------------- 1187-spec groups() -> [group()]. 1188%% Description: returns all supported groups (TLS 1.3 and later) 1189%%-------------------------------------------------------------------- 1190groups() -> 1191 tls_v1:groups(4). 1192 1193%%-------------------------------------------------------------------- 1194-spec groups(default) -> [group()]. 1195%% Description: returns the default groups (TLS 1.3 and later) 1196%%-------------------------------------------------------------------- 1197groups(default) -> 1198 tls_v1:default_groups(4). 1199 1200%%-------------------------------------------------------------------- 1201-spec getopts(SslSocket, OptionNames) -> 1202 {ok, [gen_tcp:option()]} | {error, reason()} when 1203 SslSocket :: sslsocket(), 1204 OptionNames :: [gen_tcp:option_name()]. 1205%% 1206%% Description: Gets options 1207%%-------------------------------------------------------------------- 1208getopts(#sslsocket{pid = [Pid|_]}, OptionTags) when is_pid(Pid), is_list(OptionTags) -> 1209 ssl_gen_statem:get_opts(Pid, OptionTags); 1210getopts(#sslsocket{pid = {dtls, #config{transport_info = {Transport,_,_,_,_}}}} = ListenSocket, OptionTags) when is_list(OptionTags) -> 1211 try dtls_socket:getopts(Transport, ListenSocket, OptionTags) of 1212 {ok, _} = Result -> 1213 Result; 1214 {error, InetError} -> 1215 {error, {options, {socket_options, OptionTags, InetError}}} 1216 catch 1217 _:Error -> 1218 {error, {options, {socket_options, OptionTags, Error}}} 1219 end; 1220getopts(#sslsocket{pid = {_, #config{transport_info = {Transport,_,_,_,_}}}} = ListenSocket, 1221 OptionTags) when is_list(OptionTags) -> 1222 try tls_socket:getopts(Transport, ListenSocket, OptionTags) of 1223 {ok, _} = Result -> 1224 Result; 1225 {error, InetError} -> 1226 {error, {options, {socket_options, OptionTags, InetError}}} 1227 catch 1228 _:Error -> 1229 {error, {options, {socket_options, OptionTags, Error}}} 1230 end; 1231getopts(#sslsocket{}, OptionTags) -> 1232 {error, {options, {socket_options, OptionTags}}}. 1233 1234%%-------------------------------------------------------------------- 1235-spec setopts(SslSocket, Options) -> ok | {error, reason()} when 1236 SslSocket :: sslsocket(), 1237 Options :: [gen_tcp:option()]. 1238%% 1239%% Description: Sets options 1240%%-------------------------------------------------------------------- 1241setopts(#sslsocket{pid = [Pid, Sender]}, Options0) when is_pid(Pid), is_list(Options0) -> 1242 try proplists:expand([{binary, [{mode, binary}]}, 1243 {list, [{mode, list}]}], Options0) of 1244 Options -> 1245 case proplists:get_value(packet, Options, undefined) of 1246 undefined -> 1247 ssl_gen_statem:set_opts(Pid, Options); 1248 PacketOpt -> 1249 case tls_sender:setopts(Sender, [{packet, PacketOpt}]) of 1250 ok -> 1251 ssl_gen_statem:set_opts(Pid, Options); 1252 Error -> 1253 Error 1254 end 1255 end 1256 catch 1257 _:_ -> 1258 {error, {options, {not_a_proplist, Options0}}} 1259 end; 1260setopts(#sslsocket{pid = [Pid|_]}, Options0) when is_pid(Pid), is_list(Options0) -> 1261 try proplists:expand([{binary, [{mode, binary}]}, 1262 {list, [{mode, list}]}], Options0) of 1263 Options -> 1264 ssl_gen_statem:set_opts(Pid, Options) 1265 catch 1266 _:_ -> 1267 {error, {options, {not_a_proplist, Options0}}} 1268 end; 1269setopts(#sslsocket{pid = {dtls, #config{transport_info = {Transport,_,_,_,_}}}} = ListenSocket, Options) when is_list(Options) -> 1270 try dtls_socket:setopts(Transport, ListenSocket, Options) of 1271 ok -> 1272 ok; 1273 {error, InetError} -> 1274 {error, {options, {socket_options, Options, InetError}}} 1275 catch 1276 _:Error -> 1277 {error, {options, {socket_options, Options, Error}}} 1278 end; 1279setopts(#sslsocket{pid = {_, #config{transport_info = {Transport,_,_,_,_}}}} = ListenSocket, Options) when is_list(Options) -> 1280 try tls_socket:setopts(Transport, ListenSocket, Options) of 1281 ok -> 1282 ok; 1283 {error, InetError} -> 1284 {error, {options, {socket_options, Options, InetError}}} 1285 catch 1286 _:Error -> 1287 {error, {options, {socket_options, Options, Error}}} 1288 end; 1289setopts(#sslsocket{}, Options) -> 1290 {error, {options,{not_a_proplist, Options}}}. 1291 1292%%--------------------------------------------------------------- 1293-spec getstat(SslSocket) -> 1294 {ok, OptionValues} | {error, inet:posix()} when 1295 SslSocket :: sslsocket(), 1296 OptionValues :: [{inet:stat_option(), integer()}]. 1297%% 1298%% Description: Get all statistic options for a socket. 1299%%-------------------------------------------------------------------- 1300getstat(Socket) -> 1301 getstat(Socket, inet:stats()). 1302 1303%%--------------------------------------------------------------- 1304-spec getstat(SslSocket, Options) -> 1305 {ok, OptionValues} | {error, inet:posix()} when 1306 SslSocket :: sslsocket(), 1307 Options :: [inet:stat_option()], 1308 OptionValues :: [{inet:stat_option(), integer()}]. 1309%% 1310%% Description: Get one or more statistic options for a socket. 1311%%-------------------------------------------------------------------- 1312getstat(#sslsocket{pid = {dtls, #config{transport_info = {Transport, _, _, _, _}, 1313 dtls_handler = {Listner, _}}}}, 1314 Options) when is_list(Options) -> 1315 dtls_socket:getstat(Transport, Listner, Options); 1316getstat(#sslsocket{pid = {Listen, #config{transport_info = {Transport, _, _, _, _}}}}, 1317 Options) when is_port(Listen), is_list(Options) -> 1318 tls_socket:getstat(Transport, Listen, Options); 1319getstat(#sslsocket{pid = [Pid|_], fd = {Transport, Socket, _, _}}, 1320 Options) when is_pid(Pid), is_list(Options) -> 1321 tls_socket:getstat(Transport, Socket, Options); 1322getstat(#sslsocket{pid = [Pid|_], fd = {Transport, Socket, _}}, 1323 Options) when is_pid(Pid), is_list(Options) -> 1324 dtls_socket:getstat(Transport, Socket, Options). 1325 1326%%--------------------------------------------------------------- 1327-spec shutdown(SslSocket, How) -> ok | {error, reason()} when 1328 SslSocket :: sslsocket(), 1329 How :: read | write | read_write. 1330%% 1331%% Description: Same as gen_tcp:shutdown/2 1332%%-------------------------------------------------------------------- 1333shutdown(#sslsocket{pid = {Listen, #config{transport_info = Info}}}, 1334 How) when is_port(Listen) -> 1335 Transport = element(1, Info), 1336 Transport:shutdown(Listen, How); 1337shutdown(#sslsocket{pid = {dtls,_}},_) -> 1338 {error, enotconn}; 1339shutdown(#sslsocket{pid = [Pid|_]}, How) when is_pid(Pid) -> 1340 ssl_gen_statem:shutdown(Pid, How). 1341 1342%%-------------------------------------------------------------------- 1343-spec sockname(SslSocket) -> 1344 {ok, {Address, Port}} | {error, reason()} when 1345 SslSocket :: sslsocket(), 1346 Address :: inet:ip_address(), 1347 Port :: inet:port_number(). 1348%% 1349%% Description: Same as inet:sockname/1 1350%%-------------------------------------------------------------------- 1351sockname(#sslsocket{pid = {Listen, #config{transport_info = {Transport,_,_,_,_}}}}) when is_port(Listen) -> 1352 tls_socket:sockname(Transport, Listen); 1353sockname(#sslsocket{pid = {dtls, #config{dtls_handler = {Pid, _}}}}) -> 1354 dtls_packet_demux:sockname(Pid); 1355sockname(#sslsocket{pid = [Pid|_], fd = {Transport, Socket,_}}) when is_pid(Pid) -> 1356 dtls_socket:sockname(Transport, Socket); 1357sockname(#sslsocket{pid = [Pid| _], fd = {Transport, Socket,_,_}}) when is_pid(Pid) -> 1358 tls_socket:sockname(Transport, Socket). 1359 1360%%--------------------------------------------------------------- 1361-spec versions() -> [VersionInfo] when 1362 VersionInfo :: {ssl_app, string()} | 1363 {supported | available | implemented, [tls_version()]} | 1364 {supported_dtls | available_dtls | implemented_dtls, [dtls_version()]}. 1365%% 1366%% Description: Returns a list of relevant versions. 1367%%-------------------------------------------------------------------- 1368versions() -> 1369 ConfTLSVsns = tls_record:supported_protocol_versions(), 1370 ConfDTLSVsns = dtls_record:supported_protocol_versions(), 1371 ImplementedTLSVsns = ?ALL_AVAILABLE_VERSIONS, 1372 ImplementedDTLSVsns = ?ALL_AVAILABLE_DATAGRAM_VERSIONS, 1373 1374 TLSCryptoSupported = fun(Vsn) -> 1375 tls_record:sufficient_crypto_support(Vsn) 1376 end, 1377 DTLSCryptoSupported = fun(Vsn) -> 1378 tls_record:sufficient_crypto_support(dtls_v1:corresponding_tls_version(Vsn)) 1379 end, 1380 SupportedTLSVsns = [tls_record:protocol_version(Vsn) || Vsn <- ConfTLSVsns, TLSCryptoSupported(Vsn)], 1381 SupportedDTLSVsns = [dtls_record:protocol_version(Vsn) || Vsn <- ConfDTLSVsns, DTLSCryptoSupported(Vsn)], 1382 1383 AvailableTLSVsns = [Vsn || Vsn <- ImplementedTLSVsns, TLSCryptoSupported(tls_record:protocol_version(Vsn))], 1384 AvailableDTLSVsns = [Vsn || Vsn <- ImplementedDTLSVsns, DTLSCryptoSupported(dtls_record:protocol_version(Vsn))], 1385 1386 [{ssl_app, ?VSN}, 1387 {supported, SupportedTLSVsns}, 1388 {supported_dtls, SupportedDTLSVsns}, 1389 {available, AvailableTLSVsns}, 1390 {available_dtls, AvailableDTLSVsns}, 1391 {implemented, ImplementedTLSVsns}, 1392 {implemented_dtls, ImplementedDTLSVsns} 1393 ]. 1394 1395%%--------------------------------------------------------------- 1396-spec renegotiate(SslSocket) -> ok | {error, reason()} when 1397 SslSocket :: sslsocket(). 1398%% 1399%% Description: Initiates a renegotiation. 1400%%-------------------------------------------------------------------- 1401renegotiate(#sslsocket{pid = [Pid, Sender |_]}) when is_pid(Pid), 1402 is_pid(Sender) -> 1403 case tls_sender:renegotiate(Sender) of 1404 {ok, Write} -> 1405 tls_dtls_connection:renegotiation(Pid, Write); 1406 Error -> 1407 Error 1408 end; 1409renegotiate(#sslsocket{pid = [Pid |_]}) when is_pid(Pid) -> 1410 tls_dtls_connection:renegotiation(Pid); 1411renegotiate(#sslsocket{pid = {dtls,_}}) -> 1412 {error, enotconn}; 1413renegotiate(#sslsocket{pid = {Listen,_}}) when is_port(Listen) -> 1414 {error, enotconn}. 1415 1416 1417%%--------------------------------------------------------------- 1418-spec update_keys(SslSocket, Type) -> ok | {error, reason()} when 1419 SslSocket :: sslsocket(), 1420 Type :: write | read_write. 1421%% 1422%% Description: Initiate a key update. 1423%%-------------------------------------------------------------------- 1424update_keys(#sslsocket{pid = [Pid, Sender |_]}, Type0) when is_pid(Pid) andalso 1425 is_pid(Sender) andalso 1426 (Type0 =:= write orelse 1427 Type0 =:= read_write) -> 1428 Type = case Type0 of 1429 write -> 1430 update_not_requested; 1431 read_write -> 1432 update_requested 1433 end, 1434 tls_connection_1_3:send_key_update(Sender, Type); 1435update_keys(_, Type) -> 1436 {error, {illegal_parameter, Type}}. 1437 1438%%-------------------------------------------------------------------- 1439-spec prf(SslSocket, Secret, Label, Seed, WantedLength) -> 1440 {ok, binary()} | {error, reason()} when 1441 SslSocket :: sslsocket(), 1442 Secret :: binary() | 'master_secret', 1443 Label::binary(), 1444 Seed :: [binary() | prf_random()], 1445 WantedLength :: non_neg_integer(). 1446%% 1447%% Description: use a ssl sessions TLS PRF to generate key material 1448%%-------------------------------------------------------------------- 1449prf(#sslsocket{pid = [Pid|_]}, 1450 Secret, Label, Seed, WantedLength) when is_pid(Pid) -> 1451 tls_dtls_connection:prf(Pid, Secret, Label, Seed, WantedLength); 1452prf(#sslsocket{pid = {dtls,_}}, _,_,_,_) -> 1453 {error, enotconn}; 1454prf(#sslsocket{pid = {Listen,_}}, _,_,_,_) when is_port(Listen) -> 1455 {error, enotconn}. 1456 1457%%-------------------------------------------------------------------- 1458-spec clear_pem_cache() -> ok. 1459%% 1460%% Description: Clear the PEM cache 1461%%-------------------------------------------------------------------- 1462clear_pem_cache() -> 1463 ssl_pem_cache:clear(). 1464 1465%%--------------------------------------------------------------- 1466-spec format_error({error, Reason}) -> string() when 1467 Reason :: any(). 1468%% 1469%% Description: Creates error string. 1470%%-------------------------------------------------------------------- 1471format_error({error, Reason}) -> 1472 format_error(Reason); 1473format_error(Reason) when is_list(Reason) -> 1474 Reason; 1475format_error(closed) -> 1476 "TLS connection is closed"; 1477format_error({tls_alert, {_, Description}}) -> 1478 Description; 1479format_error({options,{FileType, File, Reason}}) when FileType == cacertfile; 1480 FileType == certfile; 1481 FileType == keyfile; 1482 FileType == dhfile -> 1483 Error = file_error_format(Reason), 1484 file_desc(FileType) ++ File ++ ": " ++ Error; 1485format_error({options, {socket_options, Option, Error}}) -> 1486 lists:flatten(io_lib:format("Invalid transport socket option ~p: ~s", [Option, format_error(Error)])); 1487format_error({options, {socket_options, Option}}) -> 1488 lists:flatten(io_lib:format("Invalid socket option: ~p", [Option])); 1489format_error({options, Options}) -> 1490 lists:flatten(io_lib:format("Invalid TLS option: ~p", [Options])); 1491 1492format_error(Error) -> 1493 case inet:format_error(Error) of 1494 "unknown POSIX" ++ _ -> 1495 unexpected_format(Error); 1496 Other -> 1497 Other 1498 end. 1499 1500tls_version({3, _} = Version) -> 1501 Version; 1502tls_version({254, _} = Version) -> 1503 dtls_v1:corresponding_tls_version(Version). 1504 1505%%-------------------------------------------------------------------- 1506-spec suite_to_str(CipherSuite) -> string() when 1507 CipherSuite :: erl_cipher_suite(); 1508 (CipherSuite) -> string() when 1509 %% For internal use! 1510 CipherSuite :: #{key_exchange := null, 1511 cipher := null, 1512 mac := null, 1513 prf := null}. 1514%% 1515%% Description: Return the string representation of a cipher suite. 1516%%-------------------------------------------------------------------- 1517suite_to_str(Cipher) -> 1518 ssl_cipher_format:suite_map_to_str(Cipher). 1519 1520%%-------------------------------------------------------------------- 1521-spec suite_to_openssl_str(CipherSuite) -> string() when 1522 CipherSuite :: erl_cipher_suite(). 1523%% 1524%% Description: Return the string representation of a cipher suite. 1525%%-------------------------------------------------------------------- 1526suite_to_openssl_str(Cipher) -> 1527 ssl_cipher_format:suite_map_to_openssl_str(Cipher). 1528 1529%% 1530%%-------------------------------------------------------------------- 1531-spec str_to_suite(CipherSuiteName) -> erl_cipher_suite() when 1532 CipherSuiteName :: string() | {error, {not_recognized, CipherSuiteName :: string()}}. 1533%% 1534%% Description: Return the map representation of a cipher suite. 1535%%-------------------------------------------------------------------- 1536str_to_suite(CipherSuiteName) -> 1537 try 1538 %% Note in TLS-1.3 OpenSSL conforms to RFC names 1539 %% so if CipherSuiteName starts with TLS this 1540 %% function will call ssl_cipher_format:suite_str_to_map 1541 %% so both RFC names and legacy OpenSSL names of supported 1542 %% cipher suites will be handled 1543 ssl_cipher_format:suite_openssl_str_to_map(CipherSuiteName) 1544 catch 1545 _:_ -> 1546 {error, {not_recognized, CipherSuiteName}} 1547 end. 1548 1549%%%-------------------------------------------------------------- 1550%%% Internal functions 1551%%%-------------------------------------------------------------------- 1552 1553%% Possible filters out suites not supported by crypto 1554available_suites(default) -> 1555 Version = tls_record:highest_protocol_version([]), 1556 ssl_cipher:filter_suites(ssl_cipher:suites(Version)); 1557available_suites(all) -> 1558 Version = tls_record:highest_protocol_version([]), 1559 ssl_cipher:filter_suites(ssl_cipher:all_suites(Version)). 1560 1561supported_suites(exclusive, {3,Minor}) -> 1562 tls_v1:exclusive_suites(Minor); 1563supported_suites(default, Version) -> 1564 ssl_cipher:suites(Version); 1565supported_suites(all, Version) -> 1566 ssl_cipher:all_suites(Version); 1567supported_suites(anonymous, Version) -> 1568 ssl_cipher:anonymous_suites(Version). 1569 1570do_listen(Port, #config{transport_info = {Transport, _, _, _,_}} = Config, tls_gen_connection) -> 1571 tls_socket:listen(Transport, Port, Config); 1572 1573do_listen(Port, Config, dtls_gen_connection) -> 1574 dtls_socket:listen(Port, Config). 1575 1576-spec handle_options([any()], client | server) -> {ok, #config{}}; 1577 ([any()], ssl_options()) -> ssl_options(). 1578 1579handle_options(Opts, Role) -> 1580 handle_options(undefined, undefined, Opts, Role, undefined). 1581 1582handle_options(Opts, Role, InheritedSslOpts) -> 1583 handle_options(undefined, undefined, Opts, Role, InheritedSslOpts). 1584 1585%% Handle ssl options at handshake, handshake_continue 1586handle_options(_, _, Opts0, Role, InheritedSslOpts) when is_map(InheritedSslOpts) -> 1587 {SslOpts, _} = expand_options(Opts0, ?RULES), 1588 process_options(SslOpts, InheritedSslOpts, #{role => Role, 1589 rules => ?RULES}); 1590%% Handle all options in listen, connect and handshake 1591handle_options(Transport, Socket, Opts0, Role, Host) -> 1592 {SslOpts0, SockOpts0} = expand_options(Opts0, ?RULES), 1593 1594 %% Ensure all options are evaluated at startup 1595 SslOpts1 = add_missing_options(SslOpts0, ?RULES), 1596 SslOpts = #{protocol := Protocol} 1597 = process_options(SslOpts1, 1598 #{}, 1599 #{role => Role, 1600 host => Host, 1601 rules => ?RULES}), 1602 1603 %% Handle special options 1604 {Sock, Emulated} = emulated_options(Transport, Socket, Protocol, SockOpts0), 1605 ConnetionCb = connection_cb(Protocol), 1606 CbInfo = handle_option_cb_info(Opts0, Protocol), 1607 1608 {ok, #config{ 1609 ssl = SslOpts, 1610 emulated = Emulated, 1611 inet_ssl = Sock, 1612 inet_user = Sock, 1613 transport_info = CbInfo, 1614 connection_cb = ConnetionCb 1615 }}. 1616 1617 1618%% process_options(SSLOptions, OptionsMap, Env) where 1619%% SSLOptions is the following tuple: 1620%% {InOptions, SkippedOptions, Counter} 1621%% 1622%% The list of options is processed in multiple passes. When 1623%% processing an option all dependencies must already be resolved. 1624%% If there are unresolved dependencies the option will be 1625%% skipped and processed in a subsequent pass. 1626%% Counter is equal to the number of unprocessed options at 1627%% the beginning of a pass. Its value must monotonically decrease 1628%% after each successful pass. 1629%% If the value of the counter is unchanged at the end of a pass, 1630%% the processing stops due to faulty input data. 1631process_options({[], [], _}, OptionsMap, _Env) -> 1632 OptionsMap; 1633process_options({[], [_|_] = Skipped, Counter}, OptionsMap, Env) 1634 when length(Skipped) < Counter -> 1635 %% Continue handling options if current pass was successful 1636 process_options({Skipped, [], length(Skipped)}, OptionsMap, Env); 1637process_options({[], [_|_], _Counter}, _OptionsMap, _Env) -> 1638 throw({error, faulty_configuration}); 1639process_options({[{K0,V} = E|T], S, Counter}, OptionsMap0, Env) -> 1640 K = maybe_map_key_internal(K0), 1641 case check_dependencies(K, OptionsMap0, Env) of 1642 true -> 1643 OptionsMap = handle_option(K, V, OptionsMap0, Env), 1644 process_options({T, S, Counter}, OptionsMap, Env); 1645 false -> 1646 %% Skip option for next pass 1647 process_options({T, [E|S], Counter}, OptionsMap0, Env) 1648 end. 1649 1650handle_option(anti_replay = Option, unbound, OptionsMap, #{rules := Rules}) -> 1651 Value = validate_option(Option, default_value(Option, Rules)), 1652 OptionsMap#{Option => Value}; 1653handle_option(anti_replay = Option, Value0, 1654 #{session_tickets := SessionTickets, 1655 versions := Versions} = OptionsMap, #{rules := Rules}) -> 1656 assert_option_dependency(Option, versions, Versions, ['tlsv1.3']), 1657 assert_option_dependency(Option, session_tickets, [SessionTickets], [stateless]), 1658 case SessionTickets of 1659 stateless -> 1660 Value = validate_option(Option, Value0), 1661 OptionsMap#{Option => Value}; 1662 _ -> 1663 OptionsMap#{Option => default_value(Option, Rules)} 1664 end; 1665handle_option(beast_mitigation = Option, unbound, OptionsMap, #{rules := Rules}) -> 1666 Value = validate_option(Option, default_value(Option, Rules)), 1667 OptionsMap#{Option => Value}; 1668handle_option(beast_mitigation = Option, Value0, #{versions := Versions} = OptionsMap, _Env) -> 1669 assert_option_dependency(Option, versions, Versions, ['tlsv1']), 1670 Value = validate_option(Option, Value0), 1671 OptionsMap#{Option => Value}; 1672handle_option(cacertfile = Option, unbound, #{cacerts := CaCerts, 1673 verify := Verify, 1674 verify_fun := VerifyFun} = OptionsMap, _Env) 1675 when Verify =:= verify_none orelse 1676 Verify =:= 0 -> 1677 Value = validate_option(Option, ca_cert_default(verify_none, VerifyFun, CaCerts)), 1678 OptionsMap#{Option => Value}; 1679handle_option(cacertfile = Option, unbound, #{cacerts := CaCerts, 1680 verify := Verify, 1681 verify_fun := VerifyFun} = OptionsMap, _Env) 1682 when Verify =:= verify_peer orelse 1683 Verify =:= 1 orelse 1684 Verify =:= 2 -> 1685 Value = validate_option(Option, ca_cert_default(verify_peer, VerifyFun, CaCerts)), 1686 OptionsMap#{Option => Value}; 1687handle_option(cacertfile = Option, Value0, OptionsMap, _Env) -> 1688 Value = validate_option(Option, Value0), 1689 OptionsMap#{Option => Value}; 1690handle_option(ciphers = Option, unbound, #{versions := Versions} = OptionsMap, #{rules := Rules}) -> 1691 Value = handle_cipher_option(default_value(Option, Rules), Versions), 1692 OptionsMap#{Option => Value}; 1693handle_option(ciphers = Option, Value0, #{versions := Versions} = OptionsMap, _Env) -> 1694 Value = handle_cipher_option(Value0, Versions), 1695 OptionsMap#{Option => Value}; 1696handle_option(client_renegotiation = Option, unbound, OptionsMap, #{role := Role}) -> 1697 Value = default_option_role(server, true, Role), 1698 OptionsMap#{Option => Value}; 1699handle_option(client_renegotiation = Option, Value0, 1700 #{versions := Versions} = OptionsMap, #{role := Role}) -> 1701 assert_role(server_only, Role, Option, Value0), 1702 assert_option_dependency(Option, versions, Versions, 1703 ['tlsv1','tlsv1.1','tlsv1.2']), 1704 Value = validate_option(Option, Value0), 1705 OptionsMap#{Option => Value}; 1706handle_option(early_data = Option, unbound, OptionsMap, #{rules := Rules}) -> 1707 Value = validate_option(Option, default_value(Option, Rules)), 1708 OptionsMap#{Option => Value}; 1709handle_option(early_data = Option, Value0, #{session_tickets := SessionTickets, 1710 versions := Versions} = OptionsMap, 1711 #{role := server = Role}) -> 1712 assert_option_dependency(Option, versions, Versions, ['tlsv1.3']), 1713 assert_option_dependency(Option, session_tickets, [SessionTickets], 1714 [stateful, stateless]), 1715 Value = validate_option(Option, Value0, Role), 1716 OptionsMap#{Option => Value}; 1717handle_option(early_data = Option, Value0, #{session_tickets := SessionTickets, 1718 use_ticket := UseTicket, 1719 versions := Versions} = OptionsMap, 1720 #{role := client = Role}) -> 1721 assert_option_dependency(Option, versions, Versions, ['tlsv1.3']), 1722 assert_option_dependency(Option, session_tickets, [SessionTickets], 1723 [manual, auto]), 1724 case UseTicket of 1725 undefined when SessionTickets =/= auto -> 1726 throw({error, {options, dependency, {Option, use_ticket}}}); 1727 _ -> 1728 ok 1729 end, 1730 Value = validate_option(Option, Value0, Role), 1731 OptionsMap#{Option => Value}; 1732handle_option(eccs = Option, unbound, #{versions := [HighestVersion|_]} = OptionsMap, #{rules := _Rules}) -> 1733 Value = handle_eccs_option(eccs(), HighestVersion), 1734 OptionsMap#{Option => Value}; 1735handle_option(eccs = Option, Value0, #{versions := [HighestVersion|_]} = OptionsMap, _Env) -> 1736 Value = handle_eccs_option(Value0, HighestVersion), 1737 OptionsMap#{Option => Value}; 1738handle_option(fallback = Option, unbound, OptionsMap, #{role := Role}) -> 1739 Value = default_option_role(client, false, Role), 1740 OptionsMap#{Option => Value}; 1741handle_option(fallback = Option, Value0, OptionsMap, #{role := Role}) -> 1742 assert_role(client_only, Role, Option, Value0), 1743 Value = validate_option(Option, Value0), 1744 OptionsMap#{Option => Value}; 1745handle_option(cookie = Option, unbound, OptionsMap, #{role := Role}) -> 1746 Value = default_option_role(server, true, Role), 1747 OptionsMap#{Option => Value}; 1748handle_option(cookie = Option, Value0, #{versions := Versions} = OptionsMap, #{role := Role}) -> 1749 assert_option_dependency(Option, versions, Versions, ['tlsv1.3']), 1750 assert_role(server_only, Role, Option, Value0), 1751 Value = validate_option(Option, Value0), 1752 OptionsMap#{Option => Value}; 1753handle_option(honor_cipher_order = Option, unbound, OptionsMap, #{role := Role}) -> 1754 Value = default_option_role(server, false, Role), 1755 OptionsMap#{Option => Value}; 1756handle_option(honor_cipher_order = Option, Value0, OptionsMap, #{role := Role}) -> 1757 assert_role(server_only, Role, Option, Value0), 1758 Value = validate_option(Option, Value0), 1759 OptionsMap#{Option => Value}; 1760handle_option(honor_ecc_order = Option, unbound, OptionsMap, #{role := Role}) -> 1761 Value = default_option_role(server, false, Role), 1762 OptionsMap#{Option => Value}; 1763handle_option(honor_ecc_order = Option, Value0, OptionsMap, #{role := Role}) -> 1764 assert_role(server_only, Role, Option, Value0), 1765 Value = validate_option(Option, Value0), 1766 OptionsMap#{Option => Value}; 1767handle_option(keyfile = Option, unbound, #{certfile := CertFile} = OptionsMap, _Env) -> 1768 Value = validate_option(Option, CertFile), 1769 OptionsMap#{Option => Value}; 1770handle_option(key_update_at = Option, unbound, OptionsMap, #{rules := Rules}) -> 1771 Value = validate_option(Option, default_value(Option, Rules)), 1772 OptionsMap#{Option => Value}; 1773handle_option(key_update_at = Option, Value0, #{versions := Versions} = OptionsMap, _Env) -> 1774 assert_option_dependency(Option, versions, Versions, ['tlsv1.3']), 1775 Value = validate_option(Option, Value0), 1776 OptionsMap#{Option => Value}; 1777handle_option(next_protocols_advertised = Option, unbound, OptionsMap, 1778 #{rules := Rules}) -> 1779 Value = validate_option(Option, default_value(Option, Rules)), 1780 OptionsMap#{Option => Value}; 1781handle_option(next_protocols_advertised = Option, Value0, 1782 #{versions := Versions} = OptionsMap, _Env) -> 1783 assert_option_dependency(next_protocols_advertised, versions, Versions, 1784 ['tlsv1','tlsv1.1','tlsv1.2']), 1785 Value = validate_option(Option, Value0), 1786 OptionsMap#{Option => Value}; 1787handle_option(next_protocol_selector = Option, unbound, OptionsMap, #{rules := Rules}) -> 1788 Value = default_value(Option, Rules), 1789 OptionsMap#{Option => Value}; 1790handle_option(next_protocol_selector = Option, Value0, 1791 #{versions := Versions} = OptionsMap, _Env) -> 1792 assert_option_dependency(client_preferred_next_protocols, versions, Versions, 1793 ['tlsv1','tlsv1.1','tlsv1.2']), 1794 Value = make_next_protocol_selector( 1795 validate_option(client_preferred_next_protocols, Value0)), 1796 OptionsMap#{Option => Value}; 1797handle_option(padding_check = Option, unbound, OptionsMap, #{rules := Rules}) -> 1798 Value = validate_option(Option, default_value(Option, Rules)), 1799 OptionsMap#{Option => Value}; 1800handle_option(padding_check = Option, Value0, #{versions := Versions} = OptionsMap, _Env) -> 1801 assert_option_dependency(Option, versions, Versions, ['tlsv1']), 1802 Value = validate_option(Option, Value0), 1803 OptionsMap#{Option => Value}; 1804handle_option(psk_identity = Option, unbound, OptionsMap, #{rules := Rules}) -> 1805 Value = validate_option(Option, default_value(Option, Rules)), 1806 OptionsMap#{Option => Value}; 1807handle_option(psk_identity = Option, Value0, #{versions := Versions} = OptionsMap, _Env) -> 1808 assert_option_dependency(Option, versions, Versions, 1809 ['tlsv1','tlsv1.1','tlsv1.2']), 1810 Value = validate_option(Option, Value0), 1811 OptionsMap#{Option => Value}; 1812handle_option(secure_renegotiate = Option, unbound, OptionsMap, #{rules := Rules}) -> 1813 Value = validate_option(Option, default_value(Option, Rules)), 1814 OptionsMap#{Option => Value}; 1815handle_option(secure_renegotiate= Option, Value0, 1816 #{versions := Versions} = OptionsMap, _Env) -> 1817 assert_option_dependency(secure_renegotiate, versions, Versions, 1818 ['tlsv1','tlsv1.1','tlsv1.2']), 1819 Value = validate_option(Option, Value0), 1820 OptionsMap#{Option => Value}; 1821handle_option(reuse_session = Option, unbound, OptionsMap, #{role := Role}) -> 1822 Value = 1823 case Role of 1824 client -> 1825 undefined; 1826 server -> 1827 fun(_, _, _, _) -> true end 1828 end, 1829 OptionsMap#{Option => Value}; 1830handle_option(reuse_session = Option, Value0, 1831 #{versions := Versions} = OptionsMap, _Env) -> 1832 assert_option_dependency(reuse_session, versions, Versions, 1833 ['tlsv1','tlsv1.1','tlsv1.2']), 1834 Value = validate_option(Option, Value0), 1835 OptionsMap#{Option => Value}; 1836%% TODO: validate based on role 1837handle_option(reuse_sessions = Option, unbound, OptionsMap, #{rules := Rules}) -> 1838 Value = validate_option(Option, default_value(Option, Rules)), 1839 OptionsMap#{Option => Value}; 1840handle_option(reuse_sessions = Option, Value0, 1841 #{versions := Versions} = OptionsMap, _Env) -> 1842 assert_option_dependency(reuse_sessions, versions, Versions, 1843 ['tlsv1','tlsv1.1','tlsv1.2']), 1844 Value = validate_option(Option, Value0), 1845 OptionsMap#{Option => Value}; 1846handle_option(server_name_indication = Option, unbound, OptionsMap, #{host := Host, 1847 role := Role}) -> 1848 Value = default_option_role(client, server_name_indication_default(Host), Role), 1849 OptionsMap#{Option => Value}; 1850handle_option(server_name_indication = Option, Value0, OptionsMap, _Env) -> 1851 Value = validate_option(Option, Value0), 1852 OptionsMap#{Option => Value}; 1853handle_option(session_tickets = Option, unbound, OptionsMap, #{role := Role, 1854 rules := Rules}) -> 1855 Value = validate_option(Option, default_value(Option, Rules), Role), 1856 OptionsMap#{Option => Value}; 1857handle_option(session_tickets = Option, Value0, #{versions := Versions} = OptionsMap, #{role := Role}) -> 1858 assert_option_dependency(Option, versions, Versions, ['tlsv1.3']), 1859 Value = validate_option(Option, Value0, Role), 1860 OptionsMap#{Option => Value}; 1861handle_option(signature_algs = Option, unbound, #{versions := [HighestVersion|_]} = OptionsMap, #{role := Role}) -> 1862 Value = 1863 handle_hashsigns_option( 1864 default_option_role_sign_algs( 1865 server, 1866 tls_v1:default_signature_algs(HighestVersion), 1867 Role, 1868 HighestVersion), 1869 tls_version(HighestVersion)), 1870 OptionsMap#{Option => Value}; 1871handle_option(signature_algs = Option, Value0, #{versions := [HighestVersion|_]} = OptionsMap, _Env) -> 1872 Value = handle_hashsigns_option(Value0, tls_version(HighestVersion)), 1873 OptionsMap#{Option => Value}; 1874handle_option(signature_algs_cert = Option, unbound, #{versions := [HighestVersion|_]} = OptionsMap, _Env) -> 1875 %% Do not send by default 1876 Value = handle_signature_algorithms_option(undefined, tls_version(HighestVersion)), 1877 OptionsMap#{Option => Value}; 1878handle_option(signature_algs_cert = Option, Value0, #{versions := [HighestVersion|_]} = OptionsMap, _Env) -> 1879 Value = handle_signature_algorithms_option(Value0, tls_version(HighestVersion)), 1880 OptionsMap#{Option => Value}; 1881handle_option(sni_fun = Option, unbound, OptionsMap, #{rules := Rules}) -> 1882 Value = default_value(Option, Rules), 1883 OptionsMap#{Option => Value}; 1884handle_option(sni_fun = Option, Value0, OptionsMap, _Env) -> 1885 validate_option(Option, Value0), 1886 OptHosts = maps:get(sni_hosts, OptionsMap, undefined), 1887 Value = 1888 case {Value0, OptHosts} of 1889 {undefined, _} -> 1890 Value0; 1891 {_, []} -> 1892 Value0; 1893 _ -> 1894 throw({error, {conflict_options, [sni_fun, sni_hosts]}}) 1895 end, 1896 OptionsMap#{Option => Value}; 1897handle_option(srp_identity = Option, unbound, OptionsMap, #{rules := Rules}) -> 1898 Value = validate_option(Option, default_value(Option, Rules)), 1899 OptionsMap#{Option => Value}; 1900handle_option(srp_identity = Option, Value0, 1901 #{versions := Versions} = OptionsMap, _Env) -> 1902 assert_option_dependency(srp_identity, versions, Versions, 1903 ['tlsv1','tlsv1.1','tlsv1.2']), 1904 Value = validate_option(Option, Value0), 1905 OptionsMap#{Option => Value}; 1906handle_option(supported_groups = Option, unbound, #{versions := [HighestVersion|_]} = OptionsMap, #{rules := _Rules}) -> 1907 Value = handle_supported_groups_option(groups(default), HighestVersion), 1908 OptionsMap#{Option => Value}; 1909handle_option(supported_groups = Option, Value0, 1910 #{versions := [HighestVersion|_] = Versions} = OptionsMap, _Env) -> 1911 assert_option_dependency(Option, versions, Versions, ['tlsv1.3']), 1912 Value = handle_supported_groups_option(Value0, HighestVersion), 1913 OptionsMap#{Option => Value}; 1914handle_option(use_ticket = Option, unbound, OptionsMap, #{rules := Rules}) -> 1915 Value = validate_option(Option, default_value(Option, Rules)), 1916 OptionsMap#{Option => Value}; 1917handle_option(use_ticket = Option, Value0, 1918 #{versions := Versions} = OptionsMap, _Env) -> 1919 assert_option_dependency(Option, versions, Versions, ['tlsv1.3']), 1920 Value = validate_option(Option, Value0), 1921 OptionsMap#{Option => Value}; 1922handle_option(user_lookup_fun = Option, unbound, OptionsMap, #{rules := Rules}) -> 1923 Value = validate_option(Option, default_value(Option, Rules)), 1924 OptionsMap#{Option => Value}; 1925handle_option(user_lookup_fun = Option, Value0, 1926 #{versions := Versions} = OptionsMap, _Env) -> 1927 assert_option_dependency(Option, versions, Versions, ['tlsv1','tlsv1.1','tlsv1.2']), 1928 Value = validate_option(Option, Value0), 1929 OptionsMap#{Option => Value}; 1930handle_option(verify = Option, unbound, OptionsMap, #{rules := Rules}) -> 1931 handle_verify_option(default_value(Option, Rules), OptionsMap); 1932handle_option(verify = _Option, Value, OptionsMap, _Env) -> 1933 handle_verify_option(Value, OptionsMap); 1934handle_option(verify_fun = Option, unbound, #{verify := Verify} = OptionsMap, #{rules := Rules}) 1935 when Verify =:= verify_none -> 1936 OptionsMap#{Option => default_value(Option, Rules)}; 1937handle_option(verify_fun = Option, unbound, #{verify := Verify} = OptionsMap, _Env) 1938 when Verify =:= verify_peer -> 1939 OptionsMap#{Option => undefined}; 1940handle_option(verify_fun = Option, Value0, OptionsMap, _Env) -> 1941 Value = validate_option(Option, Value0), 1942 OptionsMap#{Option => Value}; 1943handle_option(versions = Option, unbound, #{protocol := Protocol} = OptionsMap, _Env) -> 1944 RecordCb = record_cb(Protocol), 1945 Vsns0 = RecordCb:supported_protocol_versions(), 1946 Value = lists:sort(fun RecordCb:is_higher/2, Vsns0), 1947 OptionsMap#{Option => Value}; 1948handle_option(versions = Option, Vsns0, #{protocol := Protocol} = OptionsMap, _Env) -> 1949 validate_option(versions, Vsns0), 1950 RecordCb = record_cb(Protocol), 1951 Vsns1 = [RecordCb:protocol_version(Vsn) || Vsn <- Vsns0], 1952 Value = lists:sort(fun RecordCb:is_higher/2, Vsns1), 1953 OptionsMap#{Option => Value}; 1954%% Special options 1955handle_option(cb_info = Option, unbound, #{protocol := Protocol} = OptionsMap, _Env) -> 1956 Default = default_cb_info(Protocol), 1957 validate_option(Option, Default), 1958 Value = handle_cb_info(Default), 1959 OptionsMap#{Option => Value}; 1960handle_option(cb_info = Option, Value0, OptionsMap, _Env) -> 1961 validate_option(Option, Value0), 1962 Value = handle_cb_info(Value0), 1963 OptionsMap#{Option => Value}; 1964%% Generic case 1965handle_option(Option, unbound, OptionsMap, #{rules := Rules}) -> 1966 Value = validate_option(Option, default_value(Option, Rules)), 1967 OptionsMap#{Option => Value}; 1968handle_option(Option, Value0, OptionsMap, _Env) -> 1969 Value = validate_option(Option, Value0), 1970 OptionsMap#{Option => Value}. 1971 1972handle_option_cb_info(Options, Protocol) -> 1973 Value = proplists:get_value(cb_info, Options, default_cb_info(Protocol)), 1974 #{cb_info := CbInfo} = handle_option(cb_info, Value, #{protocol => Protocol}, #{}), 1975 CbInfo. 1976 1977 1978maybe_map_key_internal(client_preferred_next_protocols) -> 1979 next_protocol_selector; 1980maybe_map_key_internal(K) -> 1981 K. 1982 1983maybe_map_key_external(next_protocol_selector) -> 1984 client_preferred_next_protocols; 1985maybe_map_key_external(K) -> 1986 K. 1987 1988check_dependencies(K, OptionsMap, Env) -> 1989 Rules = maps:get(rules, Env), 1990 Deps = get_dependencies(K, Rules), 1991 case Deps of 1992 [] -> 1993 true; 1994 L -> 1995 option_already_defined(K,OptionsMap) orelse 1996 dependecies_already_defined(L, OptionsMap) 1997 end. 1998 1999 2000%% Handle options that are not present in the map 2001get_dependencies(K, _) when K =:= cb_info orelse K =:= log_alert-> 2002 []; 2003get_dependencies(K, Rules) -> 2004 {_, Deps} = maps:get(K, Rules), 2005 Deps. 2006 2007 2008option_already_defined(K, Map) -> 2009 maps:get(K, Map, unbound) =/= unbound. 2010 2011 2012dependecies_already_defined(L, OptionsMap) -> 2013 Fun = fun (E) -> option_already_defined(E, OptionsMap) end, 2014 lists:all(Fun, L). 2015 2016 2017expand_options(Opts0, Rules) -> 2018 Opts1 = proplists:expand([{binary, [{mode, binary}]}, 2019 {list, [{mode, list}]}], Opts0), 2020 Opts2 = handle_option_format(Opts1, []), 2021 2022 %% Remove depricated ssl_imp option 2023 Opts = proplists:delete(ssl_imp, Opts2), 2024 AllOpts = maps:keys(Rules), 2025 SockOpts = lists:foldl(fun(Key, PropList) -> proplists:delete(Key, PropList) end, 2026 Opts, 2027 AllOpts ++ 2028 [ssl_imp, %% TODO: remove ssl_imp 2029 cb_info, 2030 client_preferred_next_protocols, %% next_protocol_selector 2031 log_alert]), %% obsoleted by log_level 2032 2033 SslOpts0 = Opts -- SockOpts, 2034 SslOpts = {SslOpts0, [], length(SslOpts0)}, 2035 {SslOpts, SockOpts}. 2036 2037 2038add_missing_options({L0, S, _C}, Rules) -> 2039 Fun = fun(K0, Acc) -> 2040 K = maybe_map_key_external(K0), 2041 case proplists:is_defined(K, Acc) of 2042 true -> 2043 Acc; 2044 false -> 2045 Default = unbound, 2046 [{K, Default}|Acc] 2047 end 2048 end, 2049 AllOpts = maps:keys(Rules), 2050 L = lists:foldl(Fun, L0, AllOpts), 2051 {L, S, length(L)}. 2052 2053default_value(Key, Rules) -> 2054 {Default, _} = maps:get(Key, Rules, {undefined, []}), 2055 Default. 2056 2057 2058assert_role(client_only, client, _, _) -> 2059 ok; 2060assert_role(server_only, server, _, _) -> 2061 ok; 2062assert_role(client_only, _, _, undefined) -> 2063 ok; 2064assert_role(server_only, _, _, undefined) -> 2065 ok; 2066assert_role(Type, _, Key, _) -> 2067 throw({error, {option, Type, Key}}). 2068 2069assert_option_dependency(Option, OptionDep, Values0, AllowedValues) -> 2070 case is_dtls_configured(Values0) of 2071 true -> 2072 %% TODO: Check option dependency for DTLS 2073 ok; 2074 false -> 2075 %% special handling for version 2076 Values = 2077 case OptionDep of 2078 versions -> 2079 lists:map(fun tls_record:protocol_version/1, Values0); 2080 _ -> 2081 Values0 2082 end, 2083 Set1 = sets:from_list(Values), 2084 Set2 = sets:from_list(AllowedValues), 2085 case sets:size(sets:intersection(Set1, Set2)) > 0 of 2086 true -> 2087 ok; 2088 false -> 2089 throw({error, {options, dependency, 2090 {Option, {OptionDep, AllowedValues}}}}) 2091 end 2092 end. 2093 2094is_dtls_configured(Versions) -> 2095 Fun = fun (Version) when Version =:= {254, 253} orelse 2096 Version =:= {254, 255} -> 2097 true; 2098 (_) -> 2099 false 2100 end, 2101 lists:any(Fun, Versions). 2102 2103validate_option(Option, Value) -> 2104 validate_option(Option, Value, undefined). 2105%% 2106validate_option(Opt, Value, _) 2107 when Opt =:= alpn_advertised_protocols orelse 2108 Opt =:= alpn_preferred_protocols, 2109 is_list(Value) -> 2110 validate_binary_list(Opt, Value), 2111 Value; 2112validate_option(Opt, Value, _) 2113 when Opt =:= alpn_advertised_protocols orelse 2114 Opt =:= alpn_preferred_protocols, 2115 Value =:= undefined -> 2116 undefined; 2117validate_option(anti_replay, '10k', _) -> 2118 %% n = 10000 2119 %% p = 0.030003564 (1 in 33) 2120 %% m = 72985 (8.91KiB) 2121 %% k = 5 2122 {10, 5, 72985}; 2123validate_option(anti_replay, '100k', _) -> 2124 %% n = 100000 2125 %% p = 0.03000428 (1 in 33) 2126 %% m = 729845 (89.09KiB) 2127 %% k = 5 2128 {10, 5, 729845}; 2129validate_option(anti_replay, Value, _) 2130 when (is_tuple(Value) andalso 2131 tuple_size(Value) =:= 3) -> 2132 Value; 2133validate_option(beast_mitigation, Value, _) 2134 when Value == one_n_minus_one orelse 2135 Value == zero_n orelse 2136 Value == disabled -> 2137 Value; 2138%% certfile must be present in some cases otherwhise it can be set 2139%% to the empty string. 2140validate_option(cacertfile, undefined, _) -> 2141 <<>>; 2142validate_option(cacertfile, Value, _) 2143 when is_binary(Value) -> 2144 Value; 2145validate_option(cacertfile, Value, _) 2146 when is_list(Value), Value =/= ""-> 2147 binary_filename(Value); 2148validate_option(cacerts, Value, _) 2149 when Value == undefined; 2150 is_list(Value) -> 2151 Value; 2152validate_option(cb_info, {V1, V2, V3, V4} = Value, _) 2153 when is_atom(V1), 2154 is_atom(V2), 2155 is_atom(V3), 2156 is_atom(V4) -> 2157 Value; 2158validate_option(cb_info, {V1, V2, V3, V4, V5} = Value, _) 2159 when is_atom(V1), 2160 is_atom(V2), 2161 is_atom(V3), 2162 is_atom(V4), 2163 is_atom(V5) -> 2164 Value; 2165validate_option(cert, Value, _) when Value == undefined; 2166 is_list(Value)-> 2167 Value; 2168validate_option(cert, Value, _) when Value == undefined; 2169 is_binary(Value)-> 2170 [Value]; 2171validate_option(certfile, undefined = Value, _) -> 2172 Value; 2173validate_option(certfile, Value, _) 2174 when is_binary(Value) -> 2175 Value; 2176validate_option(certfile, Value, _) 2177 when is_list(Value) -> 2178 binary_filename(Value); 2179validate_option(client_preferred_next_protocols, {Precedence, PreferredProtocols}, _) 2180 when is_list(PreferredProtocols) -> 2181 validate_binary_list(client_preferred_next_protocols, PreferredProtocols), 2182 validate_npn_ordering(Precedence), 2183 {Precedence, PreferredProtocols, ?NO_PROTOCOL}; 2184validate_option(client_preferred_next_protocols, 2185 {Precedence, PreferredProtocols, Default} = Value, _) 2186 when is_list(PreferredProtocols), is_binary(Default), 2187 byte_size(Default) > 0, byte_size(Default) < 256 -> 2188 validate_binary_list(client_preferred_next_protocols, PreferredProtocols), 2189 validate_npn_ordering(Precedence), 2190 Value; 2191validate_option(client_preferred_next_protocols, undefined, _) -> 2192 undefined; 2193validate_option(client_renegotiation, Value, _) 2194 when is_boolean(Value) -> 2195 Value; 2196validate_option(cookie, Value, _) 2197 when is_boolean(Value) -> 2198 Value; 2199validate_option(crl_cache, {Cb, {_Handle, Options}} = Value, _) 2200 when is_atom(Cb) and is_list(Options) -> 2201 Value; 2202validate_option(crl_check, Value, _) 2203 when is_boolean(Value) -> 2204 Value; 2205validate_option(crl_check, Value, _) 2206 when (Value == best_effort) or 2207 (Value == peer) -> 2208 Value; 2209validate_option(customize_hostname_check, Value, _) 2210 when is_list(Value) -> 2211 Value; 2212validate_option(depth, Value, _) 2213 when is_integer(Value), 2214 Value >= 0, Value =< 255-> 2215 Value; 2216validate_option(dh, Value, _) 2217 when Value == undefined; 2218 is_binary(Value) -> 2219 Value; 2220validate_option(dhfile, undefined = Value, _) -> 2221 Value; 2222validate_option(dhfile, Value, _) 2223 when is_binary(Value) -> 2224 Value; 2225validate_option(dhfile, Value, _) 2226 when is_list(Value), Value =/= "" -> 2227 binary_filename(Value); 2228validate_option(early_data, Value, server) 2229 when Value =:= disabled orelse 2230 Value =:= enabled -> 2231 Value; 2232validate_option(early_data = Option, Value, server) -> 2233 throw({error, 2234 {options, role, {Option, {Value, {server, [disabled, enabled]}}}}}); 2235validate_option(early_data, Value, client) 2236 when is_binary(Value) -> 2237 Value; 2238validate_option(early_data = Option, Value, client) -> 2239 throw({error, 2240 {options, type, {Option, {Value, not_binary}}}}); 2241validate_option(erl_dist, Value, _) 2242 when is_boolean(Value) -> 2243 Value; 2244validate_option(fail_if_no_peer_cert, Value, _) 2245 when is_boolean(Value) -> 2246 Value; 2247validate_option(fallback, Value, _) 2248 when is_boolean(Value) -> 2249 Value; 2250validate_option(handshake, hello = Value, _) -> 2251 Value; 2252validate_option(handshake, full = Value, _) -> 2253 Value; 2254validate_option(hibernate_after, undefined, _) -> %% Backwards compatibility 2255 infinity; 2256validate_option(hibernate_after, infinity, _) -> 2257 infinity; 2258validate_option(hibernate_after, Value, _) 2259 when is_integer(Value), Value >= 0 -> 2260 Value; 2261validate_option(honor_cipher_order, Value, _) 2262 when is_boolean(Value) -> 2263 Value; 2264validate_option(honor_ecc_order, Value, _) 2265 when is_boolean(Value) -> 2266 Value; 2267validate_option(keep_secrets, Value, _) when is_boolean(Value) -> 2268 Value; 2269validate_option(key, undefined, _) -> 2270 undefined; 2271validate_option(key, {KeyType, Value}, _) 2272 when is_binary(Value), 2273 KeyType == rsa; %% Backwards compatibility 2274 KeyType == dsa; %% Backwards compatibility 2275 KeyType == 'RSAPrivateKey'; 2276 KeyType == 'DSAPrivateKey'; 2277 KeyType == 'ECPrivateKey'; 2278 KeyType == 'PrivateKeyInfo' -> 2279 {KeyType, Value}; 2280validate_option(key, #{algorithm := _} = Value, _) -> 2281 Value; 2282validate_option(keyfile, undefined, _) -> 2283 <<>>; 2284validate_option(keyfile, Value, _) 2285 when is_binary(Value) -> 2286 Value; 2287validate_option(keyfile, Value, _) 2288 when is_list(Value), Value =/= "" -> 2289 binary_filename(Value); 2290validate_option(key_update_at, Value, _) 2291 when is_integer(Value) andalso 2292 Value > 0 -> 2293 Value; 2294validate_option(log_level, Value, _) when 2295 is_atom(Value) andalso 2296 (Value =:= none orelse 2297 Value =:= all orelse 2298 Value =:= emergency orelse 2299 Value =:= alert orelse 2300 Value =:= critical orelse 2301 Value =:= error orelse 2302 Value =:= warning orelse 2303 Value =:= notice orelse 2304 Value =:= info orelse 2305 Value =:= debug) -> 2306 Value; 2307%% RFC 6066, Section 4 2308validate_option(max_fragment_length, I, _) 2309 when I == ?MAX_FRAGMENT_LENGTH_BYTES_1; 2310 I == ?MAX_FRAGMENT_LENGTH_BYTES_2; 2311 I == ?MAX_FRAGMENT_LENGTH_BYTES_3; 2312 I == ?MAX_FRAGMENT_LENGTH_BYTES_4 -> 2313 I; 2314validate_option(max_fragment_length, undefined, _) -> 2315 undefined; 2316validate_option(max_handshake_size, Value, _) 2317 when is_integer(Value) andalso 2318 Value =< ?MAX_UNIT24 -> 2319 Value; 2320validate_option(middlebox_comp_mode, Value, _) 2321 when is_boolean(Value) -> 2322 Value; 2323validate_option(next_protocols_advertised, Value, _) when is_list(Value) -> 2324 validate_binary_list(next_protocols_advertised, Value), 2325 Value; 2326validate_option(next_protocols_advertised, undefined, _) -> 2327 undefined; 2328validate_option(ocsp_nonce, Value, _) 2329 when Value =:= true orelse 2330 Value =:= false -> 2331 Value; 2332%% The OCSP responders' certificates can be given as a suggestion and 2333%% will be used to verify the OCSP response. 2334validate_option(ocsp_responder_certs, Value, _) 2335 when is_list(Value) -> 2336 [public_key:pkix_decode_cert(CertDer, plain) || CertDer <- Value, 2337 is_binary(CertDer)]; 2338validate_option(ocsp_stapling, Value, _) 2339 when Value =:= true orelse 2340 Value =:= false -> 2341 Value; 2342validate_option(padding_check, Value, _) 2343 when is_boolean(Value) -> 2344 Value; 2345validate_option(partial_chain, Value, _) 2346 when is_function(Value) -> 2347 Value; 2348validate_option(password, Value, _) 2349 when is_list(Value) -> 2350 Value; 2351validate_option(protocol, Value = tls, _) -> 2352 Value; 2353validate_option(protocol, Value = dtls, _) -> 2354 Value; 2355validate_option(psk_identity, undefined, _) -> 2356 undefined; 2357validate_option(psk_identity, Identity, _) 2358 when is_list(Identity), Identity =/= "", length(Identity) =< 65535 -> 2359 binary_filename(Identity); 2360validate_option(renegotiate_at, Value, _) when is_integer(Value) -> 2361 erlang:min(Value, ?DEFAULT_RENEGOTIATE_AT); 2362validate_option(reuse_session, undefined, _) -> 2363 undefined; 2364validate_option(reuse_session, Value, _) 2365 when is_function(Value) -> 2366 Value; 2367validate_option(reuse_session, Value, _) 2368 when is_binary(Value) -> 2369 Value; 2370validate_option(reuse_session, {Id, Data} = Value, _) 2371 when is_binary(Id) andalso 2372 is_binary(Data) -> 2373 Value; 2374validate_option(reuse_sessions, Value, _) 2375 when is_boolean(Value) -> 2376 Value; 2377validate_option(reuse_sessions, save = Value, _) -> 2378 Value; 2379validate_option(secure_renegotiate, Value, _) 2380 when is_boolean(Value) -> 2381 Value; 2382validate_option(server_name_indication, Value, _) 2383 when is_list(Value) -> 2384 %% RFC 6066, Section 3: Currently, the only server names supported are 2385 %% DNS hostnames 2386 %% case inet_parse:domain(Value) of 2387 %% false -> 2388 %% throw({error, {options, {{Opt, Value}}}}); 2389 %% true -> 2390 %% Value 2391 %% end; 2392 %% 2393 %% But the definition seems very diffuse, so let all strings through 2394 %% and leave it up to public_key to decide... 2395 Value; 2396validate_option(server_name_indication, undefined, _) -> 2397 undefined; 2398validate_option(server_name_indication, disable, _) -> 2399 disable; 2400validate_option(session_tickets, Value, server) 2401 when Value =:= disabled orelse 2402 Value =:= stateful orelse 2403 Value =:= stateless -> 2404 Value; 2405validate_option(session_tickets, Value, server) -> 2406 throw({error, 2407 {options, role, 2408 {session_tickets, 2409 {Value, {server, [disabled, stateful, stateless]}}}}}); 2410validate_option(session_tickets, Value, client) 2411 when Value =:= disabled orelse 2412 Value =:= manual orelse 2413 Value =:= auto -> 2414 Value; 2415validate_option(session_tickets, Value, client) -> 2416 throw({error, 2417 {options, role, 2418 {session_tickets, 2419 {Value, {client, [disabled, manual, auto]}}}}}); 2420validate_option(sni_fun, undefined, _) -> 2421 undefined; 2422validate_option(sni_fun, Fun, _) 2423 when is_function(Fun) -> 2424 Fun; 2425validate_option(sni_hosts, [], _) -> 2426 []; 2427validate_option(sni_hosts, [{Hostname, SSLOptions} | Tail], _) 2428 when is_list(Hostname) -> 2429 RecursiveSNIOptions = proplists:get_value(sni_hosts, SSLOptions, undefined), 2430 case RecursiveSNIOptions of 2431 undefined -> 2432 [{Hostname, validate_options(SSLOptions)} | 2433 validate_option(sni_hosts, Tail)]; 2434 _ -> 2435 throw({error, {options, {sni_hosts, RecursiveSNIOptions}}}) 2436 end; 2437validate_option(srp_identity, undefined, _) -> 2438 undefined; 2439validate_option(srp_identity, {Username, Password}, _) 2440 when is_list(Username), 2441 is_list(Password), Username =/= "", 2442 length(Username) =< 255 -> 2443 {unicode:characters_to_binary(Username), 2444 unicode:characters_to_binary(Password)}; 2445validate_option(user_lookup_fun, undefined, _) -> 2446 undefined; 2447validate_option(user_lookup_fun, {Fun, _} = Value, _) 2448 when is_function(Fun, 3) -> 2449 Value; 2450validate_option(use_ticket, Value, _) 2451 when is_list(Value) -> 2452 Value; 2453validate_option(verify, Value, _) 2454 when Value == verify_none; Value == verify_peer -> 2455 Value; 2456validate_option(verify_fun, undefined, _) -> 2457 undefined; 2458%% Backwards compatibility 2459validate_option(verify_fun, Fun, _) when is_function(Fun) -> 2460 {fun(_,{bad_cert, _} = Reason, OldFun) -> 2461 case OldFun([Reason]) of 2462 true -> 2463 {valid, OldFun}; 2464 false -> 2465 {fail, Reason} 2466 end; 2467 (_,{extension, _}, UserState) -> 2468 {unknown, UserState}; 2469 (_, valid, UserState) -> 2470 {valid, UserState}; 2471 (_, valid_peer, UserState) -> 2472 {valid, UserState} 2473 end, Fun}; 2474validate_option(verify_fun, {Fun, _} = Value, _) when is_function(Fun) -> 2475 Value; 2476validate_option(versions, Versions, _) -> 2477 validate_versions(Versions, Versions); 2478validate_option(Opt, undefined = Value, _) -> 2479 AllOpts = maps:keys(?RULES), 2480 case lists:member(Opt, AllOpts) of 2481 true -> 2482 Value; 2483 false -> 2484 throw({error, {options, {Opt, Value}}}) 2485 end; 2486validate_option(Opt, Value, _) -> 2487 throw({error, {options, {Opt, Value}}}). 2488 2489handle_cb_info({V1, V2, V3, V4}) -> 2490 {V1,V2,V3,V4, list_to_atom(atom_to_list(V2) ++ "_passive")}; 2491handle_cb_info(CbInfo) -> 2492 CbInfo. 2493 2494handle_hashsigns_option(Value, Version) when is_list(Value) 2495 andalso Version >= {3, 4} -> 2496 case tls_v1:signature_schemes(Version, Value) of 2497 [] -> 2498 throw({error, {options, 2499 no_supported_signature_schemes, 2500 {signature_algs, Value}}}); 2501 _ -> 2502 Value 2503 end; 2504handle_hashsigns_option(Value, Version) when is_list(Value) 2505 andalso Version =:= {3, 3} -> 2506 case tls_v1:signature_algs(Version, Value) of 2507 [] -> 2508 throw({error, {options, no_supported_algorithms, {signature_algs, Value}}}); 2509 _ -> 2510 Value 2511 end; 2512handle_hashsigns_option(_, Version) when Version =:= {3, 3} -> 2513 handle_hashsigns_option(tls_v1:default_signature_algs(Version), Version); 2514handle_hashsigns_option(_, _Version) -> 2515 undefined. 2516 2517handle_signature_algorithms_option(Value, Version) when is_list(Value) 2518 andalso Version >= {3, 4} -> 2519 case tls_v1:signature_schemes(Version, Value) of 2520 [] -> 2521 throw({error, {options, 2522 no_supported_signature_schemes, 2523 {signature_algs_cert, Value}}}); 2524 _ -> 2525 Value 2526 end; 2527handle_signature_algorithms_option(_, _Version) -> 2528 undefined. 2529 2530validate_options([]) -> 2531 []; 2532validate_options([{Opt, Value} | Tail]) -> 2533 [{Opt, validate_option(Opt, Value)} | validate_options(Tail)]. 2534 2535validate_npn_ordering(client) -> 2536 ok; 2537validate_npn_ordering(server) -> 2538 ok; 2539validate_npn_ordering(Value) -> 2540 throw({error, {options, {client_preferred_next_protocols, {invalid_precedence, Value}}}}). 2541 2542validate_binary_list(Opt, List) -> 2543 lists:foreach( 2544 fun(Bin) when is_binary(Bin), 2545 byte_size(Bin) > 0, 2546 byte_size(Bin) < 256 -> 2547 ok; 2548 (Bin) -> 2549 throw({error, {options, {Opt, {invalid_protocol, Bin}}}}) 2550 end, List). 2551validate_versions([], Versions) -> 2552 Versions; 2553validate_versions([Version | Rest], Versions) when Version == 'tlsv1.3'; 2554 Version == 'tlsv1.2'; 2555 Version == 'tlsv1.1'; 2556 Version == tlsv1 -> 2557 case tls_record:sufficient_crypto_support(Version) of 2558 true -> 2559 tls_validate_versions(Rest, Versions); 2560 false -> 2561 throw({error, {options, {insufficient_crypto_support, {Version, {versions, Versions}}}}}) 2562 end; 2563validate_versions([Version | Rest], Versions) when Version == 'dtlsv1'; 2564 Version == 'dtlsv1.2'-> 2565 DTLSVer = dtls_record:protocol_version(Version), 2566 case tls_record:sufficient_crypto_support(dtls_v1:corresponding_tls_version(DTLSVer)) of 2567 true -> 2568 dtls_validate_versions(Rest, Versions); 2569 false -> 2570 throw({error, {options, {insufficient_crypto_support, {Version, {versions, Versions}}}}}) 2571 end; 2572validate_versions([Version| _], Versions) -> 2573 throw({error, {options, {Version, {versions, Versions}}}}). 2574 2575tls_validate_versions([], Versions) -> 2576 tls_validate_version_gap(Versions); 2577tls_validate_versions([Version | Rest], Versions) when Version == 'tlsv1.3'; 2578 Version == 'tlsv1.2'; 2579 Version == 'tlsv1.1'; 2580 Version == tlsv1 -> 2581 tls_validate_versions(Rest, Versions); 2582tls_validate_versions([Version| _], Versions) -> 2583 throw({error, {options, {Version, {versions, Versions}}}}). 2584 2585%% Do not allow configuration of TLS 1.3 with a gap where TLS 1.2 is not supported 2586%% as that configuration can trigger the built in version downgrade protection 2587%% mechanism and the handshake can fail with an Illegal Parameter alert. 2588tls_validate_version_gap(Versions) -> 2589 case lists:member('tlsv1.3', Versions) of 2590 true when length(Versions) >= 2 -> 2591 case lists:member('tlsv1.2', Versions) of 2592 true -> 2593 Versions; 2594 false -> 2595 throw({error, {options, missing_version, {'tlsv1.2', {versions, Versions}}}}) 2596 end; 2597 _ -> 2598 Versions 2599 end. 2600dtls_validate_versions([], Versions) -> 2601 Versions; 2602dtls_validate_versions([Version | Rest], Versions) when Version == 'dtlsv1'; 2603 Version == 'dtlsv1.2'-> 2604 dtls_validate_versions(Rest, Versions); 2605dtls_validate_versions([Ver| _], Versions) -> 2606 throw({error, {options, {Ver, {versions, Versions}}}}). 2607 2608%% The option cacerts overrides cacertsfile 2609ca_cert_default(_,_, [_|_]) -> 2610 undefined; 2611ca_cert_default(verify_none, _, _) -> 2612 undefined; 2613ca_cert_default(verify_peer, {Fun,_}, _) when is_function(Fun) -> 2614 undefined; 2615%% Server that wants to verify_peer and has no verify_fun must have 2616%% some trusted certs. 2617ca_cert_default(verify_peer, undefined, _) -> 2618 "". 2619emulated_options(undefined, undefined, Protocol, Opts) -> 2620 case Protocol of 2621 tls -> 2622 tls_socket:emulated_options(Opts); 2623 dtls -> 2624 dtls_socket:emulated_options(Opts) 2625 end; 2626emulated_options(Transport, Socket, Protocol, Opts) -> 2627 EmulatedOptions = tls_socket:emulated_options(), 2628 {ok, Original} = tls_socket:getopts(Transport, Socket, EmulatedOptions), 2629 {Inet, Emulated0} = emulated_options(undefined, undefined, Protocol, Opts), 2630 {Inet, lists:ukeymerge(1, Emulated0, Original)}. 2631 2632handle_cipher_option(Value, Versions) when is_list(Value) -> 2633 try binary_cipher_suites(Versions, Value) of 2634 Suites -> 2635 Suites 2636 catch 2637 exit:_ -> 2638 throw({error, {options, {ciphers, Value}}}); 2639 error:_-> 2640 throw({error, {options, {ciphers, Value}}}) 2641 end. 2642 2643binary_cipher_suites([{3,4} = Version], []) -> 2644 %% Defaults to all supported suites that does 2645 %% not require explicit configuration TLS-1.3 2646 %% only mode. 2647 default_binary_suites(exclusive, Version); 2648binary_cipher_suites([Version| _], []) -> 2649 %% Defaults to all supported suites that does 2650 %% not require explicit configuration 2651 default_binary_suites(default, Version); 2652binary_cipher_suites(Versions, [Map|_] = Ciphers0) when is_map(Map) -> 2653 Ciphers = [ssl_cipher_format:suite_map_to_bin(C) || C <- Ciphers0], 2654 binary_cipher_suites(Versions, Ciphers); 2655binary_cipher_suites(Versions, [Tuple|_] = Ciphers0) when is_tuple(Tuple) -> 2656 Ciphers = [ssl_cipher_format:suite_map_to_bin(tuple_to_map(C)) || C <- Ciphers0], 2657 binary_cipher_suites(Versions, Ciphers); 2658binary_cipher_suites([Version |_] = Versions, [Cipher0 | _] = Ciphers0) when is_binary(Cipher0) -> 2659 All = ssl_cipher:all_suites(Version) ++ 2660 ssl_cipher:anonymous_suites(Version), 2661 case [Cipher || Cipher <- Ciphers0, lists:member(Cipher, All)] of 2662 [] -> 2663 %% Defaults to all supported suites that does 2664 %% not require explicit configuration 2665 binary_cipher_suites(Versions, []); 2666 Ciphers -> 2667 Ciphers 2668 end; 2669binary_cipher_suites(Versions, [Head | _] = Ciphers0) when is_list(Head) -> 2670 %% Format: ["RC4-SHA","RC4-MD5"] 2671 Ciphers = [ssl_cipher_format:suite_openssl_str_to_map(C) || C <- Ciphers0], 2672 binary_cipher_suites(Versions, Ciphers); 2673binary_cipher_suites(Versions, Ciphers0) -> 2674 %% Format: "RC4-SHA:RC4-MD5" 2675 Ciphers = [ssl_cipher_format:suite_openssl_str_to_map(C) || C <- string:lexemes(Ciphers0, ":")], 2676 binary_cipher_suites(Versions, Ciphers). 2677 2678default_binary_suites(exclusive, {_, Minor}) -> 2679 ssl_cipher:filter_suites(tls_v1:exclusive_suites(Minor)); 2680default_binary_suites(default, Version) -> 2681 ssl_cipher:filter_suites(ssl_cipher:suites(Version)). 2682 2683tuple_to_map({Kex, Cipher, Mac}) -> 2684 #{key_exchange => Kex, 2685 cipher => Cipher, 2686 mac => Mac, 2687 prf => default_prf}; 2688tuple_to_map({Kex, Cipher, Mac, Prf}) -> 2689 #{key_exchange => Kex, 2690 cipher => Cipher, 2691 mac => tuple_to_map_mac(Cipher, Mac), 2692 prf => Prf}. 2693 2694%% Backwards compatible 2695tuple_to_map_mac(aes_128_gcm, _) -> 2696 aead; 2697tuple_to_map_mac(aes_256_gcm, _) -> 2698 aead; 2699tuple_to_map_mac(chacha20_poly1305, _) -> 2700 aead; 2701tuple_to_map_mac(_, MAC) -> 2702 MAC. 2703 2704handle_eccs_option(Value, Version) when is_list(Value) -> 2705 {_Major, Minor} = tls_version(Version), 2706 try tls_v1:ecc_curves(Minor, Value) of 2707 Curves -> #elliptic_curves{elliptic_curve_list = Curves} 2708 catch 2709 exit:_ -> throw({error, {options, {eccs, Value}}}); 2710 error:_ -> throw({error, {options, {eccs, Value}}}) 2711 end. 2712 2713handle_supported_groups_option(Value, Version) when is_list(Value) -> 2714 {_Major, Minor} = tls_version(Version), 2715 try tls_v1:groups(Minor, Value) of 2716 Groups -> #supported_groups{supported_groups = Groups} 2717 catch 2718 exit:_ -> throw({error, {options, {supported_groups, Value}}}); 2719 error:_ -> throw({error, {options, {supported_groups, Value}}}) 2720 end. 2721 2722 2723unexpected_format(Error) -> 2724 lists:flatten(io_lib:format("Unexpected error: ~p", [Error])). 2725 2726file_error_format({error, Error})-> 2727 case file:format_error(Error) of 2728 "unknown POSIX error" -> 2729 "decoding error"; 2730 Str -> 2731 Str 2732 end; 2733file_error_format(_) -> 2734 "decoding error". 2735 2736file_desc(cacertfile) -> 2737 "Invalid CA certificate file "; 2738file_desc(certfile) -> 2739 "Invalid certificate file "; 2740file_desc(keyfile) -> 2741 "Invalid key file "; 2742file_desc(dhfile) -> 2743 "Invalid DH params file ". 2744 2745detect(_Pred, []) -> 2746 undefined; 2747detect(Pred, [H|T]) -> 2748 case Pred(H) of 2749 true -> 2750 H; 2751 _ -> 2752 detect(Pred, T) 2753 end. 2754 2755make_next_protocol_selector(undefined) -> 2756 undefined; 2757make_next_protocol_selector({client, AllProtocols, DefaultProtocol}) -> 2758 fun(AdvertisedProtocols) -> 2759 case detect(fun(PreferredProtocol) -> 2760 lists:member(PreferredProtocol, AdvertisedProtocols) 2761 end, AllProtocols) of 2762 undefined -> 2763 DefaultProtocol; 2764 PreferredProtocol -> 2765 PreferredProtocol 2766 end 2767 end; 2768 2769make_next_protocol_selector({server, AllProtocols, DefaultProtocol}) -> 2770 fun(AdvertisedProtocols) -> 2771 case detect(fun(PreferredProtocol) -> 2772 lists:member(PreferredProtocol, AllProtocols) 2773 end, 2774 AdvertisedProtocols) of 2775 undefined -> 2776 DefaultProtocol; 2777 PreferredProtocol -> 2778 PreferredProtocol 2779 end 2780 end. 2781 2782connection_cb(tls) -> 2783 tls_gen_connection; 2784connection_cb(dtls) -> 2785 dtls_gen_connection; 2786connection_cb(Opts) -> 2787 connection_cb(proplists:get_value(protocol, Opts, tls)). 2788 2789record_cb(tls) -> 2790 tls_record; 2791record_cb(dtls) -> 2792 dtls_record; 2793record_cb(Opts) -> 2794 record_cb(proplists:get_value(protocol, Opts, tls)). 2795 2796binary_filename(FileName) -> 2797 Enc = file:native_name_encoding(), 2798 unicode:characters_to_binary(FileName, unicode, Enc). 2799 2800%% Assert that basic options are on the format {Key, Value} 2801%% with a few exceptions and phase out log_alert 2802handle_option_format([], Acc) -> 2803 lists:reverse(Acc); 2804handle_option_format([{log_alert, Bool} | Rest], Acc) when is_boolean(Bool) -> 2805 case proplists:get_value(log_level, Acc ++ Rest, undefined) of 2806 undefined -> 2807 handle_option_format(Rest, [{log_level, 2808 map_log_level(Bool)} | Acc]); 2809 _ -> 2810 handle_option_format(Rest, Acc) 2811 end; 2812handle_option_format([{Key,_} = Opt | Rest], Acc) when is_atom(Key) -> 2813 handle_option_format(Rest, [Opt | Acc]); 2814%% Handle exceptions 2815handle_option_format([{raw,_,_,_} = Opt | Rest], Acc) -> 2816 handle_option_format(Rest, [Opt | Acc]); 2817handle_option_format([inet = Opt | Rest], Acc) -> 2818 handle_option_format(Rest, [Opt | Acc]); 2819handle_option_format([inet6 = Opt | Rest], Acc) -> 2820 handle_option_format(Rest, [Opt | Acc]); 2821handle_option_format([Value | _], _) -> 2822 throw({option_not_a_key_value_tuple, Value}). 2823 2824map_log_level(true) -> 2825 notice; 2826map_log_level(false) -> 2827 none. 2828 2829handle_verify_option(verify_none, #{fail_if_no_peer_cert := false} = OptionsMap) -> 2830 OptionsMap#{verify => verify_none}; 2831handle_verify_option(verify_none, #{fail_if_no_peer_cert := true}) -> 2832 throw({error, {options, incompatible, 2833 {verify, verify_none}, 2834 {fail_if_no_peer_cert, true}}}); 2835%% The option 'verify' is simulated by the configured 'verify_fun' that is mostly 2836%% hidden from the end user. When 'verify' is set to verify_none, the option 2837%% 'verify_fun' is also set to a default verify-none-verify_fun when processing 2838%% the configuration. If 'verify' is later changed from verify_none to verify_peer, 2839%% the 'verify_fun' must also be changed to undefined. When 'verify_fun' is set to 2840%% undefined, public_key's default verify_fun will be used that performs a full 2841%% verification. 2842handle_verify_option(verify_peer, #{verify := verify_none} = OptionsMap) -> 2843 OptionsMap#{verify => verify_peer, 2844 verify_fun => undefined}; 2845handle_verify_option(verify_peer, OptionsMap) -> 2846 OptionsMap#{verify => verify_peer}; 2847handle_verify_option(Value, _) -> 2848 throw({error, {options, {verify, Value}}}). 2849 2850%% Added to handle default values for signature_algs in TLS 1.3 2851default_option_role_sign_algs(_, Value, _, Version) when Version >= {3,4} -> 2852 Value; 2853default_option_role_sign_algs(Role, Value, Role, _) -> 2854 Value; 2855default_option_role_sign_algs(_, _, _, _) -> 2856 undefined. 2857 2858default_option_role(Role, Value, Role) -> 2859 Value; 2860default_option_role(_,_,_) -> 2861 undefined. 2862 2863 2864default_cb_info(tls) -> 2865 {gen_tcp, tcp, tcp_closed, tcp_error, tcp_passive}; 2866default_cb_info(dtls) -> 2867 {gen_udp, udp, udp_closed, udp_error, udp_passive}. 2868 2869include_security_info([]) -> 2870 false; 2871include_security_info([Item | Items]) -> 2872 case lists:member(Item, [client_random, server_random, master_secret, keylog]) of 2873 true -> 2874 true; 2875 false -> 2876 include_security_info(Items) 2877 end. 2878 2879server_name_indication_default(Host) when is_list(Host) -> 2880 %% SNI should not contain a trailing dot that a hostname may 2881 string:strip(Host, right, $.); 2882server_name_indication_default(_) -> 2883 undefined. 2884 2885add_filter(undefined, Filters) -> 2886 Filters; 2887add_filter(Filter, Filters) -> 2888 [Filter | Filters]. 2889