diff --git a/openssl.go b/openssl.go index fb4b65b..23e4530 100644 --- a/openssl.go +++ b/openssl.go @@ -169,20 +169,23 @@ func SetFIPS(enabled bool) error { } else { provName = providerNameDefault } - // Check if there is any provider that matches props. - if C.go_openssl_OSSL_PROVIDER_available(nil, provName) != 1 { - // If not, fallback to provName provider. - if C.go_openssl_OSSL_PROVIDER_load(nil, provName) == nil { - return newOpenSSLError("OSSL_PROVIDER_try_load") - } - // Make sure we now have a provider available. - if C.go_openssl_OSSL_PROVIDER_available(nil, provName) != 1 { - return fail("SetFIPS(" + strconv.FormatBool(enabled) + ") not supported") - } - } + // Try to load the provider, but don't fail if it's not loaded. + // The built-in provides might not be present in the system, e.g. because + // third-party providers are being used or because the system is not well-configured. + C.go_openssl_OSSL_PROVIDER_try_load(nil, provName, 1) + C.go_openssl_ERR_clear_error() + + // Enable FIPS mode in the default properties. if C.go_openssl_EVP_default_properties_enable_fips(nil, mode) != 1 { - return newOpenSSLError("openssl: EVP_default_properties_enable_fips") + return newOpenSSLError("EVP_default_properties_enable_fips") } + + // See FIPS() for the rationale behind this check. + md := C.go_openssl_EVP_MD_fetch(nil, algorithmSHA256, nil) + if md == nil { + return newOpenSSLError("openssl: EVP_MD_fetch") + } + C.go_openssl_EVP_MD_free(md) return nil default: panic(errUnsupportedVersion()) diff --git a/shims.h b/shims.h index 2370b6c..20b55f8 100644 --- a/shims.h +++ b/shims.h @@ -172,6 +172,7 @@ typedef void* GO_SHA_CTX_PTR; // #endif #define FOR_ALL_OPENSSL_FUNCTIONS \ DEFINEFUNC(void, ERR_error_string_n, (unsigned long e, char *buf, size_t len), (e, buf, len)) \ +DEFINEFUNC(void, ERR_clear_error, (void), ()) \ DEFINEFUNC_LEGACY_1(unsigned long, ERR_get_error_line, (const char **file, int *line), (file, line)) \ DEFINEFUNC_3_0(unsigned long, ERR_get_error_all, (const char **file, int *line, const char **func, const char **data, int *flags), (file, line, func, data, flags)) \ DEFINEFUNC_RENAMED_1_1(const char *, OpenSSL_version, SSLeay_version, (int type), (type)) \ @@ -194,7 +195,7 @@ DEFINEFUNC_LEGACY_1(int, FIPS_mode_set, (int r), (r)) \ DEFINEFUNC_3_0(int, EVP_default_properties_is_fips_enabled, (GO_OSSL_LIB_CTX_PTR libctx), (libctx)) \ DEFINEFUNC_3_0(int, EVP_default_properties_enable_fips, (GO_OSSL_LIB_CTX_PTR libctx, int enable), (libctx, enable)) \ DEFINEFUNC_3_0(int, OSSL_PROVIDER_available, (GO_OSSL_LIB_CTX_PTR libctx, const char *name), (libctx, name)) \ -DEFINEFUNC_3_0(GO_OSSL_PROVIDER_PTR, OSSL_PROVIDER_load, (GO_OSSL_LIB_CTX_PTR libctx, const char *name), (libctx, name)) \ +DEFINEFUNC_3_0(GO_OSSL_PROVIDER_PTR, OSSL_PROVIDER_try_load, (GO_OSSL_LIB_CTX_PTR libctx, const char *name, int retain_fallbacks), (libctx, name, retain_fallbacks)) \ DEFINEFUNC_3_0(const char *, OSSL_PROVIDER_get0_name, (const GO_OSSL_PROVIDER_PTR prov), (prov)) \ DEFINEFUNC_3_0(GO_EVP_MD_PTR, EVP_MD_fetch, (GO_OSSL_LIB_CTX_PTR ctx, const char *algorithm, const char *properties), (ctx, algorithm, properties)) \ DEFINEFUNC_3_0(void, EVP_MD_free, (GO_EVP_MD_PTR md), (md)) \