Covered Arrays.deepEquals() in NonConstantTimeCryptoComparison.ql

This commit is contained in:
Artem Smotrakov
2021-06-16 19:44:51 +02:00
committed by Fosstars
parent 5dbcf1d611
commit 75f67959f3
3 changed files with 39 additions and 17 deletions

View File

@@ -50,7 +50,7 @@ private class NonConstantTimeCryptoComparisonConfig extends TaintTracking::Confi
sink.asExpr() = [ma.getQualifier(), ma.getAnArgument()]
or
m.getDeclaringType().hasQualifiedName("java.util", "Arrays") and
m.hasName("equals") and
m.hasName(["equals", "deepEquals"]) and
ma.getAnArgument() = sink.asExpr()
or
m.getDeclaringType().hasQualifiedName("java.util", "Objects") and

View File

@@ -7,15 +7,31 @@ import java.util.Objects;
import javax.crypto.Cipher;
import javax.crypto.Mac;
public class NotConstantTimeCryptoComparison {
public class NonConstantTimeCryptoComparison {
// BAD: compare MACs using a not-constant time method
// BAD: compare MACs using a non-constant time method
public boolean unsafeMacCheck(byte[] expectedMac, byte[] data) throws Exception {
Mac mac = Mac.getInstance("HmacSHA256");
byte[] actualMac = mac.doFinal(data);
return Arrays.equals(expectedMac, actualMac);
}
// BAD: compare MACs using a non-constant time method
public boolean unsafeMacCheckWithArraysDeepEquals(byte[] expectedMac, byte[] data) throws Exception {
Mac mac = Mac.getInstance("HmacSHA256");
byte[] actualMac = mac.doFinal(data);
return Arrays.deepEquals(cast(expectedMac), cast(actualMac));
}
private static Object[] cast(byte[] array) {
Object[] result = new Object[array.length];
for (int i = 0; i < array.length; i++) {
result[i] = array[i];
}
return result;
}
// GOOD: compare MACs using a constant time method
public boolean saferMacCheck(byte[] expectedMac, byte[] data) throws Exception {
Mac mac = Mac.getInstance("HmacSHA256");
@@ -23,7 +39,7 @@ public class NotConstantTimeCryptoComparison {
return MessageDigest.isEqual(expectedMac, actualMac);
}
// BAD: compare signatures using a not-constant time method
// BAD: compare signatures using a non-constant time method
public boolean unsafeCheckSignatures(byte[] expected, byte[] data, PrivateKey key) throws Exception {
Signature engine = Signature.getInstance("SHA256withRSA");
engine.initSign(key);
@@ -41,7 +57,7 @@ public class NotConstantTimeCryptoComparison {
return MessageDigest.isEqual(expected, signature);
}
// BAD: compare ciphertexts using a not-constant time method
// BAD: compare ciphertexts using a non-constant time method
public boolean unsafeCheckCustomMac(byte[] expected, byte[] plaintext, Key key) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);

View File

@@ -1,15 +1,21 @@
edges
| NotConstantTimeCryptoComparison.java:15:28:15:44 | doFinal(...) : byte[] | NotConstantTimeCryptoComparison.java:16:43:16:51 | actualMac |
| NotConstantTimeCryptoComparison.java:31:28:31:40 | sign(...) : byte[] | NotConstantTimeCryptoComparison.java:32:40:32:48 | signature |
| NotConstantTimeCryptoComparison.java:48:22:48:46 | doFinal(...) : byte[] | NotConstantTimeCryptoComparison.java:49:45:49:47 | tag |
| NonConstantTimeCryptoComparison.java:15:28:15:44 | doFinal(...) : byte[] | NonConstantTimeCryptoComparison.java:16:43:16:51 | actualMac |
| NonConstantTimeCryptoComparison.java:23:28:23:44 | doFinal(...) : byte[] | NonConstantTimeCryptoComparison.java:24:58:24:66 | actualMac : byte[] |
| NonConstantTimeCryptoComparison.java:24:58:24:66 | actualMac : byte[] | NonConstantTimeCryptoComparison.java:24:53:24:67 | cast(...) |
| NonConstantTimeCryptoComparison.java:47:28:47:40 | sign(...) : byte[] | NonConstantTimeCryptoComparison.java:48:40:48:48 | signature |
| NonConstantTimeCryptoComparison.java:64:22:64:46 | doFinal(...) : byte[] | NonConstantTimeCryptoComparison.java:65:45:65:47 | tag |
nodes
| NotConstantTimeCryptoComparison.java:15:28:15:44 | doFinal(...) : byte[] | semmle.label | doFinal(...) : byte[] |
| NotConstantTimeCryptoComparison.java:16:43:16:51 | actualMac | semmle.label | actualMac |
| NotConstantTimeCryptoComparison.java:31:28:31:40 | sign(...) : byte[] | semmle.label | sign(...) : byte[] |
| NotConstantTimeCryptoComparison.java:32:40:32:48 | signature | semmle.label | signature |
| NotConstantTimeCryptoComparison.java:48:22:48:46 | doFinal(...) : byte[] | semmle.label | doFinal(...) : byte[] |
| NotConstantTimeCryptoComparison.java:49:45:49:47 | tag | semmle.label | tag |
| NonConstantTimeCryptoComparison.java:15:28:15:44 | doFinal(...) : byte[] | semmle.label | doFinal(...) : byte[] |
| NonConstantTimeCryptoComparison.java:16:43:16:51 | actualMac | semmle.label | actualMac |
| NonConstantTimeCryptoComparison.java:23:28:23:44 | doFinal(...) : byte[] | semmle.label | doFinal(...) : byte[] |
| NonConstantTimeCryptoComparison.java:24:53:24:67 | cast(...) | semmle.label | cast(...) |
| NonConstantTimeCryptoComparison.java:24:58:24:66 | actualMac : byte[] | semmle.label | actualMac : byte[] |
| NonConstantTimeCryptoComparison.java:47:28:47:40 | sign(...) : byte[] | semmle.label | sign(...) : byte[] |
| NonConstantTimeCryptoComparison.java:48:40:48:48 | signature | semmle.label | signature |
| NonConstantTimeCryptoComparison.java:64:22:64:46 | doFinal(...) : byte[] | semmle.label | doFinal(...) : byte[] |
| NonConstantTimeCryptoComparison.java:65:45:65:47 | tag | semmle.label | tag |
#select
| NotConstantTimeCryptoComparison.java:16:43:16:51 | actualMac | NotConstantTimeCryptoComparison.java:15:28:15:44 | doFinal(...) : byte[] | NotConstantTimeCryptoComparison.java:16:43:16:51 | actualMac | Using a non-constant time algorithm for comparing results of a cryptographic operation. |
| NotConstantTimeCryptoComparison.java:32:40:32:48 | signature | NotConstantTimeCryptoComparison.java:31:28:31:40 | sign(...) : byte[] | NotConstantTimeCryptoComparison.java:32:40:32:48 | signature | Using a non-constant time algorithm for comparing results of a cryptographic operation. |
| NotConstantTimeCryptoComparison.java:49:45:49:47 | tag | NotConstantTimeCryptoComparison.java:48:22:48:46 | doFinal(...) : byte[] | NotConstantTimeCryptoComparison.java:49:45:49:47 | tag | Using a non-constant time algorithm for comparing results of a cryptographic operation. |
| NonConstantTimeCryptoComparison.java:16:43:16:51 | actualMac | NonConstantTimeCryptoComparison.java:15:28:15:44 | doFinal(...) : byte[] | NonConstantTimeCryptoComparison.java:16:43:16:51 | actualMac | Using a non-constant time algorithm for comparing results of a cryptographic operation. |
| NonConstantTimeCryptoComparison.java:24:53:24:67 | cast(...) | NonConstantTimeCryptoComparison.java:23:28:23:44 | doFinal(...) : byte[] | NonConstantTimeCryptoComparison.java:24:53:24:67 | cast(...) | Using a non-constant time algorithm for comparing results of a cryptographic operation. |
| NonConstantTimeCryptoComparison.java:48:40:48:48 | signature | NonConstantTimeCryptoComparison.java:47:28:47:40 | sign(...) : byte[] | NonConstantTimeCryptoComparison.java:48:40:48:48 | signature | Using a non-constant time algorithm for comparing results of a cryptographic operation. |
| NonConstantTimeCryptoComparison.java:65:45:65:47 | tag | NonConstantTimeCryptoComparison.java:64:22:64:46 | doFinal(...) : byte[] | NonConstantTimeCryptoComparison.java:65:45:65:47 | tag | Using a non-constant time algorithm for comparing results of a cryptographic operation. |