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