Okay, I finally got around to writing that SSL HOWTO I kept promising. It's 
attached.

Yeah, yeah, it's a plain old text file. I can't be bothered with XHTML or 
DocBooks at 2:00am =)

Seriously, though, the doc format stuff is still kind of up in the air AFAIK, 
and I wasn't sure how or where (or if) this would make sense in the tree, so 
let me know if you want it in a certain format and I'll see what I can do.

As always, feel free to read it, rip it apart, suggest corrections, anything. I 
went with this basic approach:

Section 1: Quickstart (the wham-bam summary for experts)

Section 2: Fluffy stuff (A brief tour of "What is SSL," "SSL and Tomcat", "Tips 
on Running SSL", etc.)

Section 3: Detailed install/config steps

Section 4: Troubleshooting (all common mistakes/exceptions and their remedies)

If you think it's too much, let me know.

Also, I'll make the minor changes necessary and fire off a TC 3.3 version in 
the morning.

Love to the family,

- Christopher

          Tomcat 4.0 Standalone - SSL Configuration


Author: Christopher Cain
        <[EMAIL PROTECTED]>

QUICKSTART VERSION

1. Download JSSE 1.0.2 or later and make it an "installed extension" by copying
   the JAR files into "$JAVA_HOME/jre/lib/ext".

2. Create the certificate keystore

   keytool -genkey -alias tomcat -keyalg RSA

3. Add the "com.sun.net.ssl.internal.ssl.Provider" provider to the
   java.security file.

4. Uncomment the secure connector example in server.xml and tweak as necessary

INTRODUCTION TO SSL

SSL, or Secure Socket Layer, is a technology which allows 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 prior to any processing. This is a two-way process, meaning that both the
server AND the browser encrypt all traffic before sending out data.

Another important aspect of the SSL protocol is Authentication. The 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 YOU are who you claim to be.
This is known as "Client Authentication," although in practice this is a
somewhat rare and highly specialized configuration. Most SSL-enabled web
servers do not request Client Authentication.

SSL AND TOMCAT

It is important to note that configuring Tomcat to take advantage of secure
sockets is usually only necessary when running it as a standalone web server.
When running Tomcat primarily as a Servlet/JSP engine 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. Typically, this server
will negotiate all SSL-related functionality, then pass on any requests
destined for the Tomcat engine only after decrypting those requests. In this
environment, Tomcat does not know, nor does it care, that communications
between the primary web server and the client are taking place over a secure
connection. It transmits and receives data just as it normally would.

CERTIFICATES

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 "driver's license" for an internet address. It states
what company the address is associated with, along with some basic contact
information about the site owner or administrator. This "driver's license"
is cryptographically signed by its owner, and an "official" Certificate is
therefore extremely difficult for anyone else to forge. For sites involved in
e-commerce, or any other business in which Authentication of identity is
important, an "official" certificate is typically purchased from a well-known
"Certificate Authority" (CA) such as VeriSign or Thawte.

In many cases, however, Authentication is not a really a concern. An
administrator may simply want to ensure that the data being transmitted and
received by the server is private and cannot be snooped by anyone who may be
eavesdropping on the connection. Fortunately, Sun provides a relatively simple
command-line tool, called "keytool," which can easily create "Self-Signed"
Certificates. Self-signed Certificates are simply user-generated Certificates
which have not been officially blessed by any well-known CA and are therefore
not really guaranteed to be authenticate at all. Again, this may or may not
even be important, depending on your specific requirements and needs.

GENERAL TIPS ON RUNNING SSL

The first time a user attempts to access a secured page on your site, he or she
is typically presented with a dialog containing the details of the certificate,
such as company and contact name, and asked if he or she wishes to accept the
certificate as valid and continue with the transaction. Some browsers will
provide an option for permanently accepting a given Certificate as valid, in
which case the user will not be bothered with the prompt each time they visit
your site. Other browsers do not provide this option. Once approved by the
user, a Certificate will be considered valid for at least the entire browser
session.

Also, while the SSL protocol was designed to be as efficient as securely
possible, encryption/decryption is a naturally expensive process from a
performance standpoint. If is not strictly necessary to run an entire web
application over SSL, and indeed a developer can pick and choose which pages
require a secure connection and which do not For a reasonably busy site, it is
customary to only run certain pages under SSL, namely those pages where
sensitive information could possibly be exchanged. This would include things
like login pages, personal information pages, and store checkouts, where credit
card information could possibly be transmitted. Any page within an application
can be requested over a secure socket by simply prefixing the address with
"https:" instead of "http:". Any pages which absolutely REQUIRE a secure
connection should check the protocol type associated with the page request and
take the appropriate action if "https" was not specified.

CONFIGURATION

(0) Download and Install JSSE 1.0.2 or Later

Download the JSSE package, available at
<http://java.sun.com/products/jsse/index-102.html>. If you built Tomcat from
source, you have probably already downloaded this package. If you are running
JDK 1.4 (currently in beta), these classes have been integrated directly into
the JDK, so you may be able to skip this step.

After expanding the package, copy all three JAR files (jcert.jar, jnet.jar,
and jsse.jar) into your "$JAVA_HOME/jre/lib/ext" directory. This effectively
makes them "installed extensions," and obviates the need to put them into the
CLASSPATH.

Note: DO NOT copy any of these JAR files into any of the internal Tomcat
classloading repositories (i.e. $TC_HOME/common/lib, $TC_HOME/lib, and
$TC_HOME/server/lib). If they are also in your CLASSPATH or installed
extensions, this will cause Tomcat to fail on startup!

(1) Prepare the Certificate Keystore

Tomcat currently operates only on JKS format keystores. This is the Sun's
standard "Java KeyStore" format, and this is the format created by Sun's
"keytool" utility. "keytool" is a generic command-line utility for managing
keystore, and is included in the JDK.

* To import an existing certificate into a JKS keystore, please read the
  documentation on the keytool utility.

* To create a new keystore from scratch, containing a single, self-signed
  certificate, execute the following from a terminal command-line:

   keytool -genkey -alias tomcat -keyalg RSA

(The RSA algorithm should be preferred as a secure algorithm, and also to ensure
general compatibility with other servers and components.)

This command will create a new file, in the home directory of the user under
which you run it, named ".keystore". To specify a different location/filename,
add the "-keystore" parameter (you will need to specify the new path/name in
the appropriate configuration file as explained later):

   keytool -genkey -alias tomcat -keyalg RSA -keystore /path/to/my/keystore

After executing this command, you will first be prompted for the keystore
password. The default password used by Tomcat is "changeit" (all lowercase),
although you can specify a custom password if you like (you will need to
specify the custom password in the appropriate configuration file as explained
later).

Next you will be prompted for general information about the certificate, such
as company, contact name, etc. Finally, you will be prompted for the
"key password", which is the password specifically for the certificate. You
MUST specify the same password that was used as the keystore password
(currently, as noted by the keytool prompt, hitting RETURN does this
automatically).

If everything was successful, you now have a keystore and certificate for your
server.

(2) Add the SSL provider to the JVM

When the JVM attempts to load up the necessary classes for SSL during
execution, it checks for an appropriate "Provider" for the service. In order
to let the JVM know that it has a suitable SSL provider installed (which was
actually included in the JSSE package), you must edit the
"$JAVA_HOME/jre/lib/security/java.security" file and add an entry. The very
first section of this configuration file should have one or more lines that
resemble the following:

   security.provider.1=sun.security.provider.Sun

The syntax here is:

   security.provider.{search order number}={installed provider class}

In order to register the SSL provider, add a line like the following:

   security.provider.3=com.sun.net.ssl.internal.ssl.Provider

The "3" is just an example number. Please use a number not already taken in the
existing provider list.

(3) Edit the "$TC_HOME/conf/server.xml" Configuration File

The final step is to configure your secure socket in the "server.xml"
configuration file. An example SSL <Connector> is included in the default
"server.xml" file installed with Tomcat. There will be a comment just above it
to the effect of:

   <!-- Define an SSL HTTP/1.1 Connector on port 8443 -->

... or something similar. The connector itself is commented-out by default, so
all that remains is to remove the comment tags and customize as necessary. The
primary attribute you may wish to change is the "port" attribute, which
tell Tomcat which port to bind the secure socket to. If you change the port
number here, you should also change the "redirectPort" attribute on any
non-secure sockets you have defined, as that is how Tomcat redirects secure
connection attempts sent to insecure HTTP ports.

Finally, you will notice a <Factory> tag nested inside the secure <Connector>
tag. This is where you will set the keystore location and/or password. If you
chose to go with the defaults in both cases, you do not have to make any
further changes, and you should now be ready to roll. If you specified a
different location/filename for the keystore, add a "KeystoreFile" attribute
and set the value to point to your keystore file. If you chose a password
other than "changeit", add a "KeystorePass" attribute and set the value to your
password. A custom keystore, therefore, might look like this:

   <Factory className="org.apache.catalina.net.SSLServerSocketFactory"
               clientAuth="false" protocol="TLS"
               KeystoreFile="/path/to/.keystore" KeystorePass="mypassword" />

(4) Fire Up That Bad Boy

You should now be in business. Simply start Tomcat up as you normally do, and
if all goes according to plan, you should now see a new binding on the
specified port number, listening for https requests, in which case you're
golden. If not ...

TROUBLESHOOTING

* I get "java.security.NoSuchAlgorithmException ..." when I try to execute the
  "keytool" command or on Tomcat startup.

The JVM cannot find the JSSE JARS, or the provider is not registered. Make sure
that the "security.provider.3=com.sun.net.ssl.internal.ssl.Provider" line is in
your "$JAVA_HOME/jre/lib/security/java.security" file, and that the three JSSE
JARS are either in the "$JAVA_HOME/jre/lib/ext" directory (preferred) or in
your CLASSPATH.

* When I try to start Tomcat, I get a long stacktrace with
  "java.io.FileNotFoundException {some_directory}/{some file} not found"
  somewhere near the beginning.

Tomcat cannot find the keystore. If you didn't specify the -keystore parameter
when generating the keystore, make sure the "/.keystore" file is in the home
directory of the user TOMCAT IS RUNNING AS. If you specified a custom file with
the -keystore parameter, make sure the file is there, that Tomcat would have
read access to it, and that it is properly specified in the "KeystoreFile"
attribute of the <Factory> tag in "server.xml".

* When I try to start Tomcat, I get a long stacktrace with
  "java.io.FileNotFoundException  Keystore was tampered with, or password was
  incorrect" near the beginning.

Assuming that someone hasn't _actually_ tampered with it, the most likely cause
is Tomcat is using an incorrect password. If you specified the Tomcat default
password of "changeit" (all lowercase) for both the keystore and the
certificate, ensure that there is not a "KeystorePass" attribute on the
<Factory> tag in "server.xml", or if there is that it is set to "changeit". If
you specified a different password, ensure that the "KeystorePass" attribute IS
set, and that it is correct. Passwords ARE case-sensitive.

Reply via email to