Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Verifying SSL Certificate's Common Name in Java

I'm opening a secure SSL socket to port 12345 on my server. I'm using a self-signed certificate for now. I installed the cert into my server keystore and client truststore; fine, blah blah noise.

I'm building off this example: http://www.exampledepot.com/egs/javax.net.ssl/Client.html

The client correctly verifies that the server has a signed certificate. The client does NOT appear to be verifying that the certificate CN (Common Name) presented matches the hostname of the server I'm connecting to. Obviously it's not difficult to get a signed certificate if there is no requirement that it match the requested domain.

When I install my certificate (using keytool --import), am I installing it as a root-level certificate? Do I need to sign a second certificate using the primary key of the first certificate? Why is the TrustManager not verifying the common name?

I hope that made sense and I'm not over-thinking this whole thing.

Thanks!

UPDATE: It appears that Java SSL might require that certificates be verified manually? (http://www.java2s.com/Open-Source/Java-Document/Net/Apache-common-HttpClient/org/apache/commons/httpclient/contrib/ssl/StrictSSLProtocolSocketFactory.java.htm) Could this really be true? I would have expected the default to be secure, and anything less would require an explicit override. I'm surprised. Can someone confirm?

like image 353
Jim Avatar asked Dec 23 '10 03:12

Jim


2 Answers

Verifying the hostname is up to the application. It is built in to Java in the case of HTTPS via the HttpsURLConnection and HostnameVerifier classes. If you're using an SSLSocket directly it is up to you, typically via a HandshakeCompletedListener.

like image 154
user207421 Avatar answered Oct 19 '22 23:10

user207421


Do you possibly have some code like this? This will ignore hostname mismatch that you have mentioned.

HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier(){
    public boolean verify(String string,SSLSession ssls) {
        return true;
    }
});

Otherwise, as one of the comments in this link says, you would get an exception HTTPS hostname wrong: should be...

like image 25
Raghuram Avatar answered Oct 19 '22 23:10

Raghuram