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 2026/05/01 10:56:43 UTC

(tomcat) branch main updated (fbcb561830 -> 4b40f2f13f)

This is an automated email from the ASF dual-hosted git repository.

markt-asf pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git


    from fbcb561830 Fix deprecation warnings
     new ebdce4eed4 Follow-up to AJP switch to constant time for secret comparison
     new 6a8ad1a902 A few more places were constant time comparisons could be used
     new 4b40f2f13f Remove deprecated code

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../realm/DigestCredentialHandlerBase.java         | 45 +---------------------
 .../realm/MessageDigestCredentialHandler.java      |  5 +--
 java/org/apache/catalina/realm/RealmBase.java      |  3 +-
 .../apache/tomcat/util/security/ConstantTime.java  | 10 ++---
 4 files changed, 10 insertions(+), 53 deletions(-)


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


(tomcat) 01/03: Follow-up to AJP switch to constant time for secret comparison

Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

markt-asf pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit ebdce4eed4c2a7ba1334902973c4b320e414c481
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Fri May 1 11:43:42 2026 +0100

    Follow-up to AJP switch to constant time for secret comparison
    
    Implements some suggestions from a CoPilot review
    Align implementations more closely
    Fix start offset bug
---
 java/org/apache/tomcat/util/security/ConstantTime.java | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/java/org/apache/tomcat/util/security/ConstantTime.java b/java/org/apache/tomcat/util/security/ConstantTime.java
index 9a9d16b365..992cfdf825 100644
--- a/java/org/apache/tomcat/util/security/ConstantTime.java
+++ b/java/org/apache/tomcat/util/security/ConstantTime.java
@@ -107,18 +107,18 @@ public class ConstantTime {
             return len1 == 0;
         }
 
-        boolean result = true;
-        result &= (len1 == len2);
+        int result = 0;
+        result |= len1 - len2;
 
         // time-constant comparison
         for (int i = 0; i < len1; i++) {
             // If i >= len2, index2 is 0; otherwise, i.
             final int index2 = ((i - len2) >>> 31) * i;
-            byte b = bytes[i];
+            byte b = bytes[bc.getStart() + i];
             char c = s.charAt(index2);
-            result &= (b == c);
+            result |= (b & 0xFF) ^ c;
         }
-        return result;
+        return result == 0;
     }
 
 


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


(tomcat) 03/03: Remove deprecated code

Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

markt-asf pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit 4b40f2f13f00d7d5dc453f9bada1801e981f4fc6
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Fri May 1 11:54:01 2026 +0100

    Remove deprecated code
---
 .../realm/DigestCredentialHandlerBase.java         | 43 ----------------------
 1 file changed, 43 deletions(-)

diff --git a/java/org/apache/catalina/realm/DigestCredentialHandlerBase.java b/java/org/apache/catalina/realm/DigestCredentialHandlerBase.java
index a18d711adc..3f8fa0d5cb 100644
--- a/java/org/apache/catalina/realm/DigestCredentialHandlerBase.java
+++ b/java/org/apache/catalina/realm/DigestCredentialHandlerBase.java
@@ -16,7 +16,6 @@
  */
 package org.apache.catalina.realm;
 
-import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.SecureRandom;
 import java.util.Random;
@@ -273,46 +272,4 @@ public abstract class DigestCredentialHandlerBase implements CredentialHandler {
      * @return the logger for the CredentialHandler instance.
      */
     protected abstract Log getLog();
-
-    /**
-     * Implements String equality which always compares all characters in the string, without stopping early if any
-     * characters do not match.
-     * <p>
-     * <i>Note:</i> This implementation was adapted from {@link MessageDigest#isEqual} which we assume is as
-     * optimizer-defeating as possible.
-     *
-     * @param s1         The first string to compare.
-     * @param s2         The second string to compare.
-     * @param ignoreCase <code>true</code> if the strings should be compared without regard to case. Note that "true"
-     *                       here is only guaranteed to work with plain ASCII characters.
-     *
-     * @return <code>true</code> if the strings are equal to each other, <code>false</code> otherwise.
-     *
-     * @deprecated Use {@link ConstantTime#equals(String, String, boolean)}. This method will be removed in Tomcat 12.
-     */
-    @Deprecated
-    public static boolean equals(final String s1, final String s2, final boolean ignoreCase) {
-        return ConstantTime.equals(s1, s2, ignoreCase);
-    }
-
-    /**
-     * Implements byte-array equality which always compares all bytes in the array, without stopping early if any bytes
-     * do not match.
-     * <p>
-     * <i>Note:</i> Implementation note: this method delegates to {@link MessageDigest#isEqual} under the assumption
-     * that it provides a constant-time comparison of the bytes in the arrays. Java 7+ has such an implementation, but
-     * neither the Javadoc nor any specification requires it. Therefore, Tomcat should continue to use <i>this</i>
-     * method internally in case the JDK implementation changes so this method can be re-implemented properly.
-     *
-     * @param b1 The first array to compare.
-     * @param b2 The second array to compare.
-     *
-     * @return <code>true</code> if the arrays are equal to each other, <code>false</code> otherwise.
-     *
-     * @deprecated Use {@link ConstantTime#equals(byte[], byte[])}. This method will be removed in Tomcat 12.
-     */
-    @Deprecated
-    public static boolean equals(final byte[] b1, final byte[] b2) {
-        return ConstantTime.equals(b1, b2);
-    }
 }


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


(tomcat) 02/03: A few more places were constant time comparisons could be used

Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

markt-asf pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit 6a8ad1a9025db7b6d3c8fd4272ce9b9ca08a9b93
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Fri May 1 11:53:18 2026 +0100

    A few more places were constant time comparisons could be used
    
    Identified by CoPilot
---
 java/org/apache/catalina/realm/DigestCredentialHandlerBase.java    | 2 +-
 java/org/apache/catalina/realm/MessageDigestCredentialHandler.java | 5 ++---
 java/org/apache/catalina/realm/RealmBase.java                      | 3 ++-
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/java/org/apache/catalina/realm/DigestCredentialHandlerBase.java b/java/org/apache/catalina/realm/DigestCredentialHandlerBase.java
index a3edbeb547..a18d711adc 100644
--- a/java/org/apache/catalina/realm/DigestCredentialHandlerBase.java
+++ b/java/org/apache/catalina/realm/DigestCredentialHandlerBase.java
@@ -192,7 +192,7 @@ public abstract class DigestCredentialHandlerBase implements CredentialHandler {
             return false;
         }
 
-        return DigestCredentialHandlerBase.equals(storedHexEncoded, inputHexEncoded, true);
+        return ConstantTime.equals(storedHexEncoded, inputHexEncoded, true);
     }
 
 
diff --git a/java/org/apache/catalina/realm/MessageDigestCredentialHandler.java b/java/org/apache/catalina/realm/MessageDigestCredentialHandler.java
index eb79b3fbc4..766cde8d92 100644
--- a/java/org/apache/catalina/realm/MessageDigestCredentialHandler.java
+++ b/java/org/apache/catalina/realm/MessageDigestCredentialHandler.java
@@ -20,7 +20,6 @@ import java.io.UnsupportedEncodingException;
 import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
 import java.security.NoSuchAlgorithmException;
-import java.util.Arrays;
 import java.util.Base64;
 
 import org.apache.juli.logging.Log;
@@ -147,7 +146,7 @@ public class MessageDigestCredentialHandler extends DigestCredentialHandlerBase
                 byte[] userDigestBytes = ConcurrentMessageDigest.digest(getAlgorithm(),
                         inputCredentials.getBytes(StandardCharsets.ISO_8859_1), serverSaltBytes);
 
-                return Arrays.equals(userDigestBytes, serverDigestBytes);
+                return ConstantTime.equals(userDigestBytes, serverDigestBytes);
             } else if (storedCredentials.indexOf('$') > -1) {
                 return matchesSaltIterationsEncoded(inputCredentials, storedCredentials);
             } else {
@@ -158,7 +157,7 @@ public class MessageDigestCredentialHandler extends DigestCredentialHandlerBase
                     // Root cause should be logged by mutate()
                     return false;
                 }
-                return storedCredentials.equalsIgnoreCase(userDigest);
+                return ConstantTime.equals(storedCredentials, userDigest, true);
             }
         }
     }
diff --git a/java/org/apache/catalina/realm/RealmBase.java b/java/org/apache/catalina/realm/RealmBase.java
index 64d9685c25..2557ddb78e 100644
--- a/java/org/apache/catalina/realm/RealmBase.java
+++ b/java/org/apache/catalina/realm/RealmBase.java
@@ -61,6 +61,7 @@ import org.apache.tomcat.util.descriptor.web.SecurityCollection;
 import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
 import org.apache.tomcat.util.res.StringManager;
 import org.apache.tomcat.util.security.ConcurrentMessageDigest;
+import org.apache.tomcat.util.security.ConstantTime;
 import org.ietf.jgss.GSSContext;
 import org.ietf.jgss.GSSCredential;
 import org.ietf.jgss.GSSException;
@@ -416,7 +417,7 @@ public abstract class RealmBase extends LifecycleMBeanBase implements Realm {
                     "digestA2:" + digestA2 + " Server digest:" + serverDigest);
         }
 
-        if (serverDigest.equals(clientDigest)) {
+        if (ConstantTime.equals(serverDigest, clientDigest, true)) {
             return getPrincipal(username);
         }
 


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