This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch 9.0.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/9.0.x by this push: new 302aec6dc1 Enable the use of Tomcat Native with OpenSSL 3 using the FIPS provider 302aec6dc1 is described below commit 302aec6dc1fd5abbb7f17f52ca829c1e2befad38 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 719b83f9f9..07757bc753 100644 --- a/java/org/apache/catalina/core/AprLifecycleListener.java +++ b/java/org/apache/catalina/core/AprLifecycleListener.java @@ -76,6 +76,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"; @@ -185,12 +190,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; @@ -201,10 +201,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()) { @@ -222,7 +222,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 @@ -233,7 +233,7 @@ public class AprLifecycleListener implements LifecycleListener { } return; } - if (apver < rqver) { + if (tcnVersion < rqver) { log.error(sm.getString("aprListener.tcnInvalid", Library.versionString(), TCN_REQUIRED_MAJOR + "." + @@ -249,7 +249,7 @@ public class AprLifecycleListener implements LifecycleListener { } return; } - if (apver < rcver) { + if (tcnVersion < rcver) { initInfoLogMessages.add(sm.getString("aprListener.tcnVersion", Library.versionString(), TCN_REQUIRED_MAJOR + "." + @@ -303,41 +303,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( @@ -359,6 +384,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 da364dc716..475f4e8641 100644 --- a/java/org/apache/catalina/core/LocalStrings.properties +++ b/java/org/apache/catalina/core/LocalStrings.properties @@ -76,6 +76,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}] @@ -90,6 +91,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 20fc8819e9..3b8fdfd1a8 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -122,6 +122,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="Jasper"> diff --git a/webapps/docs/config/listeners.xml b/webapps/docs/config/listeners.xml index af09bdebc7..14c04cc719 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