mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-17 10:11:27 +00:00
new vault-internal file extensions (no extension at all for files, "_" suffix for directories)
This commit is contained in:
@@ -21,6 +21,14 @@ 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
|
||||
*/
|
||||
boolean isEncryptedFilename(String ciphertextName);
|
||||
|
||||
/**
|
||||
* @param cleartextName original filename including cleartext file extension
|
||||
* @param associatedData optional associated data, that will not get encrypted but needs to be provided during decryption
|
||||
|
||||
@@ -49,6 +49,11 @@ class FilenameCryptorImpl implements FilenameCryptor {
|
||||
return BASE32.encodeAsString(hashedBytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEncryptedFilename(String ciphertextName) {
|
||||
return BASE32.isInAlphabet(ciphertextName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String encryptFilename(String cleartextName, byte[]... associatedData) {
|
||||
final byte[] cleartextBytes = cleartextName.getBytes(UTF_8);
|
||||
|
||||
@@ -21,8 +21,6 @@ import org.cryptomator.filesystem.WritableFile;
|
||||
|
||||
public class CryptoFile extends CryptoNode implements File {
|
||||
|
||||
static final String FILE_EXT = ".file";
|
||||
|
||||
public CryptoFile(CryptoFolder parent, String name, Cryptor cryptor) {
|
||||
super(parent, name, cryptor);
|
||||
}
|
||||
@@ -30,7 +28,7 @@ public class CryptoFile extends CryptoNode implements File {
|
||||
@Override
|
||||
protected String encryptedName() {
|
||||
final byte[] parentDirId = parent.getDirectoryId().getBytes(UTF_8);
|
||||
return cryptor.getFilenameCryptor().encryptFilename(name(), parentDirId) + FILE_EXT;
|
||||
return cryptor.getFilenameCryptor().encryptFilename(name(), parentDirId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -19,6 +19,7 @@ import java.time.Instant;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
@@ -33,7 +34,7 @@ import org.cryptomator.filesystem.WritableFile;
|
||||
|
||||
class CryptoFolder extends CryptoNode implements Folder {
|
||||
|
||||
static final String DIR_EXT = ".dir";
|
||||
static final String DIR_SUFFIX = "_";
|
||||
|
||||
private final WeakValuedCache<String, CryptoFolder> folders = WeakValuedCache.usingLoader(this::newFolder);
|
||||
private final WeakValuedCache<String, CryptoFile> files = WeakValuedCache.usingLoader(this::newFile);
|
||||
@@ -46,7 +47,7 @@ class CryptoFolder extends CryptoNode implements Folder {
|
||||
@Override
|
||||
protected String encryptedName() {
|
||||
final byte[] parentDirId = parent().map(CryptoFolder::getDirectoryId).map(s -> s.getBytes(UTF_8)).orElse(null);
|
||||
return cryptor.getFilenameCryptor().encryptFilename(name(), parentDirId) + DIR_EXT;
|
||||
return cryptor.getFilenameCryptor().encryptFilename(name(), parentDirId) + DIR_SUFFIX;
|
||||
}
|
||||
|
||||
Folder physicalFolder() {
|
||||
@@ -82,13 +83,16 @@ class CryptoFolder extends CryptoNode implements Folder {
|
||||
|
||||
@Override
|
||||
public Stream<CryptoFile> files() {
|
||||
return physicalFolder().files().map(File::name).filter(s -> s.endsWith(CryptoFile.FILE_EXT)).map(this::decryptChildFileName).map(this::file);
|
||||
return physicalFolder().files().map(File::name).filter(isEncryptedFileName()).map(this::decryptChildFileName).map(this::file);
|
||||
}
|
||||
|
||||
private Predicate<String> isEncryptedFileName() {
|
||||
return (String name) -> cryptor.getFilenameCryptor().isEncryptedFilename(name);
|
||||
}
|
||||
|
||||
private String decryptChildFileName(String encryptedFileName) {
|
||||
final byte[] dirId = getDirectoryId().getBytes(UTF_8);
|
||||
final String ciphertext = StringUtils.removeEnd(encryptedFileName, CryptoFile.FILE_EXT);
|
||||
return cryptor.getFilenameCryptor().decryptFilename(ciphertext, dirId);
|
||||
return cryptor.getFilenameCryptor().decryptFilename(encryptedFileName, dirId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -102,12 +106,16 @@ class CryptoFolder extends CryptoNode implements Folder {
|
||||
|
||||
@Override
|
||||
public Stream<CryptoFolder> folders() {
|
||||
return physicalFolder().files().map(File::name).filter(s -> s.endsWith(CryptoFolder.DIR_EXT)).map(this::decryptChildFolderName).map(this::folder);
|
||||
return physicalFolder().files().map(File::name).filter(isEncryptedDirectoryName()).map(this::decryptChildFolderName).map(this::folder);
|
||||
}
|
||||
|
||||
private Predicate<String> isEncryptedDirectoryName() {
|
||||
return (String name) -> name.endsWith(DIR_SUFFIX) && isEncryptedFileName().test(StringUtils.removeEnd(name, DIR_SUFFIX));
|
||||
}
|
||||
|
||||
private String decryptChildFolderName(String encryptedFolderName) {
|
||||
final byte[] dirId = getDirectoryId().getBytes(UTF_8);
|
||||
final String ciphertext = StringUtils.removeEnd(encryptedFolderName, CryptoFolder.DIR_EXT);
|
||||
final String ciphertext = StringUtils.removeEnd(encryptedFolderName, CryptoFolder.DIR_SUFFIX);
|
||||
return cryptor.getFilenameCryptor().decryptFilename(ciphertext, dirId);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,11 @@ class NoFilenameCryptor implements FilenameCryptor {
|
||||
return BASE32.encodeAsString(hashedBytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEncryptedFilename(String ciphertextName) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String encryptFilename(String cleartextName, byte[]... associatedData) {
|
||||
return cleartextName;
|
||||
|
||||
@@ -19,7 +19,7 @@ import org.cryptomator.filesystem.blacklisting.SamePathPredicate;
|
||||
@Singleton
|
||||
public class ShorteningFileSystemFactory {
|
||||
|
||||
private static final int SHORTENING_THRESHOLD = 140;
|
||||
private static final int SHORTENING_THRESHOLD = 129; // 128 + "_"
|
||||
private static final String METADATA_FOLDER_NAME = "m";
|
||||
|
||||
private final BlacklistingFileSystemFactory blacklistingFileSystemFactory;
|
||||
|
||||
Reference in New Issue
Block a user