From: Matt Caswell Date: Fri, 6 Feb 2026 14:57:43 +0000 (+0000) Subject: Pass low level DSA objects to the default provider X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cec26b39c3275c93c1e13e2ae112b0ce940f7577;p=thirdparty%2Fopenssl.git Pass low level DSA objects to the default provider As we did for RSA objects we do the same for DSA objects. Reviewed-by: Shane Lontis Reviewed-by: Tomas Mraz MergeDate: Fri Feb 13 07:58:23 2026 (Merged from https://github.com/openssl/openssl/pull/29960) --- diff --git a/crypto/dsa/dsa_lib.c b/crypto/dsa/dsa_lib.c index 01d5d8e3c1a..7b7c3f7e2ef 100644 --- a/crypto/dsa/dsa_lib.c +++ b/crypto/dsa/dsa_lib.c @@ -223,6 +223,11 @@ int DSA_up_ref(DSA *r) return ((i > 1) ? 1 : 0); } +OSSL_LIB_CTX *ossl_dsa_get0_libctx(const DSA *d) +{ + return d->libctx; +} + void ossl_dsa_set0_libctx(DSA *d, OSSL_LIB_CTX *libctx) { d->libctx = libctx; diff --git a/include/crypto/dsa.h b/include/crypto/dsa.h index 73a61e7a88b..fa571a610b7 100644 --- a/include/crypto/dsa.h +++ b/include/crypto/dsa.h @@ -25,6 +25,7 @@ #define DSA_PARAMGEN_TYPE_FIPS_DEFAULT 2 DSA *ossl_dsa_new(OSSL_LIB_CTX *libctx); +OSSL_LIB_CTX *ossl_dsa_get0_libctx(const DSA *d); void ossl_dsa_set0_libctx(DSA *d, OSSL_LIB_CTX *libctx); int ossl_dsa_generate_ffc_parameters(DSA *dsa, int type, int pbits, int qbits, diff --git a/providers/implementations/keymgmt/dsa_kmgmt.c b/providers/implementations/keymgmt/dsa_kmgmt.c index b3cc76a89dd..d2d4abf105a 100644 --- a/providers/implementations/keymgmt/dsa_kmgmt.c +++ b/providers/implementations/keymgmt/dsa_kmgmt.c @@ -26,6 +26,7 @@ #include "internal/sizes.h" #include "internal/nelem.h" #include "internal/param_build_set.h" +#include "internal/threads_common.h" static OSSL_FUNC_keymgmt_new_fn dsa_newdata; static OSSL_FUNC_keymgmt_free_fn dsa_freedata; @@ -121,9 +122,33 @@ static int dsa_key_todata(DSA *dsa, OSSL_PARAM_BLD *bld, OSSL_PARAM *pubkey, static void *dsa_newdata(void *provctx) { + DSA *dsa = NULL; + OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx); + if (!ossl_prov_is_running()) return NULL; - return ossl_dsa_new(PROV_LIBCTX_OF(provctx)); + +#ifndef FIPS_MODULE + /* + * This only works because we are in the default provider. We are not + * normally allowed to pass complex objects across the provider boundary + * like this. + */ + dsa = CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_LOW_LEVEL_OBJECT, libctx); + if (dsa != NULL) { + if (ossl_lib_ctx_get_concrete(ossl_dsa_get0_libctx(dsa)) != ossl_lib_ctx_get_concrete(libctx)) + dsa = NULL; + else if (!DSA_up_ref(dsa)) + return NULL; + } + if (dsa != NULL && !DSA_up_ref(dsa)) + return NULL; +#endif + + if (dsa == NULL) + dsa = ossl_dsa_new(libctx); + + return dsa; } static void dsa_freedata(void *keydata)