Add unit tests for PhpFrameworkSurface and PhpPharScanner
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Docs CI / lint-and-preview (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
Findings Ledger CI / build-test (push) Has been cancelled
Findings Ledger CI / migration-validation (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
Findings Ledger CI / generate-manifest (push) Has been cancelled

- Implement comprehensive tests for PhpFrameworkSurface, covering scenarios such as empty surfaces, presence of routes, controllers, middlewares, CLI commands, cron jobs, and event listeners.
- Validate metadata creation for route counts, HTTP methods, protected and public routes, and route patterns.
- Introduce tests for PhpPharScanner, including handling of non-existent files, null or empty paths, invalid PHAR files, and minimal PHAR structures.
- Ensure correct computation of SHA256 for valid PHAR files and validate the properties of PhpPharArchive, PhpPharEntry, and PhpPharScanResult.
This commit is contained in:
StellaOps Bot
2025-12-07 13:44:13 +02:00
parent af30fc322f
commit 965cbf9574
49 changed files with 11935 additions and 152 deletions

View File

@@ -11,6 +11,7 @@ using StellaOps.Attestor.Core.Signing;
using StellaOps.Cryptography;
using StellaOps.Cryptography.Kms;
using StellaOps.Cryptography.Plugin.BouncyCastle;
using StellaOps.Cryptography.Plugin.SmSoft;
namespace StellaOps.Attestor.Infrastructure.Signing;
@@ -44,6 +45,21 @@ internal sealed class AttestorSigningKeyRegistry : IDisposable
var edProvider = new BouncyCastleEd25519CryptoProvider();
RegisterProvider(edProvider);
// SM2 software provider (non-certified). Requires SM_SOFT_ALLOWED env to be enabled.
SmSoftCryptoProvider? smProvider = null;
if (RequiresSm2(signingOptions))
{
smProvider = new SmSoftCryptoProvider();
if (smProvider.Supports(CryptoCapability.Signing, SignatureAlgorithms.Sm2))
{
RegisterProvider(smProvider);
}
else
{
_logger.LogWarning("SM2 requested but SM_SOFT_ALLOWED is not enabled; SM provider not registered.");
}
}
KmsCryptoProvider? kmsProvider = null;
if (RequiresKms(signingOptions))
{
@@ -86,6 +102,7 @@ internal sealed class AttestorSigningKeyRegistry : IDisposable
providerMap,
defaultProvider,
edProvider,
smProvider,
kmsProvider,
_kmsClient,
timeProvider);
@@ -126,11 +143,16 @@ internal sealed class AttestorSigningKeyRegistry : IDisposable
=> signingOptions.Keys?.Any(static key =>
string.Equals(key?.Mode, "kms", StringComparison.OrdinalIgnoreCase)) == true;
private static bool RequiresSm2(AttestorOptions.SigningOptions signingOptions)
=> signingOptions.Keys?.Any(static key =>
string.Equals(key?.Algorithm, SignatureAlgorithms.Sm2, StringComparison.OrdinalIgnoreCase)) == true;
private SigningKeyEntry CreateEntry(
AttestorOptions.SigningKeyOptions key,
IReadOnlyDictionary<string, ICryptoProvider> providers,
DefaultCryptoProvider defaultProvider,
BouncyCastleEd25519CryptoProvider edProvider,
SmSoftCryptoProvider? smProvider,
KmsCryptoProvider? kmsProvider,
FileKmsClient? kmsClient,
TimeProvider timeProvider)
@@ -205,6 +227,22 @@ internal sealed class AttestorSigningKeyRegistry : IDisposable
edProvider.UpsertSigningKey(signingKey);
}
else if (string.Equals(providerName, "cn.sm.soft", StringComparison.OrdinalIgnoreCase))
{
if (smProvider is null)
{
throw new InvalidOperationException($"SM2 signing provider is not configured but signing key '{key.KeyId}' requests algorithm 'SM2'.");
}
var privateKeyBytes = LoadSm2KeyBytes(key);
var signingKey = new CryptoSigningKey(
new CryptoKeyReference(providerKeyId, providerName),
normalizedAlgorithm,
privateKeyBytes,
now);
smProvider.UpsertSigningKey(signingKey);
}
else
{
var parameters = LoadEcParameters(key);
@@ -252,6 +290,11 @@ internal sealed class AttestorSigningKeyRegistry : IDisposable
return "bouncycastle.ed25519";
}
if (string.Equals(key.Algorithm, SignatureAlgorithms.Sm2, StringComparison.OrdinalIgnoreCase))
{
return "cn.sm.soft";
}
return "default";
}
@@ -311,6 +354,20 @@ internal sealed class AttestorSigningKeyRegistry : IDisposable
return ecdsa.ExportParameters(true);
}
private static byte[] LoadSm2KeyBytes(AttestorOptions.SigningKeyOptions key)
{
var material = ReadMaterial(key);
// SM2 provider accepts PEM or PKCS#8 DER bytes
return key.MaterialFormat?.ToLowerInvariant() switch
{
null or "pem" => System.Text.Encoding.UTF8.GetBytes(material),
"base64" => Convert.FromBase64String(material),
"hex" => Convert.FromHexString(material),
_ => throw new InvalidOperationException($"Unsupported materialFormat '{key.MaterialFormat}' for SM2 signing key '{key.KeyId}'. Supported formats: pem, base64, hex.")
};
}
private static string ReadMaterial(AttestorOptions.SigningKeyOptions key)
{
if (!string.IsNullOrWhiteSpace(key.MaterialPassphrase))

View File

@@ -12,6 +12,7 @@
<ProjectReference Include="..\..\..\__Libraries\StellaOps.Cryptography\StellaOps.Cryptography.csproj" />
<ProjectReference Include="..\..\..\__Libraries\StellaOps.Cryptography.Plugin.BouncyCastle\StellaOps.Cryptography.Plugin.BouncyCastle.csproj" />
<ProjectReference Include="..\..\..\__Libraries\StellaOps.Cryptography.Kms\StellaOps.Cryptography.Kms.csproj" />
<ProjectReference Include="..\..\..\__Libraries\StellaOps.Cryptography.Plugin.SmSoft\StellaOps.Cryptography.Plugin.SmSoft.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.0" />
@@ -23,6 +24,6 @@
<PackageReference Include="Microsoft.Extensions.Http" Version="10.0.0" />
<PackageReference Include="MongoDB.Driver" Version="3.5.0" />
<PackageReference Include="StackExchange.Redis" Version="2.8.24" />
<PackageReference Include="AWSSDK.S3" Version="3.7.307.6" />
<PackageReference Include="AWSSDK.S3" Version="4.0.2" />
</ItemGroup>
</Project>