Browse Source

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<Mac> instead of
ThreadLocal<Mac>
* Fixed InMemoryWritableFile: No longer open after moveTo
Markus Kreusch 9 years ago
parent
commit
391d8013b5

+ 3 - 3
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<ByteBuffer> dataProcessor = new FifoParallelDataProcessor<>(NUM_THREADS + READ_AHEAD, SHARED_DECRYPTION_EXECUTOR);
-	private final ThreadLocal<Mac> hmacSha256;
+	private final Supplier<Mac> 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

+ 1 - 1
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));
 	}
 

+ 13 - 3
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;