mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 14:35:26 +00:00
Extend TLS context cache with TLS client session cache
This commit extends TLS context cache with TLS client session cache so that an associated session cache can be stored alongside the TLS context within the context cache.
This commit is contained in:
@@ -2764,7 +2764,8 @@ _cancel_lookup(dig_lookup_t *lookup, const char *file, unsigned int line) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static isc_tlsctx_t *
|
static isc_tlsctx_t *
|
||||||
get_create_tls_context(dig_query_t *query, const bool is_https) {
|
get_create_tls_context(dig_query_t *query, const bool is_https,
|
||||||
|
isc_tlsctx_client_session_cache_t **psess_cache) {
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
isc_tlsctx_t *ctx = NULL, *found_ctx = NULL;
|
isc_tlsctx_t *ctx = NULL, *found_ctx = NULL;
|
||||||
isc_tls_cert_store_t *store = NULL, *found_store = NULL;
|
isc_tls_cert_store_t *store = NULL, *found_store = NULL;
|
||||||
@@ -2775,6 +2776,8 @@ get_create_tls_context(dig_query_t *query, const bool is_https) {
|
|||||||
isc_tlsctx_cache_transport_t transport =
|
isc_tlsctx_cache_transport_t transport =
|
||||||
is_https ? isc_tlsctx_cache_https : isc_tlsctx_cache_tls;
|
is_https ? isc_tlsctx_cache_https : isc_tlsctx_cache_tls;
|
||||||
const bool hostname_ignore_subject = !is_https;
|
const bool hostname_ignore_subject = !is_https;
|
||||||
|
isc_tlsctx_client_session_cache_t *sess_cache = NULL,
|
||||||
|
*found_sess_cache = NULL;
|
||||||
|
|
||||||
if (query->lookup->tls_key_file_set != query->lookup->tls_cert_file_set)
|
if (query->lookup->tls_key_file_set != query->lookup->tls_cert_file_set)
|
||||||
{
|
{
|
||||||
@@ -2785,7 +2788,7 @@ get_create_tls_context(dig_query_t *query, const bool is_https) {
|
|||||||
|
|
||||||
result = isc_tlsctx_cache_find(query->lookup->tls_ctx_cache, tlsctxname,
|
result = isc_tlsctx_cache_find(query->lookup->tls_ctx_cache, tlsctxname,
|
||||||
transport, family, &found_ctx,
|
transport, family, &found_ctx,
|
||||||
&found_store);
|
&found_store, &found_sess_cache);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
if (query->lookup->tls_ca_set) {
|
if (query->lookup->tls_ca_set) {
|
||||||
if (found_store == NULL) {
|
if (found_store == NULL) {
|
||||||
@@ -2844,13 +2847,26 @@ get_create_tls_context(dig_query_t *query, const bool is_https) {
|
|||||||
}
|
}
|
||||||
#endif /* HAVE_LIBNGHTTP2 */
|
#endif /* HAVE_LIBNGHTTP2 */
|
||||||
|
|
||||||
result = isc_tlsctx_cache_add(query->lookup->tls_ctx_cache,
|
sess_cache = isc_tlsctx_client_session_cache_new(
|
||||||
tlsctxname, transport, family,
|
mctx, ctx,
|
||||||
ctx, store, NULL, NULL);
|
ISC_TLSCTX_CLIENT_SESSION_CACHE_DEFAULT_SIZE);
|
||||||
|
|
||||||
|
result = isc_tlsctx_cache_add(
|
||||||
|
query->lookup->tls_ctx_cache, tlsctxname, transport,
|
||||||
|
family, ctx, store, sess_cache, NULL, NULL, NULL);
|
||||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||||
|
if (psess_cache != NULL) {
|
||||||
|
INSIST(*psess_cache == NULL);
|
||||||
|
*psess_cache = sess_cache;
|
||||||
|
}
|
||||||
return (ctx);
|
return (ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (psess_cache != NULL) {
|
||||||
|
INSIST(*psess_cache == NULL);
|
||||||
|
*psess_cache = found_sess_cache;
|
||||||
|
}
|
||||||
|
|
||||||
INSIST(!query->lookup->tls_ca_set || found_store != NULL);
|
INSIST(!query->lookup->tls_ca_set || found_store != NULL);
|
||||||
return (found_ctx);
|
return (found_ctx);
|
||||||
failure:
|
failure:
|
||||||
@@ -2860,6 +2876,9 @@ failure:
|
|||||||
if (store != NULL && store != found_store) {
|
if (store != NULL && store != found_store) {
|
||||||
isc_tls_cert_store_free(&store);
|
isc_tls_cert_store_free(&store);
|
||||||
}
|
}
|
||||||
|
if (sess_cache != NULL && sess_cache != found_sess_cache) {
|
||||||
|
isc_tlsctx_client_session_cache_detach(&sess_cache);
|
||||||
|
}
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2878,6 +2897,7 @@ start_tcp(dig_query_t *query) {
|
|||||||
dig_query_t *connectquery = NULL;
|
dig_query_t *connectquery = NULL;
|
||||||
isc_tlsctx_t *tlsctx = NULL;
|
isc_tlsctx_t *tlsctx = NULL;
|
||||||
bool tls_mode = false;
|
bool tls_mode = false;
|
||||||
|
isc_tlsctx_client_session_cache_t *sess_cache = NULL;
|
||||||
REQUIRE(DIG_VALID_QUERY(query));
|
REQUIRE(DIG_VALID_QUERY(query));
|
||||||
|
|
||||||
debug("start_tcp(%p)", query);
|
debug("start_tcp(%p)", query);
|
||||||
@@ -2972,7 +2992,8 @@ start_tcp(dig_query_t *query) {
|
|||||||
query_attach(query, &connectquery);
|
query_attach(query, &connectquery);
|
||||||
|
|
||||||
if (tls_mode) {
|
if (tls_mode) {
|
||||||
tlsctx = get_create_tls_context(connectquery, false);
|
tlsctx = get_create_tls_context(connectquery, false,
|
||||||
|
&sess_cache);
|
||||||
if (tlsctx == NULL) {
|
if (tlsctx == NULL) {
|
||||||
goto failure_tls;
|
goto failure_tls;
|
||||||
}
|
}
|
||||||
@@ -2989,8 +3010,8 @@ start_tcp(dig_query_t *query) {
|
|||||||
uri, sizeof(uri));
|
uri, sizeof(uri));
|
||||||
|
|
||||||
if (!query->lookup->http_plain) {
|
if (!query->lookup->http_plain) {
|
||||||
tlsctx = get_create_tls_context(connectquery,
|
tlsctx = get_create_tls_context(
|
||||||
true);
|
connectquery, true, &sess_cache);
|
||||||
if (tlsctx == NULL) {
|
if (tlsctx == NULL) {
|
||||||
goto failure_tls;
|
goto failure_tls;
|
||||||
}
|
}
|
||||||
|
@@ -934,6 +934,8 @@ xfrin_start(dns_xfrin_ctx_t *xfr) {
|
|||||||
dns_transport_type_t transport_type = DNS_TRANSPORT_TCP;
|
dns_transport_type_t transport_type = DNS_TRANSPORT_TCP;
|
||||||
isc_tlsctx_t *tlsctx = NULL, *found = NULL;
|
isc_tlsctx_t *tlsctx = NULL, *found = NULL;
|
||||||
isc_tls_cert_store_t *store = NULL, *found_store = NULL;
|
isc_tls_cert_store_t *store = NULL, *found_store = NULL;
|
||||||
|
isc_tlsctx_client_session_cache_t *sess_cache = NULL,
|
||||||
|
*found_sess_cache = NULL;
|
||||||
|
|
||||||
(void)isc_refcount_increment0(&xfr->connects);
|
(void)isc_refcount_increment0(&xfr->connects);
|
||||||
dns_xfrin_attach(xfr, &connect_xfr);
|
dns_xfrin_attach(xfr, &connect_xfr);
|
||||||
@@ -972,9 +974,9 @@ xfrin_start(dns_xfrin_ctx_t *xfr) {
|
|||||||
* full TLS handshake procedure, making establishing
|
* full TLS handshake procedure, making establishing
|
||||||
* subsequent TLS connections for XoT faster.
|
* subsequent TLS connections for XoT faster.
|
||||||
*/
|
*/
|
||||||
result = isc_tlsctx_cache_find(xfr->tlsctx_cache, tlsname,
|
result = isc_tlsctx_cache_find(
|
||||||
isc_tlsctx_cache_tls, family,
|
xfr->tlsctx_cache, tlsname, isc_tlsctx_cache_tls,
|
||||||
&tlsctx, &found_store);
|
family, &tlsctx, &found_store, &found_sess_cache);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
const char *hostname =
|
const char *hostname =
|
||||||
dns_transport_get_remote_hostname(
|
dns_transport_get_remote_hostname(
|
||||||
@@ -1079,11 +1081,16 @@ xfrin_start(dns_xfrin_ctx_t *xfr) {
|
|||||||
|
|
||||||
isc_tlsctx_enable_dot_client_alpn(tlsctx);
|
isc_tlsctx_enable_dot_client_alpn(tlsctx);
|
||||||
|
|
||||||
|
sess_cache = isc_tlsctx_client_session_cache_new(
|
||||||
|
xfr->mctx, tlsctx,
|
||||||
|
ISC_TLSCTX_CLIENT_SESSION_CACHE_DEFAULT_SIZE);
|
||||||
|
|
||||||
found_store = NULL;
|
found_store = NULL;
|
||||||
result = isc_tlsctx_cache_add(
|
result = isc_tlsctx_cache_add(
|
||||||
xfr->tlsctx_cache, tlsname,
|
xfr->tlsctx_cache, tlsname,
|
||||||
isc_tlsctx_cache_tls, family, tlsctx, store,
|
isc_tlsctx_cache_tls, family, tlsctx, store,
|
||||||
&found, &found_store);
|
sess_cache, &found, &found_store,
|
||||||
|
&found_sess_cache);
|
||||||
if (result == ISC_R_EXISTS) {
|
if (result == ISC_R_EXISTS) {
|
||||||
/*
|
/*
|
||||||
* It seems the entry has just been created
|
* It seems the entry has just been created
|
||||||
@@ -1101,7 +1108,10 @@ xfrin_start(dns_xfrin_ctx_t *xfr) {
|
|||||||
INSIST(found != NULL);
|
INSIST(found != NULL);
|
||||||
isc_tlsctx_free(&tlsctx);
|
isc_tlsctx_free(&tlsctx);
|
||||||
isc_tls_cert_store_free(&store);
|
isc_tls_cert_store_free(&store);
|
||||||
|
isc_tlsctx_client_session_cache_detach(
|
||||||
|
&sess_cache);
|
||||||
tlsctx = found;
|
tlsctx = found;
|
||||||
|
sess_cache = found_sess_cache;
|
||||||
} else {
|
} else {
|
||||||
INSIST(result == ISC_R_SUCCESS);
|
INSIST(result == ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
@@ -1129,6 +1139,11 @@ failure:
|
|||||||
if (store != NULL && store != found_store) {
|
if (store != NULL && store != found_store) {
|
||||||
isc_tls_cert_store_free(&store);
|
isc_tls_cert_store_free(&store);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sess_cache != NULL && sess_cache != found_sess_cache) {
|
||||||
|
isc_tlsctx_client_session_cache_detach(&sess_cache);
|
||||||
|
}
|
||||||
|
|
||||||
isc_refcount_decrement0(&xfr->connects);
|
isc_refcount_decrement0(&xfr->connects);
|
||||||
dns_xfrin_detach(&connect_xfr);
|
dns_xfrin_detach(&connect_xfr);
|
||||||
return (result);
|
return (result);
|
||||||
|
@@ -366,7 +366,7 @@ isc_tlsctx_client_session_cache_keep(isc_tlsctx_client_session_cache_t *cache,
|
|||||||
*
|
*
|
||||||
* Requires:
|
* Requires:
|
||||||
*\li 'cache' is a pointer to a valid TLS client session cache object;
|
*\li 'cache' is a pointer to a valid TLS client session cache object;
|
||||||
*\li 'remote_peer_name' is a pointer to a non empty character string.
|
*\li 'remote_peer_name' is a pointer to a non empty character string;
|
||||||
*\li 'tls' is a valid, non-'NULL' pointer to a TLS connection state object.
|
*\li 'tls' is a valid, non-'NULL' pointer to a TLS connection state object.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -375,11 +375,11 @@ isc_tlsctx_client_session_cache_keep_sockaddr(
|
|||||||
isc_tlsctx_client_session_cache_t *cache, isc_sockaddr_t *remote_peer,
|
isc_tlsctx_client_session_cache_t *cache, isc_sockaddr_t *remote_peer,
|
||||||
isc_tls_t *tls);
|
isc_tls_t *tls);
|
||||||
/*%<
|
/*%<
|
||||||
* The same as 'isc_tlsctx_client_session_cache_keep()', but using a
|
* The same as 'isc_tlsctx_client_session_cache_keep()', but uses a
|
||||||
* 'isc_sockaddr_t' as a key, instead of a character string.
|
* 'isc_sockaddr_t' as a key, instead of a character string.
|
||||||
*
|
*
|
||||||
* Requires:
|
* Requires:
|
||||||
*\li 'remote_peer' is a valid, non-'NULL' pointer to an 'isc_sockaddr_t'
|
*\li 'remote_peer' is a valid, non-'NULL', pointer to an 'isc_sockaddr_t'
|
||||||
*object.
|
*object.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -395,7 +395,7 @@ isc_tlsctx_client_session_cache_reuse(isc_tlsctx_client_session_cache_t *cache,
|
|||||||
* Requires:
|
* Requires:
|
||||||
*\li 'cache' is a pointer to a valid TLS client session cache object;
|
*\li 'cache' is a pointer to a valid TLS client session cache object;
|
||||||
*\li 'remote_peer_name' is a pointer to a non empty character string;
|
*\li 'remote_peer_name' is a pointer to a non empty character string;
|
||||||
*\li 'tls' is a valid, non-'NULL', pointer to a TLS connection state object.
|
*\li 'tls' is a valid, non-'NULL' pointer to a TLS connection state object.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -413,6 +413,22 @@ isc_tlsctx_client_session_cache_reuse_sockaddr(
|
|||||||
|
|
||||||
const isc_tlsctx_t *
|
const isc_tlsctx_t *
|
||||||
isc_tlsctx_client_session_cache_getctx(isc_tlsctx_client_session_cache_t *cache);
|
isc_tlsctx_client_session_cache_getctx(isc_tlsctx_client_session_cache_t *cache);
|
||||||
|
/*%<
|
||||||
|
* Returns a TLS context associated with the given TLS client
|
||||||
|
* session cache object. The function is intended to be used to
|
||||||
|
* implement the sanity checks ('INSIST()'s and 'REQUIRE()'s).
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
*\li 'cache' is a pointer to a valid TLS client session cache object.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define ISC_TLSCTX_CLIENT_SESSION_CACHE_DEFAULT_SIZE (150)
|
||||||
|
/*%<
|
||||||
|
* The default maximum size of a TLS client session cache. The value
|
||||||
|
* should be large enough to hold enough sessions to successfully
|
||||||
|
* re-establish connections to the most remote TLS servers, but not
|
||||||
|
* too big to avoid keeping too much obsolete sessions.
|
||||||
|
*/
|
||||||
|
|
||||||
typedef struct isc_tlsctx_cache isc_tlsctx_cache_t;
|
typedef struct isc_tlsctx_cache isc_tlsctx_cache_t;
|
||||||
/*%<
|
/*%<
|
||||||
@@ -481,28 +497,39 @@ isc_tlsctx_cache_detach(isc_tlsctx_cache_t **cachep);
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
isc_tlsctx_cache_add(isc_tlsctx_cache_t *cache, const char *name,
|
isc_tlsctx_cache_add(
|
||||||
const isc_tlsctx_cache_transport_t transport,
|
isc_tlsctx_cache_t *cache, const char *name,
|
||||||
const uint16_t family, isc_tlsctx_t *ctx,
|
const isc_tlsctx_cache_transport_t transport, const uint16_t family,
|
||||||
isc_tls_cert_store_t *store, isc_tlsctx_t **pfound,
|
isc_tlsctx_t *ctx, isc_tls_cert_store_t *store,
|
||||||
isc_tls_cert_store_t **pfound_store);
|
isc_tlsctx_client_session_cache_t *client_sess_cache,
|
||||||
|
isc_tlsctx_t **pfound, isc_tls_cert_store_t **pfound_store,
|
||||||
|
isc_tlsctx_client_session_cache_t **pfound_client_sess_cache);
|
||||||
/*%<
|
/*%<
|
||||||
*
|
*
|
||||||
* Add a new TLS context to the TLS context cache. 'pfound' is an
|
* Add a new TLS context and its associated data to the TLS context
|
||||||
* optional pointer, which can be used to retrieve an already
|
* cache. 'pfound' is an optional pointer, which can be used to
|
||||||
* existing TLS context object in a case it exists.
|
* retrieve an already existing TLS context object in a case it
|
||||||
|
* exists.
|
||||||
*
|
*
|
||||||
* The passed certificates store object ('store') possession is
|
* The passed certificates store object ('store') possession is
|
||||||
* transferred to the cache object in a case of success. In some cases
|
* transferred to the cache object in a case of success. In some cases
|
||||||
* it might be destroyed immediately upon the call completion.
|
* it might be destroyed immediately upon the call completion.
|
||||||
*
|
*
|
||||||
|
* The possession of the passed TLS client session cache
|
||||||
|
* ('client_sess_cache') is also transferred to the cache object in a
|
||||||
|
* case of success.
|
||||||
|
*
|
||||||
* Requires:
|
* Requires:
|
||||||
*\li 'cache' is a valid pointer to a TLS context cache object;
|
*\li 'cache' is a valid pointer to a TLS context cache object;
|
||||||
*\li 'name' is a valid pointer to a non-empty string;
|
*\li 'name' is a valid pointer to a non-empty string;
|
||||||
*\li 'transport' is a valid transport identifier (currently only
|
*\li 'transport' is a valid transport identifier (currently only
|
||||||
* TLS/DoT and HTTPS/DoH are supported);
|
* TLS/DoT and HTTPS/DoH are supported);
|
||||||
*\li 'family' - either 'AF_INET' or 'AF_INET6';
|
*\li 'family' - either 'AF_INET' or 'AF_INET6';
|
||||||
*\li 'ctx' - a valid pointer to a valid TLS context object.
|
*\li 'ctx' - a valid pointer to a valid TLS context object;
|
||||||
|
*\li 'store' - a valid pointer to a valid TLS certificates store object or
|
||||||
|
* 'NULL';
|
||||||
|
*\li 'client_sess_cache' - a valid pointer to a valid TLS client sessions
|
||||||
|
*cache object or 'NULL.
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
*\li #ISC_R_EXISTS - node of the same key already exists;
|
*\li #ISC_R_EXISTS - node of the same key already exists;
|
||||||
@@ -510,12 +537,13 @@ isc_tlsctx_cache_add(isc_tlsctx_cache_t *cache, const char *name,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
isc_tlsctx_cache_find(isc_tlsctx_cache_t *cache, const char *name,
|
isc_tlsctx_cache_find(
|
||||||
const isc_tlsctx_cache_transport_t transport,
|
isc_tlsctx_cache_t *cache, const char *name,
|
||||||
const uint16_t family, isc_tlsctx_t **pctx,
|
const isc_tlsctx_cache_transport_t transport, const uint16_t family,
|
||||||
isc_tls_cert_store_t **pstore);
|
isc_tlsctx_t **pctx, isc_tls_cert_store_t **pstore,
|
||||||
|
isc_tlsctx_client_session_cache_t **pfound_client_sess_cache);
|
||||||
/*%<
|
/*%<
|
||||||
* Look up a TLS context in the TLS context cache.
|
* Look up a TLS context and its associated data in the TLS context cache.
|
||||||
*
|
*
|
||||||
* Requires:
|
* Requires:
|
||||||
*\li 'cache' is a valid pointer to a TLS context cache object;
|
*\li 'cache' is a valid pointer to a TLS context cache object;
|
||||||
@@ -523,7 +551,10 @@ isc_tlsctx_cache_find(isc_tlsctx_cache_t *cache, const char *name,
|
|||||||
*\li 'transport' - a valid transport identifier (currently only
|
*\li 'transport' - a valid transport identifier (currently only
|
||||||
* TLS/DoT and HTTPS/DoH are supported;
|
* TLS/DoT and HTTPS/DoH are supported;
|
||||||
*\li 'family' - either 'AF_INET' or 'AF_INET6';
|
*\li 'family' - either 'AF_INET' or 'AF_INET6';
|
||||||
*\li 'pctx' - a valid pointer to a non-NULL pointer.
|
*\li 'pctx' - a valid pointer to a non-NULL pointer;
|
||||||
|
*\li 'pstore' - a valid pointer to a non-NULL pointer or 'NULL'.
|
||||||
|
*\li 'pfound_client_sess_cache' - a valid pointer to a non-NULL pointer or
|
||||||
|
*'NULL'.
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
*\li #ISC_R_SUCCESS - the context has been found;
|
*\li #ISC_R_SUCCESS - the context has been found;
|
||||||
|
@@ -1086,6 +1086,8 @@ typedef struct isc_tlsctx_cache_entry {
|
|||||||
* session-resumption cache.
|
* session-resumption cache.
|
||||||
*/
|
*/
|
||||||
isc_tlsctx_t *ctx[isc_tlsctx_cache_count - 1][2];
|
isc_tlsctx_t *ctx[isc_tlsctx_cache_count - 1][2];
|
||||||
|
isc_tlsctx_client_session_cache_t
|
||||||
|
*client_sess_cache[isc_tlsctx_cache_count - 1][2];
|
||||||
/*
|
/*
|
||||||
* One certificate store is enough for all the contexts defined
|
* One certificate store is enough for all the contexts defined
|
||||||
* above. We need that for peer validation.
|
* above. We need that for peer validation.
|
||||||
@@ -1138,6 +1140,11 @@ tlsctx_cache_entry_destroy(isc_mem_t *mctx, isc_tlsctx_cache_entry_t *entry) {
|
|||||||
if (entry->ctx[i][k] != NULL) {
|
if (entry->ctx[i][k] != NULL) {
|
||||||
isc_tlsctx_free(&entry->ctx[i][k]);
|
isc_tlsctx_free(&entry->ctx[i][k]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (entry->client_sess_cache[i][k] != NULL) {
|
||||||
|
isc_tlsctx_client_session_cache_detach(
|
||||||
|
&entry->client_sess_cache[i][k]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (entry->ca_store != NULL) {
|
if (entry->ca_store != NULL) {
|
||||||
@@ -1187,17 +1194,21 @@ isc_tlsctx_cache_detach(isc_tlsctx_cache_t **cachep) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
isc_tlsctx_cache_add(isc_tlsctx_cache_t *cache, const char *name,
|
isc_tlsctx_cache_add(
|
||||||
const isc_tlsctx_cache_transport_t transport,
|
isc_tlsctx_cache_t *cache, const char *name,
|
||||||
const uint16_t family, isc_tlsctx_t *ctx,
|
const isc_tlsctx_cache_transport_t transport, const uint16_t family,
|
||||||
isc_tls_cert_store_t *store, isc_tlsctx_t **pfound,
|
isc_tlsctx_t *ctx, isc_tls_cert_store_t *store,
|
||||||
isc_tls_cert_store_t **pfound_store) {
|
isc_tlsctx_client_session_cache_t *client_sess_cache,
|
||||||
|
isc_tlsctx_t **pfound, isc_tls_cert_store_t **pfound_store,
|
||||||
|
isc_tlsctx_client_session_cache_t **pfound_client_sess_cache) {
|
||||||
isc_result_t result = ISC_R_FAILURE;
|
isc_result_t result = ISC_R_FAILURE;
|
||||||
size_t name_len, tr_offset;
|
size_t name_len, tr_offset;
|
||||||
isc_tlsctx_cache_entry_t *entry = NULL;
|
isc_tlsctx_cache_entry_t *entry = NULL;
|
||||||
bool ipv6;
|
bool ipv6;
|
||||||
|
|
||||||
REQUIRE(VALID_TLSCTX_CACHE(cache));
|
REQUIRE(VALID_TLSCTX_CACHE(cache));
|
||||||
|
REQUIRE(client_sess_cache == NULL ||
|
||||||
|
VALID_TLSCTX_CLIENT_SESSION_CACHE(client_sess_cache));
|
||||||
REQUIRE(name != NULL && *name != '\0');
|
REQUIRE(name != NULL && *name != '\0');
|
||||||
REQUIRE(transport > isc_tlsctx_cache_none &&
|
REQUIRE(transport > isc_tlsctx_cache_none &&
|
||||||
transport < isc_tlsctx_cache_count);
|
transport < isc_tlsctx_cache_count);
|
||||||
@@ -1213,6 +1224,7 @@ isc_tlsctx_cache_add(isc_tlsctx_cache_t *cache, const char *name,
|
|||||||
result = isc_ht_find(cache->data, (const uint8_t *)name, name_len,
|
result = isc_ht_find(cache->data, (const uint8_t *)name, name_len,
|
||||||
(void **)&entry);
|
(void **)&entry);
|
||||||
if (result == ISC_R_SUCCESS && entry->ctx[tr_offset][ipv6] != NULL) {
|
if (result == ISC_R_SUCCESS && entry->ctx[tr_offset][ipv6] != NULL) {
|
||||||
|
isc_tlsctx_client_session_cache_t *found_client_sess_cache;
|
||||||
/* The entry exists. */
|
/* The entry exists. */
|
||||||
if (pfound != NULL) {
|
if (pfound != NULL) {
|
||||||
INSIST(*pfound == NULL);
|
INSIST(*pfound == NULL);
|
||||||
@@ -1223,6 +1235,14 @@ isc_tlsctx_cache_add(isc_tlsctx_cache_t *cache, const char *name,
|
|||||||
INSIST(*pfound_store == NULL);
|
INSIST(*pfound_store == NULL);
|
||||||
*pfound_store = entry->ca_store;
|
*pfound_store = entry->ca_store;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
found_client_sess_cache =
|
||||||
|
entry->client_sess_cache[tr_offset][ipv6];
|
||||||
|
if (pfound_client_sess_cache != NULL &&
|
||||||
|
found_client_sess_cache != NULL) {
|
||||||
|
INSIST(*pfound_client_sess_cache == NULL);
|
||||||
|
*pfound_client_sess_cache = found_client_sess_cache;
|
||||||
|
}
|
||||||
result = ISC_R_EXISTS;
|
result = ISC_R_EXISTS;
|
||||||
} else if (result == ISC_R_SUCCESS &&
|
} else if (result == ISC_R_SUCCESS &&
|
||||||
entry->ctx[tr_offset][ipv6] == NULL) {
|
entry->ctx[tr_offset][ipv6] == NULL) {
|
||||||
@@ -1231,10 +1251,11 @@ isc_tlsctx_cache_add(isc_tlsctx_cache_t *cache, const char *name,
|
|||||||
* particular transport/IP type combination.
|
* particular transport/IP type combination.
|
||||||
*/
|
*/
|
||||||
entry->ctx[tr_offset][ipv6] = ctx;
|
entry->ctx[tr_offset][ipv6] = ctx;
|
||||||
|
entry->client_sess_cache[tr_offset][ipv6] = client_sess_cache;
|
||||||
/*
|
/*
|
||||||
* As the passed certificates store object is supposed to be
|
* As the passed certificates store object is supposed
|
||||||
* internally managed by the cache object anyway, we might
|
* to be internally managed by the cache object anyway,
|
||||||
* destroy the unneeded store object right now.
|
* we might destroy the unneeded store object right now.
|
||||||
*/
|
*/
|
||||||
if (store != NULL && store != entry->ca_store) {
|
if (store != NULL && store != entry->ca_store) {
|
||||||
isc_tls_cert_store_free(&store);
|
isc_tls_cert_store_free(&store);
|
||||||
@@ -1249,6 +1270,7 @@ isc_tlsctx_cache_add(isc_tlsctx_cache_t *cache, const char *name,
|
|||||||
/* Oracle/Red Hat Linux, GCC bug #53119 */
|
/* Oracle/Red Hat Linux, GCC bug #53119 */
|
||||||
memset(entry, 0, sizeof(*entry));
|
memset(entry, 0, sizeof(*entry));
|
||||||
entry->ctx[tr_offset][ipv6] = ctx;
|
entry->ctx[tr_offset][ipv6] = ctx;
|
||||||
|
entry->client_sess_cache[tr_offset][ipv6] = client_sess_cache;
|
||||||
entry->ca_store = store;
|
entry->ca_store = store;
|
||||||
RUNTIME_CHECK(isc_ht_add(cache->data, (const uint8_t *)name,
|
RUNTIME_CHECK(isc_ht_add(cache->data, (const uint8_t *)name,
|
||||||
name_len,
|
name_len,
|
||||||
@@ -1262,10 +1284,11 @@ isc_tlsctx_cache_add(isc_tlsctx_cache_t *cache, const char *name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
isc_tlsctx_cache_find(isc_tlsctx_cache_t *cache, const char *name,
|
isc_tlsctx_cache_find(
|
||||||
const isc_tlsctx_cache_transport_t transport,
|
isc_tlsctx_cache_t *cache, const char *name,
|
||||||
const uint16_t family, isc_tlsctx_t **pctx,
|
const isc_tlsctx_cache_transport_t transport, const uint16_t family,
|
||||||
isc_tls_cert_store_t **pstore) {
|
isc_tlsctx_t **pctx, isc_tls_cert_store_t **pstore,
|
||||||
|
isc_tlsctx_client_session_cache_t **pfound_client_sess_cache) {
|
||||||
isc_result_t result = ISC_R_FAILURE;
|
isc_result_t result = ISC_R_FAILURE;
|
||||||
size_t tr_offset;
|
size_t tr_offset;
|
||||||
isc_tlsctx_cache_entry_t *entry = NULL;
|
isc_tlsctx_cache_entry_t *entry = NULL;
|
||||||
@@ -1292,7 +1315,16 @@ isc_tlsctx_cache_find(isc_tlsctx_cache_t *cache, const char *name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (result == ISC_R_SUCCESS && entry->ctx[tr_offset][ipv6] != NULL) {
|
if (result == ISC_R_SUCCESS && entry->ctx[tr_offset][ipv6] != NULL) {
|
||||||
|
isc_tlsctx_client_session_cache_t *found_client_sess_cache =
|
||||||
|
entry->client_sess_cache[tr_offset][ipv6];
|
||||||
|
|
||||||
*pctx = entry->ctx[tr_offset][ipv6];
|
*pctx = entry->ctx[tr_offset][ipv6];
|
||||||
|
|
||||||
|
if (pfound_client_sess_cache != NULL &&
|
||||||
|
found_client_sess_cache != NULL) {
|
||||||
|
INSIST(*pfound_client_sess_cache == NULL);
|
||||||
|
*pfound_client_sess_cache = found_client_sess_cache;
|
||||||
|
}
|
||||||
} else if (result == ISC_R_SUCCESS &&
|
} else if (result == ISC_R_SUCCESS &&
|
||||||
entry->ctx[tr_offset][ipv6] == NULL) {
|
entry->ctx[tr_offset][ipv6] == NULL) {
|
||||||
result = ISC_R_NOTFOUND;
|
result = ISC_R_NOTFOUND;
|
||||||
|
@@ -49,7 +49,7 @@ listenelt_create(isc_mem_t *mctx, in_port_t port, isc_dscp_t dscp,
|
|||||||
*/
|
*/
|
||||||
result = isc_tlsctx_cache_find(tlsctx_cache, tls_params->name,
|
result = isc_tlsctx_cache_find(tlsctx_cache, tls_params->name,
|
||||||
transport, family, &sslctx,
|
transport, family, &sslctx,
|
||||||
&found_store);
|
&found_store, NULL);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
/*
|
/*
|
||||||
* The lookup failed, let's try to create a new context
|
* The lookup failed, let's try to create a new context
|
||||||
@@ -150,7 +150,8 @@ listenelt_create(isc_mem_t *mctx, in_port_t port, isc_dscp_t dscp,
|
|||||||
RUNTIME_CHECK(isc_tlsctx_cache_add(
|
RUNTIME_CHECK(isc_tlsctx_cache_add(
|
||||||
tlsctx_cache, tls_params->name,
|
tlsctx_cache, tls_params->name,
|
||||||
transport, family, sslctx, store,
|
transport, family, sslctx, store,
|
||||||
NULL, NULL) == ISC_R_SUCCESS);
|
NULL, NULL, NULL,
|
||||||
|
NULL) == ISC_R_SUCCESS);
|
||||||
} else {
|
} else {
|
||||||
INSIST(sslctx != NULL);
|
INSIST(sslctx != NULL);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user