diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 17:36:47 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 17:36:47 +0000 |
commit | 0441d265f2bb9da249c7abf333f0f771fadb4ab5 (patch) | |
tree | 3f3789daa2f6db22da6e55e92bee0062a7d613fe /src/lib-ssl-iostream/dovecot-openssl-common.c | |
parent | Initial commit. (diff) | |
download | dovecot-0441d265f2bb9da249c7abf333f0f771fadb4ab5.tar.xz dovecot-0441d265f2bb9da249c7abf333f0f771fadb4ab5.zip |
Adding upstream version 1:2.3.21+dfsg1.upstream/1%2.3.21+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/lib-ssl-iostream/dovecot-openssl-common.c')
-rw-r--r-- | src/lib-ssl-iostream/dovecot-openssl-common.c | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/src/lib-ssl-iostream/dovecot-openssl-common.c b/src/lib-ssl-iostream/dovecot-openssl-common.c new file mode 100644 index 0000000..76f98bc --- /dev/null +++ b/src/lib-ssl-iostream/dovecot-openssl-common.c @@ -0,0 +1,132 @@ +/* Copyright (c) 2016-2018 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "randgen.h" +#include "dovecot-openssl-common.h" + +#include <openssl/ssl.h> +#include <openssl/engine.h> +#include <openssl/rand.h> + +static int openssl_init_refcount = 0; +static ENGINE *dovecot_openssl_engine; + +#ifdef HAVE_SSL_NEW_MEM_FUNCS +static void *dovecot_openssl_malloc(size_t size, const char *u0 ATTR_UNUSED, int u1 ATTR_UNUSED) +#else +static void *dovecot_openssl_malloc(size_t size) +#endif +{ + /* this may be performance critical, so don't use + i_malloc() or calloc() */ + void *mem = malloc(size); + if (mem == NULL) { + i_fatal_status(FATAL_OUTOFMEM, + "OpenSSL: malloc(%zu): Out of memory", size); + } + return mem; +} + +#ifdef HAVE_SSL_NEW_MEM_FUNCS +static void *dovecot_openssl_realloc(void *ptr, size_t size, const char *u0 ATTR_UNUSED, int u1 ATTR_UNUSED) +#else +static void *dovecot_openssl_realloc(void *ptr, size_t size) +#endif +{ + void *mem = realloc(ptr, size); + if (mem == NULL) { + i_fatal_status(FATAL_OUTOFMEM, + "OpenSSL: realloc(%zu): Out of memory", size); + } + return mem; +} + +#ifdef HAVE_SSL_NEW_MEM_FUNCS +static void dovecot_openssl_free(void *ptr, const char *u0 ATTR_UNUSED, int u1 ATTR_UNUSED) +#else +static void dovecot_openssl_free(void *ptr) +#endif +{ + free(ptr); +} + +void dovecot_openssl_common_global_ref(void) +{ + if (openssl_init_refcount++ > 0) + return; + + /* use our own memory allocation functions that will die instead of + returning NULL. this avoids random failures on out-of-memory + conditions. */ + if (CRYPTO_set_mem_functions(dovecot_openssl_malloc, + dovecot_openssl_realloc, dovecot_openssl_free) == 0) { + /*i_warning("CRYPTO_set_mem_functions() was called too late");*/ + } + + SSL_library_init(); + SSL_load_error_strings(); + OpenSSL_add_all_algorithms(); +} + +bool dovecot_openssl_common_global_unref(void) +{ + i_assert(openssl_init_refcount > 0); + + if (--openssl_init_refcount > 0) + return TRUE; + + if (dovecot_openssl_engine != NULL) { + ENGINE_finish(dovecot_openssl_engine); + dovecot_openssl_engine = NULL; + } + /* OBJ_cleanup() is called automatically by EVP_cleanup() in + newer versions. Doesn't hurt to call it anyway. */ + OBJ_cleanup(); +#ifdef HAVE_SSL_COMP_FREE_COMPRESSION_METHODS + SSL_COMP_free_compression_methods(); +#endif + ENGINE_cleanup(); + EVP_cleanup(); + CRYPTO_cleanup_all_ex_data(); +#ifdef HAVE_OPENSSL_AUTO_THREAD_DEINIT + /* no cleanup needed */ +#elif defined(HAVE_OPENSSL_ERR_REMOVE_THREAD_STATE) + /* This was marked as deprecated in v1.1. */ + ERR_remove_thread_state(NULL); +#else + /* This was deprecated by ERR_remove_thread_state(NULL) in v1.0.0. */ + ERR_remove_state(0); +#endif + ERR_free_strings(); +#ifdef HAVE_OPENSSL_CLEANUP + OPENSSL_cleanup(); +#endif + return FALSE; +} + +int dovecot_openssl_common_global_set_engine(const char *engine, + const char **error_r) +{ + if (dovecot_openssl_engine != NULL) + return 1; + + ENGINE_load_builtin_engines(); + dovecot_openssl_engine = ENGINE_by_id(engine); + if (dovecot_openssl_engine == NULL) { + *error_r = t_strdup_printf("Unknown engine '%s'", engine); + return 0; + } + if (ENGINE_init(dovecot_openssl_engine) == 0) { + *error_r = t_strdup_printf("ENGINE_init(%s) failed", engine); + ENGINE_free(dovecot_openssl_engine); + dovecot_openssl_engine = NULL; + return -1; + } + if (ENGINE_set_default(dovecot_openssl_engine, ENGINE_METHOD_ALL) == 0) { + *error_r = t_strdup_printf("ENGINE_set_default(%s) failed", engine); + ENGINE_free(dovecot_openssl_engine); + dovecot_openssl_engine = NULL; + return -1; + } + return 1; +} |