Connecting to Secure Server in Java using Apache Commons HttpClient 3.1 throwing ValidatorException

StackOverflow https://stackoverflow.com/questions/1623924

  •  06-07-2019
  •  | 
  •  

Question

I am trying to connect to a secure server using Apache Commons HttpClient 3.1.
The problem is everytime the application connects it throws a

sun.security.validator.ValidatorException.

Here is the stacktrace:

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: subject/issuer name chaining check failed javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: subject/issuer name chaining check failed at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1611) at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:187) at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:181) at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1035) at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:124) at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:516) at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:454) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:884) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1112) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:623) at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:59) at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65) at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123) at org.apache.commons.httpclient.methods.EntityEnclosingMethod.writeRequestBody(EntityEnclosingMethod.java:506) at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2114) at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096) at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398) at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171) at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397) at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323) at balanceschecker.connector.Connector.conn(Connector.java:27) at balanceschecker.connector.Connector.RawPost(Connector.java:99) at balanceschecker.connector.Connector.Post(Connector.java:111) at balanceschecker.login.Login.Login(Login.java:87) at balanceschecker.Main.main(Main.java:21) Caused by: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: subject/issuer name chaining check failed at sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:251) at sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:234) at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:158) at sun.security.validator.Validator.validate(Validator.java:218) at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:126) at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:209) at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249) at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1014) ... 21 more Caused by: java.security.cert.CertPathValidatorException: subject/issuer name chaining check failed at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:139) at sun.security.provider.certpath.PKIXCertPathValidator.doValidate(PKIXCertPathValidator.java:326) at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:178) at java.security.cert.CertPathValidator.validate(CertPathValidator.java:250) at sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:246) ... 28 more

Heres the code I am using (edited and compacted a bit)

installAllTrustManager();

PostMethod post = new PostMethod(server_path);
NameValuePair[] data = new NameValuePair {
   new NameValuePair("Username", username), 
   new NameValuePair("Password", password) 
};
        post.setRequestBody(data);
        post.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(3, false));
try {
            HttpClient hc = new HttpClient();
            int result2 = hc.executeMethod(post);
            if (result2 != HttpStatus.SC_OK) {
                throw new IOException("HTTP Status Not OK: " + result2);
            }
            return post.getResponseBodyAsStream();
        } finally {
            post.releaseConnection();
        }

I had a look at the site's certificates and they are still valid for over a year. I then tried to bypass the certificate check using the code shown in "How to bypass trusted host and certificate check in Java", however the exception is still thrown.

What am I doing wrong?
How can I connect successfully to the server?

Was it helpful?

Solution

This error means it can't validate the certificate chain. Possible causes are,

  1. The root CA is not trusted by your JRE.
  2. The certificate is signed by an intermediate cert but server is not sending it along with the cert.

Here is how get a list of root cert,

keytool -list -keystore $JAVA_HOME/lib/security/cacerts -v

I don't know any Java way to check if intermediate cert is sent. I use openssl for that,

openssl s_client -host example.com -port 443

Will show you all the certificate sent by server. Pay attention to "Certificate chain".

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top