JDK-8211339 : NPE during SSL handshake caused by HostnameChecker
  • Type: Bug
  • Component: security-libs
  • Sub-Component: javax.net.ssl
  • Affected Version: 8,11,12
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2018-09-24
  • Updated: 2021-01-20
  • Resolved: 2018-11-06
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 11 JDK 12 JDK 8 Other
11.0.8-oracleFixed 12 b19Fixed 8u261Fixed openjdk8u292Fixed
Description
ADDITIONAL SYSTEM INFORMATION :
This happens with Java8 and Java11 as well:

 java -version
java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)

java -version
java version "11" 2018-09-25
Java(TM) SE Runtime Environment 18.9 (build 11+28)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11+28, mixed mode)

A DESCRIPTION OF THE PROBLEM :
While trying to write some test code for netty I did something stupid while creating the SSLEngine by passing a hostname as parameter for the server which then ended up in an NPE during handshake. I would argue we should not fail with a NPE.

Basically something like:

SSLEngine serverEngine = serverCtx.createSSLEngine("localhost", -1);


I think this is caused by sun.security.ssl.X509TrustManagerImpl.checkIdentity(������������) missing a null check for the hostname before calling sun.security.util.HostnameChecker.match(������������)

A full reproduce (which I extracted from my netty testcase)  can be found here (there is a README.md which explains how to run it):

https://github.com/normanmaurer/jdk_ssl_npe_reproducer

The stack I see is:

Exception in thread "main" java.lang.RuntimeException: Delegated task threw Exception/Error
	at sun.security.ssl.Handshaker.checkThrown(Handshaker.java:1527)
	at sun.security.ssl.SSLEngineImpl.checkTaskThrown(SSLEngineImpl.java:535)
	at sun.security.ssl.SSLEngineImpl.writeAppRecord(SSLEngineImpl.java:1214)
	at sun.security.ssl.SSLEngineImpl.wrap(SSLEngineImpl.java:1186)
	at javax.net.ssl.SSLEngine.wrap(SSLEngine.java:469)
	at JDKSslReproducer.handshake(JDKSslReproducer.java:76)
	at JDKSslReproducer.main(JDKSslReproducer.java:51)
Caused by: java.lang.NullPointerException
	at sun.net.util.IPAddressUtil.textToNumericFormatV4(IPAddressUtil.java:49)
	at sun.net.util.IPAddressUtil.isIPv4LiteralAddress(IPAddressUtil.java:241)
	at sun.security.util.HostnameChecker.isIpAddress(HostnameChecker.java:125)
	at sun.security.util.HostnameChecker.match(HostnameChecker.java:93)
	at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:455)
	at sun.security.ssl.AbstractTrustManagerWrapper.checkAdditionalTrust(SSLContextImpl.java:1068)
	at sun.security.ssl.AbstractTrustManagerWrapper.checkServerTrusted(SSLContextImpl.java:1007)
	at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1601)
	at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
	at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1052)
	at sun.security.ssl.Handshaker$1.run(Handshaker.java:992)
	at sun.security.ssl.Handshaker$1.run(Handshaker.java:989)
	at java.security.AccessController.doPrivileged(Native Method)
	at sun.security.ssl.Handshaker$DelegatedTask.run(Handshaker.java:1467)
	at JDKSslReproducer.runDelegatedTasks(JDKSslReproducer.java:131)
	at JDKSslReproducer.handshake(JDKSslReproducer.java:99)
	... 1 more

This only happens if a X509Trustmanager is used (not the Extended version) and when  setEndpointIdentificationAlgorithm(������������) is used on the client-side.


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
https://github.com/normanmaurer/jdk_ssl_npe_reproducer


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
No NPE
ACTUAL -
NPE during validation

---------- BEGIN SOURCE ----------
https://github.com/normanmaurer/jdk_ssl_npe_reproducer
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
None...

FREQUENCY : always



Comments
Fix request (8u) I'd like to have this fix in 8u as the release is affected by this bug. Having this fix will also contribute to parity between JDKs. The patch applies cleanly after replacing paths to the pre-modules scheme. sun/security/util/HostnameMatcher/NullHostnameCheck.java test passes. Risk is low.
19-01-2021

Fix request (11u) I would like to downport this change. Applies clean. While looking at "JDK-8234728: Some security tests should support TLSv1.3" I ran into this change. 8234728 changes a test introduced here. The fix looks to me as if it makes sense in 11, too. Testing is fine.
03-04-2020

To reproduce the issue, run the attached test case. JDK 8u181 - Fail JDK 11+28 - Fail JDK 12-ea+10 - Fail Output on JDK 8u181: Exception in thread "main" java.lang.RuntimeException: Delegated task threw Exception/Error at sun.security.ssl.Handshaker.checkThrown(Handshaker.java:1527) at sun.security.ssl.SSLEngineImpl.checkTaskThrown(SSLEngineImpl.java:535) at sun.security.ssl.SSLEngineImpl.writeAppRecord(SSLEngineImpl.java:1214) at sun.security.ssl.SSLEngineImpl.wrap(SSLEngineImpl.java:1186) at javax.net.ssl.SSLEngine.wrap(SSLEngine.java:469) at JDKSslReproducer.handshake(JDKSslReproducer.java:76) at JDKSslReproducer.main(JDKSslReproducer.java:51) Caused by: java.lang.NullPointerException at sun.net.util.IPAddressUtil.textToNumericFormatV4(IPAddressUtil.java:49) at sun.net.util.IPAddressUtil.isIPv4LiteralAddress(IPAddressUtil.java:241) at sun.security.util.HostnameChecker.isIpAddress(HostnameChecker.java:125) at sun.security.util.HostnameChecker.match(HostnameChecker.java:93) at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:455) at sun.security.ssl.AbstractTrustManagerWrapper.checkAdditionalTrust(SSLContextImpl.java:1068) at sun.security.ssl.AbstractTrustManagerWrapper.checkServerTrusted(SSLContextImpl.java:1007) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1601) at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216) at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1052) at sun.security.ssl.Handshaker$1.run(Handshaker.java:992) at sun.security.ssl.Handshaker$1.run(Handshaker.java:989) at java.security.AccessController.doPrivileged(Native Method) at sun.security.ssl.Handshaker$DelegatedTask.run(Handshaker.java:1467) at JDKSslReproducer.runDelegatedTasks(JDKSslReproducer.java:131) at JDKSslReproducer.handshake(JDKSslReproducer.java:99) ... 1 more Output on JDK 11 and 12-ea: Exception in thread "main" java.lang.NullPointerException at java.base/sun.net.util.IPAddressUtil.textToNumericFormatV4(IPAddressUtil.java:49) at java.base/sun.net.util.IPAddressUtil.isIPv4LiteralAddress(IPAddressUtil.java:241) at java.base/sun.security.util.HostnameChecker.isIpAddress(HostnameChecker.java:117) at java.base/sun.security.util.HostnameChecker.match(HostnameChecker.java:95) at java.base/sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:459) at java.base/sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:445) at java.base/sun.security.ssl.AbstractTrustManagerWrapper.checkAdditionalTrust(SSLContextImpl.java:1583) at java.base/sun.security.ssl.AbstractTrustManagerWrapper.checkServerTrusted(SSLContextImpl.java:1524) at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.checkServerCerts(CertificateMessage.java:1307) at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.onConsumeCertificate(CertificateMessage.java:1204) at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.consume(CertificateMessage.java:1151) at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392) at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:444) at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1065) at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1052) at java.base/java.security.AccessController.doPrivileged(Native Method) at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask.run(SSLEngineImpl.java:999) at JDKSslReproducer.runDelegatedTasks(JDKSslReproducer.java:131) at JDKSslReproducer.handshake(JDKSslReproducer.java:99) at JDKSslReproducer.main(JDKSslReproducer.java:51)
01-10-2018

OpenJDK mail thread : http://mail.openjdk.java.net/pipermail/security-dev/2018-September/018332.html
25-09-2018