Files
git.stella-ops.org/src/AirGap/StellaOps.AirGap.Importer/Reconciliation/Parsers/IAttestationParser.cs
master 2170a58734
Some checks failed
Lighthouse CI / Lighthouse Audit (push) Waiting to run
Lighthouse CI / Axe Accessibility Audit (push) Waiting to run
Manifest Integrity / Validate Schema Integrity (push) Waiting to run
Manifest Integrity / Validate Contract Documents (push) Waiting to run
Manifest Integrity / Validate Pack Fixtures (push) Waiting to run
Manifest Integrity / Audit SHA256SUMS Files (push) Waiting to run
Manifest Integrity / Verify Merkle Roots (push) Waiting to run
Policy Lint & Smoke / policy-lint (push) Waiting to run
Policy Simulation / policy-simulate (push) Waiting to run
Docs CI / lint-and-preview (push) Has been cancelled
Export Center CI / export-ci (push) Has been cancelled
Findings Ledger CI / build-test (push) Has been cancelled
Findings Ledger CI / migration-validation (push) Has been cancelled
Findings Ledger CI / generate-manifest (push) Has been cancelled
Add comprehensive security tests for OWASP A02, A05, A07, and A08 categories
- Implemented tests for Cryptographic Failures (A02) to ensure proper handling of sensitive data, secure algorithms, and key management.
- Added tests for Security Misconfiguration (A05) to validate production configurations, security headers, CORS settings, and feature management.
- Developed tests for Authentication Failures (A07) to enforce strong password policies, rate limiting, session management, and MFA support.
- Created tests for Software and Data Integrity Failures (A08) to verify artifact signatures, SBOM integrity, attestation chains, and feed updates.
2025-12-16 16:40:44 +02:00

200 lines
6.0 KiB
C#

// =============================================================================
// IAttestationParser.cs
// Attestation parsing abstraction for DSSE/in-toto attestations
// Part of Step 2: Evidence Collection (Task T6)
// =============================================================================
namespace StellaOps.AirGap.Importer.Reconciliation.Parsers;
/// <summary>
/// Interface for parsing DSSE-wrapped in-toto attestations.
/// </summary>
public interface IAttestationParser
{
/// <summary>
/// Parses a DSSE envelope from the given file path.
/// </summary>
/// <param name="filePath">Path to the attestation file.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>Parsed attestation result.</returns>
Task<AttestationParseResult> ParseAsync(string filePath, CancellationToken cancellationToken = default);
/// <summary>
/// Parses a DSSE envelope from a stream.
/// </summary>
/// <param name="stream">Stream containing the attestation content.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>Parsed attestation result.</returns>
Task<AttestationParseResult> ParseAsync(Stream stream, CancellationToken cancellationToken = default);
/// <summary>
/// Detects if a file is a DSSE attestation.
/// </summary>
/// <param name="filePath">Path to the file.</param>
/// <returns>True if the file appears to be a DSSE attestation.</returns>
bool IsAttestation(string filePath);
}
/// <summary>
/// Result of parsing an attestation document.
/// </summary>
public sealed record AttestationParseResult
{
/// <summary>
/// Whether parsing was successful.
/// </summary>
public bool IsSuccess { get; init; }
/// <summary>
/// Error message if parsing failed.
/// </summary>
public string? ErrorMessage { get; init; }
/// <summary>
/// The parsed DSSE envelope.
/// </summary>
public DsseEnvelope? Envelope { get; init; }
/// <summary>
/// The parsed in-toto statement (payload).
/// </summary>
public InTotoStatement? Statement { get; init; }
/// <summary>
/// Creates a successful parse result.
/// </summary>
public static AttestationParseResult Success(DsseEnvelope envelope, InTotoStatement statement)
{
return new AttestationParseResult
{
IsSuccess = true,
Envelope = envelope,
Statement = statement
};
}
/// <summary>
/// Creates a failed parse result.
/// </summary>
public static AttestationParseResult Failure(string errorMessage)
{
return new AttestationParseResult
{
IsSuccess = false,
ErrorMessage = errorMessage
};
}
}
/// <summary>
/// Represents a DSSE (Dead Simple Signing Envelope).
/// </summary>
public sealed record DsseEnvelope
{
/// <summary>
/// Payload type (typically "application/vnd.in-toto+json").
/// </summary>
public required string PayloadType { get; init; }
/// <summary>
/// Base64-encoded payload.
/// </summary>
public required string Payload { get; init; }
/// <summary>
/// Signatures on the envelope.
/// </summary>
public IReadOnlyList<DsseSignature> Signatures { get; init; } = [];
}
/// <summary>
/// Represents a signature in a DSSE envelope.
/// </summary>
public sealed record DsseSignature
{
/// <summary>
/// Key identifier (e.g., key ID or certificate fingerprint).
/// </summary>
public string? KeyId { get; init; }
/// <summary>
/// Base64-encoded signature.
/// </summary>
public required string Sig { get; init; }
/// <summary>
/// Certificate chain (if present).
/// </summary>
public string? Cert { get; init; }
}
/// <summary>
/// Represents an in-toto statement (attestation payload).
/// </summary>
public sealed record InTotoStatement
{
/// <summary>
/// Statement type (typically "https://in-toto.io/Statement/v1").
/// </summary>
public required string Type { get; init; }
/// <summary>
/// Predicate type URI (e.g., "https://slsa.dev/provenance/v1").
/// </summary>
public required string PredicateType { get; init; }
/// <summary>
/// Subjects (artifacts) this statement applies to.
/// </summary>
public IReadOnlyList<InTotoSubject> Subjects { get; init; } = [];
/// <summary>
/// Raw predicate JSON for further processing.
/// </summary>
public string? PredicateJson { get; init; }
}
/// <summary>
/// Represents a subject in an in-toto statement.
/// </summary>
public sealed record InTotoSubject
{
/// <summary>
/// Subject name (typically a file path or artifact reference).
/// </summary>
public string? Name { get; init; }
/// <summary>
/// Subject digests (algorithm -> hash).
/// </summary>
public IReadOnlyDictionary<string, string> Digest { get; init; } = new Dictionary<string, string>();
/// <summary>
/// Gets the normalized SHA-256 digest if available.
/// </summary>
public string? GetSha256Digest()
{
if (Digest.TryGetValue("sha256", out var hash))
{
return "sha256:" + hash.ToLowerInvariant();
}
return null;
}
}
/// <summary>
/// Well-known predicate types for attestations.
/// </summary>
public static class PredicateTypes
{
public const string SlsaProvenanceV1 = "https://slsa.dev/provenance/v1";
public const string SlsaProvenanceV02 = "https://slsa.dev/provenance/v0.2";
public const string InTotoLink = "https://in-toto.io/Link/v1";
public const string Spdx = "https://spdx.dev/Document";
public const string CycloneDx = "https://cyclonedx.org/bom";
public const string OpenVex = "https://openvex.dev/ns/v0.2.0";
public const string Csaf = "https://docs.oasis-open.org/csaf/csaf/v2.0";
public const string ScorecardV2 = "https://ossf.github.io/scorecard/v2";
public const string VulnerabilityReport = "https://cosign.sigstore.dev/attestation/vuln/v1";
}