mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-08 21:22:09 -04:00
chg: dev: unify explicit fetching and libcrypto handling
Unify libcrypto initialization and explicit digest fetching in a single place. It will remove the remaining implicit fetching and deduplicate explicit fetching inside the codebase. Initialization has been moved in to ensure OpenSSL cleanup is done only after fetched contextes are destroyed. Merge branch 'aydin/libdns-explicit-fetch' into 'main' See merge request isc-projects/bind9!9288
This commit is contained in:
commit
94e5061151
13 changed files with 273 additions and 253 deletions
|
|
@ -36,6 +36,7 @@
|
|||
#endif /* HAVE_LIBIDN2 */
|
||||
|
||||
#include <isc/base64.h>
|
||||
#include <isc/crypto.h>
|
||||
#include <isc/file.h>
|
||||
#include <isc/getaddresses.h>
|
||||
#include <isc/hex.h>
|
||||
|
|
@ -4754,7 +4755,7 @@ destroy_libs(void) {
|
|||
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
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#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>
|
||||
|
|
@ -1565,7 +1566,7 @@ main(int argc, char *argv[]) {
|
|||
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
|
||||
|
|
|
|||
|
|
@ -690,9 +690,9 @@ opensslecdsa_createctx(dst_key_t *key, dst_context_t *dctx) {
|
|||
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) {
|
||||
|
|
|
|||
|
|
@ -202,13 +202,13 @@ opensslrsa_createctx(dst_key_t *key, dst_context_t *dctx) {
|
|||
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();
|
||||
|
|
@ -1236,17 +1236,17 @@ check_algorithm(unsigned char algorithm) {
|
|||
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;
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ libisc_la_HEADERS = \
|
|||
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 \
|
||||
|
|
@ -124,6 +125,7 @@ libisc_la_SOURCES = \
|
|||
commandline.c \
|
||||
condition.c \
|
||||
counter.c \
|
||||
crypto.c \
|
||||
dir.c \
|
||||
entropy.c \
|
||||
errno.c \
|
||||
|
|
|
|||
207
lib/isc/crypto.c
Normal file
207
lib/isc/crypto.c
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
* 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
|
||||
38
lib/isc/include/isc/crypto.h
Normal file
38
lib/isc/include/isc/crypto.h
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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);
|
||||
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <isc/crypto.h>
|
||||
#include <isc/lang.h>
|
||||
#include <isc/result.h>
|
||||
#include <isc/types.h>
|
||||
|
|
@ -37,19 +38,12 @@ typedef void isc_md_t;
|
|||
*/
|
||||
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)
|
||||
|
|
@ -196,13 +190,3 @@ isc_md_type_get_size(const isc_md_type_t *md_type);
|
|||
*/
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -608,15 +608,6 @@ isc_tlsctx_set_random_session_id_context(isc_tlsctx_t *ctx);
|
|||
*\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__)
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#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>
|
||||
|
|
@ -89,7 +90,6 @@ isc__iterated_hash_shutdown(void) {
|
|||
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,
|
||||
|
|
@ -149,10 +149,8 @@ isc__iterated_hash_initialize(void) {
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
@ -168,8 +166,6 @@ isc__iterated_hash_shutdown(void) {
|
|||
REQUIRE(basectx != NULL);
|
||||
EVP_MD_CTX_free(basectx);
|
||||
basectx = NULL;
|
||||
EVP_MD_free(md);
|
||||
md = NULL;
|
||||
|
||||
initialized = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,9 +13,9 @@
|
|||
|
||||
/*! \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>
|
||||
|
|
@ -48,10 +48,9 @@ isc__initialize(void) {
|
|||
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();
|
||||
|
|
@ -61,10 +60,9 @@ isc__initialize(void) {
|
|||
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();
|
||||
|
|
|
|||
59
lib/isc/md.c
59
lib/isc/md.c
|
|
@ -167,62 +167,3 @@ end:
|
|||
|
||||
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 */
|
||||
|
|
|
|||
143
lib/isc/tls.c
143
lib/isc/tls.c
|
|
@ -34,6 +34,7 @@
|
|||
#include <openssl/x509v3.h>
|
||||
|
||||
#include <isc/atomic.h>
|
||||
#include <isc/crypto.h>
|
||||
#include <isc/fips.h>
|
||||
#include <isc/ht.h>
|
||||
#include <isc/log.h>
|
||||
|
|
@ -55,146 +56,6 @@
|
|||
#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;
|
||||
|
|
@ -441,7 +302,7 @@ isc_tlsctx_createserver(const char *keyfile, const char *certfile,
|
|||
-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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue