changeset 14574:54441ec952f7

8269618: Better session identification Reviewed-by: andrew
author cverghese
date Fri, 15 Oct 2021 03:11:56 +0100
parents 6de43823dd11
children 132377e2edb2
files src/share/classes/sun/security/ssl/HelloCookieManager.java src/share/classes/sun/security/ssl/PreSharedKeyExtension.java src/share/classes/sun/security/ssl/RandomCookie.java src/share/classes/sun/security/ssl/RenegoInfoExtension.java src/share/classes/sun/security/ssl/SessionId.java src/share/classes/sun/security/ssl/Utilities.java src/share/classes/sun/security/util/ByteArrays.java
diffstat 7 files changed, 82 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/sun/security/ssl/HelloCookieManager.java	Fri Sep 10 15:01:32 2021 +0300
+++ b/src/share/classes/sun/security/ssl/HelloCookieManager.java	Fri Oct 15 03:11:56 2021 +0100
@@ -180,7 +180,7 @@
             md.update(headerBytes);
             byte[] headerCookie = md.digest(secret);
 
-            if (!Arrays.equals(headerCookie, prevHeadCookie)) {
+            if (!MessageDigest.isEqual(headerCookie, prevHeadCookie)) {
                 return false;
             }
 
--- a/src/share/classes/sun/security/ssl/PreSharedKeyExtension.java	Fri Sep 10 15:01:32 2021 +0300
+++ b/src/share/classes/sun/security/ssl/PreSharedKeyExtension.java	Fri Oct 15 03:11:56 2021 +0100
@@ -31,7 +31,6 @@
 import java.util.List;
 import java.util.ArrayList;
 import java.util.Locale;
-import java.util.Arrays;
 import java.util.Objects;
 import java.util.Collection;
 import javax.crypto.Mac;
@@ -539,7 +538,7 @@
         SecretKey binderKey = deriveBinderKey(shc, psk, session);
         byte[] computedBinder =
                 computeBinder(shc, binderKey, session, pskBinderHash);
-        if (!Arrays.equals(binder, computedBinder)) {
+        if (!MessageDigest.isEqual(binder, computedBinder)) {
             throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
                     "Incorect PSK binder value");
         }
--- a/src/share/classes/sun/security/ssl/RandomCookie.java	Fri Sep 10 15:01:32 2021 +0300
+++ b/src/share/classes/sun/security/ssl/RandomCookie.java	Fri Oct 15 03:11:56 2021 +0100
@@ -25,10 +25,12 @@
 
 package sun.security.ssl;
 
+import sun.security.util.ByteArrays;
+
 import java.io.*;
 import java.nio.ByteBuffer;
+import java.security.MessageDigest;
 import java.security.SecureRandom;
-import java.util.Arrays;
 
 /*
  * RandomCookie ... SSL hands standard format random cookies (nonces)
@@ -111,7 +113,7 @@
     }
 
     boolean isHelloRetryRequest() {
-        return Arrays.equals(hrrRandomBytes, randomBytes);
+        return MessageDigest.isEqual(hrrRandomBytes, randomBytes);
     }
 
     // Used for client random validation of version downgrade protection.
@@ -130,10 +132,10 @@
     }
 
     private boolean isT12Downgrade() {
-        return Utilities.equals(randomBytes, 24, 32, t12Protection, 0, 8);
+        return ByteArrays.isEqual(randomBytes, 24, 32, t12Protection, 0, 8);
     }
 
     private boolean isT11Downgrade() {
-        return Utilities.equals(randomBytes, 24, 32, t11Protection, 0, 8);
+        return ByteArrays.isEqual(randomBytes, 24, 32, t11Protection, 0, 8);
     }
 }
--- a/src/share/classes/sun/security/ssl/RenegoInfoExtension.java	Fri Sep 10 15:01:32 2021 +0300
+++ b/src/share/classes/sun/security/ssl/RenegoInfoExtension.java	Fri Oct 15 03:11:56 2021 +0100
@@ -27,6 +27,7 @@
 
 import java.io.IOException;
 import java.nio.ByteBuffer;
+import java.security.MessageDigest;
 import java.text.MessageFormat;
 import java.util.Arrays;
 import java.util.Locale;
@@ -37,6 +38,7 @@
 import static sun.security.ssl.SSLExtension.SH_RENEGOTIATION_INFO;
 import sun.security.ssl.SSLExtension.SSLExtensionSpec;
 import sun.security.ssl.SSLHandshake.HandshakeMessage;
+import sun.security.util.ByteArrays;
 
 /**
  * Pack of the "renegotiation_info" extensions [RFC 5746].
@@ -243,7 +245,7 @@
                             "renegotiation");
                 } else {
                     // verify the client_verify_data value
-                    if (!Arrays.equals(shc.conContext.clientVerifyData,
+                    if (!MessageDigest.isEqual(shc.conContext.clientVerifyData,
                             spec.renegotiatedConnection)) {
                         throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
                             "Invalid renegotiation_info extension data: " +
@@ -470,14 +472,14 @@
                 }
 
                 byte[] cvd = chc.conContext.clientVerifyData;
-                if (!Utilities.equals(spec.renegotiatedConnection,
+                if (!ByteArrays.isEqual(spec.renegotiatedConnection,
                         0, cvd.length, cvd, 0, cvd.length)) {
                     throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
                         "Invalid renegotiation_info in ServerHello: " +
                         "unmatched client_verify_data value");
                 }
                 byte[] svd = chc.conContext.serverVerifyData;
-                if (!Utilities.equals(spec.renegotiatedConnection,
+                if (!ByteArrays.isEqual(spec.renegotiatedConnection,
                         cvd.length, infoLen, svd, 0, svd.length)) {
                     throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
                         "Invalid renegotiation_info in ServerHello: " +
--- a/src/share/classes/sun/security/ssl/SessionId.java	Fri Sep 10 15:01:32 2021 +0300
+++ b/src/share/classes/sun/security/ssl/SessionId.java	Fri Oct 15 03:11:56 2021 +0100
@@ -25,6 +25,7 @@
 
 package sun.security.ssl;
 
+import java.security.MessageDigest;
 import java.security.SecureRandom;
 import java.util.Arrays;
 import javax.net.ssl.SSLProtocolException;
@@ -89,7 +90,7 @@
 
         if (obj instanceof SessionId) {
             SessionId that = (SessionId)obj;
-            return Arrays.equals(this.sessionId, that.sessionId);
+            return MessageDigest.isEqual(this.sessionId, that.sessionId);
         }
 
         return false;
--- a/src/share/classes/sun/security/ssl/Utilities.java	Fri Sep 10 15:01:32 2021 +0300
+++ b/src/share/classes/sun/security/ssl/Utilities.java	Fri Oct 15 03:11:56 2021 +0100
@@ -250,23 +250,4 @@
         }
     }
 
-    /**
-     * Returns true if the two specified arrays of bytes, over the specified
-     * ranges, are <i>equal</i> to one another.
-     */
-    static boolean equals(byte[] arr1, int st1, int end1, byte[] arr2, int st2, int end2) {
-        rangeCheck(arr1.length, st1, end1);
-        rangeCheck(arr2.length, st2, end2);
-
-        int aLength = end1 - st1;
-        int bLength = end2 - st2;
-        if (aLength != bLength)
-            return false;
-
-        for(int i=0; i<aLength; i++)
-            if(arr1[i + st1] != arr2[i + st2])
-                return false;
-        return true;
-    }
-
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/sun/security/util/ByteArrays.java	Fri Oct 15 03:11:56 2021 +0100
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.util;
+
+/**
+ * A time-instance comparison of two byte arrays.
+ */
+public class ByteArrays {
+    // See the MessageDigest.isEqual(byte[] digesta, byte[] digestb)
+    // implementation.  This is a potential enhancement of the
+    // MessageDigest class.
+    public static boolean isEqual(byte[] a, int aFromIndex, int aToIndex,
+                                 byte[] b, int bFromIndex, int bToIndex) {
+        if (a == b) {
+            return true;
+        }
+
+        if (a == null || b == null) {
+            return false;
+        }
+
+        if (a.length == 0) {
+            return b.length == 0;
+        }
+
+        int lenA = aToIndex - aFromIndex;
+        int lenB = bToIndex - bFromIndex;
+
+        if (lenB == 0) {
+            return lenA == 0;
+        }
+
+        int result = 0;
+        result |= lenA - lenB;
+
+        // time-constant comparison
+        for (int indexA = 0; indexA < lenA; indexA++) {
+            int indexB = ((indexA - lenB) >>> 31) * indexA;
+            result |= a[aFromIndex + indexA] ^ b[bFromIndex + indexB];
+        }
+
+        return result == 0;
+    }
+}