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
This commit is contained in:
Markus Kreusch
2016-02-21 21:33:35 +01:00
parent 023e7d70e5
commit 391d8013b5
3 changed files with 17 additions and 7 deletions

View File

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

View File

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

View File

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