#include <openssl/core_numbers.h>
#include <openssl/params.h>
#include <openssl/opensslv.h>
-#include "internal/cryptlib.h"
+#include "internal/cryptlib_int.h"
#include "internal/nelem.h"
#include "internal/thread_once.h"
#include "internal/provider.h"
DSO *module;
OSSL_provider_init_fn *init_function;
STACK_OF(INFOPAIR) *parameters;
+ OPENSSL_CTX *libctx; /* The library context this instance is in */
struct provider_store_st *store; /* The store this instance belongs to */
/* Provider side functions */
OSSL_provider_get_param_types_fn *get_param_types;
OSSL_provider_get_params_fn *get_params;
OSSL_provider_query_operation_fn *query_operation;
+
+ /* Provider side data */
+ void *provctx;
};
DEFINE_STACK_OF(OSSL_PROVIDER)
CRYPTO_RWLOCK *lock;
unsigned int use_fallbacks:1;
};
-static int provider_store_index = -1;
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;
CRYPTOerr(CRYPTO_F_PROVIDER_STORE_NEW, ERR_R_INTERNAL_ERROR);
return NULL;
}
+ prov->libctx = ctx;
prov->store = store;
if(p->is_fallback)
ossl_provider_set_fallback(prov);
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;
{
int ref = 0;
- CRYPTO_UP_REF(&prov->refcnt, &ref, prov->refcnt_lock);
+ if (CRYPTO_UP_REF(&prov->refcnt, &ref, prov->refcnt_lock) <= 0)
+ return 0;
return ref;
}
ossl_provider_free(prov); /* -1 Reference that was to be returned */
prov = NULL;
} else {
+ prov->libctx = libctx;
prov->store = store;
}
CRYPTO_THREAD_unlock(store->lock);
* When that happens, the provider is inactivated.
*/
if (ref < 2 && prov->flag_initialized) {
+#ifndef FIPS_MODE
+ ossl_init_thread_deregister(prov);
+#endif
if (prov->teardown != NULL)
- prov->teardown();
+ prov->teardown(prov->provctx);
prov->flag_initialized = 0;
}
* the store. All we have to do here is clean it out.
*/
if (ref == 0) {
+#ifndef FIPS_MODE
DSO_free(prov->module);
+#endif
OPENSSL_free(prov->name);
OPENSSL_free(prov->path);
sk_INFOPAIR_pop_free(prov->parameters, free_infopair);
/*
* Internal version that doesn't affect the store flags, and thereby avoid
* locking. Direct callers must remember to set the store flags when
- * appropriate
+ * appropriate.
*/
static int provider_activate(OSSL_PROVIDER *prov)
{
* a loadable module.
*/
if (prov->init_function == NULL) {
+#ifdef FIPS_MODE
+ return 0;
+#else
if (prov->module == NULL) {
char *allocated_path = NULL;
const char *module_path = NULL;
if (prov->module != NULL)
prov->init_function = (OSSL_provider_init_fn *)
DSO_bind_func(prov->module, "OSSL_provider_init");
+#endif
}
+ /* Call the initialise function for the provider. */
if (prov->init_function == NULL
- || !prov->init_function(prov, core_dispatch, &provider_dispatch)) {
+ || !prov->init_function(prov, core_dispatch, &provider_dispatch,
+ &prov->provctx)) {
CRYPTOerr(CRYPTO_F_PROVIDER_ACTIVATE, ERR_R_INIT_FAIL);
ERR_add_error_data(2, "name=", prov->name);
+#ifndef FIPS_MODE
DSO_free(prov->module);
prov->module = NULL;
+#endif
return 0;
}
return 0;
}
+void *ossl_provider_ctx(const OSSL_PROVIDER *prov)
+{
+ return prov->provctx;
+}
+
static int provider_forall_loaded(struct provider_store_st *store,
int *found_activated,
}
/* Getters of Provider Object data */
-const char *ossl_provider_name(OSSL_PROVIDER *prov)
+const char *ossl_provider_name(const OSSL_PROVIDER *prov)
{
return prov->name;
}
-const DSO *ossl_provider_dso(OSSL_PROVIDER *prov)
+const DSO *ossl_provider_dso(const OSSL_PROVIDER *prov)
{
return prov->module;
}
-const char *ossl_provider_module_name(OSSL_PROVIDER *prov)
+const char *ossl_provider_module_name(const OSSL_PROVIDER *prov)
{
+#ifdef FIPS_MODE
+ return NULL;
+#else
return DSO_get_filename(prov->module);
+#endif
}
-const char *ossl_provider_module_path(OSSL_PROVIDER *prov)
+const char *ossl_provider_module_path(const OSSL_PROVIDER *prov)
{
+#ifdef FIPS_MODE
+ return NULL;
+#else
/* FIXME: Ensure it's a full path */
return DSO_get_filename(prov->module);
+#endif
}
/* Wrappers around calls to the provider */
void ossl_provider_teardown(const OSSL_PROVIDER *prov)
{
if (prov->teardown != NULL)
- prov->teardown();
+ prov->teardown(prov->provctx);
}
const OSSL_ITEM *ossl_provider_get_param_types(const OSSL_PROVIDER *prov)
{
- return prov->get_param_types == NULL ? NULL : prov->get_param_types(prov);
+ return prov->get_param_types == NULL
+ ? NULL : prov->get_param_types(prov->provctx);
}
int ossl_provider_get_params(const OSSL_PROVIDER *prov,
const OSSL_PARAM params[])
{
- return prov->get_params == NULL ? 0 : prov->get_params(prov, params);
+ return prov->get_params == NULL
+ ? 0 : prov->get_params(prov->provctx, params);
}
int operation_id,
int *no_cache)
{
- return prov->query_operation(prov, operation_id, no_cache);
+ return prov->query_operation(prov->provctx, operation_id, no_cache);
}
/*-
return 1;
}
+static OSSL_core_get_library_context_fn core_get_libctx; /* Check */
+static OPENSSL_CTX *core_get_libctx(const OSSL_PROVIDER *prov)
+{
+ return prov->libctx;
+}
+
+static int core_thread_start(const OSSL_PROVIDER *prov,
+ OSSL_thread_stop_handler_fn handfn)
+{
+ return ossl_init_thread_start(prov, prov->provctx, handfn);
+}
+
static const OSSL_DISPATCH core_dispatch_[] = {
{ OSSL_FUNC_CORE_GET_PARAM_TYPES, (void (*)(void))core_get_param_types },
{ OSSL_FUNC_CORE_GET_PARAMS, (void (*)(void))core_get_params },
+ { OSSL_FUNC_CORE_GET_LIBRARY_CONTEXT, (void (*)(void))core_get_libctx },
+ { OSSL_FUNC_CORE_THREAD_START, (void (*)(void))core_thread_start },
+ { OSSL_FUNC_CORE_PUT_ERROR, (void (*)(void))ERR_put_error },
+ { OSSL_FUNC_CORE_ADD_ERROR_VDATA, (void (*)(void))ERR_add_error_vdata },
{ 0, NULL }
};
static const OSSL_DISPATCH *core_dispatch = core_dispatch_;