diff --git a/main/filesystem-crypto/src/main/java/org/cryptomator/crypto/engine/FileContentCryptor.java b/main/filesystem-crypto/src/main/java/org/cryptomator/crypto/engine/FileContentCryptor.java index 0d5d2553dd..ec151a3144 100644 --- a/main/filesystem-crypto/src/main/java/org/cryptomator/crypto/engine/FileContentCryptor.java +++ b/main/filesystem-crypto/src/main/java/org/cryptomator/crypto/engine/FileContentCryptor.java @@ -35,7 +35,7 @@ public interface FileContentCryptor { * @param authenticate Skip authentication by setting this flag to false. Should be true by default. * @return A possibly new FileContentDecryptor instance which is capable of decrypting ciphertexts associated with the given file header. */ - FileContentDecryptor createFileContentDecryptor(ByteBuffer header, long firstCiphertextByte, boolean authenticate) throws IllegalArgumentException; + FileContentDecryptor createFileContentDecryptor(ByteBuffer header, long firstCiphertextByte, boolean authenticate) throws IllegalArgumentException, AuthenticationFailedException; /** * @param header The full fixed-length header of an encrypted file or {@link Optional#empty()}. The caller is required to pass the exact amount of bytes returned by {@link #getHeaderSize()}. diff --git a/main/filesystem-crypto/src/main/java/org/cryptomator/crypto/engine/impl/FileContentCryptorImpl.java b/main/filesystem-crypto/src/main/java/org/cryptomator/crypto/engine/impl/FileContentCryptorImpl.java index 1aadd94e67..2551ddbce9 100644 --- a/main/filesystem-crypto/src/main/java/org/cryptomator/crypto/engine/impl/FileContentCryptorImpl.java +++ b/main/filesystem-crypto/src/main/java/org/cryptomator/crypto/engine/impl/FileContentCryptorImpl.java @@ -14,6 +14,7 @@ import javax.crypto.SecretKey; +import org.cryptomator.crypto.engine.AuthenticationFailedException; import org.cryptomator.crypto.engine.FileContentCryptor; import org.cryptomator.crypto.engine.FileContentDecryptor; import org.cryptomator.crypto.engine.FileContentEncryptor; @@ -52,7 +53,7 @@ public long toCiphertextPos(long cleartextPos) { } @Override - public FileContentDecryptor createFileContentDecryptor(ByteBuffer header, long firstCiphertextByte, boolean authenticate) { + public FileContentDecryptor createFileContentDecryptor(ByteBuffer header, long firstCiphertextByte, boolean authenticate) throws IllegalArgumentException, AuthenticationFailedException { if (header.remaining() != getHeaderSize()) { throw new IllegalArgumentException("Invalid header."); } diff --git a/main/filesystem-crypto/src/main/java/org/cryptomator/crypto/engine/impl/FileHeader.java b/main/filesystem-crypto/src/main/java/org/cryptomator/crypto/engine/impl/FileHeader.java index c6ab7bc9b5..18accc34be 100644 --- a/main/filesystem-crypto/src/main/java/org/cryptomator/crypto/engine/impl/FileHeader.java +++ b/main/filesystem-crypto/src/main/java/org/cryptomator/crypto/engine/impl/FileHeader.java @@ -17,6 +17,8 @@ import javax.crypto.SecretKey; import javax.security.auth.Destroyable; +import org.cryptomator.crypto.engine.AuthenticationFailedException; + class FileHeader implements Destroyable { static final int HEADER_SIZE = 88; @@ -77,7 +79,7 @@ public void destroy() { payload.destroy(); } - public static FileHeader decrypt(SecretKey headerKey, Supplier hmacSha256Factory, ByteBuffer header) throws IllegalArgumentException { + public static FileHeader decrypt(SecretKey headerKey, Supplier hmacSha256Factory, ByteBuffer header) throws IllegalArgumentException, AuthenticationFailedException { if (header.remaining() != HEADER_SIZE) { throw new IllegalArgumentException("Invalid header size."); } @@ -97,7 +99,7 @@ public static FileHeader decrypt(SecretKey headerKey, Supplier hmacSha256Fa return new FileHeader(iv, payload); } - private static void checkHeaderMac(ByteBuffer header, Mac mac) throws IllegalArgumentException { + private static void checkHeaderMac(ByteBuffer header, Mac mac) throws AuthenticationFailedException { assert mac.getMacLength() == MAC_LEN; ByteBuffer headerData = header.asReadOnlyBuffer(); headerData.position(0).limit(MAC_POS); @@ -108,7 +110,7 @@ private static void checkHeaderMac(ByteBuffer header, Mac mac) throws IllegalArg headerMac.get(expectedMac); if (!MessageDigest.isEqual(expectedMac, mac.doFinal())) { - throw new IllegalArgumentException("Corrupt header."); + throw new AuthenticationFailedException("Corrupt header."); } } 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 885c453dbe..173d13348a 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 @@ -64,7 +64,19 @@ public void testDecryption() throws InterruptedException { } @Test(expected = AuthenticationFailedException.class) - public void testManipulatedDecryption() throws InterruptedException { + public void testManipulatedHeaderDecryption() throws InterruptedException { + 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=="); + + try (FileContentDecryptor decryptor = new FileContentDecryptorImpl(headerKey, macKey, ByteBuffer.wrap(header), 0, true)) { + + } + } + + @Test(expected = AuthenticationFailedException.class) + public void testManipulatedContentDecryption() throws InterruptedException { final byte[] keyBytes = new byte[32]; final SecretKey headerKey = new SecretKeySpec(keyBytes, "AES"); final SecretKey macKey = new SecretKeySpec(keyBytes, "HmacSHA256"); diff --git a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/jackrabbitservlet/NullInputContext.java b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/jackrabbitservlet/NullInputContext.java index 058421dcfd..94503155da 100644 --- a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/jackrabbitservlet/NullInputContext.java +++ b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/jackrabbitservlet/NullInputContext.java @@ -5,7 +5,7 @@ import org.apache.jackrabbit.webdav.io.InputContext; -public class NullInputContext implements InputContext { +class NullInputContext implements InputContext { @Override public boolean hasStream() {