This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch 8.5.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/8.5.x by this push: new a89c68ef5b Enable the use of Tomcat Native with OpenSSL 3 using the FIPS provider a89c68ef5b is described below commit a89c68ef5b4e71718f603281e4195b0db028e44f Author: Mark Thomas <ma...@apache.org> AuthorDate: Wed Jun 1 15:33:02 2022 +0100 Enable the use of Tomcat Native with OpenSSL 3 using the FIPS provider --- .../apache/catalina/core/AprLifecycleListener.java | 81 +++++++++++++++------- .../apache/catalina/core/LocalStrings.properties | 2 + webapps/docs/changelog.xml | 5 ++ webapps/docs/config/listeners.xml | 22 +++--- 4 files changed, 76 insertions(+), 34 deletions(-) diff --git a/java/org/apache/catalina/core/AprLifecycleListener.java b/java/org/apache/catalina/core/AprLifecycleListener.java index aa13e1f0db..201e1761fc 100644 --- a/java/org/apache/catalina/core/AprLifecycleListener.java +++ b/java/org/apache/catalina/core/AprLifecycleListener.java @@ -78,6 +78,11 @@ public class AprLifecycleListener implements LifecycleListener { // ---------------------------------------------- Properties + private static int tcnMajor = 0; + private static int tcnMinor = 0; + private static int tcnPatch = 0; + private static int tcnVersion = 0; + protected static String SSLEngine = "on"; //default on protected static String FIPSMode = "off"; // default off, valid only when SSLEngine="on" protected static String SSLRandomSeed = "builtin"; @@ -191,12 +196,7 @@ public class AprLifecycleListener implements LifecycleListener { } @SuppressWarnings("deprecation") - private static void init() - { - int major = 0; - int minor = 0; - int patch = 0; - int apver = 0; + private static void init() { int rqver = TCN_REQUIRED_MAJOR * 1000 + TCN_REQUIRED_MINOR * 100 + TCN_REQUIRED_PATCH; int rcver = TCN_RECOMMENDED_MAJOR * 1000 + TCN_RECOMMENDED_MINOR * 100 + TCN_RECOMMENDED_PV; @@ -207,10 +207,10 @@ public class AprLifecycleListener implements LifecycleListener { try { Library.initialize(null); - major = Library.TCN_MAJOR_VERSION; - minor = Library.TCN_MINOR_VERSION; - patch = Library.TCN_PATCH_VERSION; - apver = major * 1000 + minor * 100 + patch; + tcnMajor = Library.TCN_MAJOR_VERSION; + tcnMinor = Library.TCN_MINOR_VERSION; + tcnPatch = Library.TCN_PATCH_VERSION; + tcnVersion = tcnMajor * 1000 + tcnMinor * 100 + tcnPatch; } catch (LibraryNotFoundError lnfe) { // Library not on path if (log.isDebugEnabled()) { @@ -228,7 +228,7 @@ public class AprLifecycleListener implements LifecycleListener { log.warn(sm.getString("aprListener.aprInitError", t.getMessage()), t); return; } - if (major > 1 && "off".equalsIgnoreCase(SSLEngine)) { + if (tcnMajor > 1 && "off".equalsIgnoreCase(SSLEngine)) { log.error(sm.getString("aprListener.sslRequired", SSLEngine, Library.versionString())); try { // Tomcat Native 2.x onwards requires SSL @@ -239,7 +239,7 @@ public class AprLifecycleListener implements LifecycleListener { } return; } - if (apver < rqver) { + if (tcnVersion < rqver) { log.error(sm.getString("aprListener.tcnInvalid", Library.versionString(), TCN_REQUIRED_MAJOR + "." + @@ -255,7 +255,7 @@ public class AprLifecycleListener implements LifecycleListener { } return; } - if (apver < rcver) { + if (tcnVersion < rcver) { initInfoLogMessages.add(sm.getString("aprListener.tcnVersion", Library.versionString(), TCN_REQUIRED_MAJOR + "." + @@ -308,41 +308,66 @@ public class AprLifecycleListener implements LifecycleListener { method = clazz.getMethod(methodName, paramTypes); method.invoke(null, paramValues); - if (!(null == FIPSMode || "off".equalsIgnoreCase(FIPSMode))) { + // OpenSSL 3 onwards uses providers + boolean usingProviders = tcnMajor > 1 || (tcnVersion > 1233 && (SSL.version() & 0xF0000000L) > 2); + // Tomcat Native 1.x built with OpenSSL 1.x without explicitly enabling + // FIPS and Tomcat Native < 1.2.34 built with OpenSSL 3.x will fail if + // any calls are made to SSL.fipsModeGet or SSL.fipsModeSet + if (usingProviders || !(null == FIPSMode || "off".equalsIgnoreCase(FIPSMode))) { fipsModeActive = false; - final boolean enterFipsMode; int fipsModeState = SSL.fipsModeGet(); if(log.isDebugEnabled()) { - log.debug(sm.getString("aprListener.currentFIPSMode", - Integer.valueOf(fipsModeState))); + log.debug(sm.getString("aprListener.currentFIPSMode", Integer.valueOf(fipsModeState))); } - if ("on".equalsIgnoreCase(FIPSMode)) { + if (null == FIPSMode || "off".equalsIgnoreCase(FIPSMode)) { if (fipsModeState == FIPS_ON) { - log.info(sm.getString("aprListener.skipFIPSInitialization")); + fipsModeActive = true; + } + enterFipsMode = false; + } else if ("on".equalsIgnoreCase(FIPSMode)) { + if (fipsModeState == FIPS_ON) { + if (!usingProviders) { + log.info(sm.getString("aprListener.skipFIPSInitialization")); + } fipsModeActive = true; enterFipsMode = false; } else { - enterFipsMode = true; + if (usingProviders) { + throw new IllegalStateException(sm.getString("aprListener.FIPSProviderNotDefault", FIPSMode)); + } else { + enterFipsMode = true; + } } } else if ("require".equalsIgnoreCase(FIPSMode)) { if (fipsModeState == FIPS_ON) { fipsModeActive = true; enterFipsMode = false; } else { - throw new IllegalStateException( - sm.getString("aprListener.requireNotInFIPSMode")); + if (usingProviders) { + throw new IllegalStateException(sm.getString("aprListener.FIPSProviderNotDefault", FIPSMode)); + } else { + throw new IllegalStateException(sm.getString("aprListener.requireNotInFIPSMode")); + } } } else if ("enter".equalsIgnoreCase(FIPSMode)) { if (fipsModeState == FIPS_OFF) { - enterFipsMode = true; + if (usingProviders) { + throw new IllegalStateException(sm.getString("aprListener.FIPSProviderNotDefault", FIPSMode)); + } else { + enterFipsMode = true; + } } else { - throw new IllegalStateException(sm.getString( - "aprListener.enterAlreadyInFIPSMode", - Integer.valueOf(fipsModeState))); + if (usingProviders) { + fipsModeActive = true; + enterFipsMode = false; + } else { + throw new IllegalStateException(sm.getString( + "aprListener.enterAlreadyInFIPSMode", Integer.valueOf(fipsModeState))); + } } } else { throw new IllegalArgumentException(sm.getString( @@ -364,6 +389,10 @@ public class AprLifecycleListener implements LifecycleListener { fipsModeActive = true; log.info(sm.getString("aprListener.initializeFIPSSuccess")); } + + if (usingProviders && fipsModeActive) { + log.info(sm.getString("aprListener.usingFIPSProvider")); + } } log.info(sm.getString("aprListener.initializedOpenSSL", SSL.versionString())); diff --git a/java/org/apache/catalina/core/LocalStrings.properties b/java/org/apache/catalina/core/LocalStrings.properties index 823718ee70..d267329fc3 100644 --- a/java/org/apache/catalina/core/LocalStrings.properties +++ b/java/org/apache/catalina/core/LocalStrings.properties @@ -77,6 +77,7 @@ aprListener.config=APR/OpenSSL configuration: useAprConnector [{0}], useOpenSSL aprListener.currentFIPSMode=Current FIPS mode: [{0}] aprListener.enterAlreadyInFIPSMode=AprLifecycleListener is configured to force entering FIPS mode, but library is already in FIPS mode [{0}] aprListener.flags=APR capabilities: IPv6 [{0}], sendfile [{1}], accept filters [{2}], random [{3}], UDS [{4}]. +aprListener.FIPSProviderNotDefault=The FIPS provider must be configured as the default provider when the AprLifecycleListener is configured with FIPS mode [{0}] aprListener.initializeFIPSFailed=Failed to enter FIPS mode aprListener.initializeFIPSSuccess=Successfully entered FIPS mode aprListener.initializedOpenSSL=OpenSSL successfully initialized [{0}] @@ -91,6 +92,7 @@ aprListener.tcnVersion=An older version [{0}] of the Apache Tomcat Native librar aprListener.tooLateForFIPSMode=Cannot setFIPSMode: SSL has already been initialized aprListener.tooLateForSSLEngine=Cannot setSSLEngine: SSL has already been initialized aprListener.tooLateForSSLRandomSeed=Cannot setSSLRandomSeed: SSL has already been initialized +aprListener.usingFIPSProvider=Using OpenSSL with the FIPS provider as the default provider aprListener.wrongFIPSMode=Unexpected value of FIPSMode option of AprLifecycleListener: [{0}] asyncContextImpl.asyncDispatchError=Error during asynchronous dispatch diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 0d110a32e4..3d3b3b864e 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -113,6 +113,11 @@ <code>org.apache.tomcat.util.net.Nio2Endpoint.handshake</code>) for TLS handshake failures. (markt) </add> + <add> + Enable the use of the FIPS provider for TLS enabled Connectors when + using Tomcat Native 1.2.34 onwards built with OpenSSL 3.0.x onwards. + (markt) + </add> </changelog> </subsection> <subsection name="Web applications"> diff --git a/webapps/docs/config/listeners.xml b/webapps/docs/config/listeners.xml index c1cf3b95c7..82a2a5dc8d 100644 --- a/webapps/docs/config/listeners.xml +++ b/webapps/docs/config/listeners.xml @@ -115,17 +115,23 @@ </attribute> <attribute name="FIPSMode" required="false"> - <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). + <p>The behaviour of this attribute depends on whether Tomcat Native has + been compiled against OpenSSL 1.x or OpenSSL 3.x.</p> + <p>For OpenSSL 1.x: 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>. - If this attribute is set to any of the above values, the <b>SSLEngine</b> - must be enabled as well.</p> + <p>For OpenSSL 3.x: <code>on</code>, <code>enter</code> and + <code>require</code> all behave the same way. If the FIPS provider is + the default provider, it will be used. If the FIPS provider is not the + default provider, an error will occur.</p> + <p>FIPS mode <em>requires you to have a FIPS-capable OpenSSL library</em>. + If this attribute is set to anything other than <code>off</code>, the + <b>SSLEngine</b> must be enabled as well.</p> <p>The default value is <code>off</code>.</p> </attribute> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org