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,227 @@
using System.Collections.Immutable;
using System.Globalization;
namespace StellaOps.Scanner.Analyzers.Lang.Go.Internal;
/// <summary>
/// Aggregates capability scan results from Go source code analysis.
/// </summary>
internal sealed class GoCapabilityScanResult
{
private readonly IReadOnlyList<GoCapabilityEvidence> _evidences;
private ILookup<CapabilityKind, GoCapabilityEvidence>? _byKind;
private ILookup<CapabilityRisk, GoCapabilityEvidence>? _byRisk;
private ILookup<string, GoCapabilityEvidence>? _byFile;
public GoCapabilityScanResult(IReadOnlyList<GoCapabilityEvidence> evidences)
{
_evidences = evidences ?? Array.Empty<GoCapabilityEvidence>();
}
/// <summary>
/// All capability evidences found.
/// </summary>
public IReadOnlyList<GoCapabilityEvidence> Evidences => _evidences;
/// <summary>
/// Gets whether any capabilities were detected.
/// </summary>
public bool HasCapabilities => _evidences.Count > 0;
/// <summary>
/// Gets evidences grouped by capability kind.
/// </summary>
public ILookup<CapabilityKind, GoCapabilityEvidence> EvidencesByKind
=> _byKind ??= _evidences.ToLookup(e => e.Kind);
/// <summary>
/// Gets evidences grouped by risk level.
/// </summary>
public ILookup<CapabilityRisk, GoCapabilityEvidence> EvidencesByRisk
=> _byRisk ??= _evidences.ToLookup(e => e.Risk);
/// <summary>
/// Gets evidences grouped by source file.
/// </summary>
public ILookup<string, GoCapabilityEvidence> EvidencesByFile
=> _byFile ??= _evidences.ToLookup(e => e.SourceFile, StringComparer.OrdinalIgnoreCase);
/// <summary>
/// Gets all critical risk evidences.
/// </summary>
public IEnumerable<GoCapabilityEvidence> CriticalRiskEvidences
=> _evidences.Where(e => e.Risk == CapabilityRisk.Critical);
/// <summary>
/// Gets all high risk evidences.
/// </summary>
public IEnumerable<GoCapabilityEvidence> HighRiskEvidences
=> _evidences.Where(e => e.Risk == CapabilityRisk.High);
/// <summary>
/// Gets the set of detected capability kinds.
/// </summary>
public IReadOnlySet<CapabilityKind> DetectedKinds
=> _evidences.Select(e => e.Kind).ToHashSet();
/// <summary>
/// Gets the highest risk level found.
/// </summary>
public CapabilityRisk HighestRisk
=> _evidences.Count > 0
? _evidences.Max(e => e.Risk)
: CapabilityRisk.Low;
/// <summary>
/// Gets evidences for a specific capability kind.
/// </summary>
public IEnumerable<GoCapabilityEvidence> GetByKind(CapabilityKind kind)
=> EvidencesByKind[kind];
/// <summary>
/// Gets evidences at or above a specific risk level.
/// </summary>
public IEnumerable<GoCapabilityEvidence> GetByMinimumRisk(CapabilityRisk minRisk)
=> _evidences.Where(e => e.Risk >= minRisk);
/// <summary>
/// Creates metadata entries for the scan result.
/// </summary>
public IEnumerable<KeyValuePair<string, string?>> CreateMetadata()
{
yield return new KeyValuePair<string, string?>(
"capability.total_count",
_evidences.Count.ToString(CultureInfo.InvariantCulture));
// Count by kind (only emit non-zero)
foreach (var kindGroup in EvidencesByKind.OrderBy(g => g.Key.ToString(), StringComparer.Ordinal))
{
yield return new KeyValuePair<string, string?>(
$"capability.{kindGroup.Key.ToString().ToLowerInvariant()}_count",
kindGroup.Count().ToString(CultureInfo.InvariantCulture));
}
// Count by risk
var criticalCount = CriticalRiskEvidences.Count();
var highCount = HighRiskEvidences.Count();
var mediumCount = _evidences.Count(e => e.Risk == CapabilityRisk.Medium);
var lowCount = _evidences.Count(e => e.Risk == CapabilityRisk.Low);
yield return new KeyValuePair<string, string?>("capability.critical_risk_count", criticalCount.ToString(CultureInfo.InvariantCulture));
yield return new KeyValuePair<string, string?>("capability.high_risk_count", highCount.ToString(CultureInfo.InvariantCulture));
yield return new KeyValuePair<string, string?>("capability.medium_risk_count", mediumCount.ToString(CultureInfo.InvariantCulture));
yield return new KeyValuePair<string, string?>("capability.low_risk_count", lowCount.ToString(CultureInfo.InvariantCulture));
// Highest risk
if (_evidences.Count > 0)
{
yield return new KeyValuePair<string, string?>(
"capability.highest_risk",
HighestRisk.ToString().ToLowerInvariant());
}
// Detected capabilities as semicolon-separated list
if (DetectedKinds.Count > 0)
{
yield return new KeyValuePair<string, string?>(
"capability.detected_kinds",
string.Join(';', DetectedKinds.OrderBy(k => k.ToString(), StringComparer.Ordinal).Select(k => k.ToString().ToLowerInvariant())));
}
// Files with critical issues (first 10)
var criticalFiles = CriticalRiskEvidences
.Select(e => e.SourceFile)
.Distinct(StringComparer.OrdinalIgnoreCase)
.OrderBy(f => f, StringComparer.Ordinal)
.ToList();
if (criticalFiles.Count > 0)
{
yield return new KeyValuePair<string, string?>(
"capability.critical_files",
string.Join(';', criticalFiles.Take(10)));
if (criticalFiles.Count > 10)
{
yield return new KeyValuePair<string, string?>(
"capability.critical_files_truncated",
"true");
}
}
// Unique patterns detected
var uniquePatterns = _evidences
.Select(e => e.Pattern)
.Distinct(StringComparer.OrdinalIgnoreCase)
.Count();
yield return new KeyValuePair<string, string?>(
"capability.unique_pattern_count",
uniquePatterns.ToString(CultureInfo.InvariantCulture));
}
/// <summary>
/// Creates a summary of detected capabilities.
/// </summary>
public GoCapabilitySummary CreateSummary()
{
return new GoCapabilitySummary(
HasExec: EvidencesByKind[CapabilityKind.Exec].Any(),
HasFilesystem: EvidencesByKind[CapabilityKind.Filesystem].Any(),
HasNetwork: EvidencesByKind[CapabilityKind.Network].Any(),
HasEnvironment: EvidencesByKind[CapabilityKind.Environment].Any(),
HasSerialization: EvidencesByKind[CapabilityKind.Serialization].Any(),
HasCrypto: EvidencesByKind[CapabilityKind.Crypto].Any(),
HasDatabase: EvidencesByKind[CapabilityKind.Database].Any(),
HasDynamicCode: EvidencesByKind[CapabilityKind.DynamicCode].Any(),
HasReflection: EvidencesByKind[CapabilityKind.Reflection].Any(),
HasNativeCode: EvidencesByKind[CapabilityKind.NativeCode].Any(),
HasPluginLoading: EvidencesByKind[CapabilityKind.PluginLoading].Any(),
CriticalCount: CriticalRiskEvidences.Count(),
HighRiskCount: HighRiskEvidences.Count(),
TotalCount: _evidences.Count);
}
/// <summary>
/// Empty scan result with no capabilities detected.
/// </summary>
public static GoCapabilityScanResult Empty { get; } = new(Array.Empty<GoCapabilityEvidence>());
}
/// <summary>
/// Summary of detected Go capabilities.
/// </summary>
internal sealed record GoCapabilitySummary(
bool HasExec,
bool HasFilesystem,
bool HasNetwork,
bool HasEnvironment,
bool HasSerialization,
bool HasCrypto,
bool HasDatabase,
bool HasDynamicCode,
bool HasReflection,
bool HasNativeCode,
bool HasPluginLoading,
int CriticalCount,
int HighRiskCount,
int TotalCount)
{
/// <summary>
/// Creates metadata entries for the summary.
/// </summary>
public IEnumerable<KeyValuePair<string, string?>> CreateMetadata()
{
yield return new KeyValuePair<string, string?>("capability.has_exec", HasExec.ToString().ToLowerInvariant());
yield return new KeyValuePair<string, string?>("capability.has_filesystem", HasFilesystem.ToString().ToLowerInvariant());
yield return new KeyValuePair<string, string?>("capability.has_network", HasNetwork.ToString().ToLowerInvariant());
yield return new KeyValuePair<string, string?>("capability.has_environment", HasEnvironment.ToString().ToLowerInvariant());
yield return new KeyValuePair<string, string?>("capability.has_serialization", HasSerialization.ToString().ToLowerInvariant());
yield return new KeyValuePair<string, string?>("capability.has_crypto", HasCrypto.ToString().ToLowerInvariant());
yield return new KeyValuePair<string, string?>("capability.has_database", HasDatabase.ToString().ToLowerInvariant());
yield return new KeyValuePair<string, string?>("capability.has_dynamic_code", HasDynamicCode.ToString().ToLowerInvariant());
yield return new KeyValuePair<string, string?>("capability.has_reflection", HasReflection.ToString().ToLowerInvariant());
yield return new KeyValuePair<string, string?>("capability.has_native_code", HasNativeCode.ToString().ToLowerInvariant());
yield return new KeyValuePair<string, string?>("capability.has_plugin_loading", HasPluginLoading.ToString().ToLowerInvariant());
}
}