bcgit / bc-java

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

Oracle Java 21: NullPointerException at java.base/javax.crypto.ProviderVerifier.verify #1905

Open hostalp opened 1 week ago

hostalp commented 1 week ago

Recently we switched our Jenkins CI/CD environment to Java 21. Most of our Jenkins hosts use some build of OpenJDK (especially the Red Hat build), however some hosts are different (different, older Linux distributions) for which no OpenJDK 21 build is available from their official repositories. In these cases we tried to use the Oracle JDK 21 from https://www.oracle.com/java/technologies/downloads/#java21 (in particular the 21.0.5 deb package https://download.oracle.com/java/21/latest/jdk-21_linux-x64_bin.deb). This works except for one thing related to the Bouncy Castle JCE provider.

To get (checkout) the code from our GIT repository we use the JGit (pure Java) client provided by Jenkins. Since the repository is accessed via secure channel (SSH), some JCE provider is required to be involved and Jenkins uses Bouncy Castle here. While at the OpenJDK 21 things works smoothly, at Oracle JDK 21 we get the exception shown below.

Since the Jenkins (via the Bouncycastle API plugin) currently uses Bouncy Castle 1.78.1 and we noticed that there were some Oracle Java 21 specific fixes in the version 1.79, we also tried to update it manually in our Jenkins environment, but that didn't make any difference.

Meanwhile, we've switched (at the affected hosts) to the Eclipse Temurin OpenJDK 21 build and things started to work again so it really appears to be Oracle JDK 21 related issue.

peterdettman commented 1 week ago

So Oracle JDK 21 is attempting to authenticate the BC provider and fails due to NullPointerException during the attempt. The underlying cause of authentication failures is usually some sort of modification to the provider jar (including any kind of repackaging e.g. fat jars, or exploding into class trees).

Note that OpenJDK doesn't perform this authentication of third-party cryptographic providers, which would explain why you only see it when trying to use the Oracle JDK.

hostalp commented 1 week ago

I already checked the jars - both at the Jenkins server side as well as at the worker nodes to which these jars are copied when needed and they were the original untouched 1.78.1 and then 1.79 (when I replaced them manually. and cleared the jar cache at the worker nodes).

Verification via jarsigner (from the same Oracle JDK 21) results in the following:

s     802861 Wed Oct 30 09:42:52 CET 2024 META-INF/MANIFEST.MF

      >>> Signer
      X.509, CN=Legion of the Bouncy Castle Inc., OU=Java Software Code Signing, O=Oracle Corporation
      Signature algorithm: SHA256withRSA, 2048-bit key
      [certificate is valid from 1/25/22, 1:58 AM to 1/25/27, 1:58 AM]
      X.509, CN=JCE Code Signing CA, OU=Java Software Code Signing, O=Oracle Corporation
      Signature algorithm: SHA256withRSA, 2048-bit key
      [certificate is valid from 7/7/16, 1:48 AM to 12/31/30, 1:00 AM]
      [Invalid certificate chain: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target]
      >>> TSA
      X.509, CN=DigiCert Timestamp 2024, O=DigiCert, C=US
      Signature algorithm: SHA256withRSA, 4096-bit key
      [certificate is valid from 9/26/24, 2:00 AM to 11/26/35, 12:59 AM]
      X.509, CN=DigiCert Trusted G4 RSA4096 SHA256 TimeStamping CA, O="DigiCert, Inc.", C=US
      Signature algorithm: SHA256withRSA, 4096-bit key
      [certificate is valid from 3/23/22, 1:00 AM to 3/23/37, 12:59 AM]
      X.509, CN=DigiCert Trusted Root G4, OU=www.digicert.com, O=DigiCert Inc, C=US
      Signature algorithm: SHA384withRSA, 4096-bit key
      [certificate is valid from 8/1/22, 2:00 AM to 11/10/31, 12:59 AM]
...
jar verified.

Warning:
This jar contains entries whose certificate chain is invalid. Reason: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

The signer certificate will expire on 2027-01-25.
The timestamp will expire on 2031-11-10.

Where that complaint about the untrusted certificate chain shouldn't be critical AFAIK (and it's already been discussed in #1193).

So I believe the issue is slightly different than the JAR validity.

dghgit commented 1 day ago

Is the provider being loaded via the JVMs module path? It looks like the jar's valid, but if something is unpacking it or re-wrapping it before it gets used there will be trouble.

If you're sure it is, I think you may need to raise this with Oracle, we have worked around an issue in Java 21 as well as reporting one recently. If it's something we can deal with on our end we would be happy to do so, but available source does not really seem to suggest what's going on...