xref: /netbsd-src/external/mpl/bind/dist/lib/isc/tls.c (revision bcda20f65a8566e103791ec395f7f499ef322704)
1 /*	$NetBSD: tls.c,v 1.6 2025/01/26 16:25:39 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 #include <inttypes.h>
17 #include <netinet/in.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <sys/socket.h>
21 #if HAVE_LIBNGHTTP2
22 #include <nghttp2/nghttp2.h>
23 #endif /* HAVE_LIBNGHTTP2 */
24 #include <arpa/inet.h>
25 
26 #include <openssl/bn.h>
27 #include <openssl/conf.h>
28 #include <openssl/crypto.h>
29 #include <openssl/dh.h>
30 #include <openssl/err.h>
31 #include <openssl/evp.h>
32 #include <openssl/opensslv.h>
33 #include <openssl/rand.h>
34 #include <openssl/rsa.h>
35 #include <openssl/x509_vfy.h>
36 #include <openssl/x509v3.h>
37 
38 #include <isc/atomic.h>
39 #include <isc/ht.h>
40 #include <isc/log.h>
41 #include <isc/magic.h>
42 #include <isc/mem.h>
43 #include <isc/mutex.h>
44 #include <isc/mutexblock.h>
45 #include <isc/once.h>
46 #include <isc/random.h>
47 #include <isc/refcount.h>
48 #include <isc/rwlock.h>
49 #include <isc/sockaddr.h>
50 #include <isc/thread.h>
51 #include <isc/tls.h>
52 #include <isc/util.h>
53 
54 #include "openssl_shim.h"
55 
56 #define COMMON_SSL_OPTIONS \
57 	(SSL_OP_NO_COMPRESSION | SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION)
58 
59 static isc_mem_t *isc__tls_mctx = NULL;
60 
61 #if OPENSSL_VERSION_NUMBER < 0x10100000L
62 static isc_mutex_t *locks = NULL;
63 static int nlocks;
64 
65 static void
66 isc__tls_lock_callback(int mode, int type, const char *file, int line) {
67 	UNUSED(file);
68 	UNUSED(line);
69 	if ((mode & CRYPTO_LOCK) != 0) {
70 		LOCK(&locks[type]);
71 	} else {
72 		UNLOCK(&locks[type]);
73 	}
74 }
75 
76 static void
77 isc__tls_set_thread_id(CRYPTO_THREADID *id) {
78 	CRYPTO_THREADID_set_numeric(id, (unsigned long)isc_thread_self());
79 }
80 #endif
81 
82 #if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x30000000L
83 /*
84  * This was crippled with LibreSSL, so just skip it:
85  * https://cvsweb.openbsd.org/src/lib/libcrypto/Attic/mem.c
86  */
87 
88 #if ISC_MEM_TRACKLINES
89 /*
90  * We use the internal isc__mem API here, so we can pass the file and line
91  * arguments passed from OpenSSL >= 1.1.0 to our memory functions for better
92  * tracking of the OpenSSL allocations.  Without this, we would always just see
93  * isc__tls_{malloc,realloc,free} in the tracking output, but with this in place
94  * we get to see the places in the OpenSSL code where the allocations happen.
95  */
96 
97 static void *
98 isc__tls_malloc_ex(size_t size, const char *file, int line) {
99 	return isc__mem_allocate(isc__tls_mctx, size, 0, file,
100 				 (unsigned int)line);
101 }
102 
103 static void *
104 isc__tls_realloc_ex(void *ptr, size_t size, const char *file, int line) {
105 	return isc__mem_reallocate(isc__tls_mctx, ptr, size, 0, file,
106 				   (unsigned int)line);
107 }
108 
109 static void
110 isc__tls_free_ex(void *ptr, const char *file, int line) {
111 	if (ptr == NULL) {
112 		return;
113 	}
114 	if (isc__tls_mctx != NULL) {
115 		isc__mem_free(isc__tls_mctx, ptr, 0, file, (unsigned int)line);
116 	}
117 }
118 
119 #else /* ISC_MEM_TRACKLINES */
120 
121 static void *
122 isc__tls_malloc_ex(size_t size, const char *file, int line) {
123 	UNUSED(file);
124 	UNUSED(line);
125 	return isc_mem_allocate(isc__tls_mctx, size);
126 }
127 
128 static void *
129 isc__tls_realloc_ex(void *ptr, size_t size, const char *file, int line) {
130 	UNUSED(file);
131 	UNUSED(line);
132 	return isc_mem_reallocate(isc__tls_mctx, ptr, size);
133 }
134 
135 static void
136 isc__tls_free_ex(void *ptr, const char *file, int line) {
137 	UNUSED(file);
138 	UNUSED(line);
139 	if (ptr == NULL) {
140 		return;
141 	}
142 	if (isc__tls_mctx != NULL) {
143 		isc__mem_free(isc__tls_mctx, ptr, 0);
144 	}
145 }
146 
147 #endif /* ISC_MEM_TRACKLINES */
148 
149 #endif /* !defined(LIBRESSL_VERSION_NUMBER) */
150 
151 void
152 isc__tls_initialize(void) {
153 	isc_mem_create(&isc__tls_mctx);
154 	isc_mem_setname(isc__tls_mctx, "OpenSSL");
155 	isc_mem_setdestroycheck(isc__tls_mctx, false);
156 
157 #if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x30000000L
158 	/*
159 	 * CRYPTO_set_mem_(_ex)_functions() returns 1 on success or 0 on
160 	 * failure, which means OpenSSL already allocated some memory.  There's
161 	 * nothing we can do about it.
162 	 */
163 	(void)CRYPTO_set_mem_functions(isc__tls_malloc_ex, isc__tls_realloc_ex,
164 				       isc__tls_free_ex);
165 #endif /* !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= \
166 	  0x30000000L  */
167 
168 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
169 	uint64_t opts = OPENSSL_INIT_ENGINE_ALL_BUILTIN |
170 			OPENSSL_INIT_LOAD_CONFIG;
171 #if defined(OPENSSL_INIT_NO_ATEXIT)
172 	/*
173 	 * We call OPENSSL_cleanup() manually, in a correct order, thus disable
174 	 * the automatic atexit() handler.
175 	 */
176 	opts |= OPENSSL_INIT_NO_ATEXIT;
177 #endif
178 
179 	RUNTIME_CHECK(OPENSSL_init_ssl(opts, NULL) == 1);
180 #else
181 	nlocks = CRYPTO_num_locks();
182 	locks = isc_mem_cget(isc__tls_mctx, nlocks, sizeof(locks[0]));
183 	isc_mutexblock_init(locks, nlocks);
184 	CRYPTO_set_locking_callback(isc__tls_lock_callback);
185 	CRYPTO_THREADID_set_callback(isc__tls_set_thread_id);
186 
187 	CRYPTO_malloc_init();
188 	ERR_load_crypto_strings();
189 	SSL_load_error_strings();
190 	SSL_library_init();
191 
192 #if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000
193 	ENGINE_load_builtin_engines();
194 #endif
195 	OpenSSL_add_all_algorithms();
196 	OPENSSL_load_builtin_modules();
197 
198 	CONF_modules_load_file(NULL, NULL,
199 			       CONF_MFLAGS_DEFAULT_SECTION |
200 				       CONF_MFLAGS_IGNORE_MISSING_FILE);
201 #endif
202 
203 	/* Protect ourselves against unseeded PRNG */
204 	if (RAND_status() != 1) {
205 		FATAL_ERROR("OpenSSL pseudorandom number generator "
206 			    "cannot be initialized (see the `PRNG not "
207 			    "seeded' message in the OpenSSL FAQ)");
208 	}
209 }
210 
211 void
212 isc__tls_shutdown(void) {
213 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
214 	OPENSSL_cleanup();
215 #else
216 	CONF_modules_unload(1);
217 	OBJ_cleanup();
218 	EVP_cleanup();
219 #if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000
220 	ENGINE_cleanup();
221 #endif
222 	CRYPTO_cleanup_all_ex_data();
223 	ERR_remove_thread_state(NULL);
224 	RAND_cleanup();
225 	ERR_free_strings();
226 
227 	CRYPTO_set_locking_callback(NULL);
228 
229 	if (locks != NULL) {
230 		isc_mutexblock_destroy(locks, nlocks);
231 		isc_mem_cput(isc__tls_mctx, locks, nlocks, sizeof(locks[0]));
232 		locks = NULL;
233 	}
234 #endif
235 
236 	isc_mem_destroy(&isc__tls_mctx);
237 }
238 
239 void
240 isc__tls_setdestroycheck(bool check) {
241 	isc_mem_setdestroycheck(isc__tls_mctx, check);
242 }
243 
244 void
245 isc_tlsctx_free(isc_tlsctx_t **ctxp) {
246 	SSL_CTX *ctx = NULL;
247 	REQUIRE(ctxp != NULL && *ctxp != NULL);
248 
249 	ctx = *ctxp;
250 	*ctxp = NULL;
251 
252 	SSL_CTX_free(ctx);
253 }
254 
255 void
256 isc_tlsctx_attach(isc_tlsctx_t *src, isc_tlsctx_t **ptarget) {
257 	REQUIRE(src != NULL);
258 	REQUIRE(ptarget != NULL && *ptarget == NULL);
259 
260 	RUNTIME_CHECK(SSL_CTX_up_ref(src) == 1);
261 
262 	*ptarget = src;
263 }
264 
265 #if HAVE_SSL_CTX_SET_KEYLOG_CALLBACK
266 /*
267  * Callback invoked by the SSL library whenever a new TLS pre-master secret
268  * needs to be logged.
269  */
270 static void
271 sslkeylogfile_append(const SSL *ssl, const char *line) {
272 	UNUSED(ssl);
273 
274 	isc_log_write(isc_lctx, ISC_LOGCATEGORY_SSLKEYLOG, ISC_LOGMODULE_NETMGR,
275 		      ISC_LOG_INFO, "%s", line);
276 }
277 
278 /*
279  * Enable TLS pre-master secret logging if the SSLKEYLOGFILE environment
280  * variable is set.  This needs to be done on a per-context basis as that is
281  * how SSL_CTX_set_keylog_callback() works.
282  */
283 static void
284 sslkeylogfile_init(isc_tlsctx_t *ctx) {
285 	if (getenv("SSLKEYLOGFILE") != NULL) {
286 		SSL_CTX_set_keylog_callback(ctx, sslkeylogfile_append);
287 	}
288 }
289 #else /* HAVE_SSL_CTX_SET_KEYLOG_CALLBACK */
290 #define sslkeylogfile_init(ctx)
291 #endif /* HAVE_SSL_CTX_SET_KEYLOG_CALLBACK */
292 
293 isc_result_t
294 isc_tlsctx_createclient(isc_tlsctx_t **ctxp) {
295 	unsigned long err;
296 	char errbuf[256];
297 	SSL_CTX *ctx = NULL;
298 	const SSL_METHOD *method = NULL;
299 
300 	REQUIRE(ctxp != NULL && *ctxp == NULL);
301 
302 	method = TLS_client_method();
303 	if (method == NULL) {
304 		goto ssl_error;
305 	}
306 	ctx = SSL_CTX_new(method);
307 	if (ctx == NULL) {
308 		goto ssl_error;
309 	}
310 
311 	SSL_CTX_set_options(ctx, COMMON_SSL_OPTIONS);
312 
313 #if HAVE_SSL_CTX_SET_MIN_PROTO_VERSION
314 	SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
315 #else
316 	SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
317 					 SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1);
318 #endif
319 
320 	sslkeylogfile_init(ctx);
321 
322 	*ctxp = ctx;
323 
324 	return ISC_R_SUCCESS;
325 
326 ssl_error:
327 	err = ERR_get_error();
328 	ERR_error_string_n(err, errbuf, sizeof(errbuf));
329 	isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_NETMGR,
330 		      ISC_LOG_ERROR, "Error initializing TLS context: %s",
331 		      errbuf);
332 
333 	return ISC_R_TLSERROR;
334 }
335 
336 isc_result_t
337 isc_tlsctx_load_certificate(isc_tlsctx_t *ctx, const char *keyfile,
338 			    const char *certfile) {
339 	int rv;
340 	REQUIRE(ctx != NULL);
341 	REQUIRE(keyfile != NULL);
342 	REQUIRE(certfile != NULL);
343 
344 	rv = SSL_CTX_use_certificate_chain_file(ctx, certfile);
345 	if (rv != 1) {
346 		unsigned long err = ERR_peek_last_error();
347 		char errbuf[1024] = { 0 };
348 		ERR_error_string_n(err, errbuf, sizeof(errbuf));
349 		isc_log_write(
350 			isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_NETMGR,
351 			ISC_LOG_ERROR,
352 			"SSL_CTX_use_certificate_chain_file: '%s' failed: %s",
353 			certfile, errbuf);
354 		return ISC_R_TLSERROR;
355 	}
356 	rv = SSL_CTX_use_PrivateKey_file(ctx, keyfile, SSL_FILETYPE_PEM);
357 	if (rv != 1) {
358 		unsigned long err = ERR_peek_last_error();
359 		char errbuf[1024] = { 0 };
360 		ERR_error_string_n(err, errbuf, sizeof(errbuf));
361 		isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
362 			      ISC_LOGMODULE_NETMGR, ISC_LOG_ERROR,
363 			      "SSL_CTX_use_PrivateKey_file: '%s' failed: %s",
364 			      keyfile, errbuf);
365 		return ISC_R_TLSERROR;
366 	}
367 
368 	return ISC_R_SUCCESS;
369 }
370 
371 isc_result_t
372 isc_tlsctx_createserver(const char *keyfile, const char *certfile,
373 			isc_tlsctx_t **ctxp) {
374 	int rv;
375 	unsigned long err;
376 	bool ephemeral = (keyfile == NULL && certfile == NULL);
377 	X509 *cert = NULL;
378 	EVP_PKEY *pkey = NULL;
379 	SSL_CTX *ctx = NULL;
380 #if OPENSSL_VERSION_NUMBER < 0x30000000L
381 	EC_KEY *eckey = NULL;
382 #else
383 	EVP_PKEY_CTX *pkey_ctx = NULL;
384 	EVP_PKEY *params_pkey = NULL;
385 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */
386 	char errbuf[256];
387 	const SSL_METHOD *method = NULL;
388 
389 	REQUIRE(ctxp != NULL && *ctxp == NULL);
390 	REQUIRE((keyfile == NULL) == (certfile == NULL));
391 
392 	method = TLS_server_method();
393 	if (method == NULL) {
394 		goto ssl_error;
395 	}
396 	ctx = SSL_CTX_new(method);
397 	if (ctx == NULL) {
398 		goto ssl_error;
399 	}
400 	RUNTIME_CHECK(ctx != NULL);
401 
402 	SSL_CTX_set_options(ctx, COMMON_SSL_OPTIONS);
403 
404 #if HAVE_SSL_CTX_SET_MIN_PROTO_VERSION
405 	SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
406 #else
407 	SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
408 					 SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1);
409 #endif
410 
411 	if (ephemeral) {
412 		const int group_nid = NID_X9_62_prime256v1;
413 
414 #if OPENSSL_VERSION_NUMBER < 0x30000000L
415 		eckey = EC_KEY_new_by_curve_name(group_nid);
416 		if (eckey == NULL) {
417 			goto ssl_error;
418 		}
419 
420 		/* Generate the key. */
421 		rv = EC_KEY_generate_key(eckey);
422 		if (rv != 1) {
423 			goto ssl_error;
424 		}
425 		pkey = EVP_PKEY_new();
426 		if (pkey == NULL) {
427 			goto ssl_error;
428 		}
429 		rv = EVP_PKEY_set1_EC_KEY(pkey, eckey);
430 		if (rv != 1) {
431 			goto ssl_error;
432 		}
433 
434 		/* Use a named curve and uncompressed point conversion form. */
435 #if HAVE_EVP_PKEY_GET0_EC_KEY
436 		EC_KEY_set_asn1_flag(EVP_PKEY_get0_EC_KEY(pkey),
437 				     OPENSSL_EC_NAMED_CURVE);
438 		EC_KEY_set_conv_form(EVP_PKEY_get0_EC_KEY(pkey),
439 				     POINT_CONVERSION_UNCOMPRESSED);
440 #else
441 		EC_KEY_set_asn1_flag(pkey->pkey.ec, OPENSSL_EC_NAMED_CURVE);
442 		EC_KEY_set_conv_form(pkey->pkey.ec,
443 				     POINT_CONVERSION_UNCOMPRESSED);
444 #endif /* HAVE_EVP_PKEY_GET0_EC_KEY */
445 
446 #if defined(SSL_CTX_set_ecdh_auto)
447 		/*
448 		 * Using this macro is required for older versions of OpenSSL to
449 		 * automatically enable ECDH support.
450 		 *
451 		 * On later versions this function is no longer needed and is
452 		 * deprecated.
453 		 */
454 		(void)SSL_CTX_set_ecdh_auto(ctx, 1);
455 #endif /* defined(SSL_CTX_set_ecdh_auto) */
456 
457 		/* Cleanup */
458 		EC_KEY_free(eckey);
459 		eckey = NULL;
460 #else
461 		/* Generate the key's parameters. */
462 		pkey_ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL);
463 		if (pkey_ctx == NULL) {
464 			goto ssl_error;
465 		}
466 		rv = EVP_PKEY_paramgen_init(pkey_ctx);
467 		if (rv != 1) {
468 			goto ssl_error;
469 		}
470 		rv = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pkey_ctx,
471 							    group_nid);
472 		if (rv != 1) {
473 			goto ssl_error;
474 		}
475 		rv = EVP_PKEY_paramgen(pkey_ctx, &params_pkey);
476 		if (rv != 1 || params_pkey == NULL) {
477 			goto ssl_error;
478 		}
479 		EVP_PKEY_CTX_free(pkey_ctx);
480 
481 		/* Generate the key. */
482 		pkey_ctx = EVP_PKEY_CTX_new(params_pkey, NULL);
483 		if (pkey_ctx == NULL) {
484 			goto ssl_error;
485 		}
486 		rv = EVP_PKEY_keygen_init(pkey_ctx);
487 		if (rv != 1) {
488 			goto ssl_error;
489 		}
490 		rv = EVP_PKEY_keygen(pkey_ctx, &pkey);
491 		if (rv != 1 || pkey == NULL) {
492 			goto ssl_error;
493 		}
494 
495 		/* Cleanup */
496 		EVP_PKEY_free(params_pkey);
497 		params_pkey = NULL;
498 		EVP_PKEY_CTX_free(pkey_ctx);
499 		pkey_ctx = NULL;
500 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */
501 
502 		cert = X509_new();
503 		if (cert == NULL) {
504 			goto ssl_error;
505 		}
506 
507 		ASN1_INTEGER_set(X509_get_serialNumber(cert),
508 				 (long)isc_random32());
509 
510 		/*
511 		 * Set the "not before" property 5 minutes into the past to
512 		 * accommodate with some possible clock skew across systems.
513 		 */
514 #if OPENSSL_VERSION_NUMBER < 0x10101000L
515 		X509_gmtime_adj(X509_get_notBefore(cert), -300);
516 #else
517 		X509_gmtime_adj(X509_getm_notBefore(cert), -300);
518 #endif
519 
520 		/*
521 		 * We set the vailidy for 10 years.
522 		 */
523 #if OPENSSL_VERSION_NUMBER < 0x10101000L
524 		X509_gmtime_adj(X509_get_notAfter(cert), 3650 * 24 * 3600);
525 #else
526 		X509_gmtime_adj(X509_getm_notAfter(cert), 3650 * 24 * 3600);
527 #endif
528 
529 		X509_set_pubkey(cert, pkey);
530 
531 		X509_NAME *name = X509_get_subject_name(cert);
532 
533 		X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC,
534 					   (const unsigned char *)"AQ", -1, -1,
535 					   0);
536 		X509_NAME_add_entry_by_txt(
537 			name, "O", MBSTRING_ASC,
538 			(const unsigned char *)"BIND9 ephemeral "
539 					       "certificate",
540 			-1, -1, 0);
541 		X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
542 					   (const unsigned char *)"bind9.local",
543 					   -1, -1, 0);
544 
545 		X509_set_issuer_name(cert, name);
546 		X509_sign(cert, pkey, EVP_sha256());
547 		rv = SSL_CTX_use_certificate(ctx, cert);
548 		if (rv != 1) {
549 			goto ssl_error;
550 		}
551 		rv = SSL_CTX_use_PrivateKey(ctx, pkey);
552 		if (rv != 1) {
553 			goto ssl_error;
554 		}
555 
556 		X509_free(cert);
557 		EVP_PKEY_free(pkey);
558 	} else {
559 		isc_result_t result;
560 		result = isc_tlsctx_load_certificate(ctx, keyfile, certfile);
561 		if (result != ISC_R_SUCCESS) {
562 			goto ssl_error;
563 		}
564 	}
565 
566 	sslkeylogfile_init(ctx);
567 
568 	*ctxp = ctx;
569 	return ISC_R_SUCCESS;
570 
571 ssl_error:
572 	err = ERR_get_error();
573 	ERR_error_string_n(err, errbuf, sizeof(errbuf));
574 	isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_NETMGR,
575 		      ISC_LOG_ERROR, "Error initializing TLS context: %s",
576 		      errbuf);
577 
578 	if (ctx != NULL) {
579 		SSL_CTX_free(ctx);
580 	}
581 	if (cert != NULL) {
582 		X509_free(cert);
583 	}
584 	if (pkey != NULL) {
585 		EVP_PKEY_free(pkey);
586 	}
587 #if OPENSSL_VERSION_NUMBER < 0x30000000L
588 	if (eckey != NULL) {
589 		EC_KEY_free(eckey);
590 	}
591 #else
592 	if (params_pkey != NULL) {
593 		EVP_PKEY_free(params_pkey);
594 	}
595 	if (pkey_ctx != NULL) {
596 		EVP_PKEY_CTX_free(pkey_ctx);
597 	}
598 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */
599 
600 	return ISC_R_TLSERROR;
601 }
602 
603 static long
604 get_tls_version_disable_bit(const isc_tls_protocol_version_t tls_ver) {
605 	long bit = 0;
606 
607 	switch (tls_ver) {
608 	case ISC_TLS_PROTO_VER_1_2:
609 #ifdef SSL_OP_NO_TLSv1_2
610 		bit = SSL_OP_NO_TLSv1_2;
611 #else
612 		bit = 0;
613 #endif
614 		break;
615 	case ISC_TLS_PROTO_VER_1_3:
616 #ifdef SSL_OP_NO_TLSv1_3
617 		bit = SSL_OP_NO_TLSv1_3;
618 #else
619 		bit = 0;
620 #endif
621 		break;
622 	default:
623 		UNREACHABLE();
624 		break;
625 	};
626 
627 	return bit;
628 }
629 
630 bool
631 isc_tls_protocol_supported(const isc_tls_protocol_version_t tls_ver) {
632 	return get_tls_version_disable_bit(tls_ver) != 0;
633 }
634 
635 isc_tls_protocol_version_t
636 isc_tls_protocol_name_to_version(const char *name) {
637 	REQUIRE(name != NULL);
638 
639 	if (strcasecmp(name, "TLSv1.2") == 0) {
640 		return ISC_TLS_PROTO_VER_1_2;
641 	} else if (strcasecmp(name, "TLSv1.3") == 0) {
642 		return ISC_TLS_PROTO_VER_1_3;
643 	}
644 
645 	return ISC_TLS_PROTO_VER_UNDEFINED;
646 }
647 
648 void
649 isc_tlsctx_set_protocols(isc_tlsctx_t *ctx, const uint32_t tls_versions) {
650 	REQUIRE(ctx != NULL);
651 	REQUIRE(tls_versions != 0);
652 	long set_options = 0;
653 	long clear_options = 0;
654 	uint32_t versions = tls_versions;
655 
656 	/*
657 	 * The code below might be initially hard to follow because of the
658 	 * double negation that OpenSSL enforces.
659 	 *
660 	 * Taking into account that OpenSSL provides bits to *disable*
661 	 * specific protocol versions, like SSL_OP_NO_TLSv1_2,
662 	 * SSL_OP_NO_TLSv1_3, etc., the code has the following logic:
663 	 *
664 	 * If a protocol version is not specified in the bitmask, get the
665 	 * bit that disables it and add it to the set of TLS options to
666 	 * set ('set_options'). Otherwise, if a protocol version is set,
667 	 * add the bit to the set of options to clear ('clear_options').
668 	 */
669 
670 	/* TLS protocol versions are defined as powers of two. */
671 	for (uint32_t tls_ver = ISC_TLS_PROTO_VER_1_2;
672 	     tls_ver < ISC_TLS_PROTO_VER_UNDEFINED; tls_ver <<= 1)
673 	{
674 		if ((tls_versions & tls_ver) == 0) {
675 			set_options |= get_tls_version_disable_bit(tls_ver);
676 		} else {
677 			/*
678 			 * Only supported versions should ever be passed to the
679 			 * function SSL_CTX_clear_options. For example, in order
680 			 * to enable TLS v1.2, we have to clear
681 			 * SSL_OP_NO_TLSv1_2. Insist that the configuration file
682 			 * was verified properly, so we are not trying to enable
683 			 * an unsupported TLS version.
684 			 */
685 			INSIST(isc_tls_protocol_supported(tls_ver));
686 			clear_options |= get_tls_version_disable_bit(tls_ver);
687 		}
688 		versions &= ~(tls_ver);
689 	}
690 
691 	/* All versions should be processed at this point, thus the value
692 	 * must equal zero. If it is not, then some garbage has been
693 	 * passed to the function; this situation is worth
694 	 * investigation. */
695 	INSIST(versions == 0);
696 
697 	(void)SSL_CTX_set_options(ctx, set_options);
698 	(void)SSL_CTX_clear_options(ctx, clear_options);
699 }
700 
701 bool
702 isc_tlsctx_load_dhparams(isc_tlsctx_t *ctx, const char *dhparams_file) {
703 	REQUIRE(ctx != NULL);
704 	REQUIRE(dhparams_file != NULL);
705 	REQUIRE(*dhparams_file != '\0');
706 
707 #if OPENSSL_VERSION_NUMBER < 0x30000000L
708 	/* OpenSSL < 3.0 */
709 	DH *dh = NULL;
710 	FILE *paramfile;
711 
712 	paramfile = fopen(dhparams_file, "r");
713 
714 	if (paramfile) {
715 		int check = 0;
716 		dh = PEM_read_DHparams(paramfile, NULL, NULL, NULL);
717 		fclose(paramfile);
718 
719 		if (dh == NULL) {
720 			return false;
721 		} else if (DH_check(dh, &check) != 1 || check != 0) {
722 			DH_free(dh);
723 			return false;
724 		}
725 	} else {
726 		return false;
727 	}
728 
729 	if (SSL_CTX_set_tmp_dh(ctx, dh) != 1) {
730 		DH_free(dh);
731 		return false;
732 	}
733 
734 	DH_free(dh);
735 #else
736 	/* OpenSSL >= 3.0: low level DH APIs are deprecated in OpenSSL 3.0 */
737 	EVP_PKEY *dh = NULL;
738 	BIO *bio = NULL;
739 
740 	bio = BIO_new_file(dhparams_file, "r");
741 	if (bio == NULL) {
742 		return false;
743 	}
744 
745 	dh = PEM_read_bio_Parameters(bio, NULL);
746 	if (dh == NULL) {
747 		BIO_free(bio);
748 		return false;
749 	}
750 
751 	if (SSL_CTX_set0_tmp_dh_pkey(ctx, dh) != 1) {
752 		BIO_free(bio);
753 		EVP_PKEY_free(dh);
754 		return false;
755 	}
756 
757 	/* No need to call EVP_PKEY_free(dh) as the "dh" is owned by the
758 	 * SSL context at this point. */
759 
760 	BIO_free(bio);
761 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */
762 
763 	return true;
764 }
765 
766 bool
767 isc_tls_cipherlist_valid(const char *cipherlist) {
768 	isc_tlsctx_t *tmp_ctx = NULL;
769 	const SSL_METHOD *method = NULL;
770 	bool result;
771 	REQUIRE(cipherlist != NULL);
772 
773 	if (*cipherlist == '\0') {
774 		return false;
775 	}
776 
777 	method = TLS_server_method();
778 	if (method == NULL) {
779 		return false;
780 	}
781 	tmp_ctx = SSL_CTX_new(method);
782 	if (tmp_ctx == NULL) {
783 		return false;
784 	}
785 
786 	result = SSL_CTX_set_cipher_list(tmp_ctx, cipherlist) == 1;
787 
788 	isc_tlsctx_free(&tmp_ctx);
789 
790 	return result;
791 }
792 
793 void
794 isc_tlsctx_set_cipherlist(isc_tlsctx_t *ctx, const char *cipherlist) {
795 	REQUIRE(ctx != NULL);
796 	REQUIRE(cipherlist != NULL);
797 	REQUIRE(*cipherlist != '\0');
798 
799 	RUNTIME_CHECK(SSL_CTX_set_cipher_list(ctx, cipherlist) == 1);
800 }
801 
802 bool
803 isc_tls_cipher_suites_valid(const char *cipher_suites) {
804 #ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
805 	isc_tlsctx_t *tmp_ctx = NULL;
806 	const SSL_METHOD *method = NULL;
807 	bool result;
808 	REQUIRE(cipher_suites != NULL);
809 
810 	if (*cipher_suites == '\0') {
811 		return false;
812 	}
813 
814 	method = TLS_server_method();
815 	if (method == NULL) {
816 		return false;
817 	}
818 	tmp_ctx = SSL_CTX_new(method);
819 	if (tmp_ctx == NULL) {
820 		return false;
821 	}
822 
823 	result = SSL_CTX_set_ciphersuites(tmp_ctx, cipher_suites) == 1;
824 
825 	isc_tlsctx_free(&tmp_ctx);
826 
827 	return result;
828 #else
829 	UNUSED(cipher_suites);
830 
831 	UNREACHABLE();
832 #endif
833 }
834 
835 void
836 isc_tlsctx_set_cipher_suites(isc_tlsctx_t *ctx, const char *cipher_suites) {
837 #ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
838 	REQUIRE(ctx != NULL);
839 	REQUIRE(cipher_suites != NULL);
840 	REQUIRE(*cipher_suites != '\0');
841 
842 	RUNTIME_CHECK(SSL_CTX_set_ciphersuites(ctx, cipher_suites) == 1);
843 #else
844 	UNUSED(ctx);
845 	UNUSED(cipher_suites);
846 
847 	UNREACHABLE();
848 #endif
849 }
850 
851 void
852 isc_tlsctx_prefer_server_ciphers(isc_tlsctx_t *ctx, const bool prefer) {
853 	REQUIRE(ctx != NULL);
854 
855 	if (prefer) {
856 		(void)SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
857 	} else {
858 		(void)SSL_CTX_clear_options(ctx,
859 					    SSL_OP_CIPHER_SERVER_PREFERENCE);
860 	}
861 }
862 
863 void
864 isc_tlsctx_session_tickets(isc_tlsctx_t *ctx, const bool use) {
865 	REQUIRE(ctx != NULL);
866 
867 	if (!use) {
868 		(void)SSL_CTX_set_options(ctx, SSL_OP_NO_TICKET);
869 	} else {
870 		(void)SSL_CTX_clear_options(ctx, SSL_OP_NO_TICKET);
871 	}
872 }
873 
874 isc_tls_t *
875 isc_tls_create(isc_tlsctx_t *ctx) {
876 	isc_tls_t *newctx = NULL;
877 
878 	REQUIRE(ctx != NULL);
879 
880 	newctx = SSL_new(ctx);
881 	if (newctx == NULL) {
882 		char errbuf[256];
883 		unsigned long err = ERR_get_error();
884 
885 		ERR_error_string_n(err, errbuf, sizeof(errbuf));
886 		fprintf(stderr, "%s:SSL_new(%p) -> %s\n", __func__, ctx,
887 			errbuf);
888 	}
889 
890 	return newctx;
891 }
892 
893 void
894 isc_tls_free(isc_tls_t **tlsp) {
895 	isc_tls_t *tls = NULL;
896 	REQUIRE(tlsp != NULL && *tlsp != NULL);
897 
898 	tls = *tlsp;
899 	*tlsp = NULL;
900 	SSL_free(tls);
901 }
902 
903 const char *
904 isc_tls_verify_peer_result_string(isc_tls_t *tls) {
905 	REQUIRE(tls != NULL);
906 
907 	return X509_verify_cert_error_string(SSL_get_verify_result(tls));
908 }
909 
910 #if HAVE_LIBNGHTTP2
911 #ifndef OPENSSL_NO_NEXTPROTONEG
912 /*
913  * NPN TLS extension client callback.
914  */
915 static int
916 select_next_proto_cb(SSL *ssl, unsigned char **out, unsigned char *outlen,
917 		     const unsigned char *in, unsigned int inlen, void *arg) {
918 	UNUSED(ssl);
919 	UNUSED(arg);
920 
921 	if (nghttp2_select_next_protocol(out, outlen, in, inlen) <= 0) {
922 		return SSL_TLSEXT_ERR_NOACK;
923 	}
924 	return SSL_TLSEXT_ERR_OK;
925 }
926 #endif /* !OPENSSL_NO_NEXTPROTONEG */
927 
928 void
929 isc_tlsctx_enable_http2client_alpn(isc_tlsctx_t *ctx) {
930 	REQUIRE(ctx != NULL);
931 
932 #ifndef OPENSSL_NO_NEXTPROTONEG
933 	SSL_CTX_set_next_proto_select_cb(ctx, select_next_proto_cb, NULL);
934 #endif /* !OPENSSL_NO_NEXTPROTONEG */
935 
936 #if OPENSSL_VERSION_NUMBER >= 0x10002000L
937 	SSL_CTX_set_alpn_protos(ctx, (const unsigned char *)NGHTTP2_PROTO_ALPN,
938 				NGHTTP2_PROTO_ALPN_LEN);
939 #endif /* OPENSSL_VERSION_NUMBER >= 0x10002000L */
940 }
941 
942 #ifndef OPENSSL_NO_NEXTPROTONEG
943 static int
944 next_proto_cb(isc_tls_t *ssl, const unsigned char **data, unsigned int *len,
945 	      void *arg) {
946 	UNUSED(ssl);
947 	UNUSED(arg);
948 
949 	*data = (const unsigned char *)NGHTTP2_PROTO_ALPN;
950 	*len = (unsigned int)NGHTTP2_PROTO_ALPN_LEN;
951 	return SSL_TLSEXT_ERR_OK;
952 }
953 #endif /* !OPENSSL_NO_NEXTPROTONEG */
954 
955 #if OPENSSL_VERSION_NUMBER >= 0x10002000L
956 static int
957 alpn_select_proto_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen,
958 		     const unsigned char *in, unsigned int inlen, void *arg) {
959 	int ret;
960 
961 	UNUSED(ssl);
962 	UNUSED(arg);
963 
964 	ret = nghttp2_select_next_protocol((unsigned char **)(uintptr_t)out,
965 					   outlen, in, inlen);
966 
967 	if (ret != 1) {
968 		return SSL_TLSEXT_ERR_NOACK;
969 	}
970 
971 	return SSL_TLSEXT_ERR_OK;
972 }
973 #endif /* OPENSSL_VERSION_NUMBER >= 0x10002000L */
974 
975 void
976 isc_tlsctx_enable_http2server_alpn(isc_tlsctx_t *tls) {
977 	REQUIRE(tls != NULL);
978 
979 #ifndef OPENSSL_NO_NEXTPROTONEG
980 	SSL_CTX_set_next_protos_advertised_cb(tls, next_proto_cb, NULL);
981 #endif // OPENSSL_NO_NEXTPROTONEG
982 #if OPENSSL_VERSION_NUMBER >= 0x10002000L
983 	SSL_CTX_set_alpn_select_cb(tls, alpn_select_proto_cb, NULL);
984 #endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
985 }
986 #endif /* HAVE_LIBNGHTTP2 */
987 
988 void
989 isc_tls_get_selected_alpn(isc_tls_t *tls, const unsigned char **alpn,
990 			  unsigned int *alpnlen) {
991 	REQUIRE(tls != NULL);
992 	REQUIRE(alpn != NULL);
993 	REQUIRE(alpnlen != NULL);
994 
995 #ifndef OPENSSL_NO_NEXTPROTONEG
996 	SSL_get0_next_proto_negotiated(tls, alpn, alpnlen);
997 #endif
998 #if OPENSSL_VERSION_NUMBER >= 0x10002000L
999 	if (*alpn == NULL) {
1000 		SSL_get0_alpn_selected(tls, alpn, alpnlen);
1001 	}
1002 #endif
1003 }
1004 
1005 static bool
1006 protoneg_check_protocol(const uint8_t **pout, uint8_t *pout_len,
1007 			const uint8_t *in, size_t in_len, const uint8_t *key,
1008 			size_t key_len) {
1009 	for (size_t i = 0; i + key_len <= in_len; i += (size_t)(in[i] + 1)) {
1010 		if (memcmp(&in[i], key, key_len) == 0) {
1011 			*pout = (const uint8_t *)(&in[i + 1]);
1012 			*pout_len = in[i];
1013 			return true;
1014 		}
1015 	}
1016 	return false;
1017 }
1018 
1019 /* dot prepended by its length (3 bytes) */
1020 #define DOT_PROTO_ALPN	   "\x3" ISC_TLS_DOT_PROTO_ALPN_ID
1021 #define DOT_PROTO_ALPN_LEN (sizeof(DOT_PROTO_ALPN) - 1)
1022 
1023 static bool
1024 dot_select_next_protocol(const uint8_t **pout, uint8_t *pout_len,
1025 			 const uint8_t *in, size_t in_len) {
1026 	return protoneg_check_protocol(pout, pout_len, in, in_len,
1027 				       (const uint8_t *)DOT_PROTO_ALPN,
1028 				       DOT_PROTO_ALPN_LEN);
1029 }
1030 
1031 void
1032 isc_tlsctx_enable_dot_client_alpn(isc_tlsctx_t *ctx) {
1033 	REQUIRE(ctx != NULL);
1034 
1035 #if OPENSSL_VERSION_NUMBER >= 0x10002000L
1036 	SSL_CTX_set_alpn_protos(ctx, (const uint8_t *)DOT_PROTO_ALPN,
1037 				DOT_PROTO_ALPN_LEN);
1038 #endif /* OPENSSL_VERSION_NUMBER >= 0x10002000L */
1039 }
1040 
1041 #if OPENSSL_VERSION_NUMBER >= 0x10002000L
1042 static int
1043 dot_alpn_select_proto_cb(SSL *ssl, const unsigned char **out,
1044 			 unsigned char *outlen, const unsigned char *in,
1045 			 unsigned int inlen, void *arg) {
1046 	bool ret;
1047 
1048 	UNUSED(ssl);
1049 	UNUSED(arg);
1050 
1051 	ret = dot_select_next_protocol(out, outlen, in, inlen);
1052 
1053 	if (!ret) {
1054 		return SSL_TLSEXT_ERR_NOACK;
1055 	}
1056 
1057 	return SSL_TLSEXT_ERR_OK;
1058 }
1059 #endif /* OPENSSL_VERSION_NUMBER >= 0x10002000L */
1060 
1061 void
1062 isc_tlsctx_enable_dot_server_alpn(isc_tlsctx_t *tls) {
1063 	REQUIRE(tls != NULL);
1064 
1065 #if OPENSSL_VERSION_NUMBER >= 0x10002000L
1066 	SSL_CTX_set_alpn_select_cb(tls, dot_alpn_select_proto_cb, NULL);
1067 #endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
1068 }
1069 
1070 isc_result_t
1071 isc_tlsctx_enable_peer_verification(isc_tlsctx_t *tlsctx, const bool is_server,
1072 				    isc_tls_cert_store_t *store,
1073 				    const char *hostname,
1074 				    bool hostname_ignore_subject) {
1075 	int ret = 0;
1076 	REQUIRE(tlsctx != NULL);
1077 	REQUIRE(store != NULL);
1078 
1079 	/* Set the hostname/IP address. */
1080 	if (!is_server && hostname != NULL && *hostname != '\0') {
1081 		struct in6_addr sa6;
1082 		struct in_addr sa;
1083 		X509_VERIFY_PARAM *param = SSL_CTX_get0_param(tlsctx);
1084 		unsigned int hostflags = X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS;
1085 
1086 		/* It might be an IP address. */
1087 		if (inet_pton(AF_INET6, hostname, &sa6) == 1 ||
1088 		    inet_pton(AF_INET, hostname, &sa) == 1)
1089 		{
1090 			ret = X509_VERIFY_PARAM_set1_ip_asc(param, hostname);
1091 		} else {
1092 			/* It seems that it is a host name. Let's set it. */
1093 			ret = X509_VERIFY_PARAM_set1_host(param, hostname, 0);
1094 		}
1095 		if (ret != 1) {
1096 			ERR_clear_error();
1097 			return ISC_R_FAILURE;
1098 		}
1099 
1100 #ifdef X509_CHECK_FLAG_NEVER_CHECK_SUBJECT
1101 		/*
1102 		 * According to the RFC 8310, Section 8.1, Subject field MUST
1103 		 * NOT be inspected when verifying a hostname when using
1104 		 * DoT. Only SubjectAltName must be checked instead. That is
1105 		 * not the case for HTTPS, though.
1106 		 *
1107 		 * Unfortunately, some quite old versions of OpenSSL (< 1.1.1)
1108 		 * might lack the functionality to implement that. It should
1109 		 * have very little real-world consequences, as most of the
1110 		 * production-ready certificates issued by real CAs will have
1111 		 * SubjectAltName set. In such a case, the Subject field is
1112 		 * ignored.
1113 		 */
1114 		if (hostname_ignore_subject) {
1115 			hostflags |= X509_CHECK_FLAG_NEVER_CHECK_SUBJECT;
1116 		}
1117 #else
1118 		UNUSED(hostname_ignore_subject);
1119 #endif
1120 		X509_VERIFY_PARAM_set_hostflags(param, hostflags);
1121 	}
1122 
1123 	/* "Attach" the cert store to the context */
1124 	SSL_CTX_set1_cert_store(tlsctx, store);
1125 
1126 	/* enable verification */
1127 	if (is_server) {
1128 		SSL_CTX_set_verify(tlsctx,
1129 				   SSL_VERIFY_PEER |
1130 					   SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1131 				   NULL);
1132 	} else {
1133 		SSL_CTX_set_verify(tlsctx, SSL_VERIFY_PEER, NULL);
1134 	}
1135 
1136 	return ISC_R_SUCCESS;
1137 }
1138 
1139 isc_result_t
1140 isc_tlsctx_load_client_ca_names(isc_tlsctx_t *ctx, const char *ca_bundle_file) {
1141 	STACK_OF(X509_NAME) * cert_names;
1142 	REQUIRE(ctx != NULL);
1143 	REQUIRE(ca_bundle_file != NULL);
1144 
1145 	cert_names = SSL_load_client_CA_file(ca_bundle_file);
1146 	if (cert_names == NULL) {
1147 		ERR_clear_error();
1148 		return ISC_R_FAILURE;
1149 	}
1150 
1151 	SSL_CTX_set_client_CA_list(ctx, cert_names);
1152 
1153 	return ISC_R_SUCCESS;
1154 }
1155 
1156 isc_result_t
1157 isc_tls_cert_store_create(const char *ca_bundle_filename,
1158 			  isc_tls_cert_store_t **pstore) {
1159 	int ret = 0;
1160 	isc_tls_cert_store_t *store = NULL;
1161 	REQUIRE(pstore != NULL && *pstore == NULL);
1162 
1163 	store = X509_STORE_new();
1164 	if (store == NULL) {
1165 		goto error;
1166 	}
1167 
1168 	/* Let's treat empty string as the default (system wide) store */
1169 	if (ca_bundle_filename != NULL && *ca_bundle_filename == '\0') {
1170 		ca_bundle_filename = NULL;
1171 	}
1172 
1173 	if (ca_bundle_filename == NULL) {
1174 		ret = X509_STORE_set_default_paths(store);
1175 	} else {
1176 		ret = X509_STORE_load_locations(store, ca_bundle_filename,
1177 						NULL);
1178 	}
1179 
1180 	if (ret == 0) {
1181 		goto error;
1182 	}
1183 
1184 	*pstore = store;
1185 	return ISC_R_SUCCESS;
1186 
1187 error:
1188 	ERR_clear_error();
1189 	if (store != NULL) {
1190 		X509_STORE_free(store);
1191 	}
1192 	return ISC_R_FAILURE;
1193 }
1194 
1195 void
1196 isc_tls_cert_store_free(isc_tls_cert_store_t **pstore) {
1197 	isc_tls_cert_store_t *store;
1198 	REQUIRE(pstore != NULL && *pstore != NULL);
1199 
1200 	store = *pstore;
1201 
1202 	X509_STORE_free(store);
1203 
1204 	*pstore = NULL;
1205 }
1206 
1207 #define TLSCTX_CACHE_MAGIC    ISC_MAGIC('T', 'l', 'S', 'c')
1208 #define VALID_TLSCTX_CACHE(t) ISC_MAGIC_VALID(t, TLSCTX_CACHE_MAGIC)
1209 
1210 #define TLSCTX_CLIENT_SESSION_CACHE_MAGIC ISC_MAGIC('T', 'l', 'C', 'c')
1211 #define VALID_TLSCTX_CLIENT_SESSION_CACHE(t) \
1212 	ISC_MAGIC_VALID(t, TLSCTX_CLIENT_SESSION_CACHE_MAGIC)
1213 
1214 typedef struct isc_tlsctx_cache_entry {
1215 	/*
1216 	 * We need a TLS context entry for each transport on both IPv4 and
1217 	 * IPv6 in order to avoid cluttering a context-specific
1218 	 * session-resumption cache.
1219 	 */
1220 	isc_tlsctx_t *ctx[isc_tlsctx_cache_count - 1][2];
1221 	isc_tlsctx_client_session_cache_t
1222 		*client_sess_cache[isc_tlsctx_cache_count - 1][2];
1223 	/*
1224 	 * One certificate store is enough for all the contexts defined
1225 	 * above. We need that for peer validation.
1226 	 */
1227 	isc_tls_cert_store_t *ca_store;
1228 } isc_tlsctx_cache_entry_t;
1229 
1230 struct isc_tlsctx_cache {
1231 	uint32_t magic;
1232 	isc_refcount_t references;
1233 	isc_mem_t *mctx;
1234 
1235 	isc_rwlock_t rwlock;
1236 	isc_ht_t *data;
1237 };
1238 
1239 void
1240 isc_tlsctx_cache_create(isc_mem_t *mctx, isc_tlsctx_cache_t **cachep) {
1241 	isc_tlsctx_cache_t *nc;
1242 
1243 	REQUIRE(cachep != NULL && *cachep == NULL);
1244 	nc = isc_mem_get(mctx, sizeof(*nc));
1245 
1246 	*nc = (isc_tlsctx_cache_t){ .magic = TLSCTX_CACHE_MAGIC };
1247 	isc_refcount_init(&nc->references, 1);
1248 	isc_mem_attach(mctx, &nc->mctx);
1249 
1250 	isc_ht_init(&nc->data, mctx, 5, ISC_HT_CASE_SENSITIVE);
1251 	isc_rwlock_init(&nc->rwlock);
1252 
1253 	*cachep = nc;
1254 }
1255 
1256 void
1257 isc_tlsctx_cache_attach(isc_tlsctx_cache_t *source,
1258 			isc_tlsctx_cache_t **targetp) {
1259 	REQUIRE(VALID_TLSCTX_CACHE(source));
1260 	REQUIRE(targetp != NULL && *targetp == NULL);
1261 
1262 	isc_refcount_increment(&source->references);
1263 
1264 	*targetp = source;
1265 }
1266 
1267 static void
1268 tlsctx_cache_entry_destroy(isc_mem_t *mctx, isc_tlsctx_cache_entry_t *entry) {
1269 	size_t i, k;
1270 
1271 	for (i = 0; i < (isc_tlsctx_cache_count - 1); i++) {
1272 		for (k = 0; k < 2; k++) {
1273 			if (entry->ctx[i][k] != NULL) {
1274 				isc_tlsctx_free(&entry->ctx[i][k]);
1275 			}
1276 
1277 			if (entry->client_sess_cache[i][k] != NULL) {
1278 				isc_tlsctx_client_session_cache_detach(
1279 					&entry->client_sess_cache[i][k]);
1280 			}
1281 		}
1282 	}
1283 	if (entry->ca_store != NULL) {
1284 		isc_tls_cert_store_free(&entry->ca_store);
1285 	}
1286 	isc_mem_put(mctx, entry, sizeof(*entry));
1287 }
1288 
1289 static void
1290 tlsctx_cache_destroy(isc_tlsctx_cache_t *cache) {
1291 	isc_ht_iter_t *it = NULL;
1292 	isc_result_t result;
1293 
1294 	cache->magic = 0;
1295 
1296 	isc_refcount_destroy(&cache->references);
1297 
1298 	isc_ht_iter_create(cache->data, &it);
1299 	for (result = isc_ht_iter_first(it); result == ISC_R_SUCCESS;
1300 	     result = isc_ht_iter_delcurrent_next(it))
1301 	{
1302 		isc_tlsctx_cache_entry_t *entry = NULL;
1303 		isc_ht_iter_current(it, (void **)&entry);
1304 		tlsctx_cache_entry_destroy(cache->mctx, entry);
1305 	}
1306 
1307 	isc_ht_iter_destroy(&it);
1308 	isc_ht_destroy(&cache->data);
1309 	isc_rwlock_destroy(&cache->rwlock);
1310 	isc_mem_putanddetach(&cache->mctx, cache, sizeof(*cache));
1311 }
1312 
1313 void
1314 isc_tlsctx_cache_detach(isc_tlsctx_cache_t **cachep) {
1315 	isc_tlsctx_cache_t *cache = NULL;
1316 
1317 	REQUIRE(cachep != NULL);
1318 
1319 	cache = *cachep;
1320 	*cachep = NULL;
1321 
1322 	REQUIRE(VALID_TLSCTX_CACHE(cache));
1323 
1324 	if (isc_refcount_decrement(&cache->references) == 1) {
1325 		tlsctx_cache_destroy(cache);
1326 	}
1327 }
1328 
1329 isc_result_t
1330 isc_tlsctx_cache_add(
1331 	isc_tlsctx_cache_t *cache, const char *name,
1332 	const isc_tlsctx_cache_transport_t transport, const uint16_t family,
1333 	isc_tlsctx_t *ctx, isc_tls_cert_store_t *store,
1334 	isc_tlsctx_client_session_cache_t *client_sess_cache,
1335 	isc_tlsctx_t **pfound, isc_tls_cert_store_t **pfound_store,
1336 	isc_tlsctx_client_session_cache_t **pfound_client_sess_cache) {
1337 	isc_result_t result = ISC_R_FAILURE;
1338 	size_t name_len, tr_offset;
1339 	isc_tlsctx_cache_entry_t *entry = NULL;
1340 	bool ipv6;
1341 
1342 	REQUIRE(VALID_TLSCTX_CACHE(cache));
1343 	REQUIRE(client_sess_cache == NULL ||
1344 		VALID_TLSCTX_CLIENT_SESSION_CACHE(client_sess_cache));
1345 	REQUIRE(name != NULL && *name != '\0');
1346 	REQUIRE(transport > isc_tlsctx_cache_none &&
1347 		transport < isc_tlsctx_cache_count);
1348 	REQUIRE(family == AF_INET || family == AF_INET6);
1349 	REQUIRE(ctx != NULL);
1350 
1351 	tr_offset = (transport - 1);
1352 	ipv6 = (family == AF_INET6);
1353 
1354 	RWLOCK(&cache->rwlock, isc_rwlocktype_write);
1355 
1356 	name_len = strlen(name);
1357 	result = isc_ht_find(cache->data, (const uint8_t *)name, name_len,
1358 			     (void **)&entry);
1359 	if (result == ISC_R_SUCCESS && entry->ctx[tr_offset][ipv6] != NULL) {
1360 		isc_tlsctx_client_session_cache_t *found_client_sess_cache;
1361 		/* The entry exists. */
1362 		if (pfound != NULL) {
1363 			INSIST(*pfound == NULL);
1364 			*pfound = entry->ctx[tr_offset][ipv6];
1365 		}
1366 
1367 		if (pfound_store != NULL && entry->ca_store != NULL) {
1368 			INSIST(*pfound_store == NULL);
1369 			*pfound_store = entry->ca_store;
1370 		}
1371 
1372 		found_client_sess_cache =
1373 			entry->client_sess_cache[tr_offset][ipv6];
1374 		if (pfound_client_sess_cache != NULL &&
1375 		    found_client_sess_cache != NULL)
1376 		{
1377 			INSIST(*pfound_client_sess_cache == NULL);
1378 			*pfound_client_sess_cache = found_client_sess_cache;
1379 		}
1380 		result = ISC_R_EXISTS;
1381 	} else if (result == ISC_R_SUCCESS &&
1382 		   entry->ctx[tr_offset][ipv6] == NULL)
1383 	{
1384 		/*
1385 		 * The hash table entry exists, but is not filled for this
1386 		 * particular transport/IP type combination.
1387 		 */
1388 		entry->ctx[tr_offset][ipv6] = ctx;
1389 		entry->client_sess_cache[tr_offset][ipv6] = client_sess_cache;
1390 		/*
1391 		 * As the passed certificates store object is supposed
1392 		 * to be internally managed by the cache object anyway,
1393 		 * we might destroy the unneeded store object right now.
1394 		 */
1395 		if (store != NULL && store != entry->ca_store) {
1396 			isc_tls_cert_store_free(&store);
1397 		}
1398 		result = ISC_R_SUCCESS;
1399 	} else {
1400 		/*
1401 		 * The hash table entry does not exist, let's create one.
1402 		 */
1403 		INSIST(result != ISC_R_SUCCESS);
1404 		entry = isc_mem_get(cache->mctx, sizeof(*entry));
1405 		*entry = (isc_tlsctx_cache_entry_t){
1406 			.ca_store = store,
1407 		};
1408 
1409 		entry->ctx[tr_offset][ipv6] = ctx;
1410 		entry->client_sess_cache[tr_offset][ipv6] = client_sess_cache;
1411 		RUNTIME_CHECK(isc_ht_add(cache->data, (const uint8_t *)name,
1412 					 name_len,
1413 					 (void *)entry) == ISC_R_SUCCESS);
1414 		result = ISC_R_SUCCESS;
1415 	}
1416 
1417 	RWUNLOCK(&cache->rwlock, isc_rwlocktype_write);
1418 
1419 	return result;
1420 }
1421 
1422 isc_result_t
1423 isc_tlsctx_cache_find(
1424 	isc_tlsctx_cache_t *cache, const char *name,
1425 	const isc_tlsctx_cache_transport_t transport, const uint16_t family,
1426 	isc_tlsctx_t **pctx, isc_tls_cert_store_t **pstore,
1427 	isc_tlsctx_client_session_cache_t **pfound_client_sess_cache) {
1428 	isc_result_t result = ISC_R_FAILURE;
1429 	size_t tr_offset;
1430 	isc_tlsctx_cache_entry_t *entry = NULL;
1431 	bool ipv6;
1432 
1433 	REQUIRE(VALID_TLSCTX_CACHE(cache));
1434 	REQUIRE(name != NULL && *name != '\0');
1435 	REQUIRE(transport > isc_tlsctx_cache_none &&
1436 		transport < isc_tlsctx_cache_count);
1437 	REQUIRE(family == AF_INET || family == AF_INET6);
1438 	REQUIRE(pctx != NULL && *pctx == NULL);
1439 
1440 	tr_offset = (transport - 1);
1441 	ipv6 = (family == AF_INET6);
1442 
1443 	RWLOCK(&cache->rwlock, isc_rwlocktype_read);
1444 
1445 	result = isc_ht_find(cache->data, (const uint8_t *)name, strlen(name),
1446 			     (void **)&entry);
1447 
1448 	if (result == ISC_R_SUCCESS && pstore != NULL &&
1449 	    entry->ca_store != NULL)
1450 	{
1451 		*pstore = entry->ca_store;
1452 	}
1453 
1454 	if (result == ISC_R_SUCCESS && entry->ctx[tr_offset][ipv6] != NULL) {
1455 		isc_tlsctx_client_session_cache_t *found_client_sess_cache =
1456 			entry->client_sess_cache[tr_offset][ipv6];
1457 
1458 		*pctx = entry->ctx[tr_offset][ipv6];
1459 
1460 		if (pfound_client_sess_cache != NULL &&
1461 		    found_client_sess_cache != NULL)
1462 		{
1463 			INSIST(*pfound_client_sess_cache == NULL);
1464 			*pfound_client_sess_cache = found_client_sess_cache;
1465 		}
1466 	} else if (result == ISC_R_SUCCESS &&
1467 		   entry->ctx[tr_offset][ipv6] == NULL)
1468 	{
1469 		result = ISC_R_NOTFOUND;
1470 	} else {
1471 		INSIST(result != ISC_R_SUCCESS);
1472 	}
1473 
1474 	RWUNLOCK(&cache->rwlock, isc_rwlocktype_read);
1475 
1476 	return result;
1477 }
1478 
1479 typedef struct client_session_cache_entry client_session_cache_entry_t;
1480 
1481 typedef struct client_session_cache_bucket {
1482 	char *bucket_key;
1483 	size_t bucket_key_len;
1484 	/* Cache entries within the bucket (from the oldest to the newest). */
1485 	ISC_LIST(client_session_cache_entry_t) entries;
1486 } client_session_cache_bucket_t;
1487 
1488 struct client_session_cache_entry {
1489 	SSL_SESSION *session;
1490 	client_session_cache_bucket_t *bucket; /* "Parent" bucket pointer. */
1491 	ISC_LINK(client_session_cache_entry_t) bucket_link;
1492 	ISC_LINK(client_session_cache_entry_t) cache_link;
1493 };
1494 
1495 struct isc_tlsctx_client_session_cache {
1496 	uint32_t magic;
1497 	isc_refcount_t references;
1498 	isc_mem_t *mctx;
1499 
1500 	/*
1501 	 * We need to keep a reference to the related TLS context in order
1502 	 * to ensure that it remains valid while the TLS client sessions
1503 	 * cache object is valid, as every TLS session object
1504 	 * (SSL_SESSION) is "tied" to a particular context.
1505 	 */
1506 	isc_tlsctx_t *ctx;
1507 
1508 	/*
1509 	 * The idea is to have one bucket per remote server. Each bucket,
1510 	 * can maintain multiple TLS sessions to that server, as BIND
1511 	 * might want to establish multiple TLS connections to the remote
1512 	 * server at once.
1513 	 */
1514 	isc_ht_t *buckets;
1515 
1516 	/*
1517 	 * The list of all current entries within the cache maintained in
1518 	 * LRU-manner, so that the oldest entry might be efficiently
1519 	 * removed.
1520 	 */
1521 	ISC_LIST(client_session_cache_entry_t) lru_entries;
1522 	/* Number of the entries within the cache. */
1523 	size_t nentries;
1524 	/* Maximum number of the entries within the cache. */
1525 	size_t max_entries;
1526 
1527 	isc_mutex_t lock;
1528 };
1529 
1530 void
1531 isc_tlsctx_client_session_cache_create(
1532 	isc_mem_t *mctx, isc_tlsctx_t *ctx, const size_t max_entries,
1533 	isc_tlsctx_client_session_cache_t **cachep) {
1534 	isc_tlsctx_client_session_cache_t *nc;
1535 
1536 	REQUIRE(ctx != NULL);
1537 	REQUIRE(max_entries > 0);
1538 	REQUIRE(cachep != NULL && *cachep == NULL);
1539 
1540 	nc = isc_mem_get(mctx, sizeof(*nc));
1541 
1542 	*nc = (isc_tlsctx_client_session_cache_t){ .max_entries = max_entries };
1543 	isc_refcount_init(&nc->references, 1);
1544 	isc_mem_attach(mctx, &nc->mctx);
1545 	isc_tlsctx_attach(ctx, &nc->ctx);
1546 
1547 	isc_ht_init(&nc->buckets, mctx, 5, ISC_HT_CASE_SENSITIVE);
1548 	ISC_LIST_INIT(nc->lru_entries);
1549 	isc_mutex_init(&nc->lock);
1550 
1551 	nc->magic = TLSCTX_CLIENT_SESSION_CACHE_MAGIC;
1552 
1553 	*cachep = nc;
1554 }
1555 
1556 void
1557 isc_tlsctx_client_session_cache_attach(
1558 	isc_tlsctx_client_session_cache_t *source,
1559 	isc_tlsctx_client_session_cache_t **targetp) {
1560 	REQUIRE(VALID_TLSCTX_CLIENT_SESSION_CACHE(source));
1561 	REQUIRE(targetp != NULL && *targetp == NULL);
1562 
1563 	isc_refcount_increment(&source->references);
1564 
1565 	*targetp = source;
1566 }
1567 
1568 static void
1569 client_cache_entry_delete(isc_tlsctx_client_session_cache_t *restrict cache,
1570 			  client_session_cache_entry_t *restrict entry) {
1571 	client_session_cache_bucket_t *restrict bucket = entry->bucket;
1572 
1573 	/* Unlink and free the cache entry */
1574 	ISC_LIST_UNLINK(bucket->entries, entry, bucket_link);
1575 	ISC_LIST_UNLINK(cache->lru_entries, entry, cache_link);
1576 	cache->nentries--;
1577 	(void)SSL_SESSION_free(entry->session);
1578 	isc_mem_put(cache->mctx, entry, sizeof(*entry));
1579 
1580 	/* The bucket is empty - let's remove it */
1581 	if (ISC_LIST_EMPTY(bucket->entries)) {
1582 		RUNTIME_CHECK(isc_ht_delete(cache->buckets,
1583 					    (const uint8_t *)bucket->bucket_key,
1584 					    bucket->bucket_key_len) ==
1585 			      ISC_R_SUCCESS);
1586 
1587 		isc_mem_free(cache->mctx, bucket->bucket_key);
1588 		isc_mem_put(cache->mctx, bucket, sizeof(*bucket));
1589 	}
1590 }
1591 
1592 void
1593 isc_tlsctx_client_session_cache_detach(
1594 	isc_tlsctx_client_session_cache_t **cachep) {
1595 	isc_tlsctx_client_session_cache_t *cache = NULL;
1596 	client_session_cache_entry_t *entry = NULL, *next = NULL;
1597 
1598 	REQUIRE(cachep != NULL);
1599 
1600 	cache = *cachep;
1601 	*cachep = NULL;
1602 
1603 	REQUIRE(VALID_TLSCTX_CLIENT_SESSION_CACHE(cache));
1604 
1605 	if (isc_refcount_decrement(&cache->references) != 1) {
1606 		return;
1607 	}
1608 
1609 	cache->magic = 0;
1610 
1611 	isc_refcount_destroy(&cache->references);
1612 
1613 	entry = ISC_LIST_HEAD(cache->lru_entries);
1614 	while (entry != NULL) {
1615 		next = ISC_LIST_NEXT(entry, cache_link);
1616 		client_cache_entry_delete(cache, entry);
1617 		entry = next;
1618 	}
1619 
1620 	RUNTIME_CHECK(isc_ht_count(cache->buckets) == 0);
1621 	isc_ht_destroy(&cache->buckets);
1622 
1623 	isc_mutex_destroy(&cache->lock);
1624 	isc_tlsctx_free(&cache->ctx);
1625 	isc_mem_putanddetach(&cache->mctx, cache, sizeof(*cache));
1626 }
1627 
1628 static bool
1629 ssl_session_seems_resumable(const SSL_SESSION *sess) {
1630 #ifdef HAVE_SSL_SESSION_IS_RESUMABLE
1631 	/*
1632 	 * If SSL_SESSION_is_resumable() is available, let's use that. It
1633 	 * is expected to be available on OpenSSL >= 1.1.1 and its modern
1634 	 * siblings.
1635 	 */
1636 	return SSL_SESSION_is_resumable(sess) != 0;
1637 #elif (OPENSSL_VERSION_NUMBER >= 0x10100000L)
1638 	/*
1639 	 * Taking into consideration that OpenSSL 1.1.0 uses opaque
1640 	 * pointers for SSL_SESSION, we cannot implement a replacement for
1641 	 * SSL_SESSION_is_resumable() manually. Let's use a sensible
1642 	 * approximation for that, then: if there is an associated session
1643 	 * ticket or session ID, then, most likely, the session is
1644 	 * resumable.
1645 	 */
1646 	unsigned int session_id_len = 0;
1647 	(void)SSL_SESSION_get_id(sess, &session_id_len);
1648 	return SSL_SESSION_has_ticket(sess) || session_id_len > 0;
1649 #else
1650 	return !sess->not_resumable &&
1651 	       (sess->session_id_length > 0 || sess->tlsext_ticklen > 0);
1652 #endif
1653 }
1654 
1655 void
1656 isc_tlsctx_client_session_cache_keep(isc_tlsctx_client_session_cache_t *cache,
1657 				     char *remote_peer_name, isc_tls_t *tls) {
1658 	size_t name_len;
1659 	isc_result_t result;
1660 	SSL_SESSION *sess;
1661 	client_session_cache_bucket_t *restrict bucket = NULL;
1662 	client_session_cache_entry_t *restrict entry = NULL;
1663 
1664 	REQUIRE(VALID_TLSCTX_CLIENT_SESSION_CACHE(cache));
1665 	REQUIRE(remote_peer_name != NULL && *remote_peer_name != '\0');
1666 	REQUIRE(tls != NULL);
1667 
1668 	sess = SSL_get1_session(tls);
1669 	if (sess == NULL) {
1670 		ERR_clear_error();
1671 		return;
1672 	} else if (!ssl_session_seems_resumable(sess)) {
1673 		SSL_SESSION_free(sess);
1674 		return;
1675 	}
1676 
1677 	SSL_set_session(tls, NULL);
1678 
1679 	isc_mutex_lock(&cache->lock);
1680 
1681 	name_len = strlen(remote_peer_name);
1682 	result = isc_ht_find(cache->buckets, (const uint8_t *)remote_peer_name,
1683 			     name_len, (void **)&bucket);
1684 
1685 	if (result != ISC_R_SUCCESS) {
1686 		/* Let's create a new bucket */
1687 		INSIST(bucket == NULL);
1688 		bucket = isc_mem_get(cache->mctx, sizeof(*bucket));
1689 		*bucket = (client_session_cache_bucket_t){
1690 			.bucket_key = isc_mem_strdup(cache->mctx,
1691 						     remote_peer_name),
1692 			.bucket_key_len = name_len
1693 		};
1694 		ISC_LIST_INIT(bucket->entries);
1695 		RUNTIME_CHECK(isc_ht_add(cache->buckets,
1696 					 (const uint8_t *)remote_peer_name,
1697 					 name_len,
1698 					 (void *)bucket) == ISC_R_SUCCESS);
1699 	}
1700 
1701 	/* Let's add a new cache entry to the new/found bucket */
1702 	entry = isc_mem_get(cache->mctx, sizeof(*entry));
1703 	*entry = (client_session_cache_entry_t){ .session = sess,
1704 						 .bucket = bucket };
1705 	ISC_LINK_INIT(entry, bucket_link);
1706 	ISC_LINK_INIT(entry, cache_link);
1707 
1708 	ISC_LIST_APPEND(bucket->entries, entry, bucket_link);
1709 
1710 	ISC_LIST_APPEND(cache->lru_entries, entry, cache_link);
1711 	cache->nentries++;
1712 
1713 	if (cache->nentries > cache->max_entries) {
1714 		/*
1715 		 * Cache overrun. We need to remove the oldest entry from the
1716 		 * cache
1717 		 */
1718 		client_session_cache_entry_t *restrict oldest;
1719 		INSIST((cache->nentries - 1) == cache->max_entries);
1720 
1721 		oldest = ISC_LIST_HEAD(cache->lru_entries);
1722 		client_cache_entry_delete(cache, oldest);
1723 	}
1724 
1725 	isc_mutex_unlock(&cache->lock);
1726 }
1727 
1728 void
1729 isc_tlsctx_client_session_cache_reuse(isc_tlsctx_client_session_cache_t *cache,
1730 				      char *remote_peer_name, isc_tls_t *tls) {
1731 	client_session_cache_bucket_t *restrict bucket = NULL;
1732 	client_session_cache_entry_t *restrict entry;
1733 	size_t name_len;
1734 	isc_result_t result;
1735 
1736 	REQUIRE(VALID_TLSCTX_CLIENT_SESSION_CACHE(cache));
1737 	REQUIRE(remote_peer_name != NULL && *remote_peer_name != '\0');
1738 	REQUIRE(tls != NULL);
1739 
1740 	isc_mutex_lock(&cache->lock);
1741 
1742 	/* Let's find the bucket */
1743 	name_len = strlen(remote_peer_name);
1744 	result = isc_ht_find(cache->buckets, (const uint8_t *)remote_peer_name,
1745 			     name_len, (void **)&bucket);
1746 
1747 	if (result != ISC_R_SUCCESS) {
1748 		goto exit;
1749 	}
1750 
1751 	INSIST(bucket != NULL);
1752 
1753 	/*
1754 	 * If the bucket has been found, let's use the newest session from
1755 	 * the bucket, as it has the highest chance to be successfully
1756 	 * resumed.
1757 	 */
1758 	INSIST(!ISC_LIST_EMPTY(bucket->entries));
1759 	entry = ISC_LIST_TAIL(bucket->entries);
1760 	RUNTIME_CHECK(SSL_set_session(tls, entry->session) == 1);
1761 	client_cache_entry_delete(cache, entry);
1762 
1763 exit:
1764 	isc_mutex_unlock(&cache->lock);
1765 }
1766 
1767 void
1768 isc_tlsctx_client_session_cache_keep_sockaddr(
1769 	isc_tlsctx_client_session_cache_t *cache, isc_sockaddr_t *remote_peer,
1770 	isc_tls_t *tls) {
1771 	char peername[ISC_SOCKADDR_FORMATSIZE] = { 0 };
1772 
1773 	REQUIRE(remote_peer != NULL);
1774 
1775 	isc_sockaddr_format(remote_peer, peername, sizeof(peername));
1776 
1777 	isc_tlsctx_client_session_cache_keep(cache, peername, tls);
1778 }
1779 
1780 void
1781 isc_tlsctx_client_session_cache_reuse_sockaddr(
1782 	isc_tlsctx_client_session_cache_t *cache, isc_sockaddr_t *remote_peer,
1783 	isc_tls_t *tls) {
1784 	char peername[ISC_SOCKADDR_FORMATSIZE] = { 0 };
1785 
1786 	REQUIRE(remote_peer != NULL);
1787 
1788 	isc_sockaddr_format(remote_peer, peername, sizeof(peername));
1789 
1790 	isc_tlsctx_client_session_cache_reuse(cache, peername, tls);
1791 }
1792 
1793 const isc_tlsctx_t *
1794 isc_tlsctx_client_session_cache_getctx(
1795 	isc_tlsctx_client_session_cache_t *cache) {
1796 	REQUIRE(VALID_TLSCTX_CLIENT_SESSION_CACHE(cache));
1797 	return cache->ctx;
1798 }
1799 
1800 void
1801 isc_tlsctx_set_random_session_id_context(isc_tlsctx_t *ctx) {
1802 	uint8_t session_id_ctx[SSL_MAX_SID_CTX_LENGTH] = { 0 };
1803 	const size_t len = ISC_MIN(20, sizeof(session_id_ctx));
1804 
1805 	REQUIRE(ctx != NULL);
1806 
1807 	RUNTIME_CHECK(RAND_bytes(session_id_ctx, len) == 1);
1808 
1809 	RUNTIME_CHECK(
1810 		SSL_CTX_set_session_id_context(ctx, session_id_ctx, len) == 1);
1811 }
1812