1

I have a code which calls a rest api protected with certificate, and that code was working for some time without issues, until I migrate application from Wildfly 10 to Wildfly 16.

The code itself is straight forward, it creates http request and set custom socket factory: `

 private SSLSocketFactory getSSLSocketFactory() {
    char[] certPassword = {}; // password hidden from you 
    try {
        final KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        final SSLContext sslContext = SSLContext.getInstance("TLS");
        final KeyStore keyStore = KeyStore.getInstance("PKCS12");
        try (FileInputStream fileInputStream = new FileInputStream(new File("cert.pk12"))) {
            keyStore.load(fileInputStream, certPassword);
        } catch (final Exception e) {
            logger.error("....", e);
        }

        this.readLoadCertificateFile(keyStore);
        kmf.init(keyStore, certPassword);
        sslContext.init(kmf.getKeyManagers(), new TrustManager[]{new AnyTrust()}, null);
        return sslContext.getSocketFactory();
    } catch (Exception e) {
        logger.error(".....", e);
    }
    throw new IllegalStateException("....");
}


  HTTPRequest req = ....
  req.setSSLSocketFactory(getSSLSocketFactory());
  tokenHttpResp = req.send();`

`

All seems good but when I run this code from within WF16 it throws

IOException: Failed to load .p12 keystore:C:\Cert\cert.p12; error constructing MAC: java.lang.SecurityException: JCE cannot authenticate the provider BC; org.bouncycastle.jcajce.provider.keystore.pkcs12.PKCS12KeyStoreSpi.engineLoad::-1 java.security.KeyStore.load in KeyStore.java::1445

I checked for the bouncy castle lib, and I don't have it in the application itself... If any one knows what the issue could be I would appreciate any input.

Alternatively, I'm looking to move this socket factory creation in to the container itself, seems like Wildfly Elytron subsystem specifically designed for this, is it a good idea?

Mikhail Chibel
  • 1,865
  • 1
  • 22
  • 34

1 Answers1

0

Answering my own question. The error message like "JCE cannot authenticate the provider BC" indicating that the jar file, the Security Provider is loaded from, cannot be verified by JVM. Either the jar is not signed or signature cannot be verified. In my case, the newer Wildfly version has a newer version of bouncy castle library, which for some reason, cannot be verified by Java 8. Interesting enough, that it is fine with Java 10. Some people on the Internet says that this issue only occurs in Oracle's JVM and does not exist for Open JDK, I haven't tested it, just think it worth to mention.

To overcome issue you need to tell JVM to trust the security provider, for that, make sure that the Security Provider you want to use/JVM decided to use, mentioned in jre/lib/security/java.security file, it should have line like:

security.provider.11=org.bouncycastle.jce.provider.BouncyCastleProvider

Then copy Jars with Security Provider into /jre/lib/ext folder

Mikhail Chibel
  • 1,865
  • 1
  • 22
  • 34