JDK-8223677 : Custom HostnameVerifier gets ignored and receive SSLHandshakeException with unrecognized_name message
  • Type: Bug
  • Component: security-libs
  • Sub-Component: javax.net.ssl
  • Affected Version: 8,11,12,13
  • Priority: P4
  • Status: Closed
  • Resolution: Not an Issue
  • OS: linux
  • CPU: x86_64
  • Submitted: 2019-05-08
  • Updated: 2019-05-28
  • Resolved: 2019-05-28
Description
ADDITIONAL SYSTEM INFORMATION :
Linux / Java 11

A DESCRIPTION OF THE PROBLEM :
On Java 11 setting a HostnameVerifier gets ignored:

        final URL url = new URL("https://www.minervamedica.it");
        final HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
        conn.setHostnameVerifier((s, sslSession) -> true);
        System.out.println(new String(conn.getInputStream().readAllBytes()));

Exception in thread "main" javax.net.ssl.SSLHandshakeException: received handshake warning: unrecognized_name
	at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
	at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:308)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:264)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:255)
	at java.base/sun.security.ssl.Alert$AlertConsumer.consume(Alert.java:272)
	at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:181)
	at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:164)
	at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1152)
	at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1063)
	at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:402)
	at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:567)
	at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
	at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1581)
	at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1509)
	at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:245)


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run code above.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Should ignore a misconfigured server name.
ACTUAL -
Throws javax.net.ssl.SSLHandshakeException: received handshake warning: unrecognized_name

---------- BEGIN SOURCE ----------
public class DebugHttp {

    public static void main(final String[] args) throws IOException {

        final URL url = new URL("https://www.minervamedica.it");
        final HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
        conn.setHostnameVerifier((s, sslSession) -> true);
        System.out.println(new String(conn.getInputStream().readAllBytes()));

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

CUSTOMER SUBMITTED WORKAROUND :
Setting System.setProperty("jsse.enableSNIExtension", "false") does help, but using this system property would cause any following request to a host depending on SNI to fail.

The problem is, that there is no workaround for dynamically dealing with this situation. In proxy / crawler like situation it is not possible to fix misconfigured external servers.

FREQUENCY : always



Comments
"unrecognized_name" means the server side does not recognize the server name present in the SNI extension. It might not be related to the client side hostname verifier configuration. Please check the server side configuration. Close it as "not an issue".
28-05-2019