diff --git a/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyModule.java b/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyModule.java index b30167e73..0522e3a8d 100644 --- a/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyModule.java +++ b/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyModule.java @@ -4,7 +4,9 @@ import dagger.Binds; import dagger.Module; import dagger.Provides; import dagger.multibindings.IntoMap; +import org.cryptomator.common.Nullable; import org.cryptomator.common.vaults.Vault; +import org.cryptomator.cryptofs.VaultConfig; import org.cryptomator.ui.common.DefaultSceneFactory; import org.cryptomator.ui.common.FxController; import org.cryptomator.ui.common.FxControllerKey; @@ -22,12 +24,25 @@ import javafx.beans.property.StringProperty; import javafx.scene.Scene; import javafx.stage.Modality; import javafx.stage.Stage; +import java.io.IOException; import java.util.Map; import java.util.ResourceBundle; @Module abstract class RecoveryKeyModule { + @Provides + @Nullable + @RecoveryKeyWindow + @RecoveryKeyScoped + static VaultConfig.UnverifiedVaultConfig vaultConfig(@RecoveryKeyWindow Vault vault) { + try { + return vault.getVaultConfigCache().get(); + } catch (IOException e) { + return null; + } + } + @Provides @RecoveryKeyWindow @RecoveryKeyScoped diff --git a/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyRecoverController.java b/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyRecoverController.java index 7e40a833b..e05a73169 100644 --- a/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyRecoverController.java +++ b/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyRecoverController.java @@ -3,10 +3,16 @@ package org.cryptomator.ui.recoverykey; import com.google.common.base.CharMatcher; import com.google.common.base.Strings; import dagger.Lazy; +import org.cryptomator.common.Nullable; import org.cryptomator.common.vaults.Vault; +import org.cryptomator.cryptofs.VaultConfig; +import org.cryptomator.cryptofs.VaultConfigLoadException; +import org.cryptomator.cryptofs.VaultKeyInvalidException; import org.cryptomator.ui.common.FxController; import org.cryptomator.ui.common.FxmlFile; import org.cryptomator.ui.common.FxmlScene; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import javax.inject.Inject; import javafx.beans.binding.Bindings; @@ -24,10 +30,12 @@ import java.util.Optional; @RecoveryKeyScoped public class RecoveryKeyRecoverController implements FxController { - private final static CharMatcher ALLOWED_CHARS = CharMatcher.inRange('a', 'z').or(CharMatcher.is(' ')); + private static final Logger LOG = LoggerFactory.getLogger(RecoveryKeyCreationController.class); + private static final CharMatcher ALLOWED_CHARS = CharMatcher.inRange('a', 'z').or(CharMatcher.is(' ')); private final Stage window; private final Vault vault; + private final VaultConfig.UnverifiedVaultConfig unverifiedVaultConfig; private final StringProperty recoveryKey; private final RecoveryKeyFactory recoveryKeyFactory; private final BooleanBinding validRecoveryKey; @@ -37,9 +45,10 @@ public class RecoveryKeyRecoverController implements FxController { public TextArea textarea; @Inject - public RecoveryKeyRecoverController(@RecoveryKeyWindow Stage window, @RecoveryKeyWindow Vault vault, @RecoveryKeyWindow StringProperty recoveryKey, RecoveryKeyFactory recoveryKeyFactory, @FxmlScene(FxmlFile.RECOVERYKEY_RESET_PASSWORD) Lazy resetPasswordScene) { + public RecoveryKeyRecoverController(@RecoveryKeyWindow Stage window, @RecoveryKeyWindow Vault vault, @RecoveryKeyWindow @Nullable VaultConfig.UnverifiedVaultConfig unverifiedVaultConfig, @RecoveryKeyWindow StringProperty recoveryKey, RecoveryKeyFactory recoveryKeyFactory, @FxmlScene(FxmlFile.RECOVERYKEY_RESET_PASSWORD) Lazy resetPasswordScene) { this.window = window; this.vault = vault; + this.unverifiedVaultConfig = unverifiedVaultConfig; this.recoveryKey = recoveryKey; this.recoveryKeyFactory = recoveryKeyFactory; this.validRecoveryKey = Bindings.createBooleanBinding(this::isValidRecoveryKey, recoveryKey); @@ -96,6 +105,20 @@ public class RecoveryKeyRecoverController implements FxController { window.setScene(resetPasswordScene.get()); } + private boolean checkKeyAgainstVaultConfig(byte[] key) { + try { + var config = unverifiedVaultConfig.verify(key, unverifiedVaultConfig.allegedVaultVersion()); + LOG.info("Provided recovery key matches vault config signature for vault {}", config.getId()); + return true; + } catch (VaultKeyInvalidException e) { + LOG.debug("Provided recovery key does not match vault config signature."); + return false; + } catch (VaultConfigLoadException e) { + LOG.error("Failed to parse vault config", e); + return false; + } + } + /* Getter/Setter */ public Vault getVault() { @@ -107,7 +130,11 @@ public class RecoveryKeyRecoverController implements FxController { } public boolean isValidRecoveryKey() { - return recoveryKeyFactory.validateRecoveryKey(recoveryKey.get()); + if (unverifiedVaultConfig != null) { + return recoveryKeyFactory.validateRecoveryKey(recoveryKey.get(), this::checkKeyAgainstVaultConfig); + } else { + return recoveryKeyFactory.validateRecoveryKey(recoveryKey.get()); + } } public TextFormatter getRecoveryKeyTextFormatter() {