diff --git a/DigitalData.Core.Security/Config/AsymCryptParams.cs b/DigitalData.Core.Security/Config/AsymCryptParams.cs index fc4ce19..6f80c0b 100644 --- a/DigitalData.Core.Security/Config/AsymCryptParams.cs +++ b/DigitalData.Core.Security/Config/AsymCryptParams.cs @@ -38,40 +38,41 @@ namespace DigitalData.Core.Security.Config public RSADecryptor? Vault { get; init; } - public override void OnDeserialized() + public AsymCryptParams() { - base.OnDeserialized(); - - // Create root folder if it does not exist - if (!Directory.Exists(PemDirectory)) - Directory.CreateDirectory(PemDirectory); - - foreach (var decryptor in Decryptors) + AfterCreate += () => { - // set default path - if (decryptor.IsPemNull) + // Create root folder if it does not exist + if (!Directory.Exists(PemDirectory)) + Directory.CreateDirectory(PemDirectory); + + foreach (var decryptor in Decryptors) { - var file_name_params = new List { decryptor.Issuer, decryptor.Audience }; - if (decryptor.IsEncrypted) - file_name_params.Add(Secrets.Version); - - var path = Path.Combine(PemDirectory, string.Join(FileNameSeparator, file_name_params)); - - if (File.Exists(path)) - decryptor.SetPem(File.ReadAllText(path)); - else + // set default path + if (decryptor.IsPemNull) { - var pem = decryptor.IsEncrypted - ? Instance.RSAFactory.CreateEncryptedPrivateKeyPem(pbeParameters: PbeParameters, keySizeInBits: KeySizeInBits, password: Secrets.PBE_PASSWORD) - : Instance.RSAFactory.CreatePrivateKeyPem(keySizeInBits: KeySizeInBits); + var file_name_params = new List { decryptor.Issuer, decryptor.Audience }; + if (decryptor.IsEncrypted) + file_name_params.Add(Secrets.Version); - decryptor.SetPem(File.ReadAllText(pem)); + var path = Path.Combine(PemDirectory, string.Join(FileNameSeparator, file_name_params)); - // Save file in background - Task.Run(async () => await File.WriteAllTextAsync(path: path, pem)); + if (File.Exists(path)) + decryptor.SetPem(File.ReadAllText(path)); + else + { + var pem = decryptor.IsEncrypted + ? Instance.RSAFactory.CreateEncryptedPrivateKeyPem(pbeParameters: PbeParameters, keySizeInBits: KeySizeInBits, password: Secrets.PBE_PASSWORD) + : Instance.RSAFactory.CreatePrivateKeyPem(keySizeInBits: KeySizeInBits); + + decryptor.SetPem(File.ReadAllText(pem)); + + // Save file in background + Task.Run(async () => await File.WriteAllTextAsync(path: path, pem)); + } } } - } + }; } } } \ No newline at end of file diff --git a/DigitalData.Core.Security/Config/RSAFactoryParams.cs b/DigitalData.Core.Security/Config/RSAFactoryParams.cs index 5ab57f2..91469b5 100644 --- a/DigitalData.Core.Security/Config/RSAFactoryParams.cs +++ b/DigitalData.Core.Security/Config/RSAFactoryParams.cs @@ -22,6 +22,28 @@ namespace DigitalData.Core.Security.Config [JsonIgnore] public PbeParameters PbeParameters => _pbeParameters!; - public virtual void OnDeserialized() => _pbeParameters = new PbeParameters(PbeEncryptionAlgorithm, PbeHashAlgorithmName, PbeIterationCount); + /// + /// Provides a thread-safe initialization mechanism using Lazy initialization. + /// + private readonly Lazy _lazyInitializer; + + public bool IsInitialized => _lazyInitializer.IsValueCreated; + + public RSAFactoryParams() + { + _lazyInitializer = new(() => + { + AfterCreate?.Invoke(); + return true; + }); + + AfterCreate += () => _pbeParameters = new PbeParameters(PbeEncryptionAlgorithm, PbeHashAlgorithmName, PbeIterationCount); + } + + protected event Action AfterCreate; + + public void Init() => _ = _lazyInitializer.Value; + + public void OnDeserialized() => Init(); } } \ No newline at end of file diff --git a/DigitalData.Core.Security/Cryptographer/RSAFactory.cs b/DigitalData.Core.Security/Cryptographer/RSAFactory.cs index 8e174cd..6b0216a 100644 --- a/DigitalData.Core.Security/Cryptographer/RSAFactory.cs +++ b/DigitalData.Core.Security/Cryptographer/RSAFactory.cs @@ -9,7 +9,11 @@ namespace DigitalData.Core.Security.Cryptographer { protected readonly TRSAFactoryParams _params; - public RSAFactory(IOptions options) => _params = options.Value; + public RSAFactory(IOptions options) + { + options.Value.Init(); + _params = options.Value; + } public string CreatePrivateKeyPem(int? keySizeInBits = null, bool encrypt = false) => encrypt ? CreateEncryptedPrivateKeyPem(keySizeInBits: keySizeInBits)