#endif /* HAVE_LIBIDN2 */
#include <isc/base64.h>
+#include <isc/crypto.h>
#include <isc/file.h>
#include <isc/getaddresses.h>
#include <isc/hex.h>
isc_managers_destroy(&mctx, &loopmgr, &netmgr);
#if ENABLE_LEAK_DETECTION
- isc__tls_setdestroycheck(true);
+ isc__crypto_setdestroycheck(true);
isc__uv_setdestroycheck(true);
isc__xml_setdestroycheck(true);
#endif
#include <isc/attributes.h>
#include <isc/backtrace.h>
#include <isc/commandline.h>
+#include <isc/crypto.h>
#include <isc/dir.h>
#include <isc/file.h>
#include <isc/fips.h>
isc_managers_destroy(&named_g_mctx, &named_g_loopmgr, &named_g_netmgr);
#if ENABLE_LEAK_DETECTION
- isc__tls_setdestroycheck(true);
+ isc__crypto_setdestroycheck(true);
isc__uv_setdestroycheck(true);
isc__xml_setdestroycheck(true);
#endif
DST_RET(dst__openssl_toresult(ISC_R_NOMEMORY));
}
if (dctx->key->key_alg == DST_ALG_ECDSA256) {
- type = EVP_sha256();
+ type = isc__crypto_sha256;
} else {
- type = EVP_sha384();
+ type = isc__crypto_sha384;
}
if (dctx->use == DO_SIGN) {
switch (dctx->key->key_alg) {
case DST_ALG_RSASHA1:
case DST_ALG_NSEC3RSASHA1:
- type = EVP_sha1(); /* SHA1 + RSA */
+ type = isc__crypto_sha1; /* SHA1 + RSA */
break;
case DST_ALG_RSASHA256:
- type = EVP_sha256(); /* SHA256 + RSA */
+ type = isc__crypto_sha256; /* SHA256 + RSA */
break;
case DST_ALG_RSASHA512:
- type = EVP_sha512();
+ type = isc__crypto_sha512;
break;
default:
UNREACHABLE();
switch (algorithm) {
case DST_ALG_RSASHA1:
case DST_ALG_NSEC3RSASHA1:
- type = EVP_sha1(); /* SHA1 + RSA */
+ type = isc__crypto_sha1; /* SHA1 + RSA */
sig = sha1_sig;
len = sizeof(sha1_sig) - 1;
break;
case DST_ALG_RSASHA256:
- type = EVP_sha256(); /* SHA256 + RSA */
+ type = isc__crypto_sha256; /* SHA256 + RSA */
sig = sha256_sig;
len = sizeof(sha256_sig) - 1;
break;
case DST_ALG_RSASHA512:
- type = EVP_sha512();
+ type = isc__crypto_sha512;
sig = sha512_sig;
len = sizeof(sha512_sig) - 1;
break;
include/isc/commandline.h \
include/isc/condition.h \
include/isc/counter.h \
+ include/isc/crypto.h \
include/isc/dir.h \
include/isc/dnsstream.h \
include/isc/endian.h \
commandline.c \
condition.c \
counter.c \
+ crypto.c \
dir.c \
entropy.c \
errno.c \
--- /dev/null
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, you can obtain one at https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#include <openssl/err.h>
+#include <openssl/rand.h>
+#include <openssl/ssl.h>
+
+#include <isc/crypto.h>
+#include <isc/mem.h>
+#include <isc/util.h>
+
+static isc_mem_t *isc__crypto_mctx = NULL;
+
+const EVP_MD *isc__crypto_md5 = NULL;
+const EVP_MD *isc__crypto_sha1 = NULL;
+const EVP_MD *isc__crypto_sha224 = NULL;
+const EVP_MD *isc__crypto_sha256 = NULL;
+const EVP_MD *isc__crypto_sha384 = NULL;
+const EVP_MD *isc__crypto_sha512 = NULL;
+
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+#define md_register_algorithm(alg, algname) \
+ { \
+ REQUIRE(isc__crypto_##alg == NULL); \
+ isc__crypto_##alg = EVP_MD_fetch(NULL, algname, NULL); \
+ if (isc__crypto_##alg == NULL) { \
+ ERR_clear_error(); \
+ } \
+ }
+
+#define md_unregister_algorithm(alg) \
+ { \
+ if (isc__crypto_##alg != NULL) { \
+ EVP_MD_free(UNCONST(isc__crypto_##alg)); \
+ isc__crypto_##alg = NULL; \
+ } \
+ }
+
+#else /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
+#define md_register_algorithm(alg, algname) \
+ { \
+ isc__crypto_##alg = EVP_##alg(); \
+ if (isc__crypto_##alg == NULL) { \
+ ERR_clear_error(); \
+ } \
+ }
+#define md_unregister_algorithm(alg)
+#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
+
+#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x30000000L
+/*
+ * This was crippled with LibreSSL, so just skip it:
+ * https://cvsweb.openbsd.org/src/lib/libcrypto/Attic/mem.c
+ */
+
+#if ISC_MEM_TRACKLINES
+/*
+ * We use the internal isc__mem API here, so we can pass the file and line
+ * arguments passed from OpenSSL >= 1.1.0 to our memory functions for better
+ * tracking of the OpenSSL allocations. Without this, we would always just see
+ * isc__crypto_{malloc,realloc,free} in the tracking output, but with this in
+ * place we get to see the places in the OpenSSL code where the allocations
+ * happen.
+ */
+
+static void *
+isc__crypto_malloc_ex(size_t size, const char *file, int line) {
+ return (isc__mem_allocate(isc__crypto_mctx, size, 0, file,
+ (unsigned int)line));
+}
+
+static void *
+isc__crypto_realloc_ex(void *ptr, size_t size, const char *file, int line) {
+ return (isc__mem_reallocate(isc__crypto_mctx, ptr, size, 0, file,
+ (unsigned int)line));
+}
+
+static void
+isc__crypto_free_ex(void *ptr, const char *file, int line) {
+ if (ptr == NULL) {
+ return;
+ }
+ if (isc__crypto_mctx != NULL) {
+ isc__mem_free(isc__crypto_mctx, ptr, 0, file,
+ (unsigned int)line);
+ }
+}
+
+#else /* ISC_MEM_TRACKLINES */
+
+static void *
+isc__crypto_malloc_ex(size_t size, const char *file, int line) {
+ UNUSED(file);
+ UNUSED(line);
+ return (isc_mem_allocate(isc__crypto_mctx, size));
+}
+
+static void *
+isc__crypto_realloc_ex(void *ptr, size_t size, const char *file, int line) {
+ UNUSED(file);
+ UNUSED(line);
+ return (isc_mem_reallocate(isc__crypto_mctx, ptr, size));
+}
+
+static void
+isc__crypto_free_ex(void *ptr, const char *file, int line) {
+ UNUSED(file);
+ UNUSED(line);
+ if (ptr == NULL) {
+ return;
+ }
+ if (isc__crypto_mctx != NULL) {
+ isc__mem_free(isc__crypto_mctx, ptr, 0);
+ }
+}
+
+#endif /* ISC_MEM_TRACKLINES */
+
+#endif /* !defined(LIBRESSL_VERSION_NUMBER) */
+
+void
+isc__crypto_setdestroycheck(bool check) {
+ isc_mem_setdestroycheck(isc__crypto_mctx, check);
+}
+
+void
+isc__crypto_initialize(void) {
+ uint64_t opts = OPENSSL_INIT_LOAD_CONFIG;
+
+ isc_mem_create(&isc__crypto_mctx);
+ isc_mem_setname(isc__crypto_mctx, "OpenSSL");
+ isc_mem_setdestroycheck(isc__crypto_mctx, false);
+
+#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x30000000L
+ /*
+ * CRYPTO_set_mem_(_ex)_functions() returns 1 on success or 0 on
+ * failure, which means OpenSSL already allocated some memory. There's
+ * nothing we can do about it.
+ */
+ (void)CRYPTO_set_mem_functions(isc__crypto_malloc_ex,
+ isc__crypto_realloc_ex,
+ isc__crypto_free_ex);
+#endif /* !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= \
+ 0x30000000L */
+
+#if defined(OPENSSL_INIT_NO_ATEXIT)
+ /*
+ * We call OPENSSL_cleanup() manually, in a correct order, thus disable
+ * the automatic atexit() handler.
+ */
+ opts |= OPENSSL_INIT_NO_ATEXIT;
+#endif
+
+ RUNTIME_CHECK(OPENSSL_init_ssl(opts, NULL) == 1);
+
+ /* Protect ourselves against unseeded PRNG */
+ if (RAND_status() != 1) {
+ FATAL_ERROR("OpenSSL pseudorandom number generator "
+ "cannot be initialized (see the `PRNG not "
+ "seeded' message in the OpenSSL FAQ)");
+ }
+
+#if defined(ENABLE_FIPS_MODE)
+ if (!isc_fips_mode()) {
+ if (isc_fips_set_mode(1) != ISC_R_SUCCESS) {
+ isc_tlserr2result(ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_OTHER, "FIPS_mode_set",
+ ISC_R_CRYPTOFAILURE);
+ exit(EXIT_FAILURE);
+ }
+ }
+#endif
+
+ md_register_algorithm(md5, "MD5");
+ md_register_algorithm(sha1, "SHA1");
+ md_register_algorithm(sha224, "SHA224");
+ md_register_algorithm(sha256, "SHA256");
+ md_register_algorithm(sha384, "SHA384");
+ md_register_algorithm(sha512, "SHA512");
+}
+
+void
+isc__crypto_shutdown(void) {
+ md_unregister_algorithm(sha512);
+ md_unregister_algorithm(sha384);
+ md_unregister_algorithm(sha256);
+ md_unregister_algorithm(sha224);
+ md_unregister_algorithm(sha1);
+ md_unregister_algorithm(md5);
+
+ OPENSSL_cleanup();
+
+ isc_mem_destroy(&isc__crypto_mctx);
+}
+
+#undef md_unregister_algorithm
+#undef md_register_algorithm
--- /dev/null
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, you can obtain one at https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#pragma once
+
+#include <openssl/evp.h>
+
+#include <isc/types.h>
+
+extern const EVP_MD *isc__crypto_md5;
+extern const EVP_MD *isc__crypto_sha1;
+extern const EVP_MD *isc__crypto_sha224;
+extern const EVP_MD *isc__crypto_sha256;
+extern const EVP_MD *isc__crypto_sha384;
+extern const EVP_MD *isc__crypto_sha512;
+
+/**
+ * Private
+ */
+
+void
+isc__crypto_setdestroycheck(bool check);
+
+void
+isc__crypto_initialize(void);
+
+void
+isc__crypto_shutdown(void);
#pragma once
+#include <isc/crypto.h>
#include <isc/lang.h>
#include <isc/result.h>
#include <isc/types.h>
*/
typedef void isc_md_type_t;
-extern const isc_md_type_t *isc__md_md5;
-extern const isc_md_type_t *isc__md_sha1;
-extern const isc_md_type_t *isc__md_sha224;
-extern const isc_md_type_t *isc__md_sha256;
-extern const isc_md_type_t *isc__md_sha384;
-extern const isc_md_type_t *isc__md_sha512;
-
-#define ISC_MD_MD5 isc__md_md5
-#define ISC_MD_SHA1 isc__md_sha1
-#define ISC_MD_SHA224 isc__md_sha224
-#define ISC_MD_SHA256 isc__md_sha256
-#define ISC_MD_SHA384 isc__md_sha384
-#define ISC_MD_SHA512 isc__md_sha512
+#define ISC_MD_MD5 isc__crypto_md5
+#define ISC_MD_SHA1 isc__crypto_sha1
+#define ISC_MD_SHA224 isc__crypto_sha224
+#define ISC_MD_SHA256 isc__crypto_sha256
+#define ISC_MD_SHA384 isc__crypto_sha384
+#define ISC_MD_SHA512 isc__crypto_sha512
#define ISC_MD5_DIGESTLENGTH isc_md_type_get_size(ISC_MD_MD5)
#define ISC_MD5_BLOCK_LENGTH isc_md_type_get_block_size(ISC_MD_MD5)
*/
size_t
isc_md_type_get_block_size(const isc_md_type_t *md_type);
-
-/**
- * Private
- */
-
-void
-isc__md_initialize(void);
-
-void
-isc__md_shutdown(void);
*\li 'ctx' - a valid non-NULL pointer;
*/
-void
-isc__tls_initialize(void);
-
-void
-isc__tls_shutdown(void);
-
-void
-isc__tls_setdestroycheck(bool check);
-
#define isc_tlserr2result(category, module, funcname, fallback) \
isc__tlserr2result(category, module, funcname, fallback, __FILE__, \
__LINE__)
#include <openssl/err.h>
#include <openssl/opensslv.h>
+#include <isc/crypto.h>
#include <isc/iterated_hash.h>
#include <isc/thread.h>
#include <isc/util.h>
static thread_local bool initialized = false;
static thread_local EVP_MD_CTX *mdctx = NULL;
static thread_local EVP_MD_CTX *basectx = NULL;
-static thread_local EVP_MD *md = NULL;
int
isc_iterated_hash(unsigned char *out, const unsigned int hashalg,
INSIST(basectx != NULL);
mdctx = EVP_MD_CTX_new();
INSIST(mdctx != NULL);
- md = EVP_MD_fetch(NULL, "SHA1", NULL);
- INSIST(md != NULL);
- RUNTIME_CHECK(EVP_DigestInit_ex(basectx, md, NULL) == 1);
+ RUNTIME_CHECK(EVP_DigestInit_ex(basectx, isc__crypto_sha1, NULL) == 1);
initialized = true;
}
REQUIRE(basectx != NULL);
EVP_MD_CTX_free(basectx);
basectx = NULL;
- EVP_MD_free(md);
- md = NULL;
initialized = false;
}
/*! \file */
+#include <isc/crypto.h>
#include <isc/hash.h>
#include <isc/iterated_hash.h>
-#include <isc/log.h>
#include <isc/md.h>
#include <isc/mem.h>
#include <isc/os.h>
isc__mutex_initialize();
isc__mem_initialize();
isc__log_initialize();
- isc__tls_initialize();
+ isc__crypto_initialize();
isc__uv_initialize();
isc__xml_initialize();
- isc__md_initialize();
isc__hash_initialize();
isc__iterated_hash_initialize();
(void)isc_os_ncpus();
void
isc__shutdown(void) {
isc__iterated_hash_shutdown();
- isc__md_shutdown();
isc__xml_shutdown();
isc__uv_shutdown();
- isc__tls_shutdown();
+ isc__crypto_shutdown();
isc__log_shutdown();
isc__mem_shutdown();
isc__mutex_shutdown();
return (res);
}
-
-#ifndef UNIT_TESTING
-const isc_md_type_t *isc__md_md5 = NULL;
-const isc_md_type_t *isc__md_sha1 = NULL;
-const isc_md_type_t *isc__md_sha224 = NULL;
-const isc_md_type_t *isc__md_sha256 = NULL;
-const isc_md_type_t *isc__md_sha384 = NULL;
-const isc_md_type_t *isc__md_sha512 = NULL;
-
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
-#define md_register_algorithm(alg, algname) \
- { \
- REQUIRE(isc__md_##alg == NULL); \
- isc__md_##alg = EVP_MD_fetch(NULL, algname, NULL); \
- if (isc__md_##alg == NULL) { \
- ERR_clear_error(); \
- } \
- }
-
-#define md_unregister_algorithm(alg) \
- { \
- if (isc__md_##alg != NULL) { \
- EVP_MD_free(*(isc_md_type_t **)&isc__md_##alg); \
- isc__md_##alg = NULL; \
- } \
- }
-
-#else
-#define md_register_algorithm(alg, algname) \
- { \
- isc__md_##alg = EVP_##alg(); \
- if (isc__md_##alg == NULL) { \
- ERR_clear_error(); \
- } \
- }
-#define md_unregister_algorithm(alg)
-#endif
-
-void
-isc__md_initialize(void) {
- md_register_algorithm(md5, "MD5");
- md_register_algorithm(sha1, "SHA1");
- md_register_algorithm(sha224, "SHA224");
- md_register_algorithm(sha256, "SHA256");
- md_register_algorithm(sha384, "SHA384");
- md_register_algorithm(sha512, "SHA512");
-}
-
-void
-isc__md_shutdown(void) {
- md_unregister_algorithm(sha512);
- md_unregister_algorithm(sha384);
- md_unregister_algorithm(sha256);
- md_unregister_algorithm(sha224);
- md_unregister_algorithm(sha1);
- md_unregister_algorithm(md5);
-}
-
-#endif /* UNIT_TESTING */
#include <openssl/x509v3.h>
#include <isc/atomic.h>
+#include <isc/crypto.h>
#include <isc/fips.h>
#include <isc/ht.h>
#include <isc/log.h>
#define COMMON_SSL_OPTIONS \
(SSL_OP_NO_COMPRESSION | SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION)
-static isc_mem_t *isc__tls_mctx = NULL;
-
-#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x30000000L
-/*
- * This was crippled with LibreSSL, so just skip it:
- * https://cvsweb.openbsd.org/src/lib/libcrypto/Attic/mem.c
- */
-
-#if ISC_MEM_TRACKLINES
-/*
- * We use the internal isc__mem API here, so we can pass the file and line
- * arguments passed from OpenSSL >= 1.1.0 to our memory functions for better
- * tracking of the OpenSSL allocations. Without this, we would always just see
- * isc__tls_{malloc,realloc,free} in the tracking output, but with this in place
- * we get to see the places in the OpenSSL code where the allocations happen.
- */
-
-static void *
-isc__tls_malloc_ex(size_t size, const char *file, int line) {
- return (isc__mem_allocate(isc__tls_mctx, size, 0, file,
- (unsigned int)line));
-}
-
-static void *
-isc__tls_realloc_ex(void *ptr, size_t size, const char *file, int line) {
- return (isc__mem_reallocate(isc__tls_mctx, ptr, size, 0, file,
- (unsigned int)line));
-}
-
-static void
-isc__tls_free_ex(void *ptr, const char *file, int line) {
- if (ptr == NULL) {
- return;
- }
- if (isc__tls_mctx != NULL) {
- isc__mem_free(isc__tls_mctx, ptr, 0, file, (unsigned int)line);
- }
-}
-
-#else /* ISC_MEM_TRACKLINES */
-
-static void *
-isc__tls_malloc_ex(size_t size, const char *file, int line) {
- UNUSED(file);
- UNUSED(line);
- return (isc_mem_allocate(isc__tls_mctx, size));
-}
-
-static void *
-isc__tls_realloc_ex(void *ptr, size_t size, const char *file, int line) {
- UNUSED(file);
- UNUSED(line);
- return (isc_mem_reallocate(isc__tls_mctx, ptr, size));
-}
-
-static void
-isc__tls_free_ex(void *ptr, const char *file, int line) {
- UNUSED(file);
- UNUSED(line);
- if (ptr == NULL) {
- return;
- }
- if (isc__tls_mctx != NULL) {
- isc__mem_free(isc__tls_mctx, ptr, 0);
- }
-}
-
-#endif /* ISC_MEM_TRACKLINES */
-
-#endif /* !defined(LIBRESSL_VERSION_NUMBER) */
-
-static void
-enable_fips_mode(void) {
-#if defined(ENABLE_FIPS_MODE)
- if (isc_fips_mode()) {
- /*
- * FIPS mode is already enabled.
- */
- return;
- }
-
- if (isc_fips_set_mode(1) != ISC_R_SUCCESS) {
- isc_tlserr2result(ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_OTHER,
- "FIPS_mode_set", ISC_R_CRYPTOFAILURE);
- exit(EXIT_FAILURE);
- }
-#endif
-}
-
-void
-isc__tls_initialize(void) {
- isc_mem_create(&isc__tls_mctx);
- isc_mem_setname(isc__tls_mctx, "OpenSSL");
- isc_mem_setdestroycheck(isc__tls_mctx, false);
-
-#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x30000000L
- /*
- * CRYPTO_set_mem_(_ex)_functions() returns 1 on success or 0 on
- * failure, which means OpenSSL already allocated some memory. There's
- * nothing we can do about it.
- */
- (void)CRYPTO_set_mem_functions(isc__tls_malloc_ex, isc__tls_realloc_ex,
- isc__tls_free_ex);
-#endif /* !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= \
- 0x30000000L */
-
- uint64_t opts = OPENSSL_INIT_LOAD_CONFIG;
-
-#if defined(OPENSSL_INIT_NO_ATEXIT)
- /*
- * We call OPENSSL_cleanup() manually, in a correct order, thus disable
- * the automatic atexit() handler.
- */
- opts |= OPENSSL_INIT_NO_ATEXIT;
-#endif
-
- RUNTIME_CHECK(OPENSSL_init_ssl(opts, NULL) == 1);
-
- /* Protect ourselves against unseeded PRNG */
- if (RAND_status() != 1) {
- FATAL_ERROR("OpenSSL pseudorandom number generator "
- "cannot be initialized (see the `PRNG not "
- "seeded' message in the OpenSSL FAQ)");
- }
-
- enable_fips_mode();
-}
-
-void
-isc__tls_shutdown(void) {
- OPENSSL_cleanup();
-
- isc_mem_destroy(&isc__tls_mctx);
-}
-
-void
-isc__tls_setdestroycheck(bool check) {
- isc_mem_setdestroycheck(isc__tls_mctx, check);
-}
-
void
isc_tlsctx_free(isc_tlsctx_t **ctxp) {
SSL_CTX *ctx = NULL;
-1, -1, 0);
X509_set_issuer_name(cert, name);
- X509_sign(cert, pkey, EVP_sha256());
+ X509_sign(cert, pkey, isc__crypto_sha256);
rv = SSL_CTX_use_certificate(ctx, cert);
if (rv != 1) {
goto ssl_error;