Repository navigation
Conversation
|
Review requested:
|
|
Please note that I will be on holidays/off the grid for next week, so have patience when I'm not responding.😉 I just wanted to kick this off before leaving. |
In some cases, the CSPRNG may fail to seed properly, which currently results in assertion failure and core dump. This change will turn the behavior in a better-debuggable error report.
9fbb55f to
03d3ccf
Compare
| @@ -125,7 +125,6 @@ bool ProcessFipsOptions() { | |||
| OSSL_PROVIDER* fips_provider = OSSL_PROVIDER_load(nullptr, "fips"); | |||
| if (fips_provider == nullptr) | |||
| return false; | |||
| OSSL_PROVIDER_unload(fips_provider); | |||
There was a problem hiding this comment.
@danbev may remember why the load/unload. From the PR my read is that it was to be able to throw an error during options processing, but not have the provider loaded unless it was used.
Looking at the other branch I'm wondering if this would be consistent with what we have in the non >= section
#if OPENSSL_VERSION_MAJOR >= 3
if (!EVP_default_properties_is_fips_enabled(nullptr)) {
OSSL_PROVIDER* fips_provider = OSSL_PROVIDER_load(nullptr, "fips");
if (fips_provider == nullptr)
return false;
OSSL_PROVIDER_unload(fips_provider);
return EVP_default_properties_enable_fips(nullptr, 1) &&
EVP_default_properties_is_fips_enabled(nullptr);
}I think you mentioned to me that doing that still fails. If so, then I wonder why if FIPs is already enabled on the base system, then why the appropriate provider is not already loaded. It would be good to confirm if its expected that you still need to load the provider even if the system has enabled FIPs to make sure the correct provider is being used.
@richardlau I know you have also look a bit at how FIPs and providers work so I'd be interested in any insights you have as well.
There was a problem hiding this comment.
Yes, according to my testing just having the guard there does not help on non-FIPS system! I did not test it yet on FIPS system, as in my opinion coredump should not happen in any system configuration.
The issue might be in getting confused on what the EVP_… functions actually do – according to manual page, they do not check the provider status at all:
EVP_default_properties_enable_fips() sets the 'fips=yes' to be a default property if enable is non zero, otherwise it clears 'fips' from the default property query for the given libctx. It merges the fips default property query with any existing query strings that have been set via EVP_set_default_properties().
EVP_default_properties_is_fips_enabled() indicates if 'fips=yes' is a default property for the given libctx.
I'm very much guessing in the dark here, but I suspect setting the EVP property fips=yes does not load the provider, nor does it indicate it was ever loaded – it just indicate you want to use it by default.
There was a problem hiding this comment.
@richardlau I know you have also look a bit at how FIPs and providers work so I'd be interested in any insights you have as well.
FIPS support in OpenSSL 3 is completely different from what came before and works with the (new for OpenSSL 3) Provider model. This model is a lot more generic -- you may have any number of providers loaded (aka available) and can change the loaded providers at runtime (through OSSL_PROVIDER_load/OSSL_PROVIDER_unload). Since it's generic the providers themselves can be named anything, i.e. a FIPS provider does not need to be named "fips" (which means the code in Node.js being queried is overly specific and probably does need to change).
So what does "fips mode" mean in the provider model? When fetching an algorithm in OpenSSL the algorithm may be implemented by more than one loaded provider. If that is the case it is undefined which implemented is used unless the fetch was constrained by a property query, e.g. fips=yes -- note this may still match more than one provider if those providers set fips=yes on their algorithm implementations. You can limit to a specifically named provider by property (e.g. provider=fips) but remember that OpenSSL puts no special meaning on the provider names themselves. The property query can either be set on every individual fetch call or as a default property (which applies to all fetch calls that don't specify their own). For OpenSSL 3 Node.js treats "fips mode" as the equivalent of having set a default query of fips=yes.
The genericness of the provider model coupled with the ability to dynamically change the loaded providers also means that it is possible that an algorithm fetch returns no matching implementations. Such a corner case was reported in #46200 -- if fips=yes is set as the default property query and no implementations that have that property are available (e.g. no provider has been loaded that provides a compatible implementation) then in that reported case it was not possible to initialize the cryptographically secure pseudorandom number generator (CSPRNG).
With regards to the code being commented on, I think the intention seems to be to determine if it might be possible to load a provider called "fips" (i.e. the provider is on the filesystem and could be loaded). This is a highly specific assumption -- OpenSSL 3 makes no guarantee that a provider called "fips" actually implements any FIPS compatible algorithms -- so is probably a flawed assumption to be making. I believe OpenSSL's OSSL_PROVIDER_load/OSSL_PROVIDER_unload operates via reference counting (so the provider may not actually be unloaded if it had already been loaded prior to the OSSL_PROVIDER_load call on L125).
I suspect the issue might be that Node.js is not picking up the OpenSSL configuration as the default for Node.js is now to look for a configuration called In this case, where no configuration is loaded (because no |
Slight correction, at runtime you can pass |
|
So, finally back enough to respond 🙂
Thanks for the pointer – that does seem to help when I have my system configured to run in FIPS mode (still on Fedora): I will update our build scripts to use the proper configure option. However, this still does not help when the system is not in FIPS mode: The main culprit seems to be that in this case, even the shared configuration makes no effort to load the fips provider.
The question now is what do we want to do with this. I would have thought that if we are going to provide Alternatively, we need a better check for the availability of the fips provider, and only set the Thoughts? @richardlau |
|
My main concern is "the fips provider" is no longer a binary true/false. In a Linux distro like Fedora you could probably make some assumptions that, yes, there is a provider called "fips" that should be available and loaded, but in the general case it is a bad assumption that there is a provider called "fips", or (even if there is such a named provider) that it is providing FIPS capable functionality, or that some other named provider is available providing FIPS functionality. But maybe I'm overthinking this and we can restrict what |
Hm, given that it seems the entire code path is dependent on lot of assumptions that we are not comfortable making when working with libssl other than the bundled one ( My POV here is that a distribution could (and in case of Fedora/RHEL definitely does) have an opinion on how FIPS should be enabled and handled; in RHEL docs, there should currently be a paragraph strongly discouraging the user from ever touching the FIPS options on node, even should they work as assumed. We are currently having a discussion on downstream patching the node to effectively disabling the options anyway, but this seems like a good point to ask if that could be included here as well. 😇 |
I'd be okay with that. When I rewrote the FIPS documentation (#48194) for this project and was testing the instructions I did observe that cc @nodejs/crypto @nodejs/distros |
Something along these lines makes sense to me. I might be SemVer major (although it would not affect shipping binaries, just people who build themselves), but I think heading down the path where configuration of FIPs when using a shared OpenSSL libary is done outside of Node.js itself makes sense. does that make sense to you as well? |
03d3ccf to
137735c
Compare
|
Another draft for your consideration.🙂 I've added a define A note should also be added to the docs about the fips flags status; I will add that if I get general approval on the proposed changes. WDYT? @mhdawson @richardlau |
|
@khardix I do think the update would be SemVer major, and would still like to get confirmation from at least one more distro that it makese sense to them as well. |
|
This pull request has been marked as stale due to 90 days of inactivity. |
|
This PR is indeed stale, and the problem would probably be resolved in a different way. Closing. |
configure now fails when --shared-openssl points at OpenSSL 1.x rather than failing later at compile or link time. The check skips BoringSSL, whose version macros claim 1.1.1. Stop setting the OpenSSL 1.1 API compatibility level for bundled builds. ncrypto selects the supported API level directly. Update the assembler capability check, shared-library test matrix, package fallbacks, and internal version-number typing for the new baseline. Signed-off-by: Filip Skokan <panva.ip@gmail.com> Assisted-by: Codex PR-URL: #64777 Fixes: #56733 Refs: #64211 Refs: #63966 Refs: #53329 Refs: #48950 Refs: #45465 Refs: #42827 Refs: #47076 Refs: #62862 Refs: #38512 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Richard Lau <richard.lau@ibm.com> Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>
Remove the OpenSSL 1.x backend and its legacy dss1 digest aliases. Rename the provider-backed path switch to NCRYPTO_USE_OPENSSL_PROVIDER and rewrite the remaining version guards as OPENSSL_IS_BORINGSSL checks. Remove version-adapter casts now that supported OpenSSL signatures are uniform. Drop legacy digest-context, raw-key, seed, signature-context, SM2, primality, and RSA2 key-detail fallbacks. Keep name-based key algorithms and capability discovery, with numeric key adapters and low-level key paths only for BoringSSL. Use the same backend split for KDFs, PKCS#1 decoding, key serialization, and provider EC/RSA key details. Gate BoringSSL-only alternatives explicitly instead of leaving them in #else branches. Signed-off-by: Filip Skokan <panva.ip@gmail.com> Assisted-by: Codex PR-URL: #64777 Fixes: #56733 Refs: #64211 Refs: #63966 Refs: #53329 Refs: #48950 Refs: #45465 Refs: #42827 Refs: #47076 Refs: #62862 Refs: #38512 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Richard Lau <richard.lau@ibm.com> Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>
Remove the OpenSSL 1.x branches and stale version-specific assumptions from src/. BoringSSL does not define OPENSSL_VERSION_MAJOR, so the remaining version guards were excluding it as well; use OPENSSL_IS_BORINGSSL checks instead, including the shared PKCS12 parser and TLS PFX error handling. Gate BoringSSL-only alternatives explicitly instead of leaving them in #else branches, including the MAC/KMAC and OCB fallbacks. Fix the BoringSSL guard on QUIC's unsupported-backend diagnostic. Make the OpenSSL legacy-provider command-line help version-neutral. Signed-off-by: Filip Skokan <panva.ip@gmail.com> Assisted-by: Codex PR-URL: #64777 Fixes: #56733 Refs: #64211 Refs: #63966 Refs: #53329 Refs: #48950 Refs: #45465 Refs: #42827 Refs: #47076 Refs: #62862 Refs: #38512 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Richard Lau <richard.lau@ibm.com> Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>
Delete test-crypto-ecb.js, which can no longer run anywhere: Blowfish is available only from OpenSSL's legacy provider and is absent from BoringSSL. The addon and cctest version guards become OPENSSL_IS_BORINGSSL checks. Remove legacy digest-alias coverage and unreachable OpenSSL 1.x branches. JavaScript test and benchmark gates, skip reasons, and TLS error expectations that distinguished OpenSSL 1.x from provider-backed OpenSSL now distinguish BoringSSL, including PKCS12 parsing, named DH groups, private-key serialization, RSA-PSS parameters, consolidated provider caches, FIPS availability, and empty KMAC output. Keep the CCM alternate finalization error only for BoringSSL. Provider-only test skips use version-neutral terminology or state the actual minimum OpenSSL version. Signed-off-by: Filip Skokan <panva.ip@gmail.com> Assisted-by: Codex PR-URL: #64777 Fixes: #56733 Refs: #64211 Refs: #63966 Refs: #53329 Refs: #48950 Refs: #45465 Refs: #42827 Refs: #47076 Refs: #62862 Refs: #38512 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Richard Lau <richard.lau@ibm.com> Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>
Rename the openssl30 footnote, which marks APIs unavailable on BoringSSL rather than ones requiring OpenSSL. Remove obsolete version qualifiers from the provider and FIPS documentation, drop the "As of OpenSSL 1.1.0" anchor from the PSK size limits, and point the man1.1.1 links at man3.0. Document BoringSSL as the only backend with numeric key adapters. Signed-off-by: Filip Skokan <panva.ip@gmail.com> Assisted-by: Codex PR-URL: #64777 Fixes: #56733 Refs: #64211 Refs: #63966 Refs: #53329 Refs: #48950 Refs: #45465 Refs: #42827 Refs: #47076 Refs: #62862 Refs: #38512 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Richard Lau <richard.lau@ibm.com> Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>
The openssl_fips_*.cnf fixtures use OpenSSL 1.x syntax, and their test branches can no longer run. Remove the fixtures and related version gates while keeping the provider-backed FIPS assertions. get_env_type() sniffed for a "-fips" version suffix that can no longer occur, and the crypto-check lint rule listed a helper that no longer exists. Signed-off-by: Filip Skokan <panva.ip@gmail.com> Assisted-by: Codex PR-URL: #64777 Fixes: #56733 Refs: #64211 Refs: #63966 Refs: #53329 Refs: #48950 Refs: #45465 Refs: #42827 Refs: #47076 Refs: #62862 Refs: #38512 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Richard Lau <richard.lau@ibm.com> Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>
--openssl-is-fips with bundled OpenSSL never worked: the openssl-fipsmodule target had no dependency edge, so fipsinstall's input was produced by nothing. Repairing it would not help, since a FIPS provider built out of tree has no validation status. Remove the machinery and restrict --openssl-is-fips to --shared-openssl. Signed-off-by: Filip Skokan <panva.ip@gmail.com> Assisted-by: Codex PR-URL: #64777 Fixes: #56733 Refs: #64211 Refs: #63966 Refs: #53329 Refs: #48950 Refs: #45465 Refs: #42827 Refs: #47076 Refs: #62862 Refs: #38512 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Richard Lau <richard.lau@ibm.com> Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>
Signed-off-by: Filip Skokan <panva.ip@gmail.com> Assisted-by: Codex PR-URL: #64777 Fixes: #56733 Refs: #64211 Refs: #63966 Refs: #53329 Refs: #48950 Refs: #45465 Refs: #42827 Refs: #47076 Refs: #62862 Refs: #38512 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Richard Lau <richard.lau@ibm.com> Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>
… (DEP0183)" This reverts commit da51692. PR-URL: #64777 Fixes: #56733 Refs: #64211 Refs: #63966 Refs: #53329 Refs: #48950 Refs: #45465 Refs: #42827 Refs: #47076 Refs: #62862 Refs: #38512 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Richard Lau <richard.lau@ibm.com> Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>
OpenSSL removed support for engines in version 4. Remove the Node.js APIs, constants, native bindings, and implementation that depend on ENGINE. Keep recognizing the former TLS and HTTPS engine options so their use fails explicitly instead of appearing to work while being ignored. Move DEP0183 directly from Documentation-only to End-of-Life after reverting its unreleased Runtime deprecation. Signed-off-by: Filip Skokan <panva.ip@gmail.com> Assisted-by: Codex PR-URL: #64777 Fixes: #56733 Refs: #64211 Refs: #63966 Refs: #53329 Refs: #48950 Refs: #45465 Refs: #42827 Refs: #47076 Refs: #62862 Refs: #38512 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Richard Lau <richard.lau@ibm.com> Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>
With shared OpenSSL >= 3, I'm encountering a core dump/assertion failure when trying to use
--force-fips/--enable-fips:I'm on Fedora 38,
openssl-libs-3.0.9-1.fc38.x86_64.I was toying with fixing this a bit, and this PR is my WIP approach at fixing this. The first commit just turns that assertion into an error message in order to better debug what is wrong with the CSPRNG; the other makes the error go away, but I'm not sure what other impact it can have.
On the other hand, can anyone tell me why the unload is there? I would thought that when the FIPS flags are encountered, we would want to actually leave the provider in place in order to be utilized by the application, not immediately yanking it back once confirmed it can be loaded.
I also noticed that in
TestFipsCrypto()loads the provider again, then leaves it loaded… 😕I'm making it as draft for now, because I want to know more about the points above before trying to actually push the change.