public void DirectoryPair_NestedFolders() { ResetDirectory(); string password = "******"; using (var origToEncr = DirectoryPair.Open("1-Orig", "2-Encr", DerivedBytesProvider.FromPassword(password), true, HelixFileVersion.UnitTest)) using (var encrToDecr = DirectoryPair.Open("3-Decr", "2-Encr", DerivedBytesProvider.FromPassword(password), true, HelixFileVersion.UnitTest)) { //Creates nested folders Directory.CreateDirectory(Util.Path("1-Orig/Nested/Directory")); File.WriteAllText(Util.Path("1-Orig/Nested/File.txt"), "nested content"); //Orig => Encr origToEncr.SyncChanges(); Assert.AreEqual(0, origToEncr.FindChanges().Count); //Encr => Decr encrToDecr.SyncChanges(); Assert.AreEqual(0, origToEncr.FindChanges().Count); //Verifies nested folders Assert.IsTrue(Directory.Exists(Util.Path("3-Decr/Nested/Directory")), "Directory Exists: 3-Decr/Nested/Directory"); Assert.IsTrue(File.Exists(Util.Path("3-Decr/Nested/File.txt")), "File Exists: 3-Decr/Nested/File.txt"); } ResetDirectory(); }
public void HelixFileDecryptor_WrongPassword() { using (MemoryStream stream = new MemoryStream()) using (HelixFileEncryptor encryptor = new HelixFileEncryptor(stream, DerivedBytesProvider.FromPassword("password"), HelixFileVersion.UnitTest)) { var header = new FileEntry(); header.FileName = "testfile.txt"; encryptor.WriteHeader(header); encryptor.WriteContent("example content"); encryptor.FlushFinalBlock(); Assert.IsTrue(stream.Length > 10); stream.Position = 0; try { using (HelixFileDecryptor decryptor = new HelixFileDecryptor(stream)) { decryptor.Initialize(DerivedBytesProvider.FromPassword("wrongpassword")); var header2 = decryptor.ReadHeader(); Assert.AreEqual(header.FileName, header2.FileName); var content = decryptor.GetContentString(); Assert.AreEqual("example content", content); } Assert.IsTrue(false, "Expecting InvalidPasswordException"); } catch (InvalidPasswordException) { } } }
public void HelixFileDecryptor_UnflushedEncryptThrowsException() { try { using (MemoryStream stream = new MemoryStream()) { FileEntry headerSaved; using (HelixFileEncryptor encryptor = new HelixFileEncryptor(stream, DerivedBytesProvider.FromPassword("password"), HelixFileVersion.UnitTest)) { headerSaved = new FileEntry(); headerSaved.FileName = "testfile.txt"; encryptor.WriteHeader(headerSaved); encryptor.WriteContent("example content"); Assert.IsTrue(stream.Length > 10); using (var readStream = new MemoryStream(stream.ToArray(), false)) using (HelixFileDecryptor decryptor = new HelixFileDecryptor(readStream)) { decryptor.Initialize(DerivedBytesProvider.FromPassword("password")); var header2 = decryptor.ReadHeader(); Assert.AreEqual(headerSaved.FileName, header2.FileName); var content = decryptor.GetContentString(); Assert.AreEqual("example content", content); } } } Assert.IsTrue(false, "Expected a HelixException to be raised"); } catch (HelixException) { } }
public void HelixFileDecryptor_EncryptThenDecrypt() { using (MemoryStream stream = new MemoryStream()) { FileEntry headerSaved; using (HelixFileEncryptor encryptor = new HelixFileEncryptor(stream, DerivedBytesProvider.FromPassword("password"), HelixFileVersion.UnitTest)) { headerSaved = new FileEntry(); headerSaved.FileName = "testfile.txt"; encryptor.WriteHeader(headerSaved); encryptor.WriteContent("example content"); Assert.IsTrue(stream.Length > 10); } //Assert.IsTrue(stream.CanRead, "stream.CanRead"); //Assert.IsTrue(stream.CanWrite, "stream.CanWrite"); using (var readStream = new MemoryStream(stream.ToArray(), false)) using (HelixFileDecryptor decryptor = new HelixFileDecryptor(readStream)) { decryptor.Initialize(DerivedBytesProvider.FromPassword("password")); var header2 = decryptor.ReadHeader(); Assert.AreEqual(headerSaved.FileName, header2.FileName); var content = decryptor.GetContentString(); Assert.AreEqual("example content", content); } } }
public void HelixFileDecryptor_DecryptHeaderOnlyLargeFile() { byte[] b = new byte[50000]; System.Security.Cryptography.RandomNumberGenerator.Create().GetBytes(b); byte[] enc; using (MemoryStream originalContent = new MemoryStream(b, 0, b.Length)) using (MemoryStream encryptedStream = new MemoryStream()) using (var encryptor = new HelixFileEncryptor(encryptedStream, DerivedBytesProvider.FromPassword("password"), HelixFileVersion.UnitTest)) { encryptor.WriteHeader(new FileEntry()); encryptor.WriteContent(originalContent); encryptor.FlushFinalBlock(); enc = encryptedStream.ToArray(); Assert.IsTrue(enc.Length > 50000); } using (MemoryStream encryptedStream = new MemoryStream(enc, true)) using (var decryptor = new HelixFileDecryptor(encryptedStream)) { decryptor.Initialize(DerivedBytesProvider.FromPassword("password")); var header = decryptor.ReadHeader(); Assert.IsNotNull(header); decryptor.Dispose(); } }
public void DirectoryHeader_ThrowsExceptionWhenLoading() { var newHeader = DirectoryHeader.New(); newHeader.GetType().GetProperty(nameof(newHeader.DirectoryId)).SetValue(newHeader, "currupt**"); newHeader.Save("header.hx", DerivedBytesProvider.FromPassword("password"), HelixFileVersion.UnitTest); try { DirectoryHeader.Load("header.hx", DerivedBytesProvider.FromPassword("password")); Assert.IsTrue(false, "Did not detect curruption"); } catch (HelixException) { } }
public void DirectoryHeader_NewSaveLoad() { var newHeader = DirectoryHeader.New(); DateTime start = DateTime.Now; newHeader.Save("header.hx", DerivedBytesProvider.FromPassword("password"), HelixFileVersion.UnitTest); double dur = (DateTime.Now - start).TotalMilliseconds; var loadHeader = DirectoryHeader.Load("header.hx", DerivedBytesProvider.FromPassword("password")); //Assert.AreEqual(newHeader.DerivedBytesProvider.GetDerivedBytes().Key.ToHex(), loadHeader.DerivedBytesProvider.Key.ToHex()); //Assert.AreEqual(newHeader.DerivedBytesProvider.GetDerivedBytes().Salt.ToHex(), loadHeader.DerivedBytesProvider.Salt.ToHex()); Assert.AreEqual(newHeader.FileNameKey.ToHex(), loadHeader.FileNameKey.ToHex()); Assert.AreEqual(newHeader.DirectoryId, loadHeader.DirectoryId); File.Delete("header.hx"); }
public void DirectoryPair_RenameCaseOnly() { string password = "******"; ResetDirectory(); Directory.CreateDirectory("1-Orig"); File.WriteAllText(Util.Path("1-Orig/file.txt"), "hello"); using (var origToEncr = DirectoryPair.Open("1-Orig", "2-Encr", DerivedBytesProvider.FromPassword(password), true, HelixFileVersion.UnitTest)) using (var encrToDecr = DirectoryPair.Open("3-Decr", "2-Encr", DerivedBytesProvider.FromPassword(password), true, HelixFileVersion.UnitTest)) { //Orig => Encr origToEncr.SyncChanges(); Assert.AreEqual(0, origToEncr.FindChanges().Count); //Encr => Decr encrToDecr.SyncChanges(); Assert.AreEqual(0, origToEncr.FindChanges().Count); } System.Threading.Thread.Sleep(timeStampPrecision); File.Move(Util.Path("1-Orig/file.txt"), Util.Path("1-Orig/FILE1.txt")); File.Move(Util.Path("1-Orig/FILE1.txt"), Util.Path("1-Orig/FILE.txt")); using (var origToEncr = DirectoryPair.Open("1-Orig", "2-Encr", DerivedBytesProvider.FromPassword(password), true, HelixFileVersion.UnitTest)) using (var encrToDecr = DirectoryPair.Open("3-Decr", "2-Encr", DerivedBytesProvider.FromPassword(password), true, HelixFileVersion.UnitTest)) { //Orig => Encr Assert.AreEqual(2, origToEncr.FindChanges().Count); //delete + create origToEncr.SyncChanges(); Assert.AreEqual(0, origToEncr.FindChanges().Count); //Encr => Decr Assert.AreEqual(2, encrToDecr.FindChanges().Count); //delete + create Assert.IsTrue(encrToDecr.FindChanges().All(e => e.SyncMode == PreSyncMode.EncryptedSide)); encrToDecr.SyncChanges(); Assert.AreEqual(0, origToEncr.FindChanges().Count); Assert.AreEqual("FILE.txt", (new DirectoryInfo(@"1-Orig")).GetFileSystemInfos("*.txt").First().Name); } //Assert.IsTrue(false, "Sometimes fails, sometimes works depending on the order (false until properly fixed)"); }
public void DirectoryPair_RandomizedInitialization() { RandomValue.NewTest(1836678571); for (int i = 0; i < 10; i++) { var dirStruct = RandomValue.GetDirectoryStructure(10) .Where(d => HelixUtil.IsValidPath(d)) .ToArray(); ResetDirectory(); var setupItems = RandomValue.ChooseMany(dirStruct); foreach (var item in setupItems) { if (item.EndsWith(Path.DirectorySeparatorChar.ToString())) { Directory.CreateDirectory(Path.GetDirectoryName(Path.Combine("1-Orig", item + "a"))); } else { var fileName = Path.Combine("1-Orig", item); //Creates parent directory Directory.CreateDirectory(Path.GetDirectoryName(Path.Combine("1-Orig", item + "a"))); File.WriteAllText(fileName, RandomValue.GetValue <string>()); } } string password = RandomValue.GetValue <string>() ?? ""; using (var origToEncr = DirectoryPair.Open("2-Encr", "1-Orig", DerivedBytesProvider.FromPassword(password), true, HelixFileVersion.UnitTest)) using (var encrToDecr = DirectoryPair.Open("2-Encr", "3-Decr", DerivedBytesProvider.FromPassword(password), true, HelixFileVersion.UnitTest)) { //Orig => Encr origToEncr.SyncChanges(); Assert.AreEqual(0, origToEncr.FindChanges().Count); //Encr => Decr encrToDecr.SyncChanges(); Assert.AreEqual(0, origToEncr.FindChanges().Count); } } }
public void DirectoryPair_DecrToEncr() { if (Directory.Exists("Orig")) { Directory.Delete("Orig", true); } if (Directory.Exists("Decr")) { Directory.Delete("Decr", true); } if (Directory.Exists("Encr")) { Directory.Delete("Encr", true); } Directory.CreateDirectory("Orig"); Directory.CreateDirectory("Encr"); Directory.CreateDirectory("Decr"); //New (Orig => Encr) Util.WriteTextFile("Orig/test.txt", "hello world"); using (var origToEncr = DirectoryPair.Open("Orig", "Encr", DerivedBytesProvider.FromPassword("password"), true, HelixFileVersion.UnitTest)) using (var encrToDecr = DirectoryPair.Open("Decr", "Encr", DerivedBytesProvider.FromPassword("password"), true, HelixFileVersion.UnitTest)) { var changes = origToEncr.FindChanges(clearCache: false); Assert.AreEqual(1, changes.Count); Assert.AreEqual("test.txt", changes[0].DecrFileName); Assert.AreEqual(SyncStatus.Success, origToEncr.TrySync(changes[0]).SyncStatus); changes = origToEncr.FindChanges(clearCache: true); Assert.IsTrue(0 == changes.Count, "Single file sync still contains changes"); //New (Encr => Decr) changes = encrToDecr.FindChanges(clearCache: true); Assert.AreEqual(1, changes.Count); Assert.IsTrue(changes[0].SyncMode == PreSyncMode.EncryptedSide); Assert.IsTrue(changes[0].EncrFileName.EndsWith(".hx")); Assert.AreEqual(SyncStatus.Success, encrToDecr.TrySync(changes[0]).SyncStatus); Assert.AreEqual(0, encrToDecr.FindChanges(clearCache: true).Count); Assert.AreEqual(HelixUtil.TruncateTicks(File.GetLastWriteTimeUtc(Util.Path("Orig/test.txt"))), HelixUtil.TruncateTicks(File.GetLastWriteTimeUtc(Util.Path("Decr/test.txt")))); Assert.AreEqual("hello world", File.ReadAllText(Path.Combine("Decr", "test.txt"))); //Add (Orig => Encr) origToEncr.ClearCache(); Util.WriteTextFile("Orig/test2.txt", "aa"); changes = origToEncr.FindChanges(clearCache: true); Assert.AreEqual(1, changes.Count); Assert.IsTrue(changes[0].SyncMode == PreSyncMode.DecryptedSide); Assert.AreEqual("test2.txt", changes[0].DecrFileName); Assert.AreEqual(SyncStatus.Success, origToEncr.TrySync(changes[0]).SyncStatus); Assert.AreEqual(0, origToEncr.FindChanges(clearCache: true).Count); //Add (Encr => Decr) encrToDecr.ClearCache(); changes = encrToDecr.FindChanges(clearCache: true); Assert.AreEqual(1, changes.Count); Assert.IsTrue(changes[0].SyncMode == PreSyncMode.EncryptedSide); Assert.IsTrue(changes[0].EncrFileName.EndsWith(".hx")); Assert.AreEqual(SyncStatus.Success, encrToDecr.TrySync(changes[0]).SyncStatus); Assert.AreEqual(0, encrToDecr.FindChanges().Count); Assert.AreEqual(HelixUtil.TruncateTicks(File.GetLastWriteTimeUtc(Util.Path("Orig/test2.txt"))), HelixUtil.TruncateTicks(File.GetLastWriteTimeUtc(Util.Path(@"Decr/test2.txt")))); Assert.AreEqual("aa", File.ReadAllText(Util.Path("Decr/test2.txt"))); //System.Threading.Thread.Sleep(timeStampPrecision); //ensure the timestap changes //Update (Orig => Encr) origToEncr.ClearCache(); Util.WriteTextFile("Orig/test.txt", "hello world2"); changes = origToEncr.FindChanges(); Assert.AreEqual(1, changes.Count); Assert.IsTrue(changes[0].SyncMode == PreSyncMode.DecryptedSide); Assert.AreEqual("test.txt", changes[0].DecrFileName); Assert.AreEqual(SyncStatus.Success, origToEncr.TrySync(changes[0]).SyncStatus); Assert.AreEqual(0, origToEncr.FindChanges().Count); //Update (Encr => Decr) encrToDecr.ClearCache(); changes = encrToDecr.FindChanges(); Assert.AreEqual(1, changes.Count); Assert.IsTrue(changes[0].SyncMode == PreSyncMode.EncryptedSide); Assert.IsTrue(changes[0].EncrFileName.EndsWith(".hx")); Assert.AreEqual(SyncStatus.Success, encrToDecr.TrySync(changes[0]).SyncStatus); Assert.AreEqual(0, encrToDecr.FindChanges().Count); Assert.AreEqual( HelixUtil.TruncateTicks(File.GetLastWriteTimeUtc(Util.Path("Orig/test.txt"))), HelixUtil.TruncateTicks(File.GetLastWriteTimeUtc(Util.Path("Decr/test.txt")))); Assert.AreEqual("hello world2", File.ReadAllText(Util.Path("Decr/test.txt"))); //Delete (Orig => Encr) origToEncr.ClearCache(); File.Delete(Util.Path("Orig/test.txt")); changes = origToEncr.FindChanges(); Assert.AreEqual(1, changes.Count); Assert.IsTrue(changes[0].SyncMode == PreSyncMode.DecryptedSide); Assert.AreEqual("test.txt", changes[0].DecrFileName); Assert.AreEqual(SyncStatus.Success, origToEncr.TrySync(changes[0]).SyncStatus); Assert.IsTrue(origToEncr.SyncLog.FindByDecrFileName("test.txt").EntryType == FileEntryType.Removed); Assert.AreEqual(0, origToEncr.FindChanges().Count); //Delete (Encr => Decr) encrToDecr.ClearCache(); changes = encrToDecr.FindChanges(); Assert.IsTrue(1 == changes.Count, "Delete change did not propigate correctly"); Assert.IsTrue(changes[0].SyncMode == PreSyncMode.EncryptedSide); Assert.IsTrue(changes[0].EncrFileName.EndsWith(".hx")); Assert.AreEqual(SyncStatus.Success, encrToDecr.TrySync(changes[0]).SyncStatus); Assert.IsFalse(File.Exists(Util.Path("Decr/test.txt")), "Missing file Decr/test.txt"); } }
public void FindChanges_RemovesInOrderParentToChildren() { Decr1.UpdateTo("file1.txt < aa", "zz/file2.txt"); using (var pair = DirectoryPair.Open(Decr1.DirectoryPath, Encr1.DirectoryPath, DerivedBytesProvider.FromPassword("password"), true, HelixFileVersion.UnitTest)) { pair.SyncChanges(); Decr1.UpdateTo(""); for (int i = 0; i < 100; i++) { var changes = pair.FindChanges(); var parentIndex = changes.FindIndex(c => c.DecrFileName == "zz"); var childIndex = changes.FindIndex(c => HelixUtil.PathNative(c.DecrFileName) == HelixUtil.PathNative("zz/file2.txt")); Assert.IsTrue(parentIndex > childIndex, "Parent Directory Add did not come before Child File Add"); } } }
public void FindChanges_CaseChangeDeletesBeforeAdds() { Decr1.UpdateTo("file1.txt"); using (var pair = DirectoryPair.Open(Decr1.DirectoryPath, Encr1.DirectoryPath, DerivedBytesProvider.FromPassword("password"), true, HelixFileVersion.UnitTest)) { pair.SyncChanges(); Decr1.UpdateTo("FILE1.txt"); for (int i = 0; i < 100; i++) { var changes = pair.FindChanges(); var deleteIndex = changes.FindIndex(c => c.DecrFileName == "file1.txt"); var addIndex = changes.FindIndex(c => c.DecrFileName == "FILE1.txt"); Assert.IsTrue(deleteIndex < addIndex, "Case Rename did not order delete before add"); } } }
public void FindChanges_ReturtsInRandomOrder() { Decr1.UpdateTo("file1.txt < aa", "file2.txt", "file3.txt"); HashSet <int> indexes = new HashSet <int>(); using (var pair = DirectoryPair.Open(Decr1.DirectoryPath, Encr1.DirectoryPath, DerivedBytesProvider.FromPassword("password"), true, HelixFileVersion.UnitTest)) { for (int i = 0; i < 100; i++) { var changes = pair.FindChanges(); var index = changes.FindIndex(c => c.DecrFileName == "file1.txt"); indexes.Add(index); } Assert.IsTrue(indexes.Count == 3, "file1.txt not found in all random spots"); } }
public SyncLogEntry[] Decr1AndEncr1SyncLog() { using var pair = new DirectoryPair(Decr1.DirectoryPath, Encr1.DirectoryPath, DerivedBytesProvider.FromPassword("secret"), true); pair.OpenEncr(null); pair.OpenDecr(null); return(pair.SyncLog.ToArray()); }