views:

292

answers:

2

Ran into another problem using SSL and Tomcat: I've configured a keystore which contains a key and a certificate (the server certificate I wish to present to the clients connecting to the site). I've done the same for the truststore (I'm going to need client authentication).

The problem I have now is that when I connect to my Tomcat instance via HTTPS, the certificate presented to me (the server certificate) is not my actual server certificate, but rather the key in the JKS keystore. Using -Djavax.net.debug=ssl reveals that it's presenting the correct CA for client authentication, but not the correct server certificate.

adding as trusted cert:
  Subject: CN=A
  Issuer:  CN=A
  Algorithm: RSA; Serial number: -
  Valid from Tue Nov 10 14:48:31 CET 2009 until Mon Feb 08 14:48:31 CET 2010

adding as trusted cert:
  Subject: X
  Issuer:  X
  Algorithm: RSA; Serial number: -
  Valid from Wed Jan 19 01:00:00 CET 2005 until Mon Jan 19 00:59:59 CET 2015

I've replaced the real values with place holders. A = the domain name of the server (but in this case, for some reason this is the key and not the certificate). X = a VeriSign CA (this should be correct). I have an existing certificate I would like to use to present to the clients, which I imported into a JKS keystore using keytool.

The Tomcat connector configuration:

Connector port="444" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"       
keystoreFile="conf/ssl/keystore.jks"
keystorePass="xx"
keyAlias="testkey"
truststoreFile="conf/ssl/truststore.jks"
truststorePass="xx"

Any idea why my Tomcat instance is not presenting the correct certificate?

+2  A: 

Your configuration should work correctly.

Tomcat's how-to explains the steps to take in order to have a proper JKS.

Make sure you have imported the Certificate to the jks, with the appropriate alias (testKey)

Bozho
When I set the keyAlias to the alias of the certificate in the keystore, Tomcat won't boot correctly. I'm assuming the keyAlias parameters is used to specify the key, not the certificate.I get a feeling that Tomcat will never properly present my certificate, because it was created separately. Right now I'm going to try to generate a brand new certificate from scratch using keytool instead of openssl, and see if that makes a difference.
pHk
yes, try that. The key and the certificate, as it can be seen in the tomcat how-to, are to be under the same alias.
Bozho
My previous attempt failed. I'm doing something wrong, but I don't know what. Is it even possible to present an existing certificate, or do you have to use keytool to generate a new one? This is confusing.
pHk
What I'm trying to do is identical to the following issue: http://stackoverflow.com/questions/1180397/tomcat-server-client-self-signed-ssl-certificate. Only, I don't want to generate a new certificate, I want to use an existing one.
pHk
the general flow is this - you generate a Key an a CSR, then based on that CSR you get a certificate (either by yourself, or from VeriSign/GeoTrust/etc.) and import it.
Bozho
I have done that, generated a key and CSR using keytool, signed it with my own CA using OpenSSL, and then imported the signed certificate back into the keystore. Using this keystore, Tomcat still sends the keyEntry and not the trustedCertificate entry for some reason.
pHk
Could it be that it's not presenting the certificate because the CA with which it was signed is not a part of the truststore?
pHk
no - the truststore is completely different thing
Bozho
I've figured it out - I'll answer my question soon when I get some free time (I've already wasted too much time on this :D).
pHk
+2  A: 

The problem is (apparently - I can not really confirm this) that it's impossible to properly import a previously generated certificate (and matching key) into a JKS keystore and have it presented properly by Tomcat.

The situation in which my problem occurred is as follows:

  1. I have a certificate file, which I generated myself using OpenSSL from scratch (key + CSR -> certificate), signed by my own CA.
  2. I wish to configure Tomcat so that it presents this particular certificate to the users connecting to my site.

The solution I found to work is:

  1. Convert the existing certificate and its private key to the DER format. For example (using OpenSSL):

    For the private key;

    openssl pkcs8 -topk8 -nocrypt -in my_private_key.key -inform PEM -out my_private_key.der -outform DER

    For the actual signed certificate;

    openssl x509 -in my_certificate.crt -inform PEM -out my_certificate.der -outform DER

  2. Import both DER files into a keystore (JKS file) using a custom Java class.

    java ImportKey my_private_key.der my_certificate.der

    I did not figure this out myself (all credit goes to the original inventor(s)).The source for this Java class, and some more details can be found here and here. I modified this class slightly so that there is a 3rd (or 4th) parameter that specifies the output location of the resulting JKS file.

The end result is a JKS keystore which can then be used in the Tomcat Connector configuration as the keystore. The above tool will generate the JKS file with default passwords for the key and JKS file itself, these can be changed later using keytool -storepasswd and keytool -keypasswd. Hope this helps for people facing the same issue.

pHk