Преглед изворни кода

new vault-internal file extensions (no extension at all for files, "_" suffix for directories)

Sebastian Stenzel пре 9 година
родитељ
комит
4d2a786504

+ 8 - 0
main/filesystem-crypto/src/main/java/org/cryptomator/crypto/engine/FilenameCryptor.java

@@ -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

+ 5 - 0
main/filesystem-crypto/src/main/java/org/cryptomator/crypto/engine/impl/FilenameCryptorImpl.java

@@ -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);

+ 1 - 3
main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/crypto/CryptoFile.java

@@ -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

+ 15 - 7
main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/crypto/CryptoFolder.java

@@ -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);
 	}
 

+ 5 - 0
main/filesystem-crypto/src/test/java/org/cryptomator/crypto/engine/NoFilenameCryptor.java

@@ -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;

+ 1 - 1
main/filesystem-nameshortening/src/main/java/org/cryptomator/filesystem/shortening/ShorteningFileSystemFactory.java

@@ -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;