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
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"); ListserverNames = 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)"); CollectionOrmatchers = new ArrayList<>(1); matchers.add(matcher); SSLParameters params = sslSocket.getSSLParameters(); params.setSNIMatchers(matchers); sslSocket.setSSLParameters(params);
SSLServerSocket sslServerSocket = ...; SNIMatcher matcher = SNIHostName.createSNIMatcher( "www\\.example\\.(com|org)"); Collectionmatchers = 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