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