|  | <?xml version="1.0" encoding="UTF-8"?> | 
|  | <!-- | 
|  | Licensed to the Apache Software Foundation (ASF) under one or more | 
|  | contributor license agreements.  See the NOTICE file distributed with | 
|  | this work for additional information regarding copyright ownership. | 
|  | The ASF licenses this file to You under the Apache License, Version 2.0 | 
|  | (the "License"); you may not use this file except in compliance with | 
|  | the License.  You may obtain a copy of the License at | 
|  |  | 
|  | http://www.apache.org/licenses/LICENSE-2.0 | 
|  |  | 
|  | Unless required by applicable law or agreed to in writing, software | 
|  | distributed under the License is distributed on an "AS IS" BASIS, | 
|  | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | See the License for the specific language governing permissions and | 
|  | limitations under the License. | 
|  | --> | 
|  | <!DOCTYPE document [ | 
|  | <!ENTITY project SYSTEM "project.xml"> | 
|  | ]> | 
|  | <document url="ssl-howto.html"> | 
|  |  | 
|  | &project; | 
|  |  | 
|  | <properties> | 
|  | <title>SSL/TLS Configuration How-To</title> | 
|  | </properties> | 
|  |  | 
|  | <body> | 
|  |  | 
|  | <section name="Table of Contents"> | 
|  | <toc/> | 
|  | </section> | 
|  |  | 
|  | <section name="Quick Start"> | 
|  |  | 
|  | <p><em>The description below uses the variable name $CATALINA_BASE to refer the | 
|  | base directory against which most relative paths are resolved. If you have | 
|  | not configured Tomcat for multiple instances by setting a CATALINA_BASE | 
|  | directory, then $CATALINA_BASE will be set to the value of $CATALINA_HOME, | 
|  | the directory into which you have installed Tomcat.</em></p> | 
|  |  | 
|  | <p>To install and configure SSL/TLS support on Tomcat, you need to follow | 
|  | these simple steps.  For more information, read the rest of this How-To.</p> | 
|  | <ol> | 
|  | <li><p>Create a keystore file to store the server's private key and | 
|  | self-signed certificate by executing the following command:</p> | 
|  | <p>Windows:</p> | 
|  | <source>"%JAVA_HOME%\bin\keytool" -genkey -alias tomcat -keyalg RSA</source> | 
|  | <p>Unix:</p> | 
|  | <source>$JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA</source> | 
|  |  | 
|  | <p>and specify a password value of "changeit".</p></li> | 
|  | <li><p>Uncomment the "SSL HTTP/1.1 Connector" entry in | 
|  | <code>$CATALINA_BASE/conf/server.xml</code> and modify as described in | 
|  | the <a href="#Configuration">Configuration section</a> below.</p></li> | 
|  |  | 
|  | </ol> | 
|  |  | 
|  |  | 
|  | </section> | 
|  |  | 
|  |  | 
|  | <section name="Introduction to SSL/TLS" anchor="Introduction_to_SSL"> | 
|  |  | 
|  | <p>Transport Layer Security (TLS) and its predecessor, Secure Sockets Layer | 
|  | (SSL), are technologies which allow web browsers and web servers to communicate | 
|  | over a secured connection.  This means that the data being sent is encrypted by | 
|  | one side, transmitted, then decrypted by the other side before processing. | 
|  | This is a two-way process, meaning that both the server AND the browser encrypt | 
|  | all traffic before sending out data.</p> | 
|  |  | 
|  | <p>Another important aspect of the SSL/TLS protocol is Authentication.  This means | 
|  | that during your initial attempt to communicate with a web server over a secure | 
|  | connection, that server will present your web browser with a set of | 
|  | credentials, in the form of a "Certificate", as proof the site is who and what | 
|  | it claims to be.  In certain cases, the server may also request a Certificate | 
|  | from your web browser, asking for proof that <em>you</em> are who you claim | 
|  | to be.  This is known as "Client Authentication," although in practice this is | 
|  | used more for business-to-business (B2B) transactions than with individual | 
|  | users.  Most SSL-enabled web servers do not request Client Authentication.</p> | 
|  |  | 
|  | </section> | 
|  |  | 
|  | <section name="SSL/TLS and Tomcat" anchor="SSL_and_Tomcat"> | 
|  |  | 
|  | <p>It is important to note that configuring Tomcat to take advantage of | 
|  | secure sockets is usually only necessary when running it as a stand-alone | 
|  | web server.  Details can be found in the | 
|  | <a href="security-howto.html">Security Considerations Document</a>. | 
|  | When running Tomcat primarily as a Servlet/JSP container behind | 
|  | another web server, such as Apache or Microsoft IIS, it is usually necessary | 
|  | to configure the primary web server to handle the SSL connections from users. | 
|  | Typically, this server will negotiate all SSL-related functionality, then | 
|  | pass on any requests destined for the Tomcat container only after decrypting | 
|  | those requests.  Likewise, Tomcat will return cleartext responses, that will | 
|  | be encrypted before being returned to the user's browser.  In this environment, | 
|  | Tomcat knows that communications between the primary web server and the | 
|  | client are taking place over a secure connection (because your application | 
|  | needs to be able to ask about this), but it does not participate in the | 
|  | encryption or decryption itself.</p> | 
|  |  | 
|  | <p>Tomcat is able to use any of the cryptographic protocols that are | 
|  | provided by the underlying environment. Java itself provides cryptographic | 
|  | capabilities through <a href="https://docs.oracle.com/javase/9/security/java-cryptography-architecture-jca-reference-guide.htm">JCE/JCA</a> | 
|  | and encrypted communications capabilities through <a href="https://docs.oracle.com/javase/9/security/java-secure-socket-extension-jsse-reference-guide.htm">JSSE</a>. | 
|  | Any compliant cryptographic "provider" can provide cryptographic algorithms | 
|  | to Tomcat. The built-in provider (SunJCE) includes support for various | 
|  | SSL/TLS versions like SSLv3, TLSv1, TLSv1.1, and so on. Check the documentation | 
|  | for your version of Java for details on protocol and algorithm support.</p> | 
|  |  | 
|  | <p>If you use the optional <code>tcnative</code> library, you can use | 
|  | the <a href="https://www.openssl.org/">OpenSSL</a> cryptographic provider | 
|  | through JCA/JCE/JSSE which may provide a different selection of cryptographic | 
|  | algorithms and/or performance benefits relative to the SunJCE provider. | 
|  | Check the documentation for your version of OpenSSL for details on protocol and | 
|  | algorithm support.</p> | 
|  |  | 
|  | </section> | 
|  |  | 
|  | <section name="Certificates"> | 
|  |  | 
|  | <p>In order to implement SSL, a web server must have an associated Certificate | 
|  | for each external interface (IP address) that accepts secure connections. | 
|  | The theory behind this design is that a server should provide some kind of | 
|  | reasonable assurance that its owner is who you think it is, particularly | 
|  | before receiving any sensitive information.  While a broader explanation of | 
|  | Certificates is beyond the scope of this document, think of a Certificate as a | 
|  | "digital passport" for an Internet address. It states which organisation the | 
|  | site is associated with, along with some basic contact information about the | 
|  | site owner or administrator.</p> | 
|  |  | 
|  | <p>This certificate is cryptographically signed by its owner, and is | 
|  | therefore extremely difficult for anyone else to forge. For the certificate to | 
|  | work in the visitors browsers without warnings, it needs to be signed by a | 
|  | trusted third party. These are called <em>Certificate Authorities</em> (CAs). To | 
|  | obtain a signed certificate, you need to choose a CA and follow the instructions | 
|  | your chosen CA provides to obtain your certificate. A range of CAs is available | 
|  | including some that offer certificates at no cost.</p> | 
|  |  | 
|  | <p>Java provides a relatively simple command-line tool, called | 
|  | <code>keytool</code>, which can easily create a "self-signed" Certificate. | 
|  | Self-signed Certificates are simply user generated Certificates which have not | 
|  | been signed by a well-known CA and are, therefore, not really guaranteed to be | 
|  | authentic at all. While self-signed certificates can be useful for some testing | 
|  | scenarios, they are not suitable for any form of production use.</p> | 
|  |  | 
|  | </section> | 
|  |  | 
|  | <section name="General Tips on Running SSL"> | 
|  |  | 
|  | <p>When securing a website with SSL it's important to make sure that all assets | 
|  | that the site uses are served over SSL, so that an attacker can't bypass | 
|  | the security by injecting malicious content in a JavaScript file or similar. To | 
|  | further enhance the security of your website, you should evaluate to use the | 
|  | HSTS header. It allows you to communicate to the browser that your site should | 
|  | always be accessed over https.</p> | 
|  |  | 
|  | <p>Using name-based virtual hosts on a secured connection requires careful | 
|  | configuration of the names specified in a single certificate or Tomcat 8.5 | 
|  | onwards where Server Name Indication (SNI) support is available. SNI allows | 
|  | multiple certificates with different names to be associated with a single TLS | 
|  | connector.</p> | 
|  |  | 
|  | </section> | 
|  |  | 
|  | <section name="Configuration"> | 
|  |  | 
|  | <subsection name="Prepare the Certificate Keystore"> | 
|  |  | 
|  | <p>Tomcat currently operates only on <code>JKS</code>, <code>PKCS11</code> or | 
|  | <code>PKCS12</code> format keystores.  The <code>JKS</code> format | 
|  | is Java's standard "Java KeyStore" format, and is the format created by the | 
|  | <code>keytool</code> command-line utility.  This tool is included in the JDK. | 
|  | The <code>PKCS12</code> format is an internet standard, and can be manipulated | 
|  | via (among other things) OpenSSL and Microsoft's Key-Manager. | 
|  | </p> | 
|  |  | 
|  | <p>Each entry in a keystore is identified by an alias string. Whilst many | 
|  | keystore implementations treat aliases in a case insensitive manner, case | 
|  | sensitive implementations are available. The <code>PKCS11</code> specification, | 
|  | for example, requires that aliases are case sensitive. To avoid issues related | 
|  | to the case sensitivity of aliases, it is not recommended to use aliases that | 
|  | differ only in case. | 
|  | </p> | 
|  |  | 
|  | <p>To import an existing certificate into a <code>JKS</code> keystore, please read the | 
|  | documentation (in your JDK documentation package) about <code>keytool</code>. | 
|  | Note that OpenSSL often adds readable comments before the key, but | 
|  | <code>keytool</code> does not support that. So if your certificate has | 
|  | comments before the key data, remove them before importing the certificate with | 
|  | <code>keytool</code>. | 
|  | </p> | 
|  | <p>To import an existing certificate signed by your own CA into a <code>PKCS12</code> | 
|  | keystore using OpenSSL you would execute a command like:</p> | 
|  | <source>openssl pkcs12 -export -in mycert.crt -inkey mykey.key | 
|  | -out mycert.p12 -name tomcat -CAfile myCA.crt | 
|  | -caname root -chain</source> | 
|  | <p>For more advanced cases, consult the | 
|  | <a href="https://www.openssl.org/" rel="nofollow">OpenSSL documentation</a>.</p> | 
|  |  | 
|  | <p>To create a new <code>JKS</code> keystore from scratch, containing a single | 
|  | self-signed Certificate, execute the following from a terminal command line:</p> | 
|  | <p>Windows:</p> | 
|  | <source>"%JAVA_HOME%\bin\keytool" -genkey -alias tomcat -keyalg RSA</source> | 
|  | <p>Unix:</p> | 
|  | <source>$JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA</source> | 
|  |  | 
|  | <p>(The RSA algorithm should be preferred as a secure algorithm, and this | 
|  | also ensures general compatibility with other servers and components.)</p> | 
|  |  | 
|  | <p>This command will create a new file, in the home directory of the user | 
|  | under which you run it, named "<code>.keystore</code>".  To specify a | 
|  | different location or filename, add the <code>-keystore</code> parameter, | 
|  | followed by the complete pathname to your keystore file, | 
|  | to the <code>keytool</code> command shown above.  You will also need to | 
|  | reflect this new location in the <code>server.xml</code> configuration file, | 
|  | as described later.  For example:</p> | 
|  | <p>Windows:</p> | 
|  | <source>"%JAVA_HOME%\bin\keytool" -genkey -alias tomcat -keyalg RSA | 
|  | -keystore \path\to\my\keystore</source> | 
|  | <p>Unix:</p> | 
|  | <source>$JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA | 
|  | -keystore /path/to/my/keystore</source> | 
|  |  | 
|  | <p>After executing this command, you will first be prompted for the keystore | 
|  | password.  The default password used by Tomcat is "<code>changeit</code>" | 
|  | (all lower case), although you can specify a custom password if you like. | 
|  | You will also need to specify the custom password in the | 
|  | <code>server.xml</code> configuration file, as described later.</p> | 
|  |  | 
|  | <p>Next, you will be prompted for general information about this Certificate, | 
|  | such as company, contact name, and so on.  This information will be displayed | 
|  | to users who attempt to access a secure page in your application, so make | 
|  | sure that the information provided here matches what they will expect.</p> | 
|  |  | 
|  | <p>Finally, you will be prompted for the <em>key password</em>, which is the | 
|  | password specifically for this Certificate (as opposed to any other | 
|  | Certificates stored in the same keystore file). The <code>keytool</code> prompt | 
|  | will tell you that pressing the ENTER key automatically uses the same password | 
|  | for the key as the keystore. You are free to use the same password or to select | 
|  | a custom one. If you select a different password to the keystore password, you | 
|  | will also need to specify the custom password in the <code>server.xml</code> | 
|  | configuration file.</p> | 
|  |  | 
|  | <p>If everything was successful, you now have a keystore file with a | 
|  | Certificate that can be used by your server.</p> | 
|  |  | 
|  | </subsection> | 
|  |  | 
|  | <subsection name="Edit the Tomcat Configuration File"> | 
|  | <p> | 
|  | Tomcat can use two different implementations of SSL: | 
|  | </p> | 
|  | <ul> | 
|  | <li>JSSE implementation provided as part of the Java runtime</li> | 
|  | <li>JSSE implementation that uses OpenSSL</li> | 
|  | </ul> | 
|  | <p> | 
|  | The exact configuration details depend on which implementation is being used. | 
|  | If you configured Connector by specifying generic | 
|  | <code>protocol="HTTP/1.1"</code> then the implementation used by Tomcat is | 
|  | chosen automatically. | 
|  | </p> | 
|  |  | 
|  | <p> | 
|  | Auto-selection of implementation can be avoided if needed. It is done by specifying a classname | 
|  | in the <b>protocol</b> attribute of the <a href="config/http.html">Connector</a>.</p> | 
|  |  | 
|  | <p>To define a Java (JSSE) connector, regardless of whether the APR library is | 
|  | loaded or not, use one of the following:</p> | 
|  | <source><![CDATA[<!-- Define an HTTP/1.1 Connector on port 8443, JSSE NIO implementation --> | 
|  | <Connector protocol="org.apache.coyote.http11.Http11NioProtocol" | 
|  | sslImplementationName="org.apache.tomcat.util.net.jsse.JSSEImplementation" | 
|  | port="8443" .../> | 
|  |  | 
|  | <p>The OpenSSL JSSE implementation can also be configured explicitly if needed. | 
|  | If the Tomcat Native library or Java 22 is installed, using the | 
|  | <code>sslImplementationName</code> | 
|  | attribute allows enabling it. When using the OpenSSL JSSE implementation, the | 
|  | configuration can use either the JSSE attributes or the OpenSSL attributes, but | 
|  | must not mix attributes from both types in the same SSLHostConfig or Connector | 
|  | element.</p> | 
|  | <p>With Tomcat Native:</p> | 
|  | <source><![CDATA[<!-- Define an HTTP/1.1 Connector on port 8443, JSSE NIO implementation and OpenSSL --> | 
|  | <Connector protocol="org.apache.coyote.http11.Http11NioProtocol" port="8443" | 
|  | sslImplementationName="org.apache.tomcat.util.net.openssl.OpenSSLImplementation" | 
|  | .../>]]></source> | 
|  | <p>With Java 22 FFM API:</p> | 
|  | <source><![CDATA[<!-- Define an HTTP/1.1 Connector on port 8443, JSSE NIO implementation and OpenSSL --> | 
|  | <Connector protocol="org.apache.coyote.http11.Http11NioProtocol" port="8443" | 
|  | sslImplementationName="org.apache.tomcat.util.net.openssl.panama.OpenSSLImplementation" | 
|  | .../>]]></source> | 
|  |  | 
|  | <p>Alternately a listener can be added to the <code>Server</code> to enable | 
|  | OpenSSL on all connectors without having to add the | 
|  | <code>sslImplementationName</code> attribute on each.</p> | 
|  | <p>With Tomcat Native:</p> | 
|  | <source><![CDATA[<Listener className="org.apache.catalina.core.AprLifecycleListener"/>]]></source> | 
|  | <p>With Java 22 FFM API:</p> | 
|  | <source><![CDATA[<Listener className="org.apache.catalina.core.OpenSSLLifecycleListener"/>]]></source> | 
|  | <p> | 
|  | The <code>SSLRandomSeed</code> attribute of the listeners allows specifying a | 
|  | source of entropy. | 
|  | Productive system needs a reliable source of entropy but entropy may need a lot | 
|  | of time to be collected therefore test systems could use no blocking entropy | 
|  | sources like "/dev/urandom" that will allow quicker starts of Tomcat. | 
|  | </p> | 
|  |  | 
|  | <p>The final step is to configure the Connector in the | 
|  | <code>$CATALINA_BASE/conf/server.xml</code> file, where | 
|  | <code>$CATALINA_BASE</code> represents the base directory for the | 
|  | Tomcat instance.  An example <code><Connector></code> element | 
|  | for an SSL connector is included in the default <code>server.xml</code> | 
|  | file installed with Tomcat. To configure an SSL connector that uses JSSE with | 
|  | the JSSE configuration style, you will need to remove the comments and edit it | 
|  | so it looks something like this:</p> | 
|  | <source><![CDATA[<!-- Define an SSL Coyote HTTP/1.1 Connector on port 8443 --> | 
|  | <Connector | 
|  | protocol="org.apache.coyote.http11.Http11NioProtocol" | 
|  | port="8443" | 
|  | maxThreads="150" | 
|  | SSLEnabled="true"> | 
|  | <SSLHostConfig> | 
|  | <Certificate | 
|  | certificateKeystoreFile="${user.home}/.keystore" | 
|  | certificateKeystorePassword="changeit" | 
|  | type="RSA" | 
|  | /> | 
|  | </SSLHostConfig> | 
|  | </Connector>]]></source> | 
|  | <p> | 
|  | The OpenSSL configuration style uses different attributes for many SSL settings, | 
|  | particularly keys and certificates. An example of an APR configuration style | 
|  | is:</p> | 
|  | <source><![CDATA[<!-- Define an SSL Coyote HTTP/1.1 Connector on port 8443 --> | 
|  | <Connector | 
|  | protocol="org.apache.coyote.http11.Http11NioProtocol" | 
|  | port="8443" | 
|  | maxThreads="150" | 
|  | SSLEnabled="true" > | 
|  | <SSLHostConfig> | 
|  | <Certificate | 
|  | certificateKeyFile="conf/localhost-rsa-key.pem" | 
|  | certificateFile="conf/localhost-rsa-cert.pem" | 
|  | certificateChainFile="conf/localhost-rsa-chain.pem" | 
|  | type="RSA" | 
|  | /> | 
|  | </SSLHostConfig> | 
|  | </Connector>]]></source> | 
|  |  | 
|  |  | 
|  | <p>The configuration options and information on which attributes | 
|  | are mandatory, are documented in the SSL Support section of the | 
|  | <a href="config/http.html#SSL_Support">HTTP connector</a> configuration | 
|  | reference. Tomcat supports either configuration style (JSSE or OpenSSL) with all | 
|  | TLS connectors.</p> | 
|  |  | 
|  | <p>The <code>port</code> attribute is the TCP/IP | 
|  | port number on which Tomcat will listen for secure connections.  You can | 
|  | change this to any port number you wish (such as to the default port for | 
|  | <code>https</code> communications, which is 443).  However, special setup | 
|  | (outside the scope of this document) is necessary to run Tomcat on port | 
|  | numbers lower than 1024 on many operating systems.</p> | 
|  |  | 
|  | <p><em>If you change the port number here, you should also change the | 
|  | value specified for the <code>redirectPort</code> attribute on the | 
|  | non-SSL connector.  This allows Tomcat to automatically redirect | 
|  | users who attempt to access a page with a security constraint specifying | 
|  | that SSL is required, as required by the Servlet Specification.</em></p> | 
|  |  | 
|  | <p>After completing these configuration changes, you must restart Tomcat as | 
|  | you normally do, and you should be in business.  You should be able to access | 
|  | any web application supported by Tomcat via SSL.  For example, try:</p> | 
|  | <source>https://localhost:8443/</source> | 
|  | <p>and you should see the usual Tomcat splash page (unless you have modified | 
|  | the ROOT web application).  If this does not work, the following section | 
|  | contains some troubleshooting tips.</p> | 
|  |  | 
|  | </subsection> | 
|  |  | 
|  | </section> | 
|  |  | 
|  | <section name="Installing a Certificate from a Certificate Authority"> | 
|  | <p>To obtain and install a Certificate from a Certificate Authority (like verisign.com, thawte.com | 
|  | or trustcenter.de), read the previous section and then follow these instructions:</p> | 
|  |  | 
|  | <subsection name="Create a local Certificate Signing Request (CSR)"> | 
|  | <p>In order to obtain a Certificate from the Certificate Authority of your choice | 
|  | you have to create a so called Certificate Signing Request (CSR). That CSR will be used | 
|  | by the Certificate Authority to create a Certificate that will identify your website | 
|  | as "secure". To create a CSR follow these steps:</p> | 
|  | <ul> | 
|  | <li>Create a local self-signed Certificate (as described in the previous section): | 
|  | <source>keytool -genkey -alias tomcat -keyalg RSA | 
|  | -keystore <your_keystore_filename></source> | 
|  | Note: In some cases you will have to enter the domain of your website (i.e. <code>www.myside.org</code>) | 
|  | in the field "first- and lastname" in order to create a working Certificate. | 
|  | </li> | 
|  | <li>The CSR is then created with: | 
|  | <source>keytool -certreq -keyalg RSA -alias tomcat -file certreq.csr | 
|  | -keystore <your_keystore_filename></source> | 
|  | </li> | 
|  | </ul> | 
|  | <p>Now you have a file called <code>certreq.csr</code> that you can submit to the Certificate Authority (look at the | 
|  | documentation of the Certificate Authority website on how to do this). In return you get a Certificate.</p> | 
|  | </subsection> | 
|  |  | 
|  | <subsection name="Importing the Certificate"> | 
|  | <p>Now that you have your Certificate you can import it into you local keystore. | 
|  | First of all you have to import a so called Chain Certificate or Root Certificate into your keystore. | 
|  | After that you can proceed with importing your Certificate.</p> | 
|  |  | 
|  | <ul> | 
|  | <li>Download a Chain Certificate from the Certificate Authority you obtained the Certificate from.<br/> | 
|  | For Verisign.com commercial certificates go to: | 
|  | http://www.verisign.com/support/install/intermediate.html<br/> | 
|  | For Verisign.com trial certificates go to: | 
|  | http://www.verisign.com/support/verisign-intermediate-ca/Trial_Secure_Server_Root/index.html<br/> | 
|  | For Trustcenter.de go to: | 
|  | http://www.trustcenter.de/certservices/cacerts/en/en.htm#server<br/> | 
|  | For Thawte.com go to: | 
|  | http://www.thawte.com/certs/trustmap.html<br/> | 
|  | </li> | 
|  | <li>Import the Chain Certificate into your keystore | 
|  | <source>keytool -import -alias root -keystore <your_keystore_filename> | 
|  | -trustcacerts -file <filename_of_the_chain_certificate></source> | 
|  | </li> | 
|  | <li>And finally import your new Certificate | 
|  | <source>keytool -import -alias tomcat -keystore <your_keystore_filename> | 
|  | -file <your_certificate_filename></source> | 
|  | </li> | 
|  | </ul> | 
|  |  | 
|  | <p>Each Certificate Authority tends to differ slightly from the others. They may | 
|  | require slightly different information and/or provide the certificate and | 
|  | associated certificate chain in different formats. Additionally, the rules that | 
|  | the Certificate Authorities use for issuing certificates change over time. As a | 
|  | result you may find that the commands given above may need to be modified. If | 
|  | you require assistance then help is available via the | 
|  | <a href="http://tomcat.apache.org/lists.html#tomcat-users">Apache Tomcat users | 
|  | mailing list</a>.</p> | 
|  |  | 
|  | </subsection> | 
|  | </section> | 
|  |  | 
|  | <section name="Using OCSP Certificates"> | 
|  | <p> | 
|  | Support of the Online Certificate Status Protocol (OCSP) in Apache Tomcat | 
|  | uses OpenSSL. This can be used either through | 
|  | <a href="https://tomcat.apache.org/download-native.cgi">Tomcat Native</a> | 
|  | or the FFM API on Java 22 and newer. | 
|  | </p> | 
|  | <p>To use OCSP, you require the following:</p> | 
|  |  | 
|  | <ul> | 
|  | <li>OCSP-enabled certificates</li> | 
|  | <li>Tomcat with an OpenSSL enabled connector</li> | 
|  | <li>Configured OCSP responder</li> | 
|  | </ul> | 
|  |  | 
|  | <subsection name="Generating OCSP-Enabled Certificates"> | 
|  | <p>Apache Tomcat requires the OCSP-enabled certificate to have the OCSP | 
|  | responder location encoded in the certificate. The basic OCSP-related | 
|  | certificate authority settings in the <code>openssl.cnf</code> file could look | 
|  | as follows:</p> | 
|  |  | 
|  | <source> | 
|  | #... omitted for brevity | 
|  |  | 
|  | [x509] | 
|  | x509_extensions = v3_issued | 
|  |  | 
|  | [v3_issued] | 
|  | subjectKeyIdentifier=hash | 
|  | authorityKeyIdentifier=keyid,issuer | 
|  | # The address of your responder | 
|  | authorityInfoAccess = OCSP;URI:http://127.0.0.1:8088 | 
|  | keyUsage = critical,digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement,keyCertSign,cRLSign,encipherOnly,decipherOnly | 
|  | basicConstraints=critical,CA:FALSE | 
|  | nsComment="Testing OCSP Certificate" | 
|  |  | 
|  | #... omitted for brevity | 
|  | </source> | 
|  |  | 
|  | <p>The settings above encode the OCSP responder address | 
|  | <code>127.0.0.1:8088</code> into the certificate. Note that for the following | 
|  | steps, you must have <code>openssl.cnf</code> and other configuration of | 
|  | your CA ready. To generate an OCSP-enabled certificate:</p> | 
|  |  | 
|  | <ul> | 
|  | <li> | 
|  | Create a private key: | 
|  | <source>openssl genrsa -aes256 -out ocsp-cert.key 4096</source> | 
|  | </li> | 
|  | <li> | 
|  | Create a signing request (CSR): | 
|  | <source>openssl req -config openssl.cnf -new -sha256 \ | 
|  | -key ocsp-cert.key -out ocsp-cert.csr</source></li> | 
|  | <li> | 
|  | Sign the CSR: | 
|  | <source>openssl ca -openssl.cnf -extensions ocsp -days 375 -notext \ | 
|  | -md sha256 -in ocsp-cert.csr -out ocsp-cert.crt</source> | 
|  | </li> | 
|  | <li> | 
|  | You may verify the certificate: | 
|  | <source>openssl x509 -noout -text -in ocsp-cert.crt</source> | 
|  | </li> | 
|  | </ul> | 
|  | </subsection> | 
|  |  | 
|  | </section> | 
|  |  | 
|  | <section name="Troubleshooting"> | 
|  |  | 
|  | <p>Additional information may be obtained about TLS handshake failures by | 
|  | configuring the dedicated TLS handshake logger to log debug level messages by | 
|  | adding the following to <code>$CATALINA_BASE/conf/logging.properties</code>: | 
|  | <source>org.apache.tomcat.util.net.NioEndpoint.handshake.level=FINE</source>. | 
|  | </p> | 
|  |  | 
|  | <p>Here is a list of common problems that you may encounter when setting up | 
|  | SSL communications, and what to do about them.</p> | 
|  |  | 
|  | <ul> | 
|  |  | 
|  | <li>When Tomcat starts up, I get an exception like | 
|  | "java.io.FileNotFoundException: {some-directory}/{some-file} not found". | 
|  |  | 
|  | <p>A likely explanation is that Tomcat cannot find the keystore file | 
|  | where it is looking.  By default, Tomcat expects the keystore file to | 
|  | be named <code>.keystore</code> in the user home directory under which | 
|  | Tomcat is running (which may or may not be the same as yours :-).  If | 
|  | the keystore file is anywhere else, you will need to add a | 
|  | <code>certificateKeystoreFile</code> attribute to the | 
|  | <code><Certificate></code> | 
|  | element in the <a href="#Edit_the_Tomcat_Configuration_File">Tomcat | 
|  | configuration file</a>.</p> | 
|  | </li> | 
|  |  | 
|  | <li>When Tomcat starts up, I get an exception like | 
|  | "java.io.FileNotFoundException:  Keystore was tampered with, or | 
|  | password was incorrect". | 
|  |  | 
|  | <p>Assuming that someone has not <em>actually</em> tampered with | 
|  | your keystore file, the most likely cause is that Tomcat is using | 
|  | a different password than the one you used when you created the | 
|  | keystore file.  To fix this, you can either go back and | 
|  | <a href="#Prepare_the_Certificate_Keystore">recreate the keystore | 
|  | file</a>, or you can add or update the <code>keystorePass</code> | 
|  | attribute on the <code><Connector></code> element in the | 
|  | <a href="#Edit_the_Tomcat_Configuration_File">Tomcat configuration | 
|  | file</a>.  <strong>REMINDER</strong> - Passwords are case sensitive!</p> | 
|  | </li> | 
|  |  | 
|  | <li>When Tomcat starts up, I get an exception like | 
|  | "java.net.SocketException: SSL handshake error javax.net.ssl.SSLException: No | 
|  | available certificate or key corresponds to the SSL cipher suites which are | 
|  | enabled." | 
|  |  | 
|  | <p>A likely explanation is that Tomcat cannot find the alias for the server | 
|  | key within the specified keystore. Check that the correct | 
|  | <code>certificateKeystoreFile</code> and <code>certificateKeyAlias</code> | 
|  | are specified in the <code><Certificate></code> element in the | 
|  | <a href="#Edit_the_Tomcat_Configuration_File">Tomcat configuration file</a>. | 
|  | <strong>REMINDER</strong> - <code>keyAlias</code> values may be case | 
|  | sensitive!</p> | 
|  | </li> | 
|  |  | 
|  | </ul> | 
|  |  | 
|  | <p>If you are still having problems, a good source of information is the | 
|  | <strong>TOMCAT-USER</strong> mailing list.  You can find pointers to archives | 
|  | of previous messages on this list, as well as subscription and unsubscription | 
|  | information, at | 
|  | <a href="https://tomcat.apache.org/lists.html">https://tomcat.apache.org/lists.html</a>.</p> | 
|  |  | 
|  | </section> | 
|  |  | 
|  | <section name="Using the SSL for session tracking in your application"> | 
|  | <p>This is a new feature in the Servlet 3.0 specification. Because it uses the | 
|  | SSL session ID associated with the physical client-server connection there | 
|  | are some limitations. They are:</p> | 
|  | <ul> | 
|  | <li>Tomcat must have a connector with the attribute | 
|  | <strong>isSecure</strong> set to <code>true</code>.</li> | 
|  | <li>If SSL connections are managed by a proxy or a hardware accelerator | 
|  | they must populate the SSL request headers (see the | 
|  | <a href="config/valve.html">SSLValve</a>) so that | 
|  | the SSL session ID is visible to Tomcat.</li> | 
|  | <li>If Tomcat terminates the SSL connection, it will not be possible to use | 
|  | session replication as the SSL session IDs will be different on each | 
|  | node.</li> | 
|  | </ul> | 
|  |  | 
|  | <p> | 
|  | To enable SSL session tracking you need to use a context listener to set the | 
|  | tracking mode for the context to be just SSL (if any other tracking mode is | 
|  | enabled, it will be used in preference). It might look something like:</p> | 
|  | <source><![CDATA[package org.apache.tomcat.example; | 
|  |  | 
|  | import java.util.EnumSet; | 
|  |  | 
|  | import jakarta.servlet.ServletContext; | 
|  | import jakarta.servlet.ServletContextEvent; | 
|  | import jakarta.servlet.ServletContextListener; | 
|  | import jakarta.servlet.SessionTrackingMode; | 
|  |  | 
|  | public class SessionTrackingModeListener implements ServletContextListener { | 
|  |  | 
|  | @Override | 
|  | public void contextDestroyed(ServletContextEvent event) { | 
|  | // Do nothing | 
|  | } | 
|  |  | 
|  | @Override | 
|  | public void contextInitialized(ServletContextEvent event) { | 
|  | ServletContext context = event.getServletContext(); | 
|  | EnumSet<SessionTrackingMode> modes = | 
|  | EnumSet.of(SessionTrackingMode.SSL); | 
|  |  | 
|  | context.setSessionTrackingModes(modes); | 
|  | } | 
|  |  | 
|  | }]]></source> | 
|  |  | 
|  | </section> | 
|  |  | 
|  | <section name="Miscellaneous Tips and Bits"> | 
|  |  | 
|  | <p>To access the SSL session ID from the request, use:</p> | 
|  |  | 
|  | <source><![CDATA[String sslID = (String)request.getAttribute("jakarta.servlet.request.ssl_session_id");]]></source> | 
|  | <p> | 
|  | For additional discussion on this area, please see | 
|  | <a href="https://bz.apache.org/bugzilla/show_bug.cgi?id=22679">Bugzilla</a>. | 
|  | </p> | 
|  |  | 
|  | <p>To terminate an SSL session, use:</p> | 
|  | <source><![CDATA[// Standard HTTP session invalidation | 
|  | session.invalidate(); | 
|  |  | 
|  | // Invalidate the SSL Session | 
|  | org.apache.tomcat.util.net.SSLSessionManager mgr = | 
|  | (org.apache.tomcat.util.net.SSLSessionManager) | 
|  | request.getAttribute("jakarta.servlet.request.ssl_session_mgr"); | 
|  | mgr.invalidateSession(); | 
|  |  | 
|  | // Close the connection since the SSL session will be active until the connection | 
|  | // is closed | 
|  | response.setHeader("Connection", "close");]]></source> | 
|  | </section> | 
|  |  | 
|  | </body> | 
|  |  | 
|  | </document> |