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

Constructor of BouncyCastleFipsProvider$CoreSecureRandom does not work on Java 17 #1285

Closed
mposolda opened this issue Nov 28, 2022 · 15 comments

Comments

@mposolda
Copy link

Setup:

  • bc-fips 1.0.2.3
  • OpenJDK 17
$ java -version
openjdk version "17.0.2" 2022-01-18
OpenJDK Runtime Environment (build 17.0.2+8-86)
OpenJDK 64-Bit Server VM (build 17.0.2+8-86, mixed mode, sharing)
  • Assume that security provider "SUN" is not available in the java security providers. It can be either removed from the java.security file or programatically
  • So run this application
@Test
public void testSecureRandom() throws Exception {
    Security.removeProvider("SUN");
    SecureRandom sc2 = SecureRandom.getInstance("DEFAULT", "BCFIPS");
}
  • It fails with the stacktrace like:
java.lang.IllegalAccessError: class org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider$CoreSecureRandom (in unnamed module @0x51521cc1) cannot access class sun.security.provider.SecureRandom (in module java.base) because module java.base does not export sun.security.provider to unnamed module @0x51521cc1

	at org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider$CoreSecureRandom.<init>(Unknown Source)
	at org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider$4.run(Unknown Source)
	at org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider$4.run(Unknown Source)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:318)
	at org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider.getCoreSecureRandom(Unknown Source)
	at org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider.access$200(Unknown Source)
	at org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider$2.run(Unknown Source)
	at org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider$2.run(Unknown Source)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:318)
	at org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider.getDefaultEntropySource(Unknown Source)
	at org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider.getDefaultSecureRandom(Unknown Source)
	at org.bouncycastle.jcajce.provider.ProvRandom$1.createInstance(Unknown Source)
	at org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider$BcService.newInstance(Unknown Source)
	at java.base/sun.security.jca.GetInstance.getInstance(GetInstance.java:236)
	at java.base/sun.security.jca.GetInstance.getInstance(GetInstance.java:206)
	at java.base/java.security.SecureRandom.getInstance(SecureRandom.java:434)
	at org.keycloak.crypto.fips.test.FIPS1402SecureRandomTest.testSecureRandom(FIPS1402SecureRandomTest.java:54)

NOTE: Same code works on OpenJDK 11 (there is just warning about Illegal reflective access as specified in this other issue #510 )

@dghgit
Copy link
Contributor

dghgit commented Dec 6, 2022

The code should never be called on Java 17, or Java 11 if securerandom.strongalgorithms is set correctly. If it is called it means there is something wrong with that setting.

@mposolda
Copy link
Author

mposolda commented Dec 7, 2022

@dghgit Yes, exactly. The SecureRandom.getInstanceStrong() may not be available in some environments like for example:

  • OpenJDK 17 installation on the FIPS enabled RHEL 8.6 system
  • Default OpenJDK 17 with removed SUN provider. It is the easiest way to reproduce this and that is what I've added in the description

Typically when the SecureRandom.getInstanceStrong() is not available, BoncyCastle FIPS has this "fallback" to use BouncyCastleFipsProvider$CoreSecureRandom . What I am reporting here is, that this fallback does not work on Java 17

@dghgit
Copy link
Contributor

dghgit commented Dec 7, 2022

It's not a fallback, it's for earlier JVMs. SecureRandom.getInstanceStrong() must be available.

Please note that, as documented in the Security Policy, the module is not FIPS compliant if used with Java 17. It has never been tested with it.

@mposolda
Copy link
Author

mposolda commented Dec 8, 2022

Ok, Thanks for pointing it.

As I've mentioned, SecureRandom.getInstanceStrong() is not available at least on the RHEL 8.6 with FIPS enabled and with OpenJDK 17 configured for FIPS. But looks that this is rather issue of the RHEL/OpenJDK itself...

In general, the support for Java 17 can be nice. So leaving to you if you prefer to close this issue or use it to track Java 17 support. Thanks!

@dghgit
Copy link
Contributor

dghgit commented Dec 9, 2022

One question, if SecureRandom.getInstanceStrong() isn't available on RHEL 8.6, exactly what is? How do they provide entropy to a JVM?

@mposolda
Copy link
Author

@dghgit The SecureRandom.getInstanceStrong() fails due the java.security file is configured as securerandom.strongAlgorithms=NativePRNGBlocking:SUN,DRBG:SUN, however none of NativePRNGBlocking:SUN,DRBG:SUN algorithms is available. They are explicitly disabled in the SUN provider due they are likely considered non-FIPS compliant on this platform.

However calling of SecureRandom sr = new SecureRandom(); works fine. It returns instance of algorithm PKCS11 of provider SunPKCS11-NSS-FIPS. By default, the SunPKCS11 is the default security provider and NSS DB is also configured by default on RHEL 8 system. As far as I can see from implementation of class sun.security.pkcs11.P11SecureRandom, the secureRandom is based on the PKCS11 API calls like C_GenerateRandom() and C_SeedRandom() to the appropriate token, provided by NSS DB. Hence entropy is in fact provided somehow by NSS though.

Just for the reference, my RHEL version is 8.6, my java version is:

openjdk version "17.0.5" 2022-10-18 LTS
OpenJDK Runtime Environment (Red_Hat-17.0.5.0.8-2.el8_6) (build 17.0.5+8-LTS)
OpenJDK 64-Bit Server VM (Red_Hat-17.0.5.0.8-2.el8_6) (build 17.0.5+8-LTS, mixed mode, sharing)

I am planning to try on latest RHEL 9 and based on that, I will eventually report a bug to RHEL/OpenJDK as it looks like a mis-configuration that securerandom.strongAlgorithms is configured just to the algorithms, which are not available.

@dghgit
Copy link
Contributor

dghgit commented Dec 13, 2022

Okay, so it should be possible to deal with this by setting securerandom.strongAlgorithms to the implementation "new SecureRandom()" is using under the covers from the above it sounds like "PKCS11:SunPKCS11-NSS-FIPS" should do the trick. The security property is just a list of algorithm:provider pairs. I'd agree if they're going to do this they should add it.

@mposolda
Copy link
Author

@dghgit Yes, that is exactly what I am doing in my application. It is a workaround, but works fine for me. Thanks!

@mposolda
Copy link
Author

For the reference, here is the link to the Bugzilla about SecureRandom.getInstanceStrong() on RHEL: https://bugzilla.redhat.com/show_bug.cgi?id=2155060

@JiriOndrusek
Copy link

Hi, I met the same issue now with org.bouncycastle:bc-fips:1.0.2.3 , RHEL 8.8, java

openjdk version "17.0.7" 2023-04-18 LTS
OpenJDK Runtime Environment (Red_Hat-17.0.7.0.7-1.el7openjdkportable) (build 17.0.7+7-LTS)
OpenJDK 64-Bit Server VM (Red_Hat-17.0.7.0.7-1.el7openjdkportable) (build 17.0.7+7-LTS, mixed mode, sharing)

Are there any news about the fix?
@mposolda , @dghgit you mentioned a "workaround" by by setting securerandom.strongAlgorithms to the implementation "new SecureRandom()". I don't know much about BC. How can I apply such workaround to my project?
(I'm using project based on Quarkus 3.5.0)

@vhbcm
Copy link

vhbcm commented Nov 20, 2023

I wonder if you guys are having similar problem that we faced when I found this issue. We were initialising BC FIPS in a way that resulted in recursive calls to org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider#getCoreSecureRandom and eventual StackOverflowError exception. But this exception was masked because it goes through the SecureRandom.class.getMethod("getInstanceStrong").invoke(null) call and is wrapped by InvocationTargetException, I assume. This resulted in the execution of the return new CoreSecureRandom(); // fallback line which is where we see the exception above then.

@dghgit
Copy link
Contributor

dghgit commented Apr 22, 2024

Closing this one as it isn't anything to do with BC and has gone quiet - securerandom.strongAlgorithms needs to point at something that can be used to generate seed material. There's no other way for a 3rd party java provider to get access to a seed generator without going outside of the JVM.

@dghgit dghgit closed this as completed Apr 22, 2024
@michalvavrik
Copy link

michalvavrik commented May 15, 2024

@mposolda , @dghgit you mentioned a "workaround" by by setting securerandom.strongAlgorithms to the implementation "new SecureRandom()". I don't know much about BC. How can I apply such workaround to my project?
(I'm using project based on Quarkus 3.5.0)

@JiriOndrusek I think this is what they meant https://github.com/keycloak/keycloak/blob/main/crypto/fips1402/src/main/java/org/keycloak/crypto/fips/FIPS1402Provider.java#L327. Judging by the reactions here ( :-( ) this is a Quarkus issue now so I'll open Quarkus issue and we should do something about it in the Quarkus. I'll try.

@demonappolyon
Copy link

We can make it work using java --add-exports java.base/sun.security.provider=ALL-UNNAMED -jar your-application.jar explicitly and incase of containerized env we can use ENV JAVA_OPTS="--add-exports java.base/sun.security.provider=ALL-UNNAMED"

@dghgit
Copy link
Contributor

dghgit commented Sep 10, 2024

It's still better to manage this properly and set securerandom.strongAlgorithms to a RNG algorithm and provider that is seeded with decent entropy. I would not recommend using add-exports, you could end up falling back on the threaded seed generator and have to deal with it's performance issues instead.

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

6 participants