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
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:
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user