Implement VEX document verification system with issuer management and signature verification
- Added IIssuerDirectory interface for managing VEX document issuers, including methods for registration, revocation, and trust validation. - Created InMemoryIssuerDirectory class as an in-memory implementation of IIssuerDirectory for testing and single-instance deployments. - Introduced ISignatureVerifier interface for verifying signatures on VEX documents, with support for multiple signature formats. - Developed SignatureVerifier class as the default implementation of ISignatureVerifier, allowing extensibility for different signature formats. - Implemented handlers for DSSE and JWS signature formats, including methods for verification and signature extraction. - Defined various records and enums for issuer and signature metadata, enhancing the structure and clarity of the verification process.
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace StellaOps.Policy.Engine.Attestation;
|
||||
|
||||
/// <summary>
|
||||
/// In-memory implementation of verification policy store per CONTRACT-VERIFICATION-POLICY-006.
|
||||
/// </summary>
|
||||
internal sealed class InMemoryVerificationPolicyStore : IVerificationPolicyStore
|
||||
{
|
||||
private readonly ConcurrentDictionary<string, VerificationPolicy> _policies = new(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
public Task<VerificationPolicy?> GetAsync(string policyId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(policyId);
|
||||
|
||||
_policies.TryGetValue(policyId, out var policy);
|
||||
return Task.FromResult(policy);
|
||||
}
|
||||
|
||||
public Task<IReadOnlyList<VerificationPolicy>> ListAsync(
|
||||
string? tenantScope = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
IEnumerable<VerificationPolicy> policies = _policies.Values;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(tenantScope))
|
||||
{
|
||||
policies = policies.Where(p =>
|
||||
p.TenantScope == "*" ||
|
||||
p.TenantScope.Equals(tenantScope, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
var result = policies
|
||||
.OrderBy(p => p.PolicyId)
|
||||
.ToList() as IReadOnlyList<VerificationPolicy>;
|
||||
|
||||
return Task.FromResult(result);
|
||||
}
|
||||
|
||||
public Task<VerificationPolicy> CreateAsync(
|
||||
VerificationPolicy policy,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(policy);
|
||||
|
||||
if (!_policies.TryAdd(policy.PolicyId, policy))
|
||||
{
|
||||
throw new InvalidOperationException($"Policy '{policy.PolicyId}' already exists.");
|
||||
}
|
||||
|
||||
return Task.FromResult(policy);
|
||||
}
|
||||
|
||||
public Task<VerificationPolicy?> UpdateAsync(
|
||||
string policyId,
|
||||
Func<VerificationPolicy, VerificationPolicy> update,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(policyId);
|
||||
ArgumentNullException.ThrowIfNull(update);
|
||||
|
||||
if (!_policies.TryGetValue(policyId, out var existing))
|
||||
{
|
||||
return Task.FromResult<VerificationPolicy?>(null);
|
||||
}
|
||||
|
||||
var updated = update(existing);
|
||||
_policies[policyId] = updated;
|
||||
|
||||
return Task.FromResult<VerificationPolicy?>(updated);
|
||||
}
|
||||
|
||||
public Task<bool> DeleteAsync(string policyId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(policyId);
|
||||
|
||||
return Task.FromResult(_policies.TryRemove(policyId, out _));
|
||||
}
|
||||
|
||||
public Task<bool> ExistsAsync(string policyId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(policyId);
|
||||
|
||||
return Task.FromResult(_policies.ContainsKey(policyId));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user