3

I have a custom JKS file (keystore) on my file system under /opt/myapp/keystore/myapp.jks and am deploying a myapp.war to Tomcat7 that needs to use it.

If this was an executable JAR (and not a WAR), I might do something like:

java -jar myapp.jar -Djavax.net.ssl.keyStore=/opt/myapp/keystore/myapp.jks
    -Djavax.net.ssl/keyStorePassword=mypasswd

How/where do I accomplish the same in Tomcat7?

IAmYourFaja
  • 55,468
  • 181
  • 466
  • 756
  • Could you edit your question to clarify whether (a) you want the code within your WAR file to use those settings or (b) you want the Tomcat connector to use these settings to serve HTTPS requests? These would be completely different answers. – Bruno Jun 05 '14 at 16:19

2 Answers2

3

There are multiple options.

  • If you're happy to have those settings to be globally accessible by your JVM, including all the WARs that run within your Tomcat container (but possibly excluding your server connector itself, since it can be configured separately), add those options to JAVA_OPTS in the catalina start up script (.sh or .bat depending on the platform). This is not ideal, since effectively any code running within that JVM could get access to that keystore, so you need to be sure it's acceptable.

  • If you can change the code, you could initialise separate SSLContexts for whatever is using it (you can get an SSLEngine or an SSLSocketFactory from it, with which you can build SSLSockets or initialise an HttpsUrlConnection). Something along these lines should work:

    // Load the key store: change store type if needed
    KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
    FileInputStream fis = new FileInputStream("/path/to/keystore");
    try {
        ks.load(fis, keystorePassword);
    } finally {
        if (fis != null) { fis.close(); }
    }
    
    SSLContext sslContext = SSLContext.getInstance("TLS");
    // the second "null" argument will let you use the default trust manager settings.
    sslContext.init(kmf.getKeyManagers(), null, null);
    
    SSLSocketFactory sslSocketFactory = sslContext.getSSLSocketFactory();
    

    You could load the keystore from a resource within your webapp instead of a FileInputStream, or perhaps via JNDI, depending on how you want to configure your overall setup.

Bruno
  • 119,590
  • 31
  • 270
  • 376
  • Thanks @Bruno (+1) - I appreciate this answer and I should have clarified that I would just be deploying 1 WAR to the Tomcat instance so it suffices to define Tomcat-wide (not app-specific) SSL settings. Thanks again though! – IAmYourFaja Jun 05 '14 at 16:14
  • Sure, but the settings in the other answer you've currently accepted will only affect the Tomcat connector, not the WAR application running within it. If you want the application running within your WAR to use those settings, you'll need one of the two options I've just mentioned (probably the first one if you only have one application). – Bruno Jun 05 '14 at 16:16
2

You can add an SSL connector to the conf/server.xml file as the example below:

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
               maxThreads="150" scheme="https" secure="true"
               keyAlias="your-cert-key" keystoreFile="your-keystore-path.keystore" 
               keystorePass="yourpassword"
               clientAuth="false" sslProtocol="TLS" />
lpratlong
  • 1,421
  • 9
  • 17
  • 2
    Here, the application in the WAR file is likely to use the keystore for client certificates, or at least not for configuring the server certificate. Here, what you're configuring in the server config has nothing to do with the WAR file. – Bruno Jun 05 '14 at 15:54
  • @Bruno ` to Tomcat7 that needs to use it` => So, maybe I do not understand the question, but I understand that he wants its tomcat7 using this keystore. Tell me if I am wrong. – lpratlong Jun 05 '14 at 15:59
  • I understand the question as "the webapp in that WAR file needs to use it" ("*a myapp.war to Tomcat7 that needs to use it*"), not Tomcat needs to use it... – Bruno Jun 05 '14 at 16:01
  • @Bruno Let's wait more details :). But, if I remember well, client certificates are managed trough a Truststore and not a keystore. – lpratlong Jun 05 '14 at 16:04
  • As a client, *your* client certificates are managed via your *keystore*, not truststore. See [this question](http://stackoverflow.com/a/6341566/372643). – Bruno Jun 05 '14 at 16:14