Bläddra i källkod

recoverykey validate

Jan-Peter Klein 3 månader sedan
förälder
incheckning
a3b8297e23

+ 33 - 3
src/main/java/org/cryptomator/common/RecoverUtil.java

@@ -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 - 1
src/main/java/org/cryptomator/ui/convertvault/ConvertVaultModule.java

@@ -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);
 	}
 
 }

+ 3 - 2
src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyModule.java

@@ -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

+ 3 - 0
src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyRecoverController.java

@@ -48,6 +48,9 @@ public class RecoveryKeyRecoverController implements FxController {
 				window.setTitle(resourceBundle.getString("recoveryKey.display.title"));
 				yield resetPasswordScene;
 			}
+			default -> {
+				yield null;
+			}
 		};
 	}
 

+ 30 - 2
src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyValidateController.java

@@ -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()