Skip to content

OPENJDK-4559: Red Hat Build of OpenJDK 25 should not restrict all the providers in FIPS#45

Merged
gnu-andrew merged 1 commit intorh-openjdk:fips-25ufrom
franferrax:OPENJDK-4559
Mar 2, 2026
Merged

OPENJDK-4559: Red Hat Build of OpenJDK 25 should not restrict all the providers in FIPS#45
gnu-andrew merged 1 commit intorh-openjdk:fips-25ufrom
franferrax:OPENJDK-4559

Conversation

@franferrax
Copy link

OPENJDK-4559: Red Hat Build of OpenJDK 25 should not restrict all the providers in FIPS

Hi,

This pull request addresses the problem described in OPENJDK-4559.

The RedHatFIPSFilter implemented by df04441 in fips-25u is too restrictive. This change restores the fips-21u behavior, where the user is allowed to insert security providers without any validation. Otherwise, the user has no alternative when they need to use a third-party security provider.

Testing

I locally built a release image from the sources, and applied the create-redhat-properties-files.bash setup (with a local build of nssadapter v0.1.1), then copied the image to a RHEL 9 VM with FIPS-mode enabled.

Manual execution of a simple PKCS #12 keystore test

# Non-ASCII password
password='Th1s is a Bullet: •'

# Create a PKCS #12 keystore with a certificate and a key pair
openssl req -x509 -nodes -newkey rsa:4096 -subj /C=TT/ST=TT/L=TT/O=Test/CN=test.com/ -keyout key.pem -out cert.pem
openssl pkcs12 -export -inkey key.pem -in cert.pem -passout "pass:$password" -out ks.p12

# Read the keystore with keytool, enabling nssadapter and JCA logs
NSS_ADAPTER_DEBUG=color keytool -J-Djava.security.debug=all -list -storetype pkcs12 -keystore ks.p12 -storepass "$password"

# Cleanup
unset password && rm -f ks.p12 key.pem cert.pem

nssadapter is being used (we can see its log messages). This shows that SunPKCS11, despite no longer being part of the patch, is being allowed, as would any other third-party provider.

RedHatFIPSFilter messages are also printed, indicating that it is filtering the OpenJDK bundled security providers:

Provider[0x3|main|Provider.java:1252|2026-02-18 16:55:24.645]: SunJCE.putService(): SunJCE: Mac.HmacSHA1 -> com.sun.crypto.provider.HmacSHA1
aliases: [OID.1.2.840.113549.2.7, 1.2.840.113549.2.7]
attributes: {SupportedKeyFormats=RAW}

Provider[0x3|main|Provider.java:1265|2026-02-18 16:55:24.645]: The previous SunJCE.putService() call was skipped by java.security.Provider$RedHatFIPSFilter

Execution of ssl-tests

git clone https://github.com/rh-openjdk/ssl-tests && cd ssl-tests
make clean ssl-tests-build certgen_all
make ssl-tests

All the tests are either passing or being skipped.

Expand to see the results
IGNORED: SunJSSE/DTLS: DTLSv1.2 + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
IGNORED: SunJSSE/DTLS: DTLSv1.2 + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
IGNORED: SunJSSE/DTLS: DTLSv1.2 + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
IGNORED: SunJSSE/DTLS: DTLSv1.2 + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
IGNORED: SunJSSE/DTLS: DTLSv1.2 + TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
IGNORED: SunJSSE/DTLS: DTLSv1.2 + TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
IGNORED: SunJSSE/DTLS: DTLSv1.2 + TLS_EMPTY_RENEGOTIATION_INFO_SCSV
IGNORED: SunJSSE/DTLSv1.2: DTLSv1.2 + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
IGNORED: SunJSSE/DTLSv1.2: DTLSv1.2 + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
IGNORED: SunJSSE/DTLSv1.2: DTLSv1.2 + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
IGNORED: SunJSSE/DTLSv1.2: DTLSv1.2 + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
IGNORED: SunJSSE/DTLSv1.2: DTLSv1.2 + TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
IGNORED: SunJSSE/DTLSv1.2: DTLSv1.2 + TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
IGNORED: SunJSSE/DTLSv1.2: DTLSv1.2 + TLS_EMPTY_RENEGOTIATION_INFO_SCSV
PASSED: SunJSSE/TLS: TLSv1.3 + TLS_AES_256_GCM_SHA384
PASSED: SunJSSE/TLS: TLSv1.3 + TLS_AES_128_GCM_SHA256
IGNORED: SunJSSE/TLS: TLSv1.3 + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
IGNORED: SunJSSE/TLS: TLSv1.3 + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
IGNORED: SunJSSE/TLS: TLSv1.3 + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
IGNORED: SunJSSE/TLS: TLSv1.3 + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
IGNORED: SunJSSE/TLS: TLSv1.3 + TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
IGNORED: SunJSSE/TLS: TLSv1.3 + TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
IGNORED: SunJSSE/TLS: TLSv1.3 + TLS_EMPTY_RENEGOTIATION_INFO_SCSV
IGNORED: SunJSSE/TLS: TLSv1.2 + TLS_AES_256_GCM_SHA384
IGNORED: SunJSSE/TLS: TLSv1.2 + TLS_AES_128_GCM_SHA256
PASSED: SunJSSE/TLS: TLSv1.2 + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
PASSED: SunJSSE/TLS: TLSv1.2 + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
PASSED: SunJSSE/TLS: TLSv1.2 + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
PASSED: SunJSSE/TLS: TLSv1.2 + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
PASSED: SunJSSE/TLS: TLSv1.2 + TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
PASSED: SunJSSE/TLS: TLSv1.2 + TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
IGNORED: SunJSSE/TLS: TLSv1.2 + TLS_EMPTY_RENEGOTIATION_INFO_SCSV
PASSED: SunJSSE/Default: TLSv1.3 + TLS_AES_256_GCM_SHA384
PASSED: SunJSSE/Default: TLSv1.3 + TLS_AES_128_GCM_SHA256
IGNORED: SunJSSE/Default: TLSv1.3 + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
IGNORED: SunJSSE/Default: TLSv1.3 + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
IGNORED: SunJSSE/Default: TLSv1.3 + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
IGNORED: SunJSSE/Default: TLSv1.3 + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
IGNORED: SunJSSE/Default: TLSv1.3 + TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
IGNORED: SunJSSE/Default: TLSv1.3 + TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
IGNORED: SunJSSE/Default: TLSv1.3 + TLS_EMPTY_RENEGOTIATION_INFO_SCSV
IGNORED: SunJSSE/Default: TLSv1.2 + TLS_AES_256_GCM_SHA384
IGNORED: SunJSSE/Default: TLSv1.2 + TLS_AES_128_GCM_SHA256
PASSED: SunJSSE/Default: TLSv1.2 + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
PASSED: SunJSSE/Default: TLSv1.2 + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
PASSED: SunJSSE/Default: TLSv1.2 + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
PASSED: SunJSSE/Default: TLSv1.2 + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
PASSED: SunJSSE/Default: TLSv1.2 + TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
PASSED: SunJSSE/Default: TLSv1.2 + TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
IGNORED: SunJSSE/Default: TLSv1.2 + TLS_EMPTY_RENEGOTIATION_INFO_SCSV
PASSED: SunJSSE/TLSv1.2: TLSv1.2 + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
PASSED: SunJSSE/TLSv1.2: TLSv1.2 + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
PASSED: SunJSSE/TLSv1.2: TLSv1.2 + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
PASSED: SunJSSE/TLSv1.2: TLSv1.2 + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
PASSED: SunJSSE/TLSv1.2: TLSv1.2 + TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
PASSED: SunJSSE/TLSv1.2: TLSv1.2 + TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
IGNORED: SunJSSE/TLSv1.2: TLSv1.2 + TLS_EMPTY_RENEGOTIATION_INFO_SCSV
PASSED: SunJSSE/TLSv1.3: TLSv1.3 + TLS_AES_256_GCM_SHA384
PASSED: SunJSSE/TLSv1.3: TLSv1.3 + TLS_AES_128_GCM_SHA256
IGNORED: SunJSSE/TLSv1.3: TLSv1.3 + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
IGNORED: SunJSSE/TLSv1.3: TLSv1.3 + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
IGNORED: SunJSSE/TLSv1.3: TLSv1.3 + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
IGNORED: SunJSSE/TLSv1.3: TLSv1.3 + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
IGNORED: SunJSSE/TLSv1.3: TLSv1.3 + TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
IGNORED: SunJSSE/TLSv1.3: TLSv1.3 + TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
IGNORED: SunJSSE/TLSv1.3: TLSv1.3 + TLS_EMPTY_RENEGOTIATION_INFO_SCSV
IGNORED: SunJSSE/TLSv1.3: TLSv1.2 + TLS_AES_256_GCM_SHA384
IGNORED: SunJSSE/TLSv1.3: TLSv1.2 + TLS_AES_128_GCM_SHA256
PASSED: SunJSSE/TLSv1.3: TLSv1.2 + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
PASSED: SunJSSE/TLSv1.3: TLSv1.2 + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
PASSED: SunJSSE/TLSv1.3: TLSv1.2 + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
PASSED: SunJSSE/TLSv1.3: TLSv1.2 + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
PASSED: SunJSSE/TLSv1.3: TLSv1.2 + TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
PASSED: SunJSSE/TLSv1.3: TLSv1.2 + TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
IGNORED: SunJSSE/TLSv1.3: TLSv1.2 + TLS_EMPTY_RENEGOTIATION_INFO_SCSV

Only restrict the SUN, SunEC, SunJCE and SunRsaSign services. This makes
the fips-25u patch behave as the fips-21u patch, but with fewer changes.
@franferrax
Copy link
Author

@gnu-andrew: I'm realizing the fips-25u branch doesn't include the 25.0.2 changes, should I create PR for that sync and rebase this one? I can use #41 and #42 as templates, to make sure I align with your usual procedure.

We will still miss the 25.0.3 changes, I don't know how do you prefer handle this situation. It's clear that we can sync with 25.0.3 after the April unembargo, but at that point you already created the FIPS patch for the RPM. So an embargoed sync is required.

@gnu-andrew
Copy link

@gnu-andrew: I'm realizing the fips-25u branch doesn't include the 25.0.2 changes, should I create PR for that sync and rebase this one? I can use #41 and #42 as templates, to make sure I align with your usual procedure.

We will still miss the 25.0.3 changes, I don't know how do you prefer handle this situation. It's clear that we can sync with 25.0.3 after the April unembargo, but at that point you already created the FIPS patch for the RPM. So an embargoed sync is required.

The sync is only technically required when the patch will break when applied against the updated OpenJDK sources. It is preferable to do it every release, but I know we've skipped a few releases in the past where it hasn't been necessary.

25.0.2-ga is the right tag to sync with, especially if we want to ship this fix before April. It should just be a case of:

  1. git fetch --tags <jdk21u repo>
  2. git merge jdk-25.0.2-ga
  3. Resolve any conflicts
  4. Make sure the result builds
  5. Create a PR with the merged tree

Just don't merge it via the merge request as it'll squash it all. I can check it over and do a direct push. Thanks for doing it.

Copy link

@gnu-andrew gnu-andrew left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me. I assume the main change is that allowedServiceTypes can now be null? The ANY_SERVICE_TYPE becomes redundant due to this change as SunPKCS11-FIPS, SunJSSE & XMLDSig can go through the null return as with third party providers. So we are now only filtering SunEC, SUN, SunJCE and SunRsaSign.

@franferrax
Copy link
Author

@gnu-andrew:

Just don't merge it via the merge request as it'll squash it all. I can check it over and do a direct push. Thanks for doing it.

Ok, please find the PR at #46.

@gnu-andrew gnu-andrew merged commit e55ada9 into rh-openjdk:fips-25u Mar 2, 2026
@franferrax franferrax deleted the OPENJDK-4559 branch March 2, 2026 17:18
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

Successfully merging this pull request may close these issues.

2 participants