< Summary

Information
Class: AsiBackbone.Core.Signing.GovernanceArtifactVerifier
Assembly: AsiBackbone.Core
File(s): /home/runner/work/AsiBackbone/AsiBackbone/src/AsiBackbone.Core/Signing/GovernanceArtifactVerifier.cs
Line coverage
100%
Covered lines: 80
Uncovered lines: 0
Coverable lines: 80
Total lines: 139
Line coverage: 100%
Branch coverage
86%
Covered branches: 45
Total branches: 52
Branch coverage: 86.5%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
VerifyAsync()100%66100%
CreateProviderUnavailableOutcome(...)100%11100%
ValidateBeforeProvider(...)87.5%4040100%
MatchesCanonicalMetadata(...)50%22100%
MatchesOptionalPolicyMetadata(...)75%44100%

File(s)

/home/runner/work/AsiBackbone/AsiBackbone/src/AsiBackbone.Core/Signing/GovernanceArtifactVerifier.cs

#LineLine coverage
 1namespace AsiBackbone.Core.Signing;
 2
 3/// <summary>
 4/// Provides provider-neutral helpers for verifying signed governance artifacts and applying verification policy.
 5/// </summary>
 6/// <remarks>
 7/// The verifier wrapper does not resolve provider-specific keys in Core and does not imply legal evidence, compliance c
 8/// </remarks>
 9public static class GovernanceArtifactVerifier
 10{
 11    /// <summary>
 12    /// Verifies a signed governance artifact and maps the result to a host-facing policy outcome.
 13    /// </summary>
 14    public static async ValueTask<VerificationPolicyOutcome> VerifyAsync<TArtifact>(
 15        SignedGovernanceArtifact<TArtifact> artifact,
 16        IAsiBackboneSignatureVerificationService verificationService,
 17        VerificationPolicyOptions? options = null,
 18        VerificationPolicyContext? context = null,
 19        CancellationToken cancellationToken = default)
 20    {
 3221        ArgumentNullException.ThrowIfNull(artifact);
 3222        ArgumentNullException.ThrowIfNull(verificationService);
 3223        cancellationToken.ThrowIfCancellationRequested();
 24
 3225        VerificationPolicyContext effectiveContext = context ?? VerificationPolicyContext.Default;
 3226        SignatureVerificationResult? preflightResult = ValidateBeforeProvider(artifact, effectiveContext);
 27
 3228        if (preflightResult is not null)
 29        {
 1530            return VerificationPolicyEvaluator.Evaluate(artifact, preflightResult, options);
 31        }
 32
 33        try
 34        {
 1735            SignatureVerificationResult verificationResult = await verificationService
 1736                .VerifyAsync(
 1737                    new SignatureVerificationRequest(
 1738                        artifact.SigningHash,
 1739                        artifact.SigningMetadata,
 1740                        purpose: effectiveContext.Purpose ?? artifact.ArtifactType,
 1741                        metadata: effectiveContext.Metadata),
 1742                    cancellationToken)
 1743                .ConfigureAwait(false);
 44
 1345            return VerificationPolicyEvaluator.Evaluate(artifact, verificationResult, options);
 46        }
 247        catch (InvalidOperationException exception)
 48        {
 249            return CreateProviderUnavailableOutcome(artifact, options, exception);
 50        }
 151        catch (NotSupportedException exception)
 52        {
 153            return CreateProviderUnavailableOutcome(artifact, options, exception);
 54        }
 155        catch (TimeoutException exception)
 56        {
 157            return CreateProviderUnavailableOutcome(artifact, options, exception);
 58        }
 3259    }
 60
 61    private static VerificationPolicyOutcome CreateProviderUnavailableOutcome<TArtifact>(
 62        SignedGovernanceArtifact<TArtifact> artifact,
 63        VerificationPolicyOptions? options,
 64        Exception exception)
 65    {
 466        var providerUnavailableResult = SignatureVerificationResult.Failed(
 467            "signature.provider-unavailable",
 468            exception.GetType().Name);
 69
 470        return VerificationPolicyEvaluator.Evaluate(artifact, providerUnavailableResult, options);
 71    }
 72
 73    private static SignatureVerificationResult? ValidateBeforeProvider<TArtifact>(
 74        SignedGovernanceArtifact<TArtifact> artifact,
 75        VerificationPolicyContext context)
 76    {
 3277        SigningMetadata metadata = artifact.SigningMetadata;
 78
 3279        return artifact.HasNoSignature || !metadata.HasSignature
 3280            ? SignatureVerificationResult.MissingSignature("The governance artifact does not carry signature metadata.")
 3281            : string.IsNullOrWhiteSpace(metadata.SigningHash)
 3282            ? SignatureVerificationResult.MissingSignature("The governance artifact does not carry the hash that was sig
 3283            : !string.Equals(metadata.SigningHash, artifact.SigningHash, StringComparison.Ordinal)
 3284            ? SignatureVerificationResult.Failed(
 3285                "signature.hash-mismatch",
 3286                "The signing metadata hash does not match the canonical artifact hash.")
 3287            : metadata.HashAlgorithm is not null
 3288            && !string.Equals(metadata.HashAlgorithm, artifact.HashAlgorithm, StringComparison.OrdinalIgnoreCase)
 3289            ? SignatureVerificationResult.Failed(
 3290                "signature.hash-algorithm-unsupported",
 3291                "The signing metadata hash algorithm does not match the canonical artifact hash algorithm.")
 3292            : context.RequiredHashAlgorithm is not null
 3293            && !string.Equals(context.RequiredHashAlgorithm, artifact.HashAlgorithm, StringComparison.OrdinalIgnoreCase)
 3294            ? SignatureVerificationResult.Failed(
 3295                "signature.hash-algorithm-unsupported",
 3296                "The canonical artifact hash algorithm does not match the required verification policy algorithm.")
 3297            : !MatchesCanonicalMetadata(metadata, "artifact_id", artifact.ArtifactId)
 3298            || !MatchesCanonicalMetadata(metadata, "artifact_type", artifact.ArtifactType)
 3299            || !MatchesCanonicalMetadata(metadata, "canonicalization_version", artifact.CanonicalHash.CanonicalizationVe
 32100            || !MatchesCanonicalMetadata(metadata, "payload_schema_version", artifact.CanonicalHash.PayloadSchemaVersion
 32101            ? SignatureVerificationResult.Failed(
 32102                "signature.canonicalization-mismatch",
 32103                "The signing metadata canonical artifact descriptors do not match the artifact being verified.")
 32104            : context.ExpectedKeyId is not null
 32105            && !string.Equals(context.ExpectedKeyId, metadata.KeyId, StringComparison.Ordinal)
 32106            ? SignatureVerificationResult.Failed(
 32107                "signature.key-version-unknown",
 32108                "The signing key identifier does not match the verification policy expectation.")
 32109            : context.ExpectedKeyVersion is not null
 32110            && !string.Equals(context.ExpectedKeyVersion, metadata.KeyVersion, StringComparison.Ordinal)
 32111            ? SignatureVerificationResult.Failed(
 32112                "signature.key-version-unknown",
 32113                "The signing key version does not match the verification policy expectation.")
 32114            : context.RequiredProvider is not null
 32115            && !string.Equals(context.RequiredProvider, metadata.Provider, StringComparison.Ordinal)
 32116            ? SignatureVerificationResult.Failed(
 32117                "signature.provider-unavailable",
 32118                "The signing provider does not match the required verification policy provider.")
 32119            : !MatchesOptionalPolicyMetadata(metadata, "policy_version", context.ExpectedPolicyVersion)
 32120            || !MatchesOptionalPolicyMetadata(metadata, "policy_hash", context.ExpectedPolicyHash)
 32121            ? SignatureVerificationResult.Failed(
 32122                "signature.canonicalization-mismatch",
 32123                "The signing metadata policy context does not match the verification policy expectation.")
 32124            : null;
 125    }
 126
 127    private static bool MatchesCanonicalMetadata(SigningMetadata metadata, string key, string expectedValue)
 128    {
 98129        return !metadata.Metadata.TryGetValue(key, out string? value)
 98130            || string.Equals(value, expectedValue, StringComparison.Ordinal);
 131    }
 132
 133    private static bool MatchesOptionalPolicyMetadata(SigningMetadata metadata, string key, string? expectedValue)
 134    {
 37135        return expectedValue is null
 37136            || (metadata.Metadata.TryGetValue(key, out string? value)
 37137                && string.Equals(value, expectedValue, StringComparison.Ordinal));
 138    }
 139}