From c546f3363bfac9b474827cac1b9b0df6dfc42306 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Thu, 3 Jul 2025 12:08:41 +0200 Subject: [PATCH] reduce object creation and conversion --- .../common/recovery/MasterkeyService.java | 42 +++++++------------ .../RecoveryKeyCreationController.java | 2 +- 2 files changed, 15 insertions(+), 29 deletions(-) diff --git a/src/main/java/org/cryptomator/common/recovery/MasterkeyService.java b/src/main/java/org/cryptomator/common/recovery/MasterkeyService.java index d150c7feb..5fd74a7f0 100644 --- a/src/main/java/org/cryptomator/common/recovery/MasterkeyService.java +++ b/src/main/java/org/cryptomator/common/recovery/MasterkeyService.java @@ -1,7 +1,6 @@ package org.cryptomator.common.recovery; import org.cryptomator.common.vaults.Vault; -import org.cryptomator.cryptolib.api.AuthenticationFailedException; import org.cryptomator.cryptolib.api.CryptoException; import org.cryptomator.cryptolib.api.Cryptor; import org.cryptomator.cryptolib.api.CryptorProvider; @@ -44,7 +43,7 @@ public final class MasterkeyService { public static Optional validateRecoveryKeyAndDetectCombo(RecoveryKeyFactory recoveryKeyFactory, // Vault vault, String recoveryKey, // - MasterkeyFileAccess masterkeyFileAccess) throws IllegalArgumentException { + MasterkeyFileAccess masterkeyFileAccess) throws IllegalArgumentException { String tmpPass = UUID.randomUUID().toString(); try (RecoveryDirectory recoveryDirectory = RecoveryDirectory.create(vault.getPath())) { Path tempRecoveryPath = recoveryDirectory.getRecoveryPath(); @@ -52,7 +51,7 @@ public final class MasterkeyService { Path masterkeyFilePath = tempRecoveryPath.resolve(MASTERKEY_FILENAME); try (Masterkey mk = load(masterkeyFileAccess, masterkeyFilePath, tmpPass)) { - return detect(mk.getEncoded(), vault.getPath()); + return detect(mk, vault.getPath()); } catch (IOException | CryptoException e) { LOG.info("Recovery key validation failed", e); return Optional.empty(); @@ -63,13 +62,10 @@ public final class MasterkeyService { return Optional.empty(); } - public static Optional detect(byte[] masterkey, Path vaultPath) { + public static Optional detect(Masterkey masterkey, Path vaultPath) { try (Stream paths = Files.walk(vaultPath.resolve(DATA_DIR_NAME))) { List excludedFilenames = List.of("dirid.c9r", "dir.c9r"); - Optional c9rFile = paths - .filter(p -> p.toString().endsWith(".c9r")) - .filter(p -> excludedFilenames.stream().noneMatch(p.toString()::endsWith)) - .findFirst(); + Optional c9rFile = paths.filter(p -> p.toString().endsWith(".c9r")).filter(p -> excludedFilenames.stream().noneMatch(p.toString()::endsWith)).findFirst(); if (c9rFile.isEmpty()) { LOG.info("Unable to detect Crypto scheme: No *.c9r file found in {}", vaultPath); return Optional.empty(); @@ -81,22 +77,20 @@ public final class MasterkeyService { } } - private static Optional determineScheme(Path c9rFile, byte[] masterkey) { + private static Optional determineScheme(Path c9rFile, Masterkey masterkey) { return Arrays.stream(CryptorProvider.Scheme.values()).filter(scheme -> { - try { - try (Masterkey mk = new Masterkey(masterkey); Cryptor cryptor = CryptorProvider.forScheme(scheme).provide(mk, SecureRandom.getInstanceStrong())) { - int headerSize = cryptor.fileHeaderCryptor().headerSize(); + try (Cryptor cryptor = CryptorProvider.forScheme(scheme).provide(masterkey.copy(), SecureRandom.getInstanceStrong())) { + int headerSize = cryptor.fileHeaderCryptor().headerSize(); - ByteBuffer headerBuf = ByteBuffer.allocate(headerSize); + ByteBuffer headerBuf = ByteBuffer.allocate(headerSize); - try (FileChannel channel = FileChannel.open(c9rFile, StandardOpenOption.READ)) { - channel.read(headerBuf, 0); - } - - headerBuf.flip(); - - return isDecryptable(headerBuf, mk, scheme); + try (FileChannel channel = FileChannel.open(c9rFile, StandardOpenOption.READ)) { + channel.read(headerBuf, 0); } + + headerBuf.flip(); + cryptor.fileHeaderCryptor().decryptHeader(headerBuf.duplicate()); + return true; } catch (IOException | CryptoException | NoSuchAlgorithmException e) { LOG.info("Unable to detect Crypto scheme: Failed to decrypt .c9r file", e); return false; @@ -104,12 +98,4 @@ public final class MasterkeyService { }).findFirst(); } - private static boolean isDecryptable(ByteBuffer header, Masterkey masterkey, CryptorProvider.Scheme scheme) { - try (Cryptor cryptor = CryptorProvider.forScheme(scheme).provide(masterkey, SecureRandom.getInstanceStrong())) { - cryptor.fileHeaderCryptor().decryptHeader(header.duplicate()); - return true; - } catch (AuthenticationFailedException | NoSuchAlgorithmException e) { - return false; - } - } } diff --git a/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyCreationController.java b/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyCreationController.java index 24aa6b0c3..56b0aab5e 100644 --- a/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyCreationController.java +++ b/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyCreationController.java @@ -148,7 +148,7 @@ public class RecoveryKeyCreationController implements FxController { Path masterkeyFilePath = vault.getPath().resolve(MASTERKEY_FILENAME); try (Masterkey masterkey = MasterkeyService.load(masterkeyFileAccess, masterkeyFilePath, passwordField.getCharacters())) { - var combo = MasterkeyService.detect(masterkey.getEncoded(), vault.getPath()) + var combo = MasterkeyService.detect(masterkey, vault.getPath()) .orElseThrow(() -> new IllegalStateException("Could not detect combo for vault path: " + vault.getPath())); CryptoFsInitializer.init(recoveryPath, masterkey, shorteningThreshold.get(), combo);