up
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Json;
|
||||
using System.Text.Json;
|
||||
using FluentAssertions;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.AspNetCore.Mvc.Testing;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using StellaOps.Cryptography.Plugin.SmRemote;
|
||||
using StellaOps.Cryptography;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Cryptography.Plugin.SmRemote.Tests;
|
||||
|
||||
public class SmRemoteHttpProviderTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task Service_EndToEnd_SignsAndVerifies()
|
||||
{
|
||||
Environment.SetEnvironmentVariable("SM_SOFT_ALLOWED", "1");
|
||||
using var app = new WebApplicationFactory<Program>()
|
||||
.WithWebHostBuilder(_ => { });
|
||||
|
||||
var client = app.CreateClient();
|
||||
var status = await client.GetFromJsonAsync<SmStatusResponse>("/status");
|
||||
status.Should().NotBeNull();
|
||||
status!.Available.Should().BeTrue();
|
||||
|
||||
var payload = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes("pae"));
|
||||
var signResp = await client.PostAsJsonAsync("/sign", new SignRequest("sm2-test", SignatureAlgorithms.Sm2, payload));
|
||||
signResp.EnsureSuccessStatusCode();
|
||||
var sign = await signResp.Content.ReadFromJsonAsync<SignResponse>();
|
||||
sign.Should().NotBeNull();
|
||||
|
||||
var verifyResp = await client.PostAsJsonAsync("/verify", new VerifyRequest("sm2-test", SignatureAlgorithms.Sm2, payload, sign!.Signature));
|
||||
verifyResp.EnsureSuccessStatusCode();
|
||||
var verify = await verifyResp.Content.ReadFromJsonAsync<VerifyResponse>();
|
||||
verify!.Valid.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SignsAndVerifiesViaHttp()
|
||||
{
|
||||
var handler = new StubHandler();
|
||||
var httpClient = new HttpClient(handler) { BaseAddress = new Uri("http://localhost:8080") };
|
||||
|
||||
var client = new SmRemoteHttpClient(httpClient);
|
||||
var provider = new SmRemoteHttpProvider(
|
||||
client,
|
||||
Options.Create(new SmRemoteProviderOptions
|
||||
{
|
||||
SkipProbe = true,
|
||||
Keys = { new SmRemoteKeyOptions { KeyId = "sm2-1" } }
|
||||
}),
|
||||
NullLogger<SmRemoteHttpProvider>.Instance);
|
||||
|
||||
var signer = provider.GetSigner(SignatureAlgorithms.Sm2, new CryptoKeyReference("sm2-1", provider.Name));
|
||||
var data = System.Text.Encoding.UTF8.GetBytes("pae");
|
||||
|
||||
var signature = await signer.SignAsync(data);
|
||||
var ok = await signer.VerifyAsync(data, signature);
|
||||
|
||||
ok.Should().BeTrue();
|
||||
handler.SignCalled.Should().BeTrue();
|
||||
handler.VerifyCalled.Should().BeTrue();
|
||||
}
|
||||
|
||||
private sealed class StubHandler : HttpMessageHandler
|
||||
{
|
||||
public bool SignCalled { get; private set; }
|
||||
public bool VerifyCalled { get; private set; }
|
||||
|
||||
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
||||
{
|
||||
if (request.RequestUri?.AbsolutePath == "/status")
|
||||
{
|
||||
var status = new SmRemoteStatus { IsAvailable = true, ProviderName = "stub", SupportedAlgorithms = new[] { SignatureAlgorithms.Sm2 } };
|
||||
return Task.FromResult(Json(status));
|
||||
}
|
||||
|
||||
if (request.RequestUri?.AbsolutePath == "/sign")
|
||||
{
|
||||
SignCalled = true;
|
||||
var signature = Convert.ToBase64String(new byte[] { 1, 2, 3 });
|
||||
return Task.FromResult(Json(new SmRemoteSignResponse { Signature = signature }));
|
||||
}
|
||||
|
||||
if (request.RequestUri?.AbsolutePath == "/verify")
|
||||
{
|
||||
VerifyCalled = true;
|
||||
return Task.FromResult(Json(new SmRemoteVerifyResponse { Valid = true }));
|
||||
}
|
||||
|
||||
return Task.FromResult(new HttpResponseMessage(HttpStatusCode.NotFound));
|
||||
}
|
||||
|
||||
private static HttpResponseMessage Json<T>(T payload)
|
||||
{
|
||||
var resp = new HttpResponseMessage(HttpStatusCode.OK);
|
||||
resp.Content = new StringContent(JsonSerializer.Serialize(payload));
|
||||
resp.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
|
||||
return resp;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\StellaOps.Cryptography.Plugin.SmRemote\StellaOps.Cryptography.Plugin.SmRemote.csproj" />
|
||||
<ProjectReference Include="..\StellaOps.Cryptography\StellaOps.Cryptography.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" Version="6.12.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\\..\\SmRemote\\StellaOps.SmRemote.Service\\StellaOps.SmRemote.Service.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user