diff --git a/main/pom.xml b/main/pom.xml
index cfb5ace1a..757794d7d 100644
--- a/main/pom.xml
+++ b/main/pom.xml
@@ -28,6 +28,7 @@
UTF-8
+ 1.0.0-SNAPSHOT
2.1
1.7.7
4.12
@@ -123,6 +124,13 @@
ui
${project.version}
+
+
+
+ org.cryptomator
+ cryptolib
+ ${cryptolib.version}
+
diff --git a/main/ui/pom.xml b/main/ui/pom.xml
index 2c261d3ad..5515e6d26 100644
--- a/main/ui/pom.xml
+++ b/main/ui/pom.xml
@@ -55,6 +55,12 @@
frontend-webdav
+
+
+ org.cryptomator
+ cryptolib
+
+
org.fxmisc.easybind
diff --git a/main/ui/src/main/java/org/cryptomator/ui/model/UpgradeStrategy.java b/main/ui/src/main/java/org/cryptomator/ui/model/UpgradeStrategy.java
index 6f7f147ce..9d77b93d4 100644
--- a/main/ui/src/main/java/org/cryptomator/ui/model/UpgradeStrategy.java
+++ b/main/ui/src/main/java/org/cryptomator/ui/model/UpgradeStrategy.java
@@ -6,11 +6,11 @@ import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.nio.file.StandardOpenOption;
-import javax.inject.Provider;
-
-import org.cryptomator.crypto.engine.Cryptor;
-import org.cryptomator.crypto.engine.InvalidPassphraseException;
-import org.cryptomator.crypto.engine.UnsupportedVaultFormatException;
+import org.cryptomator.cryptolib.api.Cryptor;
+import org.cryptomator.cryptolib.api.CryptorProvider;
+import org.cryptomator.cryptolib.api.InvalidPassphraseException;
+import org.cryptomator.cryptolib.api.KeyFile;
+import org.cryptomator.cryptolib.api.UnsupportedVaultFormatException;
import org.cryptomator.filesystem.crypto.Constants;
import org.cryptomator.ui.settings.Localization;
import org.slf4j.Logger;
@@ -20,12 +20,16 @@ public abstract class UpgradeStrategy {
private static final Logger LOG = LoggerFactory.getLogger(UpgradeStrategy.class);
- protected final Provider cryptorProvider;
+ protected final CryptorProvider cryptorProvider;
protected final Localization localization;
+ protected final int vaultVersionBeforeUpgrade;
+ protected final int vaultVersionAfterUpgrade;
- UpgradeStrategy(Provider cryptorProvider, Localization localization) {
+ UpgradeStrategy(CryptorProvider cryptorProvider, Localization localization, int vaultVersionBeforeUpgrade, int vaultVersionAfterUpgrade) {
this.cryptorProvider = cryptorProvider;
this.localization = localization;
+ this.vaultVersionBeforeUpgrade = vaultVersionBeforeUpgrade;
+ this.vaultVersionAfterUpgrade = vaultVersionAfterUpgrade;
}
/**
@@ -37,27 +41,29 @@ public abstract class UpgradeStrategy {
* Upgrades a vault. Might take a moment, should be run in a background thread.
*/
public void upgrade(Vault vault, CharSequence passphrase) throws UpgradeFailedException {
- final Cryptor cryptor = cryptorProvider.get();
+ Cryptor cryptor = null;
try {
final Path masterkeyFile = vault.path().getValue().resolve(Constants.MASTERKEY_FILENAME);
final byte[] masterkeyFileContents = Files.readAllBytes(masterkeyFile);
- cryptor.readKeysFromMasterkeyFile(masterkeyFileContents, passphrase);
+ cryptor = cryptorProvider.createFromKeyFile(KeyFile.parse(masterkeyFileContents), passphrase, vaultVersionBeforeUpgrade);
// create backup, as soon as we know the password was correct:
final Path masterkeyBackupFile = vault.path().getValue().resolve(Constants.MASTERKEY_BACKUP_FILENAME);
Files.copy(masterkeyFile, masterkeyBackupFile, StandardCopyOption.REPLACE_EXISTING);
// do stuff:
upgrade(vault, cryptor);
// write updated masterkey file:
- final byte[] upgradedMasterkeyFileContents = cryptor.writeKeysToMasterkeyFile(passphrase);
- final Path masterkeyFileAfterUpgrading = vault.path().getValue().resolve(Constants.MASTERKEY_FILENAME); // path may have changed
- Files.write(masterkeyFileAfterUpgrading, upgradedMasterkeyFileContents, StandardOpenOption.TRUNCATE_EXISTING);
+ final byte[] upgradedMasterkeyFileContents = cryptor.writeKeysToMasterkeyFile(passphrase, vaultVersionAfterUpgrade).serialize();
+ final Path masterkeyFileAfterUpgrade = vault.path().getValue().resolve(Constants.MASTERKEY_FILENAME); // path may have changed
+ Files.write(masterkeyFileAfterUpgrade, upgradedMasterkeyFileContents, StandardOpenOption.TRUNCATE_EXISTING);
} catch (InvalidPassphraseException e) {
throw new UpgradeFailedException(localization.getString("unlock.errorMessage.wrongPassword"));
} catch (IOException | UnsupportedVaultFormatException e) {
LOG.warn("Upgrade failed.", e);
throw new UpgradeFailedException("Upgrade failed. Details in log message.");
} finally {
- cryptor.destroy();
+ if (cryptor != null) {
+ cryptor.destroy();
+ }
}
}
@@ -68,7 +74,21 @@ public abstract class UpgradeStrategy {
*
* @return true if and only if the vault can be migrated to a newer version without the risk of data losses.
*/
- public abstract boolean isApplicable(Vault vault);
+ public boolean isApplicable(Vault vault) {
+ final Path masterkeyFile = vault.path().getValue().resolve(Constants.MASTERKEY_FILENAME);
+ try {
+ if (Files.isRegularFile(masterkeyFile)) {
+ byte[] masterkeyFileContents = Files.readAllBytes(masterkeyFile);
+ return KeyFile.parse(masterkeyFileContents).getVersion() == vaultVersionBeforeUpgrade;
+ } else {
+ LOG.warn("Not a file: {}", masterkeyFile);
+ return false;
+ }
+ } catch (IOException e) {
+ LOG.warn("Could not determine, whether upgrade is applicable.", e);
+ return false;
+ }
+ }
/**
* Thrown when data migration failed.
diff --git a/main/ui/src/main/java/org/cryptomator/ui/model/UpgradeVersion3DropBundleExtension.java b/main/ui/src/main/java/org/cryptomator/ui/model/UpgradeVersion3DropBundleExtension.java
index 04fa63f30..a0462cd65 100644
--- a/main/ui/src/main/java/org/cryptomator/ui/model/UpgradeVersion3DropBundleExtension.java
+++ b/main/ui/src/main/java/org/cryptomator/ui/model/UpgradeVersion3DropBundleExtension.java
@@ -1,19 +1,16 @@
package org.cryptomator.ui.model;
import java.io.IOException;
-import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.security.SecureRandom;
import javax.inject.Inject;
-import javax.inject.Provider;
import javax.inject.Singleton;
import org.apache.commons.lang3.StringUtils;
-import org.cryptomator.crypto.engine.Cryptor;
-import org.cryptomator.crypto.engine.InvalidPassphraseException;
-import org.cryptomator.crypto.engine.UnsupportedVaultFormatException;
-import org.cryptomator.filesystem.crypto.Constants;
+import org.cryptomator.cryptolib.Cryptors;
+import org.cryptomator.cryptolib.api.Cryptor;
import org.cryptomator.ui.settings.Localization;
import org.cryptomator.ui.settings.Settings;
import org.slf4j.Logger;
@@ -28,8 +25,8 @@ class UpgradeVersion3DropBundleExtension extends UpgradeStrategy {
private final Settings settings;
@Inject
- public UpgradeVersion3DropBundleExtension(Provider cryptorProvider, Localization localization, Settings settings) {
- super(cryptorProvider, localization);
+ public UpgradeVersion3DropBundleExtension(SecureRandom secureRandom, Localization localization, Settings settings) {
+ super(Cryptors.version1(secureRandom), localization, 3, 3);
this.settings = settings;
}
@@ -42,25 +39,6 @@ class UpgradeVersion3DropBundleExtension extends UpgradeStrategy {
return String.format(fmt, oldVaultName, newVaultName);
}
- @Override
- public void upgrade(Vault vault, CharSequence passphrase) throws UpgradeFailedException {
- final Cryptor cryptor = cryptorProvider.get();
- try {
- final Path masterkeyFile = vault.path().getValue().resolve(Constants.MASTERKEY_FILENAME);
- final byte[] masterkeyFileContents = Files.readAllBytes(masterkeyFile);
- cryptor.readKeysFromMasterkeyFile(masterkeyFileContents, passphrase);
- upgrade(vault, cryptor);
- // don't write new masterkey. this is a special case, as we were stupid and didn't increase the vault version with this upgrade...
- } catch (InvalidPassphraseException e) {
- throw new UpgradeFailedException(localization.getString("unlock.errorMessage.wrongPassword"));
- } catch (IOException | UnsupportedVaultFormatException e) {
- LOG.warn("Upgrade failed.", e);
- throw new UpgradeFailedException("Upgrade failed. Details in log message.");
- } finally {
- cryptor.destroy();
- }
- }
-
@Override
protected void upgrade(Vault vault, Cryptor cryptor) throws UpgradeFailedException {
Path path = vault.path().getValue();
@@ -73,6 +51,7 @@ class UpgradeVersion3DropBundleExtension extends UpgradeStrategy {
throw new UpgradeFailedException(msg);
} else {
try {
+ LOG.info("Renaming {} to {}", path, newPath.getFileName());
Files.move(path, path.resolveSibling(newVaultName));
Platform.runLater(() -> {
vault.setPath(newPath);
@@ -89,19 +68,7 @@ class UpgradeVersion3DropBundleExtension extends UpgradeStrategy {
public boolean isApplicable(Vault vault) {
Path vaultPath = vault.path().getValue();
if (vaultPath.toString().endsWith(Vault.VAULT_FILE_EXTENSION)) {
- final Path masterkeyFile = vaultPath.resolve(Constants.MASTERKEY_FILENAME);
- try {
- if (Files.isRegularFile(masterkeyFile)) {
- final String keyContents = new String(Files.readAllBytes(masterkeyFile), StandardCharsets.UTF_8);
- return keyContents.contains("\"version\":3") || keyContents.contains("\"version\": 3");
- } else {
- LOG.warn("Not a file: {}", masterkeyFile);
- return false;
- }
- } catch (IOException e) {
- LOG.warn("Could not determine, whether upgrade is applicable.", e);
- return false;
- }
+ return super.isApplicable(vault);
} else {
return false;
}
diff --git a/main/ui/src/main/java/org/cryptomator/ui/model/UpgradeVersion3to4.java b/main/ui/src/main/java/org/cryptomator/ui/model/UpgradeVersion3to4.java
index 51a75b263..17bbcaac1 100644
--- a/main/ui/src/main/java/org/cryptomator/ui/model/UpgradeVersion3to4.java
+++ b/main/ui/src/main/java/org/cryptomator/ui/model/UpgradeVersion3to4.java
@@ -9,19 +9,19 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.inject.Inject;
-import javax.inject.Provider;
import javax.inject.Singleton;
import org.apache.commons.codec.binary.Base32;
import org.apache.commons.codec.binary.BaseNCodec;
import org.apache.commons.lang3.StringUtils;
-import org.cryptomator.crypto.engine.Cryptor;
-import org.cryptomator.filesystem.crypto.Constants;
+import org.cryptomator.cryptolib.Cryptors;
+import org.cryptomator.cryptolib.api.Cryptor;
+import org.cryptomator.cryptolib.common.MessageDigestSupplier;
import org.cryptomator.ui.settings.Localization;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -40,17 +40,12 @@ class UpgradeVersion3to4 extends UpgradeStrategy {
private static final String OLD_FOLDER_SUFFIX = "_";
private static final String NEW_FOLDER_PREFIX = "0";
- private final MessageDigest sha1;
+ private final MessageDigest sha1 = MessageDigestSupplier.SHA1.get();
private final BaseNCodec base32 = new Base32();
@Inject
- public UpgradeVersion3to4(Provider cryptorProvider, Localization localization) {
- super(cryptorProvider, localization);
- try {
- sha1 = MessageDigest.getInstance("SHA-1");
- } catch (NoSuchAlgorithmException e) {
- throw new AssertionError("SHA-1 exists in every JVM");
- }
+ public UpgradeVersion3to4(SecureRandom secureRandom, Localization localization) {
+ super(Cryptors.version1(secureRandom), localization, 3, 4);
}
@Override
@@ -144,21 +139,4 @@ class UpgradeVersion3to4 extends UpgradeStrategy {
}
}
- @Override
- public boolean isApplicable(Vault vault) {
- final Path masterkeyFile = vault.path().getValue().resolve(Constants.MASTERKEY_FILENAME);
- try {
- if (Files.isRegularFile(masterkeyFile)) {
- final String keyContents = new String(Files.readAllBytes(masterkeyFile), UTF_8);
- return keyContents.contains("\"version\":3") || keyContents.contains("\"version\": 3");
- } else {
- LOG.warn("Not a file: {}", masterkeyFile);
- return false;
- }
- } catch (IOException e) {
- LOG.warn("Could not determine, whether upgrade is applicable.", e);
- return false;
- }
- }
-
}