<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Hi there,<div class=""><br class=""></div><div class="">I think I found a bug in the TLSv1.3 session cache implementation which sometimes can cause failures during session resumption. </div><div class="">The cause of this sometimes show up as NPE:</div><div class=""><br class=""></div><div class=""><div class="">javax.net.ssl.SSLException: Session has no PSK</div><div class=""><span class="Apple-tab-span" style="white-space:pre">       </span>at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:133)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">    </span>at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">    </span>at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:336)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:292)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:283)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>at java.base/sun.security.ssl.PreSharedKeyExtension.checkBinder(PreSharedKeyExtension.java:537)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>at java.base/sun.security.ssl.PreSharedKeyExtension$CHPreSharedKeyUpdate.consume(PreSharedKeyExtension.java:528)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">  </span>at java.base/sun.security.ssl.SSLExtension.consumeOnTrade(SSLExtension.java:583)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">  </span>at java.base/sun.security.ssl.SSLExtensions.consumeOnTrade(SSLExtensions.java:222)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>at java.base/sun.security.ssl.ServerHello$T13ServerHelloProducer.produce(ServerHello.java:539)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">    </span>at java.base/sun.security.ssl.SSLHandshake.produce(SSLHandshake.java:436)</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>at java.base/sun.security.ssl.ClientHello$T13ClientHelloConsumer.goServerHello(ClientHello.java:1234)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">     </span>at java.base/sun.security.ssl.ClientHello$T13ClientHelloConsumer.consume(ClientHello.java:1170)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>at java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.onClientHello(ClientHello.java:852)</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>at java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.consume(ClientHello.java:813)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">       </span>at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:443)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1074)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">    </span>at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1061)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">    </span>at java.base/java.security.AccessController.doPrivileged(Native Method)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask.run(SSLEngineImpl.java:1008)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">    </span>at io.netty.handler.ssl.SslHandler.runAllDelegatedTasks(SslHandler.java:1557)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">     </span>at io.netty.handler.ssl.SslHandler.runDelegatedTasks(SslHandler.java:1571)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1455)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1282)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">      </span>at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1329)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:508)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">      </span>at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:447)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">  </span>at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276)</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">       </span>at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">       </span>at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">      </span>at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">       </span>at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">       </span>at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">       </span>at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">    </span>at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">  </span>at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">      </span>at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">  </span>at java.base/java.lang.Thread.run(Thread.java:834)</div><div class="">java.lang.NullPointerException</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>at java.base/sun.security.ssl.HKDF.extract(HKDF.java:93)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">  </span>at java.base/sun.security.ssl.HKDF.extract(HKDF.java:119)</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>at java.base/sun.security.ssl.ServerHello.setUpPskKD(ServerHello.java:1169)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">       </span>at java.base/sun.security.ssl.ServerHello$T13ServerHelloProducer.produce(ServerHello.java:547)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">    </span>at java.base/sun.security.ssl.SSLHandshake.produce(SSLHandshake.java:436)</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>at java.base/sun.security.ssl.ClientHello$T13ClientHelloConsumer.goServerHello(ClientHello.java:1234)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">     </span>at java.base/sun.security.ssl.ClientHello$T13ClientHelloConsumer.consume(ClientHello.java:1170)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>at java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.onClientHello(ClientHello.java:852)</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>at java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.consume(ClientHello.java:813)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">       </span>at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:443)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1074)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">    </span>at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1061)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">    </span>at java.base/java.security.AccessController.doPrivileged(Native Method)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask.run(SSLEngineImpl.java:1008)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">    </span>at io.netty.handler.ssl.SslHandler.runAllDelegatedTasks(SslHandler.java:1557)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">     </span>at io.netty.handler.ssl.SslHandler.runDelegatedTasks(SslHandler.java:1571)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1455)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1282)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">      </span>at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1329)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:508)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">      </span>at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:447)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">  </span>at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276)</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">       </span>at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">       </span>at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">      </span>at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">       </span>at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">       </span>at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">       </span>at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">    </span>at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">  </span>at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">      </span>at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">  </span>at java.base/java.lang.Thread.run(Thread.java:834)</div></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Other times the NPE is not included but it still fails with something like:</div><div class=""><br class=""></div><div class=""><div class="">Caused by: javax.net.ssl.SSLException: Session has no PSK</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:133)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">    </span>at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">    </span>at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:336)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:292)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:283)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>at java.base/sun.security.ssl.PreSharedKeyExtension.checkBinder(PreSharedKeyExtension.java:537)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>at java.base/sun.security.ssl.PreSharedKeyExtension$CHPreSharedKeyUpdate.consume(PreSharedKeyExtension.java:528)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">  </span>at java.base/sun.security.ssl.SSLExtension.consumeOnTrade(SSLExtension.java:583)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">  </span>at java.base/sun.security.ssl.SSLExtensions.consumeOnTrade(SSLExtensions.java:222)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>at java.base/sun.security.ssl.ServerHello$T13ServerHelloProducer.produce(ServerHello.java:539)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">    </span>at java.base/sun.security.ssl.SSLHandshake.produce(SSLHandshake.java:436)</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>at java.base/sun.security.ssl.ClientHello$T13ClientHelloConsumer.goServerHello(ClientHello.java:1234)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">     </span>at java.base/sun.security.ssl.ClientHello$T13ClientHelloConsumer.consume(ClientHello.java:1170)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>at java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.onClientHello(ClientHello.java:852)</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>at java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.consume(ClientHello.java:813)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">       </span>at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:443)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1074)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">    </span>at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1061)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">    </span>at java.base/java.security.AccessController.doPrivileged(Native Method)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask.run(SSLEngineImpl.java:1008)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">    </span>at io.netty.handler.ssl.SslHandler.runAllDelegatedTasks(SslHandler.java:1557)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">     </span>at io.netty.handler.ssl.SslHandler.runDelegatedTasks(SslHandler.java:1571)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1455)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1282)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">      </span>at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1329)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:508)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">      </span>at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:447)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">  </span>... 17 common frames omitted</div></div><div class=""><br class=""></div><div class="">Looking at the first stacktrace this seems to be related to:</div><div class=""><br class=""></div><div class=""><a href="https://bugs.openjdk.java.net/browse/JDK-8241248" class="">https://bugs.openjdk.java.net/browse/JDK-8241248</a></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Unfortunately I don’t have a reproducer which uses the JDK only here but I can reproduce this with Netty that uses OpenSSL on the client side and the JDK SSLEngine on the server side.</div><div class="">I can reproduce this with the latest JDK11 release but can't with JDK15. Also what makes me believe it may be a concurrency bug is that only some handshakes fail. Like 70 out of 2600 fail.</div><div class=""><br class=""></div><div class="">While the reproducer also involves netty I am wondering if you would still be interested in it ? It should be quite straight forward to run locally for you.</div><div class=""><br class=""></div><div class="">The code that can reproduce it is here:</div><div class=""><a href="https://github.com/netty/netty/pull/10994#issuecomment-787976965" class="">https://github.com/netty/netty/pull/10994#issuecomment-787976965</a></div><div class=""><br class=""></div><div class="">Also you will need to use this branch:</div><div class=""><a href="https://github.com/netty/netty/tree/ssl_cache_revamp" class="">https://github.com/netty/netty/tree/ssl_cache_revamp</a></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Please don’t hesitate if you have questions,</div><div class="">Norman</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div></body></html>