Replumbing: Add a mechanism to pre-populate the provider store
OpenSSL will come with a set of well known providers, some of which need to be accessible from the start. These are typically built in providers, or providers that will work as fallbacks. We do this when creating a new provider store, which means that this will happen in every library context, regardless of if it's the global default one, or an explicitely created one. We keep the data about the known providers we want to make accessible this way in crypto/provider_predefined.h, which may become generated. For now, though, we make it simple and edited manually. Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/8480)
This commit is contained in:
parent
e55008a9f2
commit
c41f3ae0d9
7 changed files with 111 additions and 26 deletions
|
@ -9,7 +9,7 @@ SUBDIRS=objects buffer bio stack lhash rand evp asn1 pem x509 x509v3 conf \
|
|||
|
||||
LIBS=../libcrypto
|
||||
# The Core
|
||||
SOURCE[../libcrypto]=provider_core.c core_fetch.c
|
||||
SOURCE[../libcrypto]=provider_core.c provider_predefined.c core_fetch.c
|
||||
|
||||
# Central utilities
|
||||
SOURCE[../libcrypto]=\
|
||||
|
|
|
@ -59,6 +59,9 @@ static const ERR_STRING_DATA CRYPTO_str_functs[] = {
|
|||
"pkey_siphash_init"},
|
||||
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_PROVIDER_ACTIVATE, 0),
|
||||
"provider_activate"},
|
||||
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_PROVIDER_NEW, 0), "provider_new"},
|
||||
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_PROVIDER_STORE_NEW, 0),
|
||||
"provider_store_new"},
|
||||
{ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_SK_RESERVE, 0), "sk_reserve"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
|
|
@ -397,6 +397,8 @@ CRYPTO_F_PKEY_HMAC_INIT:123:pkey_hmac_init
|
|||
CRYPTO_F_PKEY_POLY1305_INIT:124:pkey_poly1305_init
|
||||
CRYPTO_F_PKEY_SIPHASH_INIT:125:pkey_siphash_init
|
||||
CRYPTO_F_PROVIDER_ACTIVATE:134:provider_activate
|
||||
CRYPTO_F_PROVIDER_NEW:135:provider_new
|
||||
CRYPTO_F_PROVIDER_STORE_NEW:136:provider_store_new
|
||||
CRYPTO_F_SK_RESERVE:129:sk_reserve
|
||||
CT_F_CTLOG_NEW:117:CTLOG_new
|
||||
CT_F_CTLOG_NEW_FROM_BASE64:118:CTLOG_new_from_base64
|
||||
|
|
|
@ -11,9 +11,14 @@
|
|||
#include <openssl/core_numbers.h>
|
||||
#include <openssl/opensslv.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include "internal/nelem.h"
|
||||
#include "internal/thread_once.h"
|
||||
#include "internal/provider.h"
|
||||
#include "internal/refcount.h"
|
||||
#include "provider_local.h"
|
||||
|
||||
static OSSL_PROVIDER *provider_new(const char *name,
|
||||
OSSL_provider_init_fn *init_function);
|
||||
|
||||
/*-
|
||||
* Provider Object structure
|
||||
|
@ -78,6 +83,7 @@ static void provider_store_free(void *vstore)
|
|||
static void *provider_store_new(void)
|
||||
{
|
||||
struct provider_store_st *store = OPENSSL_zalloc(sizeof(*store));
|
||||
const struct predefined_providers_st *p = NULL;
|
||||
|
||||
if (store == NULL
|
||||
|| (store->providers = sk_OSSL_PROVIDER_new(ossl_provider_cmp)) == NULL
|
||||
|
@ -86,6 +92,28 @@ static void *provider_store_new(void)
|
|||
return NULL;
|
||||
}
|
||||
store->use_fallbacks = 1;
|
||||
|
||||
for (p = predefined_providers; p->name != NULL; p++) {
|
||||
OSSL_PROVIDER *prov = NULL;
|
||||
|
||||
/*
|
||||
* We use the internal constructor directly here,
|
||||
* otherwise we get a call loop
|
||||
*/
|
||||
prov = provider_new(p->name, p->init);
|
||||
|
||||
if (prov == NULL
|
||||
|| sk_OSSL_PROVIDER_push(store->providers, prov) == 0) {
|
||||
ossl_provider_free(prov);
|
||||
provider_store_free(store);
|
||||
CRYPTOerr(CRYPTO_F_PROVIDER_STORE_NEW, ERR_R_INTERNAL_ERROR);
|
||||
return NULL;
|
||||
}
|
||||
prov->store = store;
|
||||
if(p->is_fallback)
|
||||
ossl_provider_set_fallback(prov);
|
||||
}
|
||||
|
||||
return store;
|
||||
}
|
||||
|
||||
|
@ -116,20 +144,6 @@ static struct provider_store_st *get_provider_store(OPENSSL_CTX *libctx)
|
|||
return store;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Provider Object methods
|
||||
* =======================
|
||||
*/
|
||||
|
||||
int ossl_provider_upref(OSSL_PROVIDER *prov)
|
||||
{
|
||||
int ref = 0;
|
||||
|
||||
CRYPTO_UP_REF(&prov->refcnt, &ref, prov->refcnt_lock);
|
||||
return ref;
|
||||
}
|
||||
|
||||
/* Finder, constructor and destructor */
|
||||
OSSL_PROVIDER *ossl_provider_find(OPENSSL_CTX *libctx, const char *name)
|
||||
{
|
||||
struct provider_store_st *store = NULL;
|
||||
|
@ -151,6 +165,39 @@ OSSL_PROVIDER *ossl_provider_find(OPENSSL_CTX *libctx, const char *name)
|
|||
return prov;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Provider Object methods
|
||||
* =======================
|
||||
*/
|
||||
|
||||
static OSSL_PROVIDER *provider_new(const char *name,
|
||||
OSSL_provider_init_fn *init_function)
|
||||
{
|
||||
OSSL_PROVIDER *prov = NULL;
|
||||
|
||||
if ((prov = OPENSSL_zalloc(sizeof(*prov))) == NULL
|
||||
#ifndef HAVE_ATOMICS
|
||||
|| (prov->refcnt_lock = CRYPTO_THREAD_lock_new()) == NULL
|
||||
#endif
|
||||
|| !ossl_provider_upref(prov) /* +1 One reference to be returned */
|
||||
|| (prov->name = OPENSSL_strdup(name)) == NULL) {
|
||||
ossl_provider_free(prov);
|
||||
CRYPTOerr(CRYPTO_F_PROVIDER_NEW, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
prov->init_function = init_function;
|
||||
return prov;
|
||||
}
|
||||
|
||||
int ossl_provider_upref(OSSL_PROVIDER *prov)
|
||||
{
|
||||
int ref = 0;
|
||||
|
||||
CRYPTO_UP_REF(&prov->refcnt, &ref, prov->refcnt_lock);
|
||||
return ref;
|
||||
}
|
||||
|
||||
OSSL_PROVIDER *ossl_provider_new(OPENSSL_CTX *libctx, const char *name,
|
||||
OSSL_provider_init_fn *init_function)
|
||||
{
|
||||
|
@ -168,18 +215,9 @@ OSSL_PROVIDER *ossl_provider_new(OPENSSL_CTX *libctx, const char *name,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if ((prov = OPENSSL_zalloc(sizeof(*prov))) == NULL
|
||||
#ifndef HAVE_ATOMICS
|
||||
|| (prov->refcnt_lock = CRYPTO_THREAD_lock_new()) == NULL
|
||||
#endif
|
||||
|| !ossl_provider_upref(prov) /* +1 One reference to be returned */
|
||||
|| (prov->name = OPENSSL_strdup(name)) == NULL) {
|
||||
ossl_provider_free(prov);
|
||||
CRYPTOerr(CRYPTO_F_OSSL_PROVIDER_NEW, ERR_R_MALLOC_FAILURE);
|
||||
/* provider_new() generates an error, so no need here */
|
||||
if ((prov = provider_new(name, init_function)) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
prov->init_function = init_function;
|
||||
|
||||
CRYPTO_THREAD_write_lock(store->lock);
|
||||
if (!ossl_provider_upref(prov)) { /* +1 One reference for the store */
|
||||
|
|
18
crypto/provider_local.h
Normal file
18
crypto/provider_local.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright 2019 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <openssl/core.h>
|
||||
|
||||
struct predefined_providers_st {
|
||||
const char *name;
|
||||
OSSL_provider_init_fn *init;
|
||||
unsigned int is_fallback:1;
|
||||
};
|
||||
|
||||
extern const struct predefined_providers_st predefined_providers[];
|
22
crypto/provider_predefined.c
Normal file
22
crypto/provider_predefined.c
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright 2019 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <openssl/core.h>
|
||||
#include "provider_local.h"
|
||||
|
||||
#if 0 /* Until it exists for real */
|
||||
OSSL_provider_init_fn ossl_default_provider_init;
|
||||
#endif
|
||||
|
||||
const struct predefined_providers_st predefined_providers[] = {
|
||||
#if 0 /* Until it exists for real */
|
||||
{ "default", ossl_default_provider_init, 1 },
|
||||
#endif
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
|
@ -50,6 +50,8 @@ int ERR_load_CRYPTO_strings(void);
|
|||
# define CRYPTO_F_PKEY_POLY1305_INIT 124
|
||||
# define CRYPTO_F_PKEY_SIPHASH_INIT 125
|
||||
# define CRYPTO_F_PROVIDER_ACTIVATE 134
|
||||
# define CRYPTO_F_PROVIDER_NEW 135
|
||||
# define CRYPTO_F_PROVIDER_STORE_NEW 136
|
||||
# define CRYPTO_F_SK_RESERVE 129
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue