/*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2020 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
* https://www.openssl.org/source/license.html
*/
-#include "internal/cryptlib_int.h"
+#include "crypto/cryptlib.h"
#include "internal/thread_once.h"
-int do_ex_data_init(OPENSSL_CTX *ctx)
+int do_ex_data_init(OSSL_LIB_CTX *ctx)
{
- OSSL_EX_DATA_GLOBAL *global = openssl_ctx_get_ex_data_global(ctx);
+ OSSL_EX_DATA_GLOBAL *global = ossl_lib_ctx_get_ex_data_global(ctx);
if (global == NULL)
return 0;
/*
* Return the EX_CALLBACKS from the |ex_data| array that corresponds to
* a given class. On success, *holds the lock.*
+ * The |global| parameter is assumed to be non null (checked by the caller).
*/
-static EX_CALLBACKS *get_and_lock(OPENSSL_CTX *ctx, int class_index)
+static EX_CALLBACKS *get_and_lock(OSSL_EX_DATA_GLOBAL *global, 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;
}
- 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
- * up the locks. Subsequently the BIO that CRYPTO_mem_leaks() uses gets
- * freed, which also attempts to free the ex_data. However
- * CRYPTO_mem_leaks() ensures that the ex_data is freed early (i.e.
- * before OPENSSL_cleanup() is called), so if we get here we can safely
- * ignore this operation. We just treat it as an error.
+ * If we get here, someone (who?) cleaned up the lock, so just
+ * treat it as an error.
*/
return NULL;
}
- ip = &global->ex_data[class_index];
CRYPTO_THREAD_write_lock(global->ex_data_lock);
+ ip = &global->ex_data[class_index];
return ip;
}
* called under potential race-conditions anyway (it's for program shutdown
* after all).
*/
-void crypto_cleanup_all_ex_data_int(OPENSSL_CTX *ctx)
+void crypto_cleanup_all_ex_data_int(OSSL_LIB_CTX *ctx)
{
int i;
- OSSL_EX_DATA_GLOBAL *global = openssl_ctx_get_ex_data_global(ctx);
+ OSSL_EX_DATA_GLOBAL *global = ossl_lib_ctx_get_ex_data_global(ctx);
if (global == NULL)
return;
}
static int dummy_dup(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from,
- void *from_d, int idx,
+ void **from_d, int idx,
long argl, void *argp)
{
return 1;
}
-int crypto_free_ex_index_ex(OPENSSL_CTX *ctx, int class_index, int idx)
+int crypto_free_ex_index_ex(OSSL_LIB_CTX *ctx, int class_index, int idx)
{
- EX_CALLBACKS *ip = get_and_lock(ctx, class_index);
+ EX_CALLBACKS *ip;
EX_CALLBACK *a;
int toret = 0;
- OSSL_EX_DATA_GLOBAL *global = openssl_ctx_get_ex_data_global(ctx);
+ OSSL_EX_DATA_GLOBAL *global = ossl_lib_ctx_get_ex_data_global(ctx);
if (global == NULL)
- goto err;
+ return 0;
- ip = get_and_lock(ctx, class_index);
+ ip = get_and_lock(global, class_index);
if (ip == NULL)
return 0;
+
if (idx < 0 || idx >= sk_EX_CALLBACK_num(ip->meth))
goto err;
a = sk_EX_CALLBACK_value(ip->meth, idx);
/*
* Register a new index.
*/
-int crypto_get_ex_new_index_ex(OPENSSL_CTX *ctx, int class_index, long argl,
+int crypto_get_ex_new_index_ex(OSSL_LIB_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;
- OSSL_EX_DATA_GLOBAL *global = openssl_ctx_get_ex_data_global(ctx);
+ OSSL_EX_DATA_GLOBAL *global = ossl_lib_ctx_get_ex_data_global(ctx);
if (global == NULL)
- goto err;
+ return -1;
- ip = get_and_lock(ctx, class_index);
+ ip = get_and_lock(global, class_index);
if (ip == NULL)
return -1;
* 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_ex(OPENSSL_CTX *ctx, int class_index, void *obj,
+int crypto_new_ex_data_ex(OSSL_LIB_CTX *ctx, int class_index, void *obj,
CRYPTO_EX_DATA *ad)
{
int mx, i;
EX_CALLBACK **storage = NULL;
EX_CALLBACK *stack[10];
EX_CALLBACKS *ip;
- OSSL_EX_DATA_GLOBAL *global = openssl_ctx_get_ex_data_global(ctx);
+ OSSL_EX_DATA_GLOBAL *global = ossl_lib_ctx_get_ex_data_global(ctx);
if (global == NULL)
return 0;
- ip = get_and_lock(ctx, class_index);
+ ip = get_and_lock(global, class_index);
if (ip == NULL)
return 0;
ad->ctx = ctx;
ad->sk = NULL;
-
mx = sk_EX_CALLBACK_num(ip->meth);
if (mx > 0) {
if (mx < (int)OSSL_NELEM(stack))
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;
+ OSSL_EX_DATA_GLOBAL *global;
to->ctx = from->ctx;
if (from->sk == NULL)
/* Nothing to copy over */
return 1;
- if ((ip = get_and_lock(from->ctx, class_index)) == NULL)
+
+ global = ossl_lib_ctx_get_ex_data_global(from->ctx);
+ if (global == NULL)
+ return 0;
+
+ ip = get_and_lock(global, class_index);
+ if (ip == NULL)
return 0;
mx = sk_EX_CALLBACK_num(ip->meth);
EX_CALLBACK *f;
EX_CALLBACK *stack[10];
EX_CALLBACK **storage = NULL;
- OSSL_EX_DATA_GLOBAL *global;
+ OSSL_EX_DATA_GLOBAL *global = ossl_lib_ctx_get_ex_data_global(ad->ctx);
- 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;
+ ip = get_and_lock(global, class_index);
+ if (ip == NULL)
+ goto err;
+
mx = sk_EX_CALLBACK_num(ip->meth);
if (mx > 0) {
if (mx < (int)OSSL_NELEM(stack))
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;
+ OSSL_EX_DATA_GLOBAL *global;
curval = CRYPTO_get_ex_data(ad, idx);
-
/* Already there, no need to allocate */
if (curval != NULL)
return 1;
- ip = get_and_lock(ad->ctx, class_index);
+ global = ossl_lib_ctx_get_ex_data_global(ad->ctx);
+ if (global == NULL)
+ return 0;
+
+ ip = get_and_lock(global, class_index);
if (ip == NULL)
return 0;
f = sk_EX_CALLBACK_value(ip->meth, idx);
if (f->new_func == NULL)
return 0;
- f->new_func(obj, curval, ad, idx, f->argl, f->argp);
+ f->new_func(obj, NULL, ad, idx, f->argl, f->argp);
return 1;
}
return 0;
}
}
- sk_void_set(ad->sk, idx, val);
+ if (sk_void_set(ad->sk, idx, val) != val) {
+ /* Probably the index is out of bounds */
+ CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA, ERR_R_PASSED_INVALID_ARGUMENT);
+ return 0;
+ }
return 1;
}
return sk_void_value(ad->sk, idx);
}
-OPENSSL_CTX *crypto_ex_data_get_openssl_ctx(const CRYPTO_EX_DATA *ad)
+OSSL_LIB_CTX *crypto_ex_data_get_ossl_lib_ctx(const CRYPTO_EX_DATA *ad)
{
return ad->ctx;
}