5

i have set up a https connection between the server and the client, where the client is a java program and the server is a servlet. I have used the following code to print the certificate details from the server.

URL url = new URL("https://localhost:8443/cert");
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setSSLSocketFactory(sslsocketfactory);

connection.setDoOutput(true);
if(connection!=null){
    Certificate[] certs = connection.getServerCertificates();// #1 

    System.out.println("Cert Type : " + certs[0].getType());
    System.out.println("Cert Hash Code : " + certs[0].hashCode());
    System.out.println("Cert Public Key Algorithm : " + certs[0].getPublicKey().getAlgorithm());
    System.out.println("Cert Public Key Format : " + certs[0].getPublicKey().getFormat());
    System.out.println("\n");
}

But I am getting the following exception.

java.lang.IllegalStateException: connection not yet open

I thought handshake should take place as soon as theurl.openconnection() method in called. What is the problem here?
The Exception is thrown line number '#1'(see comments in the code above)

jww
  • 97,681
  • 90
  • 411
  • 885
Ashwin
  • 12,691
  • 31
  • 118
  • 190

2 Answers2

3

you're trying to connect to a self signed certificate host. Follow the instructions for Option 2 of the answer from this answer, which should allow you connect.

I replaced the connection.setDoOutput() with a connection.connect() and the code worked correctly for me.

Do not use this mechanism for anything other than testing - you should be using a validly signed certificate

Community
  • 1
  • 1
Anya Shenanigans
  • 91,618
  • 3
  • 107
  • 122
  • You don't need to replace it, just add it after the connection.setDooutput(). Yes it is working now. thank you. – Ashwin Mar 08 '12 at 00:50
  • 1
    dear petesh I did not disable the certificate validation. I just did not know that the handshake takes place after the call to connect() method. All along I was thinking that the handshake takesplace as soon as the open() method is called. – Ashwin Mar 08 '12 at 00:54
3

The handshake of an SSLSocket "[...] can be initiated in one of three ways:"

  • calling startHandshake which explicitly begins handshakes, or
  • any attempt to read or write application data on this socket causes an implicit handshake, or
  • a call to getSession tries to set up a session if there is no currently valid session, and an implicit handshake is done.

It seems that the only one applicable via HttpsURLConnection is to try to read/write something (as you can't get hold of the underlying SSLSocket instance directly to start the handshake or get the session).

If you just call connection.getInputStream(); before trying to get the certificate, this should initiate the handshake, and you'll get the certificates afterwards.

Note that you will only reach that point if the certificate you want to see is trusted by your SSLContext/SSLSocketFactory. To do so, you can build a keystore (which you will use as a truststore) that contains that certificate, as described in this answer. You can use if from your own SSLContext or use it globally via the javax.net.ssl.trustStore* system properties (to be set before any SSL usage. Avoid examples of TrustManagers that don't check anything (there are a few here on SO): it will just disable the certificate verification altogether, making the connection potentially vulnerable to MITM attacks.

Community
  • 1
  • 1
Bruno
  • 119,590
  • 31
  • 270
  • 376
  • 1
    I think the handshsake also takes place when the connect() method is called. Is there a way to print the handshake details. I mean like during each step of the handshake(eg printing secrete key exchanged etc) – Ashwin Mar 09 '12 at 00:47
  • 1
    Yes, `connect()` should do too. To see the details, use this system property: `-Djavax.net.debug=ssl` (see [this](http://docs.oracle.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#Debug) and [this](http://docs.oracle.com/javase/6/docs/technotes/guides/security/jsse/ReadDebug.html)). – Bruno Mar 09 '12 at 00:51