Server Name Indication (SNI) Extension

The SNI extension is a feature that extends the SSL/TLS protocols to indicate what server name the client is attempting to connect to during handshaking. Servers can use server name indication information to decide whether specific SSLSocket or SSLEngine instances should accept a connection. For example, when multiple virtual or name-based servers are hosted on a single underlying network address, the server application can use SNI information to determine whether this server is the exact server that the client wants to access. Instances of this class can be used by a server to verify the acceptable server names of a particular type, such as host names. For more information, see section 3 of TLS Extensions (RFC 6066). Developers of client applications can explicitly set the server name indication by using the SSLParameters.setServerNames(List<SNIServerName> serverNames) method. The following example illustrates this function:
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<SNIServerName> serverNames = new ArrayList<>(1);
serverNames.add(serverName);

SSLParameters params = sslSocket.getSSLParameters();
params.setServerNames(serverNames);
sslSocket.setSSLParameters(params);
// sslEngine.setSSLParameters(params);

Developers of server applications can use the SNIMatcher class to decide how to recognize server name indication. The following two examples illustrate this function:

Example 1

SSLSocket sslSocket = sslServerSocket.accept();

SNIMatcher matcher = SNIHostName.createSNIMatcher("www\\.example\\.(com|org)");
Collection<SNIMatcher> matchers = new ArrayList<>(1);
matchers.add(matcher);

SSLParameters params = sslSocket.getSSLParameters();
params.setSNIMatchers(matchers);
sslSocket.setSSLParameters(params);

Example 2

 
SSLServerSocket sslServerSocket = ...;

SNIMatcher matcher = SNIHostName.createSNIMatcher("www\\.example\\.(com|org)");
Collection<SNIMatcher> matchers = new ArrayList<>(1);
matchers.add(matcher);

SSLParameters params = sslServerSocket.getSSLParameters();
params.setSNIMatchers(matchers);
sslServerSocket.setSSLParameters(params);

SSLSocket sslSocket = sslServerSocket.accept();
The following list provides examples for the behavior of the SNIMatcher class when receiving various server name indication requests in the ClientHello message:
  • Matcher is configured to www\\.example\\.com:
    • If the requested host name is www.example.com, the request is accepted and a confirmation is sent in the ServerHello message.
    • If the requested host name is www.example.org, the request is rejected with an unrecognized_name unrecoverable error.
    • If there is no requested host name or it is empty, the request is accepted but no confirmation is sent in the ServerHello message.
  • Matcher is configured to www\\.invalid\\.com:
    • If the requested host name is www.example.com, the request is rejected with an unrecognized_name unrecoverable error.
    • If the requested host name is www.example.org, the request is accepted and a confirmation is sent in the ServerHello message.
    • If there is no requested host name or it is empty, the request is accepted but no confirmation is sent in the ServerHello message.
  • Matcher is not configured:
    • Any requested host name is accepted but no confirmation is sent in the ServerHello message.
For descriptions of new classes that implement the SNI extension, see: For examples, see Using the Server Name Indication (SNI) Extension.