diff --git a/main/filesystem-crypto/src/main/java/org/cryptomator/crypto/engine/FilenameCryptor.java b/main/filesystem-crypto/src/main/java/org/cryptomator/crypto/engine/FilenameCryptor.java
index cb94a12fa..1226da4ed 100644
--- a/main/filesystem-crypto/src/main/java/org/cryptomator/crypto/engine/FilenameCryptor.java
+++ b/main/filesystem-crypto/src/main/java/org/cryptomator/crypto/engine/FilenameCryptor.java
@@ -8,6 +8,8 @@
*******************************************************************************/
package org.cryptomator.crypto.engine;
+import java.util.regex.Pattern;
+
/**
* Provides deterministic encryption capabilities as filenames must not change on subsequent encryption attempts,
* otherwise each change results in major directory structure changes which would be a terrible idea for cloud storage encryption.
@@ -22,12 +24,9 @@ public interface FilenameCryptor {
String hashDirectoryId(String cleartextDirectoryId);
/**
- * Tests without an actual decryption attempt, if a name is a well-formed ciphertext.
- *
- * @param ciphertextName Filename in question
- * @return true if the given name is likely to be a valid ciphertext
+ * @return A Pattern that can be used to test, if a name is a well-formed ciphertext.
*/
- boolean isEncryptedFilename(String ciphertextName);
+ Pattern encryptedNamePattern();
/**
* @param cleartextName original filename including cleartext file extension
diff --git a/main/filesystem-crypto/src/main/java/org/cryptomator/crypto/engine/impl/FilenameCryptorImpl.java b/main/filesystem-crypto/src/main/java/org/cryptomator/crypto/engine/impl/FilenameCryptorImpl.java
index 5db611548..4b977d44d 100644
--- a/main/filesystem-crypto/src/main/java/org/cryptomator/crypto/engine/impl/FilenameCryptorImpl.java
+++ b/main/filesystem-crypto/src/main/java/org/cryptomator/crypto/engine/impl/FilenameCryptorImpl.java
@@ -12,6 +12,7 @@ import static java.nio.charset.StandardCharsets.UTF_8;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
+import java.util.regex.Pattern;
import javax.crypto.AEADBadTagException;
import javax.crypto.SecretKey;
@@ -25,6 +26,7 @@ import org.cryptomator.siv.SivMode;
class FilenameCryptorImpl implements FilenameCryptor {
private static final BaseNCodec BASE32 = new Base32();
+ private static final Pattern BASE32_PATTERN = Pattern.compile("([A-Z0-9]{8})*[A-Z0-9=]{8}");
private static final ThreadLocal SHA1 = new ThreadLocalSha1();
private static final ThreadLocal AES_SIV = new ThreadLocal() {
@Override
@@ -50,8 +52,8 @@ class FilenameCryptorImpl implements FilenameCryptor {
}
@Override
- public boolean isEncryptedFilename(String ciphertextName) {
- return BASE32.isInAlphabet(ciphertextName);
+ public Pattern encryptedNamePattern() {
+ return BASE32_PATTERN;
}
@Override
diff --git a/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/crypto/CryptoFolder.java b/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/crypto/CryptoFolder.java
index c8228535c..3c2040ea3 100644
--- a/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/crypto/CryptoFolder.java
+++ b/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/crypto/CryptoFolder.java
@@ -18,6 +18,7 @@ import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Predicate;
+import java.util.regex.Matcher;
import java.util.stream.Stream;
import org.apache.commons.lang3.StringUtils;
@@ -85,7 +86,10 @@ class CryptoFolder extends CryptoNode implements Folder {
}
private Predicate isEncryptedFileName() {
- return (String name) -> !name.endsWith(DIR_SUFFIX) && cryptor.getFilenameCryptor().isEncryptedFilename(name);
+ return (String name) -> {
+ final Matcher m = cryptor.getFilenameCryptor().encryptedNamePattern().matcher(name);
+ return m.matches();
+ };
}
private String decryptChildFileName(String encryptedFileName) {
@@ -109,7 +113,14 @@ class CryptoFolder extends CryptoNode implements Folder {
}
private Predicate isEncryptedDirectoryName() {
- return (String name) -> name.endsWith(DIR_SUFFIX) && cryptor.getFilenameCryptor().isEncryptedFilename(StringUtils.removeEnd(name, DIR_SUFFIX));
+ return (String name) -> {
+ if (name.endsWith(DIR_SUFFIX)) {
+ final Matcher m = cryptor.getFilenameCryptor().encryptedNamePattern().matcher(StringUtils.removeEnd(name, DIR_SUFFIX));
+ return m.matches();
+ } else {
+ return false;
+ }
+ };
}
private String decryptChildFolderName(String encryptedFolderName) {
@@ -176,7 +187,7 @@ class CryptoFolder extends CryptoNode implements Folder {
// cut all ties:
this.invalidateDirectoryIdsRecursively();
- assert!exists();
+ assert !exists();
assert target.exists();
}
diff --git a/main/filesystem-crypto/src/test/java/org/cryptomator/crypto/engine/NoFilenameCryptor.java b/main/filesystem-crypto/src/test/java/org/cryptomator/crypto/engine/NoFilenameCryptor.java
index 9f3901f7e..590582ba8 100644
--- a/main/filesystem-crypto/src/test/java/org/cryptomator/crypto/engine/NoFilenameCryptor.java
+++ b/main/filesystem-crypto/src/test/java/org/cryptomator/crypto/engine/NoFilenameCryptor.java
@@ -12,6 +12,7 @@ import static java.nio.charset.StandardCharsets.UTF_8;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
+import java.util.regex.Pattern;
import org.apache.commons.codec.binary.Base32;
import org.apache.commons.codec.binary.BaseNCodec;
@@ -19,6 +20,7 @@ import org.apache.commons.codec.binary.BaseNCodec;
class NoFilenameCryptor implements FilenameCryptor {
private static final BaseNCodec BASE32 = new Base32();
+ private static final Pattern WILDCARD_PATTERN = Pattern.compile(".*");
private static final ThreadLocal SHA1 = new ThreadLocalSha1();
@Override
@@ -29,8 +31,8 @@ class NoFilenameCryptor implements FilenameCryptor {
}
@Override
- public boolean isEncryptedFilename(String ciphertextName) {
- return true;
+ public Pattern encryptedNamePattern() {
+ return WILDCARD_PATTERN;
}
@Override