5

I am a bit confused. We have configured our v7 Tomcat server to communicate with connecting browsers using only TSLv1.2 and we have specified a restricted set of ciphers. Using a firefox browser (v60.3.0esr 64 bit). We are able to establish a connection but what is odd is after I have connected to the site I noticed that the agreed upon cipher is one that is not in the list of configured tomcat ciphers.

I was under the impression that when configuring the http connection object that the server as part of the hello connection negations would limit the connection to the list of available ciphers? What am I missing? If the ciphers parameter is missing then the list of available cipher will be limited to the cipher configured on the JVM (this is my understanding). As such, do I need to also limit the ciphers in the JVM to the same set that I am specifying in the http connector element?

DETAILS: Tomcat (v 7.0.77 java 1.8.0_151)

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true" allowTrace="false"
clientAuth="false" sslProtocols="TLS" sslEnabledProtocols="TLSv1.2"
keystoreFile="/etc/tomcat/tomcat.keystore" keystorePass="XXXX"
ciphers="TLS_RSA_WITH_AES_256_CBC_SHA256,
         TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
         TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
         TLS_RSA_WITH_AES_128_CBC_SHA256, 
         TLS_RSA_WITH_AES_128_CBC_SHA,
         TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
         TLS_RSA_WITH_AES_256_GCM_SHA384,
         TLS_RSA_WITH_AES_128_GCM_SHA256,
         TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
         TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
         TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,
         TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384" />

I don't have anything specific defined in my tomcat.config

    JAVA_HOME="/usr/lib/jvm/jre"
    CATALINA_BASE="/usr/share/tomcat"
    CATALINE_HOME="/usr/share/tomcat"
    JASPER_HOME="/usr/share/tomcat"
    CATALINE_TMPDIR="/var/cache/tomcat/temp"
    TOMCAT_USER="tomcat"
    SECURITY_MANAGER="false"
    SHUTDOWN_WAIT="30"
    SHUTDOWN_VERBOSE="false"
    CATALINA_PID="/var/run/tomcat.pid

After I made the connection I right clicked in the browser window, selected Inspect Element and selected the Network tag and clicked on the client request. I then selected the security tab (for the request) and it displayed:

     Protocol verson: TLSv1.2
     Cipher suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
     Key Exchange group: None
     ...

I did notice that our certificate had expired ( I received a security exception when I initially made the connection).

Can someone please explain why the negotiated cipher is not one of the ciphers in the tomcat cipher list? What does one need to do to limit the set of available ciphers supported by the server? Thanks in advance.

FINDINGS: So with logging enable, it appears that the server did select a cipher on our connection cipher list. However, when I examine fire-fox browse security settings, the browser indicates that it's agreed upon cipher is TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256. Questions:

  1. Regarding initialization of the protocol handler, why am I getting so many protocols unavailable? Is this Tomcat looking into the JVM and for some reason, the JVM doesn't have these protocol set. Are we not including a required library?
  2. I can see in the log the client/server hello message exchange and the agreed upon cipher. Yet the browser indicate a different cipher, how is that changing? Is something intercepting this exchange? Confused to say the least. Any idea?
user207421
  • 305,947
  • 44
  • 307
  • 483
Peter Hiross
  • 121
  • 1
  • 8
  • Your understanding is good and your configuration seems ignored. Add `-Djavax.net.debug=ssl` system property and restart Tomcat. It will logs many things and it can be interesting to see what the browser sends, and what Tomcat really chooses among. – Eugène Adell Dec 18 '18 at 07:37
  • able to turn on debug (debug=ssl:handshake). I can see the ClientHello, followed by the ServerHello. Unfortunately I cannot post the log here but it looks like the various sections of the handshake are denoted by *** i.e., *** ClientHello, TLSv1.2 *** *** ServerHello ****. Am I reading that correctly? We also have some state information in between the client and server hello messages (i.e., %% Initializing....%% Negotiating .... – Peter Hiross Dec 18 '18 at 23:27
  • in this log, it can be interesting to check what cipher suite is chosen by the server – Eugène Adell Dec 19 '18 at 01:14
  • Had some time to review the log. There are a couple of things that I found interesting. First, when tomcat server was rebooted, the log revealed that the protocol handler ("http-bio-8443") was initializing and ~60 message like the following were logged: Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_GCM_SHA384 All but 4 of our selected cipher were on that list. The four 'available' ciphers: TLS_RSA_WITH_AES_128_CBC_SHA256 TLS_RSA_WITH_AES_128_CBC_SHA TLS_DHZ_RSA_WITH_AES_128_CBC_SHA (server selected this cipher) TLS_RSA_WITH_AES_128_GCM_SHA256 – Peter Hiross Dec 19 '18 at 15:09
  • you can edit your question with the whole handshake trace, with a request/response. It's not possible that your browser uses one cipher, and the server another one. – Eugène Adell Dec 19 '18 at 15:18
  • I cannot post handshake as log file is on a separate network and no way to export to a public network, but it clearly shows the server selecting a protocol and the browser reporting a different protocol? – Peter Hiross Dec 19 '18 at 16:19
  • What was this necroed? If still relevant: does your browser use a proxy for https either explicitly or transparently? This is fairly likely if you are working/connected in a business or government or educational/school environment, and possible in some others. – dave_thompson_085 Apr 12 '19 at 04:19

1 Answers1

0

Regarding the protocols unavailable, have you confirmed the ciphers are available in the Java? Confirm your Tomcat is using the Java you expect, as defined by your Tomcat's JAVA_HOME variable. You can get a listing of the available cipher suites in the Java by compiling a simple Java program. (AGAIN, Make sure it's compiled with the right Java that matches Tomcat.) The Java code file and instructions are available here, but I'll include it below for completeness.

import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
import javax.net.ssl.SSLServerSocketFactory;

public class Ciphers
{
    public static void main(String[] args)
        throws Exception
    {
        SSLServerSocketFactory ssf = (SSLServerSocketFactory)SSLServerSocketFactory.getDefault();

        String[] defaultCiphers = ssf.getDefaultCipherSuites();
        String[] availableCiphers = ssf.getSupportedCipherSuites();

        TreeMap ciphers = new TreeMap();

        for(int i=0; i<availableCiphers.length; ++i )
            ciphers.put(availableCiphers[i], Boolean.FALSE);

        for(int i=0; i<defaultCiphers.length; ++i )
            ciphers.put(defaultCiphers[i], Boolean.TRUE);

        System.out.println("Default\tCipher");
        for(Iterator i = ciphers.entrySet().iterator(); i.hasNext(); ) 
        {
            Map.Entry cipher=(Map.Entry)i.next();

            if(Boolean.TRUE.equals(cipher.getValue()))
                System.out.print('*');
            else
                System.out.print(' ');

            System.out.print('\t');
            System.out.println(cipher.getKey());
        }
    }
}

In some temporary folder, save this file as Ciphers.java, and compile it with:

javac Ciphers.java

Then run it with:

java Ciphers

It should output a list of ciphers available. Note that the first line of Default Cipher is not a statement, but column headings for the text table (as you can read in the code).

One possibility is that the ciphers you're trying to use aren't in the Java implementation, and therefore aren't available to Tomcat.

A second possibility is that some of the ciphers aren't available to you because of the certificate you're using. Encryption is not my forte, but I believe you need an RSA certificate for RSA ciphers. Similarly TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 needs an ECDSA certificate. See this security.stackexchange question and answer. So half of those ciphers probably aren't going to work for you.

You can also use OpenSSL's sslscan command to test which cipher suites are available. (If you don't specify a port, it will assume 443.)

sslscan localhost:8443

It will help identify if you have set up your Tomcat Connector correctly. However, I suspect it will match your setup, and not address your client connection cipher suite issues. (Don't forget to restart the Tomcat service if you make any changes. I've also found there's a bit of a delay after restarting the service before sslscan will report the complete results. Either wait or execute it multiple times to be sure. I think it times out while Tomcat preps the web apps.)

Unfortunately this answer only address a sub-question of the OP. I'd like to see an answer to the main question - I don't have one. Hopefully someone else does...

FreeText
  • 339
  • 3
  • 7