Bug 61415 - SSL protocol error with Chrome, client certificates and OpenSSL/NIO in Tomcat 8.5
Summary: SSL protocol error with Chrome, client certificates and OpenSSL/NIO in Tomcat...
Status: RESOLVED FIXED
Alias: None
Product: Tomcat Native
Classification: Unclassified
Component: Library (show other bugs)
Version: unspecified
Hardware: PC All
: P2 normal (vote)
Target Milestone: ---
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-08-15 07:39 UTC by matej.spiller
Modified: 2017-08-22 11:25 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description matej.spiller 2017-08-15 07:39:45 UTC
It seems that there is a problem with openssl when replacing JSSE. It is a a problem when certificateVerficiation is enabled.
I replaced JSSE/NIO with OpenSSL/NIO because I wanted to enable HTTP/2.
We are using Spring Boot application with tomcat embedded. During startup I was able to load tcnative-1 using AprLifecycleListener. Spring Boot does not support APR connector due to different keystore configuration, but I was able to boot using OpenSSL/NIO. When opening the application in any browser I was getting SSL protocol errors.

I was able to reproduce the same problem using standalone tomcat without any applications deployed.

How to reproduce:
- download Tomcat 8.5.20 Windows x64 & unzip it
- generate keystore: "%JAVA_HOME%\bin\keytool" -genkey -alias tomcat -keyalg RSA -keystore tomcat_keystore.jks (enter localhost and other data, with password tomcat)
- copy cacerts to conf folder from JRE folder (for example: C:\Program Files\Java\jdk1.8.0_131\jre\lib\security)
- edit server.xml and add Connector

    <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="150" SSLEnabled="true">
		<UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
		<SSLHostConfig truststoreFile="conf/cacerts" truststorePassword="" certificateVerification="optional">
            <Certificate certificateKeystoreFile="conf/tomcat_keystore.jks"
                         certificateKeystorePassword="tomcat"
                         type="RSA" />
        </SSLHostConfig>
    </Connector>

- open Chrome and navigate to https://localhost:8443 (you don't need to select any client certificate)
- you should see tomcat welcome page
- press Ctrl + F5 fast couple of times and you should start seeing SSL protocol error

First I added comment inside https://bz.apache.org/bugzilla/show_bug.cgi?id=61394, but after a bit more testing I doubt it is the same problem.
Comment 1 Mark Thomas 2017-08-21 09:36:29 UTC
I can reproduce this with the latest tomcat-native and 9.0.x

I also see a JVM crash when shutting down Tomcat after this error.

My guess at this point is that Tomcat isn't handling an I/O error during the initial handshake correctly.

While the error is easily repeatable, tracking it down is going to be a little tricky because the timing is uncertain. I'm currently investigating tools to make finding this (and similar bugs) a little easier.
Comment 2 Mark Thomas 2017-08-22 07:18:49 UTC
The tools (omniscient debuggers) were a washout. All the ones I could find were either unmaintained for several years and didn't support Java 8, or were so slow with an application of Tomcat's complexity as to be unusable (which isn't really surprising given what they are trying to do). Back to doing it the hard way...
Comment 3 Mark Thomas 2017-08-22 11:25:54 UTC
Found it. The information I needed was in the debug logs all along. The root cause was in Tomcat code, not native code.

Fixed in:
- trunk for 9.0.0.M27 onwards
- 8.5.x for 8.5.21 onwards