Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated PredicateHandler to handle OR-ed predicates #265

Merged
merged 9 commits into from
Nov 24, 2023
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package crypto.analysis.errors;

import java.util.List;
import java.util.stream.Collectors;

import boomerang.jimple.Statement;
import crypto.extractparameter.CallSiteWithExtractedValue;
import crypto.rules.CrySLPredicate;
Expand All @@ -15,16 +18,20 @@

public class RequiredPredicateError extends AbstractError{

private CrySLPredicate contradictedPredicate;
private List<CrySLPredicate> contradictedPredicate;
private CallSiteWithExtractedValue extractedValues;

public RequiredPredicateError(CrySLPredicate contradictedPredicate, Statement location, CrySLRule rule, CallSiteWithExtractedValue multimap) {
public RequiredPredicateError(List<CrySLPredicate> contradictedPredicates, Statement location, CrySLRule rule, CallSiteWithExtractedValue multimap) {
super(location, rule);
this.contradictedPredicate = contradictedPredicate;
this.contradictedPredicate = contradictedPredicates;
this.extractedValues = multimap;
}

public CrySLPredicate getContradictedPredicate() {
/**
* This method returns a list of contradicting predicates
* @return list of contradicting predicates
*/
public List<CrySLPredicate> getContradictedPredicates() {
return contradictedPredicate;
}

Expand All @@ -41,7 +48,7 @@ public void accept(ErrorVisitor visitor){
public String toErrorMarkerString() {
String msg = extractedValues.toString();
msg += " was not properly generated as ";
String predicateName = getContradictedPredicate().getPredName();
String predicateName = getContradictedPredicates().stream().map(e -> e.getPredName()).collect(Collectors.joining(" OR "));
String[] parts = predicateName.split("(?=[A-Z])");
msg += parts[0];
for(int i=1; i<parts.length; i++)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,15 @@ private void partitionConstraints() {
private ISLConstraint collectAlternativePredicates(CrySLConstraint cons, AlternativeReqPredicate alt) {
CrySLPredicate left = (CrySLPredicate) cons.getLeft();
if (alt == null) {
alt = new AlternativeReqPredicate(left, left.getLocation());
for (CallSiteWithParamIndex cwpi : this.getParameterAnalysisQuerySites()) {
for (ICrySLPredicateParameter p : left.getParameters()) {
if (p.getName().equals("transformation"))
continue;
if (cwpi.getVarName().equals(p.getName())) {
alt = new AlternativeReqPredicate(left, cwpi.stmt());
}
}
}
} else {
alt.addAlternative(left);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
package crypto.predicates;

import java.util.AbstractMap.SimpleEntry;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map.Entry;
import java.util.Set;

import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.common.collect.Table;
import com.google.common.collect.Table.Cell;

import boomerang.jimple.Statement;
import boomerang.jimple.Val;
import boomerang.results.ForwardBoomerangResults;
Expand All @@ -25,7 +28,6 @@
import crypto.extractparameter.CallSiteWithExtractedValue;
import crypto.extractparameter.CallSiteWithParamIndex;
import crypto.interfaces.ISLConstraint;
import crypto.rules.CrySLConstraint;
import crypto.rules.CrySLPredicate;
import crypto.rules.CrySLRule;
import soot.SootMethod;
Expand Down Expand Up @@ -215,10 +217,8 @@ private void checkMissingRequiredPredicates() {
for (ISLConstraint pred : missingPredicates) {
if (pred instanceof RequiredCrySLPredicate) {
reportMissingPred(seed, (RequiredCrySLPredicate) pred);
} else if (pred instanceof CrySLConstraint) {
for (CrySLPredicate altPred : ((AlternativeReqPredicate) pred).getAlternatives()) {
reportMissingPred(seed, new RequiredCrySLPredicate(altPred, altPred.getLocation()));
}
} else if (pred instanceof AlternativeReqPredicate) {
reportMissingPred(seed, (AlternativeReqPredicate) pred);
}
}
}
Expand All @@ -230,7 +230,19 @@ private void reportMissingPred(AnalysisSeedWithSpecification seed, RequiredCrySL
for (CallSiteWithParamIndex v : seed.getParameterAnalysis().getAllQuerySites()) {
if (missingPred.getPred().getInvolvedVarNames().contains(v.getVarName()) && v.stmt().equals(missingPred.getLocation())) {
cryptoScanner.getAnalysisListener().reportError(seed,
new RequiredPredicateError(missingPred.getPred(), missingPred.getLocation(), seed.getSpec().getRule(), new CallSiteWithExtractedValue(v, null)));
new RequiredPredicateError(Arrays.asList(missingPred.getPred()), missingPred.getLocation(), seed.getSpec().getRule(), new CallSiteWithExtractedValue(v, null)));
}
}
}
}

private void reportMissingPred(AnalysisSeedWithSpecification seed, AlternativeReqPredicate missingPred) {
CrySLRule rule = seed.getSpec().getRule();
if (!rule.getPredicates().parallelStream().anyMatch(e -> missingPred.getAlternatives().stream().anyMatch(e1 -> e1.getPredName().equals(e.getPredName())) && missingPred.getAlternatives().stream().anyMatch(e2 -> e2.getParameters().get(0).equals(e.getParameters().get(0))))) {
for (CallSiteWithParamIndex v : seed.getParameterAnalysis().getAllQuerySites()) {
if (missingPred.getAlternatives().parallelStream().anyMatch(e4 -> e4.getInvolvedVarNames().contains(v.getVarName())) && v.stmt().equals(missingPred.getLocation())) {
cryptoScanner.getAnalysisListener().reportError(seed,
new RequiredPredicateError(missingPred.getAlternatives(), missingPred.getLocation(), seed.getSpec().getRule(), new CallSiteWithExtractedValue(v, null)));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import crypto.analysis.errors.IncompleteOperationError;
import crypto.analysis.errors.RequiredPredicateError;
import crypto.analysis.errors.TypestateError;
import tests.headless.FindingsType.FalseNegatives;
import tests.headless.FindingsType.TruePositives;

public class BouncyCastleHeadlessTest extends AbstractHeadlessTest {
Expand Down Expand Up @@ -41,7 +40,7 @@ public void testBCSymmetricCipherExamples() {
MavenProject mavenProject = createAndCompile(mavenProjectPath);
HeadlessCryptoScanner scanner = createScanner(mavenProject, Ruleset.BouncyCastle);

setErrorsCount(RequiredPredicateError.class, new TruePositives(2), new FalseNegatives(1, "https://github.com/CROSSINGTUD/CryptoAnalysis/issues/216"), "<gcm_aes_example.GCMAESBouncyCastle: byte[] processing(byte[],boolean)>");
setErrorsCount("<gcm_aes_example.GCMAESBouncyCastle: byte[] processing(byte[],boolean)>", RequiredPredicateError.class, 3);
setErrorsCount("<cbc_aes_example.CBCAESBouncyCastle: void setKey(byte[])>", RequiredPredicateError.class, 1);
setErrorsCount("<cbc_aes_example.CBCAESBouncyCastle: byte[] processing(byte[],boolean)>", RequiredPredicateError.class, 3);

Expand All @@ -56,11 +55,17 @@ public void testBCAsymmetricCipherExamples() {
HeadlessCryptoScanner scanner = createScanner(mavenProject, Ruleset.BouncyCastle);

setErrorsCount(TypestateError.class, new TruePositives(1), "<rsa_misuse.RSATest: java.lang.String Encrypt(byte[],org.bouncycastle.crypto.params.AsymmetricKeyParameter)>");
setErrorsCount(RequiredPredicateError.class, new TruePositives(1), "<rsa_misuse.RSATest: java.lang.String Decrypt(java.lang.String,org.bouncycastle.crypto.params.AsymmetricKeyParameter)>");

// These two errors occur because AsymmetricCipherKeyPair ensures the predicate only after the constructor call
setErrorsCount(RequiredPredicateError.class, new TruePositives(1), "<rsa_nomisuse.RSATest: java.lang.String Encrypt(byte[],org.bouncycastle.crypto.params.AsymmetricKeyParameter)>");
setErrorsCount(RequiredPredicateError.class, new TruePositives(1), "<rsa_nomisuse.RSATest: java.lang.String Decrypt(java.lang.String,org.bouncycastle.crypto.params.AsymmetricKeyParameter)>");

setErrorsCount(TypestateError.class, new TruePositives(1), "<crypto.RSAEngineTest: void testEncryptTwo()>");
setErrorsCount(TypestateError.class, new TruePositives(1), "<crypto.RSAEngineTest: void testDecryptTwo(byte[])>");

// Since version 3.0.0: Predicates with same name in the same statement are distinguished
setErrorsCount(RequiredPredicateError.class, new TruePositives(2), "<crypto.RSAEngineTest: void testDecryptOne(byte[])>");
setErrorsCount(RequiredPredicateError.class, new TruePositives(3), "<crypto.RSAEngineTest: void testDecryptOne(byte[])>");
setErrorsCount(RequiredPredicateError.class, new TruePositives(2), "<crypto.RSAEngineTest: void testDecryptTwo(byte[])>");
setErrorsCount(RequiredPredicateError.class, new TruePositives(2), "<params.RSAPrivateCrtKeyParametersTest: void testOne()>");

Expand Down Expand Up @@ -110,7 +115,7 @@ public void testBCEllipticCurveExamples() {
HeadlessCryptoScanner scanner = createScanner(mavenProject, Ruleset.BouncyCastle);

setErrorsCount(new ErrorSpecification.Builder("<crypto.ECElGamalEncryptorTest: void testOne()>")
.withFNs(RequiredPredicateError.class, 1, "https://github.com/CROSSINGTUD/CryptoAnalysis/issues/216")
.withTPs(RequiredPredicateError.class, 1)
.build());
setErrorsCount(new ErrorSpecification.Builder("<crypto.ECElGamalEncryptorTest: void testTwo()>")
.withTPs(TypestateError.class, 1)
Expand All @@ -134,7 +139,6 @@ public void testBCEllipticCurveExamples() {
.build());
setErrorsCount(new ErrorSpecification.Builder("<params.ECPrivateKeyParametersTest: void testOne(java.lang.String)>")
.withTPs(RequiredPredicateError.class, 2)
.withFNs(RequiredPredicateError.class, 1, "https://github.com/CROSSINGTUD/CryptoAnalysis/issues/216")
.build());
setErrorsCount(new ErrorSpecification.Builder("<params.ECPrivateKeyParametersTest: void testOne(java.lang.String)>")
.withTPs(HardCodedError.class, 1)
Expand All @@ -143,12 +147,10 @@ public void testBCEllipticCurveExamples() {
.withTPs(HardCodedError.class, 1)
.build());
setErrorsCount(new ErrorSpecification.Builder("<params.ParametersWithRandomTest: void testOne(java.lang.String)>")
.withTPs(RequiredPredicateError.class, 2)
.withFNs(RequiredPredicateError.class, 1, "https://github.com/CROSSINGTUD/CryptoAnalysis/issues/216")
.withTPs(RequiredPredicateError.class, 3)
.build());
setErrorsCount(new ErrorSpecification.Builder("<params.ParametersWithRandomTest: void testThree(java.lang.String)>")
.withTPs(RequiredPredicateError.class, 3)
.withFNs(RequiredPredicateError.class, 1, "https://github.com/CROSSINGTUD/CryptoAnalysis/issues/216")
.withTPs(RequiredPredicateError.class, 4)
.build());
setErrorsCount(new ErrorSpecification.Builder("<params.ECDomainParametersTest: void testThree(java.lang.String)>")
.withTPs(RequiredPredicateError.class, 1)
Expand Down Expand Up @@ -185,47 +187,39 @@ public void testBCEllipticCurveExamples() {
.build());
setErrorsCount(new ErrorSpecification.Builder("<transforms.ECNewPublicKeyTransformTest: void testFour(java.lang.String)>")
.withTPs(IncompleteOperationError.class, 1)
.withTPs(RequiredPredicateError.class, 2)
.withFNs(RequiredPredicateError.class, 1, "https://github.com/CROSSINGTUD/CryptoAnalysis/issues/216")
.withTPs(RequiredPredicateError.class, 3)
.build());
setErrorsCount(new ErrorSpecification.Builder("<transforms.ECNewPublicKeyTransformTest: void testFive(java.lang.String)>")
.withTPs(RequiredPredicateError.class, 2)
.withFNs(RequiredPredicateError.class, 2, "https://github.com/CROSSINGTUD/CryptoAnalysis/issues/216")
.withTPs(RequiredPredicateError.class, 4)
.build());
setErrorsCount(new ErrorSpecification.Builder("<transforms.ECNewPublicKeyTransformTest: void testTwo(java.lang.String)>")
.withTPs(RequiredPredicateError.class, 2)
.withFNs(RequiredPredicateError.class, 2, "https://github.com/CROSSINGTUD/CryptoAnalysis/issues/216")
.withTPs(RequiredPredicateError.class, 4)
.build());
setErrorsCount(new ErrorSpecification.Builder("<transforms.ECNewPublicKeyTransformTest: void testOne(java.lang.String)>")
.withTPs(RequiredPredicateError.class, 2)
.withFNs(RequiredPredicateError.class, 1, "https://github.com/CROSSINGTUD/CryptoAnalysis/issues/216")
.withTPs(RequiredPredicateError.class, 3)
.build());
setErrorsCount(new ErrorSpecification.Builder("<transforms.ECNewPublicKeyTransformTest: void testSix(java.lang.String)>")
.withFNs(RequiredPredicateError.class, 2, "https://github.com/CROSSINGTUD/CryptoAnalysis/issues/216")
.withTPs(RequiredPredicateError.class, 2)
.build());

setErrorsCount(new ErrorSpecification.Builder("<transforms.ECNewRandomessTransformTest: void testThree(java.lang.String)>")
.withTPs(TypestateError.class, 1)
.build());
setErrorsCount(new ErrorSpecification.Builder("<transforms.ECNewRandomessTransformTest: void testFour(java.lang.String)>")
.withTPs(IncompleteOperationError.class, 1)
.withTPs(RequiredPredicateError.class, 2)
.withFNs(RequiredPredicateError.class, 1, "https://github.com/CROSSINGTUD/CryptoAnalysis/issues/216")
.withTPs(RequiredPredicateError.class, 3)
.build());
setErrorsCount(new ErrorSpecification.Builder("<transforms.ECNewRandomessTransformTest: void testFive(java.lang.String)>")
.withTPs(RequiredPredicateError.class, 2)
.withFNs(RequiredPredicateError.class, 1, "https://github.com/CROSSINGTUD/CryptoAnalysis/issues/216")
.withTPs(RequiredPredicateError.class, 4)
.build());
setErrorsCount(new ErrorSpecification.Builder("<transforms.ECNewRandomessTransformTest: void testSix(java.lang.String)>")
.withFNs(RequiredPredicateError.class, 2, "https://github.com/CROSSINGTUD/CryptoAnalysis/issues/216")
.withTPs(RequiredPredicateError.class, 2)
.build());
setErrorsCount(new ErrorSpecification.Builder("<transforms.ECNewRandomessTransformTest: void testTwo(java.lang.String)>")
.withTPs(RequiredPredicateError.class, 2)
.withFNs(RequiredPredicateError.class, 2, "https://github.com/CROSSINGTUD/CryptoAnalysis/issues/216")
.withTPs(RequiredPredicateError.class, 4)
.build());
setErrorsCount(new ErrorSpecification.Builder("<transforms.ECNewRandomessTransformTest: void testOne(java.lang.String)>")
.withTPs(RequiredPredicateError.class, 2)
.withFNs(RequiredPredicateError.class, 1, "https://github.com/CROSSINGTUD/CryptoAnalysis/issues/216")
.withTPs(RequiredPredicateError.class, 3)
.build());

setErrorsCount(new ErrorSpecification.Builder("<generators.ECKeyPairGeneratorTest: void testTwo(java.lang.String)>")
Expand Down
Loading