Blame SOURCES/tomcatjss-TLSv1.1-1.2-support.patch

93a344
Index: src/org/apache/tomcat/util/net/jss/JSSSocketFactory.java
93a344
===================================================================
93a344
--- src/org/apache/tomcat/util/net/jss/JSSSocketFactory.java	(revision 278)
93a344
+++ src/org/apache/tomcat/util/net/jss/JSSSocketFactory.java	(working copy)
93a344
@@ -138,6 +138,23 @@
93a344
         cipherMap.put("TLS_ECDH_anon_WITH_AES_128_CBC_SHA",      SSLSocket.TLS_ECDH_anon_WITH_AES_128_CBC_SHA);
93a344
         cipherMap.put("TLS_ECDH_anon_WITH_AES_256_CBC_SHA",      SSLSocket.TLS_ECDH_anon_WITH_AES_256_CBC_SHA);
93a344
 
93a344
+        //TLSv1_2
93a344
+        cipherMap.put("TLS_DHE_RSA_WITH_AES_128_CBC_SHA256",     SSLSocket.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256);
93a344
+        cipherMap.put("TLS_DHE_RSA_WITH_AES_256_CBC_SHA256",     SSLSocket.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256);
93a344
+        cipherMap.put("TLS_RSA_WITH_NULL_SHA256",                SSLSocket.TLS_RSA_WITH_NULL_SHA256);
93a344
+        cipherMap.put("TLS_RSA_WITH_AES_128_CBC_SHA256",         SSLSocket.TLS_RSA_WITH_AES_128_CBC_SHA256);
93a344
+        cipherMap.put("TLS_RSA_WITH_AES_256_CBC_SHA256",         SSLSocket.TLS_RSA_WITH_AES_256_CBC_SHA256);
93a344
+        cipherMap.put("TLS_RSA_WITH_SEED_CBC_SHA",               SSLSocket.TLS_RSA_WITH_SEED_CBC_SHA);
93a344
+        cipherMap.put("TLS_RSA_WITH_AES_128_GCM_SHA256",         SSLSocket.TLS_RSA_WITH_AES_128_GCM_SHA256);
93a344
+        cipherMap.put("TLS_DHE_RSA_WITH_AES_128_GCM_SHA256",     SSLSocket.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256);
93a344
+        cipherMap.put("TLS_DHE_DSS_WITH_AES_128_GCM_SHA256",     SSLSocket.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256);
93a344
+        cipherMap.put("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", SSLSocket.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256);
93a344
+        cipherMap.put("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",   SSLSocket.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256);
93a344
+        cipherMap.put("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", SSLSocket.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256);
93a344
+        cipherMap.put("TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256",  SSLSocket.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256);
93a344
+        cipherMap.put("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",   SSLSocket.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256);
93a344
+        cipherMap.put("TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256",    SSLSocket.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256);
93a344
+
93a344
     }
93a344
 
93a344
     private static HashMap eccCipherMap = new HashMap();
93a344
@@ -197,9 +214,13 @@
93a344
         }
93a344
     }
93a344
 
93a344
-    public void setSSLCiphers(String attr) throws SocketException
93a344
+    public void setSSLCiphers(String attr) throws SocketException, IOException
93a344
     {
93a344
       String ciphers = (String)endpoint.getAttribute(attr);
93a344
+      if (ciphers == null || ciphers.equals("")) {
93a344
+          debugWrite("JSSSocketFactory setSSLCiphers: "+ attr +" not found");
93a344
+          return;
93a344
+      }
93a344
       StringTokenizer st = new StringTokenizer(ciphers, ",");
93a344
       while (st.hasMoreTokens()) {
93a344
         String cipherstr = st.nextToken();
93a344
@@ -257,7 +278,14 @@
93a344
       }
93a344
     }
93a344
 
93a344
-    public void setSSLOptions() throws SocketException
93a344
+    /*
93a344
+     * note: the SSL_OptionSet-based API for controlling the enabled
93a344
+     * protocol versions are obsolete and replaced by the
93a344
+     * setSSLVersionRange calls.  If the "range" parameters are
93a344
+     * present in the attributes then the sslOptions parameter is
93a344
+     * ignored.
93a344
+     */
93a344
+    public void setSSLOptions() throws SocketException, IOException
93a344
     {
93a344
       String options = (String)endpoint.getAttribute("sslOptions");
93a344
       StringTokenizer st = new StringTokenizer(options, ",");
93a344
@@ -308,6 +336,61 @@
93a344
         }
93a344
     }
93a344
 
93a344
+ 
93a344
+    /*
93a344
+     * setSSLVersionRangeDefault sets the range of allowed ssl versions.
93a344
+     * This replaces the obsolete SSL_Option* API
93a344
+     *
93a344
+     * @param protoVariant indicates whether this setting is for 
93a344
+       type "stream" or "datagram"
93a344
+     * @param sslVersionRange_s takes on the form of "min:max" where
93a344
+     * min/max values can be "ssl3, tls1_0, tls1_1, or tls1_2"
93a344
+     * ssl2 is not supported for tomcatjss via this interface
93a344
+     * The format is "sslVersionRange=min:max"
93a344
+     */
93a344
+    public void setSSLVersionRangeDefault(
93a344
+            org.mozilla.jss.ssl.SSLSocket.SSLProtocolVariant protoVariant,
93a344
+            String sslVersionRange_s)
93a344
+        throws SocketException, IllegalArgumentException, IOException {
93a344
+
93a344
+        // process sslVersionRange_s
93a344
+        String[] sslVersionRange = sslVersionRange_s.split(":"); 
93a344
+        if (sslVersionRange.length != 2) {
93a344
+            debugWrite("JSSSocketFactory setSSLversionRangeDefault- SSL Version Range format error: " + sslVersionRange_s +"\n");
93a344
+            throw new SocketException("tomcatjss: setSSLversionRangeDefault format error");
93a344
+        }
93a344
+        String min_s = sslVersionRange[0];
93a344
+        String max_s = sslVersionRange[1];
93a344
+        int min = getSSLVersionRangeEnum(min_s);
93a344
+        int max = getSSLVersionRangeEnum(max_s);
93a344
+        if ((min == -1) || (max== -1)) {
93a344
+            debugWrite("JSSSocketFactory setSSLversionRangeDefault- SSL Version Range format error: " + sslVersionRange_s +"\n");
93a344
+            throw new SocketException("tomcatjss: setSSLversionRangeDefault format error");
93a344
+        }
93a344
+
93a344
+        debugWrite("JSSSocketFactory setSSLversionRangeDefault- SSL Version Range set to min=" + min + " max = " + max +"\n");
93a344
+        org.mozilla.jss.ssl.SSLSocket.SSLVersionRange range =
93a344
+            new org.mozilla.jss.ssl.SSLSocket.SSLVersionRange(min, max);
93a344
+
93a344
+        SSLSocket.setSSLVersionRangeDefault(protoVariant, range);
93a344
+        debugWrite("JSSSocketFactory setSSLversionRangeDefault- variant set\n");
93a344
+    }
93a344
+
93a344
+    int getSSLVersionRangeEnum (String rangeString) {
93a344
+        if (rangeString == null)
93a344
+            return -1;
93a344
+        if (rangeString.equals("ssl3"))
93a344
+            return org.mozilla.jss.ssl.SSLSocket.SSLVersionRange.ssl3;
93a344
+        else if (rangeString.equals("tls1_0"))
93a344
+            return org.mozilla.jss.ssl.SSLSocket.SSLVersionRange.tls1_0;
93a344
+        else if (rangeString.equals("tls1_1"))
93a344
+            return org.mozilla.jss.ssl.SSLSocket.SSLVersionRange.tls1_1;
93a344
+        else if (rangeString.equals("tls1_2"))
93a344
+            return org.mozilla.jss.ssl.SSLSocket.SSLVersionRange.tls1_2;
93a344
+
93a344
+        return -1;
93a344
+    }
93a344
+
93a344
     void init() throws IOException {
93a344
         try {
93a344
             String deb = (String)endpoint.getAttribute("debug");
93a344
@@ -543,14 +626,52 @@
93a344
             }
93a344
             if (mStrictCiphers == true) {
93a344
                 // what ciphers do we have to start with? turn them all off
93a344
-                 debugWrite("SSSocketFactory init - before setSSLOptions, strictCiphers is true\n");
93a344
+                 debugWrite("SSSocketFactory init - before setSSLCiphers, strictCiphers is true\n");
93a344
                  unsetSSLCiphers();
93a344
             } else {
93a344
-                 debugWrite("SSSocketFactory init - before setSSLOptions, strictCiphers is false\n");
93a344
+                 debugWrite("SSSocketFactory init - before setSSLCiphers, strictCiphers is false\n");
93a344
             }
93a344
 
93a344
-            setSSLOptions();
93a344
-            debugWrite("SSSocketFactory init - after setSSLOptions\n");
93a344
+            String sslVersionRangeStream = (String)endpoint.getAttribute("sslVersionRangeStream");
93a344
+            if ((sslVersionRangeStream != null) && !sslVersionRangeStream.equals("")) {
93a344
+                debugWrite("SSSocketFactory init - calling setSSLVersionRangeDefault() for type STREAM\n");
93a344
+                setSSLVersionRangeDefault(org.mozilla.jss.ssl.SSLSocket.SSLProtocolVariant.STREAM, sslVersionRangeStream);
93a344
+                debugWrite("SSSocketFactory init - after setSSLVersionRangeDefault() for type STREAM\n");
93a344
+            }
93a344
+
93a344
+            String sslVersionRangeDatagram = (String)endpoint.getAttribute("sslVersionRangeDatagram");
93a344
+            if ((sslVersionRangeDatagram != null) && !sslVersionRangeDatagram.equals("")) {
93a344
+                debugWrite("SSSocketFactory init - calling setSSLVersionRangeDefault() for type DATA_GRAM\n");
93a344
+                setSSLVersionRangeDefault(org.mozilla.jss.ssl.SSLSocket.SSLProtocolVariant.DATA_GRAM, sslVersionRangeDatagram);
93a344
+                debugWrite("SSSocketFactory init - after setSSLVersionRangeDefault() for type DATA_GRAM\n");
93a344
+            }
93a344
+
93a344
+            /*
93a344
+             * According to NSS:
93a344
+             * the SSL_OptionSet-based API for controlling the enabled
93a344
+             * protocol versions are obsolete and replaced by the
93a344
+             * setSSLVersionRange calls.
93a344
+             * Therefore, if the "range" parameters are
93a344
+             * present in the attributes then the sslOptions parameter is
93a344
+             * ignored.
93a344
+             * Using the new version range API in conjunction with the older
93a344
+             * SSL_OptionSet-based API for controlling the enabled protocol
93a344
+             * versions may cause unexpected results
93a344
+             */
93a344
+            if (((sslVersionRangeStream != null)
93a344
+                    && !sslVersionRangeStream.equals(""))
93a344
+                    || ((sslVersionRangeDatagram != null)
93a344
+                    && !sslVersionRangeDatagram.equals(""))) {
93a344
+                /* deliberately lose the ssl2 here */
93a344
+                debugWrite("SSSocketFactory init - calling setSSLCiphers() honoring only sslRangeCiphers\n");
93a344
+                setSSLCiphers("sslRangeCiphers");
93a344
+                debugWrite("SSSocketFactory init - after setSSLCiphers() honoring only sslRangeCiphers\n");
93a344
+            } else {
93a344
+                debugWrite("SSSocketFactory init - calling setSSLOptions()\n");
93a344
+                setSSLOptions();
93a344
+                debugWrite("SSSocketFactory init - after setSSLOptions()\n");
93a344
+            }
93a344
+
93a344
         } catch (Exception ex) {
93a344
             debugWrite("JSSSocketFactory init - exception thrown:"+
93a344
                    ex.toString()+"\n");