feat: Implement Wine CSP HTTP provider for GOST cryptographic operations
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
Scanner Analyzers / Discover Analyzers (push) Has been cancelled
Scanner Analyzers / Build 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

- Added WineCspHttpProvider class to interface with Wine-hosted CryptoPro CSP.
- Implemented ICryptoProvider, ICryptoProviderDiagnostics, and IDisposable interfaces.
- Introduced WineCspHttpSigner and WineCspHttpHasher for signing and hashing operations.
- Created WineCspProviderOptions for configuration settings including service URL and key options.
- Developed CryptoProGostSigningService to handle GOST signing operations and key management.
- Implemented HTTP service for the Wine CSP with endpoints for signing, verification, and hashing.
- Added Swagger documentation for API endpoints.
- Included health checks and error handling for service availability.
- Established DTOs for request and response models in the service.
This commit is contained in:
StellaOps Bot
2025-12-07 14:02:42 +02:00
parent 965cbf9574
commit bd2529502e
56 changed files with 9438 additions and 699 deletions

View File

@@ -0,0 +1,343 @@
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using MongoDB.Bson.Serialization.Attributes;
namespace StellaOps.Signals.Models;
/// <summary>
/// AOC (Aggregation-Only Contract) provenance feed for runtime facts ingestion (SGSI0101).
/// Conforms to docs/schemas/provenance-feed.schema.json.
/// </summary>
public sealed class ProvenanceFeed
{
public const int CurrentSchemaVersion = 1;
[BsonElement("schemaVersion")]
[JsonPropertyName("schemaVersion")]
public int SchemaVersion { get; init; } = CurrentSchemaVersion;
[BsonElement("feedId")]
[JsonPropertyName("feedId")]
public string FeedId { get; init; } = Guid.NewGuid().ToString("D");
[BsonElement("feedType")]
[JsonPropertyName("feedType")]
public ProvenanceFeedType FeedType { get; init; } = ProvenanceFeedType.RuntimeFacts;
[BsonElement("generatedAt")]
[JsonPropertyName("generatedAt")]
public DateTimeOffset GeneratedAt { get; init; } = DateTimeOffset.UtcNow;
[BsonElement("sourceService")]
[BsonIgnoreIfNull]
[JsonPropertyName("sourceService")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? SourceService { get; init; }
[BsonElement("tenantId")]
[BsonIgnoreIfNull]
[JsonPropertyName("tenantId")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? TenantId { get; init; }
[BsonElement("correlationId")]
[BsonIgnoreIfNull]
[JsonPropertyName("correlationId")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? CorrelationId { get; init; }
[BsonElement("records")]
[JsonPropertyName("records")]
public List<ProvenanceRecord> Records { get; init; } = new();
[BsonElement("metadata")]
[BsonIgnoreIfNull]
[JsonPropertyName("metadata")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public Dictionary<string, string?>? Metadata { get; init; }
[BsonElement("attestation")]
[BsonIgnoreIfNull]
[JsonPropertyName("attestation")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public FeedAttestation? Attestation { get; init; }
}
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum ProvenanceFeedType
{
[JsonPropertyName("RUNTIME_FACTS")]
RuntimeFacts,
[JsonPropertyName("SIGNAL_ENRICHMENT")]
SignalEnrichment,
[JsonPropertyName("CAS_PROMOTION")]
CasPromotion,
[JsonPropertyName("SCORING_OUTPUT")]
ScoringOutput,
[JsonPropertyName("AUTHORITY_SCOPES")]
AuthorityScopes
}
/// <summary>
/// Individual provenance record within a feed.
/// </summary>
public sealed class ProvenanceRecord
{
[BsonElement("recordId")]
[JsonPropertyName("recordId")]
public string RecordId { get; init; } = Guid.NewGuid().ToString("D");
[BsonElement("recordType")]
[JsonPropertyName("recordType")]
public string RecordType { get; init; } = string.Empty;
[BsonElement("subject")]
[JsonPropertyName("subject")]
public ProvenanceSubject Subject { get; init; } = new();
[BsonElement("occurredAt")]
[JsonPropertyName("occurredAt")]
public DateTimeOffset OccurredAt { get; init; }
[BsonElement("observedBy")]
[BsonIgnoreIfNull]
[JsonPropertyName("observedBy")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? ObservedBy { get; init; }
[BsonElement("confidence")]
[BsonIgnoreIfNull]
[JsonPropertyName("confidence")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public double? Confidence { get; init; }
[BsonElement("facts")]
[BsonIgnoreIfNull]
[JsonPropertyName("facts")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public RuntimeProvenanceFacts? Facts { get; init; }
[BsonElement("evidence")]
[BsonIgnoreIfNull]
[JsonPropertyName("evidence")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public RecordEvidence? Evidence { get; init; }
}
/// <summary>
/// Subject of a provenance record.
/// </summary>
public sealed class ProvenanceSubject
{
[BsonElement("type")]
[JsonPropertyName("type")]
public ProvenanceSubjectType Type { get; init; } = ProvenanceSubjectType.Package;
[BsonElement("identifier")]
[JsonPropertyName("identifier")]
public string Identifier { get; init; } = string.Empty;
[BsonElement("digest")]
[BsonIgnoreIfNull]
[JsonPropertyName("digest")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? Digest { get; init; }
[BsonElement("namespace")]
[BsonIgnoreIfNull]
[JsonPropertyName("namespace")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? Namespace { get; init; }
}
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum ProvenanceSubjectType
{
[JsonPropertyName("CONTAINER")]
Container,
[JsonPropertyName("PROCESS")]
Process,
[JsonPropertyName("PACKAGE")]
Package,
[JsonPropertyName("FILE")]
File,
[JsonPropertyName("NETWORK")]
Network,
[JsonPropertyName("IMAGE")]
Image
}
/// <summary>
/// Runtime-specific provenance facts.
/// </summary>
public sealed class RuntimeProvenanceFacts
{
[BsonElement("symbolId")]
[BsonIgnoreIfNull]
[JsonPropertyName("symbolId")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? SymbolId { get; init; }
[BsonElement("processName")]
[BsonIgnoreIfNull]
[JsonPropertyName("processName")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? ProcessName { get; init; }
[BsonElement("processId")]
[BsonIgnoreIfNull]
[JsonPropertyName("processId")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public int? ProcessId { get; init; }
[BsonElement("socketAddress")]
[BsonIgnoreIfNull]
[JsonPropertyName("socketAddress")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? SocketAddress { get; init; }
[BsonElement("containerId")]
[BsonIgnoreIfNull]
[JsonPropertyName("containerId")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? ContainerId { get; init; }
[BsonElement("hitCount")]
[JsonPropertyName("hitCount")]
public int HitCount { get; init; }
[BsonElement("purl")]
[BsonIgnoreIfNull]
[JsonPropertyName("purl")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? Purl { get; init; }
[BsonElement("codeId")]
[BsonIgnoreIfNull]
[JsonPropertyName("codeId")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? CodeId { get; init; }
[BsonElement("buildId")]
[BsonIgnoreIfNull]
[JsonPropertyName("buildId")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? BuildId { get; init; }
[BsonElement("loaderBase")]
[BsonIgnoreIfNull]
[JsonPropertyName("loaderBase")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? LoaderBase { get; init; }
[BsonElement("metadata")]
[BsonIgnoreIfNull]
[JsonPropertyName("metadata")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public Dictionary<string, string?>? Metadata { get; init; }
}
/// <summary>
/// Evidence supporting a provenance record.
/// </summary>
public sealed class RecordEvidence
{
[BsonElement("sourceDigest")]
[BsonIgnoreIfNull]
[JsonPropertyName("sourceDigest")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? SourceDigest { get; init; }
[BsonElement("captureMethod")]
[BsonIgnoreIfNull]
[JsonPropertyName("captureMethod")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public EvidenceCaptureMethod? CaptureMethod { get; init; }
[BsonElement("rawDataRef")]
[BsonIgnoreIfNull]
[JsonPropertyName("rawDataRef")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? RawDataRef { get; init; }
}
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum EvidenceCaptureMethod
{
[JsonPropertyName("eBPF")]
EBpf,
[JsonPropertyName("PROC_SCAN")]
ProcScan,
[JsonPropertyName("API_CALL")]
ApiCall,
[JsonPropertyName("LOG_ANALYSIS")]
LogAnalysis,
[JsonPropertyName("STATIC_ANALYSIS")]
StaticAnalysis
}
/// <summary>
/// Attestation metadata for a provenance feed.
/// </summary>
public sealed class FeedAttestation
{
[BsonElement("predicateType")]
[JsonPropertyName("predicateType")]
public string PredicateType { get; init; } = "https://stella.ops/attestation/provenance-feed/v1";
[BsonElement("signedAt")]
[JsonPropertyName("signedAt")]
public DateTimeOffset SignedAt { get; init; }
[BsonElement("keyId")]
[BsonIgnoreIfNull]
[JsonPropertyName("keyId")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? KeyId { get; init; }
[BsonElement("envelopeDigest")]
[BsonIgnoreIfNull]
[JsonPropertyName("envelopeDigest")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? EnvelopeDigest { get; init; }
[BsonElement("transparencyLog")]
[BsonIgnoreIfNull]
[JsonPropertyName("transparencyLog")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? TransparencyLog { get; init; }
}
/// <summary>
/// Context facts container stored on ReachabilityFactDocument.
/// </summary>
public sealed class ContextFacts
{
[BsonElement("provenance")]
[BsonIgnoreIfNull]
[JsonPropertyName("provenance")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public ProvenanceFeed? Provenance { get; set; }
[BsonElement("lastUpdatedAt")]
[JsonPropertyName("lastUpdatedAt")]
public DateTimeOffset LastUpdatedAt { get; set; }
[BsonElement("recordCount")]
[JsonPropertyName("recordCount")]
public int RecordCount { get; set; }
}

View File

@@ -31,6 +31,10 @@ public sealed class ReachabilityFactDocument
[BsonIgnoreIfNull]
public Dictionary<string, string?>? Metadata { get; set; }
[BsonElement("contextFacts")]
[BsonIgnoreIfNull]
public ContextFacts? ContextFacts { get; set; }
[BsonElement("score")]
public double Score { get; set; }