1/*	$NetBSD: tlsstream.c,v 1.2 2024/02/21 22:52:32 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 <errno.h>
17#include <libgen.h>
18#include <unistd.h>
19#include <uv.h>
20
21#include <openssl/err.h>
22#include <openssl/ssl.h>
23
24#include <isc/atomic.h>
25#include <isc/buffer.h>
26#include <isc/condition.h>
27#include <isc/log.h>
28#include <isc/magic.h>
29#include <isc/mem.h>
30#include <isc/netmgr.h>
31#include <isc/once.h>
32#include <isc/quota.h>
33#include <isc/random.h>
34#include <isc/refcount.h>
35#include <isc/region.h>
36#include <isc/result.h>
37#include <isc/sockaddr.h>
38#include <isc/stdtime.h>
39#include <isc/thread.h>
40#include <isc/util.h>
41
42#include "../openssl_shim.h"
43#include "netmgr-int.h"
44#include "uv-compat.h"
45
46#define TLS_BUF_SIZE (UINT16_MAX)
47
48static isc_result_t
49tls_error_to_result(const int tls_err, const int tls_state, isc_tls_t *tls) {
50	switch (tls_err) {
51	case SSL_ERROR_ZERO_RETURN:
52		return (ISC_R_EOF);
53	case SSL_ERROR_SSL:
54		if (tls != NULL && tls_state < TLS_IO &&
55		    SSL_get_verify_result(tls) != X509_V_OK)
56		{
57			return (ISC_R_TLSBADPEERCERT);
58		}
59		return (ISC_R_TLSERROR);
60	default:
61		return (ISC_R_UNEXPECTED);
62	}
63}
64
65static void
66tls_failed_read_cb(isc_nmsocket_t *sock, const isc_result_t result);
67
68static void
69tls_do_bio(isc_nmsocket_t *sock, isc_region_t *received_data,
70	   isc__nm_uvreq_t *send_data, bool finish);
71
72static void
73tls_readcb(isc_nmhandle_t *handle, isc_result_t result, isc_region_t *region,
74	   void *cbarg);
75
76static void
77tls_close_direct(isc_nmsocket_t *sock);
78
79static void
80async_tls_do_bio(isc_nmsocket_t *sock);
81
82static void
83tls_init_listener_tlsctx(isc_nmsocket_t *listener, isc_tlsctx_t *ctx);
84
85static void
86tls_cleanup_listener_tlsctx(isc_nmsocket_t *listener);
87
88static isc_tlsctx_t *
89tls_get_listener_tlsctx(isc_nmsocket_t *listener, const int tid);
90
91static void
92tls_keep_client_tls_session(isc_nmsocket_t *sock);
93
94static void
95tls_try_shutdown(isc_tls_t *tls, const bool quite);
96
97/*
98 * The socket is closing, outerhandle has been detached, listener is
99 * inactive, or the netmgr is closing: any operation on it should abort
100 * with ISC_R_CANCELED.
101 */
102static bool
103inactive(isc_nmsocket_t *sock) {
104	return (!isc__nmsocket_active(sock) || atomic_load(&sock->closing) ||
105		sock->outerhandle == NULL ||
106		!isc__nmsocket_active(sock->outerhandle->sock) ||
107		atomic_load(&sock->outerhandle->sock->closing) ||
108		(sock->listener != NULL &&
109		 !isc__nmsocket_active(sock->listener)) ||
110		isc__nm_closing(sock));
111}
112
113static void
114tls_call_connect_cb(isc_nmsocket_t *sock, isc_nmhandle_t *handle,
115		    const isc_result_t result) {
116	if (sock->connect_cb == NULL) {
117		return;
118	}
119	sock->connect_cb(handle, result, sock->connect_cbarg);
120	if (result != ISC_R_SUCCESS) {
121		isc__nmsocket_clearcb(handle->sock);
122	}
123}
124
125static void
126tls_senddone(isc_nmhandle_t *handle, isc_result_t eresult, void *cbarg) {
127	isc_nmsocket_tls_send_req_t *send_req =
128		(isc_nmsocket_tls_send_req_t *)cbarg;
129	isc_nmsocket_t *tlssock = NULL;
130	bool finish = send_req->finish;
131
132	REQUIRE(VALID_NMHANDLE(handle));
133	REQUIRE(VALID_NMSOCK(handle->sock));
134	REQUIRE(VALID_NMSOCK(send_req->tlssock));
135
136	tlssock = send_req->tlssock;
137	send_req->tlssock = NULL;
138
139	if (finish) {
140		tls_try_shutdown(tlssock->tlsstream.tls, true);
141	}
142
143	if (send_req->cb != NULL) {
144		INSIST(VALID_NMHANDLE(tlssock->statichandle));
145		send_req->cb(send_req->handle, eresult, send_req->cbarg);
146		isc_nmhandle_detach(&send_req->handle);
147		/* The last handle has been just detached: close the underlying
148		 * socket. */
149		if (tlssock->statichandle == NULL) {
150			finish = true;
151		}
152	}
153
154	/* We are tying to avoid a memory allocation for small write
155	 * requests. See the mirroring code in the tls_send_outgoing()
156	 * function. */
157	if (send_req->data.length > sizeof(send_req->smallbuf)) {
158		isc_mem_put(handle->sock->mgr->mctx, send_req->data.base,
159			    send_req->data.length);
160	} else {
161		INSIST(&send_req->smallbuf[0] == send_req->data.base);
162	}
163	isc_mem_put(handle->sock->mgr->mctx, send_req, sizeof(*send_req));
164	tlssock->tlsstream.nsending--;
165
166	if (finish && eresult == ISC_R_SUCCESS) {
167		tlssock->tlsstream.reading = false;
168		isc_nm_cancelread(handle);
169	} else if (eresult == ISC_R_SUCCESS) {
170		tls_do_bio(tlssock, NULL, NULL, false);
171	} else if (eresult != ISC_R_SUCCESS &&
172		   tlssock->tlsstream.state <= TLS_HANDSHAKE &&
173		   !tlssock->tlsstream.server)
174	{
175		/*
176		 * We are still waiting for the handshake to complete, but
177		 * it isn't going to happen. Call the connect callback,
178		 * passing the error code there.
179		 *
180		 * (Note: tls_failed_read_cb() calls the connect
181		 * rather than the read callback in this case.
182		 * XXX: clarify?)
183		 */
184		tls_failed_read_cb(tlssock, eresult);
185	}
186
187	isc__nmsocket_detach(&tlssock);
188}
189
190static void
191tls_failed_read_cb(isc_nmsocket_t *sock, const isc_result_t result) {
192	bool destroy = true;
193
194	REQUIRE(VALID_NMSOCK(sock));
195	REQUIRE(result != ISC_R_SUCCESS);
196
197	if (!sock->tlsstream.server &&
198	    (sock->tlsstream.state == TLS_INIT ||
199	     sock->tlsstream.state == TLS_HANDSHAKE) &&
200	    sock->connect_cb != NULL)
201	{
202		isc_nmhandle_t *handle = NULL;
203		INSIST(sock->statichandle == NULL);
204		handle = isc__nmhandle_get(sock, &sock->peer, &sock->iface);
205		tls_call_connect_cb(sock, handle, result);
206		isc__nmsocket_clearcb(sock);
207		isc_nmhandle_detach(&handle);
208	} else if (sock->recv_cb != NULL && sock->statichandle != NULL &&
209		   (sock->recv_read || result == ISC_R_TIMEDOUT))
210	{
211		isc__nm_uvreq_t *req = NULL;
212		INSIST(VALID_NMHANDLE(sock->statichandle));
213		sock->recv_read = false;
214		req = isc__nm_uvreq_get(sock->mgr, sock);
215		req->cb.recv = sock->recv_cb;
216		req->cbarg = sock->recv_cbarg;
217		isc_nmhandle_attach(sock->statichandle, &req->handle);
218		if (result != ISC_R_TIMEDOUT) {
219			isc__nmsocket_clearcb(sock);
220		}
221		isc__nm_readcb(sock, req, result);
222		if (result == ISC_R_TIMEDOUT &&
223		    (sock->outerhandle == NULL ||
224		     isc__nmsocket_timer_running(sock->outerhandle->sock)))
225		{
226			destroy = false;
227		}
228	}
229
230	if (destroy) {
231		isc__nmsocket_prep_destroy(sock);
232	}
233}
234
235static void
236async_tls_do_bio(isc_nmsocket_t *sock) {
237	isc__netievent_tlsdobio_t *ievent =
238		isc__nm_get_netievent_tlsdobio(sock->mgr, sock);
239	isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid],
240			       (isc__netievent_t *)ievent);
241}
242
243static int
244tls_send_outgoing(isc_nmsocket_t *sock, bool finish, isc_nmhandle_t *tlshandle,
245		  isc_nm_cb_t cb, void *cbarg) {
246	isc_nmsocket_tls_send_req_t *send_req = NULL;
247	int pending;
248	int rv;
249	size_t len = 0;
250
251	if (inactive(sock)) {
252		if (cb != NULL) {
253			INSIST(VALID_NMHANDLE(tlshandle));
254			cb(tlshandle, ISC_R_CANCELED, cbarg);
255		}
256		return (0);
257	}
258
259	if (finish) {
260		tls_try_shutdown(sock->tlsstream.tls, false);
261		tls_keep_client_tls_session(sock);
262	}
263
264	pending = BIO_pending(sock->tlsstream.bio_out);
265	if (pending <= 0) {
266		return (pending);
267	}
268
269	/* TODO Should we keep track of these requests in a list? */
270	if ((unsigned int)pending > TLS_BUF_SIZE) {
271		pending = TLS_BUF_SIZE;
272	}
273
274	send_req = isc_mem_get(sock->mgr->mctx, sizeof(*send_req));
275	*send_req = (isc_nmsocket_tls_send_req_t){ .finish = finish,
276						   .data.length = pending };
277
278	/* Let's try to avoid a memory allocation for small write requests */
279	if ((size_t)pending > sizeof(send_req->smallbuf)) {
280		send_req->data.base = isc_mem_get(sock->mgr->mctx, pending);
281	} else {
282		send_req->data.base = &send_req->smallbuf[0];
283	}
284
285	isc__nmsocket_attach(sock, &send_req->tlssock);
286	if (cb != NULL) {
287		send_req->cb = cb;
288		send_req->cbarg = cbarg;
289		isc_nmhandle_attach(tlshandle, &send_req->handle);
290	}
291
292	rv = BIO_read_ex(sock->tlsstream.bio_out, send_req->data.base, pending,
293			 &len);
294	/* There's something pending, read must succeed */
295	RUNTIME_CHECK(rv == 1);
296
297	INSIST(VALID_NMHANDLE(sock->outerhandle));
298
299	sock->tlsstream.nsending++;
300	isc_nm_send(sock->outerhandle, &send_req->data, tls_senddone, send_req);
301
302	return (pending);
303}
304
305static int
306tls_process_outgoing(isc_nmsocket_t *sock, bool finish,
307		     isc__nm_uvreq_t *send_data) {
308	int pending;
309
310	bool received_shutdown = ((SSL_get_shutdown(sock->tlsstream.tls) &
311				   SSL_RECEIVED_SHUTDOWN) != 0);
312	bool sent_shutdown = ((SSL_get_shutdown(sock->tlsstream.tls) &
313			       SSL_SENT_SHUTDOWN) != 0);
314
315	if (received_shutdown && !sent_shutdown) {
316		finish = true;
317	}
318
319	/* Data from TLS to network */
320	if (send_data != NULL) {
321		pending = tls_send_outgoing(sock, finish, send_data->handle,
322					    send_data->cb.send,
323					    send_data->cbarg);
324	} else {
325		pending = tls_send_outgoing(sock, finish, NULL, NULL, NULL);
326	}
327
328	return (pending);
329}
330
331static int
332tls_try_handshake(isc_nmsocket_t *sock, isc_result_t *presult) {
333	int rv = 0;
334	isc_nmhandle_t *tlshandle = NULL;
335
336	REQUIRE(sock->tlsstream.state == TLS_HANDSHAKE);
337
338	if (SSL_is_init_finished(sock->tlsstream.tls) == 1) {
339		return (0);
340	}
341
342	rv = SSL_do_handshake(sock->tlsstream.tls);
343	if (rv == 1) {
344		isc_result_t result = ISC_R_SUCCESS;
345		INSIST(SSL_is_init_finished(sock->tlsstream.tls) == 1);
346		INSIST(sock->statichandle == NULL);
347		isc__nmsocket_log_tls_session_reuse(sock, sock->tlsstream.tls);
348		tlshandle = isc__nmhandle_get(sock, &sock->peer, &sock->iface);
349
350		if (isc__nm_closing(sock)) {
351			result = ISC_R_SHUTTINGDOWN;
352		}
353
354		if (sock->tlsstream.server) {
355			if (isc__nmsocket_closing(sock->listener)) {
356				result = ISC_R_CANCELED;
357			} else if (result == ISC_R_SUCCESS) {
358				result = sock->listener->accept_cb(
359					tlshandle, result,
360					sock->listener->accept_cbarg);
361			}
362		} else {
363			tls_call_connect_cb(sock, tlshandle, result);
364		}
365		isc_nmhandle_detach(&tlshandle);
366		sock->tlsstream.state = TLS_IO;
367
368		if (presult != NULL) {
369			*presult = result;
370		}
371	}
372
373	return (rv);
374}
375
376static bool
377tls_try_to_close_unused_socket(isc_nmsocket_t *sock) {
378	if (sock->tlsstream.state > TLS_HANDSHAKE &&
379	    sock->statichandle == NULL && sock->tlsstream.nsending == 0)
380	{
381		/*
382		 * It seems that no action on the socket has been
383		 * scheduled on some point after the handshake, let's
384		 * close the connection.
385		 */
386		isc__nmsocket_prep_destroy(sock);
387		return (true);
388	}
389
390	return (false);
391}
392
393static void
394tls_do_bio(isc_nmsocket_t *sock, isc_region_t *received_data,
395	   isc__nm_uvreq_t *send_data, bool finish) {
396	isc_result_t result = ISC_R_SUCCESS;
397	int pending, tls_status = SSL_ERROR_NONE;
398	int rv = 0;
399	size_t len = 0;
400	int saved_errno = 0;
401
402	REQUIRE(VALID_NMSOCK(sock));
403	REQUIRE(sock->tid == isc_nm_tid());
404
405	/* We will resume read if TLS layer wants us to */
406	if (sock->tlsstream.reading && sock->outerhandle) {
407		REQUIRE(VALID_NMHANDLE(sock->outerhandle));
408		isc_nm_pauseread(sock->outerhandle);
409	}
410
411	/*
412	 * Clear the TLS error queue so that SSL_get_error() and SSL I/O
413	 * routine calls will not get affected by prior error statuses.
414	 *
415	 * See here:
416	 * https://www.openssl.org/docs/man3.0/man3/SSL_get_error.html
417	 *
418	 * In particular, it mentions the following:
419	 *
420	 * The current thread's error queue must be empty before the
421	 * TLS/SSL I/O operation is attempted, or SSL_get_error() will not
422	 * work reliably.
423	 *
424	 * As we use the result of SSL_get_error() to decide on I/O
425	 * operations, we need to ensure that it works reliably by
426	 * cleaning the error queue.
427	 *
428	 * The sum of details: https://stackoverflow.com/a/37980911
429	 */
430	ERR_clear_error();
431
432	if (sock->tlsstream.state == TLS_INIT) {
433		INSIST(received_data == NULL && send_data == NULL);
434		if (sock->tlsstream.server) {
435			SSL_set_accept_state(sock->tlsstream.tls);
436		} else {
437			SSL_set_connect_state(sock->tlsstream.tls);
438		}
439		sock->tlsstream.state = TLS_HANDSHAKE;
440		rv = tls_try_handshake(sock, NULL);
441		INSIST(SSL_is_init_finished(sock->tlsstream.tls) == 0);
442	} else if (sock->tlsstream.state == TLS_CLOSED) {
443		return;
444	} else { /* initialised and doing I/O */
445		if (received_data != NULL) {
446			INSIST(send_data == NULL);
447			rv = BIO_write_ex(sock->tlsstream.bio_in,
448					  received_data->base,
449					  received_data->length, &len);
450			if (rv <= 0 || len != received_data->length) {
451				result = ISC_R_TLSERROR;
452#if defined(NETMGR_TRACE) && defined(NETMGR_TRACE_VERBOSE)
453				saved_errno = errno;
454#endif
455				goto error;
456			}
457
458			/*
459			 * Only after doing the IO we can check whether SSL
460			 * handshake is done.
461			 */
462			if (sock->tlsstream.state == TLS_HANDSHAKE) {
463				isc_result_t hs_result = ISC_R_UNSET;
464				rv = tls_try_handshake(sock, &hs_result);
465				if (sock->tlsstream.state == TLS_IO &&
466				    hs_result != ISC_R_SUCCESS)
467				{
468					/*
469					 * The accept callback has been called
470					 * unsuccessfully. Let's try to shut
471					 * down the TLS connection gracefully.
472					 */
473					INSIST(SSL_is_init_finished(
474						       sock->tlsstream.tls) ==
475					       1);
476					finish = true;
477				}
478			}
479		} else if (send_data != NULL) {
480			INSIST(received_data == NULL);
481			INSIST(sock->tlsstream.state > TLS_HANDSHAKE);
482			bool received_shutdown =
483				((SSL_get_shutdown(sock->tlsstream.tls) &
484				  SSL_RECEIVED_SHUTDOWN) != 0);
485			bool sent_shutdown =
486				((SSL_get_shutdown(sock->tlsstream.tls) &
487				  SSL_SENT_SHUTDOWN) != 0);
488			rv = SSL_write_ex(sock->tlsstream.tls,
489					  send_data->uvbuf.base,
490					  send_data->uvbuf.len, &len);
491			if (rv != 1 || len != send_data->uvbuf.len) {
492				result = received_shutdown || sent_shutdown
493						 ? ISC_R_CANCELED
494						 : ISC_R_TLSERROR;
495				send_data->cb.send(send_data->handle, result,
496						   send_data->cbarg);
497				send_data = NULL;
498				return;
499			}
500		}
501
502		/* Decrypt and pass data from network to client */
503		if (sock->tlsstream.state >= TLS_IO && sock->recv_cb != NULL &&
504		    !atomic_load(&sock->readpaused) &&
505		    sock->statichandle != NULL && !finish)
506		{
507			uint8_t recv_buf[TLS_BUF_SIZE];
508			INSIST(sock->tlsstream.state > TLS_HANDSHAKE);
509			while ((rv = SSL_read_ex(sock->tlsstream.tls, recv_buf,
510						 TLS_BUF_SIZE, &len)) == 1)
511			{
512				isc_region_t region;
513				region = (isc_region_t){ .base = &recv_buf[0],
514							 .length = len };
515
516				INSIST(VALID_NMHANDLE(sock->statichandle));
517				sock->recv_cb(sock->statichandle, ISC_R_SUCCESS,
518					      &region, sock->recv_cbarg);
519				/* The handle could have been detached in
520				 * sock->recv_cb, making the sock->statichandle
521				 * nullified (it happens in netmgr.c). If it is
522				 * the case, then it means that we are not
523				 * interested in keeping the connection alive
524				 * anymore. Let's shut down the SSL session,
525				 * send what we have in the SSL buffers,
526				 * and close the connection.
527				 */
528				if (sock->statichandle == NULL) {
529					finish = true;
530					break;
531				} else if (sock->recv_cb == NULL) {
532					/*
533					 * The 'sock->recv_cb' might have been
534					 * nullified during the call to
535					 * 'sock->recv_cb'. That could happen,
536					 * indirectly when wrapping up.
537					 *
538					 * In this case, let's close the TLS
539					 * connection.
540					 */
541					finish = true;
542					break;
543				} else if (atomic_load(&sock->readpaused)) {
544					/*
545					 * Reading has been paused from withing
546					 * the context of read callback - stop
547					 * processing incoming data.
548					 */
549					break;
550				}
551			}
552		}
553	}
554	errno = 0;
555	tls_status = SSL_get_error(sock->tlsstream.tls, rv);
556	saved_errno = errno;
557
558	/* See "BUGS" section at:
559	 * https://www.openssl.org/docs/man1.1.1/man3/SSL_get_error.html
560	 *
561	 * It is mentioned there that when TLS status equals
562	 * SSL_ERROR_SYSCALL AND errno == 0 it means that underlying
563	 * transport layer returned EOF prematurely.  However, we are
564	 * managing the transport ourselves, so we should just resume
565	 * reading from the TCP socket.
566	 *
567	 * It seems that this case has been handled properly on modern
568	 * versions of OpenSSL. That being said, the situation goes in
569	 * line with the manual: it is briefly mentioned there that
570	 * SSL_ERROR_SYSCALL might be returned not only in a case of
571	 * low-level errors (like system call failures).
572	 */
573	if (tls_status == SSL_ERROR_SYSCALL && saved_errno == 0 &&
574	    received_data == NULL && send_data == NULL && finish == false)
575	{
576		tls_status = SSL_ERROR_WANT_READ;
577	}
578
579	pending = tls_process_outgoing(sock, finish, send_data);
580	if (pending > 0 && tls_status != SSL_ERROR_SSL) {
581		/* We'll continue in tls_senddone */
582		return;
583	}
584
585	switch (tls_status) {
586	case SSL_ERROR_NONE:
587	case SSL_ERROR_ZERO_RETURN:
588		(void)tls_try_to_close_unused_socket(sock);
589		return;
590	case SSL_ERROR_WANT_WRITE:
591		if (sock->tlsstream.nsending == 0) {
592			/*
593			 * Launch tls_do_bio asynchronously. If we're sending
594			 * already the send callback will call it.
595			 */
596			async_tls_do_bio(sock);
597		}
598		return;
599	case SSL_ERROR_WANT_READ:
600		if (tls_try_to_close_unused_socket(sock) ||
601		    sock->outerhandle == NULL || atomic_load(&sock->readpaused))
602		{
603			return;
604		}
605
606		INSIST(VALID_NMHANDLE(sock->outerhandle));
607
608		if (sock->tlsstream.reading) {
609			isc_nm_resumeread(sock->outerhandle);
610		} else if (sock->tlsstream.state == TLS_HANDSHAKE) {
611			sock->tlsstream.reading = true;
612			isc_nm_read(sock->outerhandle, tls_readcb, sock);
613		}
614		return;
615	default:
616		result = tls_error_to_result(tls_status, sock->tlsstream.state,
617					     sock->tlsstream.tls);
618		break;
619	}
620
621error:
622#if defined(NETMGR_TRACE) && defined(NETMGR_TRACE_VERBOSE)
623	isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_NETMGR,
624		      ISC_LOG_NOTICE,
625		      "SSL error in BIO: %d %s (errno: %d). Arguments: "
626		      "received_data: %p, "
627		      "send_data: %p, finish: %s",
628		      tls_status, isc_result_totext(result), saved_errno,
629		      received_data, send_data, finish ? "true" : "false");
630#endif
631	tls_failed_read_cb(sock, result);
632}
633
634static void
635tls_readcb(isc_nmhandle_t *handle, isc_result_t result, isc_region_t *region,
636	   void *cbarg) {
637	isc_nmsocket_t *tlssock = (isc_nmsocket_t *)cbarg;
638
639	REQUIRE(VALID_NMSOCK(tlssock));
640	REQUIRE(VALID_NMHANDLE(handle));
641	REQUIRE(tlssock->tid == isc_nm_tid());
642
643	if (result != ISC_R_SUCCESS) {
644		tls_failed_read_cb(tlssock, result);
645		return;
646	}
647
648	tls_do_bio(tlssock, region, NULL, false);
649}
650
651static isc_result_t
652initialize_tls(isc_nmsocket_t *sock, bool server) {
653	REQUIRE(sock->tid == isc_nm_tid());
654
655	sock->tlsstream.bio_in = BIO_new(BIO_s_mem());
656	if (sock->tlsstream.bio_in == NULL) {
657		isc_tls_free(&sock->tlsstream.tls);
658		return (ISC_R_TLSERROR);
659	}
660	sock->tlsstream.bio_out = BIO_new(BIO_s_mem());
661	if (sock->tlsstream.bio_out == NULL) {
662		BIO_free_all(sock->tlsstream.bio_in);
663		sock->tlsstream.bio_in = NULL;
664		isc_tls_free(&sock->tlsstream.tls);
665		return (ISC_R_TLSERROR);
666	}
667
668	if (BIO_set_mem_eof_return(sock->tlsstream.bio_in, EOF) != 1 ||
669	    BIO_set_mem_eof_return(sock->tlsstream.bio_out, EOF) != 1)
670	{
671		goto error;
672	}
673
674	SSL_set_bio(sock->tlsstream.tls, sock->tlsstream.bio_in,
675		    sock->tlsstream.bio_out);
676	sock->tlsstream.server = server;
677	sock->tlsstream.nsending = 0;
678	sock->tlsstream.state = TLS_INIT;
679	return (ISC_R_SUCCESS);
680error:
681	isc_tls_free(&sock->tlsstream.tls);
682	sock->tlsstream.bio_out = sock->tlsstream.bio_in = NULL;
683	return (ISC_R_TLSERROR);
684}
685
686static isc_result_t
687tlslisten_acceptcb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
688	isc_nmsocket_t *tlslistensock = (isc_nmsocket_t *)cbarg;
689	isc_nmsocket_t *tlssock = NULL;
690	isc_tlsctx_t *tlsctx = NULL;
691	int tid;
692
693	/* If accept() was unsuccessful we can't do anything */
694	if (result != ISC_R_SUCCESS) {
695		return (result);
696	}
697
698	REQUIRE(VALID_NMHANDLE(handle));
699	REQUIRE(VALID_NMSOCK(handle->sock));
700	REQUIRE(VALID_NMSOCK(tlslistensock));
701	REQUIRE(tlslistensock->type == isc_nm_tlslistener);
702
703	if (isc__nmsocket_closing(handle->sock) ||
704	    isc__nmsocket_closing(tlslistensock) ||
705	    !atomic_load(&tlslistensock->listening))
706	{
707		return (ISC_R_CANCELED);
708	}
709
710	/*
711	 * We need to create a 'wrapper' tlssocket for this connection.
712	 */
713	tlssock = isc_mem_get(handle->sock->mgr->mctx, sizeof(*tlssock));
714	isc__nmsocket_init(tlssock, handle->sock->mgr, isc_nm_tlssocket,
715			   &handle->sock->iface);
716
717	tid = isc_nm_tid();
718	/* We need to initialize SSL now to reference SSL_CTX properly */
719	tlsctx = tls_get_listener_tlsctx(tlslistensock, tid);
720	RUNTIME_CHECK(tlsctx != NULL);
721	isc_tlsctx_attach(tlsctx, &tlssock->tlsstream.ctx);
722	tlssock->tlsstream.tls = isc_tls_create(tlssock->tlsstream.ctx);
723	if (tlssock->tlsstream.tls == NULL) {
724		atomic_store(&tlssock->closed, true);
725		isc_tlsctx_free(&tlssock->tlsstream.ctx);
726		isc__nmsocket_detach(&tlssock);
727		return (ISC_R_TLSERROR);
728	}
729
730	tlssock->extrahandlesize = tlslistensock->extrahandlesize;
731	isc__nmsocket_attach(tlslistensock, &tlssock->listener);
732	isc_nmhandle_attach(handle, &tlssock->outerhandle);
733	tlssock->peer = handle->sock->peer;
734	tlssock->read_timeout = atomic_load(&handle->sock->mgr->init);
735	tlssock->tid = tid;
736
737	/*
738	 * Hold a reference to tlssock in the TCP socket: it will
739	 * detached in isc__nm_tls_cleanup_data().
740	 */
741	handle->sock->tlsstream.tlssocket = tlssock;
742
743	result = initialize_tls(tlssock, true);
744	RUNTIME_CHECK(result == ISC_R_SUCCESS);
745	/* TODO: catch failure code, detach tlssock, and log the error */
746
747	tls_do_bio(tlssock, NULL, NULL, false);
748	return (result);
749}
750
751isc_result_t
752isc_nm_listentls(isc_nm_t *mgr, isc_sockaddr_t *iface,
753		 isc_nm_accept_cb_t accept_cb, void *accept_cbarg,
754		 size_t extrahandlesize, int backlog, isc_quota_t *quota,
755		 SSL_CTX *sslctx, isc_nmsocket_t **sockp) {
756	isc_result_t result;
757	isc_nmsocket_t *tlssock = NULL;
758	isc_nmsocket_t *tsock = NULL;
759
760	REQUIRE(VALID_NM(mgr));
761	if (atomic_load(&mgr->closing)) {
762		return (ISC_R_SHUTTINGDOWN);
763	}
764
765	tlssock = isc_mem_get(mgr->mctx, sizeof(*tlssock));
766
767	isc__nmsocket_init(tlssock, mgr, isc_nm_tlslistener, iface);
768	tlssock->result = ISC_R_UNSET;
769	tlssock->accept_cb = accept_cb;
770	tlssock->accept_cbarg = accept_cbarg;
771	tlssock->extrahandlesize = extrahandlesize;
772	tls_init_listener_tlsctx(tlssock, sslctx);
773	tlssock->tlsstream.tls = NULL;
774
775	/*
776	 * tlssock will be a TLS 'wrapper' around an unencrypted stream.
777	 * We set tlssock->outer to a socket listening for a TCP connection.
778	 */
779	result = isc_nm_listentcp(mgr, iface, tlslisten_acceptcb, tlssock,
780				  extrahandlesize, backlog, quota,
781				  &tlssock->outer);
782	if (result != ISC_R_SUCCESS) {
783		atomic_store(&tlssock->closed, true);
784		isc__nmsocket_detach(&tlssock);
785		return (result);
786	}
787
788	/* wait for listen result */
789	isc__nmsocket_attach(tlssock->outer, &tsock);
790	tlssock->result = result;
791	atomic_store(&tlssock->active, true);
792	INSIST(tlssock->outer->tlsstream.tlslistener == NULL);
793	isc__nmsocket_attach(tlssock, &tlssock->outer->tlsstream.tlslistener);
794	isc__nmsocket_detach(&tsock);
795	INSIST(result != ISC_R_UNSET);
796	tlssock->nchildren = tlssock->outer->nchildren;
797
798	isc__nmsocket_barrier_init(tlssock);
799	atomic_init(&tlssock->rchildren, tlssock->nchildren);
800
801	if (result == ISC_R_SUCCESS) {
802		atomic_store(&tlssock->listening, true);
803		*sockp = tlssock;
804	}
805
806	return (result);
807}
808
809void
810isc__nm_async_tlssend(isc__networker_t *worker, isc__netievent_t *ev0) {
811	isc__netievent_tlssend_t *ievent = (isc__netievent_tlssend_t *)ev0;
812	isc_nmsocket_t *sock = ievent->sock;
813	isc__nm_uvreq_t *req = ievent->req;
814
815	REQUIRE(VALID_UVREQ(req));
816	REQUIRE(sock->tid == isc_nm_tid());
817
818	UNUSED(worker);
819
820	ievent->req = NULL;
821
822	if (inactive(sock)) {
823		req->cb.send(req->handle, ISC_R_CANCELED, req->cbarg);
824		goto done;
825	}
826
827	tls_do_bio(sock, NULL, req, false);
828done:
829	isc__nm_uvreq_put(&req, sock);
830	return;
831}
832
833void
834isc__nm_tls_send(isc_nmhandle_t *handle, const isc_region_t *region,
835		 isc_nm_cb_t cb, void *cbarg) {
836	isc__netievent_tlssend_t *ievent = NULL;
837	isc__nm_uvreq_t *uvreq = NULL;
838	isc_nmsocket_t *sock = NULL;
839
840	REQUIRE(VALID_NMHANDLE(handle));
841	REQUIRE(VALID_NMSOCK(handle->sock));
842
843	sock = handle->sock;
844
845	REQUIRE(sock->type == isc_nm_tlssocket);
846
847	uvreq = isc__nm_uvreq_get(sock->mgr, sock);
848	isc_nmhandle_attach(handle, &uvreq->handle);
849	uvreq->cb.send = cb;
850	uvreq->cbarg = cbarg;
851	uvreq->uvbuf.base = (char *)region->base;
852	uvreq->uvbuf.len = region->length;
853
854	/*
855	 * We need to create an event and pass it using async channel
856	 */
857	ievent = isc__nm_get_netievent_tlssend(sock->mgr, sock, uvreq);
858	isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid],
859			       (isc__netievent_t *)ievent);
860}
861
862void
863isc__nm_async_tlsstartread(isc__networker_t *worker, isc__netievent_t *ev0) {
864	isc__netievent_tlsstartread_t *ievent =
865		(isc__netievent_tlsstartread_t *)ev0;
866	isc_nmsocket_t *sock = ievent->sock;
867
868	REQUIRE(sock->tid == isc_nm_tid());
869
870	UNUSED(worker);
871
872	tls_do_bio(sock, NULL, NULL, false);
873}
874
875void
876isc__nm_tls_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg) {
877	isc__netievent_tlsstartread_t *ievent = NULL;
878	isc_nmsocket_t *sock = NULL;
879
880	REQUIRE(VALID_NMHANDLE(handle));
881
882	sock = handle->sock;
883	REQUIRE(VALID_NMSOCK(sock));
884	REQUIRE(sock->statichandle == handle);
885	REQUIRE(sock->tid == isc_nm_tid());
886	REQUIRE(sock->recv_cb == NULL);
887
888	if (inactive(sock)) {
889		cb(handle, ISC_R_CANCELED, NULL, cbarg);
890		return;
891	}
892
893	sock->recv_cb = cb;
894	sock->recv_cbarg = cbarg;
895	sock->recv_read = true;
896
897	ievent = isc__nm_get_netievent_tlsstartread(sock->mgr, sock);
898	isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid],
899			       (isc__netievent_t *)ievent);
900}
901
902void
903isc__nm_tls_pauseread(isc_nmhandle_t *handle) {
904	REQUIRE(VALID_NMHANDLE(handle));
905	REQUIRE(VALID_NMSOCK(handle->sock));
906
907	if (atomic_compare_exchange_strong(&handle->sock->readpaused,
908					   &(bool){ false }, true))
909	{
910		if (handle->sock->outerhandle != NULL) {
911			isc_nm_pauseread(handle->sock->outerhandle);
912		}
913	}
914}
915
916void
917isc__nm_tls_resumeread(isc_nmhandle_t *handle) {
918	REQUIRE(VALID_NMHANDLE(handle));
919	REQUIRE(VALID_NMSOCK(handle->sock));
920
921	if (!atomic_compare_exchange_strong(&handle->sock->readpaused,
922					    &(bool){ true }, false))
923	{
924		if (inactive(handle->sock)) {
925			return;
926		}
927
928		async_tls_do_bio(handle->sock);
929	}
930}
931
932static void
933tls_close_direct(isc_nmsocket_t *sock) {
934	REQUIRE(VALID_NMSOCK(sock));
935	REQUIRE(sock->tid == isc_nm_tid());
936	/*
937	 * At this point we're certain that there are no
938	 * external references, we can close everything.
939	 */
940	if (sock->outerhandle != NULL) {
941		isc_nm_pauseread(sock->outerhandle);
942		isc__nmsocket_clearcb(sock->outerhandle->sock);
943		isc_nmhandle_detach(&sock->outerhandle);
944	}
945
946	if (sock->listener != NULL) {
947		isc__nmsocket_detach(&sock->listener);
948	}
949
950	/* Further cleanup performed in isc__nm_tls_cleanup_data() */
951	atomic_store(&sock->closed, true);
952	atomic_store(&sock->active, false);
953	sock->tlsstream.state = TLS_CLOSED;
954}
955
956void
957isc__nm_tls_close(isc_nmsocket_t *sock) {
958	isc__netievent_tlsclose_t *ievent = NULL;
959
960	REQUIRE(VALID_NMSOCK(sock));
961	REQUIRE(sock->type == isc_nm_tlssocket);
962
963	if (!atomic_compare_exchange_strong(&sock->closing, &(bool){ false },
964					    true))
965	{
966		return;
967	}
968
969	ievent = isc__nm_get_netievent_tlsclose(sock->mgr, sock);
970	isc__nm_maybe_enqueue_ievent(&sock->mgr->workers[sock->tid],
971				     (isc__netievent_t *)ievent);
972}
973
974void
975isc__nm_async_tlsclose(isc__networker_t *worker, isc__netievent_t *ev0) {
976	isc__netievent_tlsclose_t *ievent = (isc__netievent_tlsclose_t *)ev0;
977	isc_nmsocket_t *sock = ievent->sock;
978
979	REQUIRE(ievent->sock->tid == isc_nm_tid());
980
981	UNUSED(worker);
982
983	tls_close_direct(sock);
984}
985
986void
987isc__nm_tls_stoplistening(isc_nmsocket_t *sock) {
988	REQUIRE(VALID_NMSOCK(sock));
989	REQUIRE(sock->type == isc_nm_tlslistener);
990
991	isc__nmsocket_stop(sock);
992}
993
994static void
995tcp_connected(isc_nmhandle_t *handle, isc_result_t result, void *cbarg);
996
997void
998isc_nm_tlsconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
999		  isc_nm_cb_t cb, void *cbarg, isc_tlsctx_t *ctx,
1000		  isc_tlsctx_client_session_cache_t *client_sess_cache,
1001		  unsigned int timeout, size_t extrahandlesize) {
1002	isc_nmsocket_t *nsock = NULL;
1003#if defined(NETMGR_TRACE) && defined(NETMGR_TRACE_VERBOSE)
1004	fprintf(stderr, "TLS: isc_nm_tlsconnect(): in net thread: %s\n",
1005		isc__nm_in_netthread() ? "yes" : "no");
1006#endif /* NETMGR_TRACE */
1007
1008	REQUIRE(VALID_NM(mgr));
1009
1010	if (atomic_load(&mgr->closing)) {
1011		cb(NULL, ISC_R_SHUTTINGDOWN, cbarg);
1012		return;
1013	}
1014
1015	nsock = isc_mem_get(mgr->mctx, sizeof(*nsock));
1016	isc__nmsocket_init(nsock, mgr, isc_nm_tlssocket, local);
1017	nsock->extrahandlesize = extrahandlesize;
1018	nsock->result = ISC_R_UNSET;
1019	nsock->connect_cb = cb;
1020	nsock->connect_cbarg = cbarg;
1021	nsock->connect_timeout = timeout;
1022	isc_tlsctx_attach(ctx, &nsock->tlsstream.ctx);
1023	atomic_init(&nsock->client, true);
1024	if (client_sess_cache != NULL) {
1025		INSIST(isc_tlsctx_client_session_cache_getctx(
1026			       client_sess_cache) == ctx);
1027		isc_tlsctx_client_session_cache_attach(
1028			client_sess_cache, &nsock->tlsstream.client_sess_cache);
1029	}
1030
1031	isc_nm_tcpconnect(mgr, local, peer, tcp_connected, nsock,
1032			  nsock->connect_timeout, 0);
1033}
1034
1035static void
1036tcp_connected(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
1037	isc_nmsocket_t *tlssock = (isc_nmsocket_t *)cbarg;
1038	isc_nmhandle_t *tlshandle = NULL;
1039
1040	REQUIRE(VALID_NMSOCK(tlssock));
1041
1042	tlssock->tid = isc_nm_tid();
1043	if (result != ISC_R_SUCCESS) {
1044		goto error;
1045	}
1046
1047	INSIST(VALID_NMHANDLE(handle));
1048
1049	tlssock->iface = handle->sock->iface;
1050	tlssock->peer = handle->sock->peer;
1051	if (isc__nm_closing(tlssock)) {
1052		result = ISC_R_SHUTTINGDOWN;
1053		goto error;
1054	}
1055
1056	/*
1057	 * We need to initialize SSL now to reference SSL_CTX properly.
1058	 */
1059	tlssock->tlsstream.tls = isc_tls_create(tlssock->tlsstream.ctx);
1060	if (tlssock->tlsstream.tls == NULL) {
1061		result = ISC_R_TLSERROR;
1062		goto error;
1063	}
1064
1065	result = initialize_tls(tlssock, false);
1066	if (result != ISC_R_SUCCESS) {
1067		goto error;
1068	}
1069	tlssock->peer = isc_nmhandle_peeraddr(handle);
1070	isc_nmhandle_attach(handle, &tlssock->outerhandle);
1071	atomic_store(&tlssock->active, true);
1072
1073	if (tlssock->tlsstream.client_sess_cache != NULL) {
1074		isc_tlsctx_client_session_cache_reuse_sockaddr(
1075			tlssock->tlsstream.client_sess_cache, &tlssock->peer,
1076			tlssock->tlsstream.tls);
1077	}
1078
1079	/*
1080	 * Hold a reference to tlssock in the TCP socket: it will
1081	 * detached in isc__nm_tls_cleanup_data().
1082	 */
1083	handle->sock->tlsstream.tlssocket = tlssock;
1084
1085	tls_do_bio(tlssock, NULL, NULL, false);
1086	return;
1087error:
1088	tlshandle = isc__nmhandle_get(tlssock, NULL, NULL);
1089	atomic_store(&tlssock->closed, true);
1090	tls_call_connect_cb(tlssock, tlshandle, result);
1091	isc_nmhandle_detach(&tlshandle);
1092	isc__nmsocket_detach(&tlssock);
1093}
1094
1095static void
1096tls_cancelread(isc_nmsocket_t *sock) {
1097	if (!inactive(sock) && sock->tlsstream.state == TLS_IO) {
1098		tls_do_bio(sock, NULL, NULL, true);
1099	} else if (sock->outerhandle != NULL) {
1100		sock->tlsstream.reading = false;
1101		isc_nm_cancelread(sock->outerhandle);
1102	}
1103}
1104
1105void
1106isc__nm_tls_cancelread(isc_nmhandle_t *handle) {
1107	isc_nmsocket_t *sock = NULL;
1108	isc__netievent_tlscancel_t *ievent = NULL;
1109
1110	REQUIRE(VALID_NMHANDLE(handle));
1111
1112	sock = handle->sock;
1113
1114	REQUIRE(sock->type == isc_nm_tlssocket);
1115
1116	if (sock->tid == isc_nm_tid()) {
1117		tls_cancelread(sock);
1118	} else {
1119		ievent = isc__nm_get_netievent_tlscancel(sock->mgr, sock,
1120							 handle);
1121		isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid],
1122				       (isc__netievent_t *)ievent);
1123	}
1124}
1125
1126void
1127isc__nm_async_tlscancel(isc__networker_t *worker, isc__netievent_t *ev0) {
1128	isc__netievent_tlscancel_t *ievent = (isc__netievent_tlscancel_t *)ev0;
1129	isc_nmsocket_t *sock = ievent->sock;
1130
1131	REQUIRE(VALID_NMSOCK(sock));
1132	REQUIRE(worker->id == sock->tid);
1133	REQUIRE(sock->tid == isc_nm_tid());
1134
1135	UNUSED(worker);
1136	tls_cancelread(sock);
1137}
1138
1139void
1140isc__nm_async_tlsdobio(isc__networker_t *worker, isc__netievent_t *ev0) {
1141	isc__netievent_tlsdobio_t *ievent = (isc__netievent_tlsdobio_t *)ev0;
1142
1143	UNUSED(worker);
1144
1145	tls_do_bio(ievent->sock, NULL, NULL, false);
1146}
1147
1148void
1149isc__nm_tls_cleanup_data(isc_nmsocket_t *sock) {
1150	if (sock->type == isc_nm_tcplistener &&
1151	    sock->tlsstream.tlslistener != NULL)
1152	{
1153		isc__nmsocket_detach(&sock->tlsstream.tlslistener);
1154	} else if (sock->type == isc_nm_tlslistener) {
1155		tls_cleanup_listener_tlsctx(sock);
1156	} else if (sock->type == isc_nm_tlssocket) {
1157		if (sock->tlsstream.tls != NULL) {
1158			/*
1159			 * Let's shut down the TLS session properly so that
1160			 * the session will remain resumable, if required.
1161			 */
1162			tls_try_shutdown(sock->tlsstream.tls, true);
1163			tls_keep_client_tls_session(sock);
1164			isc_tls_free(&sock->tlsstream.tls);
1165			/* These are destroyed when we free SSL */
1166			sock->tlsstream.bio_out = NULL;
1167			sock->tlsstream.bio_in = NULL;
1168		}
1169		if (sock->tlsstream.ctx != NULL) {
1170			isc_tlsctx_free(&sock->tlsstream.ctx);
1171		}
1172		if (sock->tlsstream.client_sess_cache != NULL) {
1173			INSIST(atomic_load(&sock->client));
1174			isc_tlsctx_client_session_cache_detach(
1175				&sock->tlsstream.client_sess_cache);
1176		}
1177	} else if (sock->type == isc_nm_tcpsocket &&
1178		   sock->tlsstream.tlssocket != NULL)
1179	{
1180		/*
1181		 * The TLS socket can't be destroyed until its underlying TCP
1182		 * socket is, to avoid possible use-after-free errors.
1183		 */
1184		isc__nmsocket_detach(&sock->tlsstream.tlssocket);
1185	}
1186}
1187
1188void
1189isc__nm_tls_cleartimeout(isc_nmhandle_t *handle) {
1190	isc_nmsocket_t *sock = NULL;
1191
1192	REQUIRE(VALID_NMHANDLE(handle));
1193	REQUIRE(VALID_NMSOCK(handle->sock));
1194	REQUIRE(handle->sock->type == isc_nm_tlssocket);
1195
1196	sock = handle->sock;
1197	if (sock->outerhandle != NULL) {
1198		INSIST(VALID_NMHANDLE(sock->outerhandle));
1199		isc_nmhandle_cleartimeout(sock->outerhandle);
1200	}
1201}
1202
1203void
1204isc__nm_tls_settimeout(isc_nmhandle_t *handle, uint32_t timeout) {
1205	isc_nmsocket_t *sock = NULL;
1206
1207	REQUIRE(VALID_NMHANDLE(handle));
1208	REQUIRE(VALID_NMSOCK(handle->sock));
1209	REQUIRE(handle->sock->type == isc_nm_tlssocket);
1210
1211	sock = handle->sock;
1212	if (sock->outerhandle != NULL) {
1213		INSIST(VALID_NMHANDLE(sock->outerhandle));
1214		isc_nmhandle_settimeout(sock->outerhandle, timeout);
1215	}
1216}
1217
1218void
1219isc__nmhandle_tls_keepalive(isc_nmhandle_t *handle, bool value) {
1220	isc_nmsocket_t *sock = NULL;
1221
1222	REQUIRE(VALID_NMHANDLE(handle));
1223	REQUIRE(VALID_NMSOCK(handle->sock));
1224	REQUIRE(handle->sock->type == isc_nm_tlssocket);
1225
1226	sock = handle->sock;
1227	if (sock->outerhandle != NULL) {
1228		INSIST(VALID_NMHANDLE(sock->outerhandle));
1229
1230		isc_nmhandle_keepalive(sock->outerhandle, value);
1231	}
1232}
1233
1234void
1235isc__nmhandle_tls_setwritetimeout(isc_nmhandle_t *handle,
1236				  uint64_t write_timeout) {
1237	isc_nmsocket_t *sock = NULL;
1238
1239	REQUIRE(VALID_NMHANDLE(handle));
1240	REQUIRE(VALID_NMSOCK(handle->sock));
1241	REQUIRE(handle->sock->type == isc_nm_tlssocket);
1242
1243	sock = handle->sock;
1244	if (sock->outerhandle != NULL) {
1245		INSIST(VALID_NMHANDLE(sock->outerhandle));
1246
1247		isc_nmhandle_setwritetimeout(sock->outerhandle, write_timeout);
1248	}
1249}
1250
1251const char *
1252isc__nm_tls_verify_tls_peer_result_string(const isc_nmhandle_t *handle) {
1253	isc_nmsocket_t *sock = NULL;
1254
1255	REQUIRE(VALID_NMHANDLE(handle));
1256	REQUIRE(VALID_NMSOCK(handle->sock));
1257	REQUIRE(handle->sock->type == isc_nm_tlssocket);
1258
1259	sock = handle->sock;
1260	if (sock->tlsstream.tls == NULL) {
1261		return (NULL);
1262	}
1263
1264	return (isc_tls_verify_peer_result_string(sock->tlsstream.tls));
1265}
1266
1267static void
1268tls_init_listener_tlsctx(isc_nmsocket_t *listener, isc_tlsctx_t *ctx) {
1269	size_t nlisteners;
1270
1271	REQUIRE(VALID_NM(listener->mgr));
1272	REQUIRE(ctx != NULL);
1273
1274	nlisteners = (size_t)listener->mgr->nlisteners;
1275	INSIST(nlisteners > 0);
1276
1277	listener->tlsstream.listener_tls_ctx = isc_mem_get(
1278		listener->mgr->mctx, sizeof(isc_tlsctx_t *) * nlisteners);
1279	listener->tlsstream.n_listener_tls_ctx = nlisteners;
1280	for (size_t i = 0; i < nlisteners; i++) {
1281		listener->tlsstream.listener_tls_ctx[i] = NULL;
1282		isc_tlsctx_attach(ctx,
1283				  &listener->tlsstream.listener_tls_ctx[i]);
1284	}
1285}
1286
1287static void
1288tls_cleanup_listener_tlsctx(isc_nmsocket_t *listener) {
1289	REQUIRE(VALID_NM(listener->mgr));
1290
1291	if (listener->tlsstream.listener_tls_ctx == NULL) {
1292		return;
1293	}
1294
1295	for (size_t i = 0; i < listener->tlsstream.n_listener_tls_ctx; i++) {
1296		isc_tlsctx_free(&listener->tlsstream.listener_tls_ctx[i]);
1297	}
1298	isc_mem_put(listener->mgr->mctx, listener->tlsstream.listener_tls_ctx,
1299		    sizeof(isc_tlsctx_t *) *
1300			    listener->tlsstream.n_listener_tls_ctx);
1301	listener->tlsstream.n_listener_tls_ctx = 0;
1302}
1303
1304static isc_tlsctx_t *
1305tls_get_listener_tlsctx(isc_nmsocket_t *listener, const int tid) {
1306	REQUIRE(VALID_NM(listener->mgr));
1307	REQUIRE(tid >= 0);
1308
1309	if (listener->tlsstream.listener_tls_ctx == NULL) {
1310		return (NULL);
1311	}
1312
1313	return (listener->tlsstream.listener_tls_ctx[tid]);
1314}
1315
1316void
1317isc__nm_async_tls_set_tlsctx(isc_nmsocket_t *listener, isc_tlsctx_t *tlsctx,
1318			     const int tid) {
1319	REQUIRE(tid >= 0);
1320
1321	isc_tlsctx_free(&listener->tlsstream.listener_tls_ctx[tid]);
1322	isc_tlsctx_attach(tlsctx, &listener->tlsstream.listener_tls_ctx[tid]);
1323}
1324
1325static void
1326tls_keep_client_tls_session(isc_nmsocket_t *sock) {
1327	/*
1328	 * Ensure that the isc_tls_t is being accessed from
1329	 * within the worker thread the socket is bound to.
1330	 */
1331	REQUIRE(sock->tid == isc_nm_tid());
1332	if (sock->tlsstream.client_sess_cache != NULL &&
1333	    sock->tlsstream.client_session_saved == false)
1334	{
1335		INSIST(atomic_load(&sock->client));
1336		isc_tlsctx_client_session_cache_keep_sockaddr(
1337			sock->tlsstream.client_sess_cache, &sock->peer,
1338			sock->tlsstream.tls);
1339		sock->tlsstream.client_session_saved = true;
1340	}
1341}
1342
1343static void
1344tls_try_shutdown(isc_tls_t *tls, const bool force) {
1345	if (force) {
1346		(void)SSL_set_shutdown(tls, SSL_SENT_SHUTDOWN);
1347	} else if ((SSL_get_shutdown(tls) & SSL_SENT_SHUTDOWN) == 0) {
1348		(void)SSL_shutdown(tls);
1349	}
1350}
1351