Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor SetFIPS to support third-party FIPS providers #206

Merged
merged 4 commits into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 20 additions & 11 deletions openssl.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ func VersionText() string {
var (
providerNameFips = C.CString("fips")
providerNameDefault = C.CString("default")
propFIPS = C.CString("fips=yes")

algorithmSHA256 = C.CString("SHA2-256")
)
Expand Down Expand Up @@ -169,19 +170,27 @@ 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 provider might not be present in the system.
// We don't need the built-in provider if third-party providers are being used: they are already loaded.
// If the system is not well-configured and has no FIPS capability, this will be detected by the next steps.
C.go_openssl_OSSL_PROVIDER_try_load(nil, provName, 1)
C.go_openssl_ERR_clear_error()

// See FIPS() for the rationale behind this check.
md := C.go_openssl_EVP_MD_fetch(nil, algorithmSHA256, propFIPS)
if md == nil {
// Don't enable FIPS mode if there is no provider that supports it.
// This makes it easier for callers to call SetFIPS(true) to do a
// best-effort attempt to enable FIPS mode, but not fail if it's not possible.
C.go_openssl_ERR_clear_error()
return errors.New("openssl: FIPS mode not supported by any provider")
}
C.go_openssl_EVP_MD_free(md)

// 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")
}
return nil
default:
Expand Down
3 changes: 2 additions & 1 deletion shims.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,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)) \
Expand All @@ -196,7 +197,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)) \
Expand Down
Loading