[openssl] master update

Matt Caswell matt at openssl.org
Wed May 13 16:29:36 UTC 2020


The branch master has been updated
       via  78906fff4a6cfd5857045df770b47ae9ebcf0766 (commit)
       via  05aa8790ac1ef2bb39c15ae241a591704664039c (commit)
      from  484c24c8d7318cc36f9b3c2b7b55cf5ac91619ca (commit)


- Log -----------------------------------------------------------------
commit 78906fff4a6cfd5857045df770b47ae9ebcf0766
Author: Richard Levitte <levitte at openssl.org>
Date:   Tue May 12 09:02:25 2020 +0200

    PROV: Adapt all our providers to use the new PROV_CTX structure
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/11803)

commit 05aa8790ac1ef2bb39c15ae241a591704664039c
Author: Richard Levitte <levitte at openssl.org>
Date:   Tue May 12 08:46:23 2020 +0200

    PROV: Add a proper provider context structure for OpenSSL providers
    
    The provider context structure is made to include the following information:
    
    - The core provider handle (first argument to the provider init
      function).  This handle is meant to be used in all upcalls that need
      it.
    
    - A library context, used for any libcrypto calls that need it, done in
      the provider itself.
    
    Regarding the library context, that's generally only needed if the
    provider makes any libcrypto calls, i.e. is linked with libcrypto.  That
    happens to be the case for all OpenSSL providers, but is applicable for
    other providers that use libcrypto internally as well.
    
    The normal thing to do for a provider init function is to create its own
    library context.  For a provider that's meant to become a dynamically
    loadable module, this is what MUST be done.
    However, we do not do that in the default provider; it uses the library
    context associated with the core provider handle instead.  This is
    permissible, although generally discouraged, as long as the provider in
    question is guaranteed to be built-in, into libcrypto or into the
    application that uses it.
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/11803)

-----------------------------------------------------------------------

Summary of changes:
 crypto/property/build.info                   |  1 +
 providers/common/build.info                  |  2 +-
 providers/common/include/prov/provider_ctx.h | 18 ++++++++++-
 providers/common/provider_ctx.c              | 48 ++++++++++++++++++++++++++++
 providers/defltprov.c                        | 19 +++++++++--
 providers/fips/fipsprov.c                    | 38 +++++++++++++++-------
 providers/legacyprov.c                       | 24 ++++++++++----
 7 files changed, 128 insertions(+), 22 deletions(-)
 create mode 100644 providers/common/provider_ctx.c

diff --git a/crypto/property/build.info b/crypto/property/build.info
index bfa1f0602f..56f26760c6 100644
--- a/crypto/property/build.info
+++ b/crypto/property/build.info
@@ -2,3 +2,4 @@ LIBS=../../libcrypto
 $COMMON=property_string.c property_parse.c property.c defn_cache.c
 SOURCE[../../libcrypto]=$COMMON property_err.c
 SOURCE[../../providers/libfips.a]=$COMMON
+SOURCE[../../providers/liblegacy.a]=$COMMON
diff --git a/providers/common/build.info b/providers/common/build.info
index b6495d343a..c49b090227 100644
--- a/providers/common/build.info
+++ b/providers/common/build.info
@@ -1,6 +1,6 @@
 SUBDIRS=der
 
-SOURCE[../libcommon.a]=provider_err.c bio_prov.c
+SOURCE[../libcommon.a]=provider_err.c bio_prov.c provider_ctx.c
 $FIPSCOMMON=provider_util.c
 SOURCE[../libnonfips.a]=$FIPSCOMMON nid_to_name.c
 SOURCE[../libfips.a]=$FIPSCOMMON
diff --git a/providers/common/include/prov/provider_ctx.h b/providers/common/include/prov/provider_ctx.h
index 365667d19e..0984f13635 100644
--- a/providers/common/include/prov/provider_ctx.h
+++ b/providers/common/include/prov/provider_ctx.h
@@ -7,8 +7,24 @@
  * https://www.openssl.org/source/license.html
  */
 
+#include <openssl/types.h>
+#include <openssl/crypto.h>
+
+typedef struct prov_ctx_st {
+    const OSSL_PROVIDER *provider;
+    OPENSSL_CTX *libctx;         /* For all provider modules */
+} PROV_CTX;
+
 /*
  * To be used anywhere the library context needs to be passed, such as to
  * fetching functions.
  */
-#define PROV_LIBRARY_CONTEXT_OF(provctx)        (provctx)
+#define PROV_LIBRARY_CONTEXT_OF(provctx)        \
+    PROV_CTX_get0_library_context((provctx))
+
+PROV_CTX *PROV_CTX_new(void);
+void PROV_CTX_free(PROV_CTX *ctx);
+void PROV_CTX_set0_library_context(PROV_CTX *ctx, OPENSSL_CTX *libctx);
+void PROV_CTX_set0_provider(PROV_CTX *ctx, const OSSL_PROVIDER *libctx);
+OPENSSL_CTX *PROV_CTX_get0_library_context(PROV_CTX *ctx);
+const OSSL_PROVIDER *PROV_CTX_get0_provider(PROV_CTX *ctx);
diff --git a/providers/common/provider_ctx.c b/providers/common/provider_ctx.c
new file mode 100644
index 0000000000..66c7c74890
--- /dev/null
+++ b/providers/common/provider_ctx.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdlib.h>
+#include "prov/provider_ctx.h"
+
+PROV_CTX *PROV_CTX_new(void)
+{
+    return OPENSSL_zalloc(sizeof(PROV_CTX));
+}
+
+void PROV_CTX_free(PROV_CTX *ctx)
+{
+    OPENSSL_free(ctx);
+}
+
+void PROV_CTX_set0_library_context(PROV_CTX *ctx, OPENSSL_CTX *libctx)
+{
+    if (ctx != NULL)
+        ctx->libctx = libctx;
+}
+
+void PROV_CTX_set0_provider(PROV_CTX *ctx, const OSSL_PROVIDER *provider)
+{
+    if (ctx != NULL)
+        ctx->provider = provider;
+}
+
+
+OPENSSL_CTX *PROV_CTX_get0_library_context(PROV_CTX *ctx)
+{
+    if (ctx == NULL)
+        return NULL;
+    return ctx->libctx;
+}
+
+const OSSL_PROVIDER *PROV_CTX_get0_provider(PROV_CTX *ctx)
+{
+    if (ctx == NULL)
+        return NULL;
+    return ctx->provider;
+}
diff --git a/providers/defltprov.c b/providers/defltprov.c
index baea34ac04..5667825072 100644
--- a/providers/defltprov.c
+++ b/providers/defltprov.c
@@ -537,8 +537,14 @@ static const OSSL_ALGORITHM *deflt_query(void *provctx, int operation_id,
     return NULL;
 }
 
+static void deflt_teardown(void *provctx)
+{
+    PROV_CTX_free(provctx);
+}
+
 /* Functions we provide to the core */
 static const OSSL_DISPATCH deflt_dispatch_table[] = {
+    { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))deflt_teardown },
     { OSSL_FUNC_PROVIDER_GETTABLE_PARAMS, (void (*)(void))deflt_gettable_params },
     { OSSL_FUNC_PROVIDER_GET_PARAMS, (void (*)(void))deflt_get_params },
     { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))deflt_query },
@@ -576,13 +582,20 @@ int ossl_default_provider_init(const OSSL_PROVIDER *provider,
     if (c_get_libctx == NULL)
         return 0;
 
-    *out = deflt_dispatch_table;
-
     /*
      * We want to make sure that all calls from this provider that requires
      * a library context use the same context as the one used to call our
      * functions.  We do that by passing it along as the provider context.
+     *
+     * This is special for built-in providers.  External providers should
+     * create their own library context.
      */
-    *provctx = c_get_libctx(provider);
+    if ((*provctx = PROV_CTX_new()) == NULL)
+        return 0;
+    PROV_CTX_set0_library_context(*provctx, c_get_libctx(provider));
+    PROV_CTX_set0_provider(*provctx, provider);
+
+    *out = deflt_dispatch_table;
+
     return 1;
 }
diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c
index 1ed475e1f5..ac92b7885f 100644
--- a/providers/fips/fipsprov.c
+++ b/providers/fips/fipsprov.c
@@ -516,6 +516,16 @@ static const OSSL_ALGORITHM *fips_query(void *provctx, int operation_id,
 static void fips_teardown(void *provctx)
 {
     OPENSSL_CTX_free(PROV_LIBRARY_CONTEXT_OF(provctx));
+    PROV_CTX_free(provctx);
+}
+
+static void fips_intern_teardown(void *provctx)
+{
+    /*
+     * We know that the library context is the same as for the outer provider,
+     * so no need to destroy it here.
+     */
+    PROV_CTX_free(provctx);
 }
 
 /* Functions we provide to the core */
@@ -529,6 +539,7 @@ static const OSSL_DISPATCH fips_dispatch_table[] = {
 
 /* Functions we provide to ourself */
 static const OSSL_DISPATCH intern_dispatch_table[] = {
+    { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))fips_intern_teardown },
     { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))fips_query },
     { 0, NULL }
 };
@@ -540,7 +551,7 @@ int OSSL_provider_init(const OSSL_PROVIDER *provider,
                        void **provctx)
 {
     FIPS_GLOBAL *fgbl;
-    OPENSSL_CTX *libctx;
+    OPENSSL_CTX *libctx = NULL;
     OSSL_self_test_cb_fn *stcbfn = NULL;
     OSSL_core_get_library_context_fn *c_get_libctx = NULL;
 
@@ -647,9 +658,18 @@ int OSSL_provider_init(const OSSL_PROVIDER *provider,
         return 0;
 
     /*  Create a context. */
-    if ((libctx = OPENSSL_CTX_new()) == NULL)
-        return 0;
-    *provctx = libctx;
+    if ((*provctx = PROV_CTX_new()) == NULL
+        || (libctx = OPENSSL_CTX_new()) == NULL) {
+        /*
+         * We free libctx separately here and only here because it hasn't
+         * been attached to *provctx.  All other error paths below rely
+         * solely on fips_teardown.
+         */
+        OPENSSL_CTX_free(libctx);
+        goto err;
+    }
+    PROV_CTX_set0_library_context(*provctx, libctx);
+    PROV_CTX_set0_provider(*provctx, provider);
 
     if ((fgbl = openssl_ctx_get_data(libctx, OPENSSL_CTX_FIPS_PROV_INDEX,
                                      &fips_prov_ossl_ctx_method)) == NULL)
@@ -705,14 +725,10 @@ int fips_intern_provider_init(const OSSL_PROVIDER *provider,
     if (c_get_libctx == NULL)
         return 0;
 
-    *provctx = c_get_libctx(provider);
-
-    /*
-     * Safety measure...  we should get the library context that was
-     * created up in OSSL_provider_init().
-     */
-    if (*provctx == NULL)
+    if ((*provctx = PROV_CTX_new()) == NULL)
         return 0;
+    PROV_CTX_set0_library_context(*provctx, c_get_libctx(provider));
+    PROV_CTX_set0_provider(*provctx, provider);
 
     *out = intern_dispatch_table;
     return 1;
diff --git a/providers/legacyprov.c b/providers/legacyprov.c
index 07b505a8ac..9a6ed6d836 100644
--- a/providers/legacyprov.c
+++ b/providers/legacyprov.c
@@ -155,8 +155,15 @@ static const OSSL_ALGORITHM *legacy_query(void *provctx, int operation_id,
     return NULL;
 }
 
+static void legacy_teardown(void *provctx)
+{
+    OPENSSL_CTX_free(PROV_LIBRARY_CONTEXT_OF(provctx));
+    PROV_CTX_free(provctx);
+}
+
 /* Functions we provide to the core */
 static const OSSL_DISPATCH legacy_dispatch_table[] = {
+    { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))legacy_teardown },
     { OSSL_FUNC_PROVIDER_GETTABLE_PARAMS, (void (*)(void))legacy_gettable_params },
     { OSSL_FUNC_PROVIDER_GET_PARAMS, (void (*)(void))legacy_get_params },
     { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))legacy_query },
@@ -169,6 +176,7 @@ int OSSL_provider_init(const OSSL_PROVIDER *provider,
                        void **provctx)
 {
     OSSL_core_get_library_context_fn *c_get_libctx = NULL;
+    OPENSSL_CTX *libctx = NULL;
 
     for (; in->function_id != 0; in++) {
         switch (in->function_id) {
@@ -190,13 +198,17 @@ int OSSL_provider_init(const OSSL_PROVIDER *provider,
     if (c_get_libctx == NULL)
         return 0;
 
+    if ((*provctx = PROV_CTX_new()) == NULL
+        || (libctx = OPENSSL_CTX_new()) == NULL) {
+        OPENSSL_CTX_free(libctx);
+        legacy_teardown(*provctx);
+        *provctx = NULL;
+        return 0;
+    }
+    PROV_CTX_set0_library_context(*provctx, libctx);
+    PROV_CTX_set0_provider(*provctx, provider);
+
     *out = legacy_dispatch_table;
 
-    /*
-     * We want to make sure that all calls from this provider that requires
-     * a library context use the same context as the one used to call our
-     * functions.  We do that by passing it along as the provider context.
-     */
-    *provctx = c_get_libctx(provider);
     return 1;
 }


More information about the openssl-commits mailing list