summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crypto/context.c159
-rw-r--r--crypto/core_fetch.c2
-rw-r--r--crypto/cpt_err.c8
-rw-r--r--crypto/err/openssl.txt2
-rw-r--r--crypto/evp/evp_fetch.c32
-rw-r--r--crypto/ex_data.c164
-rw-r--r--crypto/init.c7
-rw-r--r--crypto/property/defn_cache.c41
-rw-r--r--crypto/property/property.c50
-rw-r--r--crypto/property/property_lcl.h25
-rw-r--r--crypto/property/property_parse.c46
-rw-r--r--crypto/property/property_string.c97
-rw-r--r--crypto/provider_core.c18
-rw-r--r--include/internal/core.h2
-rw-r--r--include/internal/cryptlib.h68
-rw-r--r--include/internal/property.h5
-rw-r--r--include/openssl/crypto.h1
-rw-r--r--include/openssl/cryptoerr.h4
-rw-r--r--test/build.info2
-rw-r--r--test/context_internal_test.c20
-rw-r--r--test/property_test.c72
21 files changed, 509 insertions, 316 deletions
diff --git a/crypto/context.c b/crypto/context.c
index a1a5d0cbd1..be2d348fec 100644
--- a/crypto/context.c
+++ b/crypto/context.c
@@ -11,31 +11,76 @@
#include "internal/thread_once.h"
struct openssl_ctx_onfree_list_st {
- openssl_ctx_onfree_fn fn;
+ openssl_ctx_onfree_fn *fn;
struct openssl_ctx_onfree_list_st *next;
};
struct openssl_ctx_st {
CRYPTO_RWLOCK *lock;
CRYPTO_EX_DATA data;
- int run_once_done[MAX_OPENSSL_CTX_RUN_ONCE];
- int run_once_ret[MAX_OPENSSL_CTX_RUN_ONCE];
+
+ /*
+ * For most data in the OPENSSL_CTX we just use ex_data to store it. But
+ * that doesn't work for ex_data itself - so we store that directly.
+ */
+ OSSL_EX_DATA_GLOBAL global;
+
+ /* Map internal static indexes to dynamically created indexes */
+ int dyn_indexes[OPENSSL_CTX_MAX_INDEXES];
+
+ CRYPTO_RWLOCK *oncelock;
+ int run_once_done[OPENSSL_CTX_MAX_RUN_ONCE];
+ int run_once_ret[OPENSSL_CTX_MAX_RUN_ONCE];
struct openssl_ctx_onfree_list_st *onfreelist;
};
-static OPENSSL_CTX default_context;
+#ifndef FIPS_MODE
+static OPENSSL_CTX default_context_int;
+#endif
+
+/* Always points at default_context_int if it has been initialised */
+static OPENSSL_CTX *default_context = NULL;
static int context_init(OPENSSL_CTX *ctx)
{
- return (ctx->lock = CRYPTO_THREAD_lock_new()) != NULL
- && CRYPTO_new_ex_data(CRYPTO_EX_INDEX_OPENSSL_CTX, NULL,
- &ctx->data);
+ size_t i;
+
+ ctx->lock = CRYPTO_THREAD_lock_new();
+ if (ctx->lock == NULL)
+ return 0;
+
+ ctx->oncelock = CRYPTO_THREAD_lock_new();
+ if (ctx->oncelock == NULL)
+ goto err;
+
+ for (i = 0; i < OPENSSL_CTX_MAX_INDEXES; i++)
+ ctx->dyn_indexes[i] = -1;
+
+ if (!do_ex_data_init(ctx))
+ goto err;
+
+ if (!crypto_new_ex_data_ex(ctx, CRYPTO_EX_INDEX_OPENSSL_CTX, NULL,
+ &ctx->data)) {
+ crypto_cleanup_all_ex_data_int(ctx);
+ goto err;
+ }
+
+ return 1;
+ err:
+ CRYPTO_THREAD_lock_free(ctx->oncelock);
+ CRYPTO_THREAD_lock_free(ctx->lock);
+ ctx->lock = NULL;
+ return 0;
}
static int context_deinit(OPENSSL_CTX *ctx)
{
- struct openssl_ctx_onfree_list_st *tmp, *onfree = ctx->onfreelist;
+ struct openssl_ctx_onfree_list_st *tmp, *onfree;
+
+ if (ctx == NULL)
+ return 1;
+ onfree = ctx->onfreelist;
while (onfree != NULL) {
onfree->fn(ctx);
tmp = onfree;
@@ -43,21 +88,28 @@ static int context_deinit(OPENSSL_CTX *ctx)
OPENSSL_free(tmp);
}
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_OPENSSL_CTX, NULL, &ctx->data);
+ crypto_cleanup_all_ex_data_int(ctx);
+ CRYPTO_THREAD_lock_free(ctx->oncelock);
CRYPTO_THREAD_lock_free(ctx->lock);
+ ctx->lock = NULL;
return 1;
}
-static CRYPTO_ONCE default_context_init = CRYPTO_ONCE_STATIC_INIT;
-static void do_default_context_deinit(void)
+#ifndef FIPS_MODE
+void openssl_ctx_default_deinit(void)
{
- context_deinit(&default_context);
+ context_deinit(default_context);
}
+
+static CRYPTO_ONCE default_context_init = CRYPTO_ONCE_STATIC_INIT;
DEFINE_RUN_ONCE_STATIC(do_default_context_init)
{
- return OPENSSL_init_crypto(0, NULL)
- && context_init(&default_context)
- && OPENSSL_atexit(do_default_context_deinit);
+ if (context_init(&default_context_int))
+ default_context = &default_context_int;
+
+ return 1;
}
+#endif
OPENSSL_CTX *OPENSSL_CTX_new(void)
{
@@ -82,7 +134,7 @@ static void openssl_ctx_generic_new(void *parent_ign, void *ptr_ign,
long argl_ign, void *argp)
{
const OPENSSL_CTX_METHOD *meth = argp;
- void *ptr = meth->new_func();
+ void *ptr = meth->new_func(crypto_ex_data_get_openssl_ctx(ad));
if (ptr != NULL)
CRYPTO_set_ex_data(ad, index, ptr);
@@ -95,37 +147,86 @@ static void openssl_ctx_generic_free(void *parent_ign, void *ptr,
meth->free_func(ptr);
}
-int openssl_ctx_new_index(const OPENSSL_CTX_METHOD *meth)
+
+/* Non-static so we can use it in context_internal_test */
+static int openssl_ctx_init_index(OPENSSL_CTX *ctx, int static_index,
+ const OPENSSL_CTX_METHOD *meth)
{
- return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_OPENSSL_CTX, 0, (void *)meth,
- openssl_ctx_generic_new, NULL,
- openssl_ctx_generic_free);
+ int idx;
+
+#ifndef FIPS_MODE
+ if (ctx == NULL) {
+ if (!RUN_ONCE(&default_context_init, do_default_context_init))
+ return 0;
+ ctx = default_context;
+ }
+#endif
+ if (ctx == NULL)
+ return 0;
+
+ idx = crypto_get_ex_new_index_ex(ctx, CRYPTO_EX_INDEX_OPENSSL_CTX, 0,
+ (void *)meth,
+ openssl_ctx_generic_new,
+ NULL, openssl_ctx_generic_free);
+ if (idx < 0)
+ return 0;
+
+ ctx->dyn_indexes[static_index] = idx;
+ return 1;
}
-void *openssl_ctx_get_data(OPENSSL_CTX *ctx, int index)
+void *openssl_ctx_get_data(OPENSSL_CTX *ctx, int index,
+ const OPENSSL_CTX_METHOD *meth)
{
void *data = NULL;
+#ifndef FIPS_MODE
if (ctx == NULL) {
if (!RUN_ONCE(&default_context_init, do_default_context_init))
return NULL;
- ctx = &default_context;
+ ctx = default_context;
}
+#endif
if (ctx == NULL)
return NULL;
CRYPTO_THREAD_read_lock(ctx->lock);
+ if (ctx->dyn_indexes[index] == -1
+ && !openssl_ctx_init_index(ctx, index, meth)) {
+ CRYPTO_THREAD_unlock(ctx->lock);
+ return NULL;
+ }
+
/* The alloc call ensures there's a value there */
if (CRYPTO_alloc_ex_data(CRYPTO_EX_INDEX_OPENSSL_CTX, NULL,
- &ctx->data, index))
- data = CRYPTO_get_ex_data(&ctx->data, index);
+ &ctx->data, ctx->dyn_indexes[index]))
+ data = CRYPTO_get_ex_data(&ctx->data, ctx->dyn_indexes[index]);
CRYPTO_THREAD_unlock(ctx->lock);
return data;
}
+OSSL_EX_DATA_GLOBAL *openssl_ctx_get_ex_data_global(OPENSSL_CTX *ctx)
+{
+ /*
+ * The default context code is not needed in FIPS_MODE and ctx should never
+ * be NULL in the FIPS provider. However we compile this code out to ensure
+ * we fail immediately if ctx == NULL in FIPS_MODE
+ */
+#ifndef FIPS_MODE
+ if (ctx == NULL) {
+ if (!RUN_ONCE(&default_context_init, do_default_context_init))
+ return NULL;
+ ctx = default_context;
+ }
+#endif
+ if (ctx == NULL)
+ return NULL;
+ return &ctx->global;
+}
+
int openssl_ctx_run_once(OPENSSL_CTX *ctx, unsigned int idx,
openssl_ctx_run_once_fn run_once_fn)
{
@@ -135,32 +236,32 @@ int openssl_ctx_run_once(OPENSSL_CTX *ctx, unsigned int idx,
if (ctx == NULL) {
if (!RUN_ONCE(&default_context_init, do_default_context_init))
return 0;
- ctx = &default_context;
+ ctx = default_context;
}
#endif
if (ctx == NULL)
return 0;
- CRYPTO_THREAD_read_lock(ctx->lock);
+ CRYPTO_THREAD_read_lock(ctx->oncelock);
done = ctx->run_once_done[idx];
if (done)
ret = ctx->run_once_ret[idx];
- CRYPTO_THREAD_unlock(ctx->lock);
+ CRYPTO_THREAD_unlock(ctx->oncelock);
if (done)
return ret;
- CRYPTO_THREAD_write_lock(ctx->lock);
+ CRYPTO_THREAD_write_lock(ctx->oncelock);
if (ctx->run_once_done[idx]) {
ret = ctx->run_once_ret[idx];
- CRYPTO_THREAD_unlock(ctx->lock);
+ CRYPTO_THREAD_unlock(ctx->oncelock);
return ret;
}
ret = run_once_fn(ctx);
ctx->run_once_done[idx] = 1;
ctx->run_once_ret[idx] = ret;
- CRYPTO_THREAD_unlock(ctx->lock);
+ CRYPTO_THREAD_unlock(ctx->oncelock);
return ret;
}
diff --git a/crypto/core_fetch.c b/crypto/core_fetch.c
index 2c4b0d71de..6c4ed6a30a 100644
--- a/crypto/core_fetch.c
+++ b/crypto/core_fetch.c
@@ -86,7 +86,7 @@ void *ossl_method_construct(OPENSSL_CTX *libctx, int operation_id,
* We have a temporary store to be able to easily search among new
* items, or items that should find themselves in the global store.
*/
- if ((cbdata.store = mcm->alloc_tmp_store()) == NULL)
+ if ((cbdata.store = mcm->alloc_tmp_store(libctx)) == NULL)
goto fin;
cbdata.libctx = libctx;
diff --git a/crypto/cpt_err.c b/crypto/cpt_err.c
index 8c386925f8..25bb81342b 100644
--- a/crypto/cpt_err.c
+++ b/crypto/cpt_err.c
@@ -21,9 +21,13 @@ static const ERR_STRING_DATA CRYPTO_str_functs[] = {
"CRYPTO_free_ex_data"},
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX, 0),
"CRYPTO_get_ex_new_index"},
+ {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX_EX, 0),
+ "CRYPTO_get_ex_new_index_ex"},
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_CRYPTO_MEMDUP, 0), "CRYPTO_memdup"},
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_CRYPTO_NEW_EX_DATA, 0),
"CRYPTO_new_ex_data"},
+ {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_CRYPTO_NEW_EX_DATA_EX, 0),
+ "crypto_new_ex_data_ex"},
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_CRYPTO_OCB128_COPY_CTX, 0),
"CRYPTO_ocb128_copy_ctx"},
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_CRYPTO_OCB128_INIT, 0),
@@ -46,10 +50,10 @@ static const ERR_STRING_DATA CRYPTO_str_functs[] = {
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OPENSSL_SK_DEEP_COPY, 0),
"OPENSSL_sk_deep_copy"},
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OPENSSL_SK_DUP, 0), "OPENSSL_sk_dup"},
- {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OSSL_PROVIDER_ADD_BUILTIN, 0),
- "OSSL_PROVIDER_add_builtin"},
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OSSL_PROVIDER_ACTIVATE, 0),
"ossl_provider_activate"},
+ {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OSSL_PROVIDER_ADD_BUILTIN, 0),
+ "OSSL_PROVIDER_add_builtin"},
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OSSL_PROVIDER_ADD_PARAMETER, 0),
"ossl_provider_add_parameter"},
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OSSL_PROVIDER_NEW, 0),
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index 5c444f5ba7..225fe218a6 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -374,8 +374,10 @@ CRYPTO_F_CMAC_CTX_NEW:120:CMAC_CTX_new
CRYPTO_F_CRYPTO_DUP_EX_DATA:110:CRYPTO_dup_ex_data
CRYPTO_F_CRYPTO_FREE_EX_DATA:111:CRYPTO_free_ex_data
CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX:100:CRYPTO_get_ex_new_index
+CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX_EX:141:crypto_get_ex_new_index_ex
CRYPTO_F_CRYPTO_MEMDUP:115:CRYPTO_memdup
CRYPTO_F_CRYPTO_NEW_EX_DATA:112:CRYPTO_new_ex_data
+CRYPTO_F_CRYPTO_NEW_EX_DATA_EX:142:crypto_new_ex_data_ex
CRYPTO_F_CRYPTO_OCB128_COPY_CTX:121:CRYPTO_ocb128_copy_ctx
CRYPTO_F_CRYPTO_OCB128_INIT:122:CRYPTO_ocb128_init
CRYPTO_F_CRYPTO_SET_EX_DATA:102:CRYPTO_set_ex_data
diff --git a/crypto/evp/evp_fetch.c b/crypto/evp/evp_fetch.c
index c054f31158..d2c0b62cd8 100644
--- a/crypto/evp/evp_fetch.c
+++ b/crypto/evp/evp_fetch.c
@@ -19,17 +19,14 @@
#include "internal/evp_int.h" /* evp_locl.h needs it */
#include "evp_locl.h"
-/* The OpenSSL library context index for the default method store */
-static int default_method_store_index = -1;
-
static void default_method_store_free(void *vstore)
{
ossl_method_store_free(vstore);
}
-static void *default_method_store_new(void)
+static void *default_method_store_new(OPENSSL_CTX *ctx)
{
- return ossl_method_store_new();
+ return ossl_method_store_new(ctx);
}
@@ -38,21 +35,6 @@ static const OPENSSL_CTX_METHOD default_method_store_method = {
default_method_store_free,
};
-static int default_method_store_init(void)
-{
- default_method_store_index =
- openssl_ctx_new_index(&default_method_store_method);
-
- return default_method_store_index != -1;
-}
-
-static CRYPTO_ONCE default_method_store_init_flag = CRYPTO_ONCE_STATIC_INIT;
-DEFINE_RUN_ONCE_STATIC(do_default_method_store_init)
-{
- return OPENSSL_init_crypto(0, NULL)
- && default_method_store_init();
-}
-
/* Data to be passed through ossl_method_construct() */
struct method_data_st {
const char *name;
@@ -68,9 +50,9 @@ struct method_data_st {
/*
* Generic routines to fetch / create EVP methods with ossl_method_construct()
*/
-static void *alloc_tmp_method_store(void)
+static void *alloc_tmp_method_store(OPENSSL_CTX *ctx)
{
- return ossl_method_store_new();
+ return ossl_method_store_new(ctx);
}
static void dealloc_tmp_method_store(void *store)
@@ -81,10 +63,8 @@ static void *alloc_tmp_method_store(void)
static OSSL_METHOD_STORE *get_default_method_store(OPENSSL_CTX *libctx)
{
- if (!RUN_ONCE(&default_method_store_init_flag,
- do_default_method_store_init))
- return NULL;
- return openssl_ctx_get_data(libctx, default_method_store_index);
+ return openssl_ctx_get_data(libctx, OPENSSL_CTX_DEFAULT_METHOD_STORE_INDEX,
+ &default_method_store_method);
}
static void *get_method_from_store(OPENSSL_CTX *libctx, void *store,
diff --git a/crypto/ex_data.c b/crypto/ex_data.c
index 5f83191bae..d9dd3d2aed 100644
--- a/crypto/ex_data.c
+++ b/crypto/ex_data.c
@@ -10,58 +10,33 @@
#include "internal/cryptlib_int.h"
#include "internal/thread_once.h"
-/*
- * Each structure type (sometimes called a class), that supports
- * exdata has a stack of callbacks for each instance.
- */
-struct ex_callback_st {
- long argl; /* Arbitrary long */
- void *argp; /* Arbitrary void * */
- CRYPTO_EX_new *new_func;
- CRYPTO_EX_free *free_func;
- CRYPTO_EX_dup *dup_func;
-};
-
-/*
- * The state for each class. This could just be a typedef, but
- * a structure allows future changes.
- */
-typedef struct ex_callbacks_st {
- STACK_OF(EX_CALLBACK) *meth;
-} EX_CALLBACKS;
-
-static EX_CALLBACKS ex_data[CRYPTO_EX_INDEX__COUNT];
-
-static CRYPTO_RWLOCK *ex_data_lock = NULL;
-static CRYPTO_ONCE ex_data_init = CRYPTO_ONCE_STATIC_INIT;
-
-DEFINE_RUN_ONCE_STATIC(do_ex_data_init)
+int do_ex_data_init(OPENSSL_CTX *ctx)
{
- if (!OPENSSL_init_crypto(0, NULL))
+ OSSL_EX_DATA_GLOBAL *global = openssl_ctx_get_ex_data_global(ctx);
+
+ if (global == NULL)
return 0;
- ex_data_lock = CRYPTO_THREAD_lock_new();
- return ex_data_lock != NULL;
+
+ global->ex_data_lock = CRYPTO_THREAD_lock_new();
+ return global->ex_data_lock != NULL;
}
/*
* Return the EX_CALLBACKS from the |ex_data| array that corresponds to
* a given class. On success, *holds the lock.*
*/
-static EX_CALLBACKS *get_and_lock(int class_index)
+static EX_CALLBACKS *get_and_lock(OPENSSL_CTX *ctx, int class_index)
{
EX_CALLBACKS *ip;
+ OSSL_EX_DATA_GLOBAL *global = NULL;
if (class_index < 0 || class_index >= CRYPTO_EX_INDEX__COUNT) {
CRYPTOerr(CRYPTO_F_GET_AND_LOCK, ERR_R_PASSED_INVALID_ARGUMENT);
return NULL;
}
- if (!RUN_ONCE(&ex_data_init, do_ex_data_init)) {
- CRYPTOerr(CRYPTO_F_GET_AND_LOCK, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
-
- if (ex_data_lock == NULL) {
+ global = openssl_ctx_get_ex_data_global(ctx);
+ if (global->ex_data_lock == NULL) {
/*
* This can happen in normal operation when using CRYPTO_mem_leaks().
* The CRYPTO_mem_leaks() function calls OPENSSL_cleanup() which cleans
@@ -74,8 +49,8 @@ static EX_CALLBACKS *get_and_lock(int class_index)
return NULL;
}
- ip = &ex_data[class_index];
- CRYPTO_THREAD_write_lock(ex_data_lock);
+ ip = &global->ex_data[class_index];
+ CRYPTO_THREAD_write_lock(global->ex_data_lock);
return ip;
}
@@ -90,19 +65,23 @@ static void cleanup_cb(EX_CALLBACK *funcs)
* called under potential race-conditions anyway (it's for program shutdown
* after all).
*/
-void crypto_cleanup_all_ex_data_int(void)
+void crypto_cleanup_all_ex_data_int(OPENSSL_CTX *ctx)
{
int i;
+ OSSL_EX_DATA_GLOBAL *global = openssl_ctx_get_ex_data_global(ctx);
+
+ if (global == NULL)
+ return;
for (i = 0; i < CRYPTO_EX_INDEX__COUNT; ++i) {
- EX_CALLBACKS *ip = &ex_data[i];
+ EX_CALLBACKS *ip = &global->ex_data[i];
sk_EX_CALLBACK_pop_free(ip->meth, cleanup_cb);
ip->meth = NULL;
}
- CRYPTO_THREAD_lock_free(ex_data_lock);
- ex_data_lock = NULL;
+ CRYPTO_THREAD_lock_free(global->ex_data_lock);
+ global->ex_data_lock = NULL;
}
@@ -127,12 +106,17 @@ static int dummy_dup(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from,
return 1;
}
-int CRYPTO_free_ex_index(int class_index, int idx)
+int crypto_free_ex_index_ex(OPENSSL_CTX *ctx, int class_index, int idx)
{
- EX_CALLBACKS *ip = get_and_lock(class_index);
+ EX_CALLBACKS *ip = get_and_lock(ctx, class_index);
EX_CALLBACK *a;
int toret = 0;
+ OSSL_EX_DATA_GLOBAL *global = openssl_ctx_get_ex_data_global(ctx);
+
+ if (global == NULL)
+ goto err;
+ ip = get_and_lock(ctx, class_index);
if (ip == NULL)
return 0;
if (idx < 0 || idx >= sk_EX_CALLBACK_num(ip->meth))
@@ -145,21 +129,32 @@ int CRYPTO_free_ex_index(int class_index, int idx)
a->free_func = dummy_free;
toret = 1;
err:
- CRYPTO_THREAD_unlock(ex_data_lock);
+ CRYPTO_THREAD_unlock(global->ex_data_lock);
return toret;
}
+int CRYPTO_free_ex_index(int class_index, int idx)
+{
+ return crypto_free_ex_index_ex(NULL, class_index, idx);
+}
+
/*
* Register a new index.
*/
-int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
- CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
- CRYPTO_EX_free *free_func)
+int crypto_get_ex_new_index_ex(OPENSSL_CTX *ctx, int class_index, long argl,
+ void *argp, CRYPTO_EX_new *new_func,
+ CRYPTO_EX_dup *dup_func,
+ CRYPTO_EX_free *free_func)
{
int toret = -1;
EX_CALLBACK *a;
- EX_CALLBACKS *ip = get_and_lock(class_index);
+ EX_CALLBACKS *ip;
+ OSSL_EX_DATA_GLOBAL *global = openssl_ctx_get_ex_data_global(ctx);
+ if (global == NULL)
+ goto err;
+
+ ip = get_and_lock(ctx, class_index);
if (ip == NULL)
return -1;
@@ -169,14 +164,14 @@ int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
* "app_data" routines use ex_data index zero. See RT 3710. */
if (ip->meth == NULL
|| !sk_EX_CALLBACK_push(ip->meth, NULL)) {
- CRYPTOerr(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX, ERR_R_MALLOC_FAILURE);
+ CRYPTOerr(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX_EX, ERR_R_MALLOC_FAILURE);
goto err;
}
}
a = (EX_CALLBACK *)OPENSSL_malloc(sizeof(*a));
if (a == NULL) {
- CRYPTOerr(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX, ERR_R_MALLOC_FAILURE);
+ CRYPTOerr(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX_EX, ERR_R_MALLOC_FAILURE);
goto err;
}
a->argl = argl;
@@ -186,7 +181,7 @@ int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
a->free_func = free_func;
if (!sk_EX_CALLBACK_push(ip->meth, NULL)) {
- CRYPTOerr(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX, ERR_R_MALLOC_FAILURE);
+ CRYPTOerr(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX_EX, ERR_R_MALLOC_FAILURE);
OPENSSL_free(a);
goto err;
}
@@ -194,10 +189,18 @@ int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
(void)sk_EX_CALLBACK_set(ip->meth, toret, a);
err:
- CRYPTO_THREAD_unlock(ex_data_lock);
+ CRYPTO_THREAD_unlock(global->ex_data_lock);
return toret;
}
+int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
+ CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
+ CRYPTO_EX_free *free_func)
+{
+ return crypto_get_ex_new_index_ex(NULL, class_index, argl, argp, new_func,
+ dup_func, free_func);
+}
+
/*
* Initialise a new CRYPTO_EX_DATA for use in a particular class - including
* calling new() callbacks for each index in the class used by this variable
@@ -205,17 +208,24 @@ int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
* in the lock, then using them outside the lock. Note this only applies
* to the global "ex_data" state (ie. class definitions), not 'ad' itself.
*/
-int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
+int crypto_new_ex_data_ex(OPENSSL_CTX *ctx, int class_index, void *obj,
+ CRYPTO_EX_DATA *ad)
{
int mx, i;
void *ptr;
EX_CALLBACK **storage = NULL;
EX_CALLBACK *stack[10];
- EX_CALLBACKS *ip = get_and_lock(class_index);
+ EX_CALLBACKS *ip;
+ OSSL_EX_DATA_GLOBAL *global = openssl_ctx_get_ex_data_global(ctx);
+
+ if (global == NULL)
+ return 0;
+ ip = get_and_lock(ctx, class_index);
if (ip == NULL)
return 0;
+ ad->ctx = ctx;
ad->sk = NULL;
mx = sk_EX_CALLBACK_num(ip->meth);
@@ -228,10 +238,10 @@ int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
for (i = 0; i < mx; i++)
storage[i] = sk_EX_CALLBACK_value(ip->meth, i);
}
- CRYPTO_THREAD_unlock(ex_data_lock);
+ CRYPTO_THREAD_unlock(global->ex_data_lock);
if (mx > 0 && storage == NULL) {
- CRYPTOerr(CRYPTO_F_CRYPTO_NEW_EX_DATA, ERR_R_MALLOC_FAILURE);
+ CRYPTOerr(CRYPTO_F_CRYPTO_NEW_EX_DATA_EX, ERR_R_MALLOC_FAILURE);
return 0;
}
for (i = 0; i < mx; i++) {
@@ -246,6 +256,11 @@ int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
return 1;
}
+int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
+{
+ return crypto_new_ex_data_ex(NULL, class_index, obj, ad);
+}
+
/*
* Duplicate a CRYPTO_EX_DATA variable - including calling dup() callbacks
* for each index in the class used by this variable
@@ -259,11 +274,16 @@ int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
EX_CALLBACK **storage = NULL;
EX_CALLBACKS *ip;
int toret = 0;
+ OSSL_EX_DATA_GLOBAL *global = openssl_ctx_get_ex_data_global(from->ctx);
+
+ if (global == NULL)
+ return 0;
+ to->ctx = from->ctx;
if (from->sk == NULL)
/* Nothing to copy over */
return 1;
- if ((ip = get_and_lock(class_index)) == NULL)
+ if ((ip = get_and_lock(from->ctx, class_index)) == NULL)
return 0;
mx = sk_EX_CALLBACK_num(ip->meth);
@@ -279,7 +299,7 @@ int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
for (i = 0; i < mx; i++)
storage[i] = sk_EX_CALLBACK_value(ip->meth, i);
}
- CRYPTO_THREAD_unlock(ex_data_lock);
+ CRYPTO_THREAD_unlock(global->ex_data_lock);
if (mx == 0)
return 1;
@@ -325,8 +345,12 @@ void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
EX_CALLBACK *f;
EX_CALLBACK *stack[10];
EX_CALLBACK **storage = NULL;
+ OSSL_EX_DATA_GLOBAL *global;
- if ((ip = get_and_lock(class_index)) == NULL)
+ if ((ip = get_and_lock(ad->ctx, class_index)) == NULL)
+ goto err;
+ global = openssl_ctx_get_ex_data_global(ad->ctx);
+ if (global == NULL)
goto err;
mx = sk_EX_CALLBACK_num(ip->meth);
@@ -339,15 +363,15 @@ void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
for (i = 0; i < mx; i++)
storage[i] = sk_EX_CALLBACK_value(ip->meth, i);
}
- CRYPTO_THREAD_unlock(ex_data_lock);
+ CRYPTO_THREAD_unlock(global->ex_data_lock);
for (i = 0; i < mx; i++) {
if (storage != NULL)
f = storage[i];
else {
- CRYPTO_THREAD_write_lock(ex_data_lock);
+ CRYPTO_THREAD_write_lock(global->ex_data_lock);
f = sk_EX_CALLBACK_value(ip->meth, i);
- CRYPTO_THREAD_unlock(ex_data_lock);
+ CRYPTO_THREAD_unlock(global->ex_data_lock);
}
if (f != NULL && f->free_func != NULL) {
ptr = CRYPTO_get_ex_data(ad, i);
@@ -360,6 +384,7 @@ void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
err:
sk_void_free(ad->sk);
ad->sk = NULL;
+ ad->ctx = NULL;
}
/*
@@ -372,6 +397,10 @@ int CRYPTO_alloc_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad,
EX_CALLBACK *f;
EX_CALLBACKS *ip;
void *curval;
+ OSSL_EX_DATA_GLOBAL *global = openssl_ctx_get_ex_data_global(ad->ctx);
+
+ if (global == NULL)
+ return 0;
curval = CRYPTO_get_ex_data(ad, idx);
@@ -379,11 +408,11 @@ int CRYPTO_alloc_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad,
if (curval != NULL)
return 1;
- ip = get_and_lock(class_index);
+ ip = get_and_lock(ad->ctx, class_index);
if (ip == NULL)
return 0;
f = sk_EX_CALLBACK_value(ip->meth, idx);
- CRYPTO_THREAD_unlock(ex_data_lock);
+ CRYPTO_THREAD_unlock(global->ex_data_lock);
/*
* This should end up calling CRYPTO_set_ex_data(), which allocates
@@ -432,3 +461,8 @@ void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx)
return NULL;
return sk_void_value(ad->sk, idx);
}
+
+OPENSSL_CTX *crypto_ex_data_get_openssl_ctx(const CRYPTO_EX_DATA *ad)
+{
+ return ad->ctx;
+}
diff --git a/crypto/init.c b/crypto/init.c
index 43fe1a6e1b..aa6f4b7125 100644
--- a/crypto/init.c
+++ b/crypto/init.c
@@ -526,7 +526,7 @@ void OPENSSL_cleanup(void)
* - rand_cleanup_int could call an ENGINE's RAND cleanup function so
* must be called before engine_cleanup_int()
* - ENGINEs use CRYPTO_EX_DATA and therefore, must be cleaned up
- * before the ex data handlers are wiped in CRYPTO_cleanup_all_ex_data().
+ * before the ex data handlers are wiped during default openssl_ctx deinit.
* - conf_modules_free_int() can end up in ENGINE code so must be called
* before engine_cleanup_int()
* - ENGINEs and additional EVP algorithms might use added OIDs names so
@@ -540,6 +540,7 @@ void OPENSSL_cleanup(void)
OSSL_TRACE(INIT, "OPENSSL_cleanup: conf_modules_free_int()\n");
conf_modules_free_int();
+
#ifndef OPENSSL_NO_ENGINE
OSSL_TRACE(INIT, "OPENSSL_cleanup: engine_cleanup_int()\n");
engine_cleanup_int();
@@ -547,8 +548,8 @@ void OPENSSL_cleanup(void)
OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_store_cleanup_int()\n");
ossl_store_cleanup_int();
- OSSL_TRACE(INIT, "OPENSSL_cleanup: crypto_cleanup_all_ex_data_int()\n");
- crypto_cleanup_all_ex_data_int();
+ OSSL_TRACE(INIT, "OPENSSL_cleanup: openssl_ctx_default_deinit()\n");
+ openssl_ctx_default_deinit();
OSSL_TRACE(INIT, "OPENSSL_cleanup: bio_cleanup()\n");
bio_cleanup();
diff --git a/crypto/property/defn_cache.c b/crypto/property/defn_cache.c
index df87c19f55..aec05c1ae3 100644
--- a/crypto/property/defn_cache.c
+++ b/crypto/property/defn_cache.c
@@ -29,8 +29,6 @@ typedef struct {
DEFINE_LHASH_OF(PROPERTY_DEFN_ELEM);
-static LHASH_OF(PROPERTY_DEFN_ELEM) *property_defns = NULL;
-
static unsigned long property_defn_hash(const PROPERTY_DEFN_ELEM *a)
{
return OPENSSL_LH_strhash(a->prop);
@@ -48,35 +46,52 @@ static void property_defn_free(PROPERTY_DEFN_ELEM *elem)
OPENSSL_free(elem);
}
-int ossl_prop_defn_init(void)
+static void property_defns_free(void *vproperty_defns)
{
- property_defns = lh_PROPERTY_DEFN_ELEM_new(&property_defn_hash,
- &property_defn_cmp);
- return property_defns != NULL;
-}
+ LHASH_OF(PROPERTY_DEFN_ELEM) *property_defns = vproperty_defns;
-void ossl_prop_defn_cleanup(void)
-{
if (property_defns != NULL) {
- lh_PROPERTY_DEFN_ELEM_doall(property_defns, &property_defn_free);
+ lh_PROPERTY_DEFN_ELEM_doall(property_defns,
+ &property_defn_free);
lh_PROPERTY_DEFN_ELEM_free(property_defns);
- property_defns = NULL;
}
}
-OSSL_PROPERTY_LIST *ossl_prop_defn_get(const char *prop)
+static void *property_defns_new(OPENSSL_CTX *ctx) {
+ return lh_PROPERTY_DEFN_ELEM_new(&property_defn_hash, &property_defn_cmp);
+}
+
+static const OPENSSL_CTX_METHOD property_defns_method = {
+ property_defns_new,
+ property_defns_free,
+};
+
+OSSL_PROPERTY_LIST *ossl_prop_defn_get(OPENSSL_CTX *ctx, const char *prop)
{
PROPERTY_DEFN_ELEM elem, *r;
+ LHASH_OF(PROPERTY_DEFN_ELEM) *property_defns;
+
+ property_defns = openssl_ctx_get_data(ctx, OPENSSL_CTX_PROPERTY_DEFN_INDEX,
+ &property_defns_method);
+ if (property_defns == NULL)
+ return NULL;
elem.prop = prop;
r = lh_PROPERTY_DEFN_ELEM_retrieve(property_defns, &elem);
return r != NULL ? r->defn : NULL;
}
-int ossl_prop_defn_set(const char *prop, OSSL_PROPERTY_LIST *pl)
+int ossl_prop_defn_set(OPENSSL_CTX *ctx, const char *prop,
+ OSSL_PROPERTY_LIST *pl)
{
PROPERTY_DEFN_ELEM elem, *old, *p = NULL;
size_t l