Files
git.stella-ops.org/src/__Libraries/StellaOps.Evidence/Services/EvidenceQueryService.cs

75 lines
2.8 KiB
C#

using StellaOps.Evidence.Models;
namespace StellaOps.Evidence.Services;
/// <summary>
/// Query helpers for evidence chains.
/// </summary>
public sealed class EvidenceQueryService : IEvidenceQueryService
{
public IEnumerable<AttestationEvidence> GetAttestationsForSbom(
EvidenceIndex index, string sbomDigest)
{
var sbomExists = index.Sboms.Any(s => string.Equals(s.Digest, sbomDigest, StringComparison.Ordinal));
if (!sbomExists)
{
return Array.Empty<AttestationEvidence>();
}
return index.Attestations
.Where(a => string.Equals(a.Type, "sbom", StringComparison.Ordinal) &&
string.Equals(a.Digest, sbomDigest, StringComparison.Ordinal));
}
public IEnumerable<ReachabilityEvidence> GetReachabilityForVulnerability(
EvidenceIndex index, string vulnerabilityId)
{
return index.ReachabilityProofs
.Where(r => r.VulnerabilityId == vulnerabilityId);
}
public IEnumerable<VexEvidence> GetVexForVulnerability(
EvidenceIndex index, string vulnerabilityId)
{
return index.VexDocuments
.Where(v => v.AffectedVulnerabilities.Contains(vulnerabilityId));
}
public EvidenceChainReport BuildChainReport(EvidenceIndex index)
{
return new EvidenceChainReport
{
VerdictDigest = index.Verdict.Digest,
SbomCount = index.Sboms.Length,
AttestationCount = index.Attestations.Length,
VexCount = index.VexDocuments.Length,
ReachabilityProofCount = index.ReachabilityProofs.Length,
UnknownCount = index.Unknowns.Length,
AllSignaturesValid = index.Attestations.All(a => a.SignatureValid),
HasRekorEntries = index.Attestations.Any(a => a.RekorLogIndex is not null),
ToolChainComplete = index.ToolChain is not null
};
}
}
public interface IEvidenceQueryService
{
IEnumerable<AttestationEvidence> GetAttestationsForSbom(EvidenceIndex index, string sbomDigest);
IEnumerable<ReachabilityEvidence> GetReachabilityForVulnerability(EvidenceIndex index, string vulnerabilityId);
IEnumerable<VexEvidence> GetVexForVulnerability(EvidenceIndex index, string vulnerabilityId);
EvidenceChainReport BuildChainReport(EvidenceIndex index);
}
public sealed record EvidenceChainReport
{
public required string VerdictDigest { get; init; }
public int SbomCount { get; init; }
public int AttestationCount { get; init; }
public int VexCount { get; init; }
public int ReachabilityProofCount { get; init; }
public int UnknownCount { get; init; }
public bool AllSignaturesValid { get; init; }
public bool HasRekorEntries { get; init; }
public bool ToolChainComplete { get; init; }
}