diff --git a/CryptoAnalysis-Android/build/CryptoAnalysis-Android-2.7.3-SNAPSHOT-jar-with-dependencies.jar b/CryptoAnalysis-Android/build/CryptoAnalysis-Android-2.7.3-SNAPSHOT-jar-with-dependencies.jar new file mode 100644 index 000000000..e53622b98 Binary files /dev/null and b/CryptoAnalysis-Android/build/CryptoAnalysis-Android-2.7.3-SNAPSHOT-jar-with-dependencies.jar differ diff --git a/CryptoAnalysis/src/main/java/crypto/analysis/errors/RequiredPredicateError.java b/CryptoAnalysis/src/main/java/crypto/analysis/errors/RequiredPredicateError.java index 247c8011a..f4c1acb39 100644 --- a/CryptoAnalysis/src/main/java/crypto/analysis/errors/RequiredPredicateError.java +++ b/CryptoAnalysis/src/main/java/crypto/analysis/errors/RequiredPredicateError.java @@ -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; @@ -15,16 +18,20 @@ public class RequiredPredicateError extends AbstractError{ - private CrySLPredicate contradictedPredicate; + private List contradictedPredicate; private CallSiteWithExtractedValue extractedValues; - public RequiredPredicateError(CrySLPredicate contradictedPredicate, Statement location, CrySLRule rule, CallSiteWithExtractedValue multimap) { + public RequiredPredicateError(List 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 getContradictedPredicates() { return contradictedPredicate; } @@ -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 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))); } } } diff --git a/CryptoAnalysis/src/test/java/tests/headless/BouncyCastleHeadlessTest.java b/CryptoAnalysis/src/test/java/tests/headless/BouncyCastleHeadlessTest.java index dfb469ee0..feb36a988 100644 --- a/CryptoAnalysis/src/test/java/tests/headless/BouncyCastleHeadlessTest.java +++ b/CryptoAnalysis/src/test/java/tests/headless/BouncyCastleHeadlessTest.java @@ -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 { @@ -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"), ""); + setErrorsCount("", RequiredPredicateError.class, 3); setErrorsCount("", RequiredPredicateError.class, 1); setErrorsCount("", RequiredPredicateError.class, 3); @@ -56,11 +55,17 @@ public void testBCAsymmetricCipherExamples() { HeadlessCryptoScanner scanner = createScanner(mavenProject, Ruleset.BouncyCastle); setErrorsCount(TypestateError.class, new TruePositives(1), ""); + setErrorsCount(RequiredPredicateError.class, new TruePositives(1), ""); + + // These two errors occur because AsymmetricCipherKeyPair ensures the predicate only after the constructor call + setErrorsCount(RequiredPredicateError.class, new TruePositives(1), ""); + setErrorsCount(RequiredPredicateError.class, new TruePositives(1), ""); + setErrorsCount(TypestateError.class, new TruePositives(1), ""); setErrorsCount(TypestateError.class, new TruePositives(1), ""); // Since version 3.0.0: Predicates with same name in the same statement are distinguished - setErrorsCount(RequiredPredicateError.class, new TruePositives(2), ""); + setErrorsCount(RequiredPredicateError.class, new TruePositives(3), ""); setErrorsCount(RequiredPredicateError.class, new TruePositives(2), ""); setErrorsCount(RequiredPredicateError.class, new TruePositives(2), ""); @@ -110,7 +115,7 @@ public void testBCEllipticCurveExamples() { HeadlessCryptoScanner scanner = createScanner(mavenProject, Ruleset.BouncyCastle); setErrorsCount(new ErrorSpecification.Builder("") - .withFNs(RequiredPredicateError.class, 1, "https://github.com/CROSSINGTUD/CryptoAnalysis/issues/216") + .withTPs(RequiredPredicateError.class, 1) .build()); setErrorsCount(new ErrorSpecification.Builder("") .withTPs(TypestateError.class, 1) @@ -134,7 +139,6 @@ public void testBCEllipticCurveExamples() { .build()); setErrorsCount(new ErrorSpecification.Builder("") .withTPs(RequiredPredicateError.class, 2) - .withFNs(RequiredPredicateError.class, 1, "https://github.com/CROSSINGTUD/CryptoAnalysis/issues/216") .build()); setErrorsCount(new ErrorSpecification.Builder("") .withTPs(HardCodedError.class, 1) @@ -143,12 +147,10 @@ public void testBCEllipticCurveExamples() { .withTPs(HardCodedError.class, 1) .build()); setErrorsCount(new ErrorSpecification.Builder("") - .withTPs(RequiredPredicateError.class, 2) - .withFNs(RequiredPredicateError.class, 1, "https://github.com/CROSSINGTUD/CryptoAnalysis/issues/216") + .withTPs(RequiredPredicateError.class, 3) .build()); setErrorsCount(new ErrorSpecification.Builder("") - .withTPs(RequiredPredicateError.class, 3) - .withFNs(RequiredPredicateError.class, 1, "https://github.com/CROSSINGTUD/CryptoAnalysis/issues/216") + .withTPs(RequiredPredicateError.class, 4) .build()); setErrorsCount(new ErrorSpecification.Builder("") .withTPs(RequiredPredicateError.class, 1) @@ -185,23 +187,19 @@ public void testBCEllipticCurveExamples() { .build()); setErrorsCount(new ErrorSpecification.Builder("") .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("") - .withTPs(RequiredPredicateError.class, 2) - .withFNs(RequiredPredicateError.class, 2, "https://github.com/CROSSINGTUD/CryptoAnalysis/issues/216") + .withTPs(RequiredPredicateError.class, 4) .build()); setErrorsCount(new ErrorSpecification.Builder("") - .withTPs(RequiredPredicateError.class, 2) - .withFNs(RequiredPredicateError.class, 2, "https://github.com/CROSSINGTUD/CryptoAnalysis/issues/216") + .withTPs(RequiredPredicateError.class, 4) .build()); setErrorsCount(new ErrorSpecification.Builder("") - .withTPs(RequiredPredicateError.class, 2) - .withFNs(RequiredPredicateError.class, 1, "https://github.com/CROSSINGTUD/CryptoAnalysis/issues/216") + .withTPs(RequiredPredicateError.class, 3) .build()); setErrorsCount(new ErrorSpecification.Builder("") - .withFNs(RequiredPredicateError.class, 2, "https://github.com/CROSSINGTUD/CryptoAnalysis/issues/216") + .withTPs(RequiredPredicateError.class, 2) .build()); setErrorsCount(new ErrorSpecification.Builder("") @@ -209,23 +207,19 @@ public void testBCEllipticCurveExamples() { .build()); setErrorsCount(new ErrorSpecification.Builder("") .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("") - .withTPs(RequiredPredicateError.class, 2) - .withFNs(RequiredPredicateError.class, 1, "https://github.com/CROSSINGTUD/CryptoAnalysis/issues/216") + .withTPs(RequiredPredicateError.class, 4) .build()); setErrorsCount(new ErrorSpecification.Builder("") - .withFNs(RequiredPredicateError.class, 2, "https://github.com/CROSSINGTUD/CryptoAnalysis/issues/216") + .withTPs(RequiredPredicateError.class, 2) .build()); setErrorsCount(new ErrorSpecification.Builder("") - .withTPs(RequiredPredicateError.class, 2) - .withFNs(RequiredPredicateError.class, 2, "https://github.com/CROSSINGTUD/CryptoAnalysis/issues/216") + .withTPs(RequiredPredicateError.class, 4) .build()); setErrorsCount(new ErrorSpecification.Builder("") - .withTPs(RequiredPredicateError.class, 2) - .withFNs(RequiredPredicateError.class, 1, "https://github.com/CROSSINGTUD/CryptoAnalysis/issues/216") + .withTPs(RequiredPredicateError.class, 3) .build()); setErrorsCount(new ErrorSpecification.Builder("")