We are getting "Certificate chaining error" while using Apache CXF WebClient (ver - 3.3.4) on Websphere 8.5 (IBM JDK 8) to invoke a PATCH request using "use.async.http.conduit". We used "tlsClientParameters.setUseHttpsURLConnectionDefaultSslSocketFactory(true)" for fixing the certificate issue for other requests - "POST/GET" which do not use "use.async.http.conduit". We tried manually setting the TrustManagers and KeyManagers but nothing is working with PATCH.
private WebClient getWebClient(String servicePath, List<Object> providers) {
WebClient client = providers != null ? WebClient.create(servicePath, providers, true)
: WebClient.create(servicePath);
client.header(AUTHORIZATION_HEADER, requestInfoBean.getAuthorizationDto().getJwtToken());
client.header(DEVICE_ID_HEADER, requestInfoBean.getAuthorizationDto().getDeviceId());
setTLSClientParameters(client);
return client;
}
private void setTLSClientParameters(WebClient client) {
Conduit conduit = WebClient.getConfig(client).getConduit();
if (conduit instanceof HTTPConduit) {
HTTPConduit httpConduit = (HTTPConduit) conduit;
TLSClientParameters tlsClientParameters = getOrCreateAndSetTLSClientParameters(httpConduit);
tlsClientParameters.setUseHttpsURLConnectionDefaultSslSocketFactory(true);
tlsClientParameters.setUseHttpsURLConnectionDefaultHostnameVerifier(false);
tlsClientParameters.setDisableCNCheck(true);
try {
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init((KeyStore) null);
tlsClientParameters.setTrustManagers(tmf.getTrustManagers());
tlsClientParameters.setKeyManagers(new KeyManager[0]);
tlsClientParameters.setSslContext(SSLUtils.getSSLContext(tlsClientParameters));
} catch (GeneralSecurityException e) {
}
httpConduit.setTlsClientParameters(tlsClientParameters);
}
}
private TLSClientParameters getOrCreateAndSetTLSClientParameters(HTTPConduit httpConduit) {
TLSClientParameters tlsClientParameters = httpConduit.getTlsClientParameters();
if (tlsClientParameters == null) {
tlsClientParameters = new TLSClientParameters();
httpConduit.setTlsClientParameters(tlsClientParameters);
}
return tlsClientParameters;
}
And then we are invoking the PATCH request as follows.
WebClient client = getWebClient(servicePath, providers);
WebClient.getConfig(client).getRequestContext().put(AsyncHTTPConduit.USE_ASYNC, true);
Response response = client.type(CONTENT_TYPE_HEADER).invoke("PATCH", updateProfileRqDto);
The code throws below certificate chaining exception.
Caused by: java.security.cert.CertPathValidatorException: The certificate issued by CN=***, O=***, L=***, ST=***, C=** is not trusted; internal cause is:
java.security.cert.CertPathValidatorException: Certificate chaining error
at com.ibm.security.cert.BasicChecker.<init>(BasicChecker.java:111)
at com.ibm.security.cert.PKIXCertPathValidatorImpl.engineValidate(PKIXCertPathValidatorImpl.java:220)
at com.ibm.security.cert.PKIXCertPathBuilderImpl.myValidator(PKIXCertPathBuilderImpl.java:749)
at com.ibm.security.cert.PKIXCertPathBuilderImpl.buildCertPath(PKIXCertPathBuilderImpl.java:661)
at com.ibm.security.cert.PKIXCertPathBuilderImpl.buildCertPath(PKIXCertPathBuilderImpl.java:607)
at com.ibm.security.cert.PKIXCertPathBuilderImpl.buildCertPath(PKIXCertPathBuilderImpl.java:607)
at com.ibm.security.cert.PKIXCertPathBuilderImpl.engineBuild(PKIXCertPathBuilderImpl.java:368)
... 25 more
Caused by: java.security.cert.CertPathValidatorException: Certificate chaining error
at com.ibm.security.cert.CertPathUtil.findIssuer(CertPathUtil.java:316)
at com.ibm.security.cert.BasicChecker.<init>(BasicChecker.java:108)
... 31 more
Please note that the code is running fine on Tomcat 9 server. Also we have imported the required certificates (the complete certificate chain) in Websphere truststore as well as in JVM but the issue still persists.