Bug 62094

Summary: Certificate verification using CRL with Tomcat APR connector does not work
Product: Tomcat Native Reporter: twsatwork
Component: LibraryAssignee: Tomcat Developers Mailing List <dev>
Status: RESOLVED FIXED    
Severity: normal CC: twsatwork
Priority: P2    
Version: 1.2.7   
Target Milestone: ---   
Hardware: PC   
OS: Linux   
Attachments: The source code with the proposed fix.

Description twsatwork 2018-02-09 19:41:38 UTC
[Title]
Certificate verification using CRL with Tomcat APR connector does not work


[Frequency of Occurrence]
Always


[Details]
Neither SSLCARevocationFile nor SSLCARevocationPath has any effect for certificate verification.


[System/Software Info]
OS: Red Hat Enterprise Linux Server release 7.3 (Maipo)
Tomcat: 8.0.44
Tomcat Native: 1.2.7
Tomcat APR: 1.5.2
OpenSSL: 1.0.2k

Note: The issue also exists in Windows platform.


[Prerequisites]
1. OpenSSL binary/utility (usually available on common Linux distribution)
2. OpenSSL library. See the References section.
3. APR library for Linux. See the References section.
4. Tomcat Native library for Linux (this needs to be built from the source code.  Tomcat does not include this for Linux.) See the References section.


[Setup Steps]
I. Certificates
1. Use OpenSSL to create the certificates as follows.  See the information regarding how to create certificates in the References section
(1.1) a private CA certificate
(1.2) a server identity certificate, signed by the private CA certificate created in Step (1.1)
(1.3) a client/browser identity certificate, signed by the private CA certificate created in Step (1.1).  Convert the client/browser identity certificate from PEM to PKCS12, say "browsercert.p12".
2. After creating the client/browser identity certificate, revoke it.
3. Create a CRL from the private CA.
4. Import the client/browser identity certificate to to the browser of your choice.


II. Tomcat Setup
1. Get Tomcat for Linux and deploy it onto a Linux test server.
2. Configure the connectors in Tomcat server.xml as follows:

// --- Tomcat 'server.xml' [S] ---
<Connector port="18080" protocol="HTTP/1.1"
  connectionTimeout="20000"
  redirectPort="18443" />

<Connector
  port="18443"
  protocol="org.apache.coyote.http11.Http11AprProtocol"
  maxThreads="50"
  maxConnections="64"
  connectionTimeout="20000"
  scheme="https"
  secure="true"
  SSLEnabled="true"
  SSLProtocol = "TLSv1.2"
  SSLCertificateFile="${catalina.base}/ssl/cert/server.pem"
  SSLCACertificateFile="${catalina.base}/ssl/ca/all-ca-certs.pem"
  SSLCARevocationPath="${catalina.base}/ssl/crl"
  SSLVerifyClient="require"
  server="Tomcat 8.0.44"
  SSLCipherSuite="ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:!aNULL:!eNULL:!ADH:!EXP:!MD5:!RC4:+HIGH:+MEDIUM:-LOW:-SSLv2"
  SSLHonorCipherOrder="true" />
// --- Tomcat 'server.xml' [E] ---

3. Create the file "setenv.sh" with the contents as below (adjust to the actual deployment environment accordingly)
// --- "setenv.sh" [S] ---
export CATALINA_HOME=_WHERE_TOMCAT_IS_
export CATALINA_BASE=_WHERE_TOMCAT_IS_

export LD_LIBRARY_PATH=$CATALINA_HOME/bin

export JRE_HOME=_WHERE_JRE_IS_
export JRE_BIN=$JRE_HOME/bin/java
// --- "setenv.sh" [E] ---

4. Copy the required APR libraries to "$CATALINA_HOME\bin"
(4.1) APR: libapr-1.so.0
(4.2) tcnative: libtcnative-1.so
(4.3) OpenSSL: libssl.so.1.0.0, libcrypto.so.1.0.0

5. Create the folder "ssl" under "$CATALINA_HOME".

6. Put the following certificates to the locations as follows, where "$CATALINA_HOME" is where Tomcat locates.
(2.1) the private CA certificate -> "$CATALINA_HOME/ssl/ca"
(2.2) the server identity certificate -> "$CATALINA_HOME/ssl/cert"
(2.3) the private CA CRL -> "$CATALINA_HOME/ssl/crl"


[Test Procedure]
*Ensure all setup is complete properly.

1. Start Tomcat.
2. Start the web browser and connect to Tomcat using "https://_TOMCAT_SERVER_ADDR:18443/index.jsp".  When prompted, choose the imported client/browser idenity certificate for the connection.

Expected Results:
1. The connection would fail due to the revoked client/browser certificate.

Actual Results:
1. The connection still goes through and Tomcat "index.jsp" is accessible.


[Investigation Findings]
1. In tcnative, CRL check flags for OpenSSL is not set for the corresponding SSLContext.  See the function “TCN_IMPLEMENT_CALL(void, SSLContext, setVerify)” in “tomcat-native-1.2.7-src\native\src\sslcontext.c”.
2. In tcnative, CRL cert store is not set in the corresponding SSLContext. See the function “TCN_IMPLEMENT_CALL(void, SSLContext, setVerify)” in “tomcat-native-1.2.7-src\native\src\sslcontext.c”.


[Proposed Fixes]
The fix is courtesy of C.Y. Chen.  See the attached file "sslconext.c".  Look for "CRL Fix" for the modification.


[References]
1. Certificate Creation
https://jamielinux.com/docs/openssl-certificate-authority/introduction.html

2. Default OpenSSL configuration file may be available on a Linux server at: "/etc/pki/tls/openssl.cnf"

3. Tomcat
(3.1) Main: https://tomcat.apache.org/index.html
(3.2) 8.0.44 download: https://archive.apache.org/dist/tomcat/tomcat-8/v8.0.44/

4. Tomcat APR:
(4.1) Main: http://apr.apache.org/
(4.2) 1.5.2 download: http://archive.apache.org/dist/apr/

5. Tomcat Native
(5.1) Main: https://tomcat.apache.org/native-doc/
(5.2) 1.2.7 download: https://archive.apache.org/dist/tomcat/tomcat-connectors/native/1.2.7/

6. OpenSSL
(6.1) Main: https://www.openssl.org/
(6.2) 1.0.2k: https://www.openssl.org/source/old/1.0.2/
Comment 1 twsatwork 2018-02-09 19:43:29 UTC
Created attachment 35725 [details]
The source code with the proposed fix.

Look for "CRL  FIX" for the places of the proposed modifications.
Comment 2 jfclere 2018-06-04 16:13:39 UTC
a diff -u would be more easy to review... I can't find CRL  FIX in the attachement
Comment 3 jfclere 2018-06-06 08:28:51 UTC
Fixed by r1832987 will by in 1.2.17