Add new features and tests for AirGap and Time modules
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
- Introduced `SbomService` tasks documentation. - Updated `StellaOps.sln` to include new projects: `StellaOps.AirGap.Time` and `StellaOps.AirGap.Importer`. - Added unit tests for `BundleImportPlanner`, `DsseVerifier`, `ImportValidator`, and other components in the `StellaOps.AirGap.Importer.Tests` namespace. - Implemented `InMemoryBundleRepositories` for testing bundle catalog and item repositories. - Created `MerkleRootCalculator`, `RootRotationPolicy`, and `TufMetadataValidator` tests. - Developed `StalenessCalculator` and `TimeAnchorLoader` tests in the `StellaOps.AirGap.Time.Tests` namespace. - Added `fetch-sbomservice-deps.sh` script for offline dependency fetching.
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
using StellaOps.AirGap.Importer.Validation;
|
||||
|
||||
namespace StellaOps.AirGap.Importer.Planning;
|
||||
|
||||
/// <summary>
|
||||
/// Immutable plan describing the deterministic steps taken when importing an offline bundle.
|
||||
/// This keeps replay/attestation logic stable for audits.
|
||||
/// </summary>
|
||||
public sealed record BundleImportPlan(
|
||||
IReadOnlyList<string> Steps,
|
||||
IReadOnlyDictionary<string, string> Inputs,
|
||||
BundleValidationResult InitialState)
|
||||
{
|
||||
public static BundleImportPlan FromDefaults(string bundlePath) => new List<string>
|
||||
{
|
||||
"load-trust-roots",
|
||||
"read-bundle-manifest",
|
||||
"verify-dsse-signature",
|
||||
"verify-manifest-digests",
|
||||
"validate-tuf-metadata",
|
||||
"compute-merkle-root",
|
||||
"stage-object-store",
|
||||
"record-audit-entry"
|
||||
}.AsReadOnlyPlan(bundlePath);
|
||||
}
|
||||
|
||||
file static class BundleImportPlanExtensions
|
||||
{
|
||||
public static BundleImportPlan AsReadOnlyPlan(this IReadOnlyList<string> steps, string bundlePath) =>
|
||||
new(steps, new Dictionary<string, string>
|
||||
{
|
||||
["bundlePath"] = bundlePath
|
||||
}, BundleValidationResult.Success("plan-staged"));
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using StellaOps.AirGap.Importer.Contracts;
|
||||
using StellaOps.AirGap.Importer.Validation;
|
||||
|
||||
namespace StellaOps.AirGap.Importer.Planning;
|
||||
|
||||
/// <summary>
|
||||
/// Produces deterministic import plans and performs fast pre-flight checks before expensive validation work.
|
||||
/// </summary>
|
||||
public sealed class BundleImportPlanner
|
||||
{
|
||||
public BundleImportPlan CreatePlan(string bundlePath, TrustRootConfig trustRoot)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(bundlePath))
|
||||
{
|
||||
return new BundleImportPlan(
|
||||
Array.Empty<string>(),
|
||||
new Dictionary<string, string> { ["bundlePath"] = "(missing)" },
|
||||
BundleValidationResult.Failure("bundle-path-required"));
|
||||
}
|
||||
|
||||
if (trustRoot.TrustedKeyFingerprints.Count == 0)
|
||||
{
|
||||
return new BundleImportPlan(
|
||||
new[] { "load-trust-roots" },
|
||||
new Dictionary<string, string> { ["bundlePath"] = bundlePath },
|
||||
BundleValidationResult.Failure("trust-roots-required"));
|
||||
}
|
||||
|
||||
if (trustRoot.NotAfterUtc is { } notAfter && trustRoot.NotBeforeUtc is { } notBefore && notAfter < notBefore)
|
||||
{
|
||||
return new BundleImportPlan(
|
||||
new[] { "load-trust-roots" },
|
||||
new Dictionary<string, string> { ["bundlePath"] = bundlePath },
|
||||
BundleValidationResult.Failure("invalid-trust-window"));
|
||||
}
|
||||
|
||||
return BundleImportPlan.FromDefaults(bundlePath);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user