99 lines
3.2 KiB
C#
99 lines
3.2 KiB
C#
// Licensed to StellaOps under the BUSL-1.1 license.
|
|
|
|
using System.Collections.Immutable;
|
|
using StellaOps.ReachGraph.Schema;
|
|
|
|
namespace StellaOps.ReachGraph.Signing;
|
|
|
|
/// <summary>
|
|
/// Service for signing and verifying reachability graphs using DSSE envelopes.
|
|
/// </summary>
|
|
public interface IReachGraphSignerService
|
|
{
|
|
/// <summary>
|
|
/// Sign a reachability graph using DSSE envelope format.
|
|
/// </summary>
|
|
/// <param name="graph">The graph to sign.</param>
|
|
/// <param name="keyId">The key identifier to use for signing.</param>
|
|
/// <param name="cancellationToken">Cancellation token.</param>
|
|
/// <returns>The graph with signature attached.</returns>
|
|
Task<ReachGraphMinimal> SignAsync(
|
|
ReachGraphMinimal graph,
|
|
string keyId,
|
|
CancellationToken cancellationToken = default);
|
|
|
|
/// <summary>
|
|
/// Verify signatures on a reachability graph.
|
|
/// </summary>
|
|
/// <param name="graph">The graph to verify.</param>
|
|
/// <param name="cancellationToken">Cancellation token.</param>
|
|
/// <returns>Verification result with valid/invalid key IDs.</returns>
|
|
Task<ReachGraphVerificationResult> VerifyAsync(
|
|
ReachGraphMinimal graph,
|
|
CancellationToken cancellationToken = default);
|
|
|
|
/// <summary>
|
|
/// Create a DSSE envelope for a reachability graph.
|
|
/// </summary>
|
|
/// <param name="graph">The graph to envelope.</param>
|
|
/// <param name="keyId">The key identifier to use for signing.</param>
|
|
/// <param name="cancellationToken">Cancellation token.</param>
|
|
/// <returns>Serialized DSSE envelope bytes.</returns>
|
|
Task<byte[]> CreateDsseEnvelopeAsync(
|
|
ReachGraphMinimal graph,
|
|
string keyId,
|
|
CancellationToken cancellationToken = default);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Result of reachability graph signature verification.
|
|
/// </summary>
|
|
public sealed record ReachGraphVerificationResult
|
|
{
|
|
/// <summary>
|
|
/// Gets whether all signatures are valid.
|
|
/// </summary>
|
|
public required bool IsValid { get; init; }
|
|
|
|
/// <summary>
|
|
/// Gets the key IDs with valid signatures.
|
|
/// </summary>
|
|
public required ImmutableArray<string> ValidKeyIds { get; init; }
|
|
|
|
/// <summary>
|
|
/// Gets the key IDs with invalid signatures.
|
|
/// </summary>
|
|
public required ImmutableArray<string> InvalidKeyIds { get; init; }
|
|
|
|
/// <summary>
|
|
/// Gets the error message if verification failed.
|
|
/// </summary>
|
|
public string? Error { get; init; }
|
|
|
|
/// <summary>
|
|
/// Creates a successful verification result.
|
|
/// </summary>
|
|
public static ReachGraphVerificationResult Success(ImmutableArray<string> validKeyIds) =>
|
|
new()
|
|
{
|
|
IsValid = true,
|
|
ValidKeyIds = validKeyIds,
|
|
InvalidKeyIds = []
|
|
};
|
|
|
|
/// <summary>
|
|
/// Creates a failed verification result.
|
|
/// </summary>
|
|
public static ReachGraphVerificationResult Failure(
|
|
ImmutableArray<string> validKeyIds,
|
|
ImmutableArray<string> invalidKeyIds,
|
|
string? error = null) =>
|
|
new()
|
|
{
|
|
IsValid = false,
|
|
ValidKeyIds = validKeyIds,
|
|
InvalidKeyIds = invalidKeyIds,
|
|
Error = error
|
|
};
|
|
}
|