Certificate chaining error in Websphere

Ayan Biswas picture Ayan Biswas · Dec 30, 2014 · Viewed 49.9k times · Source

I am trying to consume a RESTful service from url https://someurl.com. I have added the following properties in my code:

 Security.setProperty("ssl.SocketFactory.provider", "com.ibm.jsse2.SSLSocketFactoryImpl");
 Security.setProperty("ssl.ServerSocketFactory.provider", "com.ibm.jsse2.SSLServerSocketFactoryImpl");
 Security.setProperty("javax.net.ssl.trustStore", "cacerts.jks");
 Security.setProperty("javax.net.ssl.keyStore", "keystore.jks");
 Security.setProperty("javax.net.ssl.keyStoreType", "pkcs12");
 Security.setProperty("javax.net.ssl.trustStoreType", "JKS");

The configuration changes that I have done so far are:

  1. set com.ibm.websphere.ssl.retrieveLeafCert to true
  2. retrieved the certificate using url as someurl and port 443 and added it to the truststore.
  3. restarted the server

But I am getting the following exception:

java.security.cert.CertPathValidatorException: Certificate chaining error
javax.net.ssl.SSLHandshakeException: com.ibm.jsse2.util.h: PKIX path building failed:          java.security.cert.CertPathBuilderException: PKIXCertPathBuilderImpl could not build a valid CertPath.; internal cause is:
  java.security.cert.CertPathValidatorException: The certificate issued by CN=Walmart Root CA, O=Wal-Mart Stores Inc is not trusted; internal cause is:
  java.security.cert.CertPathValidatorException: Certificate chaining error
  at com.ibm.jsse2.o.a(o.java:22)
  at com.ibm.jsse2.SSLSocketImpl.a(SSLSocketImpl.java:423)
  at com.ibm.jsse2.kb.a(kb.java:192)
  at com.ibm.jsse2.kb.a(kb.java:176)
  at com.ibm.jsse2.lb.a(lb.java:53)
  at com.ibm.jsse2.lb.a(lb.java:464)
  at com.ibm.jsse2.kb.s(kb.java:545)
  at com.ibm.jsse2.kb.a(kb.java:530)
  at com.ibm.jsse2.SSLSocketImpl.a(SSLSocketImpl.java:79)
  at com.ibm.jsse2.SSLSocketImpl.h(SSLSocketImpl.java:437)
  at com.ibm.jsse2.SSLSocketImpl.a(SSLSocketImpl.java:142)
  at com.ibm.jsse2.SSLSocketImpl.startHandshake(SSLSocketImpl.java:686)
  at com.ibm.net.ssl.www2.protocol.https.c.afterConnect(c.java:98)
  at com.ibm.net.ssl.www2.protocol.https.d.connect(d.java:13)
  at com.ibm.net.ssl.www2.protocol.https.b.connect(b.java:6)
  at com.dwl.tcrm.tester.RESTClient_2.main(RESTClient_2.java:76)

Answer

Gas picture Gas · Dec 30, 2014

I'm assuming you have a web application, which is trying to access that restful service.

First, you should not set your stores via javax.net.ssl.* properties, but use SSL configurations provided in WebSphere. So comment all these setProperty() calls. Second, you have to add your service server certificate to the trust store.

Login to web admin console:

  • Go to Security > SSL certificate and key management > Key stores and certificates > NodeDefaultTrustStore > Signer certificates
  • Click Retrieve from port button, and specify hostname, 443 port, and Alias.
  • Click Retrieve singer information button.
  • Verify, if correct certificate is imported (parent).
  • Save, and restart.

In some versions, the child certificate was imported (not the root), in that case, you will have to manually download the root certificate and intermediate (e.g. via browser, and import that one to the NodeDefaultTrustStore, but this time using Add button, not Retrieve..