summaryrefslogtreecommitdiff
path: root/crypto
diff options
context:
space:
mode:
authorGraham Leggett <minfrin@apache.org>2019-06-23 22:15:31 +0000
committerGraham Leggett <minfrin@apache.org>2019-06-23 22:15:31 +0000
commit39f444510548b97f6e46e16df675bdce5f943920 (patch)
treea1b7204505c4d4271d180730b5fe57eb6a478e7e /crypto
parent6c6926d56bf0a4c4939bf3e5200539200b198cff (diff)
downloadapr-39f444510548b97f6e46e16df675bdce5f943920.tar.gz
Revert r1833421 et al:
Move OpenSSL initialisation back to apr_crypto_openssl, reinstate DSO support. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1861951 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'crypto')
-rw-r--r--crypto/apr_crypto.c25
-rw-r--r--crypto/apr_crypto_internal.c357
-rw-r--r--crypto/apr_crypto_openssl.c46
3 files changed, 45 insertions, 383 deletions
diff --git a/crypto/apr_crypto.c b/crypto/apr_crypto.c
index ea6575b4f..478e3a4a7 100644
--- a/crypto/apr_crypto.c
+++ b/crypto/apr_crypto.c
@@ -379,14 +379,7 @@ APR_DECLARE(apr_status_t) apr_crypto_lib_version(const char *name,
const char **version)
{
apr_status_t rv = APR_ENOTIMPL;
-#if APU_HAVE_OPENSSL
- if (!strcmp(name, "openssl")) {
- *version = apr__crypto_openssl_version();
- rv = *version ? APR_SUCCESS : APR_NOTFOUND;
- }
- else
-#endif
- ;
+
return rv;
}
@@ -434,16 +427,6 @@ APR_DECLARE(apr_status_t) apr_crypto_lib_init(const char *name,
}
rv = APR_ENOTIMPL;
-#if APU_HAVE_OPENSSL
- if (!strcmp(name, "openssl")) {
- rv = apr__crypto_openssl_init(params, result, pool);
- if (rv == APR_SUCCESS) {
- lib->term = apr__crypto_openssl_term;
- lib->name = "openssl";
- }
- }
- else
-#endif
;
if (rv == APR_SUCCESS) {
lib->pool = pool;
@@ -473,12 +456,6 @@ static apr_status_t crypto_lib_term(const char *name)
}
rv = APR_ENOTIMPL;
-#if APU_HAVE_OPENSSL
- if (!strcmp(name, "openssl")) {
- rv = APR_SUCCESS;
- }
- else
-#endif
;
if (rv == APR_SUCCESS) {
apr_pool_cleanup_kill(lib->pool, lib, crypto_lib_cleanup);
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 */
diff --git a/crypto/apr_crypto_openssl.c b/crypto/apr_crypto_openssl.c
index 3220eef6b..7a9c40459 100644
--- a/crypto/apr_crypto_openssl.c
+++ b/crypto/apr_crypto_openssl.c
@@ -26,6 +26,7 @@
#include "apr_strings.h"
#include "apr_time.h"
#include "apr_buckets.h"
+#include "apr_thread_mutex.h"
#include "apr_crypto_internal.h"
@@ -36,9 +37,28 @@
#include <openssl/engine.h>
#include <openssl/crypto.h>
#include <openssl/obj_mac.h> /* for NID_* */
+#include <openssl/conf.h>
+#include <openssl/comp.h>
+#include <openssl/ssl.h>
#define LOG_PREFIX "apr_crypto_openssl: "
+#ifndef APR_USE_OPENSSL_PRE_1_1_API
+#if defined(LIBRESSL_VERSION_NUMBER)
+/* LibreSSL declares OPENSSL_VERSION_NUMBER == 2.0 but does not necessarily
+ * include changes from OpenSSL >= 1.1 (new functions, macros, * deprecations,
+ * ...), so we have to work around this...
+ */
+#define APR_USE_OPENSSL_PRE_1_0_API (0)
+#define APR_USE_OPENSSL_PRE_1_1_API (LIBRESSL_VERSION_NUMBER < 0x2070000f)
+#define APR_USE_OPENSSL_PRE_1_1_1_API (1)
+#else /* defined(LIBRESSL_VERSION_NUMBER) */
+#define APR_USE_OPENSSL_PRE_1_0_API (OPENSSL_VERSION_NUMBER < 0x10000000L)
+#define APR_USE_OPENSSL_PRE_1_1_API (OPENSSL_VERSION_NUMBER < 0x10100000L)
+#define APR_USE_OPENSSL_PRE_1_1_1_API (OPENSSL_VERSION_NUMBER < 0x10101000L)
+#endif /* defined(LIBRESSL_VERSION_NUMBER) */
+#endif /* ndef APR_USE_OPENSSL_PRE_1_1_API */
+
struct apr_crypto_t {
apr_pool_t *pool;
const apr_crypto_driver_t *provider;
@@ -133,7 +153,15 @@ static apr_status_t crypto_error(const apu_err_t **result,
*/
static apr_status_t crypto_shutdown(void)
{
- return apr_crypto_lib_term("openssl");
+ ERR_free_strings();
+ EVP_cleanup();
+ ENGINE_cleanup();
+ return APR_SUCCESS;
+}
+
+static apr_status_t crypto_shutdown_helper(void *data)
+{
+ return crypto_shutdown();
}
/**
@@ -142,7 +170,21 @@ static apr_status_t crypto_shutdown(void)
static apr_status_t crypto_init(apr_pool_t *pool, const char *params,
const apu_err_t **result)
{
- return apr_crypto_lib_init("openssl", params, result, pool);
+#if APR_USE_OPENSSL_PRE_1_1_API
+ (void)CRYPTO_malloc_init();
+#else
+ OPENSSL_malloc_init();
+#endif
+ ERR_load_crypto_strings();
+ /* SSL_load_error_strings(); */
+ OpenSSL_add_all_algorithms();
+ ENGINE_load_builtin_engines();
+ ENGINE_register_all_complete();
+
+ apr_pool_cleanup_register(pool, pool, crypto_shutdown_helper,
+ apr_pool_cleanup_null);
+
+ return APR_SUCCESS;
}
#if OPENSSL_VERSION_NUMBER < 0x0090802fL