Tim, On 4/14/14, 10:45 PM, Tim Whittington wrote: > > On 15/04/2014, at 1:14 pm, [email protected] wrote: > >> Author: schultz >> Date: Tue Apr 15 01:14:40 2014 >> New Revision: 1587379 >> >> URL: http://svn.apache.org/r1587379 >> Log: >> Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=56027 >> Add more nuanced support for entering/requiring FIPS mode when using APR >> connector. >> >> Modified: >> tomcat/trunk/java/org/apache/catalina/core/AprLifecycleListener.java >> tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties >> tomcat/trunk/java/org/apache/tomcat/jni/SSL.java >> tomcat/trunk/webapps/docs/config/listeners.xml >> >> Modified: >> tomcat/trunk/java/org/apache/catalina/core/AprLifecycleListener.java >> URL: >> http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/AprLifecycleListener.java?rev=1587379&r1=1587378&r2=1587379&view=diff >> ============================================================================== >> --- tomcat/trunk/java/org/apache/catalina/core/AprLifecycleListener.java >> (original) >> +++ tomcat/trunk/java/org/apache/catalina/core/AprLifecycleListener.java Tue >> Apr 15 01:14:40 2014 >> @@ -70,6 +70,18 @@ public class AprLifecycleListener >> protected static boolean aprInitialized = false; >> protected static boolean aprAvailable = false; >> protected static boolean fipsModeActive = false; >> + /** >> + * FIPS_mode documentation states that the return value will be >> + * whatever value was originally passed-in to FIPS_mode_set(). >> + * FIPS_mode_set docs say the argument should be non-zero to enter >> + * FIPS mode, and that upon success, the return value will be the >> + * same as the argument passed-in. Docs also highly recommend >> + * that the value "1" be used "to avoid compatibility issues". >> + * In order to avoid the argument and check-value from getting out >> + * of sync for some reason, we are using the class constant >> + * FIPS_ON here. >> + */ >> + private static final int FIPS_ON = 1; > > > This looks like it belongs in SSL (as one of the valid return values of > SSL.fipsModeGet).
Fair enough.
> Also, does FIPS_mode() always return 1 if FIPS mode is enabled at boot (I see
> there’s no adaptation of the return code in the TCN imll).
FIPS_mode() is documented to return whatever was passed to it before.
There is no other information that I could find available. I'm willing
to bet that everyone always uses "1" since the API basically says "use 1".
>> protected static final Object lock = new Object();
>>
>> @@ -110,7 +122,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
>> @@ -252,13 +264,59 @@ public class AprLifecycleListener
>> method = clazz.getMethod(methodName, paramTypes);
>> method.invoke(null, paramValues);
>>
>> - if("on".equalsIgnoreCase(FIPSMode)) {
>> + final boolean enterFipsMode;
>> +
>> + if("on".equalsIgnoreCase(FIPSMode)
>> + || "require".equalsIgnoreCase(FIPSMode)) {
>> + // FIPS_mode documentation states that the return value will be
>> + // whatever value was originally passed-in to FIPS_mode_set().
>> + // FIPS_mode_set docs say the argument should be non-zero to
>> enter
>> + // FIPS mode, and that upon success, the return value will be
>> the
>> + // same as the argument passed-in. Docs also highly recommend
>> + // that the value "1" be used "to avoid compatibility issues".
>> + // In order to avoid the argument and check-value from getting
>> out
>> + // of sync for some reason, we are using the class constant
>> + // FIPS_ON here.
>> + final int fipsModeState = SSL.fipsModeGet();
>
>
> I don’t think this needs to be documented twice, and maybe not at all?
> Aren’t we already handling the FIPS_* ‘peculiarities' in TCN so that
> SSL.fipsModeGet() has a sane 0/1 return code?
No. Other code could call FIPS_mode_set() and thus the return value
might be different. Yes, this is documented identically in multiple
places. I didn't want anyone to say "oh, having a constant for (int)1 is
stupid: let's just use 1 and be done with it" without actually reading
why there is a constant being used there.
>> +
>> + if(log.isDebugEnabled())
>> + log.debug(sm.getString("aprListener.currentFIPSMode",
>> + Integer.valueOf(fipsModeState)));
>> +
>> + // Return values: 0=Not in FIPS mode, 1=In FIPS mode,
>> + // exception if FIPS totally unavailable
>> + enterFipsMode = 1 != fipsModeState;
>> +
>> + if("on".equalsIgnoreCase(FIPSMode)) {
>> + if(!enterFipsMode)
>> +
>> log.info(sm.getString("aprListener.skipFIPSInitialization"));
>> + } else if("require".equalsIgnoreCase(FIPSMode)) {
>> + if(enterFipsMode) {
>> + String message =
>> sm.getString("aprListener.alreadyInFIPSMode");
>> + log.error(message);
>> + throw new IllegalStateException(message);
>> + }
>> + }
>> + }
>> + else if("enter".equalsIgnoreCase(FIPSMode)) {
>> + enterFipsMode = true;
>> + } else
>> + enterFipsMode = false;
>> +
>> + if(enterFipsMode) {
>> log.info(sm.getString("aprListener.initializingFIPS"));
>>
>> - int result = SSL.fipsModeSet(1);
>> + // FIPS_mode_set docs say the argument should be non-zero to
>> enter
>> + // FIPS mode, and that upon success, the return value will be
>> the
>> + // same as the argument passed-in. Docs also highly recommend
>> + // that the value "1" be used "to avoid compatibility issues".
>> + // In order to avoid the argument and check-value from getting
>> out
>> + // of sync for some reason, we are using the class constant
>> + // FIPS_ON here.
>
>
> Again, these docs look like they belong on SSL.fipsModeSet or in the TCN
> implementation of that.
This can't be in TCN because the Java code needs the constant value. I
suppose I could call a function in tcnative to get the value of "1" but
that seems a bit of overkill and I'd have to wait for yet another
tcnative release to get this out there.
>> + final int result = SSL.fipsModeSet(FIPS_ON);
>>
>> - // success is defined as return value = 1
>> - if(1 == result) {
>> + // success is defined as return value = last argument to
>> FIPS_mode_set()
>> + if(FIPS_ON == result) {
>> fipsModeActive = true;
>>
>> log.info(sm.getString("aprListener.initializeFIPSSuccess"));
>>
>> Modified: tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties
>> URL:
>> http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties?rev=1587379&r1=1587378&r2=1587379&view=diff
>> ==============================================================================
>> --- tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties
>> (original)
>> +++ tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties Tue
>> Apr 15 01:14:40 2014
>> @@ -57,6 +57,9 @@ 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.alreadyInFIPSMode=AprLifecycleListener requested to force
>> entering FIPS mode, but FIPS mode was already enabled.
>> aprListener.initializingFIPS=Initializing FIPS mode...
>> aprListener.initializeFIPSSuccess=Successfully entered FIPS mode
>> aprListener.initializeFIPSFailed=Failed to enter FIPS mode
>>
>> Modified: tomcat/trunk/java/org/apache/tomcat/jni/SSL.java
>> URL:
>> http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/jni/SSL.java?rev=1587379&r1=1587378&r2=1587379&view=diff
>> ==============================================================================
>> --- tomcat/trunk/java/org/apache/tomcat/jni/SSL.java (original)
>> +++ tomcat/trunk/java/org/apache/tomcat/jni/SSL.java Tue Apr 15 01:14:40 2014
>> @@ -230,6 +230,14 @@ public final class SSL {
>> public static native int initialize(String engine);
>>
>> /**
>> + * Get the status of FIPS Mode.
>> + *
>> + * @return 0 If OpenSSL is not in FIPS mode, 1 if OpenSSL is in FIPS
>> Mode.
>> + * @throws Exception If tcnative was not compiled with FIPS Mode
>> available.
>> + */
>> + public static native int fipsModeGet();
>> +
>> + /**
>> * Enable/Disable FIPS Mode.
>> *
>> * @param mode 1 - enable, 0 - disable
>>
>> Modified: tomcat/trunk/webapps/docs/config/listeners.xml
>> URL:
>> http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/listeners.xml?rev=1587379&r1=1587378&r2=1587379&view=diff
>> ==============================================================================
>> --- tomcat/trunk/webapps/docs/config/listeners.xml (original)
>> +++ tomcat/trunk/webapps/docs/config/listeners.xml Tue Apr 15 01:14:40 2014
>> @@ -112,12 +112,22 @@
>> </attribute>
>>
>> <attribute name="FIPSMode" required="false">
>> - <p>Set to <code>on</code> to instruct OpenSSL to go into FIPS mode.
>> + <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).
>> 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.
>> + <code>FIPSMode="on"</code> or <code>FIPSMode="require"</code>
>> requires
>> + Tomcat native library version 1.1.30 or later, while
>> + <code>FIPSMode="enter"</code> can probably be done with Tomcat
>> native
>> + library version 1.2.23 or later -- either of which <em>must be built
>> + against the FIPS-compatible OpenSSL</em> library.
>> + If this attribute is set to any of the above values,
>> <b>SSLEngine</b>
>> + must be enabled as well for any effect.
>> The default value is <code>off</code>.</p>
>> </attribute>
>>
>>
>
>
> Why the ‘enter’ and ‘require’ options?
Please read the enhancement request where I've described the reasoning
behind this.
> I can understand ‘on’ == ‘I want FIPS mode’, but I don’t get how
> ‘require’ == ‘I require FIPS mode turned on before Tomcat starts’
> affects Tomcat, and I don’t get how ‘enter’ == ‘Try FIPS mode or fail
> if already set’ is useful.
>
> Also, it seems inconsistent given the above that ‘off’ does nothing
> if TCN is already in FIPS mode at startup?
I can change that if you feel it is important.
> Current behaviour would appear to be ‘on’ == ‘make sure it’s on *with
> bug’, ‘off’ == ‘don’t really care, will take whatever’?
Correct.
> Would on/off still be sufficient, or do we need the four ‘require’,
> ‘support’, ‘not supported’, ‘initiate’ options ala transactions?
I like being able to ensure that FIPS mode was already enabled.
-chris
signature.asc
Description: OpenPGP digital signature
