From a3cfcb11316ff28278fbe9382a156132b7b8b1fa Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Thu, 15 Sep 2016 23:26:13 +0200 Subject: [PATCH] Reject opening files when former filesize header is != -1 --- .../engine/impl/FileContentDecryptorImpl.java | 5 +++++ .../engine/impl/FileContentDecryptorImplTest.java | 10 +++++----- .../crypto/engine/impl/FileHeaderTest.java | 15 ++++++++++++++- 3 files changed, 24 insertions(+), 6 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 0088f6a51..fdc12bb2a 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 @@ -54,6 +54,11 @@ class FileContentDecryptorImpl implements FileContentDecryptor { this.header = FileHeader.decrypt(headerKey, hmacSha256, header); this.authenticate = authenticate; this.chunkNumber = firstCiphertextByte / CHUNK_SIZE; // floor() by int-truncation + + // vault version 5 and onwards should have filesize: -1 + if (this.header.getPayload().getFilesize() != -1l) { + throw new UncheckedIOException(new IOException("Attempted to decrypt file with invalid header (probably from previous vault version)")); + } } @Override diff --git a/main/filesystem-crypto/src/test/java/org/cryptomator/crypto/engine/impl/FileContentDecryptorImplTest.java b/main/filesystem-crypto/src/test/java/org/cryptomator/crypto/engine/impl/FileContentDecryptorImplTest.java index 173d13348..631811da7 100644 --- a/main/filesystem-crypto/src/test/java/org/cryptomator/crypto/engine/impl/FileContentDecryptorImplTest.java +++ b/main/filesystem-crypto/src/test/java/org/cryptomator/crypto/engine/impl/FileContentDecryptorImplTest.java @@ -45,7 +45,7 @@ public class FileContentDecryptorImplTest { final byte[] keyBytes = new byte[32]; final SecretKey headerKey = new SecretKeySpec(keyBytes, "AES"); final SecretKey macKey = new SecretKeySpec(keyBytes, "HmacSHA256"); - final byte[] header = Base64.decode("AAAAAAAAAAAAAAAAAAAAANyVwHiiQImjrUiiFJKEIIdTD4r7x0U2ualjtPHEy3OLzqdAPU1ga26lJzstK9RUv1hj5zDC4wC9FgMfoVE1mD0HnuENuYXkJA=="); + final byte[] header = Base64.decode("AAAAAAAAAAAAAAAAAAAAACNqP4ddv3Z2rUiiFJKEIIdTD4r7x0U2ualjtPHEy3OLzqdAPU1ga24VjC86+zlHN49BfMdzvHF3f9EE0LSnRLSsu6ps3IRcJg=="); final byte[] content = Base64.decode("AAAAAAAAAAAAAAAAAAAAALTwrBTNYP7m3yTGKlhka9WPvX1Lpn5EYfVxlyX1ISgRXtdRnivM7r6F3Og="); try (FileContentDecryptor decryptor = new FileContentDecryptorImpl(headerKey, macKey, ByteBuffer.wrap(header), 0, true)) { @@ -68,7 +68,7 @@ public class FileContentDecryptorImplTest { final byte[] keyBytes = new byte[32]; final SecretKey headerKey = new SecretKeySpec(keyBytes, "AES"); final SecretKey macKey = new SecretKeySpec(keyBytes, "HmacSHA256"); - final byte[] header = Base64.decode("AAAAAAAAAAAAAAAAAAAAANyVwHiiQImjrUiiFJKEIIdTD4r7x0U2ualjtPHEy3OLzqdAPU1ga26lJzstK9RUv1hj5zDC4wC9FgMfoVE1mD0HnuENuYXkJa=="); + final byte[] header = Base64.decode("AAAAAAAAAAAAAAAAAAAAACNqP4ddv3Z2rUiiFJKEIIdTD4r7x0U2ualjtPHEy3OLzqdAPU1ga24VjC86+zlHN49BfMdzvHF3f9EE0LSnRLSsu6ps3IRcJG=="); try (FileContentDecryptor decryptor = new FileContentDecryptorImpl(headerKey, macKey, ByteBuffer.wrap(header), 0, true)) { @@ -80,7 +80,7 @@ public class FileContentDecryptorImplTest { final byte[] keyBytes = new byte[32]; final SecretKey headerKey = new SecretKeySpec(keyBytes, "AES"); final SecretKey macKey = new SecretKeySpec(keyBytes, "HmacSHA256"); - final byte[] header = Base64.decode("AAAAAAAAAAAAAAAAAAAAANyVwHiiQImjrUiiFJKEIIdTD4r7x0U2ualjtPHEy3OLzqdAPU1ga26lJzstK9RUv1hj5zDC4wC9FgMfoVE1mD0HnuENuYXkJA=="); + final byte[] header = Base64.decode("AAAAAAAAAAAAAAAAAAAAACNqP4ddv3Z2rUiiFJKEIIdTD4r7x0U2ualjtPHEy3OLzqdAPU1ga24VjC86+zlHN49BfMdzvHF3f9EE0LSnRLSsu6ps3IRcJg=="); final byte[] content = Base64.decode("aAAAAAAAAAAAAAAAAAAAALTwrBTNYP7m3yTGKlhka9WPvX1Lpn5EYfVxlyX1ISgRXtdRnivM7r6F3Og="); try (FileContentDecryptor decryptor = new FileContentDecryptorImpl(headerKey, macKey, ByteBuffer.wrap(header), 0, true)) { @@ -101,7 +101,7 @@ public class FileContentDecryptorImplTest { final byte[] keyBytes = new byte[32]; final SecretKey headerKey = new SecretKeySpec(keyBytes, "AES"); final SecretKey macKey = new SecretKeySpec(keyBytes, "HmacSHA256"); - final byte[] header = Base64.decode("AAAAAAAAAAAAAAAAAAAAANyVwHiiQImjrUiiFJKEIIdTD4r7x0U2ualjtPHEy3OLzqdAPU1ga26lJzstK9RUv1hj5zDC4wC9FgMfoVE1mD0HnuENuYXkJA=="); + final byte[] header = Base64.decode("AAAAAAAAAAAAAAAAAAAAACNqP4ddv3Z2rUiiFJKEIIdTD4r7x0U2ualjtPHEy3OLzqdAPU1ga24VjC86+zlHN49BfMdzvHF3f9EE0LSnRLSsu6ps3IRcJg=="); final byte[] content = Base64.decode("AAAAAAAAAAAAAAAAAAAAALTwrBTNYP7m3yTGKlhka9WPvX1Lpn5EYfVxlyX1ISgRXtdRnivM7r6F3OG="); try (FileContentDecryptor decryptor = new FileContentDecryptorImpl(headerKey, macKey, ByteBuffer.wrap(header), 0, false)) { @@ -124,7 +124,7 @@ public class FileContentDecryptorImplTest { final byte[] keyBytes = new byte[32]; final SecretKey headerKey = new SecretKeySpec(keyBytes, "AES"); final SecretKey macKey = new SecretKeySpec(keyBytes, "AES"); - final byte[] header = Base64.decode("AAAAAAAAAAAAAAAAAAAAANyVwHiiQImjrUiiFJKEIIdTD4r7x0U2ualjtPHEy3OLzqdAPU1ga26lJzstK9RUv1hj5zDC4wC9FgMfoVE1mD0HnuENuYXkJA=="); + final byte[] header = Base64.decode("AAAAAAAAAAAAAAAAAAAAACNqP4ddv3Z2rUiiFJKEIIdTD4r7x0U2ualjtPHEy3OLzqdAPU1ga24VjC86+zlHN49BfMdzvHF3f9EE0LSnRLSsu6ps3IRcJg=="); try (FileContentDecryptor decryptor = new FileContentDecryptorImpl(headerKey, macKey, ByteBuffer.wrap(header), 0, true)) { decryptor.cancelWithException(new IOException("can not do")); diff --git a/main/filesystem-crypto/src/test/java/org/cryptomator/crypto/engine/impl/FileHeaderTest.java b/main/filesystem-crypto/src/test/java/org/cryptomator/crypto/engine/impl/FileHeaderTest.java index 391fa88b4..bbe61a522 100644 --- a/main/filesystem-crypto/src/test/java/org/cryptomator/crypto/engine/impl/FileHeaderTest.java +++ b/main/filesystem-crypto/src/test/java/org/cryptomator/crypto/engine/impl/FileHeaderTest.java @@ -53,13 +53,26 @@ public class FileHeaderTest { @Test public void testDecryption() { + final byte[] keyBytes = new byte[32]; + final SecretKey headerKey = new SecretKeySpec(keyBytes, "AES"); + final SecretKey macKey = new SecretKeySpec(keyBytes, "HmacSHA256"); + final ByteBuffer headerBuf = ByteBuffer.wrap(Base64.decode("AAAAAAAAAAAAAAAAAAAAACNqP4ddv3Z2rUiiFJKEIIdTD4r7x0U2ualjtPHEy3OLzqdAPU1ga24VjC86+zlHN49BfMdzvHF3f9EE0LSnRLSsu6ps3IRcJg==")); + final FileHeader header = FileHeader.decrypt(headerKey, new ThreadLocalMac(macKey, "HmacSHA256"), headerBuf); + + Assert.assertEquals(-1l, header.getPayload().getFilesize()); + Assert.assertArrayEquals(new byte[16], header.getIv()); + Assert.assertArrayEquals(new byte[32], header.getPayload().getContentKey().getEncoded()); + } + + @Test + public void testDecryptionOfOldHeader() { final byte[] keyBytes = new byte[32]; final SecretKey headerKey = new SecretKeySpec(keyBytes, "AES"); final SecretKey macKey = new SecretKeySpec(keyBytes, "HmacSHA256"); final ByteBuffer headerBuf = ByteBuffer.wrap(Base64.decode("AAAAAAAAAAAAAAAAAAAAANyVwHiiQImjrUiiFJKEIIdTD4r7x0U2ualjtPHEy3OLzqdAPU1ga26lJzstK9RUv1hj5zDC4wC9FgMfoVE1mD0HnuENuYXkJA==")); final FileHeader header = FileHeader.decrypt(headerKey, new ThreadLocalMac(macKey, "HmacSHA256"), headerBuf); - Assert.assertEquals(42, header.getPayload().getFilesize()); + Assert.assertEquals(42l, header.getPayload().getFilesize()); Assert.assertArrayEquals(new byte[16], header.getIv()); Assert.assertArrayEquals(new byte[32], header.getPayload().getContentKey().getEncoded()); }