Add post-quantum cryptography support with PqSoftCryptoProvider
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Scanner Analyzers / Discover Analyzers (push) Has been cancelled
Scanner Analyzers / Build Analyzers (push) Has been cancelled
Scanner Analyzers / Test Language Analyzers (push) Has been cancelled
Scanner Analyzers / Validate Test Fixtures (push) Has been cancelled
Scanner Analyzers / Verify Deterministic Output (push) Has been cancelled
wine-csp-build / Build Wine CSP Image (push) Has been cancelled
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Scanner Analyzers / Discover Analyzers (push) Has been cancelled
Scanner Analyzers / Build Analyzers (push) Has been cancelled
Scanner Analyzers / Test Language Analyzers (push) Has been cancelled
Scanner Analyzers / Validate Test Fixtures (push) Has been cancelled
Scanner Analyzers / Verify Deterministic Output (push) Has been cancelled
wine-csp-build / Build Wine CSP Image (push) Has been cancelled
- Implemented PqSoftCryptoProvider for software-only post-quantum algorithms (Dilithium3, Falcon512) using BouncyCastle. - Added PqSoftProviderOptions and PqSoftKeyOptions for configuration. - Created unit tests for Dilithium3 and Falcon512 signing and verification. - Introduced EcdsaPolicyCryptoProvider for compliance profiles (FIPS/eIDAS) with explicit allow-lists. - Added KcmvpHashOnlyProvider for KCMVP baseline compliance. - Updated project files and dependencies for new libraries and testing frameworks.
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using StellaOps.Attestor.Core.Options;
|
||||
using StellaOps.Attestor.Core.Signing;
|
||||
using StellaOps.Attestor.Infrastructure.Signing;
|
||||
using StellaOps.Cryptography;
|
||||
using StellaOps.Cryptography.Plugin.SmSoft;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Attestor.Tests.Signing;
|
||||
|
||||
public class Sm2AttestorTests
|
||||
{
|
||||
private readonly string? _gate;
|
||||
|
||||
public Sm2AttestorTests()
|
||||
{
|
||||
_gate = Environment.GetEnvironmentVariable("SM_SOFT_ALLOWED");
|
||||
Environment.SetEnvironmentVariable("SM_SOFT_ALLOWED", "1");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Registry_ResolvesSm2_WhenGateEnabled()
|
||||
{
|
||||
var keyPath = Sm2TestKeyFactory.WriteTempPem();
|
||||
|
||||
var options = Options.Create(new AttestorOptions
|
||||
{
|
||||
Signing = new AttestorOptions.SigningOptions
|
||||
{
|
||||
PreferredProviders = new[] { "cn.sm.soft" },
|
||||
Keys = new List<AttestorOptions.SigningKeyOptions>
|
||||
{
|
||||
new()
|
||||
{
|
||||
KeyId = "sm2-key",
|
||||
Algorithm = SignatureAlgorithms.Sm2,
|
||||
KeyPath = keyPath,
|
||||
MaterialFormat = "pem",
|
||||
Enabled = true,
|
||||
Provider = "cn.sm.soft"
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var registry = new AttestorSigningKeyRegistry(
|
||||
options,
|
||||
TimeProvider.System,
|
||||
NullLogger<AttestorSigningKeyRegistry>.Instance);
|
||||
|
||||
var entry = registry.GetRequired("sm2-key");
|
||||
Assert.Equal(SignatureAlgorithms.Sm2, entry.Algorithm);
|
||||
Assert.Equal("cn.sm.soft", entry.ProviderName);
|
||||
|
||||
var signer = registry.Registry.ResolveSigner(CryptoCapability.Signing, SignatureAlgorithms.Sm2, entry.Key.Reference).Signer;
|
||||
var payload = System.Text.Encoding.UTF8.GetBytes("sm2-attestor-test");
|
||||
var sig = signer.SignAsync(payload, CancellationToken.None).Result;
|
||||
Assert.True(signer.VerifyAsync(payload, sig, CancellationToken.None).Result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Registry_Throws_WhenGateDisabled()
|
||||
{
|
||||
Environment.SetEnvironmentVariable("SM_SOFT_ALLOWED", null);
|
||||
var keyPath = Sm2TestKeyFactory.WriteTempPem();
|
||||
|
||||
var options = Options.Create(new AttestorOptions
|
||||
{
|
||||
Signing = new AttestorOptions.SigningOptions
|
||||
{
|
||||
PreferredProviders = new[] { "cn.sm.soft" },
|
||||
Keys = new List<AttestorOptions.SigningKeyOptions>
|
||||
{
|
||||
new()
|
||||
{
|
||||
KeyId = "sm2-key",
|
||||
Algorithm = SignatureAlgorithms.Sm2,
|
||||
KeyPath = keyPath,
|
||||
MaterialFormat = "pem",
|
||||
Enabled = true,
|
||||
Provider = "cn.sm.soft"
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Assert.Throws<InvalidOperationException>(() =>
|
||||
new AttestorSigningKeyRegistry(options, TimeProvider.System, NullLogger<AttestorSigningKeyRegistry>.Instance));
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Environment.SetEnvironmentVariable("SM_SOFT_ALLOWED", _gate);
|
||||
}
|
||||
}
|
||||
|
||||
internal static class Sm2TestKeyFactory
|
||||
{
|
||||
public static string WriteTempPem()
|
||||
{
|
||||
var curve = Org.BouncyCastle.Asn1.GM.GMNamedCurves.GetByName("SM2P256V1");
|
||||
var domain = new Org.BouncyCastle.Crypto.Parameters.ECDomainParameters(curve.Curve, curve.G, curve.N, curve.H, curve.GetSeed());
|
||||
var generator = new Org.BouncyCastle.Crypto.Generators.ECKeyPairGenerator("EC");
|
||||
generator.Init(new Org.BouncyCastle.Crypto.Generators.ECKeyGenerationParameters(domain, new Org.BouncyCastle.Security.SecureRandom()));
|
||||
var pair = generator.GenerateKeyPair();
|
||||
var privInfo = Org.BouncyCastle.Asn1.Pkcs.PrivateKeyInfoFactory.CreatePrivateKeyInfo(pair.Private);
|
||||
var pem = Convert.ToBase64String(privInfo.GetDerEncoded());
|
||||
var path = System.IO.Path.GetTempFileName();
|
||||
System.IO.File.WriteAllText(path, "-----BEGIN PRIVATE KEY-----\n" + pem + "\n-----END PRIVATE KEY-----\n");
|
||||
return path;
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
<UseConcelierTestInfra>false</UseConcelierTestInfra>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BouncyCastle.Cryptography" Version="2.5.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.0" />
|
||||
<PackageReference Include="xunit" Version="2.9.2" />
|
||||
|
||||
Reference in New Issue
Block a user