consolidation of some of the modules, localization fixes, product advisories work, qa work
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using StellaOps.Provenance.Attestation;
|
||||
using Xunit;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Provenance.Attestation.Tests;
|
||||
|
||||
public class CosignAndKmsSignerTests
|
||||
{
|
||||
private sealed class FakeCosignClient : ICosignClient
|
||||
{
|
||||
public List<(byte[] payload, string contentType, string keyRef)> Calls { get; } = new();
|
||||
public Task<byte[]> SignAsync(byte[] payload, string contentType, string keyRef, CancellationToken cancellationToken)
|
||||
{
|
||||
Calls.Add((payload, contentType, keyRef));
|
||||
return Task.FromResult(Encoding.UTF8.GetBytes("cosign-" + keyRef));
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class FakeKmsClient : IKmsClient
|
||||
{
|
||||
public List<(byte[] payload, string contentType, string keyId)> Calls { get; } = new();
|
||||
public Task<byte[]> SignAsync(byte[] payload, string contentType, string keyId, CancellationToken cancellationToken)
|
||||
{
|
||||
Calls.Add((payload, contentType, keyId));
|
||||
return Task.FromResult(Encoding.UTF8.GetBytes("kms-" + keyId));
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class FixedTimeProvider : TimeProvider
|
||||
{
|
||||
private readonly DateTimeOffset _now;
|
||||
public FixedTimeProvider(DateTimeOffset now) => _now = now;
|
||||
public override DateTimeOffset GetUtcNow() => _now;
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task CosignSigner_enforces_required_claims_and_logs()
|
||||
{
|
||||
var client = new FakeCosignClient();
|
||||
var audit = new InMemoryAuditSink();
|
||||
var signer = new CosignSigner("cosign-key", client, audit, new FixedTimeProvider(DateTimeOffset.UnixEpoch));
|
||||
|
||||
var request = new SignRequest(
|
||||
Payload: Encoding.UTF8.GetBytes("payload"),
|
||||
ContentType: "application/vnd.dsse",
|
||||
Claims: new Dictionary<string, string> { ["sub"] = "artifact" },
|
||||
RequiredClaims: new[] { "sub" });
|
||||
|
||||
var result = await signer.SignAsync(request);
|
||||
|
||||
result.KeyId.Should().Be("cosign-key");
|
||||
result.Signature.Should().BeEquivalentTo(Encoding.UTF8.GetBytes("cosign-cosign-key"));
|
||||
audit.Signed.Should().ContainSingle();
|
||||
client.Calls.Should().ContainSingle(call => call.keyRef == "cosign-key" && call.contentType == "application/vnd.dsse");
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task CosignSigner_throws_on_missing_required_claim()
|
||||
{
|
||||
var client = new FakeCosignClient();
|
||||
var audit = new InMemoryAuditSink();
|
||||
var signer = new CosignSigner("cosign-key", client, audit, new FixedTimeProvider(DateTimeOffset.UnixEpoch));
|
||||
|
||||
var request = new SignRequest(
|
||||
Payload: Encoding.UTF8.GetBytes("payload"),
|
||||
ContentType: "application/vnd.dsse",
|
||||
Claims: new Dictionary<string, string>(),
|
||||
RequiredClaims: new[] { "sub" });
|
||||
|
||||
var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => signer.SignAsync(request));
|
||||
ex.Message.Should().Contain("sub");
|
||||
audit.Missing.Should().ContainSingle(m => m.claim == "sub");
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task KmsSigner_signs_with_current_key_and_logs()
|
||||
{
|
||||
var kms = new FakeKmsClient();
|
||||
var key = new InMemoryKeyProvider("kms-key-1", Encoding.UTF8.GetBytes("secret-kms"));
|
||||
var audit = new InMemoryAuditSink();
|
||||
var signer = new KmsSigner(kms, key, audit, new FixedTimeProvider(DateTimeOffset.UnixEpoch));
|
||||
|
||||
var request = new SignRequest(Encoding.UTF8.GetBytes("payload"), "application/vnd.dsse");
|
||||
var result = await signer.SignAsync(request);
|
||||
|
||||
result.KeyId.Should().Be("kms-key-1");
|
||||
result.Signature.Should().BeEquivalentTo(Encoding.UTF8.GetBytes("kms-kms-key-1"));
|
||||
audit.Signed.Should().ContainSingle();
|
||||
kms.Calls.Should().ContainSingle(call => call.keyId == "kms-key-1");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user