Skip to content

Commit

Permalink
Merge pull request #485 from CROSSINGTUD/ruleset_adaption
Browse files Browse the repository at this point in the history
Fix small bug regarding alternative required predicates and adapt tests to conform JCA and BC-JCA 3.0.1
  • Loading branch information
schlichtig authored Nov 27, 2023
2 parents 465c909 + e5b9315 commit 2228dce
Show file tree
Hide file tree
Showing 11 changed files with 296 additions and 106 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.0</version>
<version>3.0.1</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.0</version>
<version>3.0.1</version>
<classifier>ruleset</classifier>
<type>zip</type>
<overWrite>true</overWrite>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
import crypto.interfaces.ICrySLPredicateParameter;
import crypto.interfaces.ISLConstraint;
import crypto.rules.CrySLCondPredicate;
import crypto.rules.CrySLConstraint;
import crypto.rules.CrySLMethod;
import crypto.rules.CrySLObject;
import crypto.rules.CrySLPredicate;
Expand Down Expand Up @@ -387,7 +386,7 @@ private boolean checkPredicates(Collection<ISLConstraint> relConstraints) {
RequiredCrySLPredicate reqPred = (RequiredCrySLPredicate) pred;
if (reqPred.getPred().isNegated()) {
for (EnsuredCrySLPredicate ensPred : ensuredPredicates) {
if (ensPred.getPredicate().equals(reqPred.getPred())) {
if (reqPred.getPred().equals(ensPred.getPredicate())) {
return false;
}
}
Expand All @@ -414,7 +413,7 @@ private boolean checkPredicates(Collection<ISLConstraint> relConstraints) {
remainingPredicates.remove(pred);
} else if (negatives.isEmpty()) {
for (EnsuredCrySLPredicate ensPred : ensuredPredicates) {
if (alternatives.parallelStream().anyMatch(e -> ensPred.getPredicate().equals(e) && doPredsMatch(e, ensPred))) {
if (alternatives.parallelStream().anyMatch(e -> e.equals(ensPred.getPredicate()) && doPredsMatch(e, ensPred))) {
remainingPredicates.remove(pred);
break;
}
Expand All @@ -428,7 +427,7 @@ private boolean checkPredicates(Collection<ISLConstraint> relConstraints) {
}

alternatives.removeAll(negatives);
if (alternatives.parallelStream().allMatch(e -> ensPred.getPredicate().equals(e) && doPredsMatch(e, ensPred))) {
if (alternatives.parallelStream().allMatch(e -> e.equals(ensPred.getPredicate()) && doPredsMatch(e, ensPred))) {
satisfied = true;
}

Expand All @@ -447,7 +446,7 @@ private boolean checkPredicates(Collection<ISLConstraint> relConstraints) {
if (evaluatePredCond(singlePred.getPred())) {
remainingPredicates.remove(singlePred);
}
} else if (rem instanceof CrySLConstraint) {
} else if (rem instanceof AlternativeReqPredicate) {
List<CrySLPredicate> altPred = ((AlternativeReqPredicate) rem).getAlternatives();
if (altPred.parallelStream().anyMatch(e -> evaluatePredCond(e))) {
remainingPredicates.remove(rem);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,7 @@ private void initialize() {
}
for (ClassSpecification spec : getClassSpecifictions()) {
spec.invokesForbiddenMethod(method);
if (spec.getRule().getClassName().equals("javax.crypto.SecretKey")) {
continue;
}

for (Query seed : spec.getInitialSeeds(method)) {
getOrCreateSeedWithSpec(new AnalysisSeedWithSpecification(this, seed.stmt(), seed.var(), spec));
}
Expand Down
2 changes: 0 additions & 2 deletions CryptoAnalysis/src/main/java/crypto/rules/CrySLPredicate.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@ public boolean equals(Object obj) {
if(!getPredName().equals(other.getPredName()))
return false;

// TODO Do also compare the parameter types (and not just the predicate names)

return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import soot.Unit;
import soot.jimple.AssignStmt;
import soot.jimple.InstanceInvokeExpr;
import soot.jimple.InterfaceInvokeExpr;
import soot.jimple.InvokeExpr;
import soot.jimple.Stmt;
import typestate.TransitionFunction;
Expand Down Expand Up @@ -64,7 +65,7 @@ public Collection<WeightedForwardQuery<TransitionFunction>> generateSeed(SootMet
AssignStmt stmt = (AssignStmt) unit;
out.add(createQuery(stmt,method,new AllocVal(stmt.getLeftOp(), method, stmt.getRightOp(), new Statement(stmt,method))));
}
} else if (invokeExpr instanceof InstanceInvokeExpr){
} else if (invokeExpr instanceof InstanceInvokeExpr && !(invokeExpr instanceof InterfaceInvokeExpr)){
InstanceInvokeExpr iie = (InstanceInvokeExpr) invokeExpr;
out.add(createQuery(unit,method,new AllocVal(iie.getBase(), method,iie, new Statement((Stmt) unit,method))));
}
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import crypto.analysis.errors.IncompleteOperationError;
import crypto.analysis.errors.RequiredPredicateError;
import crypto.analysis.errors.TypestateError;
import tests.headless.FindingsType.FalsePositives;

/**
* @author Enri Ozuni
Expand Down Expand Up @@ -201,7 +200,7 @@ public void customCryptoExamples() {
setErrorsCount("<wc.customCrypto.RawSignatureRSA: void negativeTestCase()>", TypestateError.class, 1);
setErrorsCount("<wc.customCrypto.RawSignatureRSA: void negativeTestCase()>", RequiredPredicateError.class, 2);

setErrorsCount("<wc.customCrypto.RawSignatureRSAwHash: void main(java.lang.String[])>", RequiredPredicateError.class, 1);
setErrorsCount("<wc.customCrypto.RawSignatureRSAwHash: void main(java.lang.String[])>", RequiredPredicateError.class, 0);
setErrorsCount("<wc.customCrypto.RawSignatureRSAwHash: void main(java.lang.String[])>", TypestateError.class, 1);

scanner.exec();
Expand Down Expand Up @@ -424,8 +423,9 @@ public void insecureDefaultExamples() {

// positive test case
setErrorsCount("<pdf.insecureDefault.InsecureDefaultRSA: void positiveTestCase()>", IncompleteOperationError.class, 4);
setErrorsCount("<pdf.insecureDefault.InsecureDefaultRSA: void positiveTestCase()>", RequiredPredicateError.class, 2);
setErrorsCount("<pdf.insecureDefault.InsecureDefaultRSA: void positiveTestCase()>", RequiredPredicateError.class, 0);
setErrorsCount("<pdf.insecureDefault.InsecureDefaultRSA: void positiveTestCase()>", TypestateError.class, 0);
setErrorsCount("<pdf.insecureDefault.InsecureDefaultRSA: void positiveTestCase()>", ConstraintError.class, 0);

// negative test case
setErrorsCount("<pdf.insecureDefault.InsecureDefaultRSA: void negativeTestCase()>", IncompleteOperationError.class, 4);
Expand All @@ -448,7 +448,7 @@ public void insecurePaddingExamples() {
// positive test case
setErrorsCount("<pkc.enc.insecurePadding.InsecurePaddingRSA1: void positiveTestCase()>", TypestateError.class, 0);
setErrorsCount("<pkc.enc.insecurePadding.InsecurePaddingRSA1: void positiveTestCase()>", IncompleteOperationError.class, 4);
setErrorsCount("<pkc.enc.insecurePadding.InsecurePaddingRSA1: void positiveTestCase()>", RequiredPredicateError.class, 2);
setErrorsCount("<pkc.enc.insecurePadding.InsecurePaddingRSA1: void positiveTestCase()>", RequiredPredicateError.class, 0);
setErrorsCount("<pkc.enc.insecurePadding.InsecurePaddingRSA1: void positiveTestCase()>", ConstraintError.class, 2);

// negative test case
Expand All @@ -460,7 +460,8 @@ public void insecurePaddingExamples() {
// positive test case
setErrorsCount("<pkc.enc.insecurePadding.InsecurePaddingRSA2: void positiveTestCase()>", TypestateError.class, 0);
setErrorsCount("<pkc.enc.insecurePadding.InsecurePaddingRSA2: void positiveTestCase()>", IncompleteOperationError.class, 4);
setErrorsCount("<pkc.enc.insecurePadding.InsecurePaddingRSA2: void positiveTestCase()>", RequiredPredicateError.class, 2);
setErrorsCount("<pkc.enc.insecurePadding.InsecurePaddingRSA2: void positiveTestCase()>", RequiredPredicateError.class, 0);
setErrorsCount("<pkc.enc.insecurePadding.InsecurePaddingRSA2: void positiveTestCase()>", ConstraintError.class, 0);

// negative test case
setErrorsCount("<pkc.enc.insecurePadding.InsecurePaddingRSA2: void negativeTestCase()>", TypestateError.class, 0);
Expand All @@ -471,7 +472,8 @@ public void insecurePaddingExamples() {
// positive test case
setErrorsCount("<pkc.enc.insecurePadding.InsecurePaddingRSA3: void positiveTestCase()>", TypestateError.class, 0);
setErrorsCount("<pkc.enc.insecurePadding.InsecurePaddingRSA3: void positiveTestCase()>", IncompleteOperationError.class, 4);
setErrorsCount("<pkc.enc.insecurePadding.InsecurePaddingRSA3: void positiveTestCase()>", RequiredPredicateError.class, 2);
setErrorsCount("<pkc.enc.insecurePadding.InsecurePaddingRSA3: void positiveTestCase()>", RequiredPredicateError.class, 0);
setErrorsCount("<pkc.enc.insecurePadding.InsecurePaddingRSA3: void positiveTestCase()>", ConstraintError.class, 0);

// negative test case
setErrorsCount("<pkc.enc.insecurePadding.InsecurePaddingRSA3: void negativeTestCase()>", TypestateError.class, 0);
Expand Down Expand Up @@ -573,9 +575,14 @@ public void issuesDHandECDHExamples() {
MavenProject mavenProject = createAndCompile(mavenProjectPath);
HeadlessCryptoScanner scanner = createScanner(mavenProject);

// TODO size should be 2048, not 1048
setErrorsCount("<pkc.ka.issuesDHandECDH.NonAuthenticatedEphemeralDH_1024: void main(java.lang.String[])>", ConstraintError.class, 2);
setErrorsCount("<pkc.ka.issuesDHandECDH.NonAuthenticatedEphemeralDH_1024: void main(java.lang.String[])>", RequiredPredicateError.class, 8);
// positive test case
setErrorsCount("<pkc.ka.issuesDHandECDH.NonAuthenticatedEphemeralDH_1024: void positiveTestCase()>", ConstraintError.class, 0);
setErrorsCount("<pkc.ka.issuesDHandECDH.NonAuthenticatedEphemeralDH_1024: void positiveTestCase()>", RequiredPredicateError.class, 6);

// negative test case
setErrorsCount("<pkc.ka.issuesDHandECDH.NonAuthenticatedEphemeralDH_1024: void negativeTestCase()>", ConstraintError.class, 2);
setErrorsCount("<pkc.ka.issuesDHandECDH.NonAuthenticatedEphemeralDH_1024: void negativeTestCase()>", RequiredPredicateError.class, 8);

setErrorsCount("<pkc.ka.issuesDHandECDH.NonAuthenticatedEphemeralDH_512: void main(java.lang.String[])>", ConstraintError.class, 2);
setErrorsCount("<pkc.ka.issuesDHandECDH.NonAuthenticatedEphemeralDH_512: void main(java.lang.String[])>", RequiredPredicateError.class, 8);
setErrorsCount("<pkc.ka.issuesDHandECDH.NonAuthenticatedEphemeralECDH_112: void main(java.lang.String[])>", ConstraintError.class, 2);
Expand All @@ -584,8 +591,15 @@ public void issuesDHandECDHExamples() {
setErrorsCount("<pkc.ka.issuesDHandECDH.NonAuthenticatedEphemeralECDH_80: void main(java.lang.String[])>", RequiredPredicateError.class, 8);
setErrorsCount("<pkc.ka.issuesDHandECDH.NonAuthenticatedDH_512: void main(java.lang.String[])>", RequiredPredicateError.class, 10);
setErrorsCount("<pkc.ka.issuesDHandECDH.NonAuthenticatedDH_512: void main(java.lang.String[])>", ConstraintError.class, 1);
setErrorsCount("<pkc.ka.issuesDHandECDH.NonAuthenticatedDH_1024: void main(java.lang.String[])>", RequiredPredicateError.class, 10);
setErrorsCount("<pkc.ka.issuesDHandECDH.NonAuthenticatedDH_1024: void main(java.lang.String[])>", ConstraintError.class, 1);

// positive test case
setErrorsCount("<pkc.ka.issuesDHandECDH.NonAuthenticatedDH_1024: void positiveTestCase()>", ConstraintError.class, 0);
setErrorsCount("<pkc.ka.issuesDHandECDH.NonAuthenticatedDH_1024: void positiveTestCase()>", RequiredPredicateError.class, 10);
setErrorsCount("<pkc.ka.issuesDHandECDH.NonAuthenticatedDH_1024: void positiveTestCase()>", IncompleteOperationError.class, 1);

// negative test case
setErrorsCount("<pkc.ka.issuesDHandECDH.NonAuthenticatedDH_1024: void negativeTestCase()>", ConstraintError.class, 1);
setErrorsCount("<pkc.ka.issuesDHandECDH.NonAuthenticatedDH_1024: void negativeTestCase()>", RequiredPredicateError.class, 10);

scanner.exec();
assertErrors();
Expand Down Expand Up @@ -816,24 +830,22 @@ public void statisticPRNGExamples() {
// This test case corresponds to the following project in BragaCryptoBench:
// https://bitbucket.org/alexmbraga/cryptomisuses/src/master/cai/undefinedCSP/
@Test
@Ignore
public void undefinedCSPExamples() {
String mavenProjectPath = new File("../CryptoAnalysisTargets/BragaCryptoBench/cryptomisuses/undefinedCSP").getAbsolutePath();
MavenProject mavenProject = createAndCompile(mavenProjectPath);
HeadlessCryptoScanner scanner = createScanner(mavenProject);

setErrorsCount("<cai.undefinedCSP.UndefinedProvider1: void main(java.lang.String[])>", IncompleteOperationError.class, 3);
setErrorsCount("<cai.undefinedCSP.UndefinedProvider2: void main(java.lang.String[])>", IncompleteOperationError.class, 3);
setErrorsCount("<cai.undefinedCSP.UndefinedProvider2: void main(java.lang.String[])>", ConstraintError.class, 2);
setErrorsCount(RequiredPredicateError.class, new FalsePositives(1, ""), "<cai.undefinedCSP.UndefinedProvider3: void main(java.lang.String[])>");
setErrorsCount("<cai.undefinedCSP.UndefinedProvider4: void main(java.lang.String[])>", IncompleteOperationError.class, 2);
setErrorsCount("<cai.undefinedCSP.UndefinedProvider3: void main(java.lang.String[])>", RequiredPredicateError.class, 1);
setErrorsCount("<cai.undefinedCSP.UndefinedProvider4: void main(java.lang.String[])>", IncompleteOperationError.class, 4);
setErrorsCount("<cai.undefinedCSP.UndefinedProvider5: void main(java.lang.String[])>", IncompleteOperationError.class, 3);
setErrorsCount("<cai.undefinedCSP.UndefinedProvider6: void main(java.lang.String[])>", ConstraintError.class, 1);
setErrorsCount("<cai.undefinedCSP.UndefinedProvider6: void main(java.lang.String[])>", TypestateError.class, 1);
setErrorsCount("<cai.undefinedCSP.UndefinedProvider7: void main(java.lang.String[])>", TypestateError.class, 1);
setErrorsCount("<cai.undefinedCSP.UndefinedProvider7: void main(java.lang.String[])>", RequiredPredicateError.class, 1);
setErrorsCount("<cai.undefinedCSP.UndefinedProvider7: void main(java.lang.String[])>", ConstraintError.class, 1);
setErrorsCount("<cai.undefinedCSP.UndefinedProvider8: void main(java.lang.String[])>", TypestateError.class, 2);
setErrorsCount("<cai.undefinedCSP.UndefinedProvider7: void main(java.lang.String[])>", RequiredPredicateError.class, 3);
setErrorsCount("<cai.undefinedCSP.UndefinedProvider7: void main(java.lang.String[])>", ConstraintError.class, 2);
setErrorsCount("<cai.undefinedCSP.UndefinedProvider8: void main(java.lang.String[])>", ConstraintError.class, 1);
setErrorsCount("<cai.undefinedCSP.UndefinedProvider8: void main(java.lang.String[])>", RequiredPredicateError.class, 2);
setErrorsCount("<cai.undefinedCSP.UndefinedProvider8: void main(java.lang.String[])>", IncompleteOperationError.class, 4);

Expand Down Expand Up @@ -932,23 +944,22 @@ public void weakConfigsRSAExamples() {
// positive test case
setErrorsCount("<pkc.enc.weakConfigsRSA.ImproperConfigRSA_3072x160_1: void positiveTestCase()>", TypestateError.class, 1);
setErrorsCount("<pkc.enc.weakConfigsRSA.ImproperConfigRSA_3072x160_1: void positiveTestCase()>", ConstraintError.class, 0);
setErrorsCount("<pkc.enc.weakConfigsRSA.ImproperConfigRSA_3072x160_1: void positiveTestCase()>", RequiredPredicateError.class, 1);
setErrorsCount("<pkc.enc.weakConfigsRSA.ImproperConfigRSA_3072x160_1: void positiveTestCase()>", RequiredPredicateError.class, 0);

// negative test case
setErrorsCount("<pkc.enc.weakConfigsRSA.ImproperConfigRSA_3072x160_1: void negativeTestCase()>", TypestateError.class, 1);
setErrorsCount("<pkc.enc.weakConfigsRSA.ImproperConfigRSA_3072x160_1: void negativeTestCase()>", ConstraintError.class, 1);
setErrorsCount("<pkc.enc.weakConfigsRSA.ImproperConfigRSA_3072x160_1: void negativeTestCase()>", RequiredPredicateError.class, 3);
setErrorsCount("<pkc.enc.weakConfigsRSA.ImproperConfigRSA_3072x160_1: void negativeTestCase()>", RequiredPredicateError.class, 2);

// positive test case
setErrorsCount("<pkc.enc.weakConfigsRSA.ImproperConfigRSA_4096x160_1: void positiveTestCase()>", TypestateError.class, 1);
setErrorsCount("<pkc.enc.weakConfigsRSA.ImproperConfigRSA_4096x160_1: void positiveTestCase()>", ConstraintError.class, 0);
// TODO This is wrong: KeyPair should ensure generatedKey[..] for Cipher
setErrorsCount("<pkc.enc.weakConfigsRSA.ImproperConfigRSA_4096x160_1: void positiveTestCase()>", RequiredPredicateError.class, 1);
setErrorsCount("<pkc.enc.weakConfigsRSA.ImproperConfigRSA_4096x160_1: void positiveTestCase()>", RequiredPredicateError.class, 0);

// negative test case
setErrorsCount("<pkc.enc.weakConfigsRSA.ImproperConfigRSA_4096x160_1: void negativeTestCase()>", TypestateError.class, 1);
setErrorsCount("<pkc.enc.weakConfigsRSA.ImproperConfigRSA_4096x160_1: void negativeTestCase()>", ConstraintError.class, 1);
setErrorsCount("<pkc.enc.weakConfigsRSA.ImproperConfigRSA_4096x160_1: void negativeTestCase()>", RequiredPredicateError.class, 3);
setErrorsCount("<pkc.enc.weakConfigsRSA.ImproperConfigRSA_4096x160_1: void negativeTestCase()>", RequiredPredicateError.class, 2);

scanner.exec();
assertErrors();
Expand All @@ -957,7 +968,6 @@ public void weakConfigsRSAExamples() {
// This test case corresponds to the following project in BragaCryptoBench:
// https://bitbucket.org/alexmbraga/cryptomisuses/src/master/pkc/sign/weakSignatureECDSA/
@Test
@Ignore
public void weakSignatureECDSAExamples() {
String mavenProjectPath = new File("../CryptoAnalysisTargets/BragaCryptoBench/cryptomisuses/weakSignatureECDSA").getAbsolutePath();
MavenProject mavenProject = createAndCompile(mavenProjectPath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,65 @@

public final class NonAuthenticatedDH_2048 {

public static void main(String argv[]) {
/**
* Original test with updated constraints:
* apg.init(2048) -> apg.init(3072)
*/
public void positiveTestCase() {
try {
AlgorithmParameterGenerator apg = AlgorithmParameterGenerator.getInstance("DH", "SunJCE");
apg.init(3072);
AlgorithmParameters p = apg.generateParameters();
DHParameterSpec dhps = (DHParameterSpec) p.getParameterSpec(DHParameterSpec.class);

KeyPairGenerator kpg1 = KeyPairGenerator.getInstance("DH", "SunJCE");
kpg1.initialize(dhps);
KeyPair kp1 = kpg1.generateKeyPair();

KeyAgreement ka1 = KeyAgreement.getInstance("DH", "SunJCE");
ka1.init(kp1.getPrivate());

byte[] pubKey1 = kp1.getPublic().getEncoded();

KeyFactory kf1 = KeyFactory.getInstance("DH", "SunJCE");
X509EncodedKeySpec x509ks = new X509EncodedKeySpec(pubKey1);
PublicKey apk1 = kf1.generatePublic(x509ks);

DHParameterSpec dhps2 = ((DHPublicKey) apk1).getParams();

KeyPairGenerator kpg2 = KeyPairGenerator.getInstance("DH", "SunJCE");
kpg2.initialize(dhps2);
KeyPair kp2 = kpg2.generateKeyPair();

KeyAgreement ka2 = KeyAgreement.getInstance("DH", "SunJCE");
ka2.init(kp2.getPrivate());

byte[] pubKey2 = kp2.getPublic().getEncoded();

KeyFactory kf2 = KeyFactory.getInstance("DH", "SunJCE");
x509ks = new X509EncodedKeySpec(pubKey2);
PublicKey apk2 = kf2.generatePublic(x509ks);
ka1.doPhase(apk2, true);
byte[] secretKey1 = ka1.generateSecret();

ka2.doPhase(apk1, true);
byte[] secretKey2 = ka2.generateSecret();

if (!Arrays.equals(secretKey1, secretKey2)) {
throw new Exception("Shared secrets differ");
}

} catch (Exception e) {}
}

/**
* Original test without any changes
*/
public void negativeTestCase() {
try {
AlgorithmParameterGenerator apg = AlgorithmParameterGenerator.getInstance("DH", "SunJCE");

// Since 3.0.1: size of 2048 is not allowed
apg.init(2048);
AlgorithmParameters p = apg.generateParameters();
DHParameterSpec dhps = (DHParameterSpec) p.getParameterSpec(DHParameterSpec.class);
Expand Down
Loading

0 comments on commit 2228dce

Please sign in to comment.