]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Add the concept of a child OSSL_LIB_CTX
authorMatt Caswell <matt@openssl.org>
Wed, 21 Apr 2021 15:51:41 +0000 (16:51 +0100)
committerMatt Caswell <matt@openssl.org>
Tue, 11 May 2021 13:56:55 +0000 (14:56 +0100)
Add a child OSSL_LIB_CTX that will mirror the providers loaded into the
parent libctx. This is useful for providers that want to use algorithms
from other providers and just need to inherit the providers used by the
application.

Fixes #14925

Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14991)

15 files changed:
crypto/build.info
crypto/context.c
crypto/provider.c
crypto/provider_child.c [new file with mode: 0644]
crypto/provider_core.c
doc/man3/OSSL_LIB_CTX.pod
include/internal/core.h
include/internal/cryptlib.h
include/internal/provider.h
include/openssl/core.h
include/openssl/core_dispatch.h
include/openssl/crypto.h.in
include/openssl/provider.h
test/bio_core_test.c
util/libcrypto.num

index ffcc2b018379e6ac820bafb33cc94d9b2790955a..ed4581eef56cbdc55b26ec56c6ca486c156f0dd2 100644 (file)
@@ -99,7 +99,7 @@ $UTIL_COMMON=\
 SOURCE[../libcrypto]=$UTIL_COMMON \
         mem.c mem_sec.c \
         cversion.c info.c cpt_err.c ebcdic.c uid.c o_time.c o_dir.c \
-        o_fopen.c getenv.c o_init.c init.c trace.c provider.c \
+        o_fopen.c getenv.c o_init.c init.c trace.c provider.c provider_child.c \
         punycode.c
 SOURCE[../providers/libfips.a]=$UTIL_COMMON
 
index b21fdf077d9fdfe182f5fd3c86a10c3bd7cf8cd8..1e0dfa8e015e35d0d0bc5a13863db54a959a00f0 100644 (file)
@@ -13,6 +13,7 @@
 #include "internal/property.h"
 #include "internal/core.h"
 #include "internal/bio.h"
+#include "internal/provider.h"
 
 struct ossl_lib_ctx_onfree_list_st {
     ossl_lib_ctx_onfree_fn *fn;
@@ -39,6 +40,7 @@ struct ossl_lib_ctx_st {
     int run_once_done[OSSL_LIB_CTX_MAX_RUN_ONCE];
     int run_once_ret[OSSL_LIB_CTX_MAX_RUN_ONCE];
     struct ossl_lib_ctx_onfree_list_st *onfreelist;
+    unsigned int ischild:1;
 };
 
 int ossl_lib_ctx_write_lock(OSSL_LIB_CTX *ctx)
@@ -56,6 +58,15 @@ int ossl_lib_ctx_unlock(OSSL_LIB_CTX *ctx)
     return CRYPTO_THREAD_unlock(ossl_lib_ctx_get_concrete(ctx)->lock);
 }
 
+int ossl_lib_ctx_is_child(OSSL_LIB_CTX *ctx)
+{
+    ctx = ossl_lib_ctx_get_concrete(ctx);
+
+    if (ctx == NULL)
+        return 0;
+    return ctx->ischild;
+}
+
 static int context_init(OSSL_LIB_CTX *ctx)
 {
     size_t i;
@@ -185,7 +196,8 @@ OSSL_LIB_CTX *OSSL_LIB_CTX_new(void)
 }
 
 #ifndef FIPS_MODULE
-OSSL_LIB_CTX *OSSL_LIB_CTX_new_from_dispatch(const OSSL_DISPATCH *in)
+OSSL_LIB_CTX *OSSL_LIB_CTX_new_from_dispatch(const OSSL_CORE_HANDLE *handle,
+                                             const OSSL_DISPATCH *in)
 {
     OSSL_LIB_CTX *ctx = OSSL_LIB_CTX_new();
 
@@ -200,6 +212,23 @@ OSSL_LIB_CTX *OSSL_LIB_CTX_new_from_dispatch(const OSSL_DISPATCH *in)
     return ctx;
 }
 
+OSSL_LIB_CTX *OSSL_LIB_CTX_new_child(const OSSL_CORE_HANDLE *handle,
+                                     const OSSL_DISPATCH *in)
+{
+    OSSL_LIB_CTX *ctx = OSSL_LIB_CTX_new_from_dispatch(handle, in);
+
+    if (ctx == NULL)
+        return NULL;
+
+    if (!ossl_provider_init_as_child(ctx, handle, in)) {
+        OSSL_LIB_CTX_free(ctx);
+        return NULL;
+    }
+    ctx->ischild = 1;
+
+    return ctx;
+}
+
 int OSSL_LIB_CTX_load_config(OSSL_LIB_CTX *ctx, const char *config_file)
 {
     return CONF_modules_load_file_ex(ctx, config_file, NULL, 0) > 0;
index bdff44afb9341bc44cd1a10c7e16792ec7be8891..743c2f48467acbcb0e3ef7429aa0551da1e5ab2c 100644 (file)
@@ -88,6 +88,11 @@ void *OSSL_PROVIDER_get0_provider_ctx(const OSSL_PROVIDER *prov)
     return ossl_provider_prov_ctx(prov);
 }
 
+const OSSL_DISPATCH *OSSL_PROVIDER_get0_dispatch(const OSSL_PROVIDER *prov)
+{
+    return ossl_provider_get0_dispatch(prov);
+}
+
 int OSSL_PROVIDER_self_test(const OSSL_PROVIDER *prov)
 {
     return ossl_provider_self_test(prov);
diff --git a/crypto/provider_child.c b/crypto/provider_child.c
new file mode 100644 (file)
index 0000000..fa1d004
--- /dev/null
@@ -0,0 +1,232 @@
+/*
+ * Copyright 2019-2021 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/crypto.h>
+#include <openssl/core_dispatch.h>
+#include <openssl/core_names.h>
+#include <openssl/provider.h>
+#include "internal/provider.h"
+#include "internal/cryptlib.h"
+
+DEFINE_STACK_OF(OSSL_PROVIDER)
+
+struct child_prov_globals {
+    const OSSL_CORE_HANDLE *handle;
+    OSSL_CORE_PROVIDER *curr_prov;
+    STACK_OF(OSSL_PROVIDER) *childprovs;
+    unsigned int isinited:1;
+    CRYPTO_RWLOCK *lock;
+    OSSL_FUNC_core_get_libctx_fn *c_get_libctx;
+    OSSL_FUNC_core_provider_do_all_fn *c_prov_do_all;
+    OSSL_FUNC_core_provider_name_fn *c_prov_name;
+    OSSL_FUNC_core_provider_get0_provider_ctx_fn *c_prov_get0_provider_ctx;
+    OSSL_FUNC_core_provider_get0_dispatch_fn *c_prov_get0_dispatch;
+};
+
+static void *child_prov_ossl_ctx_new(OSSL_LIB_CTX *libctx)
+{
+    return OPENSSL_zalloc(sizeof(struct child_prov_globals));
+}
+
+/* Wrapper with a void return type for use with sk_OSSL_PROVIDER_pop_free */
+static void ossl_prov_free(OSSL_PROVIDER *prov)
+{
+    OSSL_PROVIDER_unload(prov);
+}
+
+static void child_prov_ossl_ctx_free(void *vgbl)
+{
+    struct child_prov_globals *gbl = vgbl;
+
+    sk_OSSL_PROVIDER_pop_free(gbl->childprovs, ossl_prov_free);
+    CRYPTO_THREAD_lock_free(gbl->lock);
+    OPENSSL_free(gbl);
+}
+
+static const OSSL_LIB_CTX_METHOD child_prov_ossl_ctx_method = {
+    OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY,
+    child_prov_ossl_ctx_new,
+    child_prov_ossl_ctx_free,
+};
+
+static OSSL_provider_init_fn ossl_child_provider_init;
+
+static int ossl_child_provider_init(const OSSL_CORE_HANDLE *handle,
+                                    const OSSL_DISPATCH *in,
+                                    const OSSL_DISPATCH **out,
+                                    void **provctx)
+{
+    OSSL_FUNC_core_get_libctx_fn *c_get_libctx = NULL;
+    OSSL_LIB_CTX *ctx;
+    struct child_prov_globals *gbl;
+
+    for (; in->function_id != 0; in++) {
+        switch (in->function_id) {
+        case OSSL_FUNC_CORE_GET_LIBCTX:
+            c_get_libctx = OSSL_FUNC_core_get_libctx(in);
+            break;
+        default:
+            /* Just ignore anything we don't understand */
+            break;
+        }
+    }
+
+    if (c_get_libctx == NULL)
+        return 0;
+
+    /*
+     * We need an OSSL_LIB_CTX but c_get_libctx returns OPENSSL_CORE_CTX. We are
+     * a built-in provider and so we can get away with this cast. Normal
+     * providers can't do this.
+     */
+    ctx = (OSSL_LIB_CTX *)c_get_libctx(handle);
+
+    gbl = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_CHILD_PROVIDER_INDEX,
+                                &child_prov_ossl_ctx_method);
+    if (gbl == NULL)
+        return 0;
+
+    *provctx = gbl->c_prov_get0_provider_ctx(gbl->curr_prov);
+    *out = gbl->c_prov_get0_dispatch(gbl->curr_prov);
+
+    return 1;
+}
+
+static int provider_create_child_cb(OSSL_CORE_PROVIDER *prov, void *cbdata)
+{
+    OSSL_LIB_CTX *ctx = cbdata;
+    struct child_prov_globals *gbl;
+    const char *provname;
+    OSSL_PROVIDER *cprov;
+
+    gbl = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_CHILD_PROVIDER_INDEX,
+                                &child_prov_ossl_ctx_method);
+    if (gbl == NULL)
+        return 0;
+
+    provname = gbl->c_prov_name(prov);
+
+    /*
+     * We're operating under a lock so we can store the "current" provider in
+     * the global data.
+     */
+    gbl->curr_prov = prov;
+
+    /*
+     * Create it - passing 1 as final param so we don't try and recursively init
+     * children
+     */
+    if ((cprov = ossl_provider_new(ctx, provname, ossl_child_provider_init,
+                                   1)) == NULL)
+        return 0;
+
+    if (!ossl_provider_activate(cprov, 0)) {
+        ossl_provider_free(cprov);
+        return 0;
+    }
+    ossl_provider_set_child(cprov);
+
+    if (!sk_OSSL_PROVIDER_push(gbl->childprovs, cprov)) {
+        OSSL_PROVIDER_unload(cprov);
+        return 0;
+    }
+
+    return 1;
+}
+
+int ossl_provider_init_child_providers(OSSL_LIB_CTX *ctx)
+{
+    struct child_prov_globals *gbl;
+
+    /* Should never happen */
+    if (ctx == NULL)
+        return 0;
+
+    gbl = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_CHILD_PROVIDER_INDEX,
+                                &child_prov_ossl_ctx_method);
+    if (gbl == NULL)
+        return 0;
+
+    if (!CRYPTO_THREAD_read_lock(gbl->lock))
+        return 0;
+    if (gbl->isinited) {
+        CRYPTO_THREAD_unlock(gbl->lock);
+        return 1;
+    }
+    CRYPTO_THREAD_unlock(gbl->lock);
+
+    if (!CRYPTO_THREAD_write_lock(gbl->lock))
+        return 0;
+    if (!gbl->isinited) {
+        if (!gbl->c_prov_do_all(gbl->c_get_libctx(gbl->handle),
+                                provider_create_child_cb, ctx)) {
+            CRYPTO_THREAD_unlock(gbl->lock);
+            return 0;
+        }
+        gbl->isinited = 1;
+    }
+    CRYPTO_THREAD_unlock(gbl->lock);
+
+    return 1;
+}
+
+int ossl_provider_init_as_child(OSSL_LIB_CTX *ctx,
+                                const OSSL_CORE_HANDLE *handle,
+                                const OSSL_DISPATCH *in)
+{
+    struct child_prov_globals *gbl;
+
+    if (ctx == NULL)
+        return 0;
+
+    gbl = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_CHILD_PROVIDER_INDEX,
+                                &child_prov_ossl_ctx_method);
+    if (gbl == NULL)
+        return 0;
+
+    gbl->handle = handle;
+    for (; in->function_id != 0; in++) {
+        switch (in->function_id) {
+        case OSSL_FUNC_CORE_GET_LIBCTX:
+            gbl->c_get_libctx = OSSL_FUNC_core_get_libctx(in);
+            break;
+        case OSSL_FUNC_CORE_PROVIDER_DO_ALL:
+            gbl->c_prov_do_all = OSSL_FUNC_core_provider_do_all(in);
+            break;
+        case OSSL_FUNC_CORE_PROVIDER_NAME:
+            gbl->c_prov_name = OSSL_FUNC_core_provider_name(in);
+            break;
+        case OSSL_FUNC_CORE_PROVIDER_GET0_PROVIDER_CTX:
+            gbl->c_prov_get0_provider_ctx
+                = OSSL_FUNC_core_provider_get0_provider_ctx(in);
+            break;
+        case OSSL_FUNC_CORE_PROVIDER_GET0_DISPATCH:
+            gbl->c_prov_get0_dispatch = OSSL_FUNC_core_provider_get0_dispatch(in);
+            break;
+        default:
+            /* Just ignore anything we don't understand */
+            break;
+        }
+    }
+
+    if (gbl->c_prov_do_all == NULL
+            || gbl->c_prov_name == NULL
+            || gbl->c_prov_get0_provider_ctx == NULL
+            || gbl->c_prov_get0_dispatch == NULL)
+        return 0;
+
+    gbl->childprovs = sk_OSSL_PROVIDER_new_null();
+    if (gbl->childprovs == NULL)
+        return 0;
+    gbl->lock = CRYPTO_THREAD_lock_new();
+    if (gbl->lock == NULL)
+        return 0;
+
+    return 1;
+}
index db8763d50d45f8009d905b353c9f0b97c32f3536..3e2e2ac3357feafde3edf55b0a90c4c48d6e4116 100644 (file)
@@ -22,6 +22,7 @@
 #include "internal/provider.h"
 #include "internal/refcount.h"
 #include "internal/bio.h"
+#include "internal/core.h"
 #include "provider_local.h"
 #ifndef FIPS_MODULE
 # include <openssl/self_test.h>
@@ -91,8 +92,12 @@ struct ossl_provider_st {
     size_t operation_bits_sz;
     CRYPTO_RWLOCK *opbits_lock;
 
+    /* Whether this provider is the child of some other provider */
+    unsigned int ischild:1;
+
     /* Provider side data */
     void *provctx;
+    const OSSL_DISPATCH *dispatch;
 };
 DEFINE_STACK_OF(OSSL_PROVIDER)
 
@@ -234,8 +239,13 @@ OSSL_PROVIDER *ossl_provider_find(OSSL_LIB_CTX *libctx, const char *name,
          * Make sure any providers are loaded from config before we try to find
          * them.
          */
-        if (!noconfig && ossl_lib_ctx_is_default(libctx))
-            OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL);
+        if (!noconfig) {
+            if (ossl_lib_ctx_is_default(libctx))
+                OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL);
+            if (ossl_lib_ctx_is_child(libctx)
+                    && !ossl_provider_init_child_providers(libctx))
+                return NULL;
+        }
 #endif
 
         tmpl.name = (char *)name;
@@ -362,8 +372,7 @@ void ossl_provider_free(OSSL_PROVIDER *prov)
          */
         if (ref == 0) {
             if (prov->flag_initialized) {
-                if (prov->teardown != NULL)
-                    prov->teardown(prov->provctx);
+                ossl_provider_teardown(prov);
 #ifndef OPENSSL_NO_ERR
 # ifndef FIPS_MODULE
                 if (prov->error_strings != NULL) {
@@ -581,6 +590,7 @@ static int provider_init(OSSL_PROVIDER *prov, int flag_lock)
         goto end;
     }
     prov->provctx = tmp_provctx;
+    prov->dispatch = provider_dispatch;
 
     for (; provider_dispatch->function_id != 0; provider_dispatch++) {
         switch (provider_dispatch->function_id) {
@@ -845,6 +855,9 @@ int ossl_provider_doall_activated(OSSL_LIB_CTX *ctx,
      */
     if (ossl_lib_ctx_is_default(ctx))
         OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL);
+    if (ossl_lib_ctx_is_child(ctx)
+            && !ossl_provider_init_child_providers(ctx))
+        return 0;
 #endif
 
     if (store == NULL)
@@ -990,6 +1003,14 @@ void *ossl_provider_prov_ctx(const OSSL_PROVIDER *prov)
     return NULL;
 }
 
+const OSSL_DISPATCH *ossl_provider_get0_dispatch(const OSSL_PROVIDER *prov)
+{
+    if (prov != NULL)
+        return prov->dispatch;
+
+    return NULL;
+}
+
 OSSL_LIB_CTX *ossl_provider_libctx(const OSSL_PROVIDER *prov)
 {
     return prov != NULL ? prov->libctx : NULL;
@@ -998,7 +1019,7 @@ OSSL_LIB_CTX *ossl_provider_libctx(const OSSL_PROVIDER *prov)
 /* Wrappers around calls to the provider */
 void ossl_provider_teardown(const OSSL_PROVIDER *prov)
 {
-    if (prov->teardown != NULL)
+    if (prov->teardown != NULL && !prov->ischild)
         prov->teardown(prov->provctx);
 }
 
@@ -1133,6 +1154,11 @@ int ossl_provider_test_operation_bit(OSSL_PROVIDER *provider, size_t bitnum,
     return 1;
 }
 
+void ossl_provider_set_child(OSSL_PROVIDER *prov)
+{
+    prov->ischild = 1;
+}
+
 /*-
  * Core functions for the provider
  * ===============================
@@ -1350,7 +1376,15 @@ static const OSSL_DISPATCH core_dispatch_[] = {
     { OSSL_FUNC_CRYPTO_SECURE_ALLOCATED,
         (void (*)(void))CRYPTO_secure_allocated },
     { OSSL_FUNC_OPENSSL_CLEANSE, (void (*)(void))OPENSSL_cleanse },
-
+#ifndef FIPS_MODULE
+    { OSSL_FUNC_CORE_PROVIDER_DO_ALL, (void (*)(void))OSSL_PROVIDER_do_all },
+    { OSSL_FUNC_CORE_PROVIDER_NAME,
+        (void (*)(void))OSSL_PROVIDER_name },
+    { OSSL_FUNC_CORE_PROVIDER_GET0_PROVIDER_CTX,
+        (void (*)(void))OSSL_PROVIDER_get0_provider_ctx },
+    { OSSL_FUNC_CORE_PROVIDER_GET0_DISPATCH,
+        (void (*)(void))OSSL_PROVIDER_get0_dispatch },
+#endif
     { 0, NULL }
 };
 static const OSSL_DISPATCH *core_dispatch = core_dispatch_;
index 9796c8575c6dd06f24f43cc3b3522a62dced0db9..1af8e53d7b42bf7fda3179d6588671eb54d02560 100644 (file)
@@ -14,7 +14,8 @@ OSSL_LIB_CTX_set0_default
  typedef struct ossl_lib_ctx_st OSSL_LIB_CTX;
 
  OSSL_LIB_CTX *OSSL_LIB_CTX_new(void);
- OSSL_LIB_CTX *OSSL_LIB_CTX_new_from_dispatch(const OSSL_DISPATCH *in);
+ OSSL_LIB_CTX *OSSL_LIB_CTX_new_from_dispatch(const OSSL_CORE_HANDLE *handle,
+                                              const OSSL_DISPATCH *in);
  int OSSL_LIB_CTX_load_config(OSSL_LIB_CTX *ctx, const char *config_file);
  void OSSL_LIB_CTX_free(OSSL_LIB_CTX *ctx);
  OSSL_LIB_CTX *OSSL_LIB_CTX_get0_global_default(void);
@@ -36,10 +37,11 @@ OSSL_LIB_CTX_new() creates a new OpenSSL library context.
 
 OSSL_LIB_CTX_new_from_dispatch() creates a new OpenSSL library context
 initialised to use callbacks from the OSSL_DISPATCH structure. This is primarily
-useful for provider authors. The dispatch structure passed should be the same
-one as passed to a provider's OSSL_provider_init function in the I<in> argument.
-Some OpenSSL functions, such as L<BIO_new_from_core_bio(3)>, require the library
-context to be created in this way in order to work.
+useful for provider authors. The I<handle> and dispatch structure arguments
+passed should be the same ones as passed to a provider's
+OSSL_provider_init function. Some OpenSSL functions, such as
+L<BIO_new_from_core_bio(3)>, require the library context to be created in this
+way in order to work.
 
 OSSL_LIB_CTX_load_config() loads a configuration file using the given C<ctx>.
 This can be used to associate a library context with providers that are loaded
index 68b3943679f29c1d22f7ef7ee5679e06fcad1acc..091b4b2d04c97cf497a58300329be12dec7a22dc 100644 (file)
@@ -64,5 +64,6 @@ char *ossl_algorithm_get1_first_name(const OSSL_ALGORITHM *algo);
 __owur int ossl_lib_ctx_write_lock(OSSL_LIB_CTX *ctx);
 __owur int ossl_lib_ctx_read_lock(OSSL_LIB_CTX *ctx);
 int ossl_lib_ctx_unlock(OSSL_LIB_CTX *ctx);
+int ossl_lib_ctx_is_child(OSSL_LIB_CTX *ctx);
 
 #endif
index 94d93abda2d1672c26012e1a474bb21d4699edf8..9245a0b8700a6a021007a87caccce8759de3ccda 100644 (file)
@@ -165,7 +165,8 @@ typedef struct ossl_ex_data_global_st {
 # define OSSL_LIB_CTX_STORE_LOADER_STORE_INDEX      15
 # define OSSL_LIB_CTX_PROVIDER_CONF_INDEX           16
 # define OSSL_LIB_CTX_BIO_CORE_INDEX                17
-# define OSSL_LIB_CTX_MAX_INDEXES                   18
+# define OSSL_LIB_CTX_CHILD_PROVIDER_INDEX          18
+# define OSSL_LIB_CTX_MAX_INDEXES                   19
 
 # define OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY       0
 # define OSSL_LIB_CTX_METHOD_HIGH_PRIORITY          1
index 64fe2f11786c8e8440dc3f5f431cf647cc074f25..13b72ad2dec98c1891b96ddd12e0b6ff28b794f9 100644 (file)
@@ -41,6 +41,7 @@ int ossl_provider_set_fallback(OSSL_PROVIDER *prov);
 int ossl_provider_set_module_path(OSSL_PROVIDER *prov, const char *module_path);
 int ossl_provider_add_parameter(OSSL_PROVIDER *prov, const char *name,
                                 const char *value);
+void ossl_provider_set_child(OSSL_PROVIDER *prov);
 
 /* Disable fallback loading */
 int ossl_provider_disable_fallback_loading(OSSL_LIB_CTX *libctx);
@@ -69,6 +70,7 @@ const DSO *ossl_provider_dso(const OSSL_PROVIDER *prov);
 const char *ossl_provider_module_name(const OSSL_PROVIDER *prov);
 const char *ossl_provider_module_path(const OSSL_PROVIDER *prov);
 void *ossl_provider_prov_ctx(const OSSL_PROVIDER *prov);
+const OSSL_DISPATCH *ossl_provider_get0_dispatch(const OSSL_PROVIDER *prov);
 OSSL_LIB_CTX *ossl_provider_libctx(const OSSL_PROVIDER *prov);
 
 /* Thin wrappers around calls to the provider */
@@ -96,6 +98,12 @@ int ossl_provider_clear_all_operation_bits(OSSL_LIB_CTX *libctx);
 /* Configuration */
 void ossl_provider_add_conf_module(void);
 
+/* Child providers */
+int ossl_provider_init_child_providers(OSSL_LIB_CTX *ctx);
+int ossl_provider_init_as_child(OSSL_LIB_CTX *ctx,
+                                const OSSL_CORE_HANDLE *handle,
+                                const OSSL_DISPATCH *in);
+
 # ifdef __cplusplus
 }
 # endif
index 3356ef20884335db093610d3fd9b27ae8428d68b..71e860f99debb7f71c933d8010e67f9088a44c28 100644 (file)
@@ -30,6 +30,7 @@ extern "C" {
 typedef struct ossl_core_handle_st OSSL_CORE_HANDLE;
 typedef struct openssl_core_ctx_st OPENSSL_CORE_CTX;
 typedef struct ossl_core_bio_st OSSL_CORE_BIO;
+typedef struct ossl_core_provider_st OSSL_CORE_PROVIDER;
 
 /*
  * Dispatch table element.  function_id numbers and the functions are defined
index d088a66f30794cce20ab2e6f801ba429712e53b5..6b5e2e29359286a9fce0c6f3ffdcd183238f1973 100644 (file)
@@ -183,6 +183,23 @@ OSSL_CORE_MAKE_FUNC(size_t, get_nonce, (const OSSL_CORE_HANDLE *handle,
 OSSL_CORE_MAKE_FUNC(void, cleanup_nonce, (const OSSL_CORE_HANDLE *handle,
                                           unsigned char *buf, size_t len))
 
+/* Functions to access the core's providers */
+#define OSSL_FUNC_CORE_PROVIDER_DO_ALL            105
+#define OSSL_FUNC_CORE_PROVIDER_NAME              106
+#define OSSL_FUNC_CORE_PROVIDER_GET0_PROVIDER_CTX 107
+#define OSSL_FUNC_CORE_PROVIDER_GET0_DISPATCH     108
+
+OSSL_CORE_MAKE_FUNC(int, core_provider_do_all, (const OPENSSL_CORE_CTX *ctx,
+                                                int (*cb)(OSSL_CORE_PROVIDER *provider,
+                                                          void *cbdata),
+                                                void *cbdata))
+OSSL_CORE_MAKE_FUNC(const char *, core_provider_name,
+                    (const OSSL_CORE_PROVIDER *prov))
+OSSL_CORE_MAKE_FUNC(void *, core_provider_get0_provider_ctx,
+                    (const OSSL_CORE_PROVIDER *prov))
+OSSL_CORE_MAKE_FUNC(const OSSL_DISPATCH *, core_provider_get0_dispatch,
+                    (const OSSL_CORE_PROVIDER *prov))
+
 /* Functions provided by the provider to the Core, reserved numbers 1024-1535 */
 # define OSSL_FUNC_PROVIDER_TEARDOWN           1024
 OSSL_CORE_MAKE_FUNC(void,provider_teardown,(void *provctx))
index e868172acc4dddd4a04d18f968ab8c936d1951d0..724e2ca5da792a70cdbbebb046604af89a4862e9 100644 (file)
@@ -37,6 +37,7 @@ use OpenSSL::stackhash qw(generate_stack_macros);
 # include <openssl/types.h>
 # include <openssl/opensslconf.h>
 # include <openssl/cryptoerr.h>
+# include <openssl/core.h>
 
 # ifdef CHARSET_EBCDIC
 #  include <openssl/ebcdic.h>
@@ -517,7 +518,10 @@ CRYPTO_THREAD_ID CRYPTO_THREAD_get_current_id(void);
 int CRYPTO_THREAD_compare_id(CRYPTO_THREAD_ID a, CRYPTO_THREAD_ID b);
 
 OSSL_LIB_CTX *OSSL_LIB_CTX_new(void);
-OSSL_LIB_CTX *OSSL_LIB_CTX_new_from_dispatch(const OSSL_DISPATCH *in);
+OSSL_LIB_CTX *OSSL_LIB_CTX_new_from_dispatch(const OSSL_CORE_HANDLE *handle,
+                                             const OSSL_DISPATCH *in);
+OSSL_LIB_CTX *OSSL_LIB_CTX_new_child(const OSSL_CORE_HANDLE *handle,
+                                     const OSSL_DISPATCH *in);
 int OSSL_LIB_CTX_load_config(OSSL_LIB_CTX *ctx, const char *config_file);
 void OSSL_LIB_CTX_free(OSSL_LIB_CTX *);
 OSSL_LIB_CTX *OSSL_LIB_CTX_get0_global_default(void);
index 56b430710ffdf3e24540899cd5feb6459a1fe1f2..e66d5324af7d86d2cc2e893f9e90a9bad7e262ce 100644 (file)
@@ -44,6 +44,7 @@ const OSSL_ALGORITHM *OSSL_PROVIDER_query_operation(const OSSL_PROVIDER *prov,
 void OSSL_PROVIDER_unquery_operation(const OSSL_PROVIDER *prov,
                                      int operation_id, const OSSL_ALGORITHM *algs);
 void *OSSL_PROVIDER_get0_provider_ctx(const OSSL_PROVIDER *prov);
+const OSSL_DISPATCH *OSSL_PROVIDER_get0_dispatch(const OSSL_PROVIDER *prov);
 
 /* Add a built in providers */
 int OSSL_PROVIDER_add_builtin(OSSL_LIB_CTX *, const char *name,
index 9ec8af9b8f3f9a90efa801d35a05c79e144380b3..ae326cef9290a4c1ab5c414b6294d06cb78f0459 100644 (file)
@@ -55,7 +55,7 @@ static const OSSL_DISPATCH biocbs[] = {
 static int test_bio_core(void)
 {
     BIO *cbio = NULL, *cbiobad = NULL;
-    OSSL_LIB_CTX *libctx = OSSL_LIB_CTX_new_from_dispatch(biocbs);
+    OSSL_LIB_CTX *libctx = OSSL_LIB_CTX_new_from_dispatch(NULL, biocbs);
     int testresult = 0;
     OSSL_CORE_BIO corebio;
     const char *msg = "Hello world";
index 1820baf4adcd1b36ecd823d7edf8aa741fce12ec..a99b5aa047bfdc25c50fb9c147724d1cdda1016d 100644 (file)
@@ -5402,3 +5402,5 @@ BIO_new_from_core_bio                   ? 3_0_0   EXIST::FUNCTION:
 BIO_new_ex                              ?      3_0_0   EXIST::FUNCTION:
 BIO_s_core                              ?      3_0_0   EXIST::FUNCTION:
 OSSL_LIB_CTX_new_from_dispatch          ?      3_0_0   EXIST::FUNCTION:
+OSSL_LIB_CTX_new_child                  ?      3_0_0   EXIST::FUNCTION:
+OSSL_PROVIDER_get0_dispatch             ?      3_0_0   EXIST::FUNCTION: