I\'m getting the following error
sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException
The javax.net.ssl.trustStore property, indeed, overrides all known certificates of the JVM with the one you provide.
By default, the JVM comes with a trustStore prepopulated with a fairly decent number of well known authorities (the Oracle JVM stores it in JAVA_HOME/jre/lib/security/cacerts).
This keyStore will be used as the default by the JSSE (Java Secure Socket Extension) by default to validate SSL handshakes.
The javax.net.ssl.trustStore environnement variable overrides this default location, meaning none of its content's are relevant any more.
Going forward, you have a few solutions:
One is : you build your own JKS containing everything you need.
Second is : you add certificates to your JVM's default file.
Third is : you code.
Getting your own SSL Context "by hand" ?
Sockets that underly HTTPURLConnection are made out of SocketFactory
instances.
When HTTPS is involved, what happens is that you need to initialize your own SSLSocketFactory with wathever certificate/private keys are needed for your call, and associate the SocketFactory with the HTTPURLConnection before connecting it : see http://docs.oracle.com/javase/7/docs/api/javax/net/ssl/HttpsURLConnection.html#setSSLSocketFactory%28javax.net.ssl.SSLSocketFactory%29
This works like this. First, you need to load your KeyStore (JKS file containing your certificate, exception handling cut for shortening) :
InputStream keyStoreStream = ... // Wherever it is
KeyStore ks = KeyStore.getInstance("JKS"); // or "PKCS12" for pfx/p12
ks.load(is, password);
Once you have a KeyStore instance, you can build a "TrustManager" that will use any certificates declared as trusted in the Keystore as valid trust anchors.
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); // PKIX
tmf.init(yourKeyStore); // if you pass null, you get the JVM defaults
// which is CACerts file or javax.net.ssl.trustStore
You can do the same for your SSL KeyManagerFactory (if you use 2 way SSL), the pattern is exactly the same. Once you have TrustManagerFactory and KeyManagerFactory instances, you are ready to build a SSLSocketFactory.
SSLContext sslCtx = SSLContext.getInstance("TLS");
sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
SSLSocketFactory sslSF = sslCtx.getSocketFactory();
At this point, you can do
URL url = new URL("https://test.com/test");
URLConnection conn = url.openConnection();
if(conn instanceof HttpsURLConnection) {
((HttpsURLConnection) conn).setSSLSocketFactory(sslSF);
}
conn.connect();