I am using bouncyCastle library with FIPS mode enabled for SSL communication. So, I have only 3 providers in java.security file as follows:
security.provider.1=org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider
security.provider.2=org.bouncycastle.jsse.provider.BouncyCastleJsseProvider fips:BCFIPS
security.provider.3=SUN
I have written a simple program to test connection with one of our sites:
// enable revocation check
System.setProperty("com.sun.net.ssl.checkRevocation", "true");
// enable CDP
System.setProperty("com.sun.security.enableCRLDP", "true");
System.setProperty("org.bouncycastle.x509.enableCRLDP", "true");
// disable OCSP
Security.setProperty("ocsp.enable", "false");
URL url = new URL("<my-web-site>");
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.connect();
However the connection is failing with following error:
org.bouncycastle.tls.TlsFatalAlert: certificate_unknown(46)
at org.bouncycastle.jsse.provider.ProvSSLSocketDirect.checkServerTrusted(ProvSSLSocketDirect.java:134)
at org.bouncycastle.jsse.provider.ProvTlsClient$1.notifyServerCertificate(ProvTlsClient.java:335)
at org.bouncycastle.tls.TlsUtils.processServerCertificate(TlsUtils.java:4544)
at org.bouncycastle.tls.TlsClientProtocol.handleServerCertificate(TlsClientProtocol.java:842)
at org.bouncycastle.tls.TlsClientProtocol.handleHandshakeMessage(TlsClientProtocol.java:728)
at org.bouncycastle.tls.TlsProtocol.processHandshakeQueue(TlsProtocol.java:652)
at org.bouncycastle.tls.TlsProtocol.processRecord(TlsProtocol.java:548)
at org.bouncycastle.tls.RecordStream.readRecord(RecordStream.java:232)
at org.bouncycastle.tls.TlsProtocol.safeReadRecord(TlsProtocol.java:800)
at org.bouncycastle.tls.TlsProtocol.blockForHandshake(TlsProtocol.java:396)
at org.bouncycastle.tls.TlsClientProtocol.connect(TlsClientProtocol.java:91)
at org.bouncycastle.jsse.provider.ProvSSLSocketDirect.startHandshake(ProvSSLSocketDirect.java:430)
at org.bouncycastle.jsse.provider.ProvSSLSocketDirect.startHandshake(ProvSSLSocketDirect.java:411)
at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:567)
at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:171)
at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:142)
at com.test.TestConnection.main(TestConnection.java:153)
Caused by: java.security.cert.CertificateException: Unable to construct a valid chain
at org.bouncycastle.jsse.provider.ProvX509TrustManager.validateChain(ProvX509TrustManager.java:308)
at org.bouncycastle.jsse.provider.ProvX509TrustManager.checkTrusted(ProvX509TrustManager.java:267)
at org.bouncycastle.jsse.provider.ProvX509TrustManager.checkServerTrusted(ProvX509TrustManager.java:174)
at org.bouncycastle.jsse.provider.ProvSSLSocketDirect.checkServerTrusted(ProvSSLSocketDirect.java:130)
... 16 more
Caused by: java.security.cert.CertPathBuilderException: Certification path could not be validated.
at org.bouncycastle.jcajce.provider.PKIXCertPathBuilderSpi.engineBuild(Unknown Source)
at java.base/java.security.cert.CertPathBuilder.build(CertPathBuilder.java:297)
at org.bouncycastle.jsse.provider.ProvX509TrustManager.buildCertPath(ProvX509TrustManager.java:240)
at org.bouncycastle.jsse.provider.ProvX509TrustManager.validateChain(ProvX509TrustManager.java:295)
... 19 more
Caused by: java.security.cert.CertPathValidatorException: No CRLs found for issuer "CN=Starfield Services Root Certificate Authority - G2, O="Starfield Technologies, Inc.", L=Scottsdale, ST=Arizona, C=US"
at org.bouncycastle.jcajce.provider.RFC3280CertPathUtilities.processCertA(Unknown Source)
at org.bouncycastle.jcajce.provider.PKIXCertPathValidatorSpi.engineValidate(Unknown Source)
at org.bouncycastle.jcajce.provider.PKIXCertPathBuilderSpi.build(Unknown Source)
at org.bouncycastle.jcajce.provider.PKIXCertPathBuilderSpi.build(Unknown Source)
at org.bouncycastle.jcajce.provider.PKIXCertPathBuilderSpi.build(Unknown Source)
... 23 more
Caused by: org.bouncycastle.jcajce.provider.AnnotatedException: No CRLs found for issuer "CN=Starfield Services Root Certificate Authority - G2, O="Starfield Technologies, Inc.", L=Scottsdale, ST=Arizona, C=US"
at org.bouncycastle.jcajce.provider.CertPathValidatorUtilities.getCompleteCRLs(Unknown Source)
at org.bouncycastle.jcajce.provider.RFC3280CertPathUtilities.checkCRL(Unknown Source)
at org.bouncycastle.jcajce.provider.RFC3280CertPathUtilities.checkCRLs(Unknown Source)
... 28 more
I have checked that a valid CRLDP is configured in each of the certificate in certificate chain. Here is how certificate chain looks like (The blue-highlighted CA certificate is present in my JDK truststore) :
The same code is working fine (connection successful) WITHOUT bouncyCastle (using default JDK providers). However, to make it work with bouncyCastle, I need to put entire certificate chain into my truststore (including end-entity certificate) - which is quite impractical.
Can anyone help me figuring out the problem here?