diff --git a/Bitvault.Avalonia/App.axaml.cs b/Bitvault.Avalonia/App.axaml.cs index c298628..8e2b00d 100644 --- a/Bitvault.Avalonia/App.axaml.cs +++ b/Bitvault.Avalonia/App.axaml.cs @@ -4,10 +4,8 @@ using Avalonia.Markup.Xaml; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using System; using Toolkit.Avalonia; using Toolkit.Foundation; -using System.IO; using Microsoft.Extensions.DependencyInjection.Extensions; namespace Bitvault.Avalonia; @@ -21,15 +19,6 @@ public partial class App : Application public override async void OnFrameworkInitializationCompleted() { - //var connectionString = new SqliteConnectionStringBuilder(@"Filename=C:\\Users\\dan_c\\source\\repos\\Bitvault\\Bitvault.Avalonia.Desktop\\bin\\Debug\\net8.0\\SQssLite.sql") - //{ - // Mode = SqliteOpenMode.ReadWriteCreate, - // Password = "Test123" - //}.ToString(); - - //var connection = new SqliteConnection(connectionString); - //connection.Open(); - //var command = connection.CreateCommand(); //command.CommandText = "SELECT quote($newPassword);"; //command.Parameters.AddWithValue("$newPassword", "Test123"); @@ -65,7 +54,6 @@ public partial class App : Application services.AddTransient(); services.AddTransient(); - services.AddTransient(); services.AddTransient(); services.TryAddSingleton, Container>(); services.TryAddSingleton, Container>(); diff --git a/Bitvault/CreateVaultHandler.cs b/Bitvault/CreateVaultHandler.cs index abd9de6..e27a4c4 100644 --- a/Bitvault/CreateVaultHandler.cs +++ b/Bitvault/CreateVaultHandler.cs @@ -1,5 +1,6 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; +using System.Text; using Toolkit.Foundation; namespace Bitvault; @@ -15,10 +16,22 @@ public class CreateVaultHandler(IVaultComponentFactory componentFactory) : { if (componentFactory.Create(name) is IComponentHost host) { - IVaultInitializer initializer = host.Services.GetRequiredService(); - if (await initializer.Initialize(name, password)) + IVaultKeyFactory keyVaultFactory = host.Services.GetRequiredService(); + IContainer vaultKeyContainer = host.Services.GetRequiredService>(); + IVaultStorage vaultStorage = host.Services.GetRequiredService(); + + VaultKey key = keyVaultFactory.Create(Encoding.UTF8.GetBytes(password)); + vaultKeyContainer.Set(key); + + if (await vaultStorage.CreateAsync(name, key)) { + IWritableConfiguration configuration = + host.Services.GetRequiredService>(); + + configuration.Write(args => args.Key = $"{Convert.ToBase64String(key.Salt)}:{Convert.ToBase64String(key.EncryptedKey)}:{Convert.ToBase64String(key.DecryptedKey)}"); host.Start(); + + return true; } } } diff --git a/Bitvault/IVaultInitializer.cs b/Bitvault/IVaultInitializer.cs deleted file mode 100644 index 4054b05..0000000 --- a/Bitvault/IVaultInitializer.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Bitvault; - -public interface IVaultInitializer -{ - Task Initialize(string name, string password); -} diff --git a/Bitvault/IVaultKeyFactory.cs b/Bitvault/IVaultKeyFactory.cs index 3d5bda2..1037ba8 100644 --- a/Bitvault/IVaultKeyFactory.cs +++ b/Bitvault/IVaultKeyFactory.cs @@ -2,5 +2,7 @@ public interface IVaultKeyFactory { - VaultKey Create(string password); + VaultKey Create(byte[] phrase, + byte[]? encryptedKey = null, + byte[]? salt = null); } diff --git a/Bitvault/OpenVaultHandler.cs b/Bitvault/OpenVaultHandler.cs index adab259..077fff8 100644 --- a/Bitvault/OpenVaultHandler.cs +++ b/Bitvault/OpenVaultHandler.cs @@ -1,18 +1,28 @@ -using Toolkit.Foundation; +using System.Text; +using Toolkit.Foundation; namespace Bitvault; -public class OpenVaultHandler(IMediator mediator) : +public class OpenVaultHandler(VaultConfiguration configuration, + IVaultKeyFactory keyVaultFactory, + IVaultStorage vaultStorage) : IHandler, bool> { public async Task Handle(Open args, CancellationToken cancellationToken) { - if (args.Value is Vault vault) + if (args.Value is Vault vault && configuration.Name is { Length: > 0 } name && vault.Password is { Length: > 0 } password) { - if (vault.Password is { Length: > 0 } password) + if (configuration.Key?.Split(':') is { Length: >= 2 } keyPart) { - + byte[]? salt = Convert.FromBase64String(keyPart[0]); + byte[]? encryptedKey = Convert.FromBase64String(keyPart[1]); + + VaultKey key = keyVaultFactory.Create(Encoding.UTF8.GetBytes(password), encryptedKey, salt); + if (await vaultStorage.CreateAsync(name, key)) + { + + } } } diff --git a/Bitvault/OpenVaultStorageHandler.cs b/Bitvault/OpenVaultStorageHandler.cs deleted file mode 100644 index 1ae70c2..0000000 --- a/Bitvault/OpenVaultStorageHandler.cs +++ /dev/null @@ -1,41 +0,0 @@ -//using Microsoft.EntityFrameworkCore; -//using Microsoft.Extensions.Hosting; -//using Toolkit.Foundation; - -//namespace Bitvault; - -//public class OpenVaultStorageHandler(IHostEnvironment environment, -// IDbContextFactory dbContextFactory) : IHandler, bool> -//{ -// public async Task Handle(Open args, CancellationToken cancellationToken) -// { -// if (args.Value is VaultStorage vault) -// { -// if (vault.Name is { Length: > 0 } name && vault.Password is { Length: > 0 } password) -// { -// using VaultDbContext context = dbContextFactory.CreateDbContext(); -// var d = context.Database.GetDbConnection().ConnectionString; -// context.Database.SetConnectionString($"Data Source={Path.Combine(environment.ContentRootPath, name)}.vault;Mode=ReadWriteCreate;Password={password}"); - -// bool isOpen = false; -// await Task.Run(async () => -// { -// try -// { -// await context.Database.OpenConnectionAsync(); -// isOpen = true; -// } -// catch -// { -// // We are ignoring this exception as it is either a go, or not. -// } - -// }, cancellationToken); - -// return isOpen; -// } -// } - -// return false; -// } -//} diff --git a/Bitvault/VaultInitializer.cs b/Bitvault/VaultInitializer.cs deleted file mode 100644 index d8e5855..0000000 --- a/Bitvault/VaultInitializer.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Toolkit.Foundation; - -namespace Bitvault; - -public class VaultStorageConnection(string connection) -{ - private readonly string connection = connection; - - public override string ToString() => connection; -} - -public class VaultInitializer(IVaultKeyFactory keyVaultFactory, - IContainer vaultKeyContainer, - IVaultStorage vaultStorage, - IWritableConfiguration configuration) : - IVaultInitializer -{ - public async Task Initialize(string name, - string password) - { - VaultKey key = keyVaultFactory.Create(password); - vaultKeyContainer.Set(key); - - if (await vaultStorage.CreateAsync(name, key)) - { - configuration.Write(args => args.Key = $"{Convert.ToBase64String(key.Phrase)}:{Convert.ToBase64String(key.Public)}"); - return true; - } - - return false; - } -} diff --git a/Bitvault/VaultKey.cs b/Bitvault/VaultKey.cs index a61ddcb..5218a35 100644 --- a/Bitvault/VaultKey.cs +++ b/Bitvault/VaultKey.cs @@ -1,14 +1,14 @@ namespace Bitvault; -public record VaultKey(byte[] Phrase, byte[] Public, byte[] Private) : +public record VaultKey(byte[] Salt, byte[] EncryptedKey, byte[] DecryptedKey) : IDisposable { public void Dispose() { GC.SuppressFinalize(this); - Array.Clear(Phrase, 0, Phrase.Length); - Array.Clear(Public, 0, Public.Length); - Array.Clear(Private, 0, Private.Length); + Array.Clear(Salt, 0, Salt.Length); + Array.Clear(EncryptedKey, 0, EncryptedKey.Length); + Array.Clear(DecryptedKey, 0, DecryptedKey.Length); } } \ No newline at end of file diff --git a/Bitvault/VaultKeyFactory.cs b/Bitvault/VaultKeyFactory.cs index 0c1c2ac..3598b6d 100644 --- a/Bitvault/VaultKeyFactory.cs +++ b/Bitvault/VaultKeyFactory.cs @@ -8,17 +8,17 @@ public class VaultKeyFactory(IKeyGenerator generator, IDecryptor decryptor) : IVaultKeyFactory { - public VaultKey Create(string password) + public VaultKey Create(byte[] phrase, + byte[]? encryptedKey = null, + byte[]? salt = null) { - byte[] salt = generator.Generate(16); - byte[] key = generator.Generate(32); + salt ??= generator.Generate(16); + byte[] derivedKey = deriver.DeriveKey(phrase, salt); - byte[] derivedKey = deriver.DeriveKey(password, salt); + encryptedKey ??= encryptor.Encrypt(generator.Generate(32), derivedKey); + byte[] decryptedKey = decryptor.Decrypt(encryptedKey, derivedKey); - byte[] publicKey = encryptor.Encrypt(key, derivedKey); - byte[] privateKey = decryptor.Decrypt(publicKey, derivedKey); - - return new VaultKey(salt, publicKey, privateKey); + return new VaultKey(salt, encryptedKey, decryptedKey); } } diff --git a/Bitvault/VaultStorage.cs b/Bitvault/VaultStorage.cs index 8a4759d..0c8e406 100644 --- a/Bitvault/VaultStorage.cs +++ b/Bitvault/VaultStorage.cs @@ -14,7 +14,7 @@ public class VaultStorage(IContainer connection, VaultKey key) { connection.Set(new VaultStorageConnection($"Data Source={Path.Combine(environment.ContentRootPath, name)}" + - $".vault;Mode=ReadWriteCreate;Pooling=false;Password={Convert.ToBase64String(key.Private)}")); + $".vault;Mode=ReadWriteCreate;Pooling=false;Password={Convert.ToBase64String(key.DecryptedKey)}")); IDbContextFactory dbContextFactory = provider.GetRequiredService>(); using VaultDbContext context = await dbContextFactory.CreateDbContextAsync(); diff --git a/Bitvault/VaultStorageConnection.cs b/Bitvault/VaultStorageConnection.cs new file mode 100644 index 0000000..061ff9f --- /dev/null +++ b/Bitvault/VaultStorageConnection.cs @@ -0,0 +1,8 @@ +namespace Bitvault; + +public class VaultStorageConnection(string connection) +{ + private readonly string connection = connection; + + public override string ToString() => connection; +}