Skip to content

Commit

Permalink
Fix error in reading a ruleset directory
Browse files Browse the repository at this point in the history
  • Loading branch information
smeyer198 committed Nov 28, 2023
1 parent 16ea989 commit 30ca589
Show file tree
Hide file tree
Showing 9 changed files with 95 additions and 119 deletions.
11 changes: 5 additions & 6 deletions CryptoAnalysis/src/main/java/crypto/HeadlessCryptoScanner.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,22 +85,21 @@ protected String applicationClassPath() {

@Override
protected List<CrySLRule> getRules() {
// TODO: Somehow optimize the rule getting because this has many code duplicates for no reason.
switch(settings.getRulesetPathType()) {
case DIR:
try {
rules.addAll(CrySLRuleReader.readFromDirectory(new File(settings.getRulesetPathDir())));
rulesetRootPath = settings.getRulesetPathDir().substring(0, settings.getRulesetPathDir().lastIndexOf(File.separator));
} catch (CryptoAnalysisException e) {
LOGGER.error("Error happened when getting the CrySL rules from the specified directory: "+settings.getRulesetPathDir(), e);
LOGGER.error("Error happened when getting the CrySL rules from the specified directory: " + settings.getRulesetPathDir(), e);
}
break;
case ZIP:
try {
rules.addAll(CrySLRuleReader.readFromZipFile(new File(settings.getRulesetPathZip())));
rulesetRootPath = settings.getRulesetPathZip().substring(0, settings.getRulesetPathZip().lastIndexOf(File.separator));
} catch (CryptoAnalysisException e) {
LOGGER.error("Error happened when getting the CrySL rules from the specified file: "+settings.getRulesetPathZip(), e);
LOGGER.error("Error happened when getting the CrySL rules from the specified file: " + settings.getRulesetPathZip(), e);
}
break;
default:
Expand Down Expand Up @@ -274,13 +273,13 @@ public Debugger<TransitionFunction> debugger(IDEALSeedSolver<TransitionFunction>
rules.clear();
switch(settings.getRulesetPathType()) {
case DIR:
rules.addAll(providerDetection.chooseRules(rulesetRootPath+File.separator+detectedProvider));
rules.addAll(providerDetection.chooseRules(rulesetRootPath + File.separator + detectedProvider));
break;
case ZIP:
rules.addAll(providerDetection.chooseRulesZip(rulesetRootPath+File.separator+detectedProvider+".zip"));
rules.addAll(providerDetection.chooseRulesZip(rulesetRootPath + File.separator + detectedProvider + ".zip"));
break;
default:
rules.addAll(providerDetection.chooseRules(rulesetRootPath+File.separator+detectedProvider));
rules.addAll(providerDetection.chooseRules(rulesetRootPath + File.separator + detectedProvider));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package crypto.analysis;

import java.io.File;
import java.util.Arrays;
import java.util.List;

import org.slf4j.Logger;
Expand Down Expand Up @@ -88,14 +89,10 @@ public static List<CrySLRule> makeFromRulesetString(String rulesBasePath, RuleFo
}

private static List<CrySLRule> getRulesset(String rulesBasePath, RuleFormat ruleFormat, Ruleset s) throws CryptoAnalysisException {
List<CrySLRule> rules = Lists.newArrayList();
File[] listFiles = new File(rulesBasePath + s + "/").listFiles();
for (File file : listFiles) {
CrySLRule rule = CrySLRuleReader.readFromSourceFile(file);
if(rule != null) {
rules.add(rule);
}
}
List<File> files = Arrays.asList(listFiles);

List<CrySLRule> rules = CrySLRuleReader.readFromSourceFiles(files);

if (rules.isEmpty()) {
throw new CryptoAnalysisException("No CrySL rules found in " + rulesBasePath+s+"/");
Expand All @@ -116,10 +113,12 @@ private static List<CrySLRule> getRulesset(String rulesBasePath, RuleFormat rule
*/
public static CrySLRule makeSingleRule(String rulesBasePath, RuleFormat ruleFormat, Ruleset ruleset, String rulename) throws CryptoAnalysisException {
File file = new File(rulesBasePath + "/" + ruleset + "/" + rulename + RuleFormat.SOURCE);

if (file.exists() && file.isFile()) {
CrySLRule rule = CrySLRuleReader.readFromSourceFile(file);

if(rule != null) {
return rule;
return rule;
} else {
throw new CryptoAnalysisException("CrySL rule couldn't created from path " + file.getAbsolutePath());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,36 +1,31 @@
package crypto.cryslhandler;

import java.io.File;
import java.io.InputStream;
import java.io.IOException;

import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.stream.Collectors;

import com.google.common.base.CharMatcher;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.inject.Injector;

import org.apache.commons.lang3.NotImplementedException;

import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.xtext.common.types.access.impl.ClasspathTypeProvider;
import org.eclipse.xtext.diagnostics.Severity;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.xtext.common.types.JvmDeclaredType;
import org.eclipse.xtext.common.types.JvmTypeReference;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.common.types.access.impl.ClasspathTypeProvider;
import org.eclipse.xtext.diagnostics.Severity;
import org.eclipse.xtext.linking.lazy.LazyLinkingResource;
import org.eclipse.xtext.resource.XtextResourceSet;
import org.eclipse.xtext.util.CancelIndicator;
import org.eclipse.xtext.validation.CheckMode;
Expand All @@ -39,6 +34,11 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.CharMatcher;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.inject.Injector;

import crypto.exceptions.CryptoAnalysisException;
import crypto.interfaces.ICrySLPredicateParameter;
import crypto.interfaces.ISLConstraint;
Expand All @@ -59,7 +59,7 @@
import crypto.rules.StateMachineGraph;
import crypto.rules.StateNode;
import crypto.rules.TransitionEdge;

import de.darmstadt.tu.crossing.CrySLStandaloneSetup;
import de.darmstadt.tu.crossing.crySL.AlternativeRequiredPredicates;
import de.darmstadt.tu.crossing.crySL.BuiltinPredicate;
import de.darmstadt.tu.crossing.crySL.ConditionalPredicate;
Expand Down Expand Up @@ -87,7 +87,6 @@
import de.darmstadt.tu.crossing.crySL.PredicateParameter;
import de.darmstadt.tu.crossing.crySL.RequiredPredicate;
import de.darmstadt.tu.crossing.crySL.RequiresBlock;
import de.darmstadt.tu.crossing.CrySLStandaloneSetup;
import de.darmstadt.tu.crossing.crySL.ThisPredicateParameter;
import de.darmstadt.tu.crossing.crySL.TimedPredicate;
import de.darmstadt.tu.crossing.crySL.WildcardPredicateParameter;
Expand All @@ -106,12 +105,6 @@ public class CrySLModelReader {
private static final String NULL = "null";
private static final String UNDERSCORE = "_";

/**
* For some reason, xtext is not able to resolve a call to 'getEncoded()' for the class java.security.key
* and its subclasses. In these cases, we have to manually resolve the call
*/
private static final Set<String> buggedKeyRules = new HashSet<>(Arrays.asList("java.security.Key", "javax.crypto.SecretKey", "java.security.PublicKey", "java.security.PrivateKey"));

/**
* Creates a CrySLModelReader
* @throws MalformedURLException If there is a problem with the URL
Expand All @@ -131,7 +124,41 @@ public CrySLModelReader() throws MalformedURLException {
URLClassLoader ucl = new URLClassLoader(classpath);
this.resourceSet.setClasspathURIContext(new URLClassLoader(classpath));
new ClasspathTypeProvider(ucl, this.resourceSet, null, null);
this.resourceSet.addLoadOption(XtextResource.OPTION_RESOLVE_ALL, Boolean.TRUE);
}

/**
* Read the crysl rules from all given files.
*
* @param files a list of files to read from
* @return the list with the parsed CrySLRules
* @throws CryptoAnalysisException If a file cannot be read or there is a problem with a rule
*/
public List<CrySLRule> readRulesFromFiles(List<File> files) throws CryptoAnalysisException {
Map<String, CrySLRule> ruleMap = new HashMap<String, CrySLRule>();

for (File file : files) {
resourceSet.getResource(URI.createFileURI(file.getAbsolutePath()), true);
}

EcoreUtil.resolveAll(resourceSet);

for (Resource resource : resourceSet.getResources()) {
if (resource == null) {
continue;
}

if (!(resource instanceof LazyLinkingResource)) {
continue;
}

CrySLRule rule = createRuleFromResource(resource);

if (!ruleMap.containsKey(rule.getClassName())) {
ruleMap.put(rule.getClassName(), rule);
}
}

return new ArrayList<>(ruleMap.values());
}

/**
Expand Down Expand Up @@ -219,20 +246,13 @@ private CrySLRule createRuleFromResource(Resource resource) throws CryptoAnalysi
throw new CryptoAnalysisException("Internal error creating a CrySL rule: 'resource parameter was null'.");
}

String currentClass = ((Domainmodel)resource.getContents().get(0)).getJavaType().getQualifiedName();

if (runValidator(resource, Severity.WARNING)) {
if (buggedKeyRules.contains(currentClass)) {
LOGGER.info("Class " + currentClass + " is of type java.security.key. The call to 'getEncoded()' will be resolved manually.");
} else {
throw new CryptoAnalysisException("Skipping rule since it contains errors: " + resource.getURI());
}
throw new CryptoAnalysisException("Skipping rule since it contains errors: " + resource.getURI());
}

try {
return createRuleFromDomainmodel((Domainmodel) resource.getContents().get(0));
} catch (Exception e) {
e.printStackTrace();
throw new CryptoAnalysisException("An error occured while reading the rule " + resource.getURI(), e);
}
}
Expand Down Expand Up @@ -616,10 +636,6 @@ private ISLConstraint getBuiltinPredicate(BuiltinPredicate builtinPredicate) {
}
return new CrySLPredicate(null, name, parameters, negated);
}

public static Set<String> getBuggedKeyRules() {
return buggedKeyRules;
}

public static String filterQuotes(final String dirty) {
return CharMatcher.anyOf("\"").removeFrom(dirty);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,27 +205,8 @@ private SubStateMachine buildSubSMG(final Order order, final Set<StateNode> star
StateNode node = this.result.createNewNode();
List<CrySLMethod> label = CrySLReaderUtils.resolveEventToCryslMethods(event);

/**
* In some scenarios, xtext is not able to resolve the JVMExecutable 'getEncoded()' from the
* class java.security.Key or its subclasses. In these cases, xtext defaults to the constructor.
* However, these classes have no constructors, since they are interfaces. To deal with the problem,
* we manually change the constructor call to the 'getEncoded()' call.
*/
List<CrySLMethod> updatedLabels = new ArrayList<>(label);

for (CrySLMethod method : label) {
if (CrySLModelReader.getBuggedKeyRules().contains(method.getMethodName())) {
String updatedLabel = method.getMethodName() + ".getEncoded";
CrySLMethod updatedMethod = new CrySLMethod(updatedLabel, method.getParameters(), method.getRetObject());

updatedLabels.add(updatedMethod);
} else {
updatedLabels.add(method);
}
}

for (StateNode startNode : startNodes) {
this.result.createNewEdge(updatedLabels, startNode, node);
this.result.createNewEdge(label, startNode, node);
}

return new SubStateMachine(node, node);
Expand Down
51 changes: 22 additions & 29 deletions CryptoAnalysis/src/main/java/crypto/rules/CrySLRuleReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,10 @@ public class CrySLRuleReader {
private static CrySLModelReader csmr;

private static CrySLModelReader getReader(){
if (csmr == null)
{
try {
csmr = new CrySLModelReader();
}
catch (MalformedURLException e){
e.printStackTrace();
}
try {
csmr = new CrySLModelReader();
} catch (MalformedURLException e) {
e.printStackTrace();
}
return csmr;
}
Expand All @@ -45,6 +41,17 @@ private static CrySLModelReader getReader(){
public static CrySLRule readFromSourceFile(File file) throws CryptoAnalysisException {
return getReader().readRule(file);
}

/**
* Returns a list with {@link CrySLRule} objects from the files.
*
* @param files The files to read from
* @return The list with {@link CrySLRule} objects
* @throws CryptoAnalysisException If a file could not get processed to a {@link CrySLRule}
*/
public static List<CrySLRule> readFromSourceFiles(List<File> files) throws CryptoAnalysisException {
return getReader().readRulesFromFiles(files);
}

/**
* Returns a {@link List} of {@link CrySLRule} objects read from a directory
Expand All @@ -68,26 +75,14 @@ public static List<CrySLRule> readFromDirectory(File directory) throws CryptoAna
* @throws CryptoAnalysisException Throws when a file could not get processed to a {@link CrySLRule}
*/
public static List<CrySLRule> readFromDirectory(File directory, boolean recursive) throws CryptoAnalysisException {
Map<String, CrySLRule> ruleMap = new HashMap<String, CrySLRule>();

if (!directory.exists() || !directory.isDirectory())
throw new CryptoAnalysisException("The specified path is not a directory " + directory.getAbsolutePath());

List<File> cryptSLFiles = new ArrayList<>();
findCryptSLFiles(directory, recursive, cryptSLFiles);
List<File> crySLFiles = new ArrayList<>();
findCrySLFiles(directory, recursive, crySLFiles);

CrySLModelReader reader = getReader();
for (File file : cryptSLFiles) {
CrySLRule rule = reader.readRule(file);

if(rule != null) {
if(!ruleMap.containsKey(rule.getClassName())) {
ruleMap.put(rule.getClassName(), rule);
}
}
}

return new ArrayList<>(ruleMap.values());
return reader.readRulesFromFiles(crySLFiles);
}

/**
Expand Down Expand Up @@ -122,19 +117,17 @@ public static List<CrySLRule> readFromZipFile(File file) throws CryptoAnalysisEx
return new ArrayList<>(ruleMap.values());
}

private static void findCryptSLFiles(File directory, boolean recursive, Collection<File> resultCollection) {
for (File file: directory.listFiles())
{
private static void findCrySLFiles(File directory, boolean recursive, Collection<File> resultCollection) {
for (File file: directory.listFiles()) {
if (file.isFile() && file.getName().endsWith(CrySLModelReader.cryslFileEnding))
resultCollection.add(file);

if (recursive && file.isDirectory())
findCryptSLFiles(file, recursive, resultCollection);
findCrySLFiles(file, recursive, resultCollection);
}
}

private static CrySLRule getCrySLRuleFromZipEntry(ZipEntry entry, ZipFile zip, File zipFile) throws CryptoAnalysisException
{
private static CrySLRule getCrySLRuleFromZipEntry(ZipEntry entry, ZipFile zip, File zipFile) throws CryptoAnalysisException {
if (entry.isDirectory() || !entry.getName().endsWith(CrySLModelReader.cryslFileEnding))
throw new CryptoAnalysisException("ZIP entry is a directory or not a CrySL file");

Expand Down
4 changes: 2 additions & 2 deletions CryptoAnalysis/src/test/java/tests/crysl/ZipCrySLTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
public class ZipCrySLTest {

private static final String emptyZipFilePath = "src/test/resources/crySL/empty.zip";
private static final String jcaRulesetZipFilePath = "src/test/resources/crySL/JavaCryptographicArchitecture-1.5.1-ruleset.zip";
private static final String jcaRulesetZipFilePath = "src/test/resources/crySL/JavaCryptographicArchitecture-3.0.1-ruleset.zip";
private static final String multipleRulesetZipFilePath = "src/test/resources/crySL/Multiple-rulesets.zip";
private static final String junkRuleSet = "src/test/resources/crySL/rulesetWithJunk.zip";

Expand Down Expand Up @@ -61,7 +61,7 @@ public void TestFileNoCrypSLFiles() throws CryptoAnalysisException {
public void TestFileContainsMultipleRulesets() throws CryptoAnalysisException {
File zipFile = new File(multipleRulesetZipFilePath);
Collection<CrySLRule> rules = CrySLRuleReader.readFromZipFile(zipFile);
Assert.assertEquals(107, rules.size());
Assert.assertEquals(108, rules.size());
}

@Test
Expand Down
Loading

0 comments on commit 30ca589

Please sign in to comment.