44 lines
1.3 KiB
C#
44 lines
1.3 KiB
C#
using System.Security.Cryptography;
|
|
|
|
namespace StellaOps.Scanner.Evidence;
|
|
|
|
/// <summary>
|
|
/// Creates deterministic idempotency keys for DSSE attestation payloads.
|
|
/// </summary>
|
|
public static class AttestationIdempotencyKey
|
|
{
|
|
/// <summary>
|
|
/// Computes a stable SHA-256 idempotency key for a DSSE envelope.
|
|
/// </summary>
|
|
public static string FromDsseEnvelope(ReadOnlySpan<byte> dsseEnvelopeBytes)
|
|
{
|
|
if (dsseEnvelopeBytes.IsEmpty)
|
|
{
|
|
throw new ArgumentException("DSSE envelope bytes cannot be empty.", nameof(dsseEnvelopeBytes));
|
|
}
|
|
|
|
var hash = SHA256.HashData(dsseEnvelopeBytes);
|
|
return $"sha256:{Convert.ToHexStringLower(hash)}";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts an idempotency key into a stable OCI-safe tag.
|
|
/// </summary>
|
|
public static string ToOciTag(string idempotencyKey, string prefix = "verdict")
|
|
{
|
|
ArgumentException.ThrowIfNullOrWhiteSpace(idempotencyKey);
|
|
|
|
var normalized = idempotencyKey.StartsWith("sha256:", StringComparison.OrdinalIgnoreCase)
|
|
? idempotencyKey[7..]
|
|
: idempotencyKey;
|
|
|
|
var compact = normalized.Trim().ToLowerInvariant();
|
|
if (compact.Length > 48)
|
|
{
|
|
compact = compact[..48];
|
|
}
|
|
|
|
return $"{prefix}-{compact}";
|
|
}
|
|
}
|