Skip to content
This repository has been archived by the owner on Dec 21, 2021. It is now read-only.

Commit

Permalink
Merge branch 'release/0.9'
Browse files Browse the repository at this point in the history
  • Loading branch information
tobihagemann committed Jan 31, 2017
2 parents 9a2b945 + d92c969 commit f116ed4
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 16 deletions.
26 changes: 13 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
![cryptomator](cryptomator.png)
![sanitizer](sanitizer.png)

**Cryptomator Sanitizer** - Utilities to find and fix problems within vaults
Utility to find and fix problems within vaults.

## Usage

Expand Down Expand Up @@ -35,32 +35,32 @@ Detects problems in Cryptomator vaults.
--vault <vaultPath> On which vault to work.
```

### Examples

You need to have Java 8 and the JCE unlimited strength policy files installed to run this tool.
You need to have Java 8 and JCE unlimited strength policy files installed to run this tool.

You can download these on
* http://www.oracle.com/technetwork/java/javase/downloads/jre8-downloads-2133155.html
* http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html

Install the JCE files following the description in the README.txt file inside the downloaded zip archive.
Install the JCE files following the description in the `README.txt` file inside the downloaded zip archive.

### Examples

When you have everything setup you can run the integrity check from the command line (cmd.exe on Windows) using:
When you have everything set up, you can run the integrity check from the command line (cmd.exe on Windows) using:

```
java -jar sanitizer-0.1.jar --cmd check --vault <pathToYourVault>
java -jar sanitizer-x.y.jar --cmd check --vault <pathToYourVault>
```

You will be asked for the vault passphrase in this case. If that fails you may store your passphrase in a file (without line break at the end!) and use
You will be asked for the vault passphrase in this case. If that fails, you may store your passphrase in a file (without line break at the end!) and use:

```
java -jar sanitizer-0.1.jar --cmd --vault <pathToYourVault> --passphraseFile <pathToThePassphraseFile>
java -jar sanitizer-x.y.jar --cmd --vault <pathToYourVault> --passphraseFile <pathToThePassphraseFile>
```

After completion the tool will print how many problems were found and create two files:
After completion, the tool will print how many problems were found and create two files:

* `<vault name>.structure.txt`: The full structure of the vault including all files and directories. Contains only encrypted names and the size of files < 300b so we can not see your data. This may help us to diagnose issues not already handled by the sanitizer.
* `<vault name>.check.txt`: A list of known issues and some informations. This includes the name of the encrypted root directory. This is useful to check how the root directory looks like when analyzing the structure file.
* `<vault name>.structure.txt`: The full structure of the vault including all files and directories. Contains only encrypted names and the exact size of small and the approximate size of larger ones so we can not see your data. This may help us to diagnose issues not already handled by the sanitizer.
* `<vault name>.check.txt`: A list of known issues and some information. This includes the name of the encrypted root directory. This is useful to check how the root directory looks like when analyzing the structure file.

## Building

Expand Down
Binary file removed cryptomator.png
Binary file not shown.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.cryptomator</groupId>
<artifactId>sanitizer</artifactId>
<version>0.8</version>
<version>0.9</version>
<description>Utilities to find and fix problems within vaults</description>

<properties>
Expand Down
Binary file added sanitizer.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/main/java/org/cryptomator/sanitizer/Args.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@

public class Args {

private static final String[] COMMANDS = new String[] {"check", "deepCheck", "encryptPath"};
private static final String[] COMMANDS = new String[] {"check", "deepCheck", "encryptPath", "decryptFile"};
private static final String USAGE = "java -jar sanitizer-" + Version.get() + ".jar" //
+ " -vault vaultToCheck" //
+ " -cmd " + org.apache.commons.lang3.StringUtils.join(COMMANDS, '|') //
Expand Down
16 changes: 16 additions & 0 deletions src/main/java/org/cryptomator/sanitizer/Sanitizer.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.cryptomator.sanitizer.integrity.problems.Problem;
import org.cryptomator.sanitizer.integrity.problems.Severity;
import org.cryptomator.sanitizer.integrity.problems.SolutionContext;
import org.cryptomator.sanitizer.restorer.FileDecryptor;
import org.cryptomator.sanitizer.restorer.PathEncryptor;
import org.cryptomator.sanitizer.utils.Counter;

Expand All @@ -52,6 +53,9 @@ public static void main(Args args) {
case "encryptpath":
encryptPath(args);
break;
case "decryptfile":
decryptFile(args);
break;
default:
System.err.println("Unknown command");
Args.printUsage();
Expand Down Expand Up @@ -94,6 +98,18 @@ private static void encryptPath(Args args) {
}
}

private static void decryptFile(Args args) {
try (Passphrase passphrase = args.passphrase()) {
FileDecryptor.decryptFile(args.vaultLocation(), passphrase);
} catch (InvalidPassphraseException e) {
System.err.println("Invalid passphrase.");
} catch (AbortCheckException e) {
System.err.println(e.getMessage());
} catch (IOException e) {
System.err.println(e.getMessage());
}
}

private static void maybeSolveProblems(Args args, CryptorHolder cryptorHolder, Set<Problem> problems) {
if (cryptorHolder.optionalCryptor().isPresent()) {
List<Problem> problemsToSolve = problems.stream() //
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package org.cryptomator.sanitizer.restorer;

import java.io.Console;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import org.cryptomator.cryptolib.Cryptors;
import org.cryptomator.cryptolib.api.Cryptor;
import org.cryptomator.cryptolib.api.CryptorProvider;
import org.cryptomator.cryptolib.api.KeyFile;
import org.cryptomator.cryptolib.v1.DecryptingReadableByteChannel;

public class FileDecryptor {

public static void decryptFile(Path vaultLocation, CharSequence passphrase) throws IOException {
Console console = System.console();
if (console == null) {
System.err.println("Couldn't get Console instance");
return;
}

Path masterkeyPath = vaultLocation.resolve("masterkey.cryptomator");
KeyFile keyFile = KeyFile.parse(Files.readAllBytes(masterkeyPath));
Path ciphertextPath = getCiphertextPathFromUser(console);
Path outputPath = getOutputPathFromUser(console);

CryptorProvider provider = bestGuessCryptorProvider(keyFile);
Cryptor cryptor = provider.createFromKeyFile(keyFile, passphrase, keyFile.getVersion());
try (ReadableByteChannel readableByteChannel = Files.newByteChannel(ciphertextPath, StandardOpenOption.READ);
ReadableByteChannel decryptingReadableByteChannel = new DecryptingReadableByteChannel(readableByteChannel, cryptor, true);
WritableByteChannel writableByteChannel = Files.newByteChannel(outputPath, StandardOpenOption.WRITE, StandardOpenOption.CREATE_NEW)) {
ByteBuffer buff = ByteBuffer.allocate(cryptor.fileContentCryptor().ciphertextChunkSize());
while (decryptingReadableByteChannel.read(buff) != -1) {
buff.flip();
writableByteChannel.write(buff);
buff.clear();
}
} finally {
cryptor.destroy();
}

console.printf("File successfully decrypted.\n");
}

private static Path getCiphertextPathFromUser(Console console) throws NoSuchFileException {
String ciphertextPath = console.readLine("Enter absolute path of an encrypted file: ");
Path result = Paths.get(ciphertextPath);
if (!result.isAbsolute()) {
throw new IllegalArgumentException("Given path is not absolute.");
} else if (Files.isRegularFile(result)) {
return result;
} else {
throw new NoSuchFileException("No such file: " + result.toString());
}
}

private static Path getOutputPathFromUser(Console console) throws NoSuchFileException {
String outputPath = console.readLine("Enter absolute path of decrypted output: ");
Path result = Paths.get(outputPath);
if (!result.isAbsolute()) {
throw new IllegalArgumentException("Given path is not absolute.");
} else {
return result;
}
}

private static CryptorProvider bestGuessCryptorProvider(KeyFile keyFile) {
switch (keyFile.getVersion()) {
case 1:
case 2:
case 3:
case 4:
case 5:
return Cryptors.version1(strongSecureRandom());
default:
throw new IllegalArgumentException("Unsupported vault version " + keyFile.getVersion());
}
}

private static SecureRandom strongSecureRandom() {
try {
return SecureRandom.getInstanceStrong();
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("Java platform is required to support a strong SecureRandom.", e);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public static void encryptPath(Path vaultLocation, CharSequence passphrase) thro
Cryptor cryptor = provider.createFromKeyFile(keyFile, passphrase, keyFile.getVersion());

Path filePath = resolvePath(vaultLocation, console, cryptor);
console.printf("Resolved: %s", filePath);
console.printf("Resolved: %s\n", filePath);

cryptor.destroy();
}
Expand Down

0 comments on commit f116ed4

Please sign in to comment.