using System.Text.Json.Serialization;
namespace StellaOps.BinaryIndex.Builders;
///
/// A claim asserting a CVE verdict for a specific fingerprint.
/// Created when reproducible builds show a function was modified to fix a CVE.
///
public sealed record FingerprintClaim
{
///
/// Unique identifier for this claim.
///
public Guid Id { get; init; }
///
/// ID of the fingerprint this claim is about.
///
public required Guid FingerprintId { get; init; }
///
/// CVE identifier (e.g., "CVE-2023-12345").
///
public required string CveId { get; init; }
///
/// Verdict: whether this fingerprint is fixed, vulnerable, or unknown.
///
public required ClaimVerdict Verdict { get; init; }
///
/// Evidence supporting this claim.
///
public required FingerprintClaimEvidence Evidence { get; init; }
///
/// Hash of the DSSE attestation if signed.
///
public string? AttestationDsseHash { get; init; }
///
/// When this claim was created.
///
public DateTimeOffset CreatedAt { get; init; } = DateTimeOffset.UtcNow;
///
/// When this claim was last updated.
///
public DateTimeOffset? UpdatedAt { get; init; }
///
/// Source that generated this claim (e.g., "repro-builder-alpine").
///
public string? Source { get; init; }
///
/// Confidence in this claim (0.0-1.0).
///
public decimal Confidence { get; init; } = 1.0m;
}
///
/// Verdict for a fingerprint claim.
///
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum ClaimVerdict
{
///
/// The fingerprint is from a binary that contains the CVE fix.
///
Fixed,
///
/// The fingerprint is from a binary that is vulnerable to the CVE.
///
Vulnerable,
///
/// Unable to determine fix status.
///
Unknown
}
///
/// Evidence supporting a fingerprint claim.
///
public sealed record FingerprintClaimEvidence
{
///
/// Git commit or patch reference that introduced the fix.
///
public required string PatchCommit { get; init; }
///
/// List of function names that changed between vulnerable and fixed versions.
///
public required IReadOnlyList ChangedFunctions { get; init; }
///
/// Similarity scores for modified functions (function name -> score).
///
public IReadOnlyDictionary? FunctionSimilarities { get; init; }
///
/// Reference to the vulnerable build artifacts.
///
public string? VulnerableBuildRef { get; init; }
///
/// Reference to the patched build artifacts.
///
public string? PatchedBuildRef { get; init; }
///
/// Source package name.
///
public string? SourcePackage { get; init; }
///
/// Vulnerable version string.
///
public string? VulnerableVersion { get; init; }
///
/// Patched version string.
///
public string? PatchedVersion { get; init; }
///
/// Distro and release this build was done for.
///
public string? DistroRelease { get; init; }
///
/// Builder image used for reproducible builds.
///
public string? BuilderImage { get; init; }
///
/// Timestamp of the vulnerable build.
///
public DateTimeOffset? VulnerableBuildTimestamp { get; init; }
///
/// Timestamp of the patched build.
///
public DateTimeOffset? PatchedBuildTimestamp { get; init; }
///
/// Diff statistics summary.
///
public DiffStatistics? DiffStatistics { get; init; }
}
///
/// Repository for managing fingerprint claims.
///
public interface IFingerprintClaimRepository
{
///
/// Creates a new fingerprint claim.
///
/// The claim to create.
/// Cancellation token.
/// The created claim ID.
Task CreateClaimAsync(FingerprintClaim claim, CancellationToken ct = default);
///
/// Creates multiple claims in a batch.
///
/// Claims to create.
/// Cancellation token.
Task CreateClaimsBatchAsync(IEnumerable claims, CancellationToken ct = default);
///
/// Gets a claim by ID.
///
/// Claim ID.
/// Cancellation token.
/// The claim if found.
Task GetClaimByIdAsync(Guid id, CancellationToken ct = default);
///
/// Gets all claims for a specific fingerprint.
///
/// Fingerprint ID.
/// Cancellation token.
/// List of claims for the fingerprint.
Task> GetClaimsByFingerprintAsync(
Guid fingerprintId,
CancellationToken ct = default);
///
/// Gets all claims for a specific fingerprint hash.
///
/// Fingerprint hash (hex-encoded).
/// Cancellation token.
/// List of claims for the fingerprint.
Task> GetClaimsByFingerprintHashAsync(
string fingerprintHash,
CancellationToken ct = default);
///
/// Gets all claims for a specific CVE.
///
/// CVE identifier.
/// Cancellation token.
/// List of claims for the CVE.
Task> GetClaimsByCveAsync(
string cveId,
CancellationToken ct = default);
///
/// Gets claims with a specific verdict.
///
/// Verdict to filter by.
/// Maximum results to return.
/// Cancellation token.
/// List of claims with the verdict.
Task> GetClaimsByVerdictAsync(
ClaimVerdict verdict,
int limit = 100,
CancellationToken ct = default);
///
/// Updates an existing claim.
///
/// The updated claim.
/// Cancellation token.
Task UpdateClaimAsync(FingerprintClaim claim, CancellationToken ct = default);
///
/// Deletes a claim by ID.
///
/// Claim ID.
/// Cancellation token.
/// True if deleted, false if not found.
Task DeleteClaimAsync(Guid id, CancellationToken ct = default);
///
/// Checks if a claim already exists for a fingerprint+CVE combination.
///
/// Fingerprint ID.
/// CVE identifier.
/// Cancellation token.
/// True if a claim exists.
Task ClaimExistsAsync(Guid fingerprintId, string cveId, CancellationToken ct = default);
}
///
/// Repository for managing function fingerprints (per-binary breakdown).
///
public interface IFunctionFingerprintRepository
{
///
/// Stores function fingerprints for a binary.
///
/// Parent binary fingerprint ID.
/// Function fingerprints to store.
/// Cancellation token.
Task StoreFunctionsAsync(
Guid binaryFingerprintId,
IEnumerable functions,
CancellationToken ct = default);
///
/// Gets all function fingerprints for a binary.
///
/// Parent binary fingerprint ID.
/// Cancellation token.
/// List of function fingerprints.
Task> GetFunctionsByBinaryAsync(
Guid binaryFingerprintId,
CancellationToken ct = default);
///
/// Searches for functions by name pattern.
///
/// Function name pattern (SQL LIKE).
/// Maximum results.
/// Cancellation token.
/// Matching functions with their binary IDs.
Task> SearchFunctionsByNameAsync(
string namePattern,
int limit = 100,
CancellationToken ct = default);
///
/// Finds functions matching a specific basic block hash.
///
/// Hash to search for.
/// Cancellation token.
/// Matching functions with their binary IDs.
Task> FindByBasicBlockHashAsync(
byte[] basicBlockHash,
CancellationToken ct = default);
///
/// Deletes all function fingerprints for a binary.
///
/// Parent binary fingerprint ID.
/// Cancellation token.
Task DeleteFunctionsByBinaryAsync(Guid binaryFingerprintId, CancellationToken ct = default);
}