JDK-8213782 : NullPointerException in sun.security.ssl.OutputRecord.changeWriteCiphers
  • Type: Bug
  • Component: security-libs
  • Sub-Component: javax.net.ssl
  • Affected Version: 11,12
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: os_x
  • CPU: x86
  • Submitted: 2018-11-09
  • Updated: 2020-11-20
  • Resolved: 2018-12-15
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 13 JDK 8 Other
11.0.3-oracleFixed 12 b25Fixed 13Fixed 8u261Fixed openjdk8u272Fixed
Description
ADDITIONAL SYSTEM INFORMATION :
MacOS Mojave

A DESCRIPTION OF THE PROBLEM :
I'm getting a NullPointerException when trying to establish an SSL connection from a Java 11 client to a C++ server running on the same macOS Mojave platform. The C++ server uses the macOS SecureTransport APIs for SSL communications and only access TLS connection up to 1.1 (rejects TLS 1.2/1.3).


REGRESSION : Last worked in version 8u191

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
brew install ice
git clone https://github.com/zeroc-ice/ice-demos -b 3.7
cd ice-demos/java
./gradlew build
cd Glacier2/callback
java -jar build/libs/server.jar &
glacier2router --Ice.Config=config.glacier2 --IceSSL.ProtocolVersionMax=tls1_1 &
java -jar build/libs/client.jar

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Successful connection establishment after filling username / password.
ACTUAL -
!! 11/9/18 11:16:21:951 Client: error: Ice.ThreadPool.Client-0: exception in `Ice.ThreadPool.Client':
   java.lang.NullPointerException
   	at java.base/sun.security.ssl.OutputRecord.changeWriteCiphers(OutputRecord.java:173)
   	at java.base/sun.security.ssl.ChangeCipherSpec$T10ChangeCipherSpecProducer.produce(ChangeCipherSpec.java:112)
   	at java.base/sun.security.ssl.Finished$T12FinishedProducer.onProduceFinished(Finished.java:392)
   	at java.base/sun.security.ssl.Finished$T12FinishedProducer.produce(Finished.java:376)
   	at java.base/sun.security.ssl.SSLHandshake.produce(SSLHandshake.java:436)
   	at java.base/sun.security.ssl.ServerHelloDone$ServerHelloDoneConsumer.consume(ServerHelloDone.java:173)
   	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 com.zeroc.IceSSL.TransceiverI.handshakeNonBlocking(TransceiverI.java:343)
   	at com.zeroc.IceSSL.TransceiverI.initialize(TransceiverI.java:61)
   	at com.zeroc.Ice.ConnectionI.initialize(ConnectionI.java:2111)
   	at com.zeroc.Ice.ConnectionI.message(ConnectionI.java:1093)
   	at com.zeroc.IceInternal.ThreadPool.run(ThreadPool.java:417)
   	at com.zeroc.IceInternal.ThreadPool.access$500(ThreadPool.java:12)
   	at com.zeroc.IceInternal.ThreadPool$EventHandlerThread.run(ThreadPool.java:786)
   	at java.base/java.lang.Thread.run(Thread.java:834)


CUSTOMER SUBMITTED WORKAROUND :
Disabling TLS 1.2 and 1.3 in the Java client:
java -jar build/libs/client.jar --IceSSL.Protocols="TLS1_1"


FREQUENCY : always



Comments
Fix Request Backporting this fix makes 11u reply with proper message to the clients, instead of NPEing internally. Patch applies cleanly to 11u and passes jdk_security test suite.
19-02-2019

The bug report for the MacOS SecureTransport issue: https://bugreport.apple.com/web/?problemID=46746715
17-12-2018

I did not add new regression test. The update is straightforward, while constructing an illegal handshake message for such cases is complicated.
14-12-2018

Here is the handshake message that the server is using GCM cipher suite for TLS 1.1. Please note the "server version" and "cipher suite" field. javax.net.ssl|DEBUG|0B|Ice.ThreadPool.Client-0|2018-11-30 14:15:25.424 GMT|ServerHello.java:866|Consuming ServerHello handshake message ( "ServerHello": { "server version" : "TLSv1.1", "random" : "5C 01 45 FD F9 40 6F AE 47 91 AF 17 D7 45 C7 EB BD B8 CA 66 0A 2D 64 0A FB C4 9E BF CA D0 20 F2", "session id" : "F3 88 58 C7 36 83 E6 45 3D 7E D8 9A F8 BA 2D 6C BE D3 E1 C8 1E 56 41 6A CA A5 F8 30 C4 AA 85 6E", "cipher suite" : "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384(0xC030)", "compression methods" : "00", "extensions" : [ "renegotiation_info (65,281)": { "renegotiated connection": [<no renegotiated connection>] }, "extended_master_secret (23)": { <empty> } ] } )
14-12-2018

Per the debug log, the server is using GCM mode for TLS 1.1. GCM mode is only available for TLS 1.2 and later versions. The server behavior is non-compliant with TLS 1.1. Downgrade the priority to P3 as this is third party vendor's implementation problem. The primary problem is Apple needs to fix the problem on their server to not use GCM for TLS 1.1. There is an improvement we can make in JDK - check null pointe and send back "illegal_parameter" alert (See RFC 5288). --------------------------- "ServerHello": { "server version" : "TLSv1.1", "random" : "5C 01 46 39 D8 6A 9B 18 A4 D7 C4 44 9B C6 24 91 ED AC F6 3E 42 A8 98 46 EF AC A4 27 80 F3 AE 4D", "session id" : "9A 7C DD AA A1 E4 A1 8E 1C 89 A0 50 62 91 50 2D 3C F0 3E F7 E7 F5 89 F4 C0 67 66 78 55 6E DA D1", "cipher suite" : "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384(0xC030)", "compression methods" : "00", "extensions" : [ "renegotiation_info (65,281)": { "renegotiated connection": [<no renegotiated connection>] }, "extended_master_secret (23)": { <empty> } ] }
14-12-2018

Tested on MacOs High Sierra. Followed the steps described in bug description using the attached test case. JDK 8u191 - Pass JDK 11.0.1 - Fail JDK 12-ea+16 - Fail Output: bavaidya-mac2:callback bavaidya$ java -jar build/libs/client.jar !! 19/11/18 13:15:45:822 error: Ice.ThreadPool.Client-0: exception in `Ice.ThreadPool.Client': java.lang.NullPointerException at java.base/sun.security.ssl.OutputRecord.changeWriteCiphers(OutputRecord.java:173) at java.base/sun.security.ssl.ChangeCipherSpec$T10ChangeCipherSpecProducer.produce(ChangeCipherSpec.java:112) at java.base/sun.security.ssl.Finished$T12FinishedProducer.onProduceFinished(Finished.java:392) at java.base/sun.security.ssl.Finished$T12FinishedProducer.produce(Finished.java:376) at java.base/sun.security.ssl.SSLHandshake.produce(SSLHandshake.java:436) at java.base/sun.security.ssl.ServerHelloDone$ServerHelloDoneConsumer.consume(ServerHelloDone.java:173) at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392) at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:448) 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 com.zeroc.IceSSL.TransceiverI.handshakeNonBlocking(TransceiverI.java:343) at com.zeroc.IceSSL.TransceiverI.initialize(TransceiverI.java:61) at com.zeroc.Ice.ConnectionI.initialize(ConnectionI.java:2111) at com.zeroc.Ice.ConnectionI.message(ConnectionI.java:1093) at com.zeroc.IceInternal.ThreadPool.run(ThreadPool.java:417) at com.zeroc.IceInternal.ThreadPool.access$500(ThreadPool.java:12) at com.zeroc.IceInternal.ThreadPool$EventHandlerThread.run(ThreadPool.java:786) at java.base/java.lang.Thread.run(Thread.java:835) event handler: local address = <not available> remote address = 127.0.0.1:4064 !! 19/11/18 13:16:45:716 error: Ice.ThreadPool.Client-0: exception in `Ice.ThreadPool.Client': java.lang.NullPointerException at java.base/sun.security.ssl.OutputRecord.changeWriteCiphers(OutputRecord.java:173) at java.base/sun.security.ssl.ChangeCipherSpec$T10ChangeCipherSpecProducer.produce(ChangeCipherSpec.java:112) at java.base/sun.security.ssl.Finished$T12FinishedProducer.onProduceFinished(Finished.java:392) at java.base/sun.security.ssl.Finished$T12FinishedProducer.produce(Finished.java:376) at java.base/sun.security.ssl.SSLHandshake.produce(SSLHandshake.java:436) at java.base/sun.security.ssl.ServerHelloDone$ServerHelloDoneConsumer.consume(ServerHelloDone.java:173) at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392) at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:448) 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 com.zeroc.IceSSL.TransceiverI.handshakeNonBlocking(TransceiverI.java:343) at com.zeroc.IceSSL.TransceiverI.initialize(TransceiverI.java:61) at com.zeroc.Ice.ConnectionI.initialize(ConnectionI.java:2111) at com.zeroc.Ice.ConnectionI.message(ConnectionI.java:1093) at com.zeroc.IceInternal.ThreadPool.run(ThreadPool.java:417) at com.zeroc.IceInternal.ThreadPool.access$500(ThreadPool.java:12) at com.zeroc.IceInternal.ThreadPool$EventHandlerThread.run(ThreadPool.java:786) at java.base/java.lang.Thread.run(Thread.java:835)
20-11-2018