mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-22 04:31:27 +00:00
recoverykey validate
This commit is contained in:
@@ -14,7 +14,9 @@ import org.cryptomator.cryptolib.api.CryptoException;
|
||||
import org.cryptomator.cryptolib.api.Cryptor;
|
||||
import org.cryptomator.cryptolib.api.CryptorProvider;
|
||||
import org.cryptomator.cryptolib.api.Masterkey;
|
||||
import org.cryptomator.cryptolib.common.MasterkeyFileAccess;
|
||||
import org.cryptomator.integrations.mount.MountService;
|
||||
import org.cryptomator.ui.addvaultwizard.CreateNewVaultExpertSettingsController;
|
||||
import org.cryptomator.ui.changepassword.NewPasswordController;
|
||||
import org.cryptomator.ui.dialogs.Dialogs;
|
||||
import org.cryptomator.ui.fxapp.FxApplicationWindows;
|
||||
@@ -23,6 +25,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javafx.beans.property.IntegerProperty;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.concurrent.Task;
|
||||
import javafx.scene.Scene;
|
||||
@@ -39,6 +42,7 @@ import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
import org.cryptomator.cryptolib.api.MasterkeyLoader;
|
||||
|
||||
import static org.cryptomator.common.Constants.DEFAULT_KEY_ID;
|
||||
import static org.cryptomator.common.Constants.MASTERKEY_FILENAME;
|
||||
@@ -54,7 +58,11 @@ public class RecoverUtil {
|
||||
|
||||
public static CryptorProvider.Scheme detectCipherCombo(byte[] masterkey, Path pathToVault) {
|
||||
try (Stream<Path> paths = Files.walk(pathToVault.resolve(DATA_DIR_NAME))) {
|
||||
return paths.filter(path -> path.toString().endsWith(".c9r")).findFirst().map(c9rFile -> determineScheme(c9rFile, masterkey)).orElseThrow(() -> new IllegalStateException("No .c9r file found."));
|
||||
return paths.filter(path -> path.toString()
|
||||
.endsWith(".c9r"))
|
||||
.findFirst()
|
||||
.map(c9rFile -> determineScheme(c9rFile, masterkey))
|
||||
.orElseThrow(() -> new IllegalStateException("No .c9r file found."));
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Failed to detect cipher combo.", e);
|
||||
}
|
||||
@@ -117,9 +125,30 @@ public class RecoverUtil {
|
||||
return masterkeyFileAccess.load(masterkeyFilePath, password);
|
||||
}
|
||||
|
||||
public static boolean validateRecoveryKey(RecoveryKeyFactory recoveryKeyFactory, Vault vault, StringProperty recoveryKey, MasterkeyFileAccess masterkeyFileAccess) {
|
||||
Path tempRecoveryPath = null;
|
||||
CharSequence tmpPass = "asdasdasd";
|
||||
try {
|
||||
tempRecoveryPath = createRecoveryDirectory(vault.getPath());
|
||||
createNewMasterkeyFile(recoveryKeyFactory, tempRecoveryPath, recoveryKey.get(), tmpPass);
|
||||
Path masterkeyFilePath = tempRecoveryPath.resolve(MASTERKEY_FILENAME);
|
||||
try (Masterkey masterkey = loadMasterkey(masterkeyFileAccess, masterkeyFilePath, tmpPass)) {
|
||||
initializeCryptoFileSystem(tempRecoveryPath, vault.getPath(), masterkey, new SimpleIntegerProperty(CreateNewVaultExpertSettingsController.MAX_SHORTENING_THRESHOLD));
|
||||
return true;
|
||||
}
|
||||
} catch (IOException | CryptoException e) {
|
||||
LOG.warn("Recovery key validation failed", e);
|
||||
return false;
|
||||
} finally {
|
||||
if (tempRecoveryPath != null) {
|
||||
deleteRecoveryDirectory(tempRecoveryPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void initializeCryptoFileSystem(Path recoveryPath, Path vaultPath, Masterkey masterkey, IntegerProperty shorteningThreshold) throws IOException, CryptoException {
|
||||
var combo = RecoverUtil.detectCipherCombo(masterkey.getEncoded(), vaultPath);
|
||||
org.cryptomator.cryptolib.api.MasterkeyLoader loader = ignored -> masterkey.copy();
|
||||
MasterkeyLoader loader = ignored -> masterkey.copy();
|
||||
CryptoFileSystemProperties fsProps = CryptoFileSystemProperties.cryptoFileSystemProperties().withCipherCombo(combo).withKeyLoader(loader).withShorteningThreshold(shorteningThreshold.get()).build();
|
||||
CryptoFileSystemProvider.initialize(recoveryPath, fsProps, DEFAULT_KEY_ID);
|
||||
}
|
||||
@@ -240,7 +269,8 @@ public class RecoverUtil {
|
||||
RESTORE_VAULT_CONFIG,
|
||||
RESTORE_MASTERKEY,
|
||||
RESET_PASSWORD,
|
||||
SHOW_KEY;
|
||||
SHOW_KEY,
|
||||
CONVERT_VAULT;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import dagger.Binds;
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
import dagger.multibindings.IntoMap;
|
||||
import org.cryptomator.common.RecoverUtil;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.cryptofs.VaultConfig;
|
||||
import org.cryptomator.ui.changepassword.NewPasswordController;
|
||||
@@ -20,6 +21,8 @@ import org.cryptomator.ui.recoverykey.RecoveryKeyValidateController;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.scene.Scene;
|
||||
@@ -120,7 +123,7 @@ abstract class ConvertVaultModule {
|
||||
@IntoMap
|
||||
@FxControllerKey(RecoveryKeyValidateController.class)
|
||||
static FxController bindRecoveryKeyValidateController(@ConvertVaultWindow Vault vault, @ConvertVaultWindow VaultConfig.UnverifiedVaultConfig vaultConfig, @ConvertVaultWindow StringProperty recoveryKey, RecoveryKeyFactory recoveryKeyFactory) {
|
||||
return new RecoveryKeyValidateController(vault, vaultConfig, recoveryKey, recoveryKeyFactory);
|
||||
return new RecoveryKeyValidateController(vault, vaultConfig, recoveryKey, recoveryKeyFactory, new SimpleObjectProperty<>(RecoverUtil.Type.CONVERT_VAULT),null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import org.cryptomator.common.Nullable;
|
||||
import org.cryptomator.common.RecoverUtil;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.cryptofs.VaultConfig;
|
||||
import org.cryptomator.cryptolib.common.MasterkeyFileAccess;
|
||||
import org.cryptomator.ui.addvaultwizard.CreateNewVaultExpertSettingsController;
|
||||
import org.cryptomator.ui.common.DefaultSceneFactory;
|
||||
import org.cryptomator.ui.common.FxController;
|
||||
@@ -193,8 +194,8 @@ abstract class RecoveryKeyModule {
|
||||
@Provides
|
||||
@IntoMap
|
||||
@FxControllerKey(RecoveryKeyValidateController.class)
|
||||
static FxController bindRecoveryKeyValidateController(@RecoveryKeyWindow Vault vault, @RecoveryKeyWindow @Nullable VaultConfig.UnverifiedVaultConfig vaultConfig, @RecoveryKeyWindow StringProperty recoveryKey, RecoveryKeyFactory recoveryKeyFactory) {
|
||||
return new RecoveryKeyValidateController(vault, vaultConfig, recoveryKey, recoveryKeyFactory);
|
||||
static FxController bindRecoveryKeyValidateController(@RecoveryKeyWindow Vault vault, @RecoveryKeyWindow @Nullable VaultConfig.UnverifiedVaultConfig vaultConfig, @RecoveryKeyWindow StringProperty recoveryKey, RecoveryKeyFactory recoveryKeyFactory, @Named("recoverType") ObjectProperty<RecoverUtil.Type> recoverType, @Nullable MasterkeyFileAccess masterkeyFileAccess) {
|
||||
return new RecoveryKeyValidateController(vault, vaultConfig, recoveryKey, recoveryKeyFactory, recoverType, masterkeyFileAccess);
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
||||
@@ -48,6 +48,9 @@ public class RecoveryKeyRecoverController implements FxController {
|
||||
window.setTitle(resourceBundle.getString("recoveryKey.display.title"));
|
||||
yield resetPasswordScene;
|
||||
}
|
||||
default -> {
|
||||
yield null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -5,14 +5,17 @@ import com.google.common.base.CharMatcher;
|
||||
import com.google.common.base.Strings;
|
||||
import org.cryptomator.common.Nullable;
|
||||
import org.cryptomator.common.ObservableUtil;
|
||||
import org.cryptomator.common.RecoverUtil;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.cryptofs.VaultConfig;
|
||||
import org.cryptomator.cryptofs.VaultConfigLoadException;
|
||||
import org.cryptomator.cryptofs.VaultKeyInvalidException;
|
||||
import org.cryptomator.cryptolib.common.MasterkeyFileAccess;
|
||||
import org.cryptomator.ui.common.FxController;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
@@ -37,12 +40,19 @@ public class RecoveryKeyValidateController implements FxController {
|
||||
private final RecoveryKeyFactory recoveryKeyFactory;
|
||||
private final ObjectProperty<RecoveryKeyState> recoveryKeyState;
|
||||
private final AutoCompleter autoCompleter;
|
||||
private final ObjectProperty<RecoverUtil.Type> recoverType;
|
||||
private final MasterkeyFileAccess masterkeyFileAccess;
|
||||
|
||||
private volatile boolean isWrongKey;
|
||||
|
||||
public TextArea textarea;
|
||||
|
||||
public RecoveryKeyValidateController(Vault vault, @Nullable VaultConfig.UnverifiedVaultConfig vaultConfig, StringProperty recoveryKey, RecoveryKeyFactory recoveryKeyFactory) {
|
||||
public RecoveryKeyValidateController(Vault vault, //
|
||||
@Nullable VaultConfig.UnverifiedVaultConfig vaultConfig, //
|
||||
StringProperty recoveryKey, //
|
||||
RecoveryKeyFactory recoveryKeyFactory, //
|
||||
@Named("recoverType") ObjectProperty<RecoverUtil.Type> recoverType, //
|
||||
MasterkeyFileAccess masterkeyFileAccess) {
|
||||
this.vault = vault;
|
||||
this.unverifiedVaultConfig = vaultConfig;
|
||||
this.recoveryKey = recoveryKey;
|
||||
@@ -52,6 +62,8 @@ public class RecoveryKeyValidateController implements FxController {
|
||||
this.recoveryKeyCorrect = ObservableUtil.mapWithDefault(recoveryKeyState, RecoveryKeyState.CORRECT::equals, false);
|
||||
this.recoveryKeyWrong = ObservableUtil.mapWithDefault(recoveryKeyState, RecoveryKeyState.WRONG::equals, false);
|
||||
this.recoveryKeyInvalid = ObservableUtil.mapWithDefault(recoveryKeyState, RecoveryKeyState.INVALID::equals, false);
|
||||
this.recoverType = recoverType;
|
||||
this.masterkeyFileAccess = masterkeyFileAccess;
|
||||
}
|
||||
|
||||
@FXML
|
||||
@@ -118,7 +130,23 @@ public class RecoveryKeyValidateController implements FxController {
|
||||
|
||||
private void validateRecoveryKey() {
|
||||
isWrongKey = false;
|
||||
var valid = recoveryKeyFactory.validateRecoveryKey(recoveryKey.get(), unverifiedVaultConfig != null ? this::checkKeyAgainstVaultConfig : null);
|
||||
var valid = false;
|
||||
switch (recoverType.get()) {
|
||||
case RESTORE_VAULT_CONFIG -> {
|
||||
try{
|
||||
valid = RecoverUtil.validateRecoveryKey(recoveryKeyFactory, vault, recoveryKey, masterkeyFileAccess);
|
||||
}
|
||||
catch (IllegalStateException e){
|
||||
isWrongKey = true;
|
||||
}
|
||||
catch (IllegalArgumentException e){
|
||||
isWrongKey = false;
|
||||
}
|
||||
}
|
||||
case RESTORE_MASTERKEY, RESET_PASSWORD, SHOW_KEY, CONVERT_VAULT -> {
|
||||
valid = recoveryKeyFactory.validateRecoveryKey(recoveryKey.get(), unverifiedVaultConfig != null ? this::checkKeyAgainstVaultConfig : null);
|
||||
}
|
||||
};
|
||||
if (valid) {
|
||||
recoveryKeyState.set(RecoveryKeyState.CORRECT);
|
||||
} else if (isWrongKey) { //set via side effect in checkKeyAgainstVaultConfig()
|
||||
|
||||
Reference in New Issue
Block a user