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