From 78906fff4a6cfd5857045df770b47ae9ebcf0766 Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Tue, 12 May 2020 09:02:25 +0200 Subject: [PATCH] PROV: Adapt all our providers to use the new PROV_CTX structure Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/11803) --- crypto/property/build.info | 1 + providers/common/build.info | 2 +- providers/defltprov.c | 19 ++++++++++++++++--- providers/fips/fipsprov.c | 38 ++++++++++++++++++++++++++----------- providers/legacyprov.c | 24 +++++++++++++++++------ 5 files changed, 63 insertions(+), 21 deletions(-) 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/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; } -- 2.25.1