views:

676

answers:

1

Hi,

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". Heres 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?

+1  A: 

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".

ZZ Coder