bcgit / bc-java

Bouncy Castle Java Distribution (Mirror)
https://www.bouncycastle.org/java.html
MIT License
2.21k stars 1.1k forks source link

Latest bc-fips 1.0.2.1 along with java 11 leads to StackOverflowError when attempted to initialize the BCFIPS provider #1000

Closed pope4e closed 2 years ago

pope4e commented 2 years ago

During a current upgrade of the bouncy castle fips libs to latest version (bc-fips 1.0.2 -> 1.0.2.1) we have experienced the following issue. Failure to initialize the BCFIPS provider due to StackOverflowError.

Exception in thread "main" java.lang.StackOverflowError at java.base/java.util.Dictionary.(Dictionary.java:55) at java.base/java.util.Hashtable.(Hashtable.java:239) at java.base/java.util.Properties.(Properties.java:206) at java.base/java.util.Properties.(Properties.java:174) at java.base/java.security.Provider.(Provider.java:262) at java.base/sun.security.ssl.SunJSSE.(SunJSSE.java:138) at java.base/sun.security.ssl.SunJSSE.(SunJSSE.java:126) at java.base/com.sun.net.ssl.internal.ssl.Provider.(Provider.java:52) at java.base/sun.security.jca.ProviderConfig.getProvider(ProviderConfig.java:183) at java.base/sun.security.jca.ProviderList.getProvider(ProviderList.java:266) at java.base/sun.security.jca.ProviderList.getIndex(ProviderList.java:296) at java.base/sun.security.jca.ProviderList.getProviderConfig(ProviderList.java:280) at java.base/sun.security.jca.ProviderList.getProvider(ProviderList.java:286)

I have been able to isolate and reproduce the issue with a simple java app. It seems to be also dependent on the specific java version to be used. Following are more details on the steps to reproduce and the observations:

I. Reproduction of StackOverflowError Prerequisites: 1/ Have the following java version as runtime openjdk version "11.0.11" 2021-04-20 LTS OpenJDK Runtime Environment Zulu11.48+21-CA (build 11.0.11+9-LTS) OpenJDK 64-Bit Server VM Zulu11.48+21-CA (build 11.0.11+9-LTS, mixed mode)

2/ Have the following provider list in an override of the java.security file passed to the java app

security.provider.1=org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider C:DEFRND[HMACSHA512(256)];HYBRID;ENABLE{ALL}; security.provider.2=org.bouncycastle.jsse.provider.BouncyCastleJsseProvider fips:BCFIPS security.provider.3=com.sun.net.ssl.internal.ssl.Provider BCFIPS security.provider.4=sun.security.provider.Sun security.provider.5=org.jcp.xml.dsig.internal.dom.XMLDSigRI

3/ Use bc-fips 1.0.2.1 version. ( Also it would need to have a bctls-fips jar for the BouncyCastleJsseProvider .We used bctls-fips-1.0.12.1 version )

4/ Have a java program which calls Security.getProviders() as a first call in its main method. 5/ Run the java app in fips strict mode

This will produce the above exception.

The behavior seems to be dependent also on the version of java used. We have done further testing with a prior java version: openjdk version "11.0.2" 2019-01-15 OpenJDK Runtime Environment 18.9 (build 11.0.2+9) OpenJDK 64-Bit Server VM 18.9 (build 11.0.2+9, mixed mode)

With the above version of java the BCFIPS provider loaded successfully but the BouncyCastleJsseProvider has not been initialized and was missing.

We have also tested the above scenarios with the previous version of the bc-fips ( 1.0.2 ) and it had no problems.

Debugging the app it seemed to be related to a change into the ECPoint class and the addition of getTestRandom().

I have attached also the repro app source code and the related java.security override settings and scripts to start the app.

bc-fips repro.zip

peterdettman commented 2 years ago

Please try changing the BCJSSE provider entry to this:

security.provider.2=org.bouncycastle.jsse.provider.BouncyCastleJsseProvider fips:org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider

There were "surprise" changes to provider initialisation in recent JDK 11 updates as I recall. We have a fix for it in later fips jars but this workaround should be fine until then.

dghgit commented 2 years ago

This is fixed in bc-fips-1.0.2.2 - available in early access should be in GA in next month.

alexbarbato commented 2 years ago

Looking forward to the fix here and thanks so much for your work!

Any idea if the GA release for 1.0.2.2 is on track to release soon?

dghgit commented 2 years ago

It's still with NIST, which is unexpected, but it seems things are going very slowly at the moment.

alexbarbato commented 2 years ago

Ok, thanks for the update!

dghgit commented 2 years ago

For reasons which I won't go into we ended up moving to 1.0.2.3 - this is now available in Maven Central and at https://www.bouncycastle.org/fips-java

isaacjensen commented 2 years ago

I updated to bc-fips 1.0.2.3 and am still facing this exact issue.

Java: openjdk 11.0.14.1 2022-02-08 OpenJDK Runtime Environment Temurin-11.0.14.1+1 (build 11.0.14.1+1) OpenJDK 64-Bit Server VM Temurin-11.0.14.1+1 (build 11.0.14.1+1, mixed mode)

I also have this working with jdk 11.0.2 released Jan 2019. When i upgrade my JDK, i start getting this StackOverflowError and i cant even boot the server.

zhaiyaotnt commented 1 year ago

The workaround didn't work for me. So just like @isaacjensen , I am using bc-fips-1.0.2.3 but having the same StackOverFlowError when running the keytool command to convert the keystore type from JKS to BCFKS. openjdk: 11.0.17 command: keytool -importkeystore -srckeystore /etc/ssl/certs/java/cacerts.orig -srcstoretype JKS -srcstorepass changeit -destkeystore /etc/ssl/certs/java/cacerts -deststorepass changeit -deststoretype BCFKS -providerClass org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider --providerpath /usr/lib/jvm/java-11-openjdk-amd64/jar/bc-fips-1.0.2.3.jar

To me, it looks like a version issue. My colleague used openjdk-8 and he doesn't not have the issue when running the same command. @dghgit @peterdettman

We have a tight timeline for a Fedramp certification and this is critical for our java base image. Is it possible to revisit this ticket?

dghgit commented 1 year ago

it's probably not the same issue. Do you have anything meaningful by way of a stack trace?

zhaiyaotnt commented 1 year ago

@dghgit I actually forgot to mention my java.security settings:

security.provider.1=org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider
security.provider.2=org.bouncycastle.jsse.provider.BouncyCastleJsseProvider fips:BCFIPS
security.provider.3=SUN
security.provider.4=SunRsaSign
security.provider.5=SunEC
security.provider.6=SunJSSE BCFIPS
security.provider.7=SunJCE
security.provider.8=SunJGSS
security.provider.9=SunSASL
security.provider.10=XMLDSig
security.provider.11=SunPCSC
security.provider.12=JdkLDAP
security.provider.13=JdkSASL
security.provider.14=Apple
security.provider.15=SunPKCS11

and

keystore.type=BCFKS

The StackOverFlowError happens when I append "BCFIPS" for the SunJSSE provider (provider.6). If I removed it, error is gone, but I do need it appended for ssl to use FIPS provider.

The stack trace is exactly same as the author has.

dghgit commented 1 year ago

Okay, easy fix, you should be able safely delete the SunJSSE. The experimental FIPS mode became a no-op in Java 9, they no longer try to keep it SP 800-52 compliant so in this case you cannot use it in any case.

zhaiyaotnt commented 1 year ago

@dghgit thanks! I assume you meant that I remove the entire line of provider.6 right? The keytool command did go through after I did that, but then I get the following error when using maven to download the dependencies. It might be related to the removal but I'm not sure. I am pretty new to crypto/fips, so would appreciate some insight here. thanks.

[ERROR]     Unresolveable build extension: Plugin kr.motd.maven:os-maven-plugin:1.6.2 or one of its dependencies could not be resolved: Failed to read artifact descriptor for kr.motd.maven:os-maven-plugin:jar:1.6.2: Could not transfer artifact kr.motd.maven:os-maven-plugin:pom:1.6.2 from/to central (https://repo.maven.apache.org/maven2): Transfer failed for https://repo.maven.apache.org/maven2/kr/motd/maven/os-maven-plugin/1.6.2/os-maven-plugin-1.6.2.pom: java.security.NoSuchAlgorithmException: Default SSLContext not available -> [Help 2]
[ERROR]     Non-resolvable import POM: Could not transfer artifact com.google.cloud:libraries-bom:pom:26.0.0 from/to central-repo (https://repo.maven.apache.org/maven2): Transfer failed for https://repo.maven.apache.org/maven2/com/google/cloud/libraries-bom/26.0.0/libraries-bom-26.0.0.pom @ line 12, column 16: java.security.NoSuchAlgorithmException: Default SSLContext not available -> [Help 3]
[ERROR]     'dependencies.dependency.version' for com.google.cloud:google-cloud-spanner-jdbc:jar is missing. @ line 110, column 15
[ERROR]     'dependencies.dependency.version' for com.google.cloud:google-cloud-pubsub:jar is missing. @ line 114, column 15

(btw, I replaced bcprov with bc-fips in google-cloud-spanner-jdbc and google-cloud-pubsub for FIPS compliance, hopefully that was the right thing to do)

Some more stack traces:

Caused by: java.security.NoSuchAlgorithmException: Default SSLContext not available
    at sun.security.jca.GetInstance.getInstance (GetInstance.java:159)
    at javax.net.ssl.SSLContext.getInstance (SSLContext.java:168)
    at javax.net.ssl.SSLContext.getDefault (SSLContext.java:99)
    at javax.net.ssl.SSLSocketFactory.getDefault (SSLSocketFactory.java:123)
    at javax.net.ssl.HttpsURLConnection.getDefaultSSLSocketFactory (HttpsURLConnection.java:335)
    at org.apache.maven.wagon.providers.http.wagon.shared.AbstractHttpClientWagon.createConnManager (AbstractHttpClientWagon.java:369)
    at org.apache.maven.wagon.providers.http.wagon.shared.AbstractHttpClientWagon.<clinit> (AbstractHttpClientWagon.java:295)
    at org.apache.maven.wagon.providers.http.HttpWagon$__sisu1$$FastClassByGuice$$fd3b369a.newInstance (<generated>)
zhaiyaotnt commented 1 year ago

@dghgit to add, I only started to get all these issues after I tried to convert the keystore type to BCFKS. Previous, in java.security, I kept the default keystore.type=pkcs12 and kept "security.provider.6=SunJSSE", everything was working fine. But I guess I have to do the conversion for FIPS compliance.

dghgit commented 1 year ago

check that the classpath doesn't have both BC FIPS and non-FIPS jars on it, and that the JVM concerned is properly configured to support the BCJSSE. The BCJSSE definitely provides a default context.

zhaiyaotnt commented 1 year ago

@dghgit Thank you! The errors were from "mvn clean package" command. I was reminded by your suggestion to check if "JVM concerned is properly configured to support the BCJSSE", so I set system property "-Djava.security.debug=jca" to see some debug messages, and it turned out neither BCFIPS nor BCJSSE was loaded!

ProviderConfig: Error loading legacy provider org.bouncycastle.jsse.provider.BouncyCastleJsseProvider
java.lang.ClassNotFoundException: org.bouncycastle.jsse.provider.BouncyCastleJsseProvider
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
    at java.base/sun.security.jca.ProviderConfig$ProviderLoader.legacyLoad(ProviderConfig.java:385)
    at java.base/sun.security.jca.ProviderConfig$ProviderLoader.load(ProviderConfig.java:362)
    at java.base/sun.security.jca.ProviderConfig$3.run(ProviderConfig.java:248)
    at java.base/sun.security.jca.ProviderConfig$3.run(ProviderConfig.java:242)

My understanding is that since these are externally added providers, Maven needs to know where the two jars are located in order to find the provider classes. However, since maven's job is only to download the dependencies and download, I can specify a different java.security file for maven. Kindly let me know if you have different thoughts. Thanks!