JDK-8144566 : Custom HostnameVerifier disables SNI extension
  • Type: Bug
  • Component: security-libs
  • Sub-Component: javax.net.ssl
  • Affected Version: 8u66,9
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2015-11-24
  • Updated: 2017-11-29
  • Resolved: 2016-04-22
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 JDK 9
8u141Fixed 9 b116Fixed
Related Reports
Duplicate :  
Duplicate :  
Duplicate :  
Relates :  
Relates :  
Sub Tasks
JDK-8181791 :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_66"
Java(TM) SE Runtime Environment (build 1.8.0_66-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.66-b17, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
OS X 10.11.1

A DESCRIPTION OF THE PROBLEM :
Refering to JDK-8072464, which is closed due to "cannot reproduce".
I wonder why your Devs can`t reproduce the problem, but I guess it because of his proxy settings.

Taking the following test and grep for 
Extension server_name, server_name: [type=host_name (0), value=www.google.com]

First method leads to intended output, second method setting hostnameverifier doesn't.


import javax.net.ssl.HttpsURLConnection;
import java.net.URL;

public class SslTest {
	static {
		System.setProperty("javax.net.debug", "ssl,handshake");
	}

	@Test
	public void testHandshake() throws Exception {
		URL url = new URL("https://www.google.com");
		HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
		conn.getInputStream();
	}

	@Test
	public void testHandshakeHostnameVerifier() throws Exception {
		URL url = new URL("https://www.google.com");
		HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
		conn.setHostnameVerifier((s, sslSession) -> true);
		conn.getInputStream();
	}

}

Sorry for the duplicate, but it is not possible to reopen or comment a bug.

REGRESSION.  Last worked in version 8u66

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
import javax.net.ssl.HttpsURLConnection;
import java.net.URL;

public class SslTest {
	static {
		System.setProperty("javax.net.debug", "ssl,handshake");
	}

	@Test
	public void testHandshake() throws Exception {
		URL url = new URL("https://www.google.com");
		HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
		conn.getInputStream();
	}

	@Test
	public void testHandshakeHostnameVerifier() throws Exception {
		URL url = new URL("https://www.google.com");
		HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
		conn.setHostnameVerifier((s, sslSession) -> true);
		conn.getInputStream();
	}

}

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Use of SNI Extension in both test methods

Debug Information contains:

Extension server_name, server_name: [type=host_name (0), value=www.google.com]
ACTUAL -
SNI is used without custom host name verifier only.


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import javax.net.ssl.HttpsURLConnection;
import java.net.URL;

public class SslTest {
	static {
		System.setProperty("javax.net.debug", "ssl,handshake");
	}

	@Test
	public void testHandshake() throws Exception {
		URL url = new URL("https://www.google.com");
		HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
		conn.getInputStream();
	}

	@Test
	public void testHandshakeHostnameVerifier() throws Exception {
		URL url = new URL("https://www.google.com");
		HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
		conn.setHostnameVerifier((s, sslSession) -> true);
		conn.getInputStream();
	}

}
---------- END SOURCE ----------


Comments
Flagging this for backport to an upcoming 8u CPU release as our developers are having to disable host verification to work around this, and there seems to be no schedule for an 8u152 release.
07-04-2017

Consider: SocketFactory sslsf = SSLSocketFactory.getDefault(); SSLSocket ssls = (SSLSocket) sslsf.createSocket(); ssls.connect(new InetSocketAddress("bugs.openjdk.java.net", 443), 0); ssls.startHandshake(); No SNI is sent in this case.
08-12-2015

--------- SSLSocket s = sslSocketFactory.createSocket(); s.connect(socketAddress, timeout); --------- No SNI is expected for the above case, I think. Application needs to specify the hostname explicitly, as server name indication cannot rely on DNS server.
08-12-2015

Looks like you might get into the same situation with the following codepath without a HttpsURLConnection. SSLSocket s = sslSocketFactory.createSocket(); s.connect(socketAddress, timeout); Please check for this situation when investigating. UPDATE: Confirmed. If you do fix in connect, be careful about potential reverse lookups. (getHostString())
08-12-2015

For HttpsURLConnection, the server name may be set after the TLS connection and handshake has been initialized. As may result in that the server name does not present at TLS ClientHello messages. Needs to reset the server name for the initialized handshake for above cases.
06-12-2015

The issue can be reproduces if no proxy. It's weird that proxy impacts the behaviors. Not sure of the root cause, yet.
04-12-2015

Attached test case was executed on JDK 8u 66 and JDK 9EA B85. But could not reproduce the issue. JDK 7u75 - Pass JDK 8u66 - Pass JDK 9EA b85 - Pass Few more similar issues have been reported, please see related bugs. ------------------------------------------------------------------------------------------------------------------------ java TestHostNameVerifier |findstr server_name Extension server_name, server_name: [type=host_name (0), value=google.com] Extension server_name, server_name: Extension server_name, server_name: [type=host_name (0), value=www.google.co.in] Extension server_name, server_name: Extension server_name, server_name: [type=host_name (0), value=kitematic.com] Extension server_name, server_name: Extension server_name, server_name: [type=host_name (0), value=roundcube.net] Extension server_name, server_name: Exception in thread "main" java.io.IOException: Server returned HTTP response co de: 403 for URL: https://roundcube.net/news/2015/11/23/roundcube-webmail-1.2-bet a-out-now/ at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown S ource) at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown So urce) at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unkn own Source) at TestHostNameVerifier.main(TestHostNameVerifier.java:24) ---------------------------------------------------------------------------------------------------------------------------
03-12-2015