diff -up openssl-3.0.0/crypto/provider_conf.c.fips-force openssl-3.0.0/crypto/provider_conf.c --- openssl-3.0.0/crypto/provider_conf.c.fips-force 2021-11-12 14:21:01.878339467 +0100 +++ openssl-3.0.0/crypto/provider_conf.c 2021-11-12 16:13:19.301542866 +0100 @@ -136,13 +136,73 @@ static int prov_already_activated(const return 0; } +static int provider_conf_activate(OSSL_LIB_CTX *libctx, PROVIDER_CONF_GLOBAL *pcgbl, + const char *name, const char *value, const char *path, + int soft, const CONF *cnf) +{ + int ok = 0; + OSSL_PROVIDER *prov = NULL, *actual = NULL; + + if (!CRYPTO_THREAD_write_lock(pcgbl->lock)) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + return 0; + } + if (!prov_already_activated(name, pcgbl->activated_providers)) { + /* + * There is an attempt to activate a provider, so we should disable + * loading of fallbacks. Otherwise a misconfiguration could mean the + * intended provider does not get loaded. Subsequent fetches could + * then fallback to the default provider - which may be the wrong + * thing. + */ + if (!ossl_provider_disable_fallback_loading(libctx)) { + CRYPTO_THREAD_unlock(pcgbl->lock); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + return 0; + } + prov = ossl_provider_find(libctx, name, 1); + if (prov == NULL) + prov = ossl_provider_new(libctx, name, NULL, 1); + if (prov == NULL) { + CRYPTO_THREAD_unlock(pcgbl->lock); + if (soft) + ERR_clear_error(); + return 0; + } + + if (path != NULL) + ossl_provider_set_module_path(prov, path); + + ok = cnf ? provider_conf_params(prov, NULL, NULL, value, cnf) : 1; + + if (ok) { + if (!ossl_provider_activate(prov, 1, 0)) { + ok = 0; + } else if (!ossl_provider_add_to_store(prov, &actual, 0)) { + ossl_provider_deactivate(prov); + ok = 0; + } else { + if (pcgbl->activated_providers == NULL) + pcgbl->activated_providers = sk_OSSL_PROVIDER_new_null(); + sk_OSSL_PROVIDER_push(pcgbl->activated_providers, actual); + ok = 1; + } + } + if (!ok) + ossl_provider_free(prov); + } + CRYPTO_THREAD_unlock(pcgbl->lock); + return ok; +} + + + static int provider_conf_load(OSSL_LIB_CTX *libctx, const char *name, const char *value, const CONF *cnf) { int i; STACK_OF(CONF_VALUE) *ecmds; int soft = 0; - OSSL_PROVIDER *prov = NULL, *actual = NULL; const char *path = NULL; long activate = 0; int ok = 0; @@ -185,55 +245,7 @@ static int provider_conf_load(OSSL_LIB_C } if (activate) { - if (!CRYPTO_THREAD_write_lock(pcgbl->lock)) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); - return 0; - } - if (!prov_already_activated(name, pcgbl->activated_providers)) { - /* - * There is an attempt to activate a provider, so we should disable - * loading of fallbacks. Otherwise a misconfiguration could mean the - * intended provider does not get loaded. Subsequent fetches could - * then fallback to the default provider - which may be the wrong - * thing. - */ - if (!ossl_provider_disable_fallback_loading(libctx)) { - CRYPTO_THREAD_unlock(pcgbl->lock); - ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); - return 0; - } - prov = ossl_provider_find(libctx, name, 1); - if (prov == NULL) - prov = ossl_provider_new(libctx, name, NULL, 1); - if (prov == NULL) { - CRYPTO_THREAD_unlock(pcgbl->lock); - if (soft) - ERR_clear_error(); - return 0; - } - - if (path != NULL) - ossl_provider_set_module_path(prov, path); - - ok = provider_conf_params(prov, NULL, NULL, value, cnf); - - if (ok) { - if (!ossl_provider_activate(prov, 1, 0)) { - ok = 0; - } else if (!ossl_provider_add_to_store(prov, &actual, 0)) { - ossl_provider_deactivate(prov); - ok = 0; - } else { - if (pcgbl->activated_providers == NULL) - pcgbl->activated_providers = sk_OSSL_PROVIDER_new_null(); - sk_OSSL_PROVIDER_push(pcgbl->activated_providers, actual); - ok = 1; - } - } - if (!ok) - ossl_provider_free(prov); - } - CRYPTO_THREAD_unlock(pcgbl->lock); + ok = provider_conf_activate(libctx, pcgbl, name, value, path, soft, cnf); } else { OSSL_PROVIDER_INFO entry; @@ -294,6 +306,19 @@ static int provider_conf_init(CONF_IMODU return 0; } + if (ossl_get_kernel_fips_flag() != 0) { /* XXX from provider_conf_load */ + OSSL_LIB_CTX *libctx = NCONF_get0_libctx((CONF *)cnf); + PROVIDER_CONF_GLOBAL *pcgbl + = ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_PROVIDER_CONF_INDEX, + &provider_conf_ossl_ctx_method); + if (provider_conf_activate(libctx, pcgbl, "fips", NULL, NULL, 0, NULL) != 1) + return 0; + if (provider_conf_activate(libctx, pcgbl, "base", NULL, NULL, 0, NULL) != 1) + return 0; + if (EVP_default_properties_enable_fips(libctx, 1) != 1) + return 0; + } + return 1; }