File: 02-CVE-2015-3250.patch

package info (click to toggle)
apache-directory-api 1.0.0~M20-5
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 21,200 kB
  • sloc: java: 175,971; xml: 6,498; makefile: 15; sh: 11
file content (68 lines) | stat: -rw-r--r-- 2,524 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Description: Fixes CVE-2015-3250: Timing Attack vulnerability
 This patch can be removed after upgrading to the version 1.0.0-M31 or later
Origin: backport, https://svn.apache.org/r1688300
--- a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/password/PasswordUtil.java
+++ b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/password/PasswordUtil.java
@@ -25,7 +25,6 @@
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.SecureRandom;
-import java.util.Arrays;
 import java.util.Date;
 
 import org.apache.directory.api.ldap.model.constants.LdapSecurityConstants;
@@ -254,14 +253,51 @@
             byte[] userPassword = PasswordUtil.encryptPassword( receivedCredentials, encryptionMethod.getAlgorithm(),
                 encryptionMethod.getSalt() );
 
-            // Now, compare the two passwords.
-            return Arrays.equals( userPassword, encryptedStored );
+            return compareBytes( userPassword, encryptedStored );
         }
         else
         {
-            return Arrays.equals( storedCredentials, receivedCredentials );
+            return compareBytes( receivedCredentials, storedCredentials );
         }
     }
+
+
+    /**
+     * Compare two byte[] in a constant time. This is necessary because using an Array.equals() is
+     * not Timing attack safe ([1], [2] and [3]), a breach that can be exploited to break some hashes.
+     *
+     *  [1] https://en.wikipedia.org/wiki/Timing_attack
+     *  [2] http://rdist.root.org/2009/05/28/timing-attack-in-google-keyczar-library/
+     *  [3] https://cryptocoding.net/index.php/Coding_rules
+     */
+    private static boolean compareBytes( byte[] provided, byte[] stored )
+    {
+        if ( stored == null )
+        {
+            return provided == null;
+        }
+        else if ( provided == null )
+        {
+            return false;
+        }
+
+        // Now, compare the two passwords, using a constant time method
+        if ( stored.length != provided.length )
+        {
+            return false;
+        }
+
+        // loop on *every* byte in both passwords, and at the end, if one char at least is different, return false.
+        int result = 0;
+
+        for ( int i = 0; i < stored.length; i++ )
+        {
+            // If both bytes are equal, xor will be == 0, otherwise it will be != 0 and so will result.
+            result |= ( stored[i] ^ provided[i] );
+        }
+
+        return result == 0;
+    }
 
 
     /**