feat: Add native binary analyzer test utilities and implement SM2 signing tests
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
Manifest Integrity / Audit SHA256SUMS Files (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 / Verify Merkle Roots (push) Has been cancelled
Scanner Analyzers / Build Analyzers (push) Has been cancelled
Scanner Analyzers / Discover 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
Signals CI & Image / signals-ci (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Export Center CI / export-ci (push) Has been cancelled
Notify Smoke Test / Notify Unit Tests (push) Has been cancelled
Notify Smoke Test / Notifier Service Tests (push) Has been cancelled
Notify Smoke Test / Notification Smoke Test (push) Has been cancelled

- Introduced `NativeTestBase` class for ELF, PE, and Mach-O binary parsing helpers and assertions.
- Created `TestCryptoFactory` for SM2 cryptographic provider setup and key generation.
- Implemented `Sm2SigningTests` to validate signing functionality with environment gate checks.
- Developed console export service and store with comprehensive unit tests for export status management.
This commit is contained in:
StellaOps Bot
2025-12-07 13:12:41 +02:00
parent d907729778
commit e53a282fbe
387 changed files with 21941 additions and 1518 deletions

View File

@@ -0,0 +1,257 @@
using StellaOps.Scanner.Analyzers.Native;
using StellaOps.Scanner.Analyzers.Native.Tests.Fixtures;
namespace StellaOps.Scanner.Analyzers.Native.Tests.TestUtilities;
/// <summary>
/// Base class for native binary analyzer tests.
/// Provides common parsing helpers and assertion methods.
/// </summary>
public abstract class NativeTestBase
{
#region ELF Parsing Helpers
/// <summary>
/// Parses an ELF binary from raw bytes.
/// </summary>
protected static ElfDynamicInfo ParseElf(byte[] data)
{
using var stream = new MemoryStream(data);
if (!ElfDynamicSectionParser.TryParse(stream, out var info))
throw new InvalidOperationException("Failed to parse ELF binary");
return info;
}
/// <summary>
/// Attempts to parse an ELF binary.
/// </summary>
protected static bool TryParseElf(byte[] data, out ElfDynamicInfo info)
{
using var stream = new MemoryStream(data);
return ElfDynamicSectionParser.TryParse(stream, out info);
}
/// <summary>
/// Parses an ELF binary using the builder.
/// </summary>
protected static ElfDynamicInfo ParseElf(ElfBuilder builder)
{
return ParseElf(builder.Build());
}
#endregion
#region PE Parsing Helpers
/// <summary>
/// Parses a PE binary from raw bytes.
/// </summary>
protected static PeImportInfo ParsePe(byte[] data)
{
using var stream = new MemoryStream(data);
if (!PeImportParser.TryParse(stream, out var info))
throw new InvalidOperationException("Failed to parse PE binary");
return info;
}
/// <summary>
/// Attempts to parse a PE binary.
/// </summary>
protected static bool TryParsePe(byte[] data, out PeImportInfo info)
{
using var stream = new MemoryStream(data);
return PeImportParser.TryParse(stream, out info);
}
/// <summary>
/// Parses a PE binary using the builder.
/// </summary>
protected static PeImportInfo ParsePe(PeBuilder builder)
{
return ParsePe(builder.Build());
}
#endregion
#region Mach-O Parsing Helpers
/// <summary>
/// Parses a Mach-O binary from raw bytes.
/// </summary>
protected static MachOImportInfo ParseMachO(byte[] data)
{
using var stream = new MemoryStream(data);
if (!MachOLoadCommandParser.TryParse(stream, out var info))
throw new InvalidOperationException("Failed to parse Mach-O binary");
return info;
}
/// <summary>
/// Attempts to parse a Mach-O binary.
/// </summary>
protected static bool TryParseMachO(byte[] data, out MachOImportInfo info)
{
using var stream = new MemoryStream(data);
return MachOLoadCommandParser.TryParse(stream, out info);
}
/// <summary>
/// Parses a Mach-O binary using the builder.
/// </summary>
protected static MachOImportInfo ParseMachO(MachOBuilder builder)
{
return ParseMachO(builder.Build());
}
#endregion
#region ELF Assertions
/// <summary>
/// Asserts that the dependencies match the expected sonames.
/// </summary>
protected static void AssertDependencies(IReadOnlyList<ElfDeclaredDependency> deps, params string[] expectedSonames)
{
Assert.Equal(expectedSonames.Length, deps.Count);
for (var i = 0; i < expectedSonames.Length; i++)
{
Assert.Equal(expectedSonames[i], deps[i].Soname);
}
}
/// <summary>
/// Asserts that a dependency has the expected version needs.
/// </summary>
protected static void AssertVersionNeeds(
ElfDeclaredDependency dep,
params (string Version, bool IsWeak)[] expected)
{
Assert.Equal(expected.Length, dep.VersionNeeds.Count);
foreach (var (version, isWeak) in expected)
{
var vn = dep.VersionNeeds.FirstOrDefault(v => v.Version == version);
Assert.NotNull(vn);
Assert.Equal(isWeak, vn.IsWeak);
}
}
/// <summary>
/// Asserts that a dependency has the specified weak versions.
/// </summary>
protected static void AssertWeakVersions(ElfDeclaredDependency dep, params string[] weakVersions)
{
foreach (var version in weakVersions)
{
var vn = dep.VersionNeeds.FirstOrDefault(v => v.Version == version);
Assert.NotNull(vn);
Assert.True(vn.IsWeak, $"Expected {version} to be weak");
}
}
/// <summary>
/// Asserts that a dependency has the specified strong (non-weak) versions.
/// </summary>
protected static void AssertStrongVersions(ElfDeclaredDependency dep, params string[] strongVersions)
{
foreach (var version in strongVersions)
{
var vn = dep.VersionNeeds.FirstOrDefault(v => v.Version == version);
Assert.NotNull(vn);
Assert.False(vn.IsWeak, $"Expected {version} to be strong (not weak)");
}
}
#endregion
#region PE Assertions
/// <summary>
/// Asserts that the dependencies match the expected DLL names.
/// </summary>
protected static void AssertDependencies(IReadOnlyList<PeDeclaredDependency> deps, params string[] expectedDllNames)
{
Assert.Equal(expectedDllNames.Length, deps.Count);
for (var i = 0; i < expectedDllNames.Length; i++)
{
Assert.Equal(expectedDllNames[i], deps[i].DllName, ignoreCase: true);
}
}
/// <summary>
/// Asserts that a dependency has the expected imported functions.
/// </summary>
protected static void AssertImportedFunctions(
PeDeclaredDependency dep,
params string[] expectedFunctions)
{
foreach (var func in expectedFunctions)
{
Assert.Contains(func, dep.ImportedFunctions);
}
}
/// <summary>
/// Asserts that the SxS dependencies match the expected names.
/// </summary>
protected static void AssertSxsDependencies(IReadOnlyList<PeSxsDependency> deps, params string[] expectedNames)
{
foreach (var name in expectedNames)
{
Assert.Contains(deps, d => d.Name == name);
}
}
#endregion
#region Mach-O Assertions
/// <summary>
/// Asserts that the dependencies match the expected paths.
/// </summary>
protected static void AssertDependencies(IReadOnlyList<MachODeclaredDependency> deps, params string[] expectedPaths)
{
Assert.Equal(expectedPaths.Length, deps.Count);
for (var i = 0; i < expectedPaths.Length; i++)
{
Assert.Equal(expectedPaths[i], deps[i].Path);
}
}
/// <summary>
/// Asserts that a dependency has the expected reason code.
/// </summary>
protected static void AssertDylibKind(MachODeclaredDependency dep, string expectedReasonCode)
{
Assert.Equal(expectedReasonCode, dep.ReasonCode);
}
/// <summary>
/// Asserts that a dependency has weak linkage.
/// </summary>
protected static void AssertWeakDylib(MachODeclaredDependency dep)
{
Assert.Equal("macho-weaklib", dep.ReasonCode);
}
/// <summary>
/// Asserts that a dependency is a reexport.
/// </summary>
protected static void AssertReexportDylib(MachODeclaredDependency dep)
{
Assert.Equal("macho-reexport", dep.ReasonCode);
}
/// <summary>
/// Asserts that the rpaths match expected values.
/// </summary>
protected static void AssertRpaths(IReadOnlyList<string> rpaths, params string[] expectedRpaths)
{
Assert.Equal(expectedRpaths.Length, rpaths.Count);
for (var i = 0; i < expectedRpaths.Length; i++)
{
Assert.Equal(expectedRpaths[i], rpaths[i]);
}
}
#endregion
}