Store the list of activated providers in the libctx

The provider config module was storing the list of activated providers
in a global variable. However, because different libctxs can each load
providers via config files we need to keep the list of activated providers
separate and in the libctx.

Partially fixes #15030

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15033)
This commit is contained in:
Matt Caswell 2021-04-26 14:58:40 +01:00
parent 2d5695016d
commit 460d2fbcd7
2 changed files with 39 additions and 14 deletions

View File

@ -13,12 +13,41 @@
#include <openssl/conf.h>
#include <openssl/safestack.h>
#include "internal/provider.h"
#include "internal/cryptlib.h"
DEFINE_STACK_OF(OSSL_PROVIDER)
/* PROVIDER config module */
static STACK_OF(OSSL_PROVIDER) *activated_providers = NULL;
typedef struct {
STACK_OF(OSSL_PROVIDER) *activated_providers;
} PROVIDER_CONF_GLOBAL;
static void *prov_conf_ossl_ctx_new(OSSL_LIB_CTX *libctx)
{
PROVIDER_CONF_GLOBAL *pcgbl = OPENSSL_zalloc(sizeof(*pcgbl));
if (pcgbl == NULL)
return NULL;
return pcgbl;
}
static void prov_conf_ossl_ctx_free(void *vpcgbl)
{
PROVIDER_CONF_GLOBAL *pcgbl = vpcgbl;
sk_OSSL_PROVIDER_pop_free(pcgbl->activated_providers,
ossl_provider_free);
OSSL_TRACE(CONF, "Cleaned up providers\n");
OPENSSL_free(pcgbl);
}
static const OSSL_LIB_CTX_METHOD provider_conf_ossl_ctx_method = {
prov_conf_ossl_ctx_new,
prov_conf_ossl_ctx_free,
};
static const char *skip_dot(const char *name)
{
@ -80,6 +109,9 @@ static int provider_conf_load(OSSL_LIB_CTX *libctx, const char *name,
const char *path = NULL;
long activate = 0;
int ok = 0;
PROVIDER_CONF_GLOBAL *pcgbl
= ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_PROVIDER_CONF_INDEX,
&provider_conf_ossl_ctx_method);
name = skip_dot(name);
OSSL_TRACE1(CONF, "Configuring provider %s\n", name);
@ -133,9 +165,9 @@ static int provider_conf_load(OSSL_LIB_CTX *libctx, const char *name,
if (!ossl_provider_activate(prov, 0)) {
ok = 0;
} else {
if (activated_providers == NULL)
activated_providers = sk_OSSL_PROVIDER_new_null();
sk_OSSL_PROVIDER_push(activated_providers, prov);
if (pcgbl->activated_providers == NULL)
pcgbl->activated_providers = sk_OSSL_PROVIDER_new_null();
sk_OSSL_PROVIDER_push(pcgbl->activated_providers, prov);
ok = 1;
}
}
@ -172,16 +204,8 @@ static int provider_conf_init(CONF_IMODULE *md, const CONF *cnf)
return 1;
}
static void provider_conf_deinit(CONF_IMODULE *md)
{
sk_OSSL_PROVIDER_pop_free(activated_providers, ossl_provider_free);
activated_providers = NULL;
OSSL_TRACE(CONF, "Cleaned up providers\n");
}
void ossl_provider_add_conf_module(void)
{
OSSL_TRACE(CONF, "Adding config module 'providers'\n");
CONF_module_add("providers", provider_conf_init, provider_conf_deinit);
CONF_module_add("providers", provider_conf_init, NULL);
}

View File

@ -162,7 +162,8 @@ typedef struct ossl_ex_data_global_st {
# define OSSL_LIB_CTX_BIO_PROV_INDEX 13
# define OSSL_LIB_CTX_GLOBAL_PROPERTIES 14
# define OSSL_LIB_CTX_STORE_LOADER_STORE_INDEX 15
# define OSSL_LIB_CTX_MAX_INDEXES 16
# define OSSL_LIB_CTX_PROVIDER_CONF_INDEX 16
# define OSSL_LIB_CTX_MAX_INDEXES 17
typedef struct ossl_lib_ctx_method {
void *(*new_func)(OSSL_LIB_CTX *ctx);