*/
#include "e_os.h"
-#include "internal/cryptlib_int.h"
+#include "crypto/cryptlib.h"
#include <openssl/err.h>
-#include "internal/rand_int.h"
+#include "crypto/rand.h"
#include "internal/bio.h"
#include <openssl/evp.h>
-#include "internal/evp_int.h"
+#include "crypto/evp.h"
#include "internal/conf.h"
-#include "internal/async.h"
-#include "internal/engine.h"
+#include "crypto/async.h"
+#include "crypto/engine.h"
#include "internal/comp.h"
#include "internal/err.h"
-#include "internal/err_int.h"
-#include "internal/objects.h"
+#include "crypto/err.h"
+#include "crypto/objects.h"
#include <stdlib.h>
#include <assert.h>
#include "internal/thread_once.h"
-#include "internal/dso_conf.h"
+#include "crypto/dso_conf.h"
#include "internal/dso.h"
-#include "internal/store.h"
+#include "crypto/store.h"
+#include <openssl/cmp_util.h> /* for OSSL_CMP_log_close() */
#include <openssl/trace.h>
static int stopped = 0;
-typedef struct thread_event_handler_st THREAD_EVENT_HANDLER;
-struct thread_event_handler_st {
- OPENSSL_CTX *ctx;
- ossl_thread_stop_handler_fn handfn;
- THREAD_EVENT_HANDLER *next;
-};
-
-/*
- * Since per-thread-specific-data destructors are not universally
- * available, i.e. not on Windows, only below CRYPTO_THREAD_LOCAL key
- * is assumed to have destructor associated. And then an effort is made
- * to call this single destructor on non-pthread platform[s].
- *
- * Initial value is "impossible". It is used as guard value to shortcut
- * destructor for threads terminating before libcrypto is initialized or
- * after it's de-initialized. Access to the key doesn't have to be
- * serialized for the said threads, because they didn't use libcrypto
- * and it doesn't matter if they pick "impossible" or derefernce real
- * key value and pull NULL past initialization in the first thread that
- * intends to use libcrypto.
- */
-static union {
- long sane;
- CRYPTO_THREAD_LOCAL value;
-} destructor_key = { -1 };
-
-static void ossl_init_thread_stop(THREAD_EVENT_HANDLER **hands);
-
-static void ossl_init_thread_destructor(void *hands)
-{
- ossl_init_thread_stop((THREAD_EVENT_HANDLER **)hands);
-}
-
-static THREAD_EVENT_HANDLER **ossl_init_get_thread_local(int alloc)
-{
- THREAD_EVENT_HANDLER **hands =
- CRYPTO_THREAD_get_local(&destructor_key.value);
-
- if (alloc) {
- if (hands == NULL
- && (hands = OPENSSL_zalloc(sizeof(*hands))) != NULL
- && !CRYPTO_THREAD_set_local(&destructor_key.value, hands)) {
- OPENSSL_free(hands);
- return NULL;
- }
- } else {
- CRYPTO_THREAD_set_local(&destructor_key.value, NULL);
- }
-
- return hands;
-}
-
typedef struct ossl_init_stop_st OPENSSL_INIT_STOP;
struct ossl_init_stop_st {
void (*handler)(void);
static int base_inited = 0;
DEFINE_RUN_ONCE_STATIC(ossl_init_base)
{
- CRYPTO_THREAD_LOCAL key;
-
- if (ossl_trace_init() == 0)
- return 0;
+ /* no need to init trace */
OSSL_TRACE(INIT, "ossl_init_base: setting up stop handlers\n");
#ifndef OPENSSL_NO_CRYPTO_MDEBUG
ossl_malloc_setup_failures();
#endif
- if (!CRYPTO_THREAD_init_local(&key, ossl_init_thread_destructor))
- return 0;
+
if ((init_lock = CRYPTO_THREAD_lock_new()) == NULL)
goto err;
OPENSSL_cpuid_setup();
- destructor_key.value = key;
+ if (!ossl_init_thread())
+ return 0;
+
base_inited = 1;
return 1;
CRYPTO_THREAD_lock_free(init_lock);
init_lock = NULL;
- CRYPTO_THREAD_cleanup_local(&key);
return 0;
}
return 1;
}
-static CRYPTO_ONCE add_all_macs = CRYPTO_ONCE_STATIC_INIT;
-DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_macs)
-{
- /*
- * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time
- * pulling in all the macs during static linking
- */
-#ifndef OPENSSL_NO_AUTOALGINIT
- OSSL_TRACE(INIT, "openssl_add_all_macs_int()\n");
- openssl_add_all_macs_int();
-#endif
- return 1;
-}
-
-DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_add_all_macs, ossl_init_add_all_macs)
-{
- /* Do nothing */
- return 1;
-}
-
-static CRYPTO_ONCE add_all_kdfs = CRYPTO_ONCE_STATIC_INIT;
-DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_kdfs)
-{
- /*
- * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time
- * pulling in all the macs during static linking
- */
-#ifndef OPENSSL_NO_AUTOALGINIT
- OSSL_TRACE(INIT, "openssl_add_all_kdfs_int()\n");
- openssl_add_all_kdfs_int();
-#endif
- return 1;
-}
-
-DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_add_all_kdfs, ossl_init_add_all_kdfs)
-{
- /* Do nothing */
- return 1;
-}
-
static CRYPTO_ONCE config = CRYPTO_ONCE_STATIC_INIT;
static int config_inited = 0;
static const OPENSSL_INIT_SETTINGS *conf_settings = NULL;
}
#endif
-static void ossl_init_thread_stop(THREAD_EVENT_HANDLER **hands)
-{
- THREAD_EVENT_HANDLER *curr, *prev = NULL;
-
- /* Can't do much about this */
- if (hands == NULL)
- return;
-
- curr = *hands;
- while (curr != NULL) {
- curr->handfn(curr->ctx);
- prev = curr;
- curr = curr->next;
- OPENSSL_free(prev);
- }
-
- OPENSSL_free(hands);
-}
-
-void OPENSSL_thread_stop(void)
-{
- if (destructor_key.sane != -1)
- ossl_init_thread_stop(ossl_init_get_thread_local(0));
-}
-
-int ossl_init_thread_start(OPENSSL_CTX *ctx, ossl_thread_stop_handler_fn handfn)
-{
- THREAD_EVENT_HANDLER **hands;
- THREAD_EVENT_HANDLER *hand;
-
- if (!OPENSSL_init_crypto(0, NULL))
- return 0;
-
- hands = ossl_init_get_thread_local(1);
-
- if (hands == NULL)
- return 0;
-
- hand = OPENSSL_malloc(sizeof(*hand));
- if (hand == NULL)
- return 0;
-
- hand->handfn = handfn;
- hand->ctx = ctx;
- hand->next = *hands;
- *hands = hand;
-
- return 1;
-}
-
void OPENSSL_cleanup(void)
{
OPENSSL_INIT_STOP *currhandler, *lasthandler;
- CRYPTO_THREAD_LOCAL key;
/*
* TODO(3.0): This function needs looking at with a view to moving most/all
* Thread stop may not get automatically called by the thread library for
* the very last thread in some situations, so call it directly.
*/
- ossl_init_thread_stop(ossl_init_get_thread_local(0));
+ OPENSSL_thread_stop();
currhandler = stop_handlers;
while (currhandler != NULL) {
err_free_strings_int();
}
- key = destructor_key.value;
- destructor_key.sane = -1;
- CRYPTO_THREAD_cleanup_local(&key);
-
/*
* Note that cleanup order is important:
* - rand_cleanup_int could call an ENGINE's RAND cleanup function so
OSSL_TRACE(INIT, "OPENSSL_cleanup: openssl_ctx_default_deinit()\n");
openssl_ctx_default_deinit();
+ ossl_cleanup_thread();
+
OSSL_TRACE(INIT, "OPENSSL_cleanup: bio_cleanup()\n");
bio_cleanup();
OSSL_TRACE(INIT, "OPENSSL_cleanup: CRYPTO_secure_malloc_done()\n");
CRYPTO_secure_malloc_done();
+#ifndef OPENSSL_NO_CMP
+ OSSL_TRACE(INIT, "OPENSSL_cleanup: OSSL_CMP_log_close()\n");
+ OSSL_CMP_log_close();
+#endif
+
OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_trace_cleanup()\n");
ossl_trace_cleanup();
&& !RUN_ONCE(&add_all_digests, ossl_init_add_all_digests))
return 0;
- if ((opts & OPENSSL_INIT_NO_ADD_ALL_MACS)
- && !RUN_ONCE_ALT(&add_all_macs, ossl_init_no_add_all_macs,
- ossl_init_add_all_macs))
- return 0;
-
- if ((opts & OPENSSL_INIT_ADD_ALL_MACS)
- && !RUN_ONCE(&add_all_macs, ossl_init_add_all_macs))
- return 0;
-
- if ((opts & OPENSSL_INIT_NO_ADD_ALL_KDFS)
- && !RUN_ONCE_ALT(&add_all_kdfs, ossl_init_no_add_all_kdfs,
- ossl_init_add_all_kdfs))
- return 0;
-
- if ((opts & OPENSSL_INIT_ADD_ALL_KDFS)
- && !RUN_ONCE(&add_all_kdfs, ossl_init_add_all_kdfs))
- return 0;
-
if ((opts & OPENSSL_INIT_ATFORK)
&& !openssl_init_fork_handlers())
return 0;
void OPENSSL_fork_child(void)
{
- rand_fork();
/* TODO(3.0): Inform all providers about a fork event */
}
#endif