Selected cipher negotiated by firefox browser/server does not match Tomcat configured cipher list

Viewed 294

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?
1 Answers

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...

Related