user1549994 user1549994 - 5 months ago 24
Java Question

Behavior of HttpsURLConnectioin with default implementation of HostnameVerifier and SSLSocketFactory

I am trying to understand a piece of code that does not override HostnameVerifier and SSLSocketFactory for HttpsURLConnection. The current code is able to make the SSL request fine, which is a little confusing to me.
How does the default implementation of HostnameVerifier and SSLSocketFactory classes work? Does it verify the certificate CA and hostname or it bypasses all these checks all together?

Also, is there any special behavior if the request has localhost in it?
The URL looks like this

https://localhost:/

Thanks for your help.

Answer

It will check the CA certificate against the trusted ca-certificates in the trusted store of the JDK jre/lib/security/cacerts or whatever you have configured.

It will also check, that all certificates in the chain are trusted, not only the immediate signer. It will, by default, not check online for revoked certificates, but you can enable that in the java.security policy file.

It will also check the hostname against the certificate. It supports additional CNs and wildcard CNs.

Extended question regarding localhost:

localhost is just a hostname like any other. It must be listed in the certificate. But you will not find an official CA to give you that certificate, I guess :-)

If you want to play with your real cert on localhost, you address it with a different hostname. If you want to run through a cert for foo.bar.com, add to your hosts file (Win: %WINDOWS%\system32\drivers\etc\hosts, Unix /etc/hosts) the line:

127.0.0.1 foo.bar.com

Now fire up your browser and connect to https://foo.bar.com. It will connect to your local server and post a SSL encrypted HTTP request. That request contains the hostname from the URL, not the real hostname.

I was oversimplyfying: The browser receives the SSL certificate from the server and compares the CN against the hostname it just called. If this matches, it will check if the certificate can be trusted (don't nail me down on the order, maybe it will check the trustlevel first).

Here is where you fail: The certificate provided by the server does not contain the CN localhost, and thus, the client will abort the connection. In your case, the client is the HttpSSLrequest.

To make the client believe all is well, you can do two things: - fake the hostname, and add the signing CA in the cacerts truststore. - implement a hostname and certificate validator, that lets you through.

Regarding the tutorial, a self-signed certificate is used, you will have to convince the browser to accept it by overriding the warning on first access.