Instead of global data store it in an OPENSSL_CTX
Various core and property related code files used global data. We should store all of that in an OPENSSL_CTX instead. Reviewed-by: Richard Levitte <levitte@openssl.org> (Merged from https://github.com/openssl/openssl/pull/8857)
This commit is contained in:
parent
b8fe36fee0
commit
1aedc35fd6
21 changed files with 510 additions and 317 deletions
159
crypto/context.c
159
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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
164
crypto/ex_data.c
164
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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 len;
|
||||
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 0;
|
||||
|
||||
if (prop == NULL)
|
||||
return 1;
|
||||
|
|
|
@ -47,6 +47,7 @@ typedef struct {
|
|||
} ALGORITHM;
|
||||
|
||||
struct ossl_method_store_st {
|
||||
OPENSSL_CTX *ctx;
|
||||
size_t nelem;
|
||||
SPARSE_ARRAY_OF(ALGORITHM) *algs;
|
||||
OSSL_PROPERTY_LIST *global_properties;
|
||||
|
@ -82,29 +83,10 @@ int ossl_property_unlock(OSSL_METHOD_STORE *p)
|
|||
return p != 0 ? CRYPTO_THREAD_unlock(p->lock) : 0;
|
||||
}
|
||||
|
||||
int ossl_method_store_init(void)
|
||||
static openssl_ctx_run_once_fn do_method_store_init;
|
||||
int do_method_store_init(OPENSSL_CTX *ctx)
|
||||
{
|
||||
if (ossl_property_string_init()
|
||||
&& ossl_prop_defn_init()
|
||||
&& ossl_property_parse_init())
|
||||
return 1;
|
||||
|
||||
ossl_method_store_cleanup();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ossl_method_store_cleanup(void)
|
||||
{
|
||||
ossl_property_string_cleanup();
|
||||
ossl_prop_defn_cleanup();
|
||||
}
|
||||
|
||||
static CRYPTO_ONCE method_store_init_flag = CRYPTO_ONCE_STATIC_INIT;
|
||||
DEFINE_RUN_ONCE_STATIC(do_method_store_init)
|
||||
{
|
||||
return OPENSSL_init_crypto(0, NULL)
|
||||
&& ossl_method_store_init()
|
||||
&& OPENSSL_atexit(&ossl_method_store_cleanup);
|
||||
return ossl_property_parse_init(ctx);
|
||||
}
|
||||
|
||||
static unsigned long query_hash(const QUERY *a)
|
||||
|
@ -141,15 +123,22 @@ static void alg_cleanup(ossl_uintmax_t idx, ALGORITHM *a)
|
|||
}
|
||||
}
|
||||
|
||||
OSSL_METHOD_STORE *ossl_method_store_new(void)
|
||||
/*
|
||||
* The OPENSSL_CTX param here allows access to underlying property data needed
|
||||
* for computation
|
||||
*/
|
||||
OSSL_METHOD_STORE *ossl_method_store_new(OPENSSL_CTX *ctx)
|
||||
{
|
||||
OSSL_METHOD_STORE *res;
|
||||
|
||||
if (!RUN_ONCE(&method_store_init_flag, do_method_store_init))
|
||||
return 0;
|
||||
if (!openssl_ctx_run_once(ctx,
|
||||
OPENSSL_CTX_METHOD_STORE_RUN_ONCE_INDEX,
|
||||
do_method_store_init))
|
||||
return NULL;
|
||||
|
||||
res = OPENSSL_zalloc(sizeof(*res));
|
||||
if (res != NULL) {
|
||||
res->ctx = ctx;
|
||||
if ((res->algs = ossl_sa_ALGORITHM_new()) == NULL) {
|
||||
OPENSSL_free(res);
|
||||
return NULL;
|
||||
|
@ -212,10 +201,11 @@ int ossl_method_store_add(OSSL_METHOD_STORE *store,
|
|||
*/
|
||||
ossl_property_write_lock(store);
|
||||
ossl_method_cache_flush(store, nid);
|
||||
if ((impl->properties = ossl_prop_defn_get(properties)) == NULL) {
|
||||
if ((impl->properties = ossl_parse_property(properties)) == NULL)
|
||||
if ((impl->properties = ossl_prop_defn_get(store->ctx, properties)) == NULL) {
|
||||
impl->properties = ossl_parse_property(store->ctx, properties);
|
||||
if (impl->properties == NULL)
|
||||
goto err;
|
||||
ossl_prop_defn_set(properties, impl->properties);
|
||||
ossl_prop_defn_set(store->ctx, properties, impl->properties);
|
||||
}
|
||||
|
||||
alg = ossl_method_store_retrieve(store, nid);
|
||||
|
@ -310,7 +300,7 @@ int ossl_method_store_fetch(OSSL_METHOD_STORE *store, int nid,
|
|||
}
|
||||
goto fin;
|
||||
}
|
||||
pq = ossl_parse_query(prop_query);
|
||||
pq = ossl_parse_query(store->ctx, prop_query);
|
||||
if (pq == NULL)
|
||||
goto fin;
|
||||
if (store->global_properties != NULL) {
|
||||
|
@ -350,7 +340,7 @@ int ossl_method_store_set_global_properties(OSSL_METHOD_STORE *store,
|
|||
ossl_property_unlock(store);
|
||||
return 1;
|
||||
}
|
||||
store->global_properties = ossl_parse_query(prop_query);
|
||||
store->global_properties = ossl_parse_query(store->ctx, prop_query);
|
||||
ret = store->global_properties != NULL;
|
||||
ossl_property_unlock(store);
|
||||
return ret;
|
||||
|
|
|
@ -14,18 +14,14 @@
|
|||
typedef struct ossl_property_list_st OSSL_PROPERTY_LIST;
|
||||
typedef int OSSL_PROPERTY_IDX;
|
||||
|
||||
/* Initialisation and finalisation for subsystem */
|
||||
int ossl_method_store_init(void);
|
||||
void ossl_method_store_cleanup(void);
|
||||
|
||||
/* Property string functions */
|
||||
OSSL_PROPERTY_IDX ossl_property_name(const char *s, int create);
|
||||
OSSL_PROPERTY_IDX ossl_property_value(const char *s, int create);
|
||||
int ossl_property_string_init(void);
|
||||
void ossl_property_string_cleanup(void);
|
||||
OSSL_PROPERTY_IDX ossl_property_name(OPENSSL_CTX *ctx, const char *s,
|
||||
int create);
|
||||
OSSL_PROPERTY_IDX ossl_property_value(OPENSSL_CTX *ctx, const char *s,
|
||||
int create);
|
||||
|
||||
/* Property list functions */
|
||||
int ossl_property_parse_init(void);
|
||||
int ossl_property_parse_init(OPENSSL_CTX *ctx);
|
||||
void ossl_property_free(OSSL_PROPERTY_LIST *p);
|
||||
int ossl_property_match(const OSSL_PROPERTY_LIST *query,
|
||||
const OSSL_PROPERTY_LIST *defn);
|
||||
|
@ -33,16 +29,15 @@ OSSL_PROPERTY_LIST *ossl_property_merge(const OSSL_PROPERTY_LIST *a,
|
|||
const OSSL_PROPERTY_LIST *b);
|
||||
|
||||
/* Property definition functions */
|
||||
OSSL_PROPERTY_LIST *ossl_parse_property(const char *s);
|
||||
OSSL_PROPERTY_LIST *ossl_parse_property(OPENSSL_CTX *ctx, const char *s);
|
||||
|
||||
/* Property query functions */
|
||||
OSSL_PROPERTY_LIST *ossl_parse_query(const char *s);
|
||||
OSSL_PROPERTY_LIST *ossl_parse_query(OPENSSL_CTX *ctx, const char *s);
|
||||
|
||||
/* Property definition cache functions */
|
||||
int ossl_prop_defn_init(void);
|
||||
void ossl_prop_defn_cleanup(void);
|
||||
OSSL_PROPERTY_LIST *ossl_prop_defn_get(const char *prop);
|
||||
int ossl_prop_defn_set(const char *prop, OSSL_PROPERTY_LIST *pl);
|
||||
OSSL_PROPERTY_LIST *ossl_prop_defn_get(OPENSSL_CTX *ctx, const char *prop);
|
||||
int ossl_prop_defn_set(OPENSSL_CTX *ctx, const char *prop,
|
||||
OSSL_PROPERTY_LIST *pl);
|
||||
|
||||
/* Property cache lock / unlock */
|
||||
int ossl_property_write_lock(OSSL_METHOD_STORE *);
|
||||
|
|
|
@ -78,7 +78,8 @@ static int match(const char *t[], const char m[], size_t m_len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int parse_name(const char *t[], int create, OSSL_PROPERTY_IDX *idx)
|
||||
static int parse_name(OPENSSL_CTX *ctx, const char *t[], int create,
|
||||
OSSL_PROPERTY_IDX *idx)
|
||||
{
|
||||
char name[100];
|
||||
int err = 0;
|
||||
|
@ -109,7 +110,7 @@ static int parse_name(const char *t[], int create, OSSL_PROPERTY_IDX *idx)
|
|||
name[i] = '\0';
|
||||
*t = skip_space(s);
|
||||
if (!err) {
|
||||
*idx = ossl_property_name(name, user_name && create);
|
||||
*idx = ossl_property_name(ctx, name, user_name && create);
|
||||
return 1;
|
||||
}
|
||||
PROPerr(PROP_F_PARSE_NAME, PROP_R_NAME_TOO_LONG);
|
||||
|
@ -180,8 +181,8 @@ static int parse_oct(const char *t[], PROPERTY_DEFINITION *res)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int parse_string(const char *t[], char delim, PROPERTY_DEFINITION *res,
|
||||
const int create)
|
||||
static int parse_string(OPENSSL_CTX *ctx, const char *t[], char delim,
|
||||
PROPERTY_DEFINITION *res, const int create)
|
||||
{
|
||||
char v[1000];
|
||||
const char *s = *t;
|
||||
|
@ -205,13 +206,13 @@ static int parse_string(const char *t[], char delim, PROPERTY_DEFINITION *res,
|
|||
if (err)
|
||||
PROPerr(PROP_F_PARSE_STRING, PROP_R_STRING_TOO_LONG);
|
||||
else
|
||||
res->v.str_val = ossl_property_value(v, create);
|
||||
res->v.str_val = ossl_property_value(ctx, v, create);
|
||||
res->type = PROPERTY_TYPE_STRING;
|
||||
return !err;
|
||||
}
|
||||
|
||||
static int parse_unquoted(const char *t[], PROPERTY_DEFINITION *res,
|
||||
const int create)
|
||||
static int parse_unquoted(OPENSSL_CTX *ctx, const char *t[],
|
||||
PROPERTY_DEFINITION *res, const int create)
|
||||
{
|
||||
char v[1000];
|
||||
const char *s = *t;
|
||||
|
@ -236,19 +237,20 @@ static int parse_unquoted(const char *t[], PROPERTY_DEFINITION *res,
|
|||
if (err)
|
||||
PROPerr(PROP_F_PARSE_UNQUOTED, PROP_R_STRING_TOO_LONG);
|
||||
else
|
||||
res->v.str_val = ossl_property_value(v, create);
|
||||
res->v.str_val = ossl_property_value(ctx, v, create);
|
||||
res->type = PROPERTY_TYPE_STRING;
|
||||
return !err;
|
||||
}
|
||||
|
||||
static int parse_value(const char *t[], PROPERTY_DEFINITION *res, int create)
|
||||
static int parse_value(OPENSSL_CTX *ctx, const char *t[],
|
||||
PROPERTY_DEFINITION *res, int create)
|
||||
{
|
||||
const char *s = *t;
|
||||
int r = 0;
|
||||
|
||||
if (*s == '"' || *s == '\'') {
|
||||
s++;
|
||||
r = parse_string(&s, s[-1], res, create);
|
||||
r = parse_string(ctx, &s, s[-1], res, create);
|
||||
} else if (*s == '+') {
|
||||
s++;
|
||||
r = parse_number(&s, res);
|
||||
|
@ -265,7 +267,7 @@ static int parse_value(const char *t[], PROPERTY_DEFINITION *res, int create)
|
|||
} else if (ossl_isdigit(*s)) {
|
||||
return parse_number(t, res);
|
||||
} else if (ossl_isalpha(*s))
|
||||
return parse_unquoted(t, res, create);
|
||||
return parse_unquoted(ctx, t, res, create);
|
||||
if (r)
|
||||
*t = s;
|
||||
return r;
|
||||
|
@ -312,7 +314,7 @@ static OSSL_PROPERTY_LIST *stack_to_property_list(STACK_OF(PROPERTY_DEFINITION)
|
|||
return r;
|
||||
}
|
||||
|
||||
OSSL_PROPERTY_LIST *ossl_parse_property(const char *defn)
|
||||
OSSL_PROPERTY_LIST *ossl_parse_property(OPENSSL_CTX *ctx, const char *defn)
|
||||
{
|
||||
PROPERTY_DEFINITION *prop = NULL;
|
||||
OSSL_PROPERTY_LIST *res = NULL;
|
||||
|
@ -330,7 +332,7 @@ OSSL_PROPERTY_LIST *ossl_parse_property(const char *defn)
|
|||
if (prop == NULL)
|
||||
goto err;
|
||||
memset(&prop->v, 0, sizeof(prop->v));
|
||||
if (!parse_name(&s, 1, &prop->name_idx))
|
||||
if (!parse_name(ctx, &s, 1, &prop->name_idx))
|
||||
goto err;
|
||||
prop->oper = PROPERTY_OPER_EQ;
|
||||
if (prop->name_idx == 0) {
|
||||
|
@ -338,7 +340,7 @@ OSSL_PROPERTY_LIST *ossl_parse_property(const char *defn)
|
|||
goto err;
|
||||
}
|
||||
if (match_ch(&s, '=')) {
|
||||
if (!parse_value(&s, prop, 1)) {
|
||||
if (!parse_value(ctx, &s, prop, 1)) {
|
||||
PROPerr(PROP_F_OSSL_PARSE_PROPERTY, PROP_R_NO_VALUE);
|
||||
goto err;
|
||||
}
|
||||
|
@ -365,7 +367,7 @@ err:
|
|||
return res;
|
||||
}
|
||||
|
||||
OSSL_PROPERTY_LIST *ossl_parse_query(const char *s)
|
||||
OSSL_PROPERTY_LIST *ossl_parse_query(OPENSSL_CTX *ctx, const char *s)
|
||||
{
|
||||
STACK_OF(PROPERTY_DEFINITION) *sk;
|
||||
OSSL_PROPERTY_LIST *res = NULL;
|
||||
|
@ -385,11 +387,11 @@ OSSL_PROPERTY_LIST *ossl_parse_query(const char *s)
|
|||
|
||||
if (match_ch(&s, '-')) {
|
||||
prop->oper = PROPERTY_OVERRIDE;
|
||||
if (!parse_name(&s, 0, &prop->name_idx))
|
||||
if (!parse_name(ctx, &s, 0, &prop->name_idx))
|
||||
goto err;
|
||||
goto skip_value;
|
||||
}
|
||||
if (!parse_name(&s, 0, &prop->name_idx))
|
||||
if (!parse_name(ctx, &s, 0, &prop->name_idx))
|
||||
goto err;
|
||||
|
||||
if (match_ch(&s, '=')) {
|
||||
|
@ -403,7 +405,7 @@ OSSL_PROPERTY_LIST *ossl_parse_query(const char *s)
|
|||
prop->v.str_val = ossl_property_true;
|
||||
goto skip_value;
|
||||
}
|
||||
if (!parse_value(&s, prop, 0))
|
||||
if (!parse_value(ctx, &s, prop, 0))
|
||||
prop->type = PROPERTY_TYPE_VALUE_UNDEFINED;
|
||||
|
||||
skip_value:
|
||||
|
@ -519,7 +521,7 @@ OSSL_PROPERTY_LIST *ossl_property_merge(const OSSL_PROPERTY_LIST *a,
|
|||
return r;
|
||||
}
|
||||
|
||||
int ossl_property_parse_init(void)
|
||||
int ossl_property_parse_init(OPENSSL_CTX *ctx)
|
||||
{
|
||||
static const char *const predefined_names[] = {
|
||||
"default", /* Being provided by the default built-in provider */
|
||||
|
@ -532,12 +534,12 @@ int ossl_property_parse_init(void)
|
|||
size_t i;
|
||||
|
||||
for (i = 0; i < OSSL_NELEM(predefined_names); i++)
|
||||
if (ossl_property_name(predefined_names[i], 1) == 0)
|
||||
if (ossl_property_name(ctx, predefined_names[i], 1) == 0)
|
||||
goto err;
|
||||
|
||||
/* Pre-populate the two Boolean values */
|
||||
if ((ossl_property_true = ossl_property_value("yes", 1)) == 0
|
||||
|| (ossl_property_false = ossl_property_value("no", 1)) == 0)
|
||||
if ((ossl_property_true = ossl_property_value(ctx, "yes", 1)) == 0
|
||||
|| (ossl_property_false = ossl_property_value(ctx, "no", 1)) == 0)
|
||||
goto err;
|
||||
|
||||
return 1;
|
||||
|
|
|
@ -34,10 +34,12 @@ typedef struct {
|
|||
DEFINE_LHASH_OF(PROPERTY_STRING);
|
||||
typedef LHASH_OF(PROPERTY_STRING) PROP_TABLE;
|
||||
|
||||
static PROP_TABLE *prop_names;
|
||||
static PROP_TABLE *prop_values;
|
||||
static OSSL_PROPERTY_IDX prop_name_idx = 0;
|
||||
static OSSL_PROPERTY_IDX prop_value_idx = 0;
|
||||
typedef struct {
|
||||
PROP_TABLE *prop_names;
|
||||
PROP_TABLE *prop_values;
|
||||
OSSL_PROPERTY_IDX prop_name_idx;
|
||||
OSSL_PROPERTY_IDX prop_value_idx;
|
||||
} PROPERTY_STRING_DATA;
|
||||
|
||||
static unsigned long property_hash(const PROPERTY_STRING *a)
|
||||
{
|
||||
|
@ -65,6 +67,48 @@ static void property_table_free(PROP_TABLE **pt)
|
|||
}
|
||||
}
|
||||
|
||||
static void property_string_data_free(void *vpropdata)
|
||||
{
|
||||
PROPERTY_STRING_DATA *propdata = vpropdata;
|
||||
|
||||
if (propdata == NULL)
|
||||
return;
|
||||
|
||||
property_table_free(&propdata->prop_names);
|
||||
property_table_free(&propdata->prop_values);
|
||||
propdata->prop_name_idx = propdata->prop_value_idx = 0;
|
||||
|
||||
OPENSSL_free(propdata);
|
||||
}
|
||||
|
||||
static void *property_string_data_new(OPENSSL_CTX *ctx) {
|
||||
PROPERTY_STRING_DATA *propdata = OPENSSL_zalloc(sizeof(*propdata));
|
||||
|
||||
if (propdata == NULL)
|
||||
return NULL;
|
||||
|
||||
propdata->prop_names = lh_PROPERTY_STRING_new(&property_hash,
|
||||
&property_cmp);
|
||||
if (propdata->prop_names == NULL)
|
||||
goto err;
|
||||
|
||||
propdata->prop_values = lh_PROPERTY_STRING_new(&property_hash,
|
||||
&property_cmp);
|
||||
if (propdata->prop_values == NULL)
|
||||
goto err;
|
||||
|
||||
return propdata;
|
||||
|
||||
err:
|
||||
property_string_data_free(propdata);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const OPENSSL_CTX_METHOD property_string_data_method = {
|
||||
property_string_data_new,
|
||||
property_string_data_free,
|
||||
};
|
||||
|
||||
static PROPERTY_STRING *new_property_string(const char *s,
|
||||
OSSL_PROPERTY_IDX *pidx)
|
||||
{
|
||||
|
@ -103,35 +147,30 @@ static OSSL_PROPERTY_IDX ossl_property_string(PROP_TABLE *t,
|
|||
return ps != NULL ? ps->idx : 0;
|
||||
}
|
||||
|
||||
OSSL_PROPERTY_IDX ossl_property_name(const char *s, int create)
|
||||
OSSL_PROPERTY_IDX ossl_property_name(OPENSSL_CTX *ctx, const char *s,
|
||||
int create)
|
||||
{
|
||||
return ossl_property_string(prop_names, create ? &prop_name_idx : NULL, s);
|
||||
}
|
||||
PROPERTY_STRING_DATA *propdata
|
||||
= openssl_ctx_get_data(ctx, OPENSSL_CTX_PROPERTY_STRING_INDEX,
|
||||
&property_string_data_method);
|
||||
|
||||
OSSL_PROPERTY_IDX ossl_property_value(const char *s, int create)
|
||||
{
|
||||
return ossl_property_string(prop_values, create ? &prop_value_idx : NULL, s);
|
||||
}
|
||||
|
||||
int ossl_property_string_init(void)
|
||||
{
|
||||
prop_names = lh_PROPERTY_STRING_new(&property_hash, &property_cmp);
|
||||
if (prop_names == NULL)
|
||||
if (propdata == NULL)
|
||||
return 0;
|
||||
|
||||
prop_values = lh_PROPERTY_STRING_new(&property_hash, &property_cmp);
|
||||
if (prop_values == NULL)
|
||||
goto err;
|
||||
return 1;
|
||||
|
||||
err:
|
||||
ossl_property_string_cleanup();
|
||||
return 0;
|
||||
return ossl_property_string(propdata->prop_names,
|
||||
create ? &propdata->prop_name_idx : NULL,
|
||||
s);
|
||||
}
|
||||
|
||||
void ossl_property_string_cleanup(void)
|
||||
OSSL_PROPERTY_IDX ossl_property_value(OPENSSL_CTX *ctx, const char *s,
|
||||
int create)
|
||||
{
|
||||
property_table_free(&prop_names);
|
||||
property_table_free(&prop_values);
|
||||
prop_name_idx = prop_value_idx = 0;
|
||||
PROPERTY_STRING_DATA *propdata
|
||||
= openssl_ctx_get_data(ctx, OPENSSL_CTX_PROPERTY_STRING_INDEX,
|
||||
&property_string_data_method);
|
||||
|
||||
if (propdata == NULL)
|
||||
return 0;
|
||||
return ossl_property_string(propdata->prop_values,
|
||||
create ? &propdata->prop_value_idx : NULL,
|
||||
s);
|
||||
}
|
||||
|
|
|
@ -79,7 +79,6 @@ struct provider_store_st {
|
|||
CRYPTO_RWLOCK *lock;
|
||||
unsigned int use_fallbacks:1;
|
||||
};
|
||||
static int provider_store_index = -1;
|
||||
|
||||
static void provider_store_free(void *vstore)
|
||||
{
|
||||
|
@ -92,7 +91,7 @@ static void provider_store_free(void *vstore)
|
|||
OPENSSL_free(store);
|
||||
}
|
||||
|
||||
static void *provider_store_new(void)
|
||||
static void *provider_store_new(OPENSSL_CTX *ctx)
|
||||
{
|
||||
struct provider_store_st *store = OPENSSL_zalloc(sizeof(*store));
|
||||
const struct predefined_providers_st *p = NULL;
|
||||
|
@ -134,23 +133,12 @@ static const OPENSSL_CTX_METHOD provider_store_method = {
|
|||
provider_store_free,
|
||||
};
|
||||
|
||||
static CRYPTO_ONCE provider_store_init_flag = CRYPTO_ONCE_STATIC_INIT;
|
||||
DEFINE_RUN_ONCE_STATIC(do_provider_store_init)
|
||||
{
|
||||
return OPENSSL_init_crypto(0, NULL)
|
||||
&& (provider_store_index =
|
||||
openssl_ctx_new_index(&provider_store_method)) != -1;
|
||||
}
|
||||
|
||||
|
||||
static struct provider_store_st *get_provider_store(OPENSSL_CTX *libctx)
|
||||
{
|
||||
struct provider_store_st *store = NULL;
|
||||
|
||||
if (!RUN_ONCE(&provider_store_init_flag, do_provider_store_init))
|
||||
return NULL;
|
||||
|
||||
store = openssl_ctx_get_data(libctx, provider_store_index);
|
||||
store = openssl_ctx_get_data(libctx, OPENSSL_CTX_PROVIDER_STORE_INDEX,
|
||||
&provider_store_method);
|
||||
if (store == NULL)
|
||||
CRYPTOerr(CRYPTO_F_GET_PROVIDER_STORE, ERR_R_INTERNAL_ERROR);
|
||||
return store;
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
*/
|
||||
typedef struct ossl_method_construct_method_st {
|
||||
/* Create store */
|
||||
void *(*alloc_tmp_store)(void);
|
||||
void *(*alloc_tmp_store)(OPENSSL_CTX *ctx);
|
||||
/* Remove a store */
|
||||
void (*dealloc_tmp_store)(void *store);
|
||||
/* Get an already existing method from a store */
|
||||
|
|
|
@ -88,7 +88,8 @@ DEFINE_LHASH_OF(MEM);
|
|||
void OPENSSL_cpuid_setup(void);
|
||||
extern unsigned int OPENSSL_ia32cap_P[];
|
||||
void OPENSSL_showfatal(const char *fmta, ...);
|
||||
void crypto_cleanup_all_ex_data_int(void);
|
||||
int do_ex_data_init(OPENSSL_CTX *ctx);
|
||||
void crypto_cleanup_all_ex_data_int(OPENSSL_CTX *ctx);
|
||||
int openssl_init_fork_handlers(void);
|
||||
|
||||
char *ossl_safe_getenv(const char *name);
|
||||
|
@ -105,21 +106,72 @@ uint32_t OPENSSL_rdtsc(void);
|
|||
size_t OPENSSL_instrument_bus(unsigned int *, size_t);
|
||||
size_t OPENSSL_instrument_bus2(unsigned int *, size_t, size_t);
|
||||
|
||||
# define MAX_OPENSSL_CTX_RUN_ONCE 1
|
||||
/* ex_data structures */
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
typedef struct ossl_ex_data_global_st {
|
||||
CRYPTO_RWLOCK *ex_data_lock;
|
||||
EX_CALLBACKS ex_data[CRYPTO_EX_INDEX__COUNT];
|
||||
} OSSL_EX_DATA_GLOBAL;
|
||||
|
||||
|
||||
/* OPENSSL_CTX */
|
||||
|
||||
# define OPENSSL_CTX_PROVIDER_STORE_RUN_ONCE_INDEX 0
|
||||
# define OPENSSL_CTX_DEFAULT_METHOD_STORE_RUN_ONCE_INDEX 1
|
||||
# define OPENSSL_CTX_METHOD_STORE_RUN_ONCE_INDEX 2
|
||||
# define OPENSSL_CTX_MAX_RUN_ONCE 3
|
||||
|
||||
# define OPENSSL_CTX_DEFAULT_METHOD_STORE_INDEX 0
|
||||
# define OPENSSL_CTX_PROVIDER_STORE_INDEX 1
|
||||
# define OPENSSL_CTX_PROPERTY_DEFN_INDEX 2
|
||||
# define OPENSSL_CTX_PROPERTY_STRING_INDEX 3
|
||||
# define OPENSSL_CTX_MAX_INDEXES 4
|
||||
|
||||
typedef struct openssl_ctx_method {
|
||||
void *(*new_func)(void);
|
||||
void *(*new_func)(OPENSSL_CTX *ctx);
|
||||
void (*free_func)(void *);
|
||||
} OPENSSL_CTX_METHOD;
|
||||
/* For each type of data to store in the context, an index must be created */
|
||||
int openssl_ctx_new_index(const OPENSSL_CTX_METHOD *);
|
||||
/* Functions to retrieve pointers to data by index */
|
||||
void *openssl_ctx_get_data(OPENSSL_CTX *, int /* index */);
|
||||
|
||||
typedef int (*openssl_ctx_run_once_fn)(OPENSSL_CTX *ctx);
|
||||
typedef void (*openssl_ctx_onfree_fn)(OPENSSL_CTX *ctx);
|
||||
/* Functions to retrieve pointers to data by index */
|
||||
void *openssl_ctx_get_data(OPENSSL_CTX *, int /* index */,
|
||||
const OPENSSL_CTX_METHOD * ctx);
|
||||
|
||||
void openssl_ctx_default_deinit(void);
|
||||
OSSL_EX_DATA_GLOBAL *openssl_ctx_get_ex_data_global(OPENSSL_CTX *ctx);
|
||||
typedef int (openssl_ctx_run_once_fn)(OPENSSL_CTX *ctx);
|
||||
typedef void (openssl_ctx_onfree_fn)(OPENSSL_CTX *ctx);
|
||||
|
||||
int openssl_ctx_run_once(OPENSSL_CTX *ctx, unsigned int idx,
|
||||
openssl_ctx_run_once_fn run_once_fn);
|
||||
int openssl_ctx_onfree(OPENSSL_CTX *ctx, openssl_ctx_onfree_fn onfreefn);
|
||||
|
||||
OPENSSL_CTX *crypto_ex_data_get_openssl_ctx(const CRYPTO_EX_DATA *ad);
|
||||
int crypto_new_ex_data_ex(OPENSSL_CTX *ctx, int class_index, void *obj,
|
||||
CRYPTO_EX_DATA *ad);
|
||||
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 crypto_free_ex_index_ex(OPENSSL_CTX *ctx, int class_index, int idx);
|
||||
#endif
|
||||
|
|
|
@ -11,10 +11,12 @@
|
|||
#ifndef HEADER_PROPERTY_H
|
||||
# define HEADER_PROPERTY_H
|
||||
|
||||
#include "internal/cryptlib.h"
|
||||
|
||||
typedef struct ossl_method_store_st OSSL_METHOD_STORE;
|
||||
|
||||
/* Implementation store functions */
|
||||
OSSL_METHOD_STORE *ossl_method_store_new(void);
|
||||
OSSL_METHOD_STORE *ossl_method_store_new(OPENSSL_CTX *ctx);
|
||||
void ossl_method_store_free(OSSL_METHOD_STORE *store);
|
||||
int ossl_method_store_add(OSSL_METHOD_STORE *store, int nid,
|
||||
const char *properties, void *implementation,
|
||||
|
@ -31,5 +33,4 @@ int ossl_method_store_cache_get(OSSL_METHOD_STORE *store, int nid,
|
|||
const char *prop_query, void **result);
|
||||
int ossl_method_store_cache_set(OSSL_METHOD_STORE *store, int nid,
|
||||
const char *prop_query, void *result);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -84,6 +84,7 @@ int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock);
|
|||
# define CRYPTO_MEM_CHECK_DISABLE 0x3 /* Control only */
|
||||
|
||||
struct crypto_ex_data_st {
|
||||
OPENSSL_CTX *ctx;
|
||||
STACK_OF(void) *sk;
|
||||
};
|
||||
DEFINE_STACK_OF(void)
|
||||
|
|
|
@ -27,8 +27,10 @@ int ERR_load_CRYPTO_strings(void);
|
|||
# define CRYPTO_F_CRYPTO_DUP_EX_DATA 110
|
||||
# define CRYPTO_F_CRYPTO_FREE_EX_DATA 111
|
||||
# define CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX 100
|
||||
# define CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX_EX 141
|
||||
# define CRYPTO_F_CRYPTO_MEMDUP 115
|
||||
# define CRYPTO_F_CRYPTO_NEW_EX_DATA 112
|
||||
# define CRYPTO_F_CRYPTO_NEW_EX_DATA_EX 142
|
||||
# define CRYPTO_F_CRYPTO_OCB128_COPY_CTX 121
|
||||
# define CRYPTO_F_CRYPTO_OCB128_INIT 122
|
||||
# define CRYPTO_F_CRYPTO_SET_EX_DATA 102
|
||||
|
@ -43,8 +45,8 @@ int ERR_load_CRYPTO_strings(void);
|
|||
# define CRYPTO_F_OPENSSL_LH_NEW 126
|
||||
# define CRYPTO_F_OPENSSL_SK_DEEP_COPY 127
|
||||
# define CRYPTO_F_OPENSSL_SK_DUP 128
|
||||
# define CRYPTO_F_OSSL_PROVIDER_ADD_BUILTIN 132
|
||||
# define CRYPTO_F_OSSL_PROVIDER_ACTIVATE 130
|
||||
# define CRYPTO_F_OSSL_PROVIDER_ADD_BUILTIN 132
|
||||
# define CRYPTO_F_OSSL_PROVIDER_ADD_PARAMETER 139
|
||||
# define CRYPTO_F_OSSL_PROVIDER_NEW 131
|
||||
# define CRYPTO_F_OSSL_PROVIDER_SET_MODULE_PATH 140
|
||||
|
|
|
@ -503,7 +503,7 @@ IF[{- !$disabled{tests} -}]
|
|||
DEPEND[wpackettest]=../libcrypto ../libssl.a libtestutil.a
|
||||
|
||||
SOURCE[property_test]=property_test.c
|
||||
INCLUDE[property_test]=../include ../apps/include
|
||||
INCLUDE[property_test]=.. ../include ../apps/include
|
||||
DEPEND[property_test]=../libcrypto.a libtestutil.a
|
||||
|
||||
SOURCE[ctype_internal_test]=ctype_internal_test.c
|
||||
|
|
|
@ -22,15 +22,12 @@
|
|||
* BEGIN EXAMPLE
|
||||
*/
|
||||
|
||||
/* The index will always be entirely global, and dynamically allocated */
|
||||
static int foo_index = -1;
|
||||
|
||||
typedef struct foo_st {
|
||||
int i;
|
||||
void *data;
|
||||
} FOO;
|
||||
|
||||
static void *foo_new(void)
|
||||
static void *foo_new(OPENSSL_CTX *ctx)
|
||||
{
|
||||
FOO *ptr = OPENSSL_zalloc(sizeof(*ptr));
|
||||
if (ptr != NULL)
|
||||
|
@ -46,14 +43,6 @@ static const OPENSSL_CTX_METHOD foo_method = {
|
|||
foo_free
|
||||
};
|
||||
|
||||
static int foo_init(void)
|
||||
{
|
||||
if (foo_index == -1)
|
||||
foo_index = openssl_ctx_new_index(&foo_method);
|
||||
|
||||
return foo_index != -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* END EXAMPLE
|
||||
* ======================================================================
|
||||
|
@ -63,9 +52,7 @@ static int test_context(OPENSSL_CTX *ctx)
|
|||
{
|
||||
FOO *data = NULL;
|
||||
|
||||
return
|
||||
TEST_true(foo_init())
|
||||
&& TEST_ptr(data = openssl_ctx_get_data(ctx, foo_index))
|
||||
return TEST_ptr(data = openssl_ctx_get_data(ctx, 0, &foo_method))
|
||||
/* OPENSSL_zalloc in foo_new() initialized it to zero */
|
||||
&& TEST_int_eq(data->i, 42);
|
||||
}
|
||||
|
@ -74,8 +61,7 @@ static int test_app_context(void)
|
|||
{
|
||||
OPENSSL_CTX *ctx = NULL;
|
||||
int result =
|
||||
TEST_true(foo_init())
|
||||
&& TEST_ptr(ctx = OPENSSL_CTX_new())
|
||||
TEST_ptr(ctx = OPENSSL_CTX_new())
|
||||
&& test_context(ctx);
|
||||
|
||||
OPENSSL_CTX_free(ctx);
|
||||
|
|
|
@ -21,7 +21,7 @@ static int add_property_names(const char *n, ...)
|
|||
|
||||
va_start(args, n);
|
||||
do {
|
||||
if (!TEST_int_ne(ossl_property_name(n, 1), 0))
|
||||
if (!TEST_int_ne(ossl_property_name(NULL, n, 1), 0))
|
||||
res = 0;
|
||||
} while ((n = va_arg(args, const char *)) != NULL);
|
||||
va_end(args);
|
||||
|
@ -34,24 +34,24 @@ static int test_property_string(void)
|
|||
int res = 0;
|
||||
OSSL_PROPERTY_IDX i, j;
|
||||
|
||||
if (TEST_ptr(store = ossl_method_store_new())
|
||||
&& TEST_int_eq(ossl_property_name("fnord", 0), 0)
|
||||
&& TEST_int_ne(ossl_property_name("fnord", 1), 0)
|
||||
&& TEST_int_ne(ossl_property_name("name", 1), 0)
|
||||
if (TEST_ptr(store = ossl_method_store_new(NULL))
|
||||
&& TEST_int_eq(ossl_property_name(NULL, "fnord", 0), 0)
|
||||
&& TEST_int_ne(ossl_property_name(NULL, "fnord", 1), 0)
|
||||
&& TEST_int_ne(ossl_property_name(NULL, "name", 1), 0)
|
||||
/* Property value checks */
|
||||
&& TEST_int_eq(ossl_property_value("fnord", 0), 0)
|
||||
&& TEST_int_ne(i = ossl_property_value("no", 0), 0)
|
||||
&& TEST_int_ne(j = ossl_property_value("yes", 0), 0)
|
||||
&& TEST_int_eq(ossl_property_value(NULL, "fnord", 0), 0)
|
||||
&& TEST_int_ne(i = ossl_property_value(NULL, "no", 0), 0)
|
||||
&& TEST_int_ne(j = ossl_property_value(NULL, "yes", 0), 0)
|
||||
&& TEST_int_ne(i, j)
|
||||
&& TEST_int_eq(ossl_property_value("yes", 1), j)
|
||||
&& TEST_int_eq(ossl_property_value("no", 1), i)
|
||||
&& TEST_int_ne(i = ossl_property_value("illuminati", 1), 0)
|
||||
&& TEST_int_eq(j = ossl_property_value("fnord", 1), i + 1)
|
||||
&& TEST_int_eq(ossl_property_value("fnord", 1), j)
|
||||
&& TEST_int_eq(ossl_property_value(NULL, "yes", 1), j)
|
||||
&& TEST_int_eq(ossl_property_value(NULL, "no", 1), i)
|
||||
&& TEST_int_ne(i = ossl_property_value(NULL, "illuminati", 1), 0)
|
||||
&& TEST_int_eq(j = ossl_property_value(NULL, "fnord", 1), i + 1)
|
||||
&& TEST_int_eq(ossl_property_value(NULL, "fnord", 1), j)
|
||||
/* Check name and values are distinct */
|
||||
&& TEST_int_eq(ossl_property_value("cold", 0), 0)
|
||||
&& TEST_int_ne(ossl_property_name("fnord", 0),
|
||||
ossl_property_value("fnord", 0)))
|
||||
&& TEST_int_eq(ossl_property_value(NULL, "cold", 0), 0)
|
||||
&& TEST_int_ne(ossl_property_name(NULL, "fnord", 0),
|
||||
ossl_property_value(NULL, "fnord", 0)))
|
||||
res = 1;
|
||||
ossl_method_store_free(store);
|
||||
return res;
|
||||
|
@ -95,11 +95,11 @@ static int test_property_parse(int n)
|
|||
OSSL_PROPERTY_LIST *p = NULL, *q = NULL;
|
||||
int r = 0;
|
||||
|
||||
if (TEST_ptr(store = ossl_method_store_new())
|
||||
if (TEST_ptr(store = ossl_method_store_new(NULL))
|
||||
&& add_property_names("sky", "groan", "cold", "today", "tomorrow", "n",
|
||||
NULL)
|
||||
&& TEST_ptr(p = ossl_parse_property(parser_tests[n].defn))
|
||||
&& TEST_ptr(q = ossl_parse_query(parser_tests[n].query))
|
||||
&& TEST_ptr(p = ossl_parse_property(NULL, parser_tests[n].defn))
|
||||
&& TEST_ptr(q = ossl_parse_query(NULL, parser_tests[n].query))
|
||||
&& TEST_int_eq(ossl_property_match(q, p), parser_tests[n].e))
|
||||
r = 1;
|
||||
ossl_property_free(p);
|
||||
|
@ -141,12 +141,12 @@ static int test_property_merge(int n)
|
|||
OSSL_PROPERTY_LIST *q_combined = NULL, *prop = NULL;
|
||||
int r = 0;
|
||||
|
||||
if (TEST_ptr(store = ossl_method_store_new())
|
||||
if (TEST_ptr(store = ossl_method_store_new(NULL))
|
||||
&& add_property_names("colour", "urn", "clouds", "pot", "day", "night",
|
||||
NULL)
|
||||
&& TEST_ptr(prop = ossl_parse_property(merge_tests[n].prop))
|
||||
&& TEST_ptr(q_global = ossl_parse_query(merge_tests[n].q_global))
|
||||
&& TEST_ptr(q_local = ossl_parse_query(merge_tests[n].q_local))
|
||||
&& TEST_ptr(prop = ossl_parse_property(NULL, merge_tests[n].prop))
|
||||
&& TEST_ptr(q_global = ossl_parse_query(NULL, merge_tests[n].q_global))
|
||||
&& TEST_ptr(q_local = ossl_parse_query(NULL, merge_tests[n].q_local))
|
||||
&& TEST_ptr(q_combined = ossl_property_merge(q_local, q_global))
|
||||
&& TEST_true(ossl_property_match(q_combined, prop)))
|
||||
r = 1;
|
||||
|
@ -164,15 +164,15 @@ static int test_property_defn_cache(void)
|
|||
OSSL_PROPERTY_LIST *red, *blue;
|
||||
int r = 0;
|
||||
|
||||
if (TEST_ptr(store = ossl_method_store_new())
|
||||
if (TEST_ptr(store = ossl_method_store_new(NULL))
|
||||
&& add_property_names("red", "blue", NULL)
|
||||
&& TEST_ptr(red = ossl_parse_property("red"))
|
||||
&& TEST_ptr(blue = ossl_parse_property("blue"))
|
||||
&& TEST_ptr(red = ossl_parse_property(NULL, "red"))
|
||||
&& TEST_ptr(blue = ossl_parse_property(NULL, "blue"))
|
||||
&& TEST_ptr_ne(red, blue)
|
||||
&& TEST_true(ossl_prop_defn_set("red", red))
|
||||
&& TEST_true(ossl_prop_defn_set("blue", blue))
|
||||
&& TEST_ptr_eq(ossl_prop_defn_get("red"), red)
|
||||
&& TEST_ptr_eq(ossl_prop_defn_get("blue"), blue))
|
||||
&& TEST_true(ossl_prop_defn_set(NULL, "red", red))
|
||||
&& TEST_true(ossl_prop_defn_set(NULL, "blue", blue))
|
||||
&& TEST_ptr_eq(ossl_prop_defn_get(NULL, "red"), red)
|
||||
&& TEST_ptr_eq(ossl_prop_defn_get(NULL, "blue"), blue))
|
||||
r = 1;
|
||||
ossl_method_store_free(store);
|
||||
return r;
|
||||
|
@ -196,10 +196,10 @@ static int test_definition_compares(int n)
|
|||
OSSL_PROPERTY_LIST *d = NULL, *q = NULL;
|
||||
int r;
|
||||
|
||||
r = TEST_ptr(store = ossl_method_store_new())
|
||||
r = TEST_ptr(store = ossl_method_store_new(NULL))
|
||||
&& add_property_names("alpha", "omega", NULL)
|
||||
&& TEST_ptr(d = ossl_parse_property(definition_tests[n].defn))
|
||||
&& TEST_ptr(q = ossl_parse_query(definition_tests[n].query))
|
||||
&& TEST_ptr(d = ossl_parse_property(NULL, definition_tests[n].defn))
|
||||
&& TEST_ptr(q = ossl_parse_query(NULL, definition_tests[n].query))
|
||||
&& TEST_int_eq(ossl_property_match(q, d), definition_tests[n].e);
|
||||
|
||||
ossl_property_free(d);
|
||||
|
@ -224,7 +224,7 @@ static int test_register_deregister(void)
|
|||
int ret = 0;
|
||||
OSSL_METHOD_STORE *store;
|
||||
|
||||
if (!TEST_ptr(store = ossl_method_store_new())
|
||||
if (!TEST_ptr(store = ossl_method_store_new(NULL))
|
||||
|| !add_property_names("position", NULL))
|
||||
goto err;
|
||||
|
||||
|
@ -291,7 +291,7 @@ static int test_property(void)
|
|||
int ret = 0;
|
||||
void *result;
|
||||
|
||||
if (!TEST_ptr(store = ossl_method_store_new())
|
||||
if (!TEST_ptr(store = ossl_method_store_new(NULL))
|
||||
|| !add_property_names("fast", "colour", "sky", "furry", NULL))
|
||||
goto err;
|
||||
|
||||
|
@ -329,7 +329,7 @@ static int test_query_cache_stochastic(void)
|
|||
int errors = 0;
|
||||
int v[10001];
|
||||
|
||||
if (!TEST_ptr(store = ossl_method_store_new())
|
||||
if (!TEST_ptr(store = ossl_method_store_new(NULL))
|
||||
|| !add_property_names("n", NULL))
|
||||
goto err;
|
||||
|
||||
|
|
Loading…
Reference in a new issue