Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Java 8 can HttpsURLConnection be made to send server name indication (SNI)

Tags:

java

ssl

sni

The Oracle documentation seems to indicate Java 8 sends SNI automatically and by default. Wireshark indicates otherwise. I'm a PowerShell sysadmin, not a Java developer, so it's near-certain I'm overlooking something.

When used with the proper trust keystore, the following code returns status 200 from all SSL websites that don't require SNI. It also returns well when connecting to the default SSL website of a multiple-host Apache server. When asked to connect to a non-default site, though, it fails for cert name not matching the site name, since it connects to the default site.

import java.util.*;
import java.net.*;
import javax.net.ssl.*;
import java.io.*;

public class testJavaHttpConn {
    public static void main(String[] args) throws Exception {
        String strUrl = args[0];
        System.out.println("Trying to connect to " + strUrl);
        try {
            URL url = new URL(strUrl);
            HttpsURLConnection urlConn = (HttpsURLConnection) url.openConnection();
            System.out.println("Connecting");
            urlConn.connect();
            System.out.println("Done");
            System.out.println("Response " + urlConn.getResponseCode());
        } catch (IOException e) {
            System.err.println("Error creating HTTP connection");
            e.printStackTrace();
            throw e;
        }
    }
}

I've not set System.setProperty ("jsse.enableSNIExtension", "false"); and when I set -Djavax.net.debug=ssl it clearly shows the server name extension not being set.

I'm aware I can implement an SSLSocket and set the SSLParameter serverName, if I'm willing to dive down to the next deeper layer of abstraction, but I'd like to avoid that.

Edit: The code works as written above for Flo in the comments. It's failing for me with 1.8.0_72 on Linux 2.6.18-194.11.3.el5 and with 1.8.0_51 on Windows 7. The Windows installation is vanilla, while the Linux installation has updated the urandom value to securerandom.source=file:/dev/./urandom. I'm not sure how I can determine what about my installations is different from Flo's.

like image 573
codepoke Avatar asked Feb 12 '16 15:02

codepoke


1 Answers

HttpsURLConnection does send SNI by default and out of the box iff the URL to which it's connecting is a fully qualified name. It doesn't send the SNI for local intranet shortname aliases.

Extension server_name, server_name: [type=host_name (0), value=site.company.com]

(For the record, I also needed to deploy a new certificate with SANs for the short and fully qualified names, but that was trivial.)

like image 67
codepoke Avatar answered Oct 14 '22 12:10

codepoke