Files
git.stella-ops.org/src/EvidenceLocker/StellaOps.EvidenceLocker/StellaOps.EvidenceLocker.Tests/Rfc3161TimestampAuthorityClientTests.cs
2026-02-01 21:37:40 +02:00

86 lines
3.2 KiB
C#

using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using StellaOps.Cryptography;
using StellaOps.EvidenceLocker.Core.Configuration;
using StellaOps.EvidenceLocker.Core.Signing;
using StellaOps.EvidenceLocker.Infrastructure.Signing;
using StellaOps.TestKit;
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
namespace StellaOps.EvidenceLocker.Tests;
public sealed class Rfc3161TimestampAuthorityClientTests
{
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task RequestTimestampAsync_ReturnsNull_WhenAuthorityFailsAndTimestampOptional()
{
var handler = new StubHttpMessageHandler(_ => new HttpResponseMessage(HttpStatusCode.InternalServerError));
var client = CreateClient(handler, new TimestampingOptions
{
Enabled = true,
Endpoint = "https://tsa.example",
HashAlgorithm = "SHA256",
RequireTimestamp = false
});
var result = await client.RequestTimestampAsync(new byte[] { 4, 5, 6 }, "SHA256", CancellationToken.None);
Assert.Null(result);
}
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task RequestTimestampAsync_Throws_WhenAuthorityFailsAndTimestampRequired()
{
var handler = new StubHttpMessageHandler(_ => new HttpResponseMessage(HttpStatusCode.InternalServerError));
var client = CreateClient(handler, new TimestampingOptions
{
Enabled = true,
Endpoint = "https://tsa.example",
HashAlgorithm = "SHA256",
RequireTimestamp = true
});
await Assert.ThrowsAsync<InvalidOperationException>(() => client.RequestTimestampAsync(new byte[] { 7, 8 }, "SHA256", CancellationToken.None));
}
private static Rfc3161TimestampAuthorityClient CreateClient(HttpMessageHandler handler, TimestampingOptions timestampingOptions)
{
var httpClient = new HttpClient(handler, disposeHandler: false);
var options = Options.Create(new EvidenceLockerOptions
{
Database = new DatabaseOptions { ConnectionString = "Host=localhost" },
ObjectStore = new ObjectStoreOptions
{
Kind = ObjectStoreKind.FileSystem,
FileSystem = new FileSystemStoreOptions { RootPath = "." }
},
Quotas = new QuotaOptions(),
Signing = new SigningOptions
{
Algorithm = SignatureAlgorithms.Es256,
KeyId = "test-key",
Timestamping = timestampingOptions
}
});
return new Rfc3161TimestampAuthorityClient(httpClient, options, NullLogger<Rfc3161TimestampAuthorityClient>.Instance);
}
private sealed class StubHttpMessageHandler(Func<HttpRequestMessage, HttpResponseMessage> responder) : HttpMessageHandler
{
private readonly Func<HttpRequestMessage, HttpResponseMessage> _responder = responder;
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
=> Task.FromResult(_responder(request));
}
}