up
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled

This commit is contained in:
Vladimir Moushkov
2025-10-29 19:24:20 +02:00
parent 3154c67978
commit 55464f8498
41 changed files with 2134 additions and 168 deletions

View File

@@ -0,0 +1,112 @@
using System.Security.Cryptography;
using StellaOps.Cryptography.Kms;
namespace StellaOps.Cryptography.Kms.Tests;
public sealed class FileKmsClientTests : IDisposable
{
private readonly string _rootPath;
public FileKmsClientTests()
{
_rootPath = Path.Combine(Path.GetTempPath(), $"kms-tests-{Guid.NewGuid():N}");
}
[Fact]
public async Task RotateSignVerifyLifecycle_Works()
{
using var client = CreateClient();
var keyId = "kms-test-key";
// Initial rotate creates the key.
var metadata = await client.RotateAsync(keyId);
Assert.Equal(keyId, metadata.KeyId);
Assert.Single(metadata.Versions);
Assert.Equal(KmsKeyState.Active, metadata.State);
var version = metadata.Versions[0];
Assert.Equal(KmsKeyState.Active, version.State);
var firstData = RandomNumberGenerator.GetBytes(256);
var firstSignature = await client.SignAsync(keyId, null, firstData);
Assert.Equal(keyId, firstSignature.KeyId);
Assert.Equal(KmsAlgorithms.Es256, firstSignature.Algorithm);
Assert.True(await client.VerifyAsync(keyId, firstSignature.VersionId, firstData, firstSignature.Signature));
// Rotate again and ensure metadata reflects both versions.
var rotated = await client.RotateAsync(keyId);
Assert.Equal(2, rotated.Versions.Length);
var activeVersion = rotated.Versions.Single(v => v.State == KmsKeyState.Active);
Assert.Equal(rotated.Versions.Max(v => v.VersionId), activeVersion.VersionId);
var previousVersion = rotated.Versions.Single(v => v.State != KmsKeyState.Active);
Assert.Equal(KmsKeyState.PendingRotation, previousVersion.State);
var newData = RandomNumberGenerator.GetBytes(128);
var activeSignature = await client.SignAsync(keyId, null, newData);
Assert.Equal(activeVersion.VersionId, activeSignature.VersionId);
Assert.True(await client.VerifyAsync(keyId, null, newData, activeSignature.Signature));
// Explicit version verify should still pass for previous version using the old signature.
Assert.True(await client.VerifyAsync(keyId, previousVersion.VersionId, firstData, firstSignature.Signature));
}
[Fact]
public async Task RevokePreventsSigning()
{
using var client = CreateClient();
var keyId = "kms-revoke";
await client.RotateAsync(keyId);
await client.RevokeAsync(keyId);
var metadata = await client.GetMetadataAsync(keyId);
Assert.Equal(KmsKeyState.Revoked, metadata.State);
Assert.All(metadata.Versions, v => Assert.Equal(KmsKeyState.Revoked, v.State));
var data = RandomNumberGenerator.GetBytes(32);
await Assert.ThrowsAsync<InvalidOperationException>(() => client.SignAsync(keyId, null, data));
}
[Fact]
public async Task ExportAsync_ReturnsKeyMaterial()
{
using var client = CreateClient();
var keyId = "kms-export";
await client.RotateAsync(keyId);
var material = await client.ExportAsync(keyId, null);
Assert.Equal(keyId, material.KeyId);
Assert.Equal(KmsAlgorithms.Es256, material.Algorithm);
Assert.Equal("nistP256", material.Curve);
Assert.NotEmpty(material.D);
Assert.NotEmpty(material.Qx);
Assert.NotEmpty(material.Qy);
}
private FileKmsClient CreateClient()
{
var options = new FileKmsOptions
{
RootPath = _rootPath,
Password = "P@ssw0rd!",
Algorithm = KmsAlgorithms.Es256,
};
return new FileKmsClient(options);
}
public void Dispose()
{
try
{
if (Directory.Exists(_rootPath))
{
Directory.Delete(_rootPath, recursive: true);
}
}
catch
{
// ignore cleanup errors
}
}
}

View File

@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<UseConcelierTestInfra>false</UseConcelierTestInfra>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.4" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
<PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2" />
</ItemGroup>
<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../../StellaOps.Cryptography.Kms/StellaOps.Cryptography.Kms.csproj" />
</ItemGroup>
</Project>