mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-09 02:22:04 -04:00
DoT: implement TLS client session resumption
This commit extends DoT code with TLS client session resumption
support implemented on top of the TLS client session cache.
(cherry picked from commit 86465c1dac)
This commit is contained in:
parent
0a4a76ff7a
commit
e02284354a
7 changed files with 86 additions and 22 deletions
|
|
@ -3008,7 +3008,7 @@ start_tcp(dig_query_t *query) {
|
|||
isc_nm_tlsdnsconnect(netmgr, &localaddr,
|
||||
&query->sockaddr, tcp_connected,
|
||||
connectquery, local_timeout, 0,
|
||||
tlsctx);
|
||||
tlsctx, sess_cache);
|
||||
#if HAVE_LIBNGHTTP2
|
||||
} else if (query->lookup->https_mode) {
|
||||
char uri[4096] = { 0 };
|
||||
|
|
|
|||
|
|
@ -407,7 +407,8 @@ run(void) {
|
|||
isc_tlsctx_createclient(&tls_ctx);
|
||||
|
||||
isc_nm_tlsdnsconnect(netmgr, &sockaddr_local, &sockaddr_remote,
|
||||
connect_cb, NULL, timeout, 0, tls_ctx);
|
||||
connect_cb, NULL, timeout, 0, tls_ctx,
|
||||
NULL);
|
||||
break;
|
||||
}
|
||||
#if HAVE_LIBNGHTTP2
|
||||
|
|
|
|||
|
|
@ -1118,7 +1118,7 @@ xfrin_start(dns_xfrin_ctx_t *xfr) {
|
|||
}
|
||||
isc_nm_tlsdnsconnect(xfr->netmgr, &xfr->sourceaddr,
|
||||
&xfr->primaryaddr, xfrin_connect_done,
|
||||
connect_xfr, 30000, 0, tlsctx);
|
||||
connect_xfr, 30000, 0, tlsctx, sess_cache);
|
||||
} break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
|
|
|
|||
|
|
@ -519,7 +519,8 @@ isc_nm_tcpdnsconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
|
|||
void
|
||||
isc_nm_tlsdnsconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
|
||||
isc_nm_cb_t cb, void *cbarg, unsigned int timeout,
|
||||
size_t extrahandlesize, isc_tlsctx_t *sslctx);
|
||||
size_t extrahandlesize, isc_tlsctx_t *sslctx,
|
||||
isc_tlsctx_client_session_cache_t *client_sess_cache);
|
||||
/*%<
|
||||
* Establish a DNS client connection via a TCP or TLS connection, bound to
|
||||
* the address 'local' and connected to the address 'peer'.
|
||||
|
|
|
|||
|
|
@ -940,6 +940,8 @@ struct isc_nmsocket {
|
|||
struct tls {
|
||||
isc_tls_t *tls;
|
||||
isc_tlsctx_t *ctx;
|
||||
isc_tlsctx_client_session_cache_t *client_sess_cache;
|
||||
bool client_session_saved;
|
||||
BIO *app_rbio;
|
||||
BIO *app_wbio;
|
||||
BIO *ssl_rbio;
|
||||
|
|
|
|||
|
|
@ -80,6 +80,14 @@ tls_cycle(isc_nmsocket_t *sock);
|
|||
static void
|
||||
call_pending_send_callbacks(isc_nmsocket_t *sock, const isc_result_t result);
|
||||
|
||||
static void
|
||||
tlsdns_keep_client_tls_session(isc_nmsocket_t *sock);
|
||||
|
||||
static void
|
||||
tlsdns_set_tls_shutdown(isc_tls_t *tls) {
|
||||
(void)SSL_set_shutdown(tls, SSL_SENT_SHUTDOWN);
|
||||
}
|
||||
|
||||
static bool
|
||||
peer_verification_has_failed(isc_nmsocket_t *sock) {
|
||||
if (sock->tls.tls != NULL && sock->tls.state == TLS_STATE_HANDSHAKE &&
|
||||
|
|
@ -295,11 +303,17 @@ tlsdns_connect_cb(uv_connect_t *uvreq, int status) {
|
|||
SSL_set_bio(sock->tls.tls, sock->tls.ssl_rbio, sock->tls.ssl_wbio);
|
||||
#endif
|
||||
|
||||
SSL_set_connect_state(sock->tls.tls);
|
||||
|
||||
result = isc_sockaddr_fromsockaddr(&sock->peer, (struct sockaddr *)&ss);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
if (sock->tls.client_sess_cache != NULL) {
|
||||
isc_tlsctx_client_session_cache_reuse_sockaddr(
|
||||
sock->tls.client_sess_cache, &sock->peer,
|
||||
sock->tls.tls);
|
||||
}
|
||||
|
||||
SSL_set_connect_state(sock->tls.tls);
|
||||
|
||||
/* Setting pending req */
|
||||
sock->tls.pending_req = req;
|
||||
|
||||
|
|
@ -324,7 +338,8 @@ error:
|
|||
void
|
||||
isc_nm_tlsdnsconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
|
||||
isc_nm_cb_t cb, void *cbarg, unsigned int timeout,
|
||||
size_t extrahandlesize, isc_tlsctx_t *sslctx) {
|
||||
size_t extrahandlesize, isc_tlsctx_t *sslctx,
|
||||
isc_tlsctx_client_session_cache_t *client_sess_cache) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
isc_nmsocket_t *sock = NULL;
|
||||
isc__netievent_tlsdnsconnect_t *ievent = NULL;
|
||||
|
|
@ -355,6 +370,13 @@ isc_nm_tlsdnsconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
|
|||
req->local = *local;
|
||||
req->handle = isc__nmhandle_get(sock, &req->peer, &sock->iface);
|
||||
|
||||
if (client_sess_cache != NULL) {
|
||||
INSIST(isc_tlsctx_client_session_cache_getctx(
|
||||
client_sess_cache) == sslctx);
|
||||
isc_tlsctx_client_session_cache_attach(
|
||||
client_sess_cache, &sock->tls.client_sess_cache);
|
||||
}
|
||||
|
||||
result = isc__nm_socket(sa_family, SOCK_STREAM, 0, &sock->fd);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto failure;
|
||||
|
|
@ -1014,6 +1036,11 @@ isc__nm_tlsdns_processbuffer(isc_nmsocket_t *sock) {
|
|||
|
||||
isc_nmhandle_detach(&handle);
|
||||
|
||||
if (isc__nmsocket_closing(sock)) {
|
||||
tlsdns_set_tls_shutdown(sock->tls.tls);
|
||||
tlsdns_keep_client_tls_session(sock);
|
||||
}
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
|
|
@ -1116,6 +1143,8 @@ tls_cycle_input(isc_nmsocket_t *sock) {
|
|||
const unsigned char *alpn = NULL;
|
||||
unsigned int alpnlen = 0;
|
||||
|
||||
isc__nmsocket_log_tls_session_reuse(sock, sock->tls.tls);
|
||||
|
||||
isc_tls_get_selected_alpn(sock->tls.tls, &alpn, &alpnlen);
|
||||
if (alpn != NULL && alpnlen == ISC_TLS_DOT_PROTO_ALPN_ID_LEN &&
|
||||
memcmp(ISC_TLS_DOT_PROTO_ALPN_ID, alpn,
|
||||
|
|
@ -1841,6 +1870,12 @@ tlsdns_close_sock(isc_nmsocket_t *sock) {
|
|||
atomic_store(&sock->connected, false);
|
||||
|
||||
if (sock->tls.tls != NULL) {
|
||||
/*
|
||||
* Let's shutdown the TLS session properly so that the session
|
||||
* will remain resumable, if required.
|
||||
*/
|
||||
tlsdns_set_tls_shutdown(sock->tls.tls);
|
||||
tlsdns_keep_client_tls_session(sock);
|
||||
isc_tls_free(&sock->tls.tls);
|
||||
}
|
||||
|
||||
|
|
@ -2021,7 +2056,7 @@ isc__nm_tlsdns_shutdown(isc_nmsocket_t *sock) {
|
|||
|
||||
if (sock->tls.tls) {
|
||||
/* Shutdown any active TLS connections */
|
||||
(void)SSL_shutdown(sock->tls.tls);
|
||||
tlsdns_set_tls_shutdown(sock->tls.tls);
|
||||
}
|
||||
|
||||
if (atomic_load(&sock->accepting)) {
|
||||
|
|
@ -2152,10 +2187,35 @@ isc__nm_async_tlsdns_set_tlsctx(isc_nmsocket_t *listener, isc_tlsctx_t *tlsctx,
|
|||
|
||||
void
|
||||
isc__nm_tlsdns_cleanup_data(isc_nmsocket_t *sock) {
|
||||
if ((sock->type == isc_nm_tlsdnslistener ||
|
||||
sock->type == isc_nm_tlsdnssocket) &&
|
||||
sock->tls.ctx != NULL)
|
||||
{
|
||||
isc_tlsctx_free(&sock->tls.ctx);
|
||||
if (sock->type == isc_nm_tlsdnslistener ||
|
||||
sock->type == isc_nm_tlsdnssocket) {
|
||||
if (sock->tls.client_sess_cache != NULL) {
|
||||
INSIST(atomic_load(&sock->client));
|
||||
INSIST(sock->type == isc_nm_tlsdnssocket);
|
||||
isc_tlsctx_client_session_cache_detach(
|
||||
&sock->tls.client_sess_cache);
|
||||
}
|
||||
if (sock->tls.ctx != NULL) {
|
||||
INSIST(ISC_LIST_EMPTY(sock->tls.sendreqs));
|
||||
isc_tlsctx_free(&sock->tls.ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tlsdns_keep_client_tls_session(isc_nmsocket_t *sock) {
|
||||
/*
|
||||
* Ensure that the isc_tls_t is being accessed from
|
||||
* within the worker thread the socket is bound to.
|
||||
*/
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
if (sock->tls.client_sess_cache != NULL &&
|
||||
sock->tls.client_session_saved == false)
|
||||
{
|
||||
INSIST(atomic_load(&sock->client));
|
||||
isc_tlsctx_client_session_cache_keep_sockaddr(
|
||||
sock->tls.client_sess_cache, &sock->peer,
|
||||
sock->tls.tls);
|
||||
sock->tls.client_session_saved = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2229,7 +2229,7 @@ static void
|
|||
tlsdns_connect(isc_nm_t *nm) {
|
||||
isc_nm_tlsdnsconnect(nm, &tcp_connect_addr, &tcp_listen_addr,
|
||||
connect_connect_cb, NULL, T_CONNECT, 0,
|
||||
tcp_connect_tlsctx);
|
||||
tcp_connect_tlsctx, tcp_tlsctx_client_sess_cache);
|
||||
}
|
||||
|
||||
ISC_RUN_TEST_IMPL(tlsdns_noop) {
|
||||
|
|
@ -2249,7 +2249,7 @@ ISC_RUN_TEST_IMPL(tlsdns_noop) {
|
|||
isc_refcount_increment0(&active_cconnects);
|
||||
isc_nm_tlsdnsconnect(connect_nm, &tcp_connect_addr, &tcp_listen_addr,
|
||||
connect_connect_cb, NULL, T_CONNECT, 0,
|
||||
tcp_connect_tlsctx);
|
||||
tcp_connect_tlsctx, tcp_tlsctx_client_sess_cache);
|
||||
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
|
||||
|
|
@ -2276,7 +2276,7 @@ ISC_RUN_TEST_IMPL(tlsdns_noresponse) {
|
|||
isc_refcount_increment0(&active_cconnects);
|
||||
isc_nm_tlsdnsconnect(connect_nm, &connect_addr, &tcp_listen_addr,
|
||||
connect_connect_cb, NULL, T_CONNECT, 0,
|
||||
tcp_connect_tlsctx);
|
||||
tcp_connect_tlsctx, tcp_tlsctx_client_sess_cache);
|
||||
|
||||
WAIT_FOR_EQ(cconnects, 1);
|
||||
WAIT_FOR_EQ(csends, 1);
|
||||
|
|
@ -2330,7 +2330,7 @@ ISC_RUN_TEST_IMPL(tlsdns_timeout_recovery) {
|
|||
isc_refcount_increment0(&active_cconnects);
|
||||
isc_nm_tlsdnsconnect(connect_nm, &tcp_connect_addr, &tcp_listen_addr,
|
||||
connect_connect_cb, NULL, T_SOFT, 0,
|
||||
tcp_connect_tlsctx);
|
||||
tcp_connect_tlsctx, tcp_tlsctx_client_sess_cache);
|
||||
|
||||
WAIT_FOR_EQ(cconnects, 1);
|
||||
WAIT_FOR_GE(csends, 1);
|
||||
|
|
@ -2361,7 +2361,7 @@ ISC_RUN_TEST_IMPL(tlsdns_recv_one) {
|
|||
isc_refcount_increment0(&active_cconnects);
|
||||
isc_nm_tlsdnsconnect(connect_nm, &tcp_connect_addr, &tcp_listen_addr,
|
||||
connect_connect_cb, NULL, T_CONNECT, 0,
|
||||
tcp_connect_tlsctx);
|
||||
tcp_connect_tlsctx, tcp_tlsctx_client_sess_cache);
|
||||
|
||||
WAIT_FOR_EQ(cconnects, 1);
|
||||
WAIT_FOR_LE(nsends, 0);
|
||||
|
|
@ -2403,14 +2403,14 @@ ISC_RUN_TEST_IMPL(tlsdns_recv_two) {
|
|||
isc_refcount_increment0(&active_cconnects);
|
||||
isc_nm_tlsdnsconnect(connect_nm, &tcp_connect_addr, &tcp_listen_addr,
|
||||
connect_connect_cb, NULL, T_CONNECT, 0,
|
||||
tcp_connect_tlsctx);
|
||||
tcp_connect_tlsctx, tcp_tlsctx_client_sess_cache);
|
||||
|
||||
WAIT_FOR_EQ(cconnects, 1);
|
||||
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
isc_nm_tlsdnsconnect(connect_nm, &tcp_connect_addr, &tcp_listen_addr,
|
||||
connect_connect_cb, NULL, T_CONNECT, 0,
|
||||
tcp_connect_tlsctx);
|
||||
tcp_connect_tlsctx, tcp_tlsctx_client_sess_cache);
|
||||
|
||||
WAIT_FOR_EQ(cconnects, 2);
|
||||
|
||||
|
|
@ -2673,7 +2673,7 @@ ISC_RUN_TEST_IMPL(tlsdns_connect_noalpn) {
|
|||
isc_refcount_increment0(&active_cconnects);
|
||||
isc_nm_tlsdnsconnect(connect_nm, &connect_addr, &tcp_listen_addr,
|
||||
tlsdns_connect_connect_noalpn, NULL, T_CONNECT, 0,
|
||||
connect_tlsctx_noalpn);
|
||||
connect_tlsctx_noalpn, NULL);
|
||||
|
||||
WAIT_FOR_EQ(active_cconnects, 0);
|
||||
|
||||
|
|
@ -2739,7 +2739,7 @@ ISC_RUN_TEST_IMPL(tlsdns_listen_noalpn) {
|
|||
isc_refcount_increment0(&active_cconnects);
|
||||
isc_nm_tlsdnsconnect(connect_nm, &connect_addr, &tcp_listen_addr,
|
||||
connect_connect_cb, NULL, T_CONNECT, 0,
|
||||
tcp_connect_tlsctx);
|
||||
tcp_connect_tlsctx, tcp_tlsctx_client_sess_cache);
|
||||
|
||||
WAIT_FOR_EQ(saccepts, 1);
|
||||
WAIT_FOR_EQ(cconnects, 1);
|
||||
|
|
|
|||
Loading…
Reference in a new issue