Author: kkolinko
Date: Sat May 10 13:06:46 2014
New Revision: 1593696

URL: http://svn.apache.org/r1593696
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=56027
Add more options for managing FIPS mode in the AprLifecycleListener.
The minimum required version of Tomcat Native library is now 1.1.30.

Modified:
    tomcat/tc6.0.x/trunk/   (props changed)
    tomcat/tc6.0.x/trunk/STATUS.txt
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/AprLifecycleListener.java
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/LocalStrings.properties
    tomcat/tc6.0.x/trunk/java/org/apache/tomcat/jni/SSL.java
    tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml
    tomcat/tc6.0.x/trunk/webapps/docs/config/listeners.xml

Propchange: tomcat/tc6.0.x/trunk/
------------------------------------------------------------------------------
  Merged /tomcat/trunk:r1590646
  Merged /tomcat/tc7.0.x/trunk:r1590845

Modified: tomcat/tc6.0.x/trunk/STATUS.txt
URL: 
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/STATUS.txt?rev=1593696&r1=1593695&r2=1593696&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/STATUS.txt (original)
+++ tomcat/tc6.0.x/trunk/STATUS.txt Sat May 10 13:06:46 2014
@@ -28,40 +28,6 @@ None
 PATCHES PROPOSED TO BACKPORT:
   [ New proposals should be added at the end of the list ]
 
-* Back-port patch to allow different kinds of FIPS configuration.
-  http://people.apache.org/~schultz/patches/tcnative.heartbleed.tomcat6.diff
-  http://svn.apache.org/viewvc?view=revision&revision=r1587379
-  http://svn.apache.org/viewvc?view=revision&revision=r1587723 (adapt)
-  (Note: requires tcnative 1.1.30)
-  +1: schultz, markt, remm
-  -1: kkolinko:
-       a) I cannot test (without FIPS-enabled library), but from my code review
-          the new options will not work because you are not setting
-          "fipsModeActive" field in AprLifecycleListener.
-
-          Thus AprLifecycleListener.isFIPSModeActive() will return false
-          and startup will be aborted.
-
-       b) It needs backport of r1588102 as an Exception is thrown by native 
code
-
-       c) "enterFipsMode = 1 != fipsModeState;" code and comment before it are 
wrong.
-
-          FIPS_mode() function of OpenSSL is documented to return non-zero
-          value when in FIPS mode. You cannot expect it to be '1'.
-          Reference:
-           http://wiki.openssl.org/index.php/FIPS_mode%28%29
-       Alternative patch is proposed below.
-
-* Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=56027
-  Add more options for managing FIPS mode in the AprLifecycleListener.
-  Update to version 1.1.30 of Tomcat Native library.
-  (This feature requires TCNative 1.1.30)
-  (Reimplemented, based on earlier proposal by schultz)
-  
https://people.apache.org/~kkolinko/patches/2014-04-27_tc6_56027_FIPSMode.patch
-  http://svn.apache.org/r1590845 (javadoc fixes)
-  +1: kkolinko, markt, fhanik
-  -1:
-
 * Defensive coding around some XML activities that are triggered by web
   applications and are therefore at potential risk of a memory leak.
   http://people.apache.org/~markt/patches/2014-04-25-memory-leak-tc6-v1.patch

Modified: 
tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/AprLifecycleListener.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/AprLifecycleListener.java?rev=1593696&r1=1593695&r2=1593696&view=diff
==============================================================================
--- 
tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/AprLifecycleListener.java 
(original)
+++ 
tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/AprLifecycleListener.java 
Sat May 10 13:06:46 2014
@@ -61,7 +61,7 @@ public class AprLifecycleListener
 
     protected static final int TCN_REQUIRED_MAJOR = 1;
     protected static final int TCN_REQUIRED_MINOR = 1;
-    protected static final int TCN_REQUIRED_PATCH = 17;
+    protected static final int TCN_REQUIRED_PATCH = 30;
     protected static final int TCN_RECOMMENDED_PV = 30;
 
 
@@ -75,6 +75,22 @@ public class AprLifecycleListener
     protected static boolean aprAvailable = false;
     protected static boolean fipsModeActive = false;
 
+    /**
+     * The "FIPS mode" level that we use as the argument to OpenSSL method
+     * <code>FIPS_mode_set()</code> to enable FIPS mode and that we expect as
+     * the return value of <code>FIPS_mode()</code> when FIPS mode is enabled.
+     * <p>
+     * In the future the OpenSSL library might grow support for different
+     * non-zero "FIPS" modes that specify different allowed subsets of ciphers
+     * or whatever, but nowadays only "1" is the supported value.
+     * </p>
+     * @see <a 
href="http://wiki.openssl.org/index.php/FIPS_mode_set%28%29";>OpenSSL method 
FIPS_mode_set()</a>
+     * @see <a 
href="http://wiki.openssl.org/index.php/FIPS_mode%28%29";>OpenSSL method 
FIPS_mode()</a>
+     */
+    private static final int FIPS_ON = 1;
+
+    private static final int FIPS_OFF = 0;
+
     protected static final Object lock = new Object();
 
     public static boolean isAprAvailable() {
@@ -112,7 +128,7 @@ public class AprLifecycleListener
                     }
                 }
                 // Failure to initialize FIPS mode is fatal
-                if ("on".equalsIgnoreCase(FIPSMode) && !isFIPSModeActive()) {
+                if (!(null == FIPSMode || "off".equalsIgnoreCase(FIPSMode)) && 
!isFIPSModeActive()) {
                     Error e = new Error(
                             sm.getString("aprListener.initializeFIPSFailed"));
                     // Log here, because thrown error might be not logged
@@ -170,11 +186,11 @@ public class AprLifecycleListener
 
         try {
             String methodName = "initialize";
-            Class paramTypes[] = new Class[1];
+            Class<?> paramTypes[] = new Class[1];
             paramTypes[0] = String.class;
             Object paramValues[] = new Object[1];
             paramValues[0] = null;
-            Class clazz = Class.forName("org.apache.tomcat.jni.Library");
+            Class<?> clazz = Class.forName("org.apache.tomcat.jni.Library");
             Method method = clazz.getMethod(methodName, paramTypes);
             method.invoke(null, paramValues);
             major = clazz.getField("TCN_MAJOR_VERSION").getInt(null);
@@ -234,15 +250,15 @@ public class AprLifecycleListener
                      + minor + "." + patch));
         }
         // Log APR flags
-        log.info(sm.getString("aprListener.flags", Library.APR_HAVE_IPV6, 
Library.APR_HAS_SENDFILE,
-                Library.APR_HAS_SO_ACCEPTFILTER, Library.APR_HAS_RANDOM));
+        log.info(sm.getString("aprListener.flags",
+                Boolean.valueOf(Library.APR_HAVE_IPV6),
+                Boolean.valueOf(Library.APR_HAS_SENDFILE),
+                Boolean.valueOf(Library.APR_HAS_SO_ACCEPTFILTER),
+                Boolean.valueOf(Library.APR_HAS_RANDOM)));
         aprAvailable = true;
     }
 
-    private static void initializeSSL()
-        throws ClassNotFoundException, NoSuchMethodException,
-               IllegalAccessException, InvocationTargetException
-    {
+    private static void initializeSSL() throws Exception {
 
         if ("off".equalsIgnoreCase(SSLEngine)) {
             return;
@@ -251,14 +267,15 @@ public class AprLifecycleListener
              //only once per VM
             return;
         }
+
         sslInitialized = true;
 
         String methodName = "randSet";
-        Class paramTypes[] = new Class[1];
+        Class<?> paramTypes[] = new Class[1];
         paramTypes[0] = String.class;
         Object paramValues[] = new Object[1];
         paramValues[0] = SSLRandomSeed;
-        Class clazz = Class.forName("org.apache.tomcat.jni.SSL");
+        Class<?> clazz = Class.forName("org.apache.tomcat.jni.SSL");
         Method method = clazz.getMethod(methodName, paramTypes);
         method.invoke(null, paramValues);
 
@@ -268,22 +285,61 @@ public class AprLifecycleListener
         method = clazz.getMethod(methodName, paramTypes);
         method.invoke(null, paramValues);
 
-        if("on".equalsIgnoreCase(FIPSMode)) {
-            log.info(sm.getString("aprListener.initializingFIPS"));
+        if (!(null == FIPSMode || "off".equalsIgnoreCase(FIPSMode))) {
 
-            int result = SSL.fipsModeSet(1);
+            fipsModeActive = false;
 
-            // success is defined as return value = 1
-            if(1 == result) {
-                fipsModeActive = true;
+            final boolean enterFipsMode;
+            int fipsModeState = SSL.fipsModeGet();
 
-                log.info(sm.getString("aprListener.initializeFIPSSuccess"));
+            if(log.isDebugEnabled()) {
+                log.debug(sm.getString("aprListener.currentFIPSMode",
+                                       Integer.valueOf(fipsModeState)));
+            }
+
+            if ("on".equalsIgnoreCase(FIPSMode)) {
+                if (fipsModeState == FIPS_ON) {
+                    
log.info(sm.getString("aprListener.skipFIPSInitialization"));
+                    fipsModeActive = true;
+                    enterFipsMode = false;
+                } else {
+                    enterFipsMode = true;
+                }
+            } else if ("require".equalsIgnoreCase(FIPSMode)) {
+                if (fipsModeState == FIPS_ON) {
+                    fipsModeActive = true;
+                    enterFipsMode = false;
+                } else {
+                    throw new IllegalStateException(
+                            sm.getString("aprListener.requireNotInFIPSMode"));
+                }
+            } else if ("enter".equalsIgnoreCase(FIPSMode)) {
+                if (fipsModeState == FIPS_OFF) {
+                    enterFipsMode = true;
+                } else {
+                    throw new IllegalStateException(sm.getString(
+                            "aprListener.enterAlreadyInFIPSMode",
+                            Integer.valueOf(fipsModeState)));
+                }
             } else {
-                // This case should be handled by the native method,
-                // but we'll make absolutely sure, here.
-                String message = 
sm.getString("aprListener.initializeFIPSFailed");
-                log.error(message);
-                throw new IllegalStateException(message);
+                throw new IllegalArgumentException(sm.getString(
+                        "aprListener.wrongFIPSMode", FIPSMode));
+            }
+
+            if (enterFipsMode) {
+                log.info(sm.getString("aprListener.initializingFIPS"));
+
+                fipsModeState = SSL.fipsModeSet(FIPS_ON);
+                if (fipsModeState != FIPS_ON) {
+                    // This case should be handled by the native method,
+                    // but we'll make absolutely sure, here.
+                    String message = 
sm.getString("aprListener.initializeFIPSFailed");
+                    log.error(message);
+                    throw new IllegalStateException(message);
+                }
+
+                fipsModeActive = true;
+                log.info(sm.getString("aprListener.initializeFIPSSuccess"));
             }
         }
 

Modified: 
tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/LocalStrings.properties
URL: 
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/LocalStrings.properties?rev=1593696&r1=1593695&r2=1593696&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/LocalStrings.properties 
(original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/LocalStrings.properties 
Sat May 10 13:06:46 2014
@@ -43,6 +43,11 @@ aprListener.aprDestroy=Failed shutdown o
 aprListener.sslInit=Failed to initialize the SSLEngine.
 aprListener.tcnValid=Loaded APR based Apache Tomcat Native library {0} using 
APR version {1}.
 aprListener.flags=APR capabilities: IPv6 [{0}], sendfile [{1}], accept filters 
[{2}], random [{3}].
+aprListener.currentFIPSMode=Current FIPS mode: {0}
+aprListener.skipFIPSInitialization=Already in FIPS mode; skipping FIPS 
initialization.
+aprListener.enterAlreadyInFIPSMode=AprLifecycleListener is configured to force 
entering FIPS mode, but library is already in FIPS mode ({0})
+aprListener.requireNotInFIPSMode=AprLifecycleListener is configured to require 
the library to already be in FIPS mode, but it was not in FIPS mode
+aprListener.wrongFIPSMode=Unexpected value of FIPSMode option of 
AprLifecycleListener: "{0}"
 aprListener.initializingFIPS=Initializing FIPS mode...
 aprListener.initializeFIPSSuccess=Successfully entered FIPS mode
 aprListener.initializeFIPSFailed=Failed to enter FIPS mode

Modified: tomcat/tc6.0.x/trunk/java/org/apache/tomcat/jni/SSL.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/tomcat/jni/SSL.java?rev=1593696&r1=1593695&r2=1593696&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/tomcat/jni/SSL.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/tomcat/jni/SSL.java Sat May 10 
13:06:46 2014
@@ -229,13 +229,26 @@ public final class SSL {
     public static native int initialize(String engine);
 
     /**
+     * Get the status of FIPS Mode.
+     *
+     * @return FIPS_mode return code. It is <code>0</code> if OpenSSL is not
+     *  in FIPS mode, <code>1</code> if OpenSSL is in FIPS Mode.
+     * @throws Exception If tcnative was not compiled with FIPS Mode available.
+     * @see <a 
href="http://wiki.openssl.org/index.php/FIPS_mode%28%29";>OpenSSL method 
FIPS_mode()</a>
+     */
+    public static native int fipsModeGet() throws Exception;
+
+    /**
      * Enable/Disable FIPS Mode.
      *
      * @param mode 1 - enable, 0 - disable
      *
      * @return FIPS_mode_set return code
+     * @throws Exception If tcnative was not compiled with FIPS Mode available,
+     *  or if <code>FIPS_mode_set()</code> call returned an error value.
+     * @see <a 
href="http://wiki.openssl.org/index.php/FIPS_mode_set%28%29";>OpenSSL method 
FIPS_mode_set()</a>
      */
-    public static native int fipsModeSet(int mode);
+    public static native int fipsModeSet(int mode) throws Exception;
 
     /**
       * Set source of entropy to use in SSL

Modified: tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml?rev=1593696&r1=1593695&r2=1593696&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml Sat May 10 13:06:46 2014
@@ -47,6 +47,10 @@
   <subsection name="Catalina">
     <changelog>
       <fix>
+        <bug>56027</bug>: Add more options for managing FIPS mode in the
+        AprLifecycleListener. (schultz/kkolinko)
+      </fix>
+      <fix>
         <bug>56082</bug>: Fix a concurrency bug in JULI&apos;s LogManager
         implementation. (markt)
       </fix>

Modified: tomcat/tc6.0.x/trunk/webapps/docs/config/listeners.xml
URL: 
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/webapps/docs/config/listeners.xml?rev=1593696&r1=1593695&r2=1593696&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/webapps/docs/config/listeners.xml (original)
+++ tomcat/tc6.0.x/trunk/webapps/docs/config/listeners.xml Sat May 10 13:06:46 
2014
@@ -113,13 +113,18 @@
       </attribute>
 
       <attribute name="FIPSMode" required="false">
-        <p>Set to <code>on</code> to instruct OpenSSL to go into FIPS mode.
-        FIPS mode <em>requires you to have a FIPS-capable OpenSSL library which
+        <p>Set to <code>on</code> to request that OpenSSL be in FIPS mode
+        (if OpenSSL is already in FIPS mode, it will remain in FIPS mode).
+        Set to <code>enter</code> to force OpenSSL to enter FIPS mode (an error
+        will occur if OpenSSL is already in FIPS mode).
+        Set to <code>require</code> to require that OpenSSL <i>already</i> be
+        in FIPS mode (an error will occur if OpenSSL is not already in FIPS
+        mode).</p>
+        <p>FIPS mode <em>requires you to have a FIPS-capable OpenSSL library 
which
         you must build yourself</em>.
-        FIPS mode also requires Tomcat native library version 1.1.23 or later,
-        which <em>must be built against the FIPS-compatible OpenSSL</em> 
library.
-        If this attribute is "on", <b>SSLEngine</b> must be enabled as well.
-        The default value is <code>off</code>.</p>
+        If this attribute is set to any of the above values, the 
<b>SSLEngine</b>
+        must be enabled as well.</p>
+        <p>The default value is <code>off</code>.</p>
       </attribute>
 
     </attributes>



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to