Using TLS/SSL

Introduction

The usage of TLS/SSL (Transport Layer Security / Secure Sockets Layer) protocols allows two applications to exchange data in an encrypted way, as for example between a browser client and an HTTP server when using the HTTPS access method (https://.....).

The TLS/SSL support in James is available for both SMTPS ("secured" SMTP) and POP3S ("secured" POP3), independently of each other. To activate it, James must be configured in such a way that it expects TLS/SSL connection requests over specific ports, typically 465 for SMTPS and 995 for POP3S.

POP3S is used between a mail client application and a James server to download confidential messages from the inbox to the client. SMTPS is used between a mail client application and a James server to upload confidential messages to James and have it sent out.

SMTPS could also be used between two SMTP servers to exchange messages, but it would be a special setting, as the two servers would need to known in advance that they should communicate between them in a special way (SMTPS). Instead, the standard behaviour is to have an SMTP server connect to another SMTP server on port 25 using plain SMTP.

So, the most useful scenario is the following:

  1. Have your James server as usual waiting with the "pop3server" service on port 110 using plain POP3 to allow the clients download emails from their inboxes as per their normal setup.
  2. Have your James server as usual waiting with the "smtpserver" service on port 25 using plain SMTP to allow the clients upload emails as per their normal setup and other SMTP servers connect as standard to bring inbound mail.
  3. Add a new service waiting on port 995 using POP3S to allow the clients to securely download emails from their inboxes if properly setup.
  4. Add a new service waiting on port 465 using SMTPS to allow the clients to securely upload emails if properly setup.

This way, properly setup clients, managed by users "local" to your James server, can securely exchange confidential messages even if running on laptops or other PCs physically located outside the local network: no internal or external sniffer can "see" the contents of such messages. Obviously, messages coming from / going to other SMTP servers do anyway travel in clear. All this assumes that the administrator is reliable and the James server spools and mailboxes are properly protected, as they are not encrypted.

Same considerations (and equivalent setup examples) would also apply to NNTPS.


PKI and X.509 Certificates

TLS/SSL uses PKI technology, with X.509 certificates; the James implementation uses "standard" Java Cryptography Architecture.

A "keypair" must be generated for the James server (use -keyalg RSA); a signed X.509 certificate could be requested from a Certification Authority automatically trusted by the various mail clients, in order to have them accept the TLS/SSL session without asking the end user for a "trust" confirmation.

A "self-signed" certificate (i.e. not signed by anyone else) or signed by a "non trusted" Certification Authority should also work (tested with MS Outlook 2000 and MS Outlook Express). In such case the behaviour of an Outlook 2000 client is to popup a message box saying: "The server you are connected to is using a security certificate that could not be verified. A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider. Do you want to continue using this server?". If the answer is yes further requests to the server will be automatically accepted until the client is restarted, in which case the server will become untrusted again. To have the server become permanently trusted by the client, the certificate must be exported from the server java keystore by the administrator and imported into the Windows certificate store of the client by the end user. If the keypair is shared with an HTTP server, an HTTPS request from Internet Explorer by the end user on the client will allow for storing the certificate in the Windows certificate store of the client.

From this discussion it should become clear that a certificate signed by a recognized Certification Authority is a must for a production James server.

Recognized Certification Authorities among others are Verisign (http://www.verisign.com/products/site/index.html?sl=060302) and Thawte (http://www.thawte.com/buy.html).

The process is the same as for Apache/Tomcat (the keypair and the keystore can even be shared): see http://jakarta.apache.org/tomcat/tomcat-4.1-doc/ssl-howto.html. Other info can be found in http://java.sun.com/j2se/1.4.2/docs/tooldocs/windows/keytool.html#Examples (for Windows) and http://java.sun.com/j2se/1.4.2/docs/tooldocs/solaris/keytool.html/keytool.html#Examples (for Unix/Linux). See also http://developer.java.sun.com/developer/qow/archive/167/index.jsp.


James setup examples

James setup example for SMTPS

Here follows an SMTPS example, where a new SMTP service named smtpserver-tls is setup.


In config.xml, setup a different service for ssl/tls, using port 465 (just duplicate the existing entry for the smtpserver service, change the name to smtpserver-tls and change the entries as shown below):

<smtpserver-tls enabled="true">
    <!-- port 465  is the well-known/IANA registered port for SMTPS -->
    <port>465</port>
    <useTLS>true</useTLS>
    ...
</smtpserver-tls>


Enable the ssl factory section of <server-sockets> (shared with POP3S), replacing <file> with the appropriate certificate keystore address and setting the correct keystore password and private key password.

<factory name="ssl"
         class="org.apache.avalon.cornerstone.blocks.sockets.TLSServerSocketFactory">
    <ssl-factory>
        <keystore>
            <file>conf/keystore</file>
            <password>secret</password>
            <key-password>keysecret</key-password>
            <type>JKS</type>
            <protocol>TLS</protocol>
            <algorithm>SunX509</algorithm>
            <authenticate-client>false</authenticate-client>
        </keystore>
    </ssl-factory>
</factory>

The <key-password> element must be filled even if the private key password is the same as the keystore password.

If using James with a version < 2.3.x, the entry will be as follows (no <ssl-factory> nor <key-password> tags, and the private key password must be the same as the keystore password):

<factory name="ssl"
         class="org.apache.avalon.cornerstone.blocks.sockets.TLSServerSocketFactory">
    <keystore>
        <file>conf/keystore</file>
        <password>secret</password>
        <type>JKS</type>
        <protocol>TLS</protocol>
        <algorithm>SunX509</algorithm>
        <authenticate-client>false</authenticate-client>
    </keystore>
</factory>


The smtpserver-tls service must be declared in assembly.xml (just duplicate the existing entry for the smtpserver service and change the name to smtpserver-tls):

<block name="smtpserver-tls" class="org.apache.james.smtpserver.SMTPServer">
    <provide name="James" role="org.apache.mailet.MailetContext"/>
    <provide name="mailstore" role="org.apache.james.services.MailStore"/>
    <provide name="users-store" role="org.apache.james.services.UsersStore"/>
    <provide name="sockets"
             role="org.apache.avalon.cornerstone.services.sockets.SocketManager"/>
    <provide name="connections"
             role="org.apache.avalon.cornerstone.services.connection.ConnectionManager"/>
    <provide name="James" role="org.apache.james.services.MailServer"/>
    <provide name="thread-manager"
             role="org.apache.avalon.cornerstone.services.threads.ThreadManager" />
</block>


Also add this to environment.xml to get log files (set the log-level as appropriate) (just duplicate the existing entry for the smtpserver category and change the name to smtpserver-tls):

<category name="smtpserver-tls" log-level="DEBUG">
    <log-target id-ref="smtpserver-target"/>
</category>

In this example the log target is shared with smtpserver.


James setup example for POP3S

Here follows a POP3S example, where a new POP3 service named pop3server-tls is setup.


In config.xml, setup a different service for ssl/tls, using port 995 (just duplicate the existing entry for the pop3server service, change the name to pop3server-tls and change the entries as shown below):

<pop3server-tls enabled="true">
<!-- port 995 is the well-known/IANA registered port for POP3S ie over SSL/TLS -->
    <port>995</port>
    <useTLS>true</useTLS>
    ...
</pop3server-tls>


Enable the ssl factory section of <server-sockets>, shared with SMTPS (see the SMTPS example above).


The pop3server-tls service must be declared in assembly.xml (just duplicate the existing entry for the pop3server service and change the name to pop3server-tls):

<block name="pop3server-tls" class="org.apache.james.pop3server.POP3Server" >
    <provide name="mailstore" role="org.apache.james.services.MailStore"/>
    <provide name="users-store" role="org.apache.james.services.UsersStore"/>
    <provide name="sockets"
             role="org.apache.avalon.cornerstone.services.sockets.SocketManager"/>
    <provide name="connections"
             role="org.apache.avalon.cornerstone.services.connection.ConnectionManager"/>
    <provide name="James" role="org.apache.james.services.MailServer"/>
    <provide name="thread-manager"
             role="org.apache.avalon.cornerstone.services.threads.ThreadManager" />
</block>


Also add this to environment.xml to get log files (set the log-level as appropriate) (just duplicate the existing entry for the pop3server category and change the name to pop3server-tls):

<category name="pop3server-tls" log-level="DEBUG">
    <log-target id-ref="pop3server-target"/>
</category>

In this example the log target is shared with pop3server.


Mail Client Setup

MS Outlook 2000

In the "Advanced" tab of the account setup check the "This server requires a secure connection (SSL)" checkboxes, and set the port numbers to the appropriate values. Warning: while the POP3 checkbox will automatically change the port number from 110 to 995, the SMTP checkbox will keep the port number as 25; you must manually set it to 465.

Mozilla 1.7

Go to "Edit/Mail & Newsgroups Accounts Settings" menu, choose you account, enter in "Server Settings". Check the "Use secure connection (SSL)" box; "995" will be choosen as the default port: don't change it. Next, in the same panel, choose the "Outgoing Server (SMTP)" entry and select the SSL radio button (not the TLS ones); "465" will be choosen as the default port: don't change it.

With Mozilla a problem can now occur: you can get a "mysmtp.mydomain.com has received an incorrect or unexpected message. Error Code: -12229" error, with a related set of "java.security.NoSuchAlgorithmException: Could not create cipher AES/128" message in the pop3server log. This is not a bug in James: it simply arises because Mozilla tries by default to use some cryptographic algorithms not provided as a standard in the Java VM (at least - in my knowledge - not in the Sun JRE 1.4.2). A solution on the client side would be to tell Mozilla not to use the unsupported algorithms; a much better solution is to have the JVM used by James support such algorithms - see the section Supporting More Security Algorithms below.


Supporting More Security Algorithms

Some cryptographic algorithms not provided as a standard in the Java VM (at least - in my knowledge - not in the Sun JRE 1.4.2) may be needed by some Mail Clients, for example by Mozilla 1.7.

The solution is to add other security providers.

Using Sun JRE 1.4.2

Here follow the steps to add the Legion of the Bouncy Castle provider, assuming a Sun JRE 1.4.2 installation under Windows:

  1. Download the appropriate bcprov-jdkxx-yyy.jar from http://www.bouncycastle.org/latest_releases.html (where xx is the jdk release and yyy is the Bouncy Castle release - bcprov-jdk14-124.jar is the current one for JRE 1.4.x at the beginning of July 2004).

  2. Put the jar in the {james}\lib directory (warning: not in the {james}\apps\james\SAR-INF\lib directory!).
  3. Edit the {Program Files}\Java\j2re1.4.2\lib\security\java.security file, adding a security.provider.n=org.bouncycastle.jce.provider.BouncyCastleProvider line to the other security.provider lines, where n is the preference order.

  4. Restart James, and Mozilla will work with SSL!

You could play with the preference order above to get the best performance.

Using Sun JRE 1.5.n

With JRE 1.5.n you must copy the Sun JCE provider from {Program Files}\Java\j2re1.5.n_nn\lib\ext\sunjce_provider.jar file into the {james}\lib directory (warning: not in the {james}\apps\james\SAR-INF\lib directory!). The Bouncy Castle bcprov*.jar won't make it.


Preparing the Certificate Keystore

(Adapted from the Tomcat 4.1 documentation)

James currently operates only on JKS format keystores. This is Java's standard "Java KeyStore" format, and is the format created by the keytool command-line utility. This tool is included in the JDK.

To import an existing certificate into a JKS keystore, please read the documentation (in your JDK documentation package) about keytool.

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

keytool -genkey -alias james -keyalg RSA -keystore <your_keystore_filename>

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

As a suggested standard, create the keystore in the james/conf directory (the same containing sqlResources.xml), with a name like james.keystore. Any name and location though is fine, as long as is the same as in the <file> of the ssl factory section of <server-sockets> in config.xml.

After executing this command, you will first be prompted for the keystore password.

Next, you will be prompted for general information about this Certificate, such as company, contact name, and so on. This information may be displayed to users when importing into the certificate store of the client, so make sure that the information provided here matches what they will expect.

Important: in the "distinguished name", set the "common name" (CN) to the DNS name of your James server, the one you will use to access it from your mail client (like "mail.xyz.com").

Finally, you will be prompted for the key password, which is the password specifically for this Certificate (as opposed to any other Certificates stored in the same keystore file). If using James with version < 3.x, you MUST use the same password here as was used for the keystore password itself. (Currently, the keytool prompt will tell you that pressing the ENTER key does this for you automatically.)

If everything was successful, you now have a keystore file with a Certificate that can be used by your server.

You MUST have only one certificate in the keystore file used by James.


Installing a Certificate from a Certificate Authority

(Adapted from the Tomcat 4.1 documentation)

To obtain and install a Certificate from a Certificate Authority (like verisign.com, thawte.com or trustcenter.de) you should have read the previous section and then follow these instructions:

Create a local Certificate Signing Request (CSR)

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 James server as "secure". To create a CSR follow these steps:

Create a local Certificate as described in the previous section.

The CSR is then created with:

keytool -certreq -keyalg RSA -alias james \
        -file certreq.csr -keystore <your_keystore_filename>

Now you have a file called certreq.csr. The file is encoded in PEM format. You can submit it to the Certificate Authority (look at the documentation of the Certificate Authority website on how to do this). In return you get a Certificate.

Importing the Certificate

Now that you have your Certificate you can import it into you local keystore. First of all you may have to import a so called Chain Certificate or Root Certificate into your keystore (the major Certificate Authorities are already in place, so it's unlikely that you will need to perform this step). After that you can procede with importing your Certificate.

Optionally Importing a so called Chain Certificate or Root Certificate

Download a Chain Certificate from the Certificate Authority you obtained the Certificate from.

Import the Chain Certificate into you keystore

keytool -import -alias root -keystore <your_keystore_filename> \
        -trustcacerts -file <filename_of_the_chain_certificate>

Importing the requested Cerificate

And finally import your new Certificate (It must be in X509 format):

keytool -import -alias james -keystore <your_keystore_filename> \
        -trustcacerts -file <your_certificate_filename>

See also: http://www.agentbob.info/agentbob/79.html

UsingSSL (last edited 2009-09-20 22:58:14 by localhost)