diff --git a/Bitvault.Avalonia.Desktop/Bitvault.Avalonia.Desktop.csproj b/Bitvault.Avalonia.Desktop/Bitvault.Avalonia.Desktop.csproj
index 182cb26..292dd06 100644
--- a/Bitvault.Avalonia.Desktop/Bitvault.Avalonia.Desktop.csproj
+++ b/Bitvault.Avalonia.Desktop/Bitvault.Avalonia.Desktop.csproj
@@ -5,6 +5,8 @@
enable
true
app.manifest
+ true
+ win-x64
diff --git a/Bitvault.Avalonia/App.axaml.cs b/Bitvault.Avalonia/App.axaml.cs
index d7c67d4..c298628 100644
--- a/Bitvault.Avalonia/App.axaml.cs
+++ b/Bitvault.Avalonia/App.axaml.cs
@@ -4,8 +4,11 @@ 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;
@@ -61,17 +64,21 @@ public partial class App : Application
services.AddTransient();
services.AddTransient();
- services.AddTransient();
- services.AddTransient();
+ services.AddTransient();
+ services.AddTransient();
services.AddTransient();
+ services.TryAddSingleton, Container>();
+ services.TryAddSingleton, Container>();
- services.AddDbContextFactory(args =>
+ services.AddDbContextFactory((provider, args) =>
{
- args.UseSqlite();
+ if (provider.GetRequiredService>()
+ is IContainer connection)
+ {
+ args.UseSqlite($"{connection.Value}");
+ }
});
- services.AddDbContextFactory();
-
services.AddHandler();
services.AddTemplate();
diff --git a/Bitvault/AesDecryptor.cs b/Bitvault/AesDecryptor.cs
deleted file mode 100644
index 6e4d359..0000000
--- a/Bitvault/AesDecryptor.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System.Security.Cryptography;
-
-namespace Bitvault;
-
-public class AesDecryptor :
- IDecryptor
-{
- private const int IvSize = 16;
-
- public byte[] Decrypt(byte[] cipher, byte[] key)
- {
- Span iv = cipher.AsSpan(0, IvSize);
- ReadOnlySpan encryptedContent = cipher.AsSpan(IvSize);
-
- using Aes aes = Aes.Create();
- aes.Key = key;
- aes.IV = iv.ToArray();
-
- using MemoryStream memoryStream = new(encryptedContent.ToArray());
- using ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
- using CryptoStream cryptoStream = new(memoryStream, decryptor, CryptoStreamMode.Read);
-
- using MemoryStream resultStream = new();
- cryptoStream.CopyTo(resultStream);
-
- return resultStream.ToArray();
- }
-}
diff --git a/Bitvault/AesEncryptor.cs b/Bitvault/AesEncryptor.cs
deleted file mode 100644
index fec9065..0000000
--- a/Bitvault/AesEncryptor.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-using System.Security.Cryptography;
-
-namespace Bitvault;
-
-public class AesEncryptor :
- IEncryptor
-{
- private const int IvSize = 16;
-
- public byte[] Encrypt(byte[] data,
- byte[] key)
- {
- if (key.Length != 32)
- {
- throw new ArgumentException("Key must be 256 bits (32 bytes).");
- }
-
- using Aes aes = Aes.Create();
- aes.Key = key;
- aes.GenerateIV();
-
- using MemoryStream memoryStream = new();
- memoryStream.Write(aes.IV.AsSpan(0, IvSize));
-
- using (ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV))
- using (CryptoStream cryptoStream = new(memoryStream, encryptor, CryptoStreamMode.Write))
- {
- cryptoStream.Write(data, 0, data.Length);
- cryptoStream.FlushFinalBlock();
- }
-
- return memoryStream.ToArray();
- }
-}
diff --git a/Bitvault/CreateVaultHandler.cs b/Bitvault/CreateVaultHandler.cs
index 46cddb1..abd9de6 100644
--- a/Bitvault/CreateVaultHandler.cs
+++ b/Bitvault/CreateVaultHandler.cs
@@ -1,25 +1,28 @@
using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
using Toolkit.Foundation;
namespace Bitvault;
-public class CreateVaultHandler(IVaultComponentFactory vaultComponentFactory) :
+public class CreateVaultHandler(IVaultComponentFactory componentFactory) :
IHandler, bool>
{
- public Task Handle(Create args,
+ public async Task Handle(Create args,
CancellationToken cancellationToken)
{
- if (args.Value is Vault vault && vault.Name is { Length: > 0 } name && vault.Password is { Length: > 0 } password)
+ if (args.Value is Vault vault && vault.Name is { Length: > 0 } name &&
+ vault.Password is { Length: > 0 } password)
{
- if (vaultComponentFactory.Create(name) is IComponentHost host)
+ if (componentFactory.Create(name) is IComponentHost host)
{
- IVaultFactory factory = host.Services.GetRequiredService();
- factory.Create(name, password);
-
- return Task.FromResult(true);
+ IVaultInitializer initializer = host.Services.GetRequiredService();
+ if (await initializer.Initialize(name, password))
+ {
+ host.Start();
+ }
}
}
- return Task.FromResult(false);
+ return false;
}
}
\ No newline at end of file
diff --git a/Bitvault/IDecryptor.cs b/Bitvault/IDecryptor.cs
deleted file mode 100644
index bfe8f27..0000000
--- a/Bitvault/IDecryptor.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Bitvault;
-
-public interface IDecryptor
-{
- byte[] Decrypt(byte[] cipher,
- byte[] key);
-}
\ No newline at end of file
diff --git a/Bitvault/IEncryptor.cs b/Bitvault/IEncryptor.cs
deleted file mode 100644
index c438b36..0000000
--- a/Bitvault/IEncryptor.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Bitvault;
-
-public interface IEncryptor
-{
-
- byte[] Encrypt(byte[] data, byte[] key);
-}
\ No newline at end of file
diff --git a/Bitvault/IKeyDeriver.cs b/Bitvault/IKeyDeriver.cs
deleted file mode 100644
index a181c48..0000000
--- a/Bitvault/IKeyDeriver.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-namespace Bitvault;
-
-public interface IKeyDeriver
-{
- byte[] DeriveKey(string password, byte[] salt, int keySize = 32, int iterations = 10000);
-}
diff --git a/Bitvault/IKeyGenerator.cs b/Bitvault/IKeyGenerator.cs
deleted file mode 100644
index e6536a4..0000000
--- a/Bitvault/IKeyGenerator.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-namespace Bitvault;
-
-public interface IKeyGenerator
-{
- byte[] Generate(int size);
-}
\ No newline at end of file
diff --git a/Bitvault/IPasswordHasher.cs b/Bitvault/IPasswordHasher.cs
deleted file mode 100644
index 27e66d0..0000000
--- a/Bitvault/IPasswordHasher.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-namespace Bitvault;
-
-public interface IPasswordHasher
-{
- string HashPassword(string password, int iterations = 10000);
-}
\ No newline at end of file
diff --git a/Bitvault/IVaultFactory.cs b/Bitvault/IVaultFactory.cs
deleted file mode 100644
index 931155b..0000000
--- a/Bitvault/IVaultFactory.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Bitvault
-{
- public interface IVaultFactory
- {
- bool Create(string name, string password);
- }
-}
\ No newline at end of file
diff --git a/Bitvault/IVaultInitializer.cs b/Bitvault/IVaultInitializer.cs
new file mode 100644
index 0000000..4054b05
--- /dev/null
+++ b/Bitvault/IVaultInitializer.cs
@@ -0,0 +1,6 @@
+namespace Bitvault;
+
+public interface IVaultInitializer
+{
+ Task Initialize(string name, string password);
+}
diff --git a/Bitvault/IVaultKeyGenerator.cs b/Bitvault/IVaultKeyFactory.cs
similarity index 63%
rename from Bitvault/IVaultKeyGenerator.cs
rename to Bitvault/IVaultKeyFactory.cs
index 5f6521c..3d5bda2 100644
--- a/Bitvault/IVaultKeyGenerator.cs
+++ b/Bitvault/IVaultKeyFactory.cs
@@ -1,6 +1,6 @@
namespace Bitvault;
-public interface IVaultKeyGenerator
+public interface IVaultKeyFactory
{
VaultKey Create(string password);
-}
\ No newline at end of file
+}
diff --git a/Bitvault/IVaultStorage.cs b/Bitvault/IVaultStorage.cs
index 1961e31..cd11ca6 100644
--- a/Bitvault/IVaultStorage.cs
+++ b/Bitvault/IVaultStorage.cs
@@ -2,5 +2,5 @@
public interface IVaultStorage
{
- bool Create(string name, VaultKey key);
+ Task CreateAsync(string name, VaultKey key);
}
\ No newline at end of file
diff --git a/Bitvault/KeyDeriver.cs b/Bitvault/KeyDeriver.cs
deleted file mode 100644
index f82e14d..0000000
--- a/Bitvault/KeyDeriver.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System.Security.Cryptography;
-
-namespace Bitvault;
-
-public class KeyDeriver :
- IKeyDeriver
-{
- public byte[] DeriveKey(string password, byte[] salt, int keySize = 32, int iterations = 100000)
- {
- using Rfc2898DeriveBytes pbkdf2 = new(password, salt, iterations, HashAlgorithmName.SHA256);
- return pbkdf2.GetBytes(keySize);
- }
-}
diff --git a/Bitvault/KeyGenerator.cs b/Bitvault/KeyGenerator.cs
deleted file mode 100644
index 3ee74d9..0000000
--- a/Bitvault/KeyGenerator.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System.Security.Cryptography;
-namespace Bitvault;
-
-public class KeyGenerator :
- IKeyGenerator
-{
- public byte[] Generate(int size)
- {
- byte[] key = new byte[size];
- RandomNumberGenerator.Fill(key);
-
- return key;
- }
-}
diff --git a/Bitvault/OpenVaultHandler.cs b/Bitvault/OpenVaultHandler.cs
index d975b70..adab259 100644
--- a/Bitvault/OpenVaultHandler.cs
+++ b/Bitvault/OpenVaultHandler.cs
@@ -12,10 +12,7 @@ public class OpenVaultHandler(IMediator mediator) :
{
if (vault.Password is { Length: > 0 } password)
{
- //if (await mediator.Handle, bool>(Open.As(new VaultStorage("Personal", password)), cancellationToken))
- //{
- // return true;
- //}
+
}
}
diff --git a/Bitvault/PasswordHasher.cs b/Bitvault/PasswordHasher.cs
deleted file mode 100644
index b077e8f..0000000
--- a/Bitvault/PasswordHasher.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using System.Security.Cryptography;
-
-namespace Bitvault;
-
-public class PasswordHasher :
- IPasswordHasher
-{
- private const int SaltSize = 16;
-
- public string HashPassword(string password, int iterations = 10000)
- {
- using Rfc2898DeriveBytes pbkdf2 = new(password, SaltSize, iterations, HashAlgorithmName.SHA256);
-
- byte[] salt = pbkdf2.Salt;
- byte[] hash = pbkdf2.GetBytes(32);
-
- return $"{Convert.ToBase64String(salt)}:{Convert.ToBase64String(hash)}";
- }
-}
diff --git a/Bitvault/VaultFactory.cs b/Bitvault/VaultFactory.cs
deleted file mode 100644
index 28576e2..0000000
--- a/Bitvault/VaultFactory.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-namespace Bitvault;
-
-public class VaultFactory(IVaultKeyGenerator keyGenerator,
- IVaultStorage vaultStorageFactory) :
- IVaultFactory
-{
- public bool Create(string name,
- string password)
- {
- VaultKey key = keyGenerator.Create(password);
- return vaultStorageFactory.Create(name, key);
- }
-}
diff --git a/Bitvault/VaultInitializer.cs b/Bitvault/VaultInitializer.cs
new file mode 100644
index 0000000..d8e5855
--- /dev/null
+++ b/Bitvault/VaultInitializer.cs
@@ -0,0 +1,32 @@
+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 2ef97c9..a61ddcb 100644
--- a/Bitvault/VaultKey.cs
+++ b/Bitvault/VaultKey.cs
@@ -1,3 +1,14 @@
namespace Bitvault;
-public record VaultKey(byte[] Salt, byte[] Public, byte[] Private);
+public record VaultKey(byte[] Phrase, byte[] Public, byte[] Private) :
+ 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);
+ }
+}
\ No newline at end of file
diff --git a/Bitvault/VaultKeyGenerator.cs b/Bitvault/VaultKeyFactory.cs
similarity index 79%
rename from Bitvault/VaultKeyGenerator.cs
rename to Bitvault/VaultKeyFactory.cs
index 95f47b7..0c1c2ac 100644
--- a/Bitvault/VaultKeyGenerator.cs
+++ b/Bitvault/VaultKeyFactory.cs
@@ -1,10 +1,12 @@
-namespace Bitvault;
+using Toolkit.Foundation;
-public class VaultKeyGenerator(IKeyGenerator generator,
+namespace Bitvault;
+
+public class VaultKeyFactory(IKeyGenerator generator,
IKeyDeriver deriver,
IEncryptor encryptor,
IDecryptor decryptor) :
- IVaultKeyGenerator
+ IVaultKeyFactory
{
public VaultKey Create(string password)
{
@@ -19,3 +21,4 @@ public class VaultKeyGenerator(IKeyGenerator generator,
return new VaultKey(salt, publicKey, privateKey);
}
}
+
diff --git a/Bitvault/VaultStorage.cs b/Bitvault/VaultStorage.cs
index d499ec6..8a4759d 100644
--- a/Bitvault/VaultStorage.cs
+++ b/Bitvault/VaultStorage.cs
@@ -1,17 +1,39 @@
using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
+using Toolkit.Foundation;
namespace Bitvault;
-public class VaultStorage(IHostEnvironment environment,
- IDbContextFactory dbContextFactory) :
+public class VaultStorage(IContainer connection,
+ IHostEnvironment environment,
+ IServiceProvider provider) :
IVaultStorage
{
- public bool Create(string name, VaultKey key)
+ public async Task CreateAsync(string name,
+ VaultKey key)
{
- using VaultDbContext context = dbContextFactory.CreateDbContext();
- context.Database.SetConnectionString($"Data Source={Path.Combine(environment.ContentRootPath, name)}" +
- $".vault;Mode=ReadWriteCreate;Password={Convert.ToBase64String(key.Private)}");
+ connection.Set(new VaultStorageConnection($"Data Source={Path.Combine(environment.ContentRootPath, name)}" +
+ $".vault;Mode=ReadWriteCreate;Pooling=false;Password={Convert.ToBase64String(key.Private)}"));
+
+ IDbContextFactory dbContextFactory = provider.GetRequiredService>();
+ using VaultDbContext context = await dbContextFactory.CreateDbContextAsync();
+
+ try
+ {
+ await Task.Run(async () =>
+ {
+ await context.Database.EnsureCreatedAsync().ConfigureAwait(false);
+ await context.Database.CloseConnectionAsync().ConfigureAwait(false);
+
+ context.Database.SetConnectionString(null);
+
+ }).ConfigureAwait(false);
+ }
+ catch
+ {
+ return false;
+ }
return true;
}