*/
result = isc_tlsctx_cache_find(xfr->tlsctx_cache, tlsname,
isc_tlsctx_cache_tls, family,
- &tlsctx);
+ &tlsctx, NULL);
if (result != ISC_R_SUCCESS) {
/*
* So, no context exists. Let's create one using the
result = isc_tlsctx_cache_add(
xfr->tlsctx_cache, tlsname,
- isc_tlsctx_cache_tls, family, tlsctx, &found);
+ isc_tlsctx_cache_tls, family, tlsctx, NULL,
+ &found, NULL);
if (result == ISC_R_EXISTS) {
/*
* It seems the entry has just been created
isc_tlsctx_cache_add(isc_tlsctx_cache_t *cache, const char *name,
const isc_tlsctx_cache_transport_t transport,
const uint16_t family, isc_tlsctx_t *ctx,
- isc_tlsctx_t **pfound);
+ isc_tls_cert_store_t *store, isc_tlsctx_t **pfound,
+ isc_tls_cert_store_t **pfound_store);
/*%<
*
* Add a new TLS context to the TLS context cache. 'pfound' is an
* optional pointer, which can be used to retrieve an already
* existing TLS context object in a case it exists.
*
+ * The passed certificates store object ('store') possession is
+ * transferred to the cache object in a case of success. In some cases
+ * it might be destroyed immediately upon the call completion.
+ *
* Requires:
*\li 'cache' is a valid pointer to a TLS context cache object;
*\li 'name' is a valid pointer to a non-empty string;
isc_result_t
isc_tlsctx_cache_find(isc_tlsctx_cache_t *cache, const char *name,
const isc_tlsctx_cache_transport_t transport,
- const uint16_t family, isc_tlsctx_t **pctx);
+ const uint16_t family, isc_tlsctx_t **pctx,
+ isc_tls_cert_store_t **pstore);
/*%<
* Look up a TLS context in the TLS context cache.
*
*/
isc_tlsctx_t *ctx[isc_tlsctx_cache_count - 1][2];
/*
- * TODO: add a certificate store for an intermediate certificates
- * from a CA-bundle file. One is enough for all the contexts defined
- * above. We will need that for validation.
- *
- * X509_STORE *ca_bundle_store; // TODO: define the utilities to
- * operate on these ones
+ * One certificate store is enough for all the contexts defined
+ * above. We need that for peer validation.
*/
+ isc_tls_cert_store_t *ca_store;
} isc_tlsctx_cache_entry_t;
struct isc_tlsctx_cache {
}
}
}
+ if (entry->ca_store != NULL) {
+ isc_tls_cert_store_free(&entry->ca_store);
+ }
isc_mem_put(mctx, entry, sizeof(*entry));
}
isc_tlsctx_cache_add(isc_tlsctx_cache_t *cache, const char *name,
const isc_tlsctx_cache_transport_t transport,
const uint16_t family, isc_tlsctx_t *ctx,
- isc_tlsctx_t **pfound) {
+ isc_tls_cert_store_t *store, isc_tlsctx_t **pfound,
+ isc_tls_cert_store_t **pfound_store) {
isc_result_t result = ISC_R_FAILURE;
size_t name_len, tr_offset;
isc_tlsctx_cache_entry_t *entry = NULL;
INSIST(*pfound == NULL);
*pfound = entry->ctx[tr_offset][ipv6];
}
+
+ if (pfound_store != NULL && entry->ca_store != NULL) {
+ INSIST(*pfound_store == NULL);
+ *pfound_store = entry->ca_store;
+ }
result = ISC_R_EXISTS;
} else if (result == ISC_R_SUCCESS &&
entry->ctx[tr_offset][ipv6] == NULL) {
/*
- * The hast table entry exists, but is not filled for this
+ * The hash table entry exists, but is not filled for this
* particular transport/IP type combination.
*/
entry->ctx[tr_offset][ipv6] = ctx;
+ /*
+ * As the passed certificates store object is supposed to be
+ * internally managed by the cache object anyway, we might
+ * destroy the unneeded store object right now.
+ */
+ if (store != NULL && store != entry->ca_store) {
+ isc_tls_cert_store_free(&store);
+ }
result = ISC_R_SUCCESS;
} else {
/*
/* Oracle/Red Hat Linux, GCC bug #53119 */
memset(entry, 0, sizeof(*entry));
entry->ctx[tr_offset][ipv6] = ctx;
+ entry->ca_store = store;
RUNTIME_CHECK(isc_ht_add(cache->data, (const uint8_t *)name,
name_len,
(void *)entry) == ISC_R_SUCCESS);
isc_result_t
isc_tlsctx_cache_find(isc_tlsctx_cache_t *cache, const char *name,
const isc_tlsctx_cache_transport_t transport,
- const uint16_t family, isc_tlsctx_t **pctx) {
+ const uint16_t family, isc_tlsctx_t **pctx,
+ isc_tls_cert_store_t **pstore) {
isc_result_t result = ISC_R_FAILURE;
size_t tr_offset;
isc_tlsctx_cache_entry_t *entry = NULL;
result = isc_ht_find(cache->data, (const uint8_t *)name, strlen(name),
(void **)&entry);
+
+ if (result == ISC_R_SUCCESS && pstore != NULL &&
+ entry->ca_store != NULL) {
+ *pstore = entry->ca_store;
+ }
+
if (result == ISC_R_SUCCESS && entry->ctx[tr_offset][ipv6] != NULL) {
*pctx = entry->ctx[tr_offset][ipv6];
} else if (result == ISC_R_SUCCESS &&
* order to avoid excessive TLS contexts creation.
*/
result = isc_tlsctx_cache_find(tlsctx_cache, tls_params->name,
- transport, family, &sslctx);
+ transport, family, &sslctx,
+ NULL);
if (result != ISC_R_SUCCESS) {
/*
* The lookup failed, let's try to create a new context
*/
RUNTIME_CHECK(isc_tlsctx_cache_add(
tlsctx_cache, tls_params->name,
- transport, family, sslctx,
- NULL) == ISC_R_SUCCESS);
+ transport, family, sslctx, NULL,
+ NULL, NULL) == ISC_R_SUCCESS);
} else {
INSIST(sslctx != NULL);
}