diff options
Diffstat (limited to 'crypto/apr_crypto_internal.c')
-rw-r--r-- | crypto/apr_crypto_internal.c | 357 |
1 files changed, 0 insertions, 357 deletions
diff --git a/crypto/apr_crypto_internal.c b/crypto/apr_crypto_internal.c deleted file mode 100644 index 2dcd24a7c..000000000 --- a/crypto/apr_crypto_internal.c +++ /dev/null @@ -1,357 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "apr_lib.h" -#include "apu.h" -#include "apr_private.h" -#include "apr_crypto.h" -#include "apr_crypto_internal.h" -#include "apr_strings.h" - -#if APU_HAVE_CRYPTO - -#if APU_HAVE_OPENSSL -#include "apr_thread_mutex.h" - -#include <openssl/crypto.h> -#include <openssl/engine.h> -#include <openssl/conf.h> -#include <openssl/comp.h> -#include <openssl/evp.h> -#include <openssl/ssl.h> - -#if APR_HAS_THREADS && APR_USE_OPENSSL_PRE_1_1_API -static apr_status_t ossl_thread_setup(apr_pool_t *pool); -#else -static APR_INLINE apr_status_t ossl_thread_setup(apr_pool_t *pool) -{ - return APR_SUCCESS; -} -#endif - -const char *apr__crypto_openssl_version(void) -{ - return OPENSSL_VERSION_TEXT; -} - -apr_status_t apr__crypto_openssl_init(const char *params, - const apu_err_t **result, - apr_pool_t *pool) -{ - /* Both undefined (or no-op) with LibreSSL */ -#if OPENSSL_VERSION_NUMBER < 0x10100000L - CRYPTO_malloc_init(); -#elif !defined(LIBRESSL_VERSION_NUMBER) - OPENSSL_malloc_init(); -#endif - ERR_load_crypto_strings(); - OpenSSL_add_all_algorithms(); - ENGINE_load_builtin_engines(); - ENGINE_register_all_complete(); - - SSL_load_error_strings(); - SSL_library_init(); - - return ossl_thread_setup(pool); -} - -apr_status_t apr__crypto_openssl_term(void) -{ -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - -#ifdef OPENSSL_FIPS - FIPS_mode_set(0); -#endif - CONF_modules_unload(1); - OBJ_cleanup(); - EVP_cleanup(); -#if !defined(LIBRESSL_VERSION_NUMBER) - RAND_cleanup(); -#endif - ENGINE_cleanup(); -#ifndef OPENSSL_NO_COMP - COMP_zlib_cleanup(); -#endif -#if OPENSSL_VERSION_NUMBER >= 0x1000000fL - ERR_remove_thread_state(NULL); -#else - ERR_remove_state(0); -#endif - ERR_free_strings(); - CRYPTO_cleanup_all_ex_data(); - -#else /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ - OPENSSL_cleanup(); -#endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ - - return APR_SUCCESS; -} - -/* - * To ensure thread-safetyness in OpenSSL - work in progress - * Taken from httpd's mod_ssl code. - */ - -#if APR_HAS_THREADS && APR_USE_OPENSSL_PRE_1_1_API - -static apr_thread_mutex_t **ossl_locks; -static int ossl_num_locks; - -static void ossl_thread_locking(int mode, int type, const char *file, int line) -{ - if (type < ossl_num_locks) { - if (mode & CRYPTO_LOCK) { - (void)apr_thread_mutex_lock(ossl_locks[type]); - } - else { - (void)apr_thread_mutex_unlock(ossl_locks[type]); - } - } -} - -/* Dynamic lock structure */ -struct CRYPTO_dynlock_value { - apr_pool_t *pool; - apr_thread_mutex_t *mutex; - const char* file; - int line; -}; - -/* Global reference to the pool passed into ossl_thread_setup() */ -static apr_pool_t *ossl_dynlock_pool = NULL; - -/* - * Dynamic lock creation callback - */ -static -struct CRYPTO_dynlock_value *ossl_dynlock_create(const char *file, int line) -{ - struct CRYPTO_dynlock_value *value; - apr_status_t rv; - apr_pool_t *p; - - /* - * We need a pool to allocate our mutex. Since we can't clear - * allocated memory from a pool, create a subpool that we can blow - * away in the destruction callback. - */ - rv = apr_pool_create(&p, ossl_dynlock_pool); - if (rv != APR_SUCCESS) { - return NULL; - } - - value = apr_palloc(p, sizeof(*value)); - - rv = apr_thread_mutex_create(&value->mutex, APR_THREAD_MUTEX_DEFAULT, p); - if (rv != APR_SUCCESS) { - apr_pool_destroy(p); - return NULL; - } - - /* Keep our own copy of the place from which we were created, - using our own pool. */ - value->file = apr_pstrdup(p, file); - value->line = line; - value->pool = p; - return value; -} - -/* - * Dynamic locking and unlocking function - */ - -static void ossl_dynlock_locking(int mode, struct CRYPTO_dynlock_value *l, - const char *file, int line) -{ - if (mode & CRYPTO_LOCK) { - (void)apr_thread_mutex_lock(l->mutex); - } - else { - (void)apr_thread_mutex_unlock(l->mutex); - } -} - -/* - * Dynamic lock destruction callback - */ -static void ossl_dynlock_destroy(struct CRYPTO_dynlock_value *l, - const char *file, int line) -{ - /* Trust that whomever owned the CRYPTO_dynlock_value we were - * passed has no future use for it... - */ - apr_pool_destroy(l->pool); -} - -/* Windows and BeOS can use the default THREADID callback shipped with OpenSSL - * 1.0.x, as can any platform with a thread-safe errno. - */ -#define OSSL_DEFAULT_THREADID_IS_SAFE (OPENSSL_VERSION_NUMBER >= 0x10000000L \ - && (defined(_REENTRANT) \ - || __BEOS__ \ - || _WIN32 \ - )) -#if OSSL_DEFAULT_THREADID_IS_SAFE - -/* We don't need to set up a threadid callback on this platform. */ -static APR_INLINE apr_status_t ossl_thread_id_setup(apr_pool_t *pool) -{ - return APR_SUCCESS; -} - -static APR_INLINE apr_status_t ossl_thread_id_cleanup(void) -{ - return APR_SUCCESS; -} - -#else - -/** - * Used by both versions of ossl_thread_id(). Returns an unsigned long that - * should be unique to the currently executing thread. - */ -static unsigned long ossl_thread_id_internal(void) -{ - /* OpenSSL needs this to return an unsigned long. On OS/390, the pthread - * id is a structure twice that big. Use the TCB pointer instead as a - * unique unsigned long. - */ -#ifdef __MVS__ - struct PSA { - char unmapped[540]; /* PSATOLD is at offset 540 in the PSA */ - unsigned long PSATOLD; - } *psaptr = 0; /* PSA is at address 0 */ - - return psaptr->PSATOLD; -#else - return (unsigned long) apr_os_thread_current(); -#endif -} - -#ifndef OPENSSL_NO_DEPRECATED - -static unsigned long ossl_thread_id(void) -{ - return ossl_thread_id_internal(); -} - -#else - -static void ossl_thread_id(CRYPTO_THREADID *id) -{ - /* XXX Ideally we would be using the _set_pointer() callback on platforms - * that have a pointer-based thread "identity". But this entire API is - * fraught with problems (see PR60947) and has been removed completely in - * OpenSSL 1.1.0, so I'm not too invested in fixing it right now. */ - CRYPTO_THREADID_set_numeric(id, ossl_thread_id_internal()); -} - -#endif /* OPENSSL_NO_DEPRECATED */ - -static apr_status_t ossl_thread_id_cleanup(void) -{ -#ifndef OPENSSL_NO_DEPRECATED - CRYPTO_set_id_callback(NULL); -#else - /* XXX This does nothing. The new-style THREADID callback is write-once. */ - CRYPTO_THREADID_set_callback(NULL); -#endif - - return APR_SUCCESS; -} - -static apr_status_t ossl_thread_id_setup(apr_pool_t *pool) -{ -#ifndef OPENSSL_NO_DEPRECATED - /* This API is deprecated, but we prefer it to its replacement since it - * allows us to unset the callback when this module is being unloaded. */ - CRYPTO_set_id_callback(ossl_thread_id); -#else - /* This is a last resort. We can only set this once, which means that we'd - * better not get reloaded into a different address. See PR60947. - */ - CRYPTO_THREADID_set_callback(ossl_thread_id); - - if (CRYPTO_THREADID_get_callback() != ossl_thread_id) { - return APR_EGENERAL; - } -#endif - - return APR_SUCCESS; -} - -#endif /* OSSL_DEFAULT_THREADID_IS_SAFE */ - -static apr_status_t ossl_thread_cleanup(void *data) -{ - CRYPTO_set_dynlock_create_callback(NULL); - CRYPTO_set_dynlock_lock_callback(NULL); - CRYPTO_set_dynlock_destroy_callback(NULL); - ossl_dynlock_pool = NULL; - - CRYPTO_set_locking_callback(NULL); - - ossl_thread_id_cleanup(); - - return APR_SUCCESS; -} - -static apr_status_t ossl_thread_setup(apr_pool_t *pool) -{ - apr_status_t rv; - int i, num_locks; - - rv = ossl_thread_id_setup(pool); - if (rv != APR_SUCCESS) { - return rv; - } - - num_locks = CRYPTO_num_locks(); - ossl_locks = apr_palloc(pool, num_locks * sizeof(*ossl_locks)); - if (!ossl_locks) { - return APR_ENOMEM; - } - for (i = 0; i < num_locks; i++) { - rv = apr_thread_mutex_create(&ossl_locks[i], - APR_THREAD_MUTEX_DEFAULT, pool); - if (rv != APR_SUCCESS) { - return rv; - } - } - ossl_num_locks = num_locks; - - CRYPTO_set_locking_callback(ossl_thread_locking); - - /* Set up dynamic locking scaffolding for OpenSSL to use at its - * convenience. - */ - ossl_dynlock_pool = pool; - CRYPTO_set_dynlock_create_callback(ossl_dynlock_create); - CRYPTO_set_dynlock_lock_callback(ossl_dynlock_locking); - CRYPTO_set_dynlock_destroy_callback(ossl_dynlock_destroy); - - apr_pool_cleanup_register(pool, NULL, ossl_thread_cleanup, - apr_pool_cleanup_null); - return APR_SUCCESS; -} - -#endif /* #if APR_HAS_THREADS && APR_USE_OPENSSL_PRE_1_1_API */ - - -#endif /* APU_HAVE_OPENSSL */ - - -#endif /* APU_HAVE_CRYPTO */ |