122 lines
4.1 KiB
C#
122 lines
4.1 KiB
C#
using System;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.Extensions.Logging.Abstractions;
|
|
using Microsoft.Extensions.Options;
|
|
using StellaOps.Cryptography;
|
|
using StellaOps.Cryptography.Plugin.SmSoft;
|
|
using StellaOps.Signer.Core;
|
|
using StellaOps.Signer.Infrastructure.Signing;
|
|
using StellaOps.Signer.Tests.Fixtures;
|
|
using Xunit;
|
|
|
|
namespace StellaOps.Signer.Tests.Signing;
|
|
|
|
public class Sm2SigningTests : IDisposable
|
|
{
|
|
private readonly string? _gate;
|
|
|
|
public Sm2SigningTests()
|
|
{
|
|
_gate = Environment.GetEnvironmentVariable("SM_SOFT_ALLOWED");
|
|
Environment.SetEnvironmentVariable("SM_SOFT_ALLOWED", "1");
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Sign_Sm2_Succeeds_WhenGateOn()
|
|
{
|
|
var registry = TestCryptoFactory.CreateSm2Registry();
|
|
var keyResolver = new StubKeyResolver("sm2-key", SignatureAlgorithms.Sm2, "cn.sm.soft");
|
|
var options = Options.Create(new DsseSignerOptions
|
|
{
|
|
KeylessAlgorithm = SignatureAlgorithms.Sm2,
|
|
KmsAlgorithm = SignatureAlgorithms.Sm2,
|
|
PreferredProvider = "cn.sm.soft"
|
|
});
|
|
|
|
var signer = new CryptoDsseSigner(
|
|
registry,
|
|
keyResolver,
|
|
options,
|
|
NullLogger<CryptoDsseSigner>.Instance);
|
|
|
|
var request = BuildRequest();
|
|
var entitlement = new ProofOfEntitlementResult("lic", "cust", "plan", 0, 0, 0, DateTimeOffset.UtcNow.AddHours(1));
|
|
var caller = BuildCaller();
|
|
|
|
var bundle = await signer.SignAsync(request, entitlement, caller, default);
|
|
|
|
Assert.Equal(SignatureAlgorithms.Sm2, bundle.Metadata.AlgorithmId);
|
|
Assert.Equal("cn.sm.soft", bundle.Metadata.ProviderName);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Sign_Sm2_Fails_WhenGateOff()
|
|
{
|
|
Environment.SetEnvironmentVariable("SM_SOFT_ALLOWED", null);
|
|
|
|
var registry = TestCryptoFactory.CreateSm2Registry();
|
|
var keyResolver = new StubKeyResolver("sm2-key", SignatureAlgorithms.Sm2, "cn.sm.soft");
|
|
var options = Options.Create(new DsseSignerOptions { KeylessAlgorithm = SignatureAlgorithms.Sm2 });
|
|
|
|
var signer = new CryptoDsseSigner(
|
|
registry,
|
|
keyResolver,
|
|
options,
|
|
NullLogger<CryptoDsseSigner>.Instance);
|
|
|
|
var request = BuildRequest();
|
|
var entitlement = new ProofOfEntitlementResult("lic", "cust", "plan", 0, 0, 0, DateTimeOffset.UtcNow.AddHours(1));
|
|
var caller = BuildCaller();
|
|
|
|
await Assert.ThrowsAsync<InvalidOperationException>(() => signer.SignAsync(request, entitlement, caller, default).AsTask());
|
|
}
|
|
|
|
private class StubKeyResolver : ISigningKeyResolver
|
|
{
|
|
private readonly string _keyId;
|
|
private readonly string _alg;
|
|
private readonly string _provider;
|
|
|
|
public StubKeyResolver(string keyId, string alg, string provider)
|
|
{
|
|
_keyId = keyId;
|
|
_alg = alg;
|
|
_provider = provider;
|
|
}
|
|
|
|
public ValueTask<SigningKeyResolution> ResolveKeyAsync(SigningMode mode, string tenant, CancellationToken cancellationToken)
|
|
{
|
|
var resolution = new SigningKeyResolution(_keyId, _provider, "https://sm.test", "sm2-subject");
|
|
return ValueTask.FromResult(resolution);
|
|
}
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
Environment.SetEnvironmentVariable("SM_SOFT_ALLOWED", _gate);
|
|
}
|
|
|
|
private static SigningRequest BuildRequest()
|
|
{
|
|
var subject = new SigningSubject("pkg", new Dictionary<string, string> { ["sha256"] = "00" });
|
|
return new SigningRequest(
|
|
new[] { subject },
|
|
"test-predicate",
|
|
JsonDocument.Parse("{}"),
|
|
"sha256:00",
|
|
new ProofOfEntitlement(SignerPoEFormat.Jwt, "stub"),
|
|
new SigningOptions(SigningMode.Keyless, null, "dsse"));
|
|
}
|
|
|
|
private static CallerContext BuildCaller() => new(
|
|
Subject: "subject-1",
|
|
Tenant: "tenant-1",
|
|
Scopes: Array.Empty<string>(),
|
|
Audiences: Array.Empty<string>(),
|
|
SenderBinding: string.Empty,
|
|
ClientCertificateThumbprint: string.Empty);
|
|
}
|