You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2022/02/03 10:08:07 UTC

[tomcat] branch 8.5.x updated: Fix BZ 65806 - FIPS enabled JREs don't support SHA1PRNG

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 b8a372e  Fix BZ 65806 - FIPS enabled JREs don't support SHA1PRNG
b8a372e is described below

commit b8a372e32b811c159fa8db98f444d42ffb570614
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Thu Feb 3 10:02:01 2022 +0000

    Fix BZ 65806 - FIPS enabled JREs don't support SHA1PRNG
    
    https://bz.apache.org/bugzilla/show_bug.cgi?id=65806
    Refactor SecureRandom creation for session IDs to void multiple SEVERE
    log messages when SHA1PRNG is not available
---
 .../catalina/authenticator/AuthenticatorBase.java  |  9 +++--
 java/org/apache/catalina/session/ManagerBase.java  | 13 ++++---
 .../apache/catalina/util/LocalStrings.properties   |  1 +
 .../catalina/util/SessionIdGeneratorBase.java      | 43 ++++++++++++++++------
 webapps/docs/changelog.xml                         |  6 +++
 5 files changed, 51 insertions(+), 21 deletions(-)

diff --git a/java/org/apache/catalina/authenticator/AuthenticatorBase.java b/java/org/apache/catalina/authenticator/AuthenticatorBase.java
index 3dc0e0f..c94b610 100644
--- a/java/org/apache/catalina/authenticator/AuthenticatorBase.java
+++ b/java/org/apache/catalina/authenticator/AuthenticatorBase.java
@@ -196,18 +196,19 @@ public abstract class AuthenticatorBase extends ValveBase
     /**
      * The name of the algorithm to use to create instances of
      * {@link java.security.SecureRandom} which are used to generate SSO session
-     * IDs. If no algorithm is specified, SHA1PRNG is used. To use the platform
-     * default (which may be SHA1PRNG), specify the empty string. If an invalid
+     * IDs. If no algorithm is specified, SHA1PRNG is used. If SHA1PRNG is not
+     * available, the platform default will be used. To use the platform default
+     * (which may be SHA1PRNG), specify the empty string. If an invalid
      * algorithm and/or provider is specified the SecureRandom instances will be
      * created using the defaults. If that fails, the SecureRandom instances
      * will be created using platform defaults.
      */
-    protected String secureRandomAlgorithm = "SHA1PRNG";
+    protected String secureRandomAlgorithm = SessionIdGeneratorBase.DEFAULT_SECURE_RANDOM_ALGORITHM;
 
     /**
      * The name of the provider to use to create instances of
      * {@link java.security.SecureRandom} which are used to generate session SSO
-     * IDs. If no algorithm is specified the of SHA1PRNG default is used. If an
+     * IDs. If no provider is specified the platform default is used. If an
      * invalid algorithm and/or provider is specified the SecureRandom instances
      * will be created using the defaults. If that fails, the SecureRandom
      * instances will be created using platform defaults.
diff --git a/java/org/apache/catalina/session/ManagerBase.java b/java/org/apache/catalina/session/ManagerBase.java
index 9317bd7..93c6216 100644
--- a/java/org/apache/catalina/session/ManagerBase.java
+++ b/java/org/apache/catalina/session/ManagerBase.java
@@ -87,19 +87,20 @@ public abstract class ManagerBase extends LifecycleMBeanBase implements Manager
 
     /**
      * The name of the algorithm to use to create instances of
-     * {@link java.security.SecureRandom} which are used to generate session IDs.
-     * If no algorithm is specified, SHA1PRNG is used. To use the platform
-     * default (which may be SHA1PRNG), specify the empty string. If an invalid
+     * {@link java.security.SecureRandom} which are used to generate session
+     * IDs. If no algorithm is specified, SHA1PRNG is used. If SHA1PRNG is not
+     * available, the platform default will be used. To use the platform default
+     * (which may be SHA1PRNG), specify the empty string. If an invalid
      * algorithm and/or provider is specified the SecureRandom instances will be
      * created using the defaults. If that fails, the SecureRandom instances
      * will be created using platform defaults.
      */
-    protected String secureRandomAlgorithm = "SHA1PRNG";
+    protected String secureRandomAlgorithm = SessionIdGeneratorBase.DEFAULT_SECURE_RANDOM_ALGORITHM;
 
     /**
      * The name of the provider to use to create instances of
-     * {@link java.security.SecureRandom} which are used to generate session IDs.
-     * If no algorithm is specified the of SHA1PRNG default is used. If an
+     * {@link java.security.SecureRandom} which are used to generate session
+     * IDs. If no provider is specified the platform default is used. If an
      * invalid algorithm and/or provider is specified the SecureRandom instances
      * will be created using the defaults. If that fails, the SecureRandom
      * instances will be created using platform defaults.
diff --git a/java/org/apache/catalina/util/LocalStrings.properties b/java/org/apache/catalina/util/LocalStrings.properties
index f4f8241..866939e 100644
--- a/java/org/apache/catalina/util/LocalStrings.properties
+++ b/java/org/apache/catalina/util/LocalStrings.properties
@@ -54,6 +54,7 @@ parameterMap.locked=No modifications are allowed to a locked ParameterMap
 resourceSet.locked=No modifications are allowed to a locked ResourceSet
 
 sessionIdGeneratorBase.createRandom=Creation of SecureRandom instance for session ID generation using [{0}] took [{1}] milliseconds.
+sessionIdGeneratorBase.noSHA1PRNG=The default SHA1PRNG algorithm for SecureRandom is not supported by this JVM. Using the platform default.
 sessionIdGeneratorBase.random=Exception initializing random number generator of class [{0}]. Falling back to java.secure.SecureRandom
 sessionIdGeneratorBase.randomAlgorithm=Exception initializing random number generator using algorithm [{0}]
 sessionIdGeneratorBase.randomProvider=Exception initializing random number generator using provider [{0}]
diff --git a/java/org/apache/catalina/util/SessionIdGeneratorBase.java b/java/org/apache/catalina/util/SessionIdGeneratorBase.java
index c0a2a2f..b2af0f3 100644
--- a/java/org/apache/catalina/util/SessionIdGeneratorBase.java
+++ b/java/org/apache/catalina/util/SessionIdGeneratorBase.java
@@ -19,7 +19,9 @@ package org.apache.catalina.util;
 import java.security.NoSuchAlgorithmException;
 import java.security.NoSuchProviderException;
 import java.security.SecureRandom;
+import java.security.Security;
 import java.util.Queue;
+import java.util.Set;
 import java.util.concurrent.ConcurrentLinkedQueue;
 
 import org.apache.catalina.LifecycleException;
@@ -29,15 +31,31 @@ import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
 import org.apache.tomcat.util.res.StringManager;
 
-public abstract class SessionIdGeneratorBase extends LifecycleBase
-        implements SessionIdGenerator {
+public abstract class SessionIdGeneratorBase extends LifecycleBase implements SessionIdGenerator {
 
     private final Log log = LogFactory.getLog(SessionIdGeneratorBase.class); // must not be static
 
-
-    private static final StringManager sm =
-        StringManager.getManager("org.apache.catalina.util");
-
+    private static final StringManager sm = StringManager.getManager("org.apache.catalina.util");
+
+    public static final String DEFAULT_SECURE_RANDOM_ALGORITHM;
+
+    static {
+        /*
+         * The default is normally SHA1PRNG. This was chosen because a) it is
+         * quick and b) it available by default in all JREs. However, it may not
+         * be available in some configurations such as those that use a FIPS
+         * certified provider. In those cases, use the platform default.
+         */
+        Set<String> algorithmNames = Security.getAlgorithms("SecureRandom");
+        if (algorithmNames.contains("SHA1PRNG")) {
+            DEFAULT_SECURE_RANDOM_ALGORITHM = "SHA1PRNG";
+        } else {
+            // Empty string - This will trigger the use of the platform default.
+            DEFAULT_SECURE_RANDOM_ALGORITHM = "";
+            Log log = LogFactory.getLog(SessionIdGeneratorBase.class);
+            log.warn(sm.getString("sessionIdGeneratorBase.noSHA1PRNG"));
+        }
+    }
 
     /**
      * Queue of random number generator objects to be used when creating session
@@ -50,7 +68,7 @@ public abstract class SessionIdGeneratorBase extends LifecycleBase
 
     private String secureRandomClass = null;
 
-    private String secureRandomAlgorithm = "SHA1PRNG";
+    private String secureRandomAlgorithm = DEFAULT_SECURE_RANDOM_ALGORITHM;
 
     private String secureRandomProvider = null;
 
@@ -102,7 +120,8 @@ public abstract class SessionIdGeneratorBase extends LifecycleBase
     /**
      * Specify a non-default algorithm to use to create instances of
      * {@link SecureRandom} which are used to generate session IDs. If no
-     * algorithm is specified, SHA1PRNG is used. To use the platform default
+     * algorithm is specified, SHA1PRNG will be used. If SHA1PRNG is not
+     * available, the platform default will be used. To use the platform default
      * (which may be SHA1PRNG), specify {@code null} or the empty string. If an
      * invalid algorithm and/or provider is specified the {@link SecureRandom}
      * instances will be created using the defaults for this
@@ -250,10 +269,12 @@ public abstract class SessionIdGeneratorBase extends LifecycleBase
             }
         }
 
-        if (result == null && error) {
-            // Invalid provider / algorithm
+        // In theory, DEFAULT_SECURE_RANDOM_ALGORITHM should always work but
+        // with custom providers that might not be the case.
+        if (result == null && error && !DEFAULT_SECURE_RANDOM_ALGORITHM.equals(secureRandomAlgorithm)) {
+            // Invalid provider / algorithm - use the default
             try {
-                result = SecureRandom.getInstance("SHA1PRNG");
+                result = SecureRandom.getInstance(DEFAULT_SECURE_RANDOM_ALGORITHM);
             } catch (NoSuchAlgorithmException e) {
                 log.error(sm.getString("sessionIdGeneratorBase.randomAlgorithm",
                         secureRandomAlgorithm), e);
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index b7777a2..524b6c7 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -117,6 +117,12 @@
         <code>ServletResponse.setLocale()</code> to include a mapping from the
         <code>ja</code> locale to the <code>Shift_JIS</code> encoding. (markt)
       </add>
+      <fix>
+        <bug>65806</bug>: Improve the handling of session ID generation when the
+        default algorithm for <code>SecureRandom</code> (<code>SHA1PRNG</code>)
+        is not supported by the configured providers as will be the case for a
+        FIPS compliant configuration. (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Coyote">

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