Home | History | Annotate | Line # | Download | only in isc
      1 /*	$NetBSD: tls.h,v 1.5 2025/05/21 14:48:05 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
      5  *
      6  * SPDX-License-Identifier: MPL-2.0
      7  *
      8  * This Source Code Form is subject to the terms of the Mozilla Public
      9  * License, v. 2.0. If a copy of the MPL was not distributed with this
     10  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
     11  *
     12  * See the COPYRIGHT file distributed with this work for additional
     13  * information regarding copyright ownership.
     14  */
     15 
     16 #pragma once
     17 
     18 #include <isc/mem.h>
     19 #include <isc/region.h>
     20 #include <isc/result.h>
     21 #include <isc/types.h>
     22 
     23 typedef struct ssl_ctx_st isc_tlsctx_t;
     24 typedef struct ssl_st	  isc_tls_t;
     25 
     26 typedef struct x509_store_st isc_tls_cert_store_t;
     27 
     28 void
     29 isc_tlsctx_free(isc_tlsctx_t **ctpx);
     30 /*%<
     31  * Free a TLS client or server context.
     32  *
     33  * Requires:
     34  *\li	'ctxp' != NULL and '*ctxp' != NULL.
     35  */
     36 
     37 void
     38 isc_tlsctx_attach(isc_tlsctx_t *src, isc_tlsctx_t **ptarget);
     39 /*%<
     40  * Attach to the TLS context.
     41  *
     42  * Requires:
     43  *\li	'src' != NULL;
     44  *\li	'ptarget' != NULL;
     45  *\li	'*ptarget' == NULL.
     46  */
     47 
     48 isc_result_t
     49 isc_tlsctx_createserver(const char *keyfile, const char *certfile,
     50 			isc_tlsctx_t **ctxp);
     51 /*%<
     52  * Set up a TLS server context, using the key and certificate specified in
     53  * 'keyfile' and 'certfile', or a self-generated ephemeral key and
     54  * certificdate if both 'keyfile' and 'certfile' are NULL.
     55  *
     56  * Requires:
     57  *\li	'ctxp' != NULL and '*ctxp' == NULL.
     58  *\li	'keyfile' and 'certfile' are either both NULL or both non-NULL.
     59  */
     60 
     61 isc_result_t
     62 isc_tlsctx_createclient(isc_tlsctx_t **ctxp);
     63 /*%<
     64  * Set up a TLS client context.
     65  *
     66  * Requires:
     67  *\li	'ctxp' != NULL and '*ctxp' == NULL.
     68  */
     69 
     70 isc_result_t
     71 isc_tlsctx_load_certificate(isc_tlsctx_t *ctx, const char *keyfile,
     72 			    const char *certfile);
     73 /*%<
     74  * Load a TLS certificate into a TLS context.
     75  *
     76  * Requires:
     77  *\li	'ctx' != NULL;
     78  *\li	'keyfile' and 'certfile' are both non-NULL.
     79  */
     80 
     81 typedef enum isc_tls_protocol_version {
     82 	/* these must be the powers of two */
     83 	ISC_TLS_PROTO_VER_1_2 = 1 << 0,
     84 	ISC_TLS_PROTO_VER_1_3 = 1 << 1,
     85 	ISC_TLS_PROTO_VER_UNDEFINED,
     86 } isc_tls_protocol_version_t;
     87 
     88 void
     89 isc_tlsctx_set_protocols(isc_tlsctx_t *ctx, const uint32_t tls_versions);
     90 /*%<
     91  * Sets the supported TLS protocol versions via the 'tls_versions' bit
     92  * set argument (see `isc_tls_protocol_version_t` enum for the
     93  * expected values).
     94  *
     95  * Requires:
     96  *\li	'ctx' != NULL;
     97  *\li	'tls_versions' != 0.
     98  */
     99 
    100 bool
    101 isc_tls_protocol_supported(const isc_tls_protocol_version_t tls_ver);
    102 /*%<
    103  * Check in runtime that the specified TLS protocol versions is supported.
    104  */
    105 
    106 isc_tls_protocol_version_t
    107 isc_tls_protocol_name_to_version(const char *name);
    108 /*%<
    109  * Convert the protocol version string into the version of
    110  * 'isc_tls_protocol_version_t' type.
    111  * Requires:
    112  *\li	'name' != NULL.
    113  */
    114 
    115 bool
    116 isc_tlsctx_load_dhparams(isc_tlsctx_t *ctx, const char *dhparams_file);
    117 /*%<
    118  * Load Diffie-Hellman parameters file and apply it to the given TLS context
    119  * 'ctx'.
    120  *
    121  * Requires:
    122  * \li	'ctx' != NULL;
    123  * \li	'dhaprams_file' a valid pointer to a non empty string.
    124  */
    125 
    126 bool
    127 isc_tls_cipherlist_valid(const char *cipherlist);
    128 /*%<
    129  * Check if cipher list string is valid.
    130  *
    131  * Requires:
    132  * \li	'cipherlist' a valid pointer to a non empty string.
    133  */
    134 
    135 void
    136 isc_tlsctx_set_cipherlist(isc_tlsctx_t *ctx, const char *cipherlist);
    137 /*%<
    138  * Set cipher list string for on the given TLS context 'ctx'. This affects only
    139  * TLSv1.2 (and older).
    140  *
    141  * Requires:
    142  * \li	'ctx' != NULL;
    143  * \li	'cipherlist' a valid pointer to a non empty string.
    144  */
    145 
    146 bool
    147 isc_tls_cipher_suites_valid(const char *cipher_suites);
    148 /*%<
    149  * Check if cipher suites string is valid.
    150  *
    151  * Requires:
    152  * \li	'cipher_suites' a valid pointer to a non empty string.
    153  */
    154 
    155 void
    156 isc_tlsctx_set_cipher_suites(isc_tlsctx_t *ctx, const char *cipher_suites);
    157 /*%<
    158  * Set cipher suites string for on the given TLS context 'ctx'. This affects
    159  * only TLSv1.3.
    160  *
    161  * Requires:
    162  * \li	'ctx' != NULL;
    163  * \li	'cipher_suites' a valid pointer to a non empty string.
    164  */
    165 
    166 void
    167 isc_tlsctx_prefer_server_ciphers(isc_tlsctx_t *ctx, const bool prefer);
    168 /*%<
    169  * Make the given TLS context 'ctx' to prefer or to not prefer
    170  * server side ciphers during the ciphers negotiation.
    171  *
    172  * Requires:
    173  * \li	'ctx' != NULL.
    174  */
    175 
    176 void
    177 isc_tlsctx_session_tickets(isc_tlsctx_t *ctx, const bool use);
    178 /*%<
    179  * Enable/Disable stateless session resumptions tickets on the given
    180  * TLS context 'ctx' (see RFC5077).
    181  *
    182  * Requires:
    183  * \li	'ctx' != NULL.
    184  */
    185 
    186 isc_tls_t *
    187 isc_tls_create(isc_tlsctx_t *ctx);
    188 /*%<
    189  * Set up the structure to hold data for a new TLS connection.
    190  *
    191  * Requires:
    192  *\li	'ctx' != NULL.
    193  */
    194 
    195 void
    196 isc_tls_free(isc_tls_t **tlsp);
    197 /*%<
    198  * Free a TLS structure.
    199  *
    200  * Requires:
    201  *\li	'tlsp' != NULL and '*tlsp' != NULL.
    202  */
    203 
    204 const char *
    205 isc_tls_verify_peer_result_string(isc_tls_t *tls);
    206 /*%<
    207  * Return a user readable description of a remote peer's certificate
    208  * validation.
    209  *
    210  * Requires:
    211  *\li	'tls' != NULL.
    212  */
    213 
    214 #if HAVE_LIBNGHTTP2
    215 void
    216 isc_tlsctx_enable_http2client_alpn(isc_tlsctx_t *ctx);
    217 void
    218 isc_tlsctx_enable_http2server_alpn(isc_tlsctx_t *ctx);
    219 /*%<
    220  * Enable HTTP/2 Application Layer Protocol Negotation for 'ctx'.
    221  *
    222  * Requires:
    223  *\li	'ctx' is not NULL.
    224  */
    225 #endif /* HAVE_LIBNGHTTP2 */
    226 
    227 void
    228 isc_tls_get_selected_alpn(isc_tls_t *tls, const unsigned char **alpn,
    229 			  unsigned int *alpnlen);
    230 
    231 #define ISC_TLS_DOT_PROTO_ALPN_ID     "dot"
    232 #define ISC_TLS_DOT_PROTO_ALPN_ID_LEN 3
    233 
    234 void
    235 isc_tlsctx_enable_dot_client_alpn(isc_tlsctx_t *ctx);
    236 void
    237 isc_tlsctx_enable_dot_server_alpn(isc_tlsctx_t *ctx);
    238 /*%<
    239  * Enable DoT Application Layer Protocol Negotation for 'ctx'.
    240  *
    241  * Requires:
    242  *\li	'ctx' is not NULL.
    243  */
    244 
    245 isc_result_t
    246 isc_tlsctx_enable_peer_verification(isc_tlsctx_t *ctx, const bool is_server,
    247 				    isc_tls_cert_store_t *store,
    248 				    const char		 *hostname,
    249 				    bool hostname_ignore_subject);
    250 /*%<
    251  * Enable peer certificate and, optionally, hostname (for client contexts)
    252  * verification.
    253  *
    254  * Requires:
    255  *\li	'ctx' is not NULL;
    256  *\li	'store' is not NULL.
    257  */
    258 
    259 isc_result_t
    260 isc_tlsctx_load_client_ca_names(isc_tlsctx_t *ctx, const char *ca_bundle_file);
    261 /*%<
    262  * Load the list of CA-certificate names from a CA-bundle file to
    263  * send by the server to a client when requesting a peer certificate.
    264  * Usually used in conjunction with
    265  * isc_tlsctx_enable_peer_validation().
    266  *
    267  * Requires:
    268  *\li	'ctx' is not NULL;
    269  *\li	'ca_bundle_file' is not NULL.
    270  */
    271 
    272 isc_result_t
    273 isc_tls_cert_store_create(const char		*ca_bundle_filename,
    274 			  isc_tls_cert_store_t **pstore);
    275 /*%<
    276  * Create X509 certificate store. The 'ca_bundle_filename' might be
    277  * 'NULL' or an empty string, which means use the default system wide
    278  * bundle/directory.
    279  *
    280  * Requires:
    281  *\li	'pstore' is a valid pointer to a pointer containing 'NULL'.
    282  */
    283 
    284 void
    285 isc_tls_cert_store_free(isc_tls_cert_store_t **pstore);
    286 /*%<
    287  * Free X509 certificate store.
    288  *
    289  * Requires:
    290  *\li	'pstore' is a valid pointer to a pointer containing a non-'NULL' value.
    291  */
    292 
    293 typedef struct isc_tlsctx_client_session_cache isc_tlsctx_client_session_cache_t;
    294 /*%<
    295  * TLS client session cache is an object which allows efficient
    296  * storing and retrieval of previously saved TLS sessions so that they
    297  * can be resumed. This object is supposed to be a foundation for
    298  * implementing TLS session resumption - a standard technique to
    299  * reduce the cost of re-establishing a connection to the remote
    300  * server endpoint.
    301  *
    302  * OpenSSL does server-side TLS session caching transparently by
    303  * default. However, on the client-side, a TLS session to resume must
    304  * be manually specified when establishing the TLS connection. The TLS
    305  * client session cache is precisely the foundation for that.
    306  *
    307  * The cache has been designed to have the following characteristics:
    308  *
    309  * - Fixed maximal number of entries to not keep too many obsolete
    310  * sessions within the cache;
    311  *
    312  * - The cache is indexed by character string keys. Each string is a
    313  * key representing a remote endpoint (unique remote endpoint name,
    314  * e.g. combination of the remote IP address and port);
    315  *
    316  * - Least Recently Used (LRU) cache replacement policy while allowing
    317  * easy removal of obsolete entries;
    318  *
    319  * - Ability to store multiple TLS sessions associated with the given
    320  * key (remote endpoint name). This characteristic is important if
    321  * multiple connections to the same remote server can be established;
    322  *
    323  * - Ability to efficiently retrieve the most recent TLS sessions
    324  * associated with the key (remote endpoint name).
    325  *
    326  * Because of these characteristics, the cache will end up having the
    327  * necessary amount of resumable TLS session parameters to the most
    328  * used remote endpoints ("hot entries") after a short period of
    329  * initial use ("warmup").
    330  *
    331  * Attempting to resume TLS sessions is an optimisation, which is not
    332  * guaranteed to succeed because it requires the same session to be
    333  * present in the server session caches. If it is not the case, the
    334  * usual handshake procedure takes place. However, when session
    335  * resumption is successful, it reduces the amount of the
    336  * computational resources required as well as the amount of data to
    337  * be transmitted when (re)establishing the connection. Also, it
    338  * reduces round trip time (by reducing the number of packets to
    339  * transmit).
    340  *
    341  * This optimisation is important in the context of DNS because the
    342  * amount of data within the full handshake messages might be
    343  * comparable to or surpass the size of a typical DNS message.
    344  */
    345 
    346 void
    347 isc_tlsctx_client_session_cache_create(
    348 	isc_mem_t *mctx, isc_tlsctx_t *ctx, const size_t max_entries,
    349 	isc_tlsctx_client_session_cache_t **cachep);
    350 /*%<
    351  * Create a new TLS client session cache object.
    352  *
    353  * Requires:
    354  *\li	'mctx' is a valid memory context object;
    355  *\li	'ctx' is a valid TLS context object;
    356  *\li	'max_entries' is a positive number;
    357  *\li	'cachep' is a valid pointer to a pointer which must be equal to NULL.
    358  */
    359 
    360 void
    361 isc_tlsctx_client_session_cache_attach(
    362 	isc_tlsctx_client_session_cache_t  *source,
    363 	isc_tlsctx_client_session_cache_t **targetp);
    364 /*%<
    365  * Create a reference to the TLS client session cache object.
    366  *
    367  * Requires:
    368  *\li	'source' is a valid TLS client session cache object;
    369  *\li	'targetp' is a valid pointer to a pointer which must equal NULL.
    370  */
    371 
    372 void
    373 isc_tlsctx_client_session_cache_detach(
    374 	isc_tlsctx_client_session_cache_t **cachep);
    375 /*%<
    376  * Remove a reference to the TLS client session cache object.
    377  *
    378  * Requires:
    379  *\li	'cachep' is a pointer to a pointer to a valid TLS client session cache
    380  *object.
    381  */
    382 
    383 void
    384 isc_tlsctx_client_session_cache_keep(isc_tlsctx_client_session_cache_t *cache,
    385 				     char *remote_peer_name, isc_tls_t *tls);
    386 /*%<
    387  * Add a resumable TLS client session within 'tls' to the TLS client
    388  * session cache object 'cache' and associate it with
    389  * 'remote_server_name' string. Also, the oldest entry from the cache
    390  * might get removed if the cache is full.
    391  *
    392  * Requires:
    393  *\li	'cache' is a pointer to a valid TLS client session cache object;
    394  *\li	'remote_peer_name' is a pointer to a non empty character string;
    395  *\li	'tls' is a valid, non-'NULL' pointer to a TLS connection state object.
    396  */
    397 
    398 void
    399 isc_tlsctx_client_session_cache_keep_sockaddr(
    400 	isc_tlsctx_client_session_cache_t *cache, isc_sockaddr_t *remote_peer,
    401 	isc_tls_t *tls);
    402 /*%<
    403  * The same as 'isc_tlsctx_client_session_cache_keep()', but uses a
    404  * 'isc_sockaddr_t' as a key, instead of a character string.
    405  *
    406  * Requires:
    407  *\li	'remote_peer' is a valid, non-'NULL', pointer to an 'isc_sockaddr_t'
    408  *object.
    409  */
    410 
    411 void
    412 isc_tlsctx_client_session_cache_reuse(isc_tlsctx_client_session_cache_t *cache,
    413 				      char *remote_server_name, isc_tls_t *tls);
    414 /*%
    415  * Try to restore a previously stored TLS session denoted by a remote
    416  * server name as a key ('remote_server_name') into the given TLS
    417  * connection state object ('tls'). The successfully restored session
    418  * gets removed from the cache.
    419  *
    420  * Requires:
    421  *\li	'cache' is a pointer to a valid TLS client session cache object;
    422  *\li	'remote_peer_name' is a pointer to a non empty character string;
    423  *\li	'tls' is a valid, non-'NULL' pointer to a TLS connection state object.
    424  */
    425 
    426 void
    427 isc_tlsctx_client_session_cache_reuse_sockaddr(
    428 	isc_tlsctx_client_session_cache_t *cache, isc_sockaddr_t *remote_peer,
    429 	isc_tls_t *tls);
    430 /*%<
    431  * The same as 'isc_tlsctx_client_session_cache_reuse()', but uses a
    432  * 'isc_sockaddr_t' as a key, instead of a character string.
    433  *
    434  * Requires:
    435  *\li	'remote_peer' is a valid, non-'NULL' pointer to an 'isc_sockaddr_t'
    436  *object.
    437  */
    438 
    439 const isc_tlsctx_t *
    440 isc_tlsctx_client_session_cache_getctx(isc_tlsctx_client_session_cache_t *cache);
    441 /*%<
    442  * Returns a TLS context associated with the given TLS client
    443  * session cache object. The function is intended to be used to
    444  * implement the sanity checks ('INSIST()'s and 'REQUIRE()'s).
    445  *
    446  * Requires:
    447  *\li	'cache' is a pointer to a valid TLS client session cache object.
    448  */
    449 
    450 #define ISC_TLSCTX_CLIENT_SESSION_CACHE_DEFAULT_SIZE (150)
    451 /*%<
    452  * The default maximum size of a TLS client session cache. The value
    453  * should be large enough to hold enough sessions to successfully
    454  * re-establish connections to the most remote TLS servers, but not
    455  * too big to avoid keeping too much obsolete sessions.
    456  */
    457 
    458 typedef struct isc_tlsctx_cache isc_tlsctx_cache_t;
    459 /*%<
    460  * The TLS context cache is an object which allows retrieving a
    461  * previously created TLS context based on the following tuple:
    462  *
    463  * 1. The name of a TLS entry, as defined in the configuration file;
    464  * 2. A transport type. Currently, only TLS (DoT) and HTTPS (DoH) are
    465  *    supported;
    466  * 3. An IP address family (AF_INET or AF_INET6).
    467  *
    468  * There are multiple uses for this object:
    469  *
    470  * First, it allows reuse of client-side contexts during zone transfers.
    471  * That, in turn, allows use of session caches associated with these
    472  * contexts, which enables TLS session resumption, making establishment
    473  * of XoT connections faster and computationally cheaper.
    474  *
    475  * Second, it can be extended to be used as storage for TLS context related
    476  * data, as defined in 'tls' statements in the configuration file (for
    477  * example, CA-bundle intermediate certificate storage, client-side contexts
    478  * with pre-loaded certificates in a case of Mutual TLS, etc). This will
    479  * be used to implement Strict/Mutual TLS.
    480  *
    481  * Third, it avoids creating an excessive number of server-side TLS
    482  * contexts, which might help to reduce the number of contexts
    483  * created during server initialisation and reconfiguration.
    484  */
    485 
    486 typedef enum {
    487 	isc_tlsctx_cache_none = 0,
    488 	isc_tlsctx_cache_tls,
    489 	isc_tlsctx_cache_https,
    490 	isc_tlsctx_cache_count
    491 } isc_tlsctx_cache_transport_t;
    492 /*%< TLS context cache transport type values. */
    493 
    494 void
    495 isc_tlsctx_cache_create(isc_mem_t *mctx, isc_tlsctx_cache_t **cachep);
    496 /*%<
    497  * Create a new TLS context cache object.
    498  *
    499  * Requires:
    500  *\li	'mctx' is a valid memory context;
    501  *\li	'cachep' is a valid pointer to a pointer which must be equal to NULL.
    502  */
    503 
    504 void
    505 isc_tlsctx_cache_attach(isc_tlsctx_cache_t  *source,
    506 			isc_tlsctx_cache_t **targetp);
    507 /*%<
    508  * Create a reference to the TLS context cache object.
    509  *
    510  * Requires:
    511  *\li	'source' is a valid TLS context cache object;
    512  *\li	'targetp' is a valid pointer to a pointer which must equal NULL.
    513  */
    514 
    515 void
    516 isc_tlsctx_cache_detach(isc_tlsctx_cache_t **cachep);
    517 /*%<
    518  * Remove a reference to the TLS context cache object.
    519  *
    520  * Requires:
    521  *\li	'cachep' is a pointer to a pointer to a valid TLS
    522  *	 context cache object.
    523  */
    524 
    525 isc_result_t
    526 isc_tlsctx_cache_add(
    527 	isc_tlsctx_cache_t *cache, const char *name,
    528 	const isc_tlsctx_cache_transport_t transport, const uint16_t family,
    529 	isc_tlsctx_t *ctx, isc_tls_cert_store_t *store,
    530 	isc_tlsctx_client_session_cache_t *client_sess_cache,
    531 	isc_tlsctx_t **pfound, isc_tls_cert_store_t **pfound_store,
    532 	isc_tlsctx_client_session_cache_t **pfound_client_sess_cache);
    533 /*%<
    534  *
    535  * Add a new TLS context and its associated data to the TLS context
    536  * cache. 'pfound' is an optional pointer, which can be used to
    537  * retrieve an already existing TLS context object in a case it
    538  * exists.
    539  *
    540  * The passed certificates store object ('store') possession is
    541  * transferred to the cache object in a case of success. In some cases
    542  * it might be destroyed immediately upon the call completion.
    543  *
    544  * The possession of the passed TLS client session cache
    545  * ('client_sess_cache') is also transferred to the cache object in a
    546  * case of success.
    547  *
    548  * Requires:
    549  *\li	'cache' is a valid pointer to a TLS context cache object;
    550  *\li	'name' is a valid pointer to a non-empty string;
    551  *\li	'transport' is a valid transport identifier (currently only
    552  *       TLS/DoT and HTTPS/DoH are supported);
    553  *\li	'family' - either 'AF_INET' or 'AF_INET6';
    554  *\li   'ctx' - a valid pointer to a valid TLS context object;
    555  *\li   'store' - a valid pointer to a valid TLS certificates store object or
    556  *		'NULL';
    557  *\li   'client_sess_cache' - a valid pointer to a valid TLS client sessions
    558  *cache object or 'NULL.
    559  *
    560  * Returns:
    561  *\li	#ISC_R_EXISTS - node of the same key already exists;
    562  *\li	#ISC_R_SUCCESS - the new entry has been added successfully.
    563  */
    564 
    565 isc_result_t
    566 isc_tlsctx_cache_find(
    567 	isc_tlsctx_cache_t *cache, const char *name,
    568 	const isc_tlsctx_cache_transport_t transport, const uint16_t family,
    569 	isc_tlsctx_t **pctx, isc_tls_cert_store_t **pstore,
    570 	isc_tlsctx_client_session_cache_t **pfound_client_sess_cache);
    571 /*%<
    572  * Look up a TLS context and its associated data in the TLS context cache.
    573  *
    574  * Requires:
    575  *\li	'cache' is a valid pointer to a TLS context cache object;
    576  *\li	'name' is a valid pointer to a non empty string;
    577  *\li	'transport' - a valid transport identifier (currently only
    578  *       TLS/DoT and HTTPS/DoH are supported;
    579  *\li	'family' - either 'AF_INET' or 'AF_INET6';
    580  *\li   'pctx' - a valid pointer to a non-NULL pointer;
    581  *\li   'pstore' - a valid pointer to a non-NULL pointer or 'NULL'.
    582  *\li   'pfound_client_sess_cache' - a valid pointer to a non-NULL pointer or
    583  *'NULL'.
    584  *
    585  * Returns:
    586  *\li	#ISC_R_SUCCESS - the context has been found;
    587  *\li	#ISC_R_NOTFOUND	- the context has not been found. In such a case,
    588  *		'pstore' still might get initialised as there is one to many
    589  *		relation between stores and contexts.
    590  */
    591 
    592 void
    593 isc_tlsctx_set_random_session_id_context(isc_tlsctx_t *ctx);
    594 /*%<
    595  * Set context within which session can be reused to a randomly
    596  * generated value. This one is used for TLS session resumption using
    597  * session IDs. See OpenSSL documentation for
    598  * 'SSL_CTX_set_session_id_context()'.
    599  *
    600  * It might be worth noting that usually session ID contexts are kept
    601  * static for an application and particular certificate
    602  * combination. However, for the cases when exporting server side TLS
    603  * session cache to/loading from external memory is not required, we
    604  * might use random IDs just fine. See,
    605  * e.g. 'ngx_ssl_session_id_context()' in NGINX for an example of how
    606  * a session ID might be obtained.
    607  *
    608  * Requires:
    609  *\li   'ctx' - a valid non-NULL pointer;
    610  */
    611 
    612 bool
    613 isc_tls_valid_sni_hostname(const char *hostname);
    614 /*%<
    615  * Checks if a 'hostname' is not a valid IPv4 or IPv6 address
    616  * string. Returns 'true' if the hostname is likely a domain name, and
    617  * 'false' if it represents an IP address.
    618  */
    619 
    620 void
    621 isc__tls_initialize(void);
    622 
    623 void
    624 isc__tls_shutdown(void);
    625 
    626 void
    627 isc__tls_setdestroycheck(bool check);
    628