using System; using System.Threading; using System.Threading.Tasks; using static StellaOps.Localization.T; namespace StellaOps.Cryptography.Kms; public sealed partial class FileKmsClient { public async Task GetMetadataAsync(string keyId, CancellationToken cancellationToken = default) { ArgumentException.ThrowIfNullOrWhiteSpace(keyId); await _mutex.WaitAsync(cancellationToken).ConfigureAwait(false); try { var record = await LoadOrCreateMetadataAsync(keyId, cancellationToken, createIfMissing: false).ConfigureAwait(false) ?? throw new InvalidOperationException(_t("crypto.kms.key_not_found", keyId)); return ToMetadata(record); } finally { _mutex.Release(); } } public async Task ExportAsync(string keyId, string? keyVersion, CancellationToken cancellationToken = default) { ArgumentException.ThrowIfNullOrWhiteSpace(keyId); await _mutex.WaitAsync(cancellationToken).ConfigureAwait(false); try { var record = await LoadOrCreateMetadataAsync(keyId, cancellationToken, createIfMissing: false).ConfigureAwait(false) ?? throw new InvalidOperationException(_t("crypto.kms.key_not_found", keyId)); var version = ResolveVersion(record, keyVersion); if (string.IsNullOrWhiteSpace(version.PublicKey)) { throw new InvalidOperationException(_t("crypto.kms.key_no_public_material", keyId, version.VersionId)); } var privateKey = await LoadPrivateKeyAsync(record, version, cancellationToken).ConfigureAwait(false); return new KmsKeyMaterial( record.KeyId, version.VersionId, record.Algorithm, version.CurveName, Convert.FromBase64String(privateKey.D), Convert.FromBase64String(privateKey.Qx), Convert.FromBase64String(privateKey.Qy), version.CreatedAt); } finally { _mutex.Release(); } } }