using DigitalData.Core.Abstractions.Security; using DigitalData.Core.Security.Config; using DigitalData.Core.Security.Cryptographer; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using System.Collections; namespace DigitalData.Core.Security { public class AsymCryptService : RSAFactory, IAsymCryptService, IRSAFactory, IEnumerable where TAsymCryptParams : AsymCryptParams { public IEnumerable Decryptors { get; } /// /// It is a separate decryptor for permanently stored encrypted data. It is assigned to the first Default decryptor by default. /// public IRSADecryptor Vault { get; } public IRSADecryptor this[string key] { get { var key_params = key.Split(_params.KeyNameSeparator); if (key_params.Length != 2) throw new ArgumentException($"Invalid key format. Expected two segments separated by '{_params.KeyNameSeparator}', but received: '{key}'.", nameof(key)); return _params.Decryptors.FirstOrDefault(d => d.Issuer == key_params[0] && d.Audience == key_params[1]) ?? throw new KeyNotFoundException($"No decryptor found matching the issuer '{key_params[0]}' and audience '{key_params[1]}'."); } } public IRSADecryptor this[int index] => index < 0 || index >= Decryptors.Count() ? Decryptors.ElementAt(index) : throw new ArgumentOutOfRangeException( nameof(index), index, $"The index {index} is out of range. The valid indices for {GetType()} are between 0 and {Decryptors.Count() - 1} (inclusive). Please ensure the index is within this range."); public AsymCryptService(IOptions options, ILogger>? logger = null) : base(options) { logger?.LogInformation("Core.Secrets version: {Version}, Created on: {CreationDate}.", Secrets.Version, Secrets.CreationDate.ToString("dd.MM.yyyy")); if (!_params.Decryptors.Any()) throw new InvalidOperationException( "Any decryptor is not found. Ensure that at least one decryptor is configured in the provided parameters. " + "This issue typically arises if the configuration for decryptors is incomplete or missing. " + "Check the 'Decryptors' collection in the configuration and verify that it contains valid entries." ); Decryptors = _params.Decryptors; Vault = _params.Vault ?? Decryptors.First(); } public IEnumerator GetEnumerator() => Decryptors.GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => Decryptors.GetEnumerator(); public IEnumerable Encryptors { get { foreach (var decryptor in Decryptors) yield return decryptor.Encryptor; } } } }