소스 검색

fixed writing short ciphertext to file, that existed with a longer ciphertext before but wasn't truncated

Sebastian Stenzel 9 년 전
부모
커밋
5b22806bbc

+ 9 - 6
main/filesystem-crypto/src/main/java/org/cryptomator/crypto/engine/impl/FileContentDecryptorImpl.java

@@ -11,6 +11,7 @@ package org.cryptomator.crypto.engine.impl;
 import static org.cryptomator.crypto.engine.impl.FileContentCryptorImpl.CHUNK_SIZE;
 import static org.cryptomator.crypto.engine.impl.FileContentCryptorImpl.MAC_SIZE;
 import static org.cryptomator.crypto.engine.impl.FileContentCryptorImpl.NONCE_SIZE;
+import static org.cryptomator.crypto.engine.impl.FileContentCryptorImpl.PAYLOAD_SIZE;
 
 import java.io.IOException;
 import java.io.UncheckedIOException;
@@ -31,6 +32,7 @@ import javax.crypto.SecretKey;
 import javax.crypto.ShortBufferException;
 import javax.crypto.spec.IvParameterSpec;
 
+import org.apache.commons.codec.binary.Hex;
 import org.cryptomator.crypto.engine.AuthenticationFailedException;
 import org.cryptomator.crypto.engine.FileContentCryptor;
 import org.cryptomator.crypto.engine.FileContentDecryptor;
@@ -47,7 +49,7 @@ class FileContentDecryptorImpl implements FileContentDecryptor {
 	private final Supplier<Mac> hmacSha256;
 	private final FileHeader header;
 	private final boolean authenticate;
-	private final LongAdder cleartextBytesScheduledForDecryption = new LongAdder();
+	private final LongAdder ciphertextBytesScheduledForDecryption = new LongAdder();
 	private final LongAdder cleartextBytesDecrypted = new LongAdder();
 	private ByteBuffer ciphertextBuffer = ByteBuffer.allocate(CHUNK_SIZE);
 	private long chunkNumber = 0;
@@ -66,13 +68,15 @@ class FileContentDecryptorImpl implements FileContentDecryptor {
 
 	@Override
 	public void append(ByteBuffer ciphertext) throws InterruptedException {
-		if (cleartextBytesScheduledForDecryption.sum() >= contentLength()) {
-			submitEof();
-		} else if (ciphertext == FileContentCryptor.EOF) {
+		long numChunksNeeded = (contentLength() - 1) / PAYLOAD_SIZE + 1;
+		long numCiphertextBytesNeeded = numChunksNeeded * CHUNK_SIZE;
+
+		if (ciphertext == FileContentCryptor.EOF || ciphertextBytesScheduledForDecryption.sum() >= numCiphertextBytesNeeded) {
 			submitCiphertextBuffer();
 			submitEof();
 		} else {
-			while (ciphertext.hasRemaining() && cleartextBytesScheduledForDecryption.sum() < contentLength()) {
+			ciphertextBytesScheduledForDecryption.add(ciphertext.remaining());
+			while (ciphertext.hasRemaining()) {
 				ByteBuffers.copy(ciphertext, ciphertextBuffer);
 				submitCiphertextBufferIfFull();
 			}
@@ -96,7 +100,6 @@ class FileContentDecryptorImpl implements FileContentDecryptor {
 	private void submitCiphertextBuffer() throws InterruptedException {
 		ciphertextBuffer.flip();
 		if (ciphertextBuffer.hasRemaining()) {
-			cleartextBytesScheduledForDecryption.add(ciphertextBuffer.remaining() - MAC_SIZE - NONCE_SIZE);
 			Callable<ByteBuffer> encryptionJob = new DecryptionJob(ciphertextBuffer, chunkNumber++);
 			dataProcessor.submit(encryptionJob);
 		}

+ 1 - 4
main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/crypto/CryptoWritableFile.java

@@ -31,7 +31,6 @@ class CryptoWritableFile implements WritableFile {
 
 	private FileContentEncryptor encryptor;
 	private Future<Void> writeTask;
-	private boolean contentChanged = false;
 
 	public CryptoWritableFile(FileContentCryptor cryptor, WritableFile file) {
 		this.file = file;
@@ -54,7 +53,6 @@ class CryptoWritableFile implements WritableFile {
 
 	@Override
 	public int write(ByteBuffer source) {
-		contentChanged = true;
 		final int size = source.remaining();
 		final ByteBuffer cleartextCopy = ByteBuffer.allocate(size);
 		ByteBuffers.copy(source, cleartextCopy);
@@ -74,7 +72,6 @@ class CryptoWritableFile implements WritableFile {
 
 	@Override
 	public void truncate() {
-		contentChanged = true;
 		terminateAndWaitForWriteTask();
 		file.truncate();
 		initialize(0);
@@ -88,7 +85,7 @@ class CryptoWritableFile implements WritableFile {
 	@Override
 	public void close() {
 		try {
-			if (contentChanged && file.isOpen()) {
+			if (file.isOpen()) {
 				terminateAndWaitForWriteTask();
 				writeHeader();
 			}

+ 1 - 0
main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/jackrabbitservlet/DavFolder.java

@@ -73,6 +73,7 @@ class DavFolder extends DavNode<FolderLocator> {
 
 	private void addMemberFile(DavFile memberFile, InputStream inputStream) {
 		try (ReadableByteChannel src = Channels.newChannel(inputStream); WritableFile dst = node.file(memberFile.getDisplayName()).openWritable()) {
+			dst.truncate();
 			ByteStreams.copy(src, dst);
 		} catch (IOException e) {
 			throw new UncheckedIOException(e);