mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-08-18 05:06:02 +00:00
Using pattern based filename filtering
This is a preparation for finding valid encrypted names inside filenames that include additional characters
This commit is contained in:
+4
-5
@@ -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 <code>true</code> 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
|
||||
|
||||
+4
-2
@@ -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<MessageDigest> SHA1 = new ThreadLocalSha1();
|
||||
private static final ThreadLocal<SivMode> AES_SIV = new ThreadLocal<SivMode>() {
|
||||
@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
|
||||
|
||||
+14
-3
@@ -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<String> 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<String> 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();
|
||||
}
|
||||
|
||||
|
||||
+4
-2
@@ -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<MessageDigest> 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
|
||||
|
||||
Reference in New Issue
Block a user