From 59ddb1da06353f07f7c686c7bce584dcf4cc2d78 Mon Sep 17 00:00:00 2001 From: Slavasil Date: Fri, 5 Dec 2025 17:52:10 +0300 Subject: [PATCH 1/2] implement IPassStore.Save --- src/KeyKeeper/PasswordStore/IPassStore.cs | 1 + .../PasswordStore/PassStoreFileAccessor.cs | 44 +++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/src/KeyKeeper/PasswordStore/IPassStore.cs b/src/KeyKeeper/PasswordStore/IPassStore.cs index 68a1f6f..617df9b 100644 --- a/src/KeyKeeper/PasswordStore/IPassStore.cs +++ b/src/KeyKeeper/PasswordStore/IPassStore.cs @@ -10,4 +10,5 @@ public interface IPassStore int GetTotalEntryCount(); void Unlock(CompositeKey key); void Lock(); + void Save(); } diff --git a/src/KeyKeeper/PasswordStore/PassStoreFileAccessor.cs b/src/KeyKeeper/PasswordStore/PassStoreFileAccessor.cs index 61ddb4c..640c87e 100644 --- a/src/KeyKeeper/PasswordStore/PassStoreFileAccessor.cs +++ b/src/KeyKeeper/PasswordStore/PassStoreFileAccessor.cs @@ -21,6 +21,7 @@ public class PassStoreFileAccessor : IPassStore private string filename; private byte[]? key; private InnerEncryptionInfo? innerCrypto; + private OuterEncryptionHeader? outerCryptoHdr; private PassStoreEntry? root; public PassStoreFileAccessor(string filename, bool create, StoreCreationOptions? createOptions) @@ -59,6 +60,7 @@ public class PassStoreFileAccessor : IPassStore using FileStream file = new(filename, FileMode.Open, FileAccess.Read, FileShare.None); FileHeader hdr = FileHeader.ReadFrom(file); + outerCryptoHdr = hdr.OuterCryptoHeader; file.Seek((file.Position + 4096 - 1) / 4096 * 4096, SeekOrigin.Begin); @@ -109,6 +111,47 @@ public class PassStoreFileAccessor : IPassStore public void Lock() { if (Locked) return; + Save(); + Array.Fill(key!, 0); + key = null; + } + + public void Save() + { + if (Locked) return; + + // skip file header + using FileStream file = new(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.Read); + FileHeader.ReadFrom(file); + file.Seek((file.Position + 4096 - 1) / 4096 * 4096, SeekOrigin.Begin); + + // write the new contents + using OuterEncryptionWriter cryptoWriter = new(file, key!, ((OuterAesHeader)outerCryptoHdr!).InitVector); + + using (BinaryWriter wr = new(cryptoWriter)) + { + wr.Write(FILE_FIELD_BEGIN); + cryptoWriter.Write(BEGIN_MARKER); + + byte[] innerKey = new byte[32]; + RandomNumberGenerator.Fill(innerKey); + byte[] innerIv = new byte[16]; + RandomNumberGenerator.Fill(innerIv); + + wr.Write(FILE_FIELD_INNER_CRYPTO); + cryptoWriter.Write(innerKey); + cryptoWriter.Write(innerIv); + + wr.Write(FILE_FIELD_CONFIG); + + wr.Write(FILE_FIELD_STORE); + root!.WriteToStream(cryptoWriter); + + wr.Write(FILE_FIELD_END); + } + cryptoWriter.Flush(); + + file.SetLength(file.Position); } /// @@ -166,6 +209,7 @@ public class PassStoreFileAccessor : IPassStore using FileStream file = File.Open(filename, FileMode.Create, FileAccess.Write, FileShare.None); FileHeader newHeader = FileHeader.Default(); newHeader.WriteTo(file); + outerCryptoHdr = newHeader.OuterCryptoHeader; options.Key.Salt = newHeader.PreSalt; From b143d9233d954c6846b649e2ee48ca5a67006e3d Mon Sep 17 00:00:00 2001 From: Artem Bugaev Date: Fri, 5 Dec 2025 20:21:15 +0300 Subject: [PATCH 2/2] Add button to save passwords --- src/KeyKeeper/ViewModels/UnlockedRepositoryViewModel.cs | 5 +++++ src/KeyKeeper/Views/RepositoryWindow.axaml | 1 + src/KeyKeeper/Views/RepositoryWindow.axaml.cs | 9 +++++++++ 3 files changed, 15 insertions(+) diff --git a/src/KeyKeeper/ViewModels/UnlockedRepositoryViewModel.cs b/src/KeyKeeper/ViewModels/UnlockedRepositoryViewModel.cs index 23b2e71..3433c21 100644 --- a/src/KeyKeeper/ViewModels/UnlockedRepositoryViewModel.cs +++ b/src/KeyKeeper/ViewModels/UnlockedRepositoryViewModel.cs @@ -10,4 +10,9 @@ public class UnlockedRepositoryViewModel : ViewModelBase { passStore = store; } + + public void Save() + { + passStore.Save(); + } } \ No newline at end of file diff --git a/src/KeyKeeper/Views/RepositoryWindow.axaml b/src/KeyKeeper/Views/RepositoryWindow.axaml index e215380..c660103 100644 --- a/src/KeyKeeper/Views/RepositoryWindow.axaml +++ b/src/KeyKeeper/Views/RepositoryWindow.axaml @@ -44,6 +44,7 @@