This question is similar to How to use PEM file to create a SSL socket in Java? however I cannot seem to get the suggested solutions working from that question. I used to be able to connect to a .Net Web Service but now they have implemented SLL through certificates, I can no longer access it. The server team have provided me with a cert that will enable me to connect to the Web Service again. And I have confirmed this as working using curl:
curl -E cer_file.pem:password https://hostname/servicename.svc?wsdl
So, the above returns the wsdl correctly. I had to create .cacert.pem file for the curl call to work correctly, to avoid this message (curl: (77) error setting certificate verify locations):
curl http://curl.haxx.se/ca/cacert.pem > .cacert.pem
export SSL_CERT_FILE=/Users/jcran/.cacert.pem
Now when I am trying to use the below Java, I am still getting a 403. I was wondering if anyone can spot what I am doing wrong?
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSocketFactory;
public class TestSSL {
private static final String WS_URL
= "https://hostname/servicename.svc?wsdl";
private static final String KS_FILE
= "C:/tstfolder/client_side_keystore.jks";
private static final String TS_FILE
= "C:/tstfolder/curl_trusted_ca.jks";
public static void main(String... args) throws Exception {
testConn();
}
public static void testConn() throws Exception {
System.setProperty("javax.net.ssl.keyStore", KS_FILE);
System.setProperty("javax.net.ssl.keyStoreType", "jks");
System.setProperty("javax.net.ssl.keyStorePassword", "importkey");
System.setProperty("javax.net.ssl.trustStoreType", "jks");
System.setProperty("javax.net.ssl.trustStore", TS_FILE);
System.setProperty("javax.net.ssl.trustStorePassword", "password");
System.setProperty("javax.net.debug", "all");
SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
URL url = new URL(WS_URL);
HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();
conn.setSSLSocketFactory(sslsocketfactory);
InputStream inputstream = conn.getInputStream();
InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
BufferedReader bufferedreader = new BufferedReader(inputstreamreader);
String string = null;
while ((string = bufferedreader.readLine()) != null) {
System.out.println("Received " + string);
}
}
}
Below are the steps that I used to create the truststore and the keystore. Break the cer_file.pem into a seperate cert.pem and key.pem. Then using the directions at the following link http://www.agentbob.info/agentbob/79-AB.html , I created the client_side_keystore.jks. And then I created the trust store by importing the curl certs file into a jks using the utility found at http://code.google.com/p/java-keyutil/
Unfortunately when I try and read the wsdl through the java test class, I get a 403. Where-as it works through the curl call. I suspect I am doing something silly, or else mis-understanding something. But I was wondering if someone could point me in the right direction?