JEP 114: TLS SNI Extension - SunJSSE Behavior Changes

Silver Cave, Guilin, China

The implementation of JEP 114 (TLS Server Name Indication (SNI) Extension) had integrated into JDK 8 at October, 2012. This blog entry will talk about some useful behavior changes and user cases that make use of SNI extenstion.  Please refer to javax.net.ssl package of JDK 8 APIs for the detailed specification.

The SNI extension in client mode


In JDK 7, if a SSL/TSL connection specified hostname of the server, and when the hostname is fully qualified domain name (FQDN), the hostname will be used as the default server name indication in ClientHello message, implicitly.

For example:
    SSLSocketFactory factory = ...
    SSLSocket sslSocket = factory.createSocket("www.example.com", 443);

the hostname, "www.example.com" will appear in the server name indication extension in ClientHello message.

While for
    SSLSocketFactory factory = ...
    SSLSocket sslSocket = factory.createSocket("172.16.10.6", 443);

as the hostname is an IP address, No server name indication extension will appear in ClientHello message.

And for
    SSLSocketFactory factory = ...
    SSLSocket sslSocket = factory.createSocket("docs", 443);

although the real hostname may be docs.example.com, but as "docs" is not a fully qualified domain name, No server name indication extension will appear in ClientHello message.

For
    SSLSocketFactory factory = ...
    SSLSocket sslSocket = factory.createSocket("docs.example", 443);

the real hostname may be docs.example.com, although "docs.example" is not a fully qualified domain name, but the computer cannot tell this point. "docs.example" will be regarded as a fully qualified domain name, and server name indication extension will appear in ClientHello message. It is ambiguous!

In JDK 8, developers have a chance to explicitly set the server name indication. It is SSLParameters.setServerNames(List serverNames).

    SSLSocketFactory factory = ...
    SSLSocket sslSocket = factory.createSocket("172.16.10.6", 443);
    // SSLEngine sslEngine = sslContext.createSSLEngine("172.16.10.6", 443);

    SNIHostName serverName = new SNIHostName("www.example.com");
    List serverNames = new ArrayList<>(1);
    serverNames.add(serverName);

    SSLParameters params = sslSocket.getSSLParameters();
    params.setServerNames(serverNames);

    sslSocket.setSSLParameters(params);
    // sslEngine.setSSLParameters(params);

The SNI extension in server mode


In JDK 7, server will ignore all server name indication extension.

In JDK 8, by default, server reserves the behaviors of JDK 7.  For better interoperability, providers generally will not define default matchers so that by default servers will ignore the SNI extension and continue the handshake. However, in JDK 8, server can use SNIMatcher to decide how to recognize server name indication.
        SSLSocket sslSocket = sslServerSocket.accept();
 
        SNIMatcher matcher = SNIHostName.createSNIMatcher(
                                        "www\\.example\\.(com|org)");
        Collection matchers = new ArrayList<>(1);
        matchers.add(matcher);
 
        SSLParameters params = sslSocket.getSSLParameters();
        params.setSNIMatchers(matchers);
        sslSocket.setSSLParameters(params);
Or
        SSLServerSocket sslServerSocket = ...;
 
        SNIMatcher matcher = SNIHostName.createSNIMatcher(
                                        "www\\.example\\.(com|org)");
        Collection matchers = new ArrayList<>(1);
        matchers.add(matcher);
 
        SSLParameters params = sslServerSocket.getSSLParameters();
        params.setSNIMatchers(matchers);
        sslServerSocket.setSSLParameters(params);
 
        SSLSocket sslSocket = sslServerSocket.accept();

If server does not configure the server name matchers, the behavior is the same as JDK 7.
The following table shows the interaction behaviors between server SNI configuration and client request SNI in ClientHello message.

  Server configured matcher           client requested SNI
                             www.example.com    www.invalid.com    empty
 
        www\\.example\\.com       +                    x             v
        www\\.invalid\\.com       x                    +             v
        no matcher                v                    v             v
 
v: accepted server name indication, but no server name confirmation in
   server hello message.
+: accepted server name indication, response with recognized server name
   confirmation in server hello message
x: rejected with unrecognized_name fatal error

For example, if the server name in SNI extension of ClientHello message is "www.example.com", and the server is configured to support "www.example.com", the server will accept the SNI extension, and reply a confirmation in server hello message. However, if the server is configurated to support "www.invalid.com", but not "www.example.com", the server will deny the SNI extension, and response with a unrecognized_name fatal error.


More blog entries about TLS Server Name Indication (SNI) Extension:
TLS Server Name Indication Extension and Unrecognized_name
JEP 114: TLS SNI Extension - SunJSSE Behavior Changes (Continue)
JEP 114: TLS SNI Extension - Typical User Cases
JEP 114: TLS SNI Extension - Virtual Servers Dispatcher

Popular posts from this blog

TLS Server Name Indication Extension and Unrecognized_name

JSSE Oracle Provider Preference of TLS Cipher Suites

JSSE Oracle Provider Default Disabled TLS Cipher Suites