-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add crysl components from CryptoAnalysis to this repository
- Loading branch information
Showing
42 changed files
with
3,234 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
<parent> | ||
<groupId>de.darmstadt.tu.crossing.CrySL</groupId> | ||
<artifactId>de.darmstadt.tu.crossing.CrySL.parent</artifactId> | ||
<version>3.0.2</version> | ||
<relativePath>../pom.xml</relativePath> | ||
</parent> | ||
|
||
<artifactId>CrySLParser</artifactId> | ||
|
||
<name>CrySL-Parser</name> | ||
<description>CrySL domain-specific language</description> | ||
<url>https://github.com/CROSSINGTUD/CryptSL</url> | ||
|
||
<licenses> | ||
<license> | ||
<name>Eclipse Public License - v2.0</name> | ||
<url>https://www.eclipse.org/legal/epl-2.0/</url> | ||
</license> | ||
</licenses> | ||
|
||
<developers> | ||
<developer> | ||
<id>CogniCrypt</id> | ||
<name>CogniCrypt</name> | ||
<email>[email protected]</email> | ||
</developer> | ||
</developers> | ||
|
||
<scm> | ||
<connection>scm:git:[email protected]:CROSSINGTUD/CryptSL.git</connection> | ||
<developerConnection>scm:git:ssh://github.com:CROSSINGTUD/CryptSL.git</developerConnection> | ||
<url>https://github.com/CROSSINGTUD/CryptSL</url> | ||
</scm> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>${project.groupId}</groupId> | ||
<artifactId>de.darmstadt.tu.crossing.CrySL</artifactId> | ||
<version>${project.version}</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.eclipse.xtext</groupId> | ||
<artifactId>org.eclipse.xtext</artifactId> | ||
<version>${xtextVersion}</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.eclipse.xtext</groupId> | ||
<artifactId>org.eclipse.xtext.xbase</artifactId> | ||
<version>${xtextVersion}</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.eclipse.xtext</groupId> | ||
<artifactId>org.eclipse.xtext.common.types</artifactId> | ||
<version>${xtextVersion}</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.eclipse.emf</groupId> | ||
<artifactId>org.eclipse.emf.common</artifactId> | ||
<version>${emfVersion}</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.eclipse.emf</groupId> | ||
<artifactId>org.eclipse.emf.ecore</artifactId> | ||
<version>${emfVersion}</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>javax.servlet</groupId> | ||
<artifactId>javax.servlet-api</artifactId> | ||
<version>4.0.1</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.slf4j</groupId> | ||
<artifactId>slf4j-api</artifactId> | ||
<version>2.0.16</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.slf4j</groupId> | ||
<artifactId>slf4j-simple</artifactId> | ||
<version>2.0.16</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>junit</groupId> | ||
<artifactId>junit</artifactId> | ||
<version>4.13.2</version> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
</project> |
192 changes: 192 additions & 0 deletions
192
CryslParser/src/main/java/de/darmstadt/tu/crossing/CrySLParser.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,192 @@ | ||
package de.darmstadt.tu.crossing; | ||
|
||
import de.darmstadt.tu.crossing.parsing.CrySLException; | ||
import de.darmstadt.tu.crossing.parsing.CrySLModelReader; | ||
import de.darmstadt.tu.crossing.rule.CrySLRule; | ||
import java.io.File; | ||
import java.io.FileNotFoundException; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.io.RandomAccessFile; | ||
import java.security.MessageDigest; | ||
import java.security.NoSuchAlgorithmException; | ||
import java.util.Arrays; | ||
import java.util.Collection; | ||
import java.util.Enumeration; | ||
import java.util.HashSet; | ||
import java.util.zip.ZipEntry; | ||
import java.util.zip.ZipFile; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
public class CrySLParser { | ||
|
||
private static final Logger LOGGER = LoggerFactory.getLogger(CrySLParser.class); | ||
private static final String CRYSL_FILE_ENDING = ".crysl"; | ||
|
||
/** | ||
* Reads the rules from a specific path. The path can either direct to a directory containing | ||
* the .crysl files or a .zip file. | ||
* | ||
* @param path path to a directory or .zip file containing the .crysl files | ||
* @return the {@link CrySLRule} objects from the path | ||
* @throws IOException if there are problems reading the files | ||
*/ | ||
public Collection<CrySLRule> parseRulesFromPath(String path) throws IOException { | ||
if (isZipFile(path)) { | ||
return parseRulesFromZipArchive(path); | ||
} | ||
|
||
return parseRulesFromDirectory(path); | ||
} | ||
|
||
public Collection<CrySLRule> parseRulesFromDirectory(String path) throws IOException { | ||
File directory = new File(path); | ||
if (!directory.exists()) { | ||
throw new FileNotFoundException("Directory " + path + " does not exist"); | ||
} | ||
|
||
if (!directory.isDirectory()) { | ||
throw new IOException(path + " is not a directory"); | ||
} | ||
|
||
Collection<File> files = Arrays.asList(directory.listFiles()); | ||
return parseRulesFromFiles(files); | ||
} | ||
|
||
public Collection<CrySLRule> parseRulesFromFiles(Collection<File> files) { | ||
Collection<CrySLRule> result = new HashSet<>(); | ||
|
||
for (File file : files) { | ||
try { | ||
CrySLRule rule = parseRuleFromFile(file); | ||
|
||
if (result.contains(rule)) { | ||
LOGGER.warn("Rule for class {} appears multiple times", rule.getClassName()); | ||
continue; | ||
} | ||
|
||
result.add(rule); | ||
} catch (CrySLException e) { | ||
LOGGER.error(e.getMessage()); | ||
} | ||
} | ||
return result; | ||
} | ||
|
||
public CrySLRule parseRuleFromFile(File file) throws CrySLException { | ||
String fileName = file.getName(); | ||
if (!fileName.endsWith(CRYSL_FILE_ENDING)) { | ||
throw new CrySLException( | ||
"The extension of " + fileName + " does not match " + CRYSL_FILE_ENDING); | ||
} | ||
|
||
CrySLModelReader modelReader = new CrySLModelReader(); | ||
return modelReader.readRule(file); | ||
} | ||
|
||
private boolean isZipFile(String path) { | ||
File file = new File(path); | ||
|
||
// Copied from | ||
// https://stackoverflow.com/questions/33934178/how-to-identify-a-zip-file-in-java | ||
int fileSignature; | ||
|
||
try (RandomAccessFile raf = new RandomAccessFile(file, "r")) { | ||
fileSignature = raf.readInt(); | ||
} catch (IOException e) { | ||
return false; | ||
} | ||
return fileSignature == 0x504B0304 | ||
|| fileSignature == 0x504B0506 | ||
|| fileSignature == 0x504B0708; | ||
} | ||
|
||
public Collection<CrySLRule> parseRulesFromZipArchive(String path) throws IOException { | ||
Collection<CrySLRule> result = new HashSet<>(); | ||
File file = new File(path); | ||
|
||
try (ZipFile zipFile = new ZipFile(file)) { | ||
Enumeration<? extends ZipEntry> entries = zipFile.entries(); | ||
|
||
while (entries.hasMoreElements()) { | ||
ZipEntry entry = entries.nextElement(); | ||
|
||
if (entry.isDirectory()) { | ||
continue; | ||
} | ||
|
||
try { | ||
CrySLRule rule = parseRuleFromZipEntry(entry, zipFile, file); | ||
result.add(rule); | ||
} catch (CrySLException e) { | ||
LOGGER.error(e.getMessage()); | ||
} | ||
} | ||
} | ||
return result; | ||
} | ||
|
||
private CrySLRule parseRuleFromZipEntry(ZipEntry entry, ZipFile zipFile, File file) | ||
throws CrySLException { | ||
String entryName = entry.getName(); | ||
if (entry.isDirectory() || !entryName.endsWith(CRYSL_FILE_ENDING)) { | ||
throw new CrySLException("ZIP entry " + entryName + " is not a CrySL file"); | ||
} | ||
|
||
try { | ||
String name = createUniqueZipEntryName(file, entry); | ||
CrySLModelReader reader = new CrySLModelReader(); | ||
|
||
InputStream inputStream = zipFile.getInputStream(entry); | ||
CrySLRule rule = reader.readRule(inputStream, name); | ||
inputStream.close(); | ||
|
||
return rule; | ||
} catch (IOException ex) { | ||
throw new CrySLException( | ||
"Could not read file " | ||
+ entry.getName() | ||
+ " from Zip archive " | ||
+ ex.getMessage()); | ||
} | ||
} | ||
|
||
/** | ||
* For zip file entries there is no real URI. Using the raw absolute path of the zip file will | ||
* cause an exception when trying to resolve/create the resource in the {@link | ||
* CrySLModelReader#readRule(File)} methods. Solution: Create a custom URI with the following | ||
* scheme: uri := [HexHashedAbsoluteZipFilePath][SystemFileSeparator][ZipEntryName] This scheme | ||
* has the properties that it still is unique system-wide, The hash will be the same for the | ||
* same file, so you could know if two rules come from the same ruleset file, and you still can | ||
* get the information of the zipped file. | ||
* | ||
* @param zipFile the File that holds the zip archive | ||
* @param zipEntry the Zip entry to create the name for | ||
* @return the unique name | ||
*/ | ||
private static String createUniqueZipEntryName(File zipFile, ZipEntry zipEntry) { | ||
StringBuilder sb = new StringBuilder(); | ||
|
||
MessageDigest messageDigest; | ||
try { | ||
messageDigest = MessageDigest.getInstance("SHA-256"); | ||
} catch (NoSuchAlgorithmException e) { | ||
throw new RuntimeException(e); | ||
} | ||
messageDigest.update(zipFile.getAbsolutePath().getBytes()); | ||
byte[] updatedFileName = messageDigest.digest(zipFile.getAbsolutePath().getBytes()); | ||
|
||
String partFileName = bytesToHex(updatedFileName); | ||
sb.append(partFileName); | ||
sb.append(File.separator); | ||
sb.append(zipEntry.getName()); | ||
return sb.toString(); | ||
} | ||
|
||
private static String bytesToHex(byte[] bytes) { | ||
StringBuilder sb = new StringBuilder(); | ||
for (byte b : bytes) sb.append(String.format("%02x", b)); | ||
return sb.toString(); | ||
} | ||
} |
Oops, something went wrong.