[Pki-devel] [PATCH] Bug 871171 - Provide Tomcat support for TLS v1.1 and TLS v1.2 (Tomcatjss)

Christina Fu cfu at redhat.com
Mon Sep 29 22:25:45 UTC 2014


updated with jmagne's comments mainly on adding some error checking.

Also, rrelyea added the following NSS information regarding the now 
obsolete old (obsolete) ssl version enable functions so we know what to 
expect (I will add that to the bug):
"
At the NSS level:

There is only range now. We added range before we added TLS 1.1. So the 
old code was SSL2 on/off SSL3 on/off, and TLS 1.0 on/off. Now we have 
TLS_range 0 = ssl3, 1=tls 1.0, 2=tls 1.1, 3=tls 1.2 (SSL2 is still 
on/off). The old functions that turned on ciphers still operate, but 
they work by extending the range. If TLS 1.1, and tls 1.2 are turned 
off, then it all works the same way it did before (the range is 
ssl3-tls.10). If tls 1.1 is on, though, now turning on ssl3 will also 
turn on tls 1.0 as a side effect. You can't turn on just ssl 3.0 and TLS 
1.2, for example. If your old sslOptions have tls 1.1 or tls 1.2 as 
options, you wont' be able to turn them on in NSS without invoking a range.
"

thanks,
Christina

On 09/29/2014 11:32 AM, Christina Fu wrote:
> This tomcatjss patch is for the following bug:
> *Bug 871171* <https://bugzilla.redhat.com/show_bug.cgi?id=871171> 
> -Provide Tomcat support for TLS v1.1 and TLS v1.2 (Tomcatjss)
>
> It provides the minimum code to support setting the ssl version range 
> from tomcatjss server.
> The tlsv1.1 and 1.2 ciphers are made available as well.
>
> This patch works in conjunction with the JSS patch that was sent out 
> for review.
>
> Three are three new variables introduced in the server.xml :
> sslVersionRangeStream - for stream protocol type.  it takes a format 
> of "min:max" where min/max values can be "ssl3, tls1_0, tls1_1, or tls1_2"
> sslVersionRangeDatagram - for datagram protocol type. it takes a 
> format of "min:max" where min/max values can be "tls1_1, or tls1_2"
> sslRangeCiphers - a complete list of ciphers you wish to support 
> (provided supported by NSS) in such ssl version range.
>
> When the new *range* parameters are set, the old sslOptions parameter 
> is ignored, as it is obsolete.  However, if the *range* parameters are 
> not specified, the sslOptions will be supported as before.
>
> thanks,
> Christina
>
>
>
>
> _______________________________________________
> Pki-devel mailing list
> Pki-devel at redhat.com
> https://www.redhat.com/mailman/listinfo/pki-devel

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listman.redhat.com/archives/pki-devel/attachments/20140929/03f8a638/attachment.htm>
-------------- next part --------------
Index: src/org/apache/tomcat/util/net/jss/JSSSocketFactory.java
===================================================================
--- src/org/apache/tomcat/util/net/jss/JSSSocketFactory.java	(revision 278)
+++ src/org/apache/tomcat/util/net/jss/JSSSocketFactory.java	(working copy)
@@ -138,6 +138,23 @@
         cipherMap.put("TLS_ECDH_anon_WITH_AES_128_CBC_SHA",      SSLSocket.TLS_ECDH_anon_WITH_AES_128_CBC_SHA);
         cipherMap.put("TLS_ECDH_anon_WITH_AES_256_CBC_SHA",      SSLSocket.TLS_ECDH_anon_WITH_AES_256_CBC_SHA);
 
+        //TLSv1_2
+        cipherMap.put("TLS_DHE_RSA_WITH_AES_128_CBC_SHA256",     SSLSocket.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256);
+        cipherMap.put("TLS_DHE_RSA_WITH_AES_256_CBC_SHA256",     SSLSocket.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256);
+        cipherMap.put("TLS_RSA_WITH_NULL_SHA256",                SSLSocket.TLS_RSA_WITH_NULL_SHA256);
+        cipherMap.put("TLS_RSA_WITH_AES_128_CBC_SHA256",         SSLSocket.TLS_RSA_WITH_AES_128_CBC_SHA256);
+        cipherMap.put("TLS_RSA_WITH_AES_256_CBC_SHA256",         SSLSocket.TLS_RSA_WITH_AES_256_CBC_SHA256);
+        cipherMap.put("TLS_RSA_WITH_SEED_CBC_SHA",               SSLSocket.TLS_RSA_WITH_SEED_CBC_SHA);
+        cipherMap.put("TLS_RSA_WITH_AES_128_GCM_SHA256",         SSLSocket.TLS_RSA_WITH_AES_128_GCM_SHA256);
+        cipherMap.put("TLS_DHE_RSA_WITH_AES_128_GCM_SHA256",     SSLSocket.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256);
+        cipherMap.put("TLS_DHE_DSS_WITH_AES_128_GCM_SHA256",     SSLSocket.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256);
+        cipherMap.put("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", SSLSocket.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256);
+        cipherMap.put("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",   SSLSocket.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256);
+        cipherMap.put("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", SSLSocket.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256);
+        cipherMap.put("TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256",  SSLSocket.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256);
+        cipherMap.put("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",   SSLSocket.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256);
+        cipherMap.put("TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256",    SSLSocket.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256);
+
     }
 
     private static HashMap eccCipherMap = new HashMap();
@@ -197,9 +214,13 @@
         }
     }
 
-    public void setSSLCiphers(String attr) throws SocketException
+    public void setSSLCiphers(String attr) throws SocketException, IOException
     {
       String ciphers = (String)endpoint.getAttribute(attr);
+      if (ciphers == null || ciphers.equals("")) {
+          debugWrite("JSSSocketFactory setSSLCiphers: "+ attr +" not found");
+          return;
+      }
       StringTokenizer st = new StringTokenizer(ciphers, ",");
       while (st.hasMoreTokens()) {
         String cipherstr = st.nextToken();
@@ -257,7 +278,14 @@
       }
     }
 
-    public void setSSLOptions() throws SocketException
+    /*
+     * note: the SSL_OptionSet-based API for controlling the enabled
+     * protocol versions are obsolete and replaced by the
+     * setSSLVersionRange calls.  If the "range" parameters are
+     * present in the attributes then the sslOptions parameter is
+     * ignored.
+     */
+    public void setSSLOptions() throws SocketException, IOException
     {
       String options = (String)endpoint.getAttribute("sslOptions");
       StringTokenizer st = new StringTokenizer(options, ",");
@@ -308,6 +336,61 @@
         }
     }
 
+ 
+    /*
+     * setSSLVersionRangeDefault sets the range of allowed ssl versions.
+     * This replaces the obsolete SSL_Option* API
+     *
+     * @param protoVariant indicates whether this setting is for 
+       type "stream" or "datagram"
+     * @param sslVersionRange_s takes on the form of "min:max" where
+     * min/max values can be "ssl3, tls1_0, tls1_1, or tls1_2"
+     * ssl2 is not supported for tomcatjss via this interface
+     * The format is "sslVersionRange=min:max"
+     */
+    public void setSSLVersionRangeDefault(
+            org.mozilla.jss.ssl.SSLSocket.SSLProtocolVariant protoVariant,
+            String sslVersionRange_s)
+        throws SocketException, IllegalArgumentException, IOException {
+
+        // process sslVersionRange_s
+        String[] sslVersionRange = sslVersionRange_s.split(":"); 
+        if (sslVersionRange.length != 2) {
+            debugWrite("JSSSocketFactory setSSLversionRangeDefault- SSL Version Range format error: " + sslVersionRange_s +"\n");
+            throw new SocketException("tomcatjss: setSSLversionRangeDefault format error");
+        }
+        String min_s = sslVersionRange[0];
+        String max_s = sslVersionRange[1];
+        int min = getSSLVersionRangeEnum(min_s);
+        int max = getSSLVersionRangeEnum(max_s);
+        if ((min == -1) || (max== -1)) {
+            debugWrite("JSSSocketFactory setSSLversionRangeDefault- SSL Version Range format error: " + sslVersionRange_s +"\n");
+            throw new SocketException("tomcatjss: setSSLversionRangeDefault format error");
+        }
+
+        debugWrite("JSSSocketFactory setSSLversionRangeDefault- SSL Version Range set to min=" + min + " max = " + max +"\n");
+        org.mozilla.jss.ssl.SSLSocket.SSLVersionRange range =
+            new org.mozilla.jss.ssl.SSLSocket.SSLVersionRange(min, max);
+
+        SSLSocket.setSSLVersionRangeDefault(protoVariant, range);
+        debugWrite("JSSSocketFactory setSSLversionRangeDefault- variant set\n");
+    }
+
+    int getSSLVersionRangeEnum (String rangeString) {
+        if (rangeString == null)
+            return -1;
+        if (rangeString.equals("ssl3"))
+            return org.mozilla.jss.ssl.SSLSocket.SSLVersionRange.ssl3;
+        else if (rangeString.equals("tls1_0"))
+            return org.mozilla.jss.ssl.SSLSocket.SSLVersionRange.tls1_0;
+        else if (rangeString.equals("tls1_1"))
+            return org.mozilla.jss.ssl.SSLSocket.SSLVersionRange.tls1_1;
+        else if (rangeString.equals("tls1_2"))
+            return org.mozilla.jss.ssl.SSLSocket.SSLVersionRange.tls1_2;
+
+        return -1;
+    }
+
     void init() throws IOException {
         try {
             String deb = (String)endpoint.getAttribute("debug");
@@ -543,14 +626,52 @@
             }
             if (mStrictCiphers == true) {
                 // what ciphers do we have to start with? turn them all off
-                 debugWrite("SSSocketFactory init - before setSSLOptions, strictCiphers is true\n");
+                 debugWrite("SSSocketFactory init - before setSSLCiphers, strictCiphers is true\n");
                  unsetSSLCiphers();
             } else {
-                 debugWrite("SSSocketFactory init - before setSSLOptions, strictCiphers is false\n");
+                 debugWrite("SSSocketFactory init - before setSSLCiphers, strictCiphers is false\n");
             }
 
-            setSSLOptions();
-            debugWrite("SSSocketFactory init - after setSSLOptions\n");
+            String sslVersionRangeStream = (String)endpoint.getAttribute("sslVersionRangeStream");
+            if ((sslVersionRangeStream != null) && !sslVersionRangeStream.equals("")) {
+                debugWrite("SSSocketFactory init - calling setSSLVersionRangeDefault() for type STREAM\n");
+                setSSLVersionRangeDefault(org.mozilla.jss.ssl.SSLSocket.SSLProtocolVariant.STREAM, sslVersionRangeStream);
+                debugWrite("SSSocketFactory init - after setSSLVersionRangeDefault() for type STREAM\n");
+            }
+
+            String sslVersionRangeDatagram = (String)endpoint.getAttribute("sslVersionRangeDatagram");
+            if ((sslVersionRangeDatagram != null) && !sslVersionRangeDatagram.equals("")) {
+                debugWrite("SSSocketFactory init - calling setSSLVersionRangeDefault() for type DATA_GRAM\n");
+                setSSLVersionRangeDefault(org.mozilla.jss.ssl.SSLSocket.SSLProtocolVariant.DATA_GRAM, sslVersionRangeDatagram);
+                debugWrite("SSSocketFactory init - after setSSLVersionRangeDefault() for type DATA_GRAM\n");
+            }
+
+            /*
+             * According to NSS:
+             * the SSL_OptionSet-based API for controlling the enabled
+             * protocol versions are obsolete and replaced by the
+             * setSSLVersionRange calls.
+             * Therefore, if the "range" parameters are
+             * present in the attributes then the sslOptions parameter is
+             * ignored.
+             * Using the new version range API in conjunction with the older
+             * SSL_OptionSet-based API for controlling the enabled protocol
+             * versions may cause unexpected results
+             */
+            if (((sslVersionRangeStream != null)
+                    && !sslVersionRangeStream.equals(""))
+                    || ((sslVersionRangeDatagram != null)
+                    && !sslVersionRangeDatagram.equals(""))) {
+                /* deliberately lose the ssl2 here */
+                debugWrite("SSSocketFactory init - calling setSSLCiphers() honoring only sslRangeCiphers\n");
+                setSSLCiphers("sslRangeCiphers");
+                debugWrite("SSSocketFactory init - after setSSLCiphers() honoring only sslRangeCiphers\n");
+            } else {
+                debugWrite("SSSocketFactory init - calling setSSLOptions()\n");
+                setSSLOptions();
+                debugWrite("SSSocketFactory init - after setSSLOptions()\n");
+            }
+
         } catch (Exception ex) {
             debugWrite("JSSSocketFactory init - exception thrown:"+
                    ex.toString()+"\n");
Index: tomcatjss.spec
===================================================================
--- tomcatjss.spec	(revision 278)
+++ tomcatjss.spec	(working copy)
@@ -1,6 +1,6 @@
 Name:     tomcatjss
 Version:  7.1.0
-Release:  4%{?dist}
+Release:  5%{?dist}
 Summary:  JSSE implementation using JSS for Tomcat
 URL:      http://pki.fedoraproject.org/
 License:  LGPLv2+
@@ -17,12 +17,12 @@
 BuildRequires:    ant
 BuildRequires:    java-devel
 BuildRequires:    jpackage-utils >= 0:1.7.5-15
-BuildRequires:    jss >= 4.2.6-24
+BuildRequires:    jss >= 4.2.6-34
 BuildRequires:    tomcat >= 7.0.40
 
 Requires:         java
 Requires:         jpackage-utils >= 0:1.7.5-15
-Requires:         jss >= 4.2.6-24
+Requires:         jss >= 4.2.6-34
 Requires:         tomcat >= 7.0.40
 
 # The 'tomcatjss' package conflicts with the 'tomcat-native' package
@@ -75,6 +75,9 @@
 %{_javadir}/*
 
 %changelog
+* Wed Sep 10 2014 Christina Fu <cfu at redhat.com> - 7.1.0-5
+- added support for TLS v1.1 and v1.2
+
 * Fri Aug  2 2013 Ville Skyttä <ville.skytta at iki.fi> - 7.1.0-4
 - Simplify installation of docs.
 


More information about the Pki-devel mailing list