up the blokcing tasks
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Notify Smoke Test / Notifier Service Tests (push) Has been cancelled
Notify Smoke Test / Notification Smoke Test (push) Has been cancelled
Notify Smoke Test / Notify Unit Tests (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Export Center CI / export-ci (push) Has been cancelled
Manifest Integrity / Validate Schema Integrity (push) Has been cancelled
Manifest Integrity / Validate Contract Documents (push) Has been cancelled
Manifest Integrity / Validate Pack Fixtures (push) Has been cancelled
Manifest Integrity / Audit SHA256SUMS Files (push) Has been cancelled
Manifest Integrity / Verify Merkle Roots (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Risk Bundle CI / risk-bundle-build (push) Has been cancelled
Scanner Analyzers / Discover Analyzers (push) Has been cancelled
Scanner Analyzers / Validate Test Fixtures (push) Has been cancelled
Risk Bundle CI / risk-bundle-offline-kit (push) Has been cancelled
Risk Bundle CI / publish-checksums (push) Has been cancelled
Scanner Analyzers / Build Analyzers (push) Has been cancelled
Scanner Analyzers / Test Language Analyzers (push) Has been cancelled
Scanner Analyzers / Verify Deterministic Output (push) Has been cancelled
devportal-offline / build-offline (push) Has been cancelled
Mirror Thin Bundle Sign & Verify / mirror-sign (push) Has been cancelled
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Notify Smoke Test / Notifier Service Tests (push) Has been cancelled
Notify Smoke Test / Notification Smoke Test (push) Has been cancelled
Notify Smoke Test / Notify Unit Tests (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Export Center CI / export-ci (push) Has been cancelled
Manifest Integrity / Validate Schema Integrity (push) Has been cancelled
Manifest Integrity / Validate Contract Documents (push) Has been cancelled
Manifest Integrity / Validate Pack Fixtures (push) Has been cancelled
Manifest Integrity / Audit SHA256SUMS Files (push) Has been cancelled
Manifest Integrity / Verify Merkle Roots (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Risk Bundle CI / risk-bundle-build (push) Has been cancelled
Scanner Analyzers / Discover Analyzers (push) Has been cancelled
Scanner Analyzers / Validate Test Fixtures (push) Has been cancelled
Risk Bundle CI / risk-bundle-offline-kit (push) Has been cancelled
Risk Bundle CI / publish-checksums (push) Has been cancelled
Scanner Analyzers / Build Analyzers (push) Has been cancelled
Scanner Analyzers / Test Language Analyzers (push) Has been cancelled
Scanner Analyzers / Verify Deterministic Output (push) Has been cancelled
devportal-offline / build-offline (push) Has been cancelled
Mirror Thin Bundle Sign & Verify / mirror-sign (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Json;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
using StellaOps.Cryptography;
|
||||
using StellaOps.Cryptography.Plugin.SimRemote;
|
||||
using StellaOps.Cryptography.DependencyInjection;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Cryptography.Tests;
|
||||
|
||||
public class SimRemoteProviderTests
|
||||
{
|
||||
[Fact]
|
||||
public void Supports_DefaultAlgorithms_CoversStandardIds()
|
||||
{
|
||||
var handler = new NoopHandler();
|
||||
var client = new HttpClient(handler) { BaseAddress = new Uri("http://sim.test") };
|
||||
var options = Options.Create(new SimRemoteProviderOptions());
|
||||
var provider = new SimRemoteProvider(new SimRemoteHttpClient(client), options);
|
||||
|
||||
Assert.True(provider.Supports(CryptoCapability.Signing, SignatureAlgorithms.Sm2));
|
||||
Assert.True(provider.Supports(CryptoCapability.Signing, SignatureAlgorithms.GostR3410_2012_256));
|
||||
Assert.True(provider.Supports(CryptoCapability.Signing, SignatureAlgorithms.Dilithium3));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SignAndVerify_WithSimProvider_Succeeds()
|
||||
{
|
||||
// Arrange
|
||||
using var services = new ServiceCollection();
|
||||
services.AddLogging();
|
||||
services.Configure<SimRemoteProviderOptions>(opts =>
|
||||
{
|
||||
opts.BaseAddress = "http://sim.test";
|
||||
opts.Algorithms.Clear();
|
||||
opts.Algorithms.Add("pq.sim");
|
||||
opts.RemoteKeyId = "sim-key";
|
||||
});
|
||||
services.AddHttpClient<SimRemoteHttpClient>()
|
||||
.ConfigurePrimaryHttpMessageHandler(() => new SimHandler());
|
||||
|
||||
services.AddSingleton<IOptions<SimRemoteProviderOptions>>(sp => Options.Create(sp.GetRequiredService<IOptions<SimRemoteProviderOptions>>().Value));
|
||||
services.AddSingleton<SimRemoteProvider>();
|
||||
|
||||
using var providerScope = services.BuildServiceProvider();
|
||||
var provider = providerScope.GetRequiredService<SimRemoteProvider>();
|
||||
var signer = provider.GetSigner("pq.sim", new CryptoKeyReference("sim-key"));
|
||||
var payload = Encoding.UTF8.GetBytes("hello-sim");
|
||||
|
||||
// Act
|
||||
var signature = await signer.SignAsync(payload);
|
||||
var ok = await signer.VerifyAsync(payload, signature);
|
||||
|
||||
// Assert
|
||||
Assert.True(ok);
|
||||
Assert.Equal("sim-key", signer.KeyId);
|
||||
Assert.Equal("pq.sim", signer.AlgorithmId);
|
||||
}
|
||||
|
||||
private sealed class SimHandler : HttpMessageHandler
|
||||
{
|
||||
private static readonly byte[] Key = Encoding.UTF8.GetBytes("sim-hmac-key");
|
||||
|
||||
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
||||
{
|
||||
var path = request.RequestUri?.AbsolutePath ?? string.Empty;
|
||||
if (path.Contains("/sign", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var payload = await request.Content!.ReadFromJsonAsync<SignPayload>(cancellationToken: cancellationToken).ConfigureAwait(false)
|
||||
?? throw new InvalidOperationException("Missing sign payload");
|
||||
var data = Convert.FromBase64String(payload.MessageBase64);
|
||||
var sig = HMACSHA256.HashData(Key, data);
|
||||
var response = new SignResponse(Convert.ToBase64String(sig), payload.Algorithm);
|
||||
return new HttpResponseMessage(HttpStatusCode.OK)
|
||||
{
|
||||
Content = JsonContent.Create(response)
|
||||
};
|
||||
}
|
||||
|
||||
if (path.Contains("/verify", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var payload = await request.Content!.ReadFromJsonAsync<VerifyPayload>(cancellationToken: cancellationToken).ConfigureAwait(false)
|
||||
?? throw new InvalidOperationException("Missing verify payload");
|
||||
var data = Convert.FromBase64String(payload.MessageBase64);
|
||||
var expected = HMACSHA256.HashData(Key, data);
|
||||
var actual = Convert.FromBase64String(payload.SignatureBase64);
|
||||
var ok = CryptographicOperations.FixedTimeEquals(expected, actual);
|
||||
var response = new VerifyResponse(ok, payload.Algorithm);
|
||||
return new HttpResponseMessage(HttpStatusCode.OK)
|
||||
{
|
||||
Content = JsonContent.Create(response)
|
||||
};
|
||||
}
|
||||
|
||||
return new HttpResponseMessage(HttpStatusCode.NotFound);
|
||||
}
|
||||
|
||||
private sealed record SignPayload(string MessageBase64, string Algorithm);
|
||||
private sealed record VerifyPayload(string MessageBase64, string SignatureBase64, string Algorithm);
|
||||
private sealed record SignResponse(string SignatureBase64, string Algorithm);
|
||||
private sealed record VerifyResponse(bool Ok, string Algorithm);
|
||||
}
|
||||
|
||||
private sealed class NoopHandler : HttpMessageHandler
|
||||
{
|
||||
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
||||
=> Task.FromResult(new HttpResponseMessage(HttpStatusCode.NotFound));
|
||||
}
|
||||
}
|
||||
@@ -18,5 +18,7 @@
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\StellaOps.Cryptography\StellaOps.Cryptography.csproj" />
|
||||
<ProjectReference Include="..\StellaOps.Cryptography.Plugin.PqSoft\StellaOps.Cryptography.Plugin.PqSoft.csproj" />
|
||||
<ProjectReference Include="..\StellaOps.Cryptography.DependencyInjection\StellaOps.Cryptography.DependencyInjection.csproj" />
|
||||
<ProjectReference Include="..\StellaOps.Cryptography.Plugin.SimRemote\StellaOps.Cryptography.Plugin.SimRemote.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
Reference in New Issue
Block a user