From b975ee7be48014d88f1572380385cc0862a87f91 Mon Sep 17 00:00:00 2001 From: Artem Boldariev Date: Thu, 30 Dec 2021 23:24:25 +0200 Subject: [PATCH] Add utility functions to manipulate X509 certificate stores This commit adds a set of high-level utility functions to manipulate the certificate stores. The stores are needed to implement TLS certificates verification efficiently. --- lib/isc/include/isc/tls.h | 23 ++++++++++++++++++ lib/isc/tls.c | 50 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/lib/isc/include/isc/tls.h b/lib/isc/include/isc/tls.h index bc7f537da6..764aece5a1 100644 --- a/lib/isc/include/isc/tls.h +++ b/lib/isc/include/isc/tls.h @@ -21,6 +21,8 @@ typedef struct ssl_ctx_st isc_tlsctx_t; typedef struct ssl_st isc_tls_t; +typedef struct x509_store_st isc_tls_cert_store_t; + void isc_tlsctx_free(isc_tlsctx_t **ctpx); /*%< @@ -196,6 +198,27 @@ isc_tlsctx_enable_dot_server_alpn(isc_tlsctx_t *ctx); *\li 'ctx' is not NULL. */ +isc_result_t +isc_tls_cert_store_create(const char *ca_bundle_filename, + isc_tls_cert_store_t **pstore); +/*%< + * Create X509 certificate store. The 'ca_bundle_filename' might be + * 'NULL' or an empty string, which means use the default system wide + * bundle/directory. + * + * Requires: + *\li 'pstore' is a valid pointer to a pointer containing 'NULL'. + */ + +void +isc_tls_cert_store_free(isc_tls_cert_store_t **pstore); +/*%< + * Free X509 certificate store. + * + * Requires: + *\li 'pstore' is a valid pointer to a pointer containing a non-'NULL' value. + */ + typedef struct isc_tlsctx_cache isc_tlsctx_cache_t; /*%< * The TLS context cache is an object which allows retrieving a diff --git a/lib/isc/tls.c b/lib/isc/tls.c index f517c26170..85c52ca109 100644 --- a/lib/isc/tls.c +++ b/lib/isc/tls.c @@ -910,6 +910,56 @@ isc_tlsctx_enable_dot_server_alpn(isc_tlsctx_t *tls) { #endif // OPENSSL_VERSION_NUMBER >= 0x10002000L } +isc_result_t +isc_tls_cert_store_create(const char *ca_bundle_filename, + isc_tls_cert_store_t **pstore) { + int ret = 0; + isc_tls_cert_store_t *store = NULL; + REQUIRE(pstore != NULL && *pstore == NULL); + + store = X509_STORE_new(); + if (store == NULL) { + goto error; + } + + /* Let's treat empty string as the default (system wide) store */ + if (ca_bundle_filename != NULL && *ca_bundle_filename == '\0') { + ca_bundle_filename = NULL; + } + + if (ca_bundle_filename == NULL) { + ret = X509_STORE_set_default_paths(store); + } else { + ret = X509_STORE_load_locations(store, ca_bundle_filename, + NULL); + } + + if (ret == 0) { + goto error; + } + + *pstore = store; + return (ISC_R_SUCCESS); + +error: + if (store != NULL) { + X509_STORE_free(store); + } + return (ISC_R_FAILURE); +} + +void +isc_tls_cert_store_free(isc_tls_cert_store_t **pstore) { + isc_tls_cert_store_t *store; + REQUIRE(pstore != NULL && *pstore != NULL); + + store = *pstore; + + X509_STORE_free(store); + + *pstore = NULL; +} + #define TLSCTX_CACHE_MAGIC ISC_MAGIC('T', 'l', 'S', 'c') #define VALID_TLSCTX_CACHE(t) ISC_MAGIC_VALID(t, TLSCTX_CACHE_MAGIC)