Bug 43094

Summary: Allowing non-file based keystore and other providers
Product: Tomcat 6 Reporter: Bruno Harbulot <Bruno.Harbulot>
Component: ConnectorsAssignee: Tomcat Developers Mailing List <dev>
Severity: normal CC: hauser
Priority: P2    
Version: 6.0.13   
Target Milestone: default   
Hardware: Other   
OS: other   
Attachments: Patch for allowing to specify keystores providers and not to need a keystore file

Description Bruno Harbulot 2007-08-11 14:50:54 UTC

I would like to use the MacOSX Keychain store for providing my 
certificates to Tomcat. Generally speaking, this can be done by loading the
KeyStore like this:

  KeyStore keyStore = KeyStore.getInstance("KeychainStore","Apple");
  keyStore.load(null, null);
In fact, it seems to work without specifying the "Apple" provider too.
However, similarly to PKCS11, this type does not require an input file.

The problem is that org.apache.tomcat.util.net.jsse.JSSESocketFactory
always tries to load a file, except when the type is PKCS11.

Not specifying a keystoreFile or truststoreFile parameter defaults to
trying to load ~/.keystore. I would like to suggest the following patch
which allows to specify an empty value, indicating the no file needs to
be loaded:

--- JSSESocketFactory.java.old  2007-08-11 22:58:24.000000000 +0200
+++ JSSESocketFactory.java      2007-08-11 23:24:53.000000000 +0200
@@ -307,7 +307,7 @@
         InputStream istream = null;
         try {
             ks = KeyStore.getInstance(type);
-            if(! "PKCS11".equalsIgnoreCase(type) ) {
+            if(! "".equalsIgnoreCase(path) ) {
                 File keyStoreFile = new File(path);
                 if (!keyStoreFile.isAbsolute()) {
                     keyStoreFile = new File(System.getProperty("catalina.base"),
This way, not having to load a file is not limited to PKCS11, but could be 
used by other keystore types.
Using this patch, the following configuration works fine with keys and
certificates stored in the Apple Keychain (for some reason, the KeychainStore 
requires a non-empty password; it seems to work whatever the password is, 
since it may be asked interactively by the Keychain utility, depending on 
how it is set up)

<Connector SSLEnabled="true" clientAuth="want"
	keystoreFile="" keystorePass="-"
	keystoreType="KeychainStore" maxThreads="150" port="8443"
	protocol="HTTP/1.1" scheme="https" secure="true" sslProtocol="TLS"
	truststorePass="-" truststoreType="KeychainStore" />


Comment 1 Bruno Harbulot 2007-08-11 15:01:07 UTC
Created attachment 20649 [details]
Patch for allowing to specify keystores providers and not to need a keystore file

Another improvement to this might be to add a parameter for the provider to the

'getStore' method and pass it through 'keystoreProvider' and
truststoreProvider' attributes.
In my use case, it seems to work without specifying the provider, "Apple", but
I guess there might be cases where it could be useful, for other providers.

The configuration would look like this (I've tried it and it works -- it also
fails if I provide the wrong provider, quite logically):

<Connector SSLEnabled="true" clientAuth="want"
	keystoreFile="" keystorePass="-" keystoreProvider="Apple"
	keystoreType="KeychainStore" maxThreads="150" port="8443"
	protocol="HTTP/1.1" scheme="https" secure="true" sslProtocol="TLS"
	truststoreFile="" truststoreProvider="Apple"
	truststorePass="-" truststoreType="KeychainStore" />
Comment 2 Filip Hanik 2007-08-13 10:26:26 UTC
Thanks for the patch, I will review it and possible extend it to the NIO
connector as well
Comment 3 Mark Thomas 2008-05-03 13:22:07 UTC
I have applied a patch to trunk based on your suggestion and proposed it for 6.0.x.
Comment 4 Bruno Harbulot 2008-05-12 10:32:02 UTC
(In reply to comment #3)
> I have applied a patch to trunk based on your suggestion and proposed it for
> 6.0.x.

Thank you.
I've just had a look at http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java?revision=653128&view=markup
It seems that you've applied a patch along the original report and not the second patch I sent with comment #1. I believe that second patch (being able to set the provider name) could also be useful, even for PKCS#11 applications (one of the ways to configure PKCS#11 is to set up the PKCS#11 options as part of the JVM security provider list, which adds a provider with a new name).

More generally, since I opened this issue, I've been making similar suggestions for other projects, in particular Jetty [1] and Restlet [2]. This led me to write a few classes (SSLContext factories) to make the configuration of SSL properties a bit easier, including more advanced options such as Certificate Revocation Lists (I must admit I'm not quite sure how CRLs are to be configured in Tomcat). These classes are available at http://code.google.com/p/jsslutils/. I'm not sure whether this would be useful for Tomcat, but this might be of interest (feel free to get in touch...).

[1] http://www.mortbay.org/jetty/
[2] http://www.restlet.org/
Comment 5 Mark Thomas 2008-05-15 12:48:50 UTC
The simple patch has been committed to 6.0.x and will be in 6.0.17 onwards. I am leaving this bug open and I'll come back to it for the provider name bit.

Please create a new bz item for the CRL stuff. I'd be happy to look at patches / provide you with some pointers but my focus is going to be bug fixing for the short to medium term.
Comment 6 Mark Thomas 2008-05-17 12:58:16 UTC
I have committed a modified version of the provider patch to trunk and proposed it for 6.0.x
Comment 7 Mark Thomas 2008-05-20 15:54:16 UTC
The provider part of the patch has now been applied and will be included in 6.0.17 onwards.