using Microsoft.Extensions.Options; using System; using System.Collections.Concurrent; using System.Threading.Tasks; using static StellaOps.Localization.T; namespace StellaOps.Cryptography.Kms; /// /// AWS KMS implementation of . /// public sealed partial class AwsKmsClient : IKmsClient, IDisposable { private readonly IAwsKmsFacade _facade; private readonly TimeProvider _timeProvider; private readonly TimeSpan _metadataCacheDuration; private readonly TimeSpan _publicKeyCacheDuration; private readonly ConcurrentDictionary _metadataCache = new(StringComparer.Ordinal); private readonly ConcurrentDictionary _publicKeyCache = new(StringComparer.Ordinal); private bool _disposed; public AwsKmsClient(IAwsKmsFacade facade, AwsKmsOptions options, TimeProvider? timeProvider = null) { _facade = facade ?? throw new ArgumentNullException(nameof(facade)); ArgumentNullException.ThrowIfNull(options); _timeProvider = timeProvider ?? TimeProvider.System; _metadataCacheDuration = options.MetadataCacheDuration; _publicKeyCacheDuration = options.PublicKeyCacheDuration; } public AwsKmsClient(IAwsKmsFacade facade, IOptions options, TimeProvider timeProvider) : this(facade, options?.Value ?? new AwsKmsOptions(), timeProvider) { } public Task RotateAsync(string keyId, CancellationToken cancellationToken = default) => throw new NotSupportedException(_t("crypto.kms.rotation_via_policy", "AWS KMS", "AWS KMS")); public Task RevokeAsync(string keyId, CancellationToken cancellationToken = default) => throw new NotSupportedException(_t("crypto.kms.revocation_via_policy", "AWS KMS key", "AWS KMS")); public void Dispose() { if (_disposed) { return; } _disposed = true; _facade.Dispose(); } }