PasswordEncoderUtils do not leak length

Enforce constant time even when expectedLength != actualLength.

Fixes gh-255
This commit is contained in:
avri-schneider 2016-01-18 18:44:47 +02:00 committed by Rob Winch
parent dc9f9b140f
commit a98389fa98
1 changed files with 12 additions and 9 deletions

View File

@ -33,15 +33,18 @@ class PasswordEncoderUtils {
static boolean equals(String expected, String actual) { static boolean equals(String expected, String actual) {
byte[] expectedBytes = bytesUtf8(expected); byte[] expectedBytes = bytesUtf8(expected);
byte[] actualBytes = bytesUtf8(actual); byte[] actualBytes = bytesUtf8(actual);
int expectedLength = expectedBytes == null ? -1 : expectedBytes.length; int expectedLength = expectedBytes == null ? 0 : expectedBytes.length;
int actualLength = actualBytes == null ? -1 : actualBytes.length; int actualLength = actualBytes == null ? 0 : actualBytes.length;
if (expectedLength != actualLength) { byte[] tmpBytes = new byte[1];
return false; int result = (expectedLength != actualLength) ? 1 : 0;
}
tmpBytes[0] = (byte) 0xFF; // value is ignored, just initializing.
result |= ((expectedBytes == null && actualBytes != null) || (expectedBytes != null && actualBytes == null)) ? 1 : 0;
expectedBytes = (expectedBytes == null ? expectedBytes : tmpBytes);
int result = 0; for (int i = 0; i < actualLength; i++) {
for (int i = 0; i < expectedLength; i++) { result |= expectedBytes[i % (expectedLength!=0?expectedLength:1)] ^ actualBytes[i % actualLength];
result |= expectedBytes[i] ^ actualBytes[i];
} }
return result == 0; return result == 0;
} }
@ -51,7 +54,7 @@ class PasswordEncoderUtils {
return null; return null;
} }
return Utf8.encode(s); return Utf8.encode(s); // need to check if Utf8.encode() runs in constant time (probably not). This may leak length of string.
} }
private PasswordEncoderUtils() { private PasswordEncoderUtils() {