From 391d8013b535f4448353492e9e1dea8cf5d1bdf1 Mon Sep 17 00:00:00 2001 From: Markus Kreusch Date: Sun, 21 Feb 2016 21:33:35 +0100 Subject: [PATCH] Fixed CryptoWritableFile errors when reading from moved file * CryptoWritableFile no longer writes header with zero size if file is opened for writing * Refactored FileContentDecryptor: Using Supplier instead of ThreadLocal * Fixed InMemoryWritableFile: No longer open after moveTo --- .../engine/impl/FileContentDecryptorImpl.java | 6 +++--- .../filesystem/crypto/CryptoWritableFile.java | 2 +- .../filesystem/inmem/InMemoryWritableFile.java | 16 +++++++++++++--- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/main/filesystem-crypto/src/main/java/org/cryptomator/crypto/engine/impl/FileContentDecryptorImpl.java b/main/filesystem-crypto/src/main/java/org/cryptomator/crypto/engine/impl/FileContentDecryptorImpl.java index 7afc299a9..b5476a183 100644 --- a/main/filesystem-crypto/src/main/java/org/cryptomator/crypto/engine/impl/FileContentDecryptorImpl.java +++ b/main/filesystem-crypto/src/main/java/org/cryptomator/crypto/engine/impl/FileContentDecryptorImpl.java @@ -23,6 +23,7 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.LongAdder; +import java.util.function.Supplier; import javax.crypto.Cipher; import javax.crypto.Mac; @@ -43,7 +44,7 @@ class FileContentDecryptorImpl implements FileContentDecryptor { private static final ExecutorService SHARED_DECRYPTION_EXECUTOR = Executors.newFixedThreadPool(NUM_THREADS); private final FifoParallelDataProcessor dataProcessor = new FifoParallelDataProcessor<>(NUM_THREADS + READ_AHEAD, SHARED_DECRYPTION_EXECUTOR); - private final ThreadLocal hmacSha256; + private final Supplier hmacSha256; private final FileHeader header; private final boolean authenticate; private final LongAdder cleartextBytesScheduledForDecryption = new LongAdder(); @@ -52,8 +53,7 @@ class FileContentDecryptorImpl implements FileContentDecryptor { private long chunkNumber = 0; public FileContentDecryptorImpl(SecretKey headerKey, SecretKey macKey, ByteBuffer header, long firstCiphertextByte, boolean authenticate) { - final ThreadLocalMac hmacSha256 = new ThreadLocalMac(macKey, HMAC_SHA256); - this.hmacSha256 = hmacSha256; + this.hmacSha256 = new ThreadLocalMac(macKey, HMAC_SHA256); this.header = FileHeader.decrypt(headerKey, hmacSha256, header); this.authenticate = authenticate; this.chunkNumber = firstCiphertextByte / CHUNK_SIZE; // floor() by int-truncation diff --git a/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/crypto/CryptoWritableFile.java b/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/crypto/CryptoWritableFile.java index 5f4ecc177..c1c725bfa 100644 --- a/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/crypto/CryptoWritableFile.java +++ b/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/crypto/CryptoWritableFile.java @@ -41,7 +41,7 @@ class CryptoWritableFile implements WritableFile { private void initialize(long firstCleartextByte) { encryptor = cryptor.createFileContentEncryptor(Optional.empty(), firstCleartextByte); - writeHeader(); + file.position(cryptor.getHeaderSize()); // skip header size, header is written on close writeTask = executorService.submit(new CiphertextWriter(file, encryptor)); } diff --git a/main/filesystem-inmemory/src/main/java/org/cryptomator/filesystem/inmem/InMemoryWritableFile.java b/main/filesystem-inmemory/src/main/java/org/cryptomator/filesystem/inmem/InMemoryWritableFile.java index 2294b7043..d9559fc90 100644 --- a/main/filesystem-inmemory/src/main/java/org/cryptomator/filesystem/inmem/InMemoryWritableFile.java +++ b/main/filesystem-inmemory/src/main/java/org/cryptomator/filesystem/inmem/InMemoryWritableFile.java @@ -47,11 +47,21 @@ public class InMemoryWritableFile implements WritableFile { @Override public void moveTo(WritableFile other) throws UncheckedIOException { if (other instanceof InMemoryWritableFile) { - InMemoryWritableFile destination = (InMemoryWritableFile) other; + internalMoveTo((InMemoryWritableFile) other); + } else { + throw new IllegalArgumentException("Can only move an InMemoryWritableFile to another InMemoryWritableFile"); + } + } + + private void internalMoveTo(InMemoryWritableFile destination) { + try { destination.contentSetter.accept(this.contentGetter.get()); destination.contentGetter.get().rewind(); + deleter.run(); + } finally { + open = false; + destination.open = false; } - deleter.run(); } @Override @@ -84,8 +94,8 @@ public class InMemoryWritableFile implements WritableFile { ByteBuffers.copy(old, destination); contentSetter.accept(destination); } - destination.position(position); destination.limit(newFileSize); + destination.position(position); int numWritten = ByteBuffers.copy(source, destination); this.position += numWritten; return numWritten;