Skip to content

Commit

Permalink
Adapt tests to report RequiredPredicateErrors with 'this' as parameter
Browse files Browse the repository at this point in the history
  • Loading branch information
smeyer198 committed Feb 5, 2024
1 parent b5250ac commit e962f6b
Show file tree
Hide file tree
Showing 15 changed files with 192 additions and 186 deletions.
4 changes: 2 additions & 2 deletions CryptoAnalysis/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@
<artifactItem>
<groupId>de.darmstadt.tu.crossing</groupId>
<artifactId>JavaCryptographicArchitecture</artifactId>
<version>3.0.2</version>
<version>3.1.0</version>
<classifier>ruleset</classifier>
<type>zip</type>
<overWrite>true</overWrite>
Expand Down Expand Up @@ -117,7 +117,7 @@
<artifactItem>
<groupId>de.paderborn.uni</groupId>
<artifactId>BouncyCastle-JCA</artifactId>
<version>3.0.2</version>
<version>3.1.0</version>
<classifier>ruleset</classifier>
<type>zip</type>
<overWrite>true</overWrite>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,6 @@ public void execute() {
runExtractParameterAnalysis();
this.internalConstraintsSatisfied = checkInternalConstraints();


computeTypestateErrorUnits();
computeTypestateErrorsForEndOfObjectLifeTime();

Expand Down Expand Up @@ -314,11 +313,6 @@ private void checkConstraintsAndEnsurePredicates() {
* @param stateNode the next state after executing {@code currStmt}
*/
private void ensurePredicate(EnsuredCrySLPredicate ensuredPred, Statement currStmt, State stateNode) {
// Check, whether subsequent error detection is enabled
if (ensuredPred instanceof HiddenPredicate && !cryptoScanner.isSubsequentErrorDetection()) {
return;
}

// TODO only for first parameter?
for (ICrySLPredicateParameter predicateParam : ensuredPred.getPredicate().getParameters()) {
if (predicateParam.getName().equals("this")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,4 @@ public Collection<String> getForbiddenPredicates() {
public Collection<String> getIgnoredSections() {
return new ArrayList<>();
}

public boolean isSubsequentErrorDetection() {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ private void checkForContradictions() {
if(!rule.getPredicates().isEmpty()) {
for (ISLConstraint cons : rule.getConstraints()) {
if (cons instanceof CrySLPredicate && ((CrySLPredicate) cons).isNegated()) {
// TODO This is weird; why is it always get(0)?
contradictionPairs.add(new SimpleEntry<CrySLPredicate, CrySLPredicate>(rule.getPredicates().get(0), ((CrySLPredicate) cons).setNegated(false)));
}
}
Expand All @@ -311,7 +312,8 @@ private void checkForContradictions() {
}
for (Entry<CrySLPredicate, CrySLPredicate> disPair : contradictionPairs) {
if (preds.contains(disPair.getKey().getPredName()) && preds.contains(disPair.getValue().getPredName())) {
cryptoScanner.getAnalysisListener().reportError(null, new PredicateContradictionError(generatingPredicateStmt, null, disPair));
// TODO Rule should not be null
//cryptoScanner.getAnalysisListener().reportError(null, new PredicateContradictionError(generatingPredicateStmt, null, disPair));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,20 +238,24 @@ public void addProgress(int processedSeeds, int workListsize) {}
}

protected void assertErrors() {
boolean errorFound = false;
StringBuilder builder = new StringBuilder();
for (Cell<String, Class<?>, Integer> c : errorMarkerCountPerErrorTypeAndMethod.cellSet()) {
Integer value = c.getValue();
if (value != 0) {
builder.append("\n");
if (value > 0) {
// System.out.println(
throw new RuntimeException(
"Found " + value + " too few errors of type " + c.getColumnKey() + " in method " + c.getRowKey());
builder.append("\tFound " + value + " too few errors of type " + c.getColumnKey() + " in method " + c.getRowKey());
} else {
// System.out.println(
throw new RuntimeException(
"Found " + Math.abs(value) + " too many errors of type " + c.getColumnKey() + " in method " + c.getRowKey());
builder.append("\tFound " + Math.abs(value) + " too many errors of type " + c.getColumnKey() + " in method " + c.getRowKey());
}
errorFound = true;
}
}

if (errorFound) {
throw new RuntimeException("Tests not executed as planned:" + builder);
}
}

protected void setErrorsCount(String methodSignature, Class<?> errorType, int errorMarkerCount) {
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public void fileEncryptor() {
HeadlessCryptoScanner scanner = createScanner(mavenProject);

//All the following errors are false positives
setErrorsCount("<Crypto.KeyDeriv: javax.crypto.SecretKey getKey(char[])>", RequiredPredicateError.class, 2);
setErrorsCount("<Crypto.KeyDeriv: javax.crypto.SecretKey getKey(char[])>", RequiredPredicateError.class, 3);
setErrorsCount("<Crypto.KeyDeriv: javax.crypto.SecretKey getKey(char[])>", HardCodedError.class, 1);
setErrorsCount("<Crypto.Enc: byte[] encrypt(byte[],javax.crypto.SecretKey)>", RequiredPredicateError.class, 1);
setErrorsCount("<Crypto.Enc: byte[] decrypt(byte[],javax.crypto.SecretKey)>", RequiredPredicateError.class, 2);
Expand All @@ -32,9 +32,9 @@ public void userAuthenticator() {
HeadlessCryptoScanner scanner = createScanner(mavenProject);

//All the following errors are false positives
setErrorsCount("<Crypto.PWHasher: java.lang.Boolean verifyPWHash(char[],java.lang.String)>", RequiredPredicateError.class, 2);
setErrorsCount("<Crypto.PWHasher: java.lang.Boolean verifyPWHash(char[],java.lang.String)>", RequiredPredicateError.class, 3);
setErrorsCount("<Crypto.PWHasher: java.lang.Boolean verifyPWHash(char[],java.lang.String)>", HardCodedError.class, 1);
setErrorsCount("<Crypto.PWHasher: java.lang.String createPWHash(char[])>", RequiredPredicateError.class, 1);
setErrorsCount("<Crypto.PWHasher: java.lang.String createPWHash(char[])>", RequiredPredicateError.class, 2);
setErrorsCount("<Crypto.PWHasher: java.lang.String createPWHash(char[])>", HardCodedError.class, 1);

scanner.exec();
Expand Down
16 changes: 9 additions & 7 deletions CryptoAnalysis/src/test/java/tests/headless/CryptoGuardTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,21 +41,21 @@ public void brokenCryptoExamples() {
// This test case corresponds to the following project in CryptoGuard:
// https://github.com/CryptoGuardOSS/cryptoapi-bench/blob/master/src/main/java/org/cryptoapi/bench/brokencrypto/BrokenCryptoABICase2.java
setErrorsCount("<example.brokencrypto.BrokenCryptoABICase2: void doCrypto(java.lang.String)>", ConstraintError.class, 2);
setErrorsCount("<example.brokencrypto.BrokenCryptoABICase2: void doCrypto(java.lang.String)>", RequiredPredicateError.class, 1);
setErrorsCount("<example.brokencrypto.BrokenCryptoABICase2: void doCrypto(java.lang.String)>", RequiredPredicateError.class, 2);
setErrorsCount("<example.brokencrypto.BrokenCryptoABICase2: void doCrypto(java.lang.String)>", IncompleteOperationError.class, 1);
// ABICase3, ABICase4, ABICase9 not included as tests due to being similar to ABICase1 and ABICase2 above

// This test case corresponds to the following project in CryptoGuard:
// https://github.com/CryptoGuardOSS/cryptoapi-bench/blob/master/src/main/java/org/cryptoapi/bench/brokencrypto/BrokenCryptoABICase5.java
setErrorsCount("<example.brokencrypto.BrokenCryptoABICase5: void doCrypto()>", RequiredPredicateError.class, 1);
setErrorsCount("<example.brokencrypto.BrokenCryptoABICase5: void doCrypto()>", RequiredPredicateError.class, 2);
setErrorsCount("<example.brokencrypto.BrokenCryptoABICase5: void doCrypto()>", IncompleteOperationError.class, 1);
setErrorsCount(ConstraintError.class, new TruePositives(1), new FalseNegatives(1, "ConstraintError not caught! //Related to https://github.com/CROSSINGTUD/CryptoAnalysis/issues/163"), "<example.brokencrypto.BrokenCryptoABICase5: void doCrypto()>");
// ABICase6, -7, -8, -10 not included as tests due to being similar to ABICase5 above

// This test case corresponds to the following project in CryptoGuard:
// https://github.com/CryptoGuardOSS/cryptoapi-bench/blob/master/src/main/java/org/cryptoapi/bench/brokencrypto/BrokenCryptoBBCase3.java
setErrorsCount("<example.brokencrypto.BrokenCryptoBBCase3: void go()>", ConstraintError.class, 2);
setErrorsCount("<example.brokencrypto.BrokenCryptoBBCase3: void go()>", RequiredPredicateError.class, 1);
setErrorsCount("<example.brokencrypto.BrokenCryptoBBCase3: void go()>", RequiredPredicateError.class, 2);
setErrorsCount("<example.brokencrypto.BrokenCryptoBBCase3: void go()>", IncompleteOperationError.class, 1);
// BBCase1, BBCase2, BBCase4, BBCase5 not included as tests due to being similar to BBCase3 above

Expand Down Expand Up @@ -130,15 +130,17 @@ public void insecureAsymmetricCryptoExamples() {

// This test case corresponds to the following project in CryptoGuard:
// https://github.com/CryptoGuardOSS/cryptoapi-bench/blob/master/src/main/java/org/cryptoapi/bench/insecureasymmetriccrypto/InsecureAsymmetricCipherABICase1.java
setErrorsCount("<example.insecureasymmetriccrypto.InsecureAsymmetricCipherABICase1: void go(java.security.KeyPairGenerator,java.security.KeyPair)>", IncompleteOperationError.class, 2);
setErrorsCount("<example.insecureasymmetriccrypto.InsecureAsymmetricCipherABICase1: void main(java.lang.String[])>", TypestateError.class, 1);
setErrorsCount("<example.insecureasymmetriccrypto.InsecureAsymmetricCipherABICase1: void go(java.security.KeyPairGenerator,java.security.KeyPair)>", RequiredPredicateError.class, 2);
setErrorsCount("<example.insecureasymmetriccrypto.InsecureAsymmetricCipherABICase1: void main(java.lang.String[])>", RequiredPredicateError.class, 1);
setErrorsCount("<example.insecureasymmetriccrypto.InsecureAsymmetricCipherABICase1: void go(java.security.KeyPairGenerator,java.security.KeyPair)>", IncompleteOperationError.class, 2);
setErrorsCount("<example.insecureasymmetriccrypto.InsecureAsymmetricCipherABICase1: void go(java.security.KeyPairGenerator,java.security.KeyPair)>", RequiredPredicateError.class, 4);

// This test case corresponds to the following project in CryptoGuard:
// https://github.com/CryptoGuardOSS/cryptoapi-bench/blob/master/src/main/java/org/cryptoapi/bench/insecureasymmetriccrypto/InsecureAsymmetricCipherABICase2.java
setErrorsCount("<example.insecureasymmetriccrypto.InsecureAsymmetricCipherABICase2: void go(java.security.KeyPairGenerator,java.security.KeyPair)>", IncompleteOperationError.class, 2);
setErrorsCount("<example.insecureasymmetriccrypto.InsecureAsymmetricCipherABICase2: void go(java.security.KeyPairGenerator,java.security.KeyPair)>", RequiredPredicateError.class, 2);
setErrorsCount("<example.insecureasymmetriccrypto.InsecureAsymmetricCipherABICase2: void go(java.security.KeyPairGenerator,java.security.KeyPair)>", RequiredPredicateError.class, 4);
setErrorsCount("<example.insecureasymmetriccrypto.InsecureAsymmetricCipherABICase2: void main(java.lang.String[])>", ConstraintError.class, 1);
setErrorsCount("<example.insecureasymmetriccrypto.InsecureAsymmetricCipherABICase2: void main(java.lang.String[])>", RequiredPredicateError.class, 1);
// In the case above, misuse is caught correctly, but the keysize is reported to be 0
// and not 1024, as it really is. This is caused because of the structure of the project
// as explained in the issue: https://github.com/CROSSINGTUD/CryptoAnalysis/issues/163
Expand All @@ -147,7 +149,7 @@ public void insecureAsymmetricCryptoExamples() {
// https://github.com/CryptoGuardOSS/cryptoapi-bench/blob/master/src/main/java/org/cryptoapi/bench/insecureasymmetriccrypto/InsecureAsymmetricCipherBB Case1.java
setErrorsCount("<example.insecureasymmetriccrypto.InsecureAsymmetricCipherBBCase1: void go()>", IncompleteOperationError.class, 2);
setErrorsCount("<example.insecureasymmetriccrypto.InsecureAsymmetricCipherBBCase1: void go()>", ConstraintError.class, 1);
setErrorsCount("<example.insecureasymmetriccrypto.InsecureAsymmetricCipherBBCase1: void go()>", RequiredPredicateError.class, 2);
setErrorsCount("<example.insecureasymmetriccrypto.InsecureAsymmetricCipherBBCase1: void go()>", RequiredPredicateError.class, 5);

scanner.exec();
assertErrors();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public void ignoreNoPackages() {
setErrorsCount("<example.ConstraintErrorExample: void main(java.lang.String[])>", IncompleteOperationError.class, 1);
setErrorsCount("<example.IncompleteOperationErrorExample: void main(java.lang.String[])>", IncompleteOperationError.class, 1);
setErrorsCount("<example.PredicateMissingExample: void main(java.lang.String[])>", ConstraintError.class, 1);
setErrorsCount("<example.PredicateMissingExample: void main(java.lang.String[])>", RequiredPredicateError.class, 1);
setErrorsCount("<example.PredicateMissingExample: void main(java.lang.String[])>", RequiredPredicateError.class, 2);
setErrorsCount("<example.TypestateErrorExample: void main(java.lang.String[])>", TypestateError.class, 1);

scanner.exec();
Expand Down Expand Up @@ -78,7 +78,7 @@ public void ignoreClassesExample() {
setErrorsCount("<example.IncompleteOperationErrorExample: void main(java.lang.String[])>", IncompleteOperationError.class, 0);

setErrorsCount("<example.PredicateMissingExample: void main(java.lang.String[])>", ConstraintError.class, 1);
setErrorsCount("<example.PredicateMissingExample: void main(java.lang.String[])>", RequiredPredicateError.class, 1);
setErrorsCount("<example.PredicateMissingExample: void main(java.lang.String[])>", RequiredPredicateError.class, 2);
setErrorsCount("<example.TypestateErrorExample: void main(java.lang.String[])>", TypestateError.class, 1);

scanner.exec();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public void loadMessageDigestExample() {
HeadlessCryptoScanner scanner = createScanner(mavenProject);

//false positive
setErrorsCount("<MessageDigestExample.MessageDigestExample.Main: java.lang.String getSHA256(java.io.InputStream)>", IncompleteOperationError.class, 2);
setErrorsCount("<MessageDigestExample.MessageDigestExample.Main: java.lang.String getSHA256(java.io.InputStream)>", IncompleteOperationError.class, 3);

scanner.exec();
assertErrors();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public void reportedIssues() {
setErrorsCount("<issue81.Encryption: byte[] encrypt(byte[],javax.crypto.SecretKey)>", RequiredPredicateError.class, 1);

setErrorsCount("<issue81.Encryption: javax.crypto.SecretKey generateKey(java.lang.String)>", IncompleteOperationError.class, 1);
setErrorsCount("<issue81.Encryption: javax.crypto.SecretKey generateKey(java.lang.String)>", RequiredPredicateError.class, 3);
setErrorsCount("<issue81.Encryption: javax.crypto.SecretKey generateKey(java.lang.String)>", RequiredPredicateError.class, 4);
setErrorsCount("<issue81.Encryption: javax.crypto.SecretKey generateKey(java.lang.String)>", NeverTypeOfError.class, 1);
setErrorsCount("<issue81.Encryption: javax.crypto.SecretKey generateKey(java.lang.String)>", ConstraintError.class, 1);
setErrorsCount("<issue81.Encryption: javax.crypto.SecretKey generateKey(java.lang.String)>", HardCodedError.class, 1);
Expand All @@ -34,7 +34,7 @@ public void reportedIssues() {
setErrorsCount("<issue81.Main: void main(java.lang.String[])>", HardCodedError.class, 1);

setErrorsCount("<issuecognicrypt210.CogniCryptSecretKeySpec: void main(java.lang.String[])>", ConstraintError.class, 0);
setErrorsCount("<issuecognicrypt210.CogniCryptSecretKeySpec: void main(java.lang.String[])>", RequiredPredicateError.class, 2);
setErrorsCount("<issuecognicrypt210.CogniCryptSecretKeySpec: void main(java.lang.String[])>", RequiredPredicateError.class, 3);
setErrorsCount("<issuecognicrypt210.CogniCryptSecretKeySpec: void main(java.lang.String[])>", HardCodedError.class, 1);

setErrorsCount("<issue70.ClientProtocolDecoder: byte[] decryptAES(byte[])>", ConstraintError.class, 1);
Expand All @@ -43,7 +43,7 @@ public void reportedIssues() {
setErrorsCount("<issue68.Main: void main(java.lang.String[])>", IncompleteOperationError.class, 2);

setErrorsCount("<issue68.AESCryptor: byte[] getKey(java.lang.String)>", NeverTypeOfError.class, 1);
setErrorsCount("<issue68.AESCryptor: byte[] getKey(java.lang.String)>", RequiredPredicateError.class, 2);
setErrorsCount("<issue68.AESCryptor: byte[] getKey(java.lang.String)>", RequiredPredicateError.class, 3);
setErrorsCount("<issue68.AESCryptor: byte[] getKey(java.lang.String)>", IncompleteOperationError.class, 1);
setErrorsCount("<issue68.AESCryptor: byte[] getKey(java.lang.String)>", HardCodedError.class, 1);
setErrorsCount("<issue68.AESCryptor: javax.crypto.SecretKeyFactory getFactory()>", ConstraintError.class, 1);
Expand All @@ -53,6 +53,7 @@ public void reportedIssues() {
setErrorsCount("<issue68.AESCryptor: byte[] decryptImpl(byte[])>", RequiredPredicateError.class, 2);

setErrorsCount("<issue49.Main: java.security.PrivateKey getPrivateKey()>", ConstraintError.class, 1);
setErrorsCount("<issue49.Main: java.security.PrivateKey getPrivateKey()>", RequiredPredicateError.class, 2);
setErrorsCount("<issue49.Main: byte[] sign(java.lang.String)>", RequiredPredicateError.class, 1);

setErrorsCount("<issue103.Main: void main(java.lang.String[])>", RequiredPredicateError.class, 4);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public void testJava8Project() {
MavenProject mavenProject = createAndCompile(mavenProjectPath);
HeadlessCryptoScanner scanner = createScanner(mavenProject, Ruleset.JavaCryptographicArchitecture);

setErrorsCount("<example.PredicateMissingExample: void main(java.lang.String[])>", RequiredPredicateError.class, 1);
setErrorsCount("<example.PredicateMissingExample: void main(java.lang.String[])>", RequiredPredicateError.class, 2);
setErrorsCount("<example.PredicateMissingExample: void main(java.lang.String[])>", ConstraintError.class, 1);
setErrorsCount("<example.IncompleOperationErrorExample: void main(java.lang.String[])>", IncompleteOperationError.class, 1);
setErrorsCount("<example.ConstraintErrorExample: void main(java.lang.String[])>", ConstraintError.class, 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public void cogniCryptDemoExamples() {
setErrorsCount("<example.ConstraintErrorExample: void main(java.lang.String[])>", IncompleteOperationError.class, 1);
setErrorsCount("<example.fixed.ConstraintErrorExample: void main(java.lang.String[])>", IncompleteOperationError.class, 1);

setErrorsCount("<example.PredicateMissingExample: void main(java.lang.String[])>", RequiredPredicateError.class, 1);
setErrorsCount("<example.PredicateMissingExample: void main(java.lang.String[])>", RequiredPredicateError.class, 2);
setErrorsCount("<example.PredicateMissingExample: void main(java.lang.String[])>", ConstraintError.class, 1);
setErrorsCount("<example.TypestateErrorExample: void main(java.lang.String[])>", TypestateError.class, 1);
setErrorsCount("<example.IncompleOperationErrorExample: void main(java.lang.String[])>", IncompleteOperationError.class, 1);
Expand All @@ -44,6 +44,7 @@ public void cryptoMisuseExampleProject() {
setErrorsCount("<main.Msg: byte[] sign(java.lang.String)>", ConstraintError.class, 1);
setErrorsCount("<main.Msg: byte[] sign(java.lang.String)>", RequiredPredicateError.class, 1);
setErrorsCount("<main.Msg: java.security.PrivateKey getPrivateKey()>", ConstraintError.class, 1);
setErrorsCount("<main.Msg: java.security.PrivateKey getPrivateKey()>", RequiredPredicateError.class, 2);

setErrorsCount("<main.Msg: void encryptAlgFromField()>", ConstraintError.class, 1);
setErrorsCount("<main.Msg: void encryptAlgFromField()>", IncompleteOperationError.class, 1);
Expand All @@ -58,7 +59,7 @@ public void cryptoMisuseExampleProject() {
setErrorsCount("<main.Encrypt: void incorrectBigInteger()>", RequiredPredicateError.class, 1);

setErrorsCount("<main.Encrypt: void incorrect()>", ConstraintError.class, 2);
setErrorsCount("<main.Encrypt: void incorrect()>", RequiredPredicateError.class, 1);
setErrorsCount("<main.Encrypt: void incorrect()>", RequiredPredicateError.class, 2);

scanner.exec();
assertErrors();
Expand Down Expand Up @@ -99,7 +100,7 @@ public void oracleExample() {


//TODO this is a spurious finding. What happens here?
setErrorsCount("<Crypto.PWHasher: java.lang.Boolean verifyPWHash(char[],java.lang.String)>", RequiredPredicateError.class, 2);
setErrorsCount("<Crypto.PWHasher: java.lang.Boolean verifyPWHash(char[],java.lang.String)>", RequiredPredicateError.class, 3);


setErrorsCount("<main.Main: void incorrectKeyForWrongCipher()>", ConstraintError.class, 1);
Expand Down
2 changes: 1 addition & 1 deletion CryptoAnalysis/src/test/java/tests/pattern/IssuesTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public void testIssue421() throws GeneralSecurityException {
PublicKey pubkey2 = kf.generatePublic(keySpec2);
Assertions.notHasEnsuredPredicate(pubkey2);

Assertions.predicateErrors(4);
Assertions.predicateErrors(6);
}

}

0 comments on commit e962f6b

Please sign in to comment.