/*
- * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
#include "internal/thread_once.h"
#ifdef FIPS_MODULE
+#include "prov/provider_ctx.h"
+
/*
* Thread aware code may want to be told about thread stop events. We register
* to hear about those thread stop events when we see a new thread has started.
typedef struct thread_event_handler_st THREAD_EVENT_HANDLER;
struct thread_event_handler_st {
+#ifndef FIPS_MODULE
const void *index;
+#endif
void *arg;
OSSL_thread_stop_handler_fn handfn;
THREAD_EVENT_HANDLER *next;
if (gtr == NULL)
return 0;
- CRYPTO_THREAD_write_lock(gtr->lock);
+ if (!CRYPTO_THREAD_write_lock(gtr->lock))
+ return 0;
ret = (sk_THREAD_EVENT_HANDLER_PTR_push(gtr->skhands, hands) != 0);
CRYPTO_THREAD_unlock(gtr->lock);
gtr = get_global_tevent_register();
if (gtr == NULL)
return;
- CRYPTO_THREAD_write_lock(gtr->lock);
+ if (!CRYPTO_THREAD_write_lock(gtr->lock))
+ return;
for (i = 0; i < sk_THREAD_EVENT_HANDLER_PTR_num(gtr->skhands); i++) {
THREAD_EVENT_HANDLER **hands
= sk_THREAD_EVENT_HANDLER_PTR_value(gtr->skhands, i);
if (hands == handsin) {
- hands = sk_THREAD_EVENT_HANDLER_PTR_delete(gtr->skhands, i);
+ sk_THREAD_EVENT_HANDLER_PTR_delete(gtr->skhands, i);
CRYPTO_THREAD_unlock(gtr->lock);
return;
}
destructor_key.sane = -1;
}
-void OPENSSL_thread_stop_ex(OPENSSL_CTX *ctx)
+void OPENSSL_thread_stop_ex(OSSL_LIB_CTX *ctx)
{
- ctx = openssl_ctx_get_concrete(ctx);
+ ctx = ossl_lib_ctx_get_concrete(ctx);
/*
- * TODO(3.0). It would be nice if we could figure out a way to do this on
- * all threads that have used the OPENSSL_CTX when the OPENSSL_CTX is freed.
- * This is currently not possible due to the use of thread local variables.
+ * It would be nice if we could figure out a way to do this on all threads
+ * that have used the OSSL_LIB_CTX when the context is freed. This is
+ * currently not possible due to the use of thread local variables.
*/
ossl_ctx_thread_stop(ctx);
}
}
}
-void ossl_ctx_thread_stop(void *arg)
+void ossl_ctx_thread_stop(OSSL_LIB_CTX *ctx)
{
if (destructor_key.sane != -1) {
THREAD_EVENT_HANDLER **hands
= init_get_thread_local(&destructor_key.value, 0, 1);
- init_thread_stop(arg, hands);
+ init_thread_stop(ctx, hands);
}
}
#else
-static void *thread_event_ossl_ctx_new(OPENSSL_CTX *libctx)
+static void *thread_event_ossl_ctx_new(OSSL_LIB_CTX *libctx)
{
THREAD_EVENT_HANDLER **hands = NULL;
CRYPTO_THREAD_LOCAL *tlocal = OPENSSL_zalloc(sizeof(*tlocal));
OPENSSL_free(tlocal);
}
-static const OPENSSL_CTX_METHOD thread_event_ossl_ctx_method = {
+static const OSSL_LIB_CTX_METHOD thread_event_ossl_ctx_method = {
+ OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY,
thread_event_ossl_ctx_new,
thread_event_ossl_ctx_free,
};
-void ossl_ctx_thread_stop(void *arg)
+static void ossl_arg_thread_stop(void *arg)
+{
+ ossl_ctx_thread_stop((OSSL_LIB_CTX *)arg);
+}
+
+void ossl_ctx_thread_stop(OSSL_LIB_CTX *ctx)
{
THREAD_EVENT_HANDLER **hands;
- OPENSSL_CTX *ctx = arg;
CRYPTO_THREAD_LOCAL *local
- = openssl_ctx_get_data(ctx, OPENSSL_CTX_THREAD_EVENT_HANDLER_INDEX,
- &thread_event_ossl_ctx_method);
+ = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_THREAD_EVENT_HANDLER_INDEX,
+ &thread_event_ossl_ctx_method);
if (local == NULL)
return;
hands = init_get_thread_local(local, 0, 0);
- init_thread_stop(arg, hands);
+ init_thread_stop(ctx, hands);
OPENSSL_free(hands);
}
#endif /* FIPS_MODULE */
THREAD_EVENT_HANDLER **hands;
THREAD_EVENT_HANDLER *hand;
#ifdef FIPS_MODULE
- OPENSSL_CTX *ctx = arg;
+ OSSL_LIB_CTX *ctx = arg;
/*
* In FIPS mode the list of THREAD_EVENT_HANDLERs is unique per combination
- * of OPENSSL_CTX and thread. This is because in FIPS mode each OPENSSL_CTX
- * gets informed about thread stop events individually.
+ * of OSSL_LIB_CTX and thread. This is because in FIPS mode each
+ * OSSL_LIB_CTX gets informed about thread stop events individually.
*/
CRYPTO_THREAD_LOCAL *local
- = openssl_ctx_get_data(ctx, OPENSSL_CTX_THREAD_EVENT_HANDLER_INDEX,
- &thread_event_ossl_ctx_method);
+ = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_THREAD_EVENT_HANDLER_INDEX,
+ &thread_event_ossl_ctx_method);
#else
/*
* Outside of FIPS mode the list of THREAD_EVENT_HANDLERs is unique per
- * thread, but may hold multiple OPENSSL_CTXs. We only get told about
+ * thread, but may hold multiple OSSL_LIB_CTXs. We only get told about
* thread stop events globally, so we have to ensure all affected
- * OPENSSL_CTXs are informed.
+ * OSSL_LIB_CTXs are informed.
*/
CRYPTO_THREAD_LOCAL *local = &destructor_key.value;
#endif
* libcrypto to tell us about later thread stop events. c_thread_start
* is a callback to libcrypto defined in fipsprov.c
*/
- if (!c_thread_start(FIPS_get_core_handle(ctx), ossl_ctx_thread_stop))
+ if (!c_thread_start(FIPS_get_core_handle(ctx), ossl_arg_thread_stop,
+ ctx))
return 0;
}
#endif
hand->handfn = handfn;
hand->arg = arg;
+#ifndef FIPS_MODULE
hand->index = index;
+#endif
hand->next = *hands;
*hands = hand;
gtr = get_global_tevent_register();
if (gtr == NULL)
return 0;
- if (!all)
- CRYPTO_THREAD_write_lock(gtr->lock);
+ if (!all) {
+ if (!CRYPTO_THREAD_write_lock(gtr->lock))
+ return 0;
+ } else {
+ glob_tevent_reg = NULL;
+ }
for (i = 0; i < sk_THREAD_EVENT_HANDLER_PTR_num(gtr->skhands); i++) {
THREAD_EVENT_HANDLER **hands
= sk_THREAD_EVENT_HANDLER_PTR_value(gtr->skhands, i);
- THREAD_EVENT_HANDLER *curr = *hands, *prev = NULL, *tmp;
+ THREAD_EVENT_HANDLER *curr = NULL, *prev = NULL, *tmp;
if (hands == NULL) {
if (!all)
CRYPTO_THREAD_unlock(gtr->lock);
return 0;
}
+ curr = *hands;
while (curr != NULL) {
if (all || curr->index == index) {
if (prev != NULL)