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

Undocumented dependency on specific OpenSSL version #144

Open
bdarnell opened this issue Nov 9, 2023 · 3 comments
Open

Undocumented dependency on specific OpenSSL version #144

bdarnell opened this issue Nov 9, 2023 · 3 comments

Comments

@bdarnell
Copy link

bdarnell commented Nov 9, 2023

golang-fips/openssl is flexible in its support for OpenSSL versions; the version available at runtime does not have to match the version available at build time (https://github.com/golang-fips/openssl#portable-openssl). golang-fips/go does not have this property; _goboringcrypto_DLOPEN_OPENSSL loads only the version of the library that was available at build time (

+_goboringcrypto_DLOPEN_OPENSSL(void)
) What's worse, if the shared library fails to load, this is completely silent and the crypto package falls back to the non-fips-compliant Go implementations.

Is it possible for this repo to use the same tricks as golang-fips/openssl to be version-agnostic? If not, could the failure to load the expected openssl version be a panic instead of silently falling back to the wrong crypto implementations? At the very least this hidden dependency should be documented.

FYI I ran into this moving a binary between Red Hat's ubi9 (which uses OpenSSL 3.0) and ubi8 (which uses OpenSSL 1.1).

@bdarnell
Copy link
Author

bdarnell commented Nov 9, 2023

Ah, I think I see that the version-agnostic behavior is new in v2 of the openssl package and that there are open PRs to update to that version. So it looks like that will get better soon but in the meantime some docs would be nice.

@dbenoit17
Copy link
Collaborator

Hey, that's right, currently golang-fips/go is still targeting the legacy branches of golang-fips/openssl, where the dependency version is hard-coded in the preprocessor. Though it's not totally clear yet if or how the portable openssl selection mechanism in the v2 backend will translate into the golang-fips/go fork. The bindings depend on dlopen, meaning glibc environment compatibility must also be preserved between build and deployment target. I've seen Go projects get around similar object compatibility issues by disabling CGO and linking statically but with golang-fips we can't do this without losing the ability to call into openssl. Likewise static linking with CGO enabled is also not possible because of the caveats of moving around static binaries that make use of dlopen. So copying between different base images has basically been out of scope for the golang-fips/go fork in the past, and it's still a bit of an open question going forward at this point.

That said, there is a compile time switch that will produce a panic like you mentioned. GOEXPERIMENT=strictfipsruntime, implemented in 002-strict-fips-runtime-detection.patch, will force a panic if boring.Enabled() == true and the openssl object can't be loaded.

And +1 to documentation, it's becoming clear the need for project docs in general. I can open a new issue for docs tomorrow and link this as a sub task. Feel free to leave this open until it's complete if you like!

@bdarnell
Copy link
Author

The bindings depend on dlopen, meaning glibc environment compatibility must also be preserved between build and deployment target.

True, but glibc has a pretty good compatibility story with symbol versioning. Personally I'm OK with the glibc requirement - we don't care about portability to non-glibc distributions and already have other dependencies on dlopen. But this is a good reminder that I'm not sure we've tested this issue recently.

That said, there is a compile time switch that will produce a panic like you mentioned. GOEXPERIMENT=strictfipsruntime, implemented in 002-strict-fips-runtime-detection.patch, will force a panic if boring.Enabled() == true and the openssl object can't be loaded.

Thanks, that's helpful (if a bit confusingly named - there's also GOLANG_STRICT_FIPS which activates more strictness in a different way). FWIW I'd like something that goes a little further, and also fails if you build with this toolchain but don't set /proc/sys/crypto/fips_enabled. The way I'm thinking about it is "download this build instead of the standard one, and then you'll never fall back to Go crypto" (that's how boringcrypto does it, right?). I see that you're intending this toolchain to be something you could use for a single release binary that could be FIPS or not based on the runtime configuration, which makes sense but I'm not sure we're ready to commit to using golang-fips for all our releases.

@dbenoit17 dbenoit17 mentioned this issue Nov 13, 2023
7 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants