As discussed in http://mail-archives.apache.org/mod_mbox/tomcat-users/201910.mbox/%3Cee96a553-81ea-ad01-f51b-f638de934600%40apache.org%3E I installed Tomcat 9.0.27 on my Windows 7 machine and using the following java runtime to get support for TLSv1.3 Server built: Oct 7 2019 09:57:22 UTC Server version number: 9.0.27.0 Architecture: amd64 JVM Version: 13.0.1+9 JVM Vendor: Oracle Corporation My TLS connector is configured with client auth. <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true" sslImplementationName="org.apache.tomcat.util.net.jsse.JSSEImplementation" keystoreFile="conf/keys/server.jks" keystoreType="JKS" keystorePass="" keyAlias="server" clientAuth="true" truststoreFile="conf/keys/clients.jks" truststorePass="" sslProtocol="TLS"> </Connector> If i connect with a browser i can choose my client key but get an error afterwards. The following error happens in SecureNioChannel: 28-Oct-2019 10:04:27.939 FINE [https-jsse-nio-8443-exec-4] org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun Error during SSL handshake java.io.IOException: NOT_HANDSHAKING during handshake at org.apache.tomcat.util.net.SecureNioChannel.handshake(SecureNioChannel.java:193) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1556) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.base/java.lang.Thread.run(Thread.java:830) With java runtime 8 everything works fine but i do not have TLSv1.3 there, so only a TLSv1.2 handshake is done. Please note that the problem also occur with 8.5.x.
The Tomcat unit tests include a test for this that has been passing for quite some time. I am unable to re-create this issue using the same configuration but my own keys / certificates with OpekJDK 13.0.1+9 At this point I suspect a client issue and/or configuration issue. Please provide: a) full version information for the client used to re-create this issue b) a set of keys/certificates we can use to re-create the issue.
Created attachment 36871 [details] keystores for testing
Find attached the following keystores: client.p12 for import in Firefox 70.0.1. localhost.jks for the tomcat keystoreFile parameter client_certs.jks for the tomcat truststoreFile parameter No password needed for all of them. I always open a new private tab for testing with url https://localhost:8443/
Created attachment 36872 [details] tomcat 9.0.27 logfile
Looking at it, it seems to do the same on Java 11, so the BZ is likely misleading. After unwrap there's a task being run, after the task is run in the tasks() method, the handshake status is returned as NOT_HANDSHAKING by the SSL engine. I don't understand what is going on or what the failure is at this point, but it might not be a Tomcat issue. We could probably add additional debug logging in SecureNio(2)Channel to trace the processing of handshake() when needed. 05-Nov-2019 11:09:26.157 FINE [https-jsse-nio-8443-exec-1] org.apache.tomcat.util.net.SecureNioChannel.handshake handshakeStatus: NEED_UNWRAP Run task: sun.security.ssl.SSLEngineImpl$DelegatedTask@4de31d09 sslEngine.getHandshakeStatus() after tasks: NEED_WRAP 05-Nov-2019 11:09:26.236 FINE [https-jsse-nio-8443-exec-1] org.apache.tomcat.util.net.SecureNioChannel.handshake handshakeStatus: NEED_WRAP 05-Nov-2019 11:09:26.237 FINE [https-jsse-nio-8443-exec-1] org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.registerWriteInterest Registered write interest for [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@1184d389:org.apache.tomcat.util.net.SecureNioChannel@1ebc5f1c:java.nio.channels.SocketChannel[connected local=/0:0:0:0:0:0:0:1:8443 remote=/0:0:0:0:0:0:0:1:57612]] 05-Nov-2019 11:09:26.237 FINE [https-jsse-nio-8443-exec-2] org.apache.tomcat.util.net.SecureNioChannel.handshake handshakeStatus: NEED_WRAP 05-Nov-2019 11:09:26.238 FINE [https-jsse-nio-8443-exec-2] org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.registerWriteInterest Registered write interest for [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@1184d389:org.apache.tomcat.util.net.SecureNioChannel@1ebc5f1c:java.nio.channels.SocketChannel[connected local=/0:0:0:0:0:0:0:1:8443 remote=/0:0:0:0:0:0:0:1:57612]] 05-Nov-2019 11:09:26.238 FINE [https-jsse-nio-8443-exec-3] org.apache.tomcat.util.net.SecureNioChannel.handshake handshakeStatus: NEED_WRAP 05-Nov-2019 11:09:26.247 FINE [https-jsse-nio-8443-exec-3] org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.registerReadInterest Registered read interest for [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@1184d389:org.apache.tomcat.util.net.SecureNioChannel@1ebc5f1c:java.nio.channels.SocketChannel[connected local=/0:0:0:0:0:0:0:1:8443 remote=/0:0:0:0:0:0:0:1:57612]] 05-Nov-2019 11:09:26.251 FINE [https-jsse-nio-8443-exec-4] org.apache.tomcat.util.net.SecureNioChannel.handshake handshakeStatus: NEED_UNWRAP Run task: sun.security.ssl.SSLEngineImpl$DelegatedTask@427c714f sslEngine.getHandshakeStatus() after tasks: NOT_HANDSHAKING
Interesting. The private browsing part is important. I can re-create this with the standard Tomcat certs we use in the unit tests now. Also seen on Linux and Firefox 70.0. I only see this with JSSE, not with OpenSSL. I'm going to capture a couple of network traces to see if I can see a difference.
This looks like a JVM bug to me. When Firefox's private browsing is enabled the penultimate handshake status is NEED_TASK. Immediately after calling tasks() the handshake status is NOT_HANDSHAKING rather than finished. I'll write this up as an OpenJDK bug. I'll link to it here when that is done. We could work around it but it seems rare enough (at this point) that a workaround of "use OpenSSL if you need TLS 1.3 and are hitting this bug" is sufficient.
+1 I don't see how it can be a Tomcat issue at this point since the NOT_HANDSHAKING status occurs after running the task run(), without errors and without further wrapping or unwrapping. Working around it didn't work for me, I tried to return 0 (handshake complete) but then the engine is really not in "handshake finished" status so it fails. There's probably no way to escape this NOT_HANDSHAKING status once you go into it.
https://bugs.openjdk.java.net/browse/JDK-8233619 I am resolving this Tomcat bug as invalid on the basis the root cause is a JVM TLSv1.3 bug. If the OpenJDK folks indicate that Tomcat is doing something wrong, we can re-open this bug and investigate further.
Wild guess based only upon comments here: Java's TLSv1.3 implementation does not support TLS ESNI (encrypted SNI) extension. Usually, SNI is sent with initial TLS handshake. When the browser is in "private" mode, perhaps ESNI is used. Again, a wild guess. But it might explain what is happening, here.
(In reply to Christopher Schultz from comment #10) > Again, a wild guess. But it might explain what is happening, here. It doesn't. The failure happens right at the end of the handshake more details of exactly where in the JDK bug report.