Provided by: erlang-manpages_25.2.3+dfsg-1_all bug

NAME

       ssl - Interface Functions for Secure Socket Layer

DESCRIPTION

       This  module  contains  interface  functions  for  the  TLS/DTLS  protocol.  For  detailed
       information about the supported standards see ssl(7).

DATA TYPES

   Types used in TLS/DTLS
       socket() = gen_tcp:socket()

       sslsocket() = any()

              An opaque reference to the TLS/DTLS connection, may be used for equality matching.

       tls_option() = tls_client_option() | tls_server_option()

       tls_client_option() =
           client_option() |
           common_option() |
           socket_option() |
           transport_option()

       tls_server_option() =
           server_option() |
           common_option() |
           socket_option() |
           transport_option()

       socket_option() =
           gen_tcp:connect_option() |
           gen_tcp:listen_option() |
           gen_udp:option()

              The  default  socket  options  are  [{mode,list},{packet,  0},{header,  0},{active,
              true}].

              For valid options, see the inet(3erl), gen_tcp(3erl) and gen_udp(3erl) manual pages
              in Kernel. Note that stream oriented options such as packet are only  relevant  for
              TLS and not DTLS

       active_msgs() =
           {ssl, sslsocket(), Data :: binary() | list()} |
           {ssl_closed, sslsocket()} |
           {ssl_error, sslsocket(), Reason :: any()} |
           {ssl_passive, sslsocket()}

              When  a  TLS/DTLS  socket  is in active mode (the default), data from the socket is
              delivered to the owner of the socket in the form of messages as described above.

              The ssl_passive message is sent only when the socket is in {active, N} mode and the
              counter  dropped  to  0.  It  indicates that the socket has transitioned to passive
              ({active, false}) mode.

       transport_option() =
           {cb_info,
            {CallbackModule :: atom(),
             DataTag :: atom(),
             ClosedTag :: atom(),
             ErrTag :: atom()}} |
           {cb_info,
            {CallbackModule :: atom(),
             DataTag :: atom(),
             ClosedTag :: atom(),
             ErrTag :: atom(),
             PassiveTag :: atom()}}

              Defaults to  {gen_tcp,  tcp,  tcp_closed,  tcp_error,  tcp_passive}  for  TLS  (for
              backward compatibility a four tuple will be converted to a five tuple with the last
              element "second_element"_passive) and {gen_udp,  udp,  udp_closed,  udp_error}  for
              DTLS  (might also be changed to five tuple in the future). Can be used to customize
              the transport layer. The tag values should be the values  used  by  the  underlying
              transport in its active mode messages. For TLS the callback module must implement a
              reliable transport protocol, behave as gen_tcp, and have functions corresponding to
              inet:setopts/2,  inet:getopts/2, inet:peername/1, inet:sockname/1, and inet:port/1.
              The callback gen_tcp is treated specially and calls inet directly.  For  DTLS  this
              feature must be considered experimental.

       host() = hostname() | ip_address()

       hostname() = string()

       ip_address() = inet:ip_address()

       protocol_version() = tls_version() | dtls_version()

       tls_version() = 'tlsv1.2' | 'tlsv1.3' | tls_legacy_version()

       dtls_version() = 'dtlsv1.2' | dtls_legacy_version()

       tls_legacy_version() = tlsv1 | 'tlsv1.1'

       dtls_legacy_version() = dtlsv1

       prf_random() = client_random | server_random

       verify_type() = verify_none | verify_peer

       ciphers() = [erl_cipher_suite()] | string()

       erl_cipher_suite() =
           #{key_exchange := kex_algo(),
             cipher := cipher(),
             mac := hash() | aead,
             prf := hash() | default_prf}

       cipher() =
           aes_128_cbc | aes_256_cbc | aes_128_gcm | aes_256_gcm |
           aes_128_ccm | aes_256_ccm | aes_128_ccm_8 | aes_256_ccm_8 |
           chacha20_poly1305 |
           legacy_cipher()

       legacy_cipher() = rc4_128 | des_cbc | '3des_ede_cbc'

       cipher_filters() =
           [{key_exchange | cipher | mac | prf, algo_filter()}]

       hash() = sha | sha2() | legacy_hash()

       sha2() = sha224 | sha256 | sha384 | sha512

       legacy_hash() = md5

       old_cipher_suite() =
           {kex_algo(), cipher(), hash()} |
           {kex_algo(), cipher(), hash() | aead, hash()}

       sign_algo() = rsa | dsa | ecdsa | eddsa

       sign_scheme() =
           eddsa_ed25519 | eddsa_ed448 | ecdsa_secp256r1_sha256 |
           ecdsa_secp384r1_sha384 | ecdsa_secp521r1_sha512 |
           rsassa_pss_scheme() |
           sign_scheme_legacy()

       rsassa_pss_scheme() =
           rsa_pss_rsae_sha256 | rsa_pss_rsae_sha384 |
           rsa_pss_rsae_sha512 | rsa_pss_pss_sha256 |
           rsa_pss_pss_sha384 | rsa_pss_pss_sha512

       sign_scheme_legacy() =
           rsa_pkcs1_sha256 | rsa_pkcs1_sha384 | rsa_pkcs1_sha512 |
           rsa_pkcs1_sha1 | ecdsa_sha1

       group() =
           secp256r1 | secp384r1 | secp521r1 | ffdhe2048 | ffdhe3072 |
           ffdhe4096 | ffdhe6144 | ffdhe8192

       kex_algo() =
           rsa | dhe_rsa | dhe_dss | ecdhe_ecdsa | ecdh_ecdsa |
           ecdh_rsa | srp_rsa | srp_dss | psk | dhe_psk | rsa_psk |
           dh_anon | ecdh_anon | srp_anon | any

       algo_filter() =
           fun((kex_algo() | cipher() | hash() | aead | default_prf) ->
                   true | false)

       named_curve() =
           sect571r1 | sect571k1 | secp521r1 | brainpoolP512r1 |
           sect409k1 | sect409r1 | brainpoolP384r1 | secp384r1 |
           sect283k1 | sect283r1 | brainpoolP256r1 | secp256k1 |
           secp256r1 | sect239k1 | sect233k1 | sect233r1 | secp224k1 |
           secp224r1 | sect193r1 | sect193r2 | secp192k1 | secp192r1 |
           sect163k1 | sect163r1 | sect163r2 | secp160k1 | secp160r1 |
           secp160r2

       psk_identity() = string()

       srp_identity() = {Username :: string(), Password :: string()}

       srp_param_type() =
           srp_1024 | srp_1536 | srp_2048 | srp_3072 | srp_4096 |
           srp_6144 | srp_8192

       app_level_protocol() = binary()

       protocol_extensions() =
           #{renegotiation_info => binary(),
             signature_algs => signature_algs(),
             alpn => app_level_protocol(),
             srp => binary(),
             next_protocol => app_level_protocol(),
             max_frag_enum => 1..4,
             ec_point_formats => [0..2],
             elliptic_curves => [public_key:oid()],
             sni => hostname()}

       error_alert() =
           {tls_alert, {tls_alert(), Description :: string()}}

       tls_alert() =
           close_notify | unexpected_message | bad_record_mac |
           record_overflow | handshake_failure | bad_certificate |
           unsupported_certificate | certificate_revoked |
           certificate_expired | certificate_unknown |
           illegal_parameter | unknown_ca | access_denied |
           decode_error | decrypt_error | export_restriction |
           protocol_version | insufficient_security | internal_error |
           inappropriate_fallback | user_canceled | no_renegotiation |
           unsupported_extension | certificate_unobtainable |
           unrecognized_name | bad_certificate_status_response |
           bad_certificate_hash_value | unknown_psk_identity |
           no_application_protocol

       reason() = any()

       bloom_filter_window_size() = integer()

       bloom_filter_hash_functions() = integer()

       bloom_filter_bits() = integer()

       client_session_tickets() = disabled | manual | auto

       server_session_tickets() = disabled | stateful | stateless

   TLS/DTLS OPTION DESCRIPTIONS - COMMON for SERVER and CLIENT
       common_option() =
           {protocol, protocol()} |
           {handshake, handshake_completion()} |
           {cert, cert() | [cert()]} |
           {certfile, cert_pem()} |
           {key, key()} |
           {keyfile, key_pem()} |
           {password, key_pem_password()} |
           {certs_keys, certs_keys()} |
           {ciphers, cipher_suites()} |
           {eccs, [named_curve()]} |
           {signature_algs, signature_algs()} |
           {signature_algs_cert, sign_schemes()} |
           {supported_groups, supported_groups()} |
           {secure_renegotiate, secure_renegotiation()} |
           {keep_secrets, keep_secrets()} |
           {depth, allowed_cert_chain_length()} |
           {verify_fun, custom_verify()} |
           {crl_check, crl_check()} |
           {crl_cache, crl_cache_opts()} |
           {max_handshake_size, handshake_size()} |
           {partial_chain, root_fun()} |
           {versions, protocol_versions()} |
           {user_lookup_fun, custom_user_lookup()} |
           {log_level, logging_level()} |
           {log_alert, log_alert()} |
           {hibernate_after, hibernate_after()} |
           {padding_check, padding_check()} |
           {beast_mitigation, beast_mitigation()} |
           {ssl_imp, ssl_imp()} |
           {session_tickets, session_tickets()} |
           {key_update_at, key_update_at()} |
           {receiver_spawn_opts, spawn_opts()} |
           {sender_spawn_opts, spawn_opts()}

       protocol() = tls | dtls

              Choose  TLS or DTLS protocol for the transport layer security. Defaults to tls. For
              DTLS other transports than UDP are not yet supported.

       handshake_completion() = hello | full

              Defaults to full. If hello is specified the handshake will pause  after  the  hello
              message  and  give  the user a possibility make decisions based on hello extensions
              before continuing or aborting the handshake  by  calling   handshake_continue/3  or
              handshake_cancel/1

       cert() = public_key:der_encoded()

              The  DER-encoded  user certificate. Note that the cert option may also be a list of
              DER-encoded certificates where the first one is the user certificate, and the  rest
              of the certificates constitutes the certificate chain. For maximum interoperability
              the certificates in the chain should be in the correct order,  the  chain  will  be
              sent  as  is to the peer. If chain certificates are not provided, certificates from
              client_cacerts(), server_cacerts(), or client_cafile(), server_cafile() are used to
              construct the chain. If this option is supplied, it overrides option certfile.

       cert_pem() = file:filename()

              Path  to  a  file containing the user certificate on PEM format or possible several
              certificates where the first one is the  user  certificate  and  the  rest  of  the
              certificates constitutes the certificate chain. For more details see cert(),

       key() =
           {'RSAPrivateKey' | 'DSAPrivateKey' | 'ECPrivateKey' |
            'PrivateKeyInfo',
            public_key:der_encoded()} |
           #{algorithm := rsa | dss | ecdsa,
             engine := crypto:engine_ref(),
             key_id := crypto:key_id(),
             password => crypto:password()}

              The  DER-encoded  user's  private key or a map referring to a crypto engine and its
              key   reference   that   optionally   can   be   password   protected,   see   also
              crypto:engine_load/3   and   Crypto's  Users  Guide. If this option is supplied, it
              overrides option keyfile.

       key_pem() = file:filename()

              Path to the file containing the user's private PEM-encoded key.  As  PEM-files  can
              contain  several  entries, this option defaults to the same file as given by option
              certfile.

       key_pem_password() = iodata() | fun(() -> iodata())

              String containing the user's password or a function returning same type. Only  used
              if the private keyfile is password-protected.

       certs_keys() = [cert_key_conf()]

              A  list  of  a  certificate  (or  possible  a  certificate  and  its chain) and the
              associated key of the certificate, that may be used to authenticate the  client  or
              the server. The certificate key pair that is considered best and matches negotiated
              parameters for the connection will be selected. Different signature algorithms  are
              prioritized in the order  eddsa, ecdsa, rsa_pss_pss, rsa and dsa . If more than one
              key is supplied for the same signing algorithm (which is probably  an  unusual  use
              case)  they  will  prioritized by strength unless it is a so called engine key that
              will be favoured over other keys. As engine keys  cannot  be  inspected,  supplying
              more  than  one  engine  key  will  make  no  sense. This offers flexibility to for
              instance configure a newer certificate that is expected to be used  in  most  cases
              and  an older but acceptable certificate that will only be used to communicate with
              legacy systems. Note that there is a trade off between the induced overhead and the
              flexibility  so  alternatives  should be chosen for good reasons. If the certs_keys
              option is specified it overrides  all  single  certificate  and  key  options.  For
              examples see  the Users Guide

          Note:
              eddsa  certificates  are  only  supported  by  TLS-1.3  that  does  not support dsa
              certificates. rsa_pss_pss (RSA certificates using Probabilistic  Signature  Scheme)
              are  supported  in  TLS-1.2  and  TLS-1.3, but some TLS-1.2 implementations may not
              support rsa_pss_pss.

       cert_key_conf() =
           #{cert => cert(),
             key => key(),
             certfile => cert_pem(),
             keyfile => key_pem(),
             password => key_pem_password()}

              A certificate (or possibly a certificate and its chain) and its associated  key  on
              one  of  the possible formats. For the PEM file format there may also be a password
              associated with the file containg the key.

       cipher_suites() = ciphers()

              A list of cipher suites that should be supported

              The function  ssl:cipher_suites/2  can be used to find all cipher suites  that  are
              supported by default and all cipher suites that may be configured.

              If  you  compose your own cipher_suites() make sure they are filtered for cryptolib
              support       ssl:filter_cipher_suites/2       Additionally      the      functions
              ssl:append_cipher_suites/2    ,   ssl:prepend_cipher_suites/2,  ssl:suite_to_str/1,
              ssl:str_to_suite/1, and ssl:suite_to_openssl_str/1  also  exist  to  help  creating
              customized cipher suite lists.

          Note:
              Note  that  TLS-1.3  and  TLS-1.2  cipher suites are not overlapping sets of cipher
              suites so to support both these versions cipher suites from both versions  need  to
              be included. Also if the supplied list does not comply with the configured versions
              or cryptolib so that the list becomes empty,  this  option  will  fallback  on  its
              appropriate default value for the configured versions.

              Non-default  cipher  suites  including  anonymous  cipher  suites (PRE TLS-1.3) are
              supported for interop/testing purposes and may be  used  by  adding  them  to  your
              cipher  suite  list.  Note  that they must also be supported/enabled by the peer to
              actually be used.

       signature_algs() = [{hash(), sign_algo()} | sign_scheme()]

              Explicitly list acceptable signature  algorithms  for  certificates  and  handshake
              messages  in the preferred order. The client will send its list as the client hello
              signature_algorithm extension introduced in TLS-1.2, see Section 7.4.1.4.1  in  RFC
              5246.  Previously  these algorithms where implicitly chosen and partly derived from
              the cipher suite.

              In TLS-1.2 a somewhat more explicit negotiation is made possible using  a  list  of
              {hash(), sign_algo()} pairs.

              In  TLS-1.3  these  algorithm  pairs  are  replaced  by so called signature schemes
              sign_scheme() and completely decoupled from the cipher suite.

              Signature algorithms used for certificates  may  be  overridden  by  the  signature
              schemes (algorithms) supplied by the signature_algs_cert option.

              TLS-1.2  default is Default_TLS_12_Alg_Pairs interleaved with rsa_pss_schemes since
              ssl-11.0 (OTP-25) pss_pss is prefered over pss_rsae that is prefered over rsa

              Default_TLS_12_Alg_Pairs =

              [
              %% SHA2
              {sha512, ecdsa},
              {sha512, rsa},
              {sha384, ecdsa},
              {sha384, rsa},
              {sha256, ecdsa},
              {sha256, rsa},
              {sha224, ecdsa},
              {sha224, rsa},
              %% SHA
              {sha, ecdsa},
              {sha, rsa},
              {sha, dsa}
              ]

              Support for {md5, rsa} was removed from the the TLS-1.2 default in ssl-8.0 (OTP-22)

               rsa_pss_schemes =

              [rsa_pss_pss_sha512,
              rsa_pss_pss_sha384,
              rsa_pss_pss_sha256,
              rsa_pss_rsae_sha512,
              rsa_pss_rsae_sha384,
              rsa_pss_rsae_sha256]

               TLS_13_Legacy_Schemes =

               [
               %% Legacy algorithms only applicable to certificate signatures
              rsa_pkcs1_sha512, %% Corresponds to {sha512, rsa}
              rsa_pkcs1_sha384, %% Corresponds to {sha384, rsa}
              rsa_pkcs1_sha256, %% Corresponds to {sha256, rsa}
              ecdsa_sha1,       %% Corresponds to {sha, ecdsa}
              rsa_pkcs1_sha1    %% Corresponds to {sha, rsa}
              ]

               Default_TLS_13_Schemes =

               [
               %% EDDSA
              eddsa_ed25519,
              eddsa_ed448

              %% ECDSA
              ecdsa_secp521r1_sha512,
              ecdsa_secp384r1_sha384,
              ecdsa_secp256r1_sha256] ++

              %% RSASSA-PSS
              rsa_pss_schemes()

              EDDSA was made highest priority in ssl-11.0 (OTP-25)

              TLS-1.3 default is

              Default_TLS_13_Schemes ++ Legacy_TLS_13_Schemes

              If both TLS-1.3 and TLS-1.2 are supported the default will be

              Default_TLS_13_Schemes ++ Default_TLS_12_Alg_Pairs

              so appropriate algorithms can be chosen for the negotiated version.

          Note:
              TLS-1.2 algorithms will not be  negotiated  for  TLS-1.3,  but  TLS-1.3  RSASSA-PSS
              rsassa_pss_scheme()  signature schemes may be negotiated also for TLS-1.2 from 24.1
              (fully working from 24.1.3). However if TLS-1.3 is negotiated when both TLS-1.3 and
              TLS-1.2  is  supported  using defaults, the corresponding TLS-1.2 algorithms to the
              TLS-1.3 legacy signature schemes will be  considered  as  the  legacy  schemes  and
              applied only to certificate signatures.

       sign_schemes() = [sign_scheme()]

              Explicitly  list  acceptable signature schemes (algorithms) in the preferred order.
              Overrides the algorithms supplied in signature_algs option for certificates.

              In addition to the signature_algorithms extension from TLS 1.2, TLS 1.3  (RFC  5246
              Section  4.2.3)  adds  the signature_algorithms_cert extension which enables having
              special requirements on the signatures used in the certificates that  differs  from
              the  requirements  on  digital  signatures as a whole. If this is not required this
              extension is not need.

              The client will send a signature_algorithms_cert extension  (in  the  client  hello
              message), if TLS version 1.2 (back-ported to TLS 1.2 in 24.1) or later is used, and
              the signature_algs_cert option  is  explicitly  specified.  By  default,  only  the
              signature_algs extension is sent.

          Note:
              Note  that  supported  signature  schemes  for TLS-1.2 are sign_scheme_legacy() and
              rsassa_pss_scheme()

       supported_groups() = [group()]

              TLS 1.3 introduces the "supported_groups" extension that is  used  for  negotiating
              the  Diffie-Hellman  parameters  in a TLS 1.3 handshake. Both client and server can
              specify a list of parameters that they are willing to use.

              If it is not specified it will  use  a  default  list  ([x25519,  x448,  secp256r1,
              secp384r1]) that is filtered based on the installed crypto library version.

       secure_renegotiation() = boolean()

              Specifies  if to reject renegotiation attempt that does not live up to RFC 5746. By
              default secure_renegotiate is  set  to  true,  that  is,  secure  renegotiation  is
              enforced.  If set to false secure renegotiation will still be used if possible, but
              it falls back to insecure renegotiation if the peer does not support RFC 5746.

       allowed_cert_chain_length() = integer()

              Maximum number of non-self-issued intermediate certificates  that  can  follow  the
              peer  certificate in a valid certification path. So, if depth is 0 the PEER must be
              signed by the trusted ROOT-CA directly; if 1 the path can be PEER, CA, ROOT-CA;  if
              2 the path can be PEER, CA, CA, ROOT-CA, and so on. The default value is 10.

       custom_verify() =
           {Verifyfun :: function(), InitialUserState :: any()}

              The verification fun is to be defined as follows:

              fun(OtpCert :: #'OTPCertificate'{},
                  Event, InitialUserState :: term()) ->
                   {valid, UserState :: term()} |
                   {fail, Reason :: term()} | {unknown, UserState :: term()}.

              fun(OtpCert :: #'OTPCertificate'{}, DerCert :: public_key:der_encoded(),
                  Event, InitialUserState :: term()) ->
                   {valid, UserState :: term()} |
                   {fail, Reason :: term()} | {unknown, UserState :: term()}.

              Types:
                    Event = {bad_cert, Reason :: atom() |
                            {revoked, atom()}} |
                         {extension, #'Extension'{}} |
                            valid |
                            valid_peer

              The  verification fun is called during the X509-path validation when an error or an
              extension unknown to the SSL application is encountered. It is also called  when  a
              certificate  is  considered  valid  by  the path validation to allow access to each
              certificate in the path to the user application. It differentiates between the peer
              certificate  and the CA certificates by using valid_peer or valid as Event argument
              to the verification  fun.  See  the  public_key  User's  Guide  for  definition  of
              #'OTPCertificate'{} and #'Extension'{}.

                * If  the verify callback fun returns {fail, Reason}, the verification process is
                  immediately stopped, an alert is sent to the peer, and the  TLS/DTLS  handshake
                  terminates.

                * If the verify callback fun returns {valid, UserState}, the verification process
                  continues.

                * If the verify callback fun always  returns  {valid,  UserState},  the  TLS/DTLS
                  handshake does not terminate regarding verification failures and the connection
                  is established.

                * If called with an extension unknown  to  the  user  application,  return  value
                  {unknown, UserState} is to be used.

                  Note  that  if  the  fun  returns  unknown for an extension marked as critical,
                  validation will fail.

              Default option verify_fun in verify_peer mode:

              {fun(_,{bad_cert, _} = Reason, _) ->
                    {fail, Reason};
                  (_,{extension, _}, UserState) ->
                    {unknown, UserState};
                  (_, valid, UserState) ->
                    {valid, UserState};
                  (_, valid_peer, UserState) ->
                       {valid, UserState}
               end, []}

              Default option verify_fun in mode verify_none:

              {fun(_,{bad_cert, _}, UserState) ->
                    {valid, UserState};
                  (_,{extension, #'Extension'{critical = true}}, UserState) ->
                    {valid, UserState};
                  (_,{extension, _}, UserState) ->
                    {unknown, UserState};
                  (_, valid, UserState) ->
                    {valid, UserState};
                  (_, valid_peer, UserState) ->
                       {valid, UserState}
               end, []}

              The possible path validation errors are given  on  form  {bad_cert,  Reason}  where
              Reason is:

                unknown_ca:
                  No  trusted  CA was found in the trusted store. The trusted CA is normally a so
                  called ROOT CA, which is a self-signed certificate. Trust can be claimed for an
                  intermediate  CA  (trusted  anchor does not have to be self-signed according to
                  X-509) by using option partial_chain.

                selfsigned_peer:
                  The chain consisted only of one self-signed certificate.

                PKIX X-509-path validation error:
                  For possible reasons, see public_key:pkix_path_validation/3

       crl_check() = boolean() | peer | best_effort

              Perform      CRL       (Certificate       Revocation       List)       verification
              (public_key:pkix_crls_validate/3)   on   all   the  certificates  during  the  path
              validation (public_key:pkix_path_validation/3)  of the certificate chain.  Defaults
              to false.

                peer:
                  check is only performed on the peer certificate.

                best_effort:
                  if  certificate  revocation  status cannot be determined it will be accepted as
                  valid.

              The CA certificates specified for the connection will  be  used  to  construct  the
              certificate chain validating the CRLs.

              The    CRLs   will   be   fetched   from   a   local   or   external   cache.   See
              ssl_crl_cache_api(3erl).

       crl_cache_opts() =
           {Module :: atom(),
            {DbHandle :: internal | term(), Args :: list()}}

              Specify how to perform lookup and caching of certificate revocation  lists.  Module
              defaults  to  ssl_crl_cache  with   DbHandle   being internal and an empty argument
              list.

              There are two implementations available:

                ssl_crl_cache:
                  This module maintains a cache of CRLs. CRLs can be added to the cache using the
                  function  ssl_crl_cache:insert/1,  and optionally automatically fetched through
                  HTTP if the following argument is specified:

                  {http, timeout()}:
                    Enables  fetching  of  CRLs  specified  as  http  URIs   inX509   certificate
                    extensions. Requires the OTP inets application.

                ssl_crl_hash_dir:
                  This  module  makes  use of a directory where CRLs are stored in files named by
                  the hash of the issuer name.

                  The file names consist of eight hexadecimal digits followed by .rN, where N  is
                  an  integer,  e.g.  1a2b3c4d.r0.  For the first version of the CRL, N starts at
                  zero, and for each new version, N is incremented by one.  The  OpenSSL  utility
                  c_rehash creates symlinks according to this pattern.

                  For  a  given  hash value, this module finds all consecutive .r* files starting
                  from zero, and those files taken together make  up  the  revocation  list.  CRL
                  files  whose  nextUpdate  fields  are  in  the  past,  or  that are issued by a
                  different CA that happens to have the same name hash, are excluded.

                  The following argument is required:

                  {dir, string()}:
                    Specifies the directory in which the CRLs can be found.

       root_fun() = function()

              fun(Chain::[public_key:der_encoded()]) ->
                   {trusted_ca, DerCert::public_key:der_encoded()} | unknown_ca}

              Claim  an  intermediate  CA  in  the  chain   as   trusted.   TLS   then   performs
              public_key:pkix_path_validation/3  with  the  selected CA as trusted anchor and the
              rest of the chain.

       protocol_versions() = [protocol_version()]

              TLS protocol versions  supported  by  started  clients  and  servers.  This  option
              overrides    the    application    environment    option    protocol_version    and
              dtls_protocol_version. If the environment option is not set,  it  defaults  to  all
              versions, supported by the SSL application. See also ssl(7).

       custom_user_lookup() =
           {Lookupfun :: function(), UserState :: any()}

              The lookup fun is to defined as follows:

              fun(psk, PSKIdentity :: binary(), UserState :: term()) ->
                   {ok, SharedSecret :: binary()} | error;
              fun(srp, Username :: binary(), UserState :: term()) ->
                   {ok, {SRPParams :: srp_param_type(), Salt :: binary(),
                         DerivedKey :: binary()}} | error.

              For  Pre-Shared Key (PSK) cipher suites, the lookup fun is called by the client and
              server to determine the shared secret. When called by the  client,  PSKIdentity  is
              set to the hint presented by the server or to undefined. When called by the server,
              PSKIdentity is the identity presented by the client.

              For Secure Remote Password (SRP), the fun is only used  by  the  server  to  obtain
              parameters  that  it uses to generate its session keys. DerivedKey is to be derived
              according to  RFC  2945  and   RFC  5054:  crypto:sha([Salt,  crypto:sha([Username,
              <<$:>>, Password])])

       session_id() = binary()

              Identifies a TLS session.

       log_alert() = boolean()

              If  set  to  false, TLS/DTLS Alert reports are not displayed. Deprecated in OTP 22,
              use {log_level, logging_level()} instead.

       logging_level() = logger:level() | none | all

              Specifies the log level for a TLS/DTLS connection.  Alerts  are  logged  on  notice
              level,  which  is  the  default  level. The level debug triggers verbose logging of
              TLS/DTLS protocol messages. See also ssl(7)

       hibernate_after() = timeout()

              When an integer-value is specified, TLS/DTLS-connection goes into hibernation after
              the  specified  number  of  milliseconds  of  inactivity,  thus reducing its memory
              footprint. When undefined is specified (this is the  default),  the  process  never
              goes into hibernation.

       handshake_size() = integer()

              Integer  (24  bits unsigned). Used to limit the size of valid TLS handshake packets
              to avoid DoS attacks. Defaults to 256*1024.

       padding_check() = boolean()

              Affects TLS-1.0 connections only. If set to false, it  disables  the  block  cipher
              padding check to be able to interoperate with legacy software.

          Warning:
              Using {padding_check, boolean()} makes TLS vulnerable to the Poodle attack.

       beast_mitigation() = one_n_minus_one | zero_n | disabled

              Affects  TLS-1.0  connections only. Used to change the BEAST mitigation strategy to
              interoperate with legacy software. Defaults to one_n_minus_one.

              one_n_minus_one - Perform 1/n-1 BEAST mitigation.

              zero_n - Perform 0/n BEAST mitigation.

              disabled - Disable BEAST mitigation.

          Warning:
              Using {beast_mitigation, disabled} makes TLS-1.0 vulnerable to the BEAST attack.

       ssl_imp() = new | old

              Deprecated since OTP-17, has no effect.

       session_tickets() =
           client_session_tickets() | server_session_tickets()

              Configures the session ticket functionality in TLS 1.3 client and server.

       key_update_at() = integer() >= 1

              Configures the maximum amount of bytes that can be sent on  a  TLS  1.3  connection
              before an automatic key update is performed.

              There  are  cryptographic  limits  on  the  amount of plaintext which can be safely
              encrypted under a given  set  of  keys.  The  current  default  ensures  that  data
              integrity  will  not  be  breached  with  probability greater than 1/2^57. For more
              information see Limits on Authenticated Encryption Use in TLS.

          Warning:
              The default value of  this  option  shall  provide  the  above  mentioned  security
              guarantees and it shall be reasonable for most applications (~353 TB).

       middlebox_comp_mode() = boolean()

              Configures the middlebox compatibility mode on a TLS 1.3 connection.

              A  significant  number  of  middleboxes  misbehave  when  a  TLS  1.3 connection is
              negotiated. Implementations can increase the chance of making  connections  through
              those middleboxes by making the TLS 1.3 handshake more like a TLS 1.2 handshake.

              The middlebox compatibility mode is enabled (true) by default.

       spawn_opts() = [erlang:spawn_opt_option()]

              Configures spawn options of TLS sender and receiver processes.

              Setting  up  garbage  collection  options can be helpful for trade-offs between CPU
              usage and Memory usage. See erlang:spawn_opt/2.

              For dist connections, default sender option is [...{priority, max}], this  priority
              option  cannot  be  changed.  For all connections, ...link is added to receiver and
              cannot be changed.

       keep_secrets() = boolean()

              Configures a TLS 1.3 connection for keylogging

              In order to retrieve keylog information  on  a  TLS  1.3  connection,  it  must  be
              configured in advance to keep the client_random and various handshake secrets.

              The keep_secrets functionality is disabled (false) by default.

              Added in OTP 23.2

   TLS/DTLS OPTION DESCRIPTIONS - CLIENT
       client_option() =
           {verify, client_verify_type()} |
           {reuse_session, client_reuse_session()} |
           {reuse_sessions, client_reuse_sessions()} |
           {cacerts, client_cacerts()} |
           {cacertfile, client_cafile()} |
           {alpn_advertised_protocols, client_alpn()} |
           {client_preferred_next_protocols,
            client_preferred_next_protocols()} |
           {psk_identity, client_psk_identity()} |
           {srp_identity, client_srp_identity()} |
           {server_name_indication, sni()} |
           {max_fragment_length, max_fragment_length()} |
           {customize_hostname_check, customize_hostname_check()} |
           {fallback, fallback()} |
           {middlebox_comp_mode, middlebox_comp_mode()} |
           {certificate_authorities, client_certificate_authorities()} |
           {session_tickets, client_session_tickets()} |
           {use_ticket, use_ticket()} |
           {early_data, client_early_data()}

       client_verify_type() = verify_type()

              Defaults  to verify_none as additional options are needed to be able to perform the
              certificate  verification.  A  warning  will  be  emitted  unless  verify_none   is
              explicitly  configured. Usually the applications will want to configure verify_peer
              together with an appropriate cacert or cacertfile  option.  For  example  an  HTTPS
              client would normally use the option {cacerts, public_key:cacerts_get()} (available
              since OTP-25) to access the CA certificates provided by the OS.  Using  verify_none
              means  that  all  x509-certificate path validation errors will be ignored. See also
              option verify_fun.

       client_reuse_session() =
           session_id() | {session_id(), SessionData :: binary()}

              Reuses a specific session. The session should be referred by its session id  if  it
              is  earlier  saved  with  the  option  {reuse_sessions,  save}  since  OTP-21.3  or
              explicitly specified by its session id and associated data since OTP-22.3. See also
              SSL's Users Guide, Session Reuse pre TLS 1.3.

       client_reuse_sessions() = boolean() | save

              When  save  is  specified  a  new connection will be negotiated and saved for later
              reuse. The session ID can be fetched with connection_information/2  and  used  with
              the  client option reuse_session The boolean value true specifies that if possible,
              automated session reuse will be performed. If a new  session  is  created,  and  is
              unique  in  regard to previous stored sessions, it will be saved for possible later
              reuse. Since OTP-21.3.

       client_certificate_authorities() = boolean()

              If set to true, sends the  certificate  authorities  extension  in  TLS-1.3  client
              hello.  The  default  is  false.  Note  that setting it to true may result in a big
              overhead if you have many trusted CA certificates. Since OTP-24.3.

       client_cacerts() =
           [public_key:der_encoded()] | [public_key:combined_cert()]

              The DER-encoded trusted certificates. If  this  option  is  supplied  it  overrides
              option cacertfile.

       client_cafile() = file:filename()

              Path to a file containing PEM-encoded CA certificates. The CA certificates are used
              during server authentication and when building the client certificate chain.

          Note:
              When PEM caching is enabled, files provided with this option will  be  checked  for
              updates  at  fixed  time intervals specified by the ssl_pem_cache_clean environment
              parameter.

          Note:
              Alternatively, CA certificates  can  be  provided  as  a  DER-encoded  binary  with
              client_cacerts option.

       client_alpn() = [app_level_protocol()]

              The  list  of protocols supported by the client to be sent to the server to be used
              for an Application-Layer Protocol Negotiation (ALPN). If the server  supports  ALPN
              then  it  will  choose  a  protocol  from  this  list;  otherwise  it will fail the
              connection with a "no_application_protocol" alert. A server that does  not  support
              ALPN will ignore this value.

              The list of protocols must not contain an empty binary.

              The negotiated protocol can be retrieved using the negotiated_protocol/1 function.

       client_preferred_next_protocols() =
           {Precedence :: server | client,
            ClientPrefs :: [app_level_protocol()]} |
           {Precedence :: server | client,
            ClientPrefs :: [app_level_protocol()],
            Default :: app_level_protocol()}

              Indicates that the client is to try to perform Next Protocol Negotiation.

              If  precedence is server, the negotiated protocol is the first protocol to be shown
              on the server advertised list, which is also on the client preference list.

              If precedence is client, the negotiated protocol is the first protocol to be  shown
              on the client preference list, which is also on the server advertised list.

              If the client does not support any of the server advertised protocols or the server
              does not advertise any protocols, the client falls back to the  first  protocol  in
              its  list or to the default protocol (if a default is supplied). If the server does
              not support Next Protocol Negotiation, the  connection  terminates  if  no  default
              protocol is supplied.

       max_fragment_length() = undefined | 512 | 1024 | 2048 | 4096

              Specifies  the  maximum  fragment  length the client is prepared to accept from the
              server. See RFC 6066

       client_psk_identity() = psk_identity()

              Specifies the identity the client presents to the server. The  matching  secret  is
              found by calling user_lookup_fun

       client_srp_identity() = srp_identity()

              Specifies the username and password to use to authenticate to the server.

       sni() = hostname() | disable

              Specify  the  hostname  to  be used in TLS Server Name Indication extension. If not
              specified it will default to the Host argument of connect/[3,4]  unless  it  is  of
              type inet:ipaddress().

              The HostName will also be used in the hostname verification of the peer certificate
              using public_key:pkix_verify_hostname/2.

              The special value disable prevents the Server Name Indication extension from  being
              sent and disables the hostname verification check public_key:pkix_verify_hostname/2

       customize_hostname_check() = list()

              Customizes  the  hostname  verification  of  the  peer  certificate,  as  different
              protocols that use TLS such as HTTP or LDAP may want  to  do  it  differently,  for
              possible options see public_key:pkix_verify_hostname/3

       fallback() = boolean()

              Send  special  cipher  suite  TLS_FALLBACK_SCSV  to  avoid  undesired  TLS  version
              downgrade. Defaults to false

          Warning:
              Note this option is not needed in normal TLS  usage  and  should  not  be  used  to
              implement new clients. But legacy clients that retries connections in the following
              manner

               ssl:connect(Host, Port, [...{versions, ['tlsv2', 'tlsv1.1', 'tlsv1']}])

               ssl:connect(Host, Port, [...{versions, [tlsv1.1', 'tlsv1']}, {fallback, true}])

               ssl:connect(Host, Port, [...{versions, ['tlsv1']}, {fallback, true}])

              may use it to avoid undesired TLS version downgrade.  Note  that  TLS_FALLBACK_SCSV
              must also be supported by the server for the prevention to work.

       client_session_tickets() = disabled | manual | auto

              Configures  the  session  ticket functionality. Allowed values are disabled, manual
              and auto. If it is set to manual the client will send  the  ticket  information  to
              user process in a 3-tuple:

              {ssl, session_ticket, {SNI, TicketData}}

              where  SNI  is  the ServerNameIndication and TicketData is the extended ticket data
              that can be used in subsequent session resumptions.

              If it is set to auto, the client automatically handles received tickets  and  tries
              to  use  them  when  making new TLS connections (session resumption with pre-shared
              keys).

          Note:
              This option is supported by TLS 1.3 and above. See also  SSL's Users Guide, Session
              Tickets and Session Resumption in TLS 1.3

       use_ticket() = [binary()]

              Configures the session tickets to be used for session resumption. It is a mandatory
              option in manual mode (session_tickets = manual).

          Note:
              Session tickets are only sent to user if option session_tickets is set to manual

              This option is supported by TLS 1.3 and above. See also  SSL's Users Guide, Session
              Tickets and Session Resumption in TLS 1.3

       client_early_data() = binary()

              Configures the early data to be sent by the client.

              In  order  to  be  able  to verify that the server has the intention to process the
              early data, the following 3-tuple is sent to the user process:

              {ssl, SslSocket, {early_data, Result}}

              where Result is either accepted or rejected.

          Warning:
              It is the responsibility of the user to handle a rejected Early Data and to  resend
              when it is appropriate.

   TLS/DTLS OPTION DESCRIPTIONS - SERVER
       server_option() =
           {cacerts, server_cacerts()} |
           {cacertfile, server_cafile()} |
           {dh, dh_der()} |
           {dhfile, dh_file()} |
           {verify, server_verify_type()} |
           {fail_if_no_peer_cert, fail_if_no_peer_cert()} |
           {certificate_authorities, server_certificate_authorities()} |
           {reuse_sessions, server_reuse_sessions()} |
           {reuse_session, server_reuse_session()} |
           {alpn_preferred_protocols, server_alpn()} |
           {next_protocols_advertised, server_next_protocol()} |
           {psk_identity, server_psk_identity()} |
           {sni_hosts, sni_hosts()} |
           {sni_fun, sni_fun()} |
           {honor_cipher_order, honor_cipher_order()} |
           {honor_ecc_order, honor_ecc_order()} |
           {client_renegotiation, client_renegotiation()} |
           {session_tickets, server_session_tickets()} |
           {anti_replay, anti_replay()} |
           {cookie, cookie()} |
           {early_data, server_early_data()}

       server_cacerts() =
           [public_key:der_encoded()] | [public_key:combined_cert()]

              The  DER-encoded  trusted  certificates.  If  this  option is supplied it overrides
              option cacertfile.

       server_certificate_authorities() = boolean()

              Determines if a TLS-1.3 server should include  the  authorities  extension  in  its
              certificate  request  message  that  will  be  sent  if the option verify is set to
              verify_peer. Defaults to true.

              A reason to exclude the extension would be if the server wants to communicate  with
              clients  incapable  of  sending  complete  certificate  chains  that  adhere to the
              extension, but the server still has the capability to recreate a chain that it  can
              verify.

       server_cafile() = file:filename()

              Path to a file containing PEM-encoded CA certificates. The CA certificates are used
              to build the server certificate chain and for client authentication.  The  CAs  are
              also  used  in  the  list  of  acceptable  client  CAs  passed to the client when a
              certificate is requested. Can be omitted if there is no need to verify  the  client
              and if there are no intermediate CAs for the server certificate.

          Note:
              When  PEM  caching  is enabled, files provided with this option will be checked for
              updates at fixed time intervals specified by  the  ssl_pem_cache_clean  environment
              parameter.

          Note:
              Alternatively,  CA  certificates  can  be  provided  as  a  DER-encoded binary with
              server_cacerts option.

       dh_der() = binary()

              The DER-encoded  Diffie-Hellman  parameters.  If  specified,  it  overrides  option
              dhfile.

          Warning:
              The  dh_der  option  is  not  supported by TLS 1.3. Use the supported_groups option
              instead.

       dh_file() = file:filename()

              Path to a file containing PEM-encoded Diffie Hellman parameters to be used  by  the
              server  if  a  cipher suite using Diffie Hellman key exchange is negotiated. If not
              specified, default parameters are used.

          Warning:
              The dh_file option is not supported by TLS 1.3.  Use  the  supported_groups  option
              instead.

       server_verify_type() = verify_type()

              Client  certificates  are  an optional part of the TLS protocol. A server only does
              x509-certificate path validation in mode verify_peer. By default the server  is  in
              verify_none  mode an hence will not send an certificate request to the client. When
              using verify_peer you may also want to specify the options fail_if_no_peer_cert and
              certificate_authorities.

       fail_if_no_peer_cert() = boolean()

              Used together with {verify, verify_peer} by an TLS/DTLS server. If set to true, the
              server fails if the client does not have a certificate to send, that is,  sends  an
              empty  certificate.  If  set to false, it fails only if the client sends an invalid
              certificate (an empty certificate is considered valid). Defaults to false.

       server_reuse_sessions() = boolean()

              The boolean value true specifies that the server  will  agree  to  reuse  sessions.
              Setting it to false will result in an empty session table, that is no sessions will
              be reused. See also option reuse_session.

       server_reuse_session() = function()

              Enables the TLS/DTLS server to have a local policy for deciding if a session is  to
              be   reused   or   not.   Meaningful   only  if  reuse_sessions  is  set  to  true.
              SuggestedSessionId  is  a  binary(),  PeerCert  is   a   DER-encoded   certificate,
              Compression is an enumeration integer, and CipherSuite is of type ciphersuite().

       server_alpn() = [app_level_protocol()]

              Indicates  the  server  will  try to perform Application-Layer Protocol Negotiation
              (ALPN).

              The list of protocols is in order of preference. The protocol  negotiated  will  be
              the  first  in the list that matches one of the protocols advertised by the client.
              If  no  protocol  matches,  the  server   will   fail   the   connection   with   a
              "no_application_protocol" alert.

              The negotiated protocol can be retrieved using the negotiated_protocol/1 function.

       server_next_protocol() = [app_level_protocol()]

              List  of  protocols  to send to the client if the client indicates that it supports
              the Next Protocol extension. The client can select a protocol that is not  on  this
              list.  The  list  of  protocols  must  not  contain  an empty binary. If the server
              negotiates a Next Protocol, it can be accessed using the negotiated_next_protocol/1
              method.

       server_psk_identity() = psk_identity()

              Specifies the server identity hint, which the server presents to the client.

       honor_cipher_order() = boolean()

              If  set  to  true,  use the server preference for cipher selection. If set to false
              (the default), use the client preference.

       sni_hosts() =
           [{hostname(), [server_option() | common_option()]}]

              If the server receives a SNI (Server Name Indication) from the  client  matching  a
              host  listed  in  the  sni_hosts  option,  the  specific options for that host will
              override previously specified  options.  The  option  sni_fun,  and  sni_hosts  are
              mutually exclusive.

       sni_fun() = function()

              If  the  server  receives a SNI (Server Name Indication) from the client, the given
              function will be called to retrieve [server_option()]  for  the  indicated  server.
              These  options will be merged into predefined [server_option()]  list. The function
              should be defined as: fun(ServerName :: string()) -> [server_option()]  and can  be
              specified  as  a  fun  or  as  named  fun module:function/1 The option sni_fun, and
              sni_hosts are mutually exclusive.

       client_renegotiation() = boolean()

              In protocols that support client-initiated renegotiation, the cost of resources  of
              such  an  operation  is  higher  for  the server than the client. This can act as a
              vector for denial of service attacks. The SSL application already takes measures to
              counter-act  such  attempts,  but  client-initiated  renegotiation  can be strictly
              disabled by setting this option to false. The default  value  is  true.  Note  that
              disabling  renegotiation can result in long-lived connections becoming unusable due
              to limits on the number of messages the underlying cipher suite can encipher.

       honor_cipher_order() = boolean()

              If true, use the server's preference for cipher selection. If false (the  default),
              use the client's preference.

       honor_ecc_order() = boolean()

              If  true,  use  the  server's  preference  for  ECC  curve selection. If false (the
              default), use the client's preference.

       server_session_tickets() = disabled | stateful | stateless

              Configures the session ticket functionality. Allowed values are disabled,  stateful
              and stateless.

              If  it  is set to stateful or stateless, session resumption with pre-shared keys is
              enabled and the server will send stateful  or  stateless  session  tickets  to  the
              client after successful connections.

              A  stateful session ticket is a database reference to internal state information. A
              stateless  session  ticket  is  a  self-encrypted   binary   that   contains   both
              cryptographic keying material and state data.

          Note:
              This option is supported by TLS 1.3 and above. See also  SSL's Users Guide, Session
              Tickets and Session Resumption in TLS 1.3

       anti_replay() =
           '10k' | '100k' |
           {bloom_filter_window_size(),
            bloom_filter_hash_functions(),
            bloom_filter_bits()}

              Configures the server's built-in anti replay feature based on Bloom filters.

              Allowed values are the pre-defined '10k', '100k' or a custom 3-tuple  that  defines
              the  properties of the bloom filters: {WindowSize, HashFunctions, Bits}. WindowSize
              is the number of seconds after the current Bloom filter is  rotated  and  also  the
              window  size  used for freshness checks. HashFunctions is the number hash functions
              and Bits is the number of bits in the bit  vector.  '10k'  and  '100k'  are  simple
              defaults with the following properties:

                * '10k':  Bloom  filters  can  hold  10000  elements with 3% probability of false
                  positives. WindowSize: 10, HashFunctions: 5, Bits: 72985 (8.91 KiB).

                * '100k': Bloom filters can hold 100000 elements with  3%  probability  of  false
                  positives. WindowSize: 10, HashFunctions: 5, Bits: 729845 (89.09 KiB).

          Note:
              This  option  is  supported  by  TLS  1.3 and above and only with stateless session
              tickets. Ticket lifetime, the number of tickets sent by the server and the  maximum
              number  of  tickets  stored  by  the  server  in  stateful  mode  are configured by
              application variables. See also  SSL's Users Guide, Anti-Replay Protection  in  TLS
              1.3

       cookie() = boolean()

              If  true  (default),  the  server sends a cookie extension in its HelloRetryRequest
              messages.

          Note:
              The cookie extension has two main purposes. It  allows  the  server  to  force  the
              client  to  demonstrate  reachability  at  their  apparent  network  address  (thus
              providing a  measure  of  DoS  protection).  This  is  primarily  useful  for  non-
              connection-oriented transports. It also allows to offload the server's state to the
              client. The cookie extension is enabled by default as it is a  mandatory  extension
              in RFC8446.

       server_early_data() = disabled | enabled

              Configures  if the server accepts (enabled) or rejects (rejects) early data sent by
              a client. The default value is disabled.

          Warning:
              This option is a placeholder, early data is not yet implemented on the server side.

       connection_info() =
           [common_info() |
            curve_info() |
            ssl_options_info() |
            security_info()]

       common_info() =
           {protocol, protocol_version()} |
           {session_id, session_id()} |
           {session_resumption, boolean()} |
           {selected_cipher_suite, erl_cipher_suite()} |
           {sni_hostname, term()} |
           {srp_username, term()}

       curve_info() = {ecc, {named_curve, term()}}

       ssl_options_info() = tls_option()

       security_info() =
           {client_random, binary()} |
           {server_random, binary()} |
           {master_secret, binary()}

       connection_info_items() = [connection_info_item()]

       connection_info_item() =
           protocol | session_id | session_resumption |
           selected_cipher_suite | sni_hostname | srp_username | ecc |
           client_random | server_random | master_secret | keylog |
           tls_options_name()

       tls_options_name() = atom()

EXPORTS

       append_cipher_suites(Deferred, Suites) -> ciphers()

              Types:

                 Deferred = ciphers() | cipher_filters()
                 Suites = ciphers()

              Make Deferred suites become the least preferred suites, that is put them at the end
              of  the  cipher  suite  list  Suites  after  removing  them from Suites if present.
              Deferred may be a list of cipher suites or a list of  filters  in  which  case  the
              filters are use on Suites to extract the Deferred cipher list.

       cipher_suites(Description, Version) -> ciphers()

              Types:

                 Description =
                     default | all | exclusive | anonymous | exclusive_anonymous
                 Version = protocol_version()

              Lists  all  possible cipher suites corresponding to Description that are available.
              The exclusive and exclusive_anonymous option will exclusively  list  cipher  suites
              first  supported in Version whereas the other options are inclusive from the lowest
              possible version to Version.  The  all  options  includes  all  suites  except  the
              anonymous and no anonymous suites are supported by default.

          Note:
              TLS-1.3  has  no  overlapping cipher suites with previous TLS versions, that is the
              result of cipher_suites(all, 'tlsv1.3'). contains a separate set of suites that can
              be  used  with  TLS-1.3  an  other  set  that  can  be  used  if a lower version is
              negotiated. PRE TLS-1.3 so called PSK and SRP suites need  extra  configuration  to
              work see user lookup function. No anonymous suites are supported by TLS-1.3.

              Also  note  that  the cipher suites returned by this function are the cipher suites
              that the OTP ssl application can support provided that they are  supported  by  the
              cryptolib      linked      with     the     OTP     crypto     application.     Use
              ssl:filter_cipher_suites(Suites, []). to filter the list for the current cryptolib.
              Note  that  cipher  suites  may be filtered out because they are too old or too new
              depending on the cryptolib

       cipher_suites(Description, Version, StringType :: rfc | openssl) ->
                        [string()]

              Types:

                 Description = default | all | exclusive | anonymous
                 Version = protocol_version()

              Same  as  cipher_suites/2  but  lists  RFC  or  OpenSSL  string  names  instead  of
              erl_cipher_suite()

       eccs() -> NamedCurves

       eccs(Version) -> NamedCurves

              Types:

                 Version = protocol_version()
                 NamedCurves = [named_curve()]

              Returns  a  list  of supported ECCs. eccs() is equivalent to calling eccs(Protocol)
              with all supported protocols and then deduplicating the output.

       clear_pem_cache() -> ok

              PEM files, used by ssl API-functions, are cached for performance reasons. The cache
              is automatically checked at regular intervals to see if any cache entries should be
              invalidated.

              This function provides a way to unconditionally clear  the  entire  cache,  thereby
              forcing a reload of previously cached PEM files.

       connect(TCPSocket, TLSOptions) ->
                  {ok, sslsocket()} |
                  {error, reason()} |
                  {option_not_a_key_value_tuple, any()}

       connect(TCPSocket, TLSOptions, Timeout) ->
                  {ok, sslsocket()} | {error, reason()}

              Types:

                 TCPSocket = socket()
                 TLSOptions = [tls_client_option()]
                 Timeout = timeout()

              Upgrades  a  gen_tcp,  or  equivalent,  connected  socket to a TLS socket, that is,
              performs the client-side TLS handshake.

          Note:
              If the option verify is set to verify_peer the option server_name_indication  shall
              also  be  specified, if it is not no Server Name Indication extension will be sent,
              and public_key:pkix_verify_hostname/2 will be called with  the  IP-address  of  the
              connection as ReferenceID, which is probably not what you want.

              If  the  option  {handshake, hello} is used the handshake is paused after receiving
              the server hello message and the success response is {ok, SslSocket,  Ext}  instead
              of  {ok,  SslSocket}.  Thereafter the handshake is continued or canceled by calling
              handshake_continue/3 or handshake_cancel/1.

              If the option active is set to once, true or an integer value, the  process  owning
              the sslsocket will receive messages of type  active_msgs()

       connect(Host, Port, TLSOptions) ->
                  {ok, sslsocket()} |
                  {ok, sslsocket(), Ext :: protocol_extensions()} |
                  {error, reason()} |
                  {option_not_a_key_value_tuple, any()}

       connect(Host, Port, TLSOptions, Timeout) ->
                  {ok, sslsocket()} |
                  {ok, sslsocket(), Ext :: protocol_extensions()} |
                  {error, reason()} |
                  {option_not_a_key_value_tuple, any()}

              Types:

                 Host = host()
                 Port = inet:port_number()
                 TLSOptions = [tls_client_option()]
                 Timeout = timeout()

              Opens a TLS/DTLS connection to Host, Port.

              When     the     option    verify    is    set    to    verify_peer    the    check
              public_key:pkix_verify_hostname/2 will  be  performed  in  addition  to  the  usual
              x509-path   validation   checks.   If   the   check   fails  the  error  {bad_cert,
              hostname_check_failed} will be propagated to the path  validation  fun  verify_fun,
              where it is possible to do customized checks by using the full possibilities of the
              public_key:pkix_verify_hostname/3 API. When the  option  server_name_indication  is
              provided,   its   value   (the   DNS   name)   will   be  used  as  ReferenceID  to
              public_key:pkix_verify_hostname/2. When no server_name_indication option is  given,
              the  Host  argument  will  be  used  as  Server Name Indication extension. The Host
              argument will also be used for the public_key:pkix_verify_hostname/2 check  and  if
              the  Host  argument is an inet:ip_address() the ReferenceID used for the check will
              be {ip, Host} otherwise dns_id will be assumed with a fallback to ip if that fails.

          Note:
              According to good practices certificates should not  use  IP-addresses  as  "server
              names". It would be very surprising if this happened outside a closed network.

              If  the  option  {handshake, hello} is used the handshake is paused after receiving
              the server hello message and the success response is {ok, SslSocket,  Ext}  instead
              of  {ok,  SslSocket}.  Thereafter the handshake is continued or canceled by calling
              handshake_continue/3 or handshake_cancel/1.

              If the option active is set to once, true or an integer value, the  process  owning
              the sslsocket will receive messages of type  active_msgs()

       close(SslSocket) -> ok | {error, Reason}

              Types:

                 SslSocket = sslsocket()
                 Reason = any()

              Closes a TLS/DTLS connection.

       close(SslSocket, How) ->
                ok | {ok, port()} | {ok, port(), Data} | {error, Reason}

              Types:

                 SslSocket = sslsocket()
                 How = timeout() | {NewController :: pid(), timeout()}
                 Data = binary()
                 Reason = any()

              Closes  or downgrades a TLS connection. In the latter case the transport connection
              will be handed over to the NewController process  after  receiving  the  TLS  close
              alert  from the peer. The returned transport socket will have the following options
              set: [{active, false}, {packet, 0}, {mode, binary}].

              In case of downgrade, the close function might return some binary data that  should
              be treated by the user as the first bytes received on the downgraded connection.

       controlling_process(SslSocket, NewOwner) -> ok | {error, Reason}

              Types:

                 SslSocket = sslsocket()
                 NewOwner = pid()
                 Reason = any()

              Assigns  a  new controlling process to the SSL socket. A controlling process is the
              owner of an SSL socket, and receives all messages from the socket.

       connection_information(SslSocket) ->
                                 {ok, Result} | {error, reason()}

              Types:

                 SslSocket = sslsocket()
                 Result = connection_info()

              Returns the most relevant information about the connection, ssl  options  that  are
              undefined  will  be  filtered out. Note that values that affect the security of the
              connection    will    only    be    returned    if    explicitly    requested    by
              connection_information/2.

          Note:
              The  legacy  Item  = cipher_suite was removed in OTP-23. Previously it returned the
              cipher  suite  on  its  (undocumented)   legacy   format.   It   is   replaced   by
              selected_cipher_suite.

       connection_information(SslSocket, Items) ->
                                 {ok, Result} | {error, reason()}

              Types:

                 SslSocket = sslsocket()
                 Items = connection_info_items()
                 Result = connection_info()

              Returns the requested information items about the connection, if they are defined.

              Note  that  client_random,  server_random, master_secret and keylog are values that
              affect the security of connection. Meaningful atoms, not specified above,  are  the
              ssl option names.

              In order to retrieve keylog and other secret information from a TLS 1.3 connection,
              keep_secrets must be configured in advance and set to true.

          Note:
              If only undefined options are requested the resulting list can be empty.

       filter_cipher_suites(Suites, Filters) -> Ciphers

              Types:

                 Suites = ciphers()
                 Filters = cipher_filters()
                 Ciphers = ciphers()

              Removes cipher suites if any of the filter functions returns false for any part  of
              the  cipher  suite.  If  no  filter  function is supplied for some part the default
              behaviour regards it as if there was a filter  function  that  returned  true.  For
              examples  see   Customizing cipher suites  Additionally, this function also filters
              the cipher suites to exclude cipher suites not supported by the cryptolib  used  by
              the  OTP  crypto  application. That is calling ssl:filter_cipher_suites(Suites, [])
              will be equivalent to only applying the filters for cryptolib support.

       format_error(Reason :: {error, Reason}) -> string()

              Types:

                 Reason = any()

              Presents the error returned by an SSL function as a printable string.

       getopts(SslSocket, OptionNames) ->
                  {ok, [gen_tcp:option()]} | {error, reason()}

              Types:

                 SslSocket = sslsocket()
                 OptionNames = [gen_tcp:option_name()]

              Gets the values of the specified socket options.

       getstat(SslSocket) -> {ok, OptionValues} | {error, inet:posix()}

       getstat(SslSocket, Options) ->
                  {ok, OptionValues} | {error, inet:posix()}

              Types:

                 SslSocket = sslsocket()
                 Options = [inet:stat_option()]
                 OptionValues = [{inet:stat_option(), integer()}]

              Gets one or more statistic options for the underlying TCP socket.

              See inet:getstat/2 for statistic options description.

       handshake(HsSocket) ->
                    {ok, SslSocket} |
                    {ok, SslSocket, Ext} |
                    {error, Reason}

       handshake(HsSocket, Timeout) ->
                    {ok, SslSocket} |
                    {ok, SslSocket, Ext} |
                    {error, Reason}

              Types:

                 HsSocket = sslsocket()
                 Timeout = timeout()
                 SslSocket = sslsocket()
                 Ext = protocol_extensions()
                 Reason = closed | timeout | error_alert()

              Performs the TLS/DTLS server-side handshake.

              Returns a new TLS/DTLS socket if the handshake is successful.

              If the option active is set to once, true or an integer value, the  process  owning
              the sslsocket will receive messages of type  active_msgs()

          Warning:
              Not setting the timeout makes the server more vulnerable to DoS attacks.

       handshake(Socket, Options) ->
                    {ok, SslSocket} |
                    {ok, SslSocket, Ext} |
                    {error, Reason}

       handshake(Socket, Options, Timeout) ->
                    {ok, SslSocket} |
                    {ok, SslSocket, Ext} |
                    {error, Reason}

              Types:

                 Socket = socket() | sslsocket()
                 SslSocket = sslsocket()
                 Options = [server_option()]
                 Timeout = timeout()
                 Ext = protocol_extensions()
                 Reason = closed | timeout | {options, any()} | error_alert()

              If  Socket  is a ordinary socket(): upgrades a gen_tcp, or equivalent, socket to an
              SSL socket, that is, performs the TLS  server-side  handshake  and  returns  a  TLS
              socket.

          Warning:
              The  ordinary Socket shall be in passive mode ({active, false}) before calling this
              function, and before the client tries to connect with TLS, or else the behavior  of
              this  function  is undefined. The best way to ensure this is to create the ordinary
              listen socket in passive mode.

              If Socket is an  sslsocket() : provides extra TLS/DTLS options to  those  specified
              in listen/2 and then performs the TLS/DTLS handshake. Returns a new TLS/DTLS socket
              if the handshake is successful.

          Warning:
              Not setting the timeout makes the server more vulnerable to DoS attacks.

              If option {handshake, hello} is specified the handshake is paused  after  receiving
              the  client  hello message and the success response is {ok, SslSocket, Ext} instead
              of {ok, SslSocket}. Thereafter the handshake is continued or  canceled  by  calling
              handshake_continue/3 or handshake_cancel/1.

              If  the  option active is set to once, true or an integer value, the process owning
              the sslsocket will receive messages of type  active_msgs()

       handshake_cancel(Sslsocket :: #sslsocket{}) -> any()

              Cancel the handshake with a fatal USER_CANCELED alert.

       handshake_continue(HsSocket, Options) ->
                             {ok, SslSocket} | {error, Reason}

       handshake_continue(HsSocket, Options, Timeout) ->
                             {ok, SslSocket} | {error, Reason}

              Types:

                 HsSocket = sslsocket()
                 Options = [tls_client_option() | tls_server_option()]
                 Timeout = timeout()
                 SslSocket = sslsocket()
                 Reason = closed | timeout | error_alert()

              Continue the TLS handshake, possibly with new, additional or changed options.

       listen(Port, Options) -> {ok, ListenSocket} | {error, reason()}

              Types:

                 Port = inet:port_number()
                 Options = [tls_server_option()]
                 ListenSocket = sslsocket()

              Creates an SSL listen socket.

       negotiated_protocol(SslSocket) -> {ok, Protocol} | {error, Reason}

              Types:

                 SslSocket = sslsocket()
                 Protocol = binary()
                 Reason = protocol_not_negotiated

              Returns the protocol negotiated through ALPN or NPN extensions.

       peercert(SslSocket) -> {ok, Cert} | {error, reason()}

              Types:

                 SslSocket = sslsocket()
                 Cert = public_key:der_encoded()

              The peer certificate is returned as a DER-encoded binary. The  certificate  can  be
              decoded   with   public_key:pkix_decode_cert/2   Suggested  further  reading  about
              certificates is public_key User's Guide and ssl User's Guide

       peername(SslSocket) -> {ok, {Address, Port}} | {error, reason()}

              Types:

                 SslSocket = sslsocket()
                 Address = inet:ip_address()
                 Port = inet:port_number()

              Returns the address and port number of the peer.

       prepend_cipher_suites(Preferred, Suites) -> ciphers()

              Types:

                 Preferred = ciphers() | cipher_filters()
                 Suites = ciphers()

              Make Preferred suites become the most preferred suites that is put them at the head
              of  the  cipher  suite  list  Suites  after  removing  them from Suites if present.
              Preferred may be a list of cipher suites or a list of filters  in  which  case  the
              filters are use on Suites to extract the preferred cipher list.

       prf(SslSocket, Secret, Label, Seed, WantedLength) ->
              {ok, binary()} | {error, reason()}

              Types:

                 SslSocket = sslsocket()
                 Secret = binary() | master_secret
                 Label = binary()
                 Seed = [binary() | prf_random()]
                 WantedLength = integer() >= 0

              Uses  the  Pseudo-Random  Function  (PRF)  of  a  TLS session to generate extra key
              material. It either takes user-generated  values  for  Secret  and  Seed  or  atoms
              directing it to use a specific value from the session security parameters.

       recv(SslSocket, Length) -> {ok, Data} | {error, reason()}

       recv(SslSocket, Length, Timeout) -> {ok, Data} | {error, reason()}

              Types:

                 SslSocket = sslsocket()
                 Length = integer()
                 Data = binary() | list() | HttpPacket
                 Timeout = timeout()
                 HttpPacket = any()
                   See the description of HttpPacket in erlang:decode_packet/3 in ERTS.

              Receives  a  packet  from a socket in passive mode. A closed socket is indicated by
              return value {error, closed}.

              Argument Length is meaningful only when the socket is in mode raw and  denotes  the
              number of bytes to read. If Length = 0, all available bytes are returned. If Length
              > 0, exactly Length bytes are returned, or an error; possibly discarding less  than
              Length bytes of data when the socket gets closed from the other side.

              Optional  argument  Timeout specifies a time-out in milliseconds. The default value
              is infinity.

       renegotiate(SslSocket) -> ok | {error, reason()}

              Types:

                 SslSocket = sslsocket()

              Initiates   a   new   handshake.   A    notable    return    value    is    {error,
              renegotiation_rejected}  indicating  that  the  peer refused to go through with the
              renegotiation, but the connection is still active using the  previously  negotiated
              session.

       update_keys(SslSocket, Type) -> ok | {error, reason()}

              Types:

                 SslSocket = sslsocket()
                 Type = write | read_write

              There  are  cryptographic  limits  on  the  amount of plaintext which can be safely
              encrypted under a given set of keys. If the amount of data surpasses those  limits,
              a  key update is triggered and a new set of keys are installed. See also the option
              key_update_at.

              This function can be used to explicitly start a key update on a TLS 1.3 connection.
              There  are  two  types of the key update: if Type is set to write, only the writing
              key is updated; if Type is set to read_write, both the reading and writing keys are
              updated.

       send(SslSocket, Data) -> ok | {error, reason()}

              Types:

                 SslSocket = sslsocket()
                 Data = iodata()

              Writes Data to SslSocket.

              A notable return value is {error, closed} indicating that the socket is closed.

       setopts(SslSocket, Options) -> ok | {error, reason()}

              Types:

                 SslSocket = sslsocket()
                 Options = [gen_tcp:option()]

              Sets options according to Options for socket SslSocket.

       shutdown(SslSocket, How) -> ok | {error, reason()}

              Types:

                 SslSocket = sslsocket()
                 How = read | write | read_write

              Immediately closes a socket in one or two directions.

              How  ==  write  means  closing  the  socket  for  writing, reading from it is still
              possible.

              To be able to handle that the peer has done a shutdown on the  write  side,  option
              {exit_on_close, false} is useful.

       sockname(SslSocket) -> {ok, {Address, Port}} | {error, reason()}

              Types:

                 SslSocket = sslsocket()
                 Address = inet:ip_address()
                 Port = inet:port_number()

              Returns the local address and port number of socket SslSocket.

       start() -> ok | {error, reason()}

       start(Type :: permanent | transient | temporary) ->
                ok | {error, reason()}

              Starts the SSL application. Default type is temporary.

       stop() -> ok

              Stops the SSL application.

       str_to_suite(CipherSuiteName) ->
                       erl_cipher_suite() |
                       {error, {not_recognized, CipherSuiteName}}

              Types:

                 CipherSuiteName = string()

              Converts an RFC or OpenSSL name string to an erl_cipher_suite() Returns an error if
              the cipher suite is not supported or the name is not a valid cipher suite name.

       suite_to_openssl_str(CipherSuite) -> string()

              Types:

                 CipherSuite = erl_cipher_suite()

              Converts erl_cipher_suite() to OpenSSL name string.

              PRE TLS-1.3 these names differ for RFC names

       suite_to_str(CipherSuite) -> string()

              Types:

                 CipherSuite = erl_cipher_suite()

              Converts erl_cipher_suite() to RFC name string.

       transport_accept(ListenSocket) ->
                           {ok, SslSocket} | {error, reason()}

       transport_accept(ListenSocket, Timeout) ->
                           {ok, SslSocket} | {error, reason()}

              Types:

                 ListenSocket = sslsocket()
                 Timeout = timeout()
                 SslSocket = sslsocket()

              Accepts an incoming connection request on a listen socket. ListenSocket must  be  a
              socket   returned   from   listen/2.  The  socket  returned  is  to  be  passed  to
              handshake/[2,3]  to  complete  handshaking,  that  is,  establishing  the  TLS/DTLS
              connection.

          Warning:
              Most  API  functions require that the TLS/DTLS connection is established to work as
              expected.

              The accepted socket inherits the options set for ListenSocket in  listen/2.

              The default value  for  Timeout  is  infinity.  If  Timeout  is  specified  and  no
              connection is accepted within the given time, {error, timeout} is returned.

       versions() -> [VersionInfo]

              Types:

                 VersionInfo =
                     {ssl_app, string()} |
                     {supported | available | implemented, [tls_version()]} |
                     {supported_dtls | available_dtls | implemented_dtls,
                      [dtls_version()]}

              Lists  information,  mainly  concerning TLS/DTLS versions, in runtime for debugging
              and testing purposes.

                app_vsn:
                  The application version of the SSL application.

                supported:
                  TLS versions supported with current application environment and crypto  library
                  configuration.  Overridden  by a version option on  connect/[2,3,4],  listen/2,
                  and    handshake/[2,3].    For    the    negotiated    TLS     version,     see
                  connection_information/1 .

                supported_dtls:
                  DTLS versions supported with current application environment and crypto library
                  configuration. Overridden by a version option on   connect/[2,3,4],   listen/2,
                  and     handshake/[2,3].    For    the    negotiated    DTLS    version,    see
                  connection_information/1 .

                available:
                  All TLS versions supported with the linked crypto library.

                available_dtls:
                  All DTLS versions supported with the linked crypto library.

                implemented:
                  All TLS versions supported by the SSL  application  if  linked  with  a  crypto
                  library with the necessary support.

                implemented_dtls:
                  All  DTLS  versions  supported  by  the SSL application if linked with a crypto
                  library with the necessary support.

SEE ALSO

       inet(3erl) and gen_tcp(3erl) gen_udp(3erl)