< 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
94%
Covered branches: 49
Total branches: 52
Branch coverage: 94.2%
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(...)97.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    {
 7221        ArgumentNullException.ThrowIfNull(artifact);
 7222        ArgumentNullException.ThrowIfNull(verificationService);
 7223        cancellationToken.ThrowIfCancellationRequested();
 24
 7225        VerificationPolicyContext effectiveContext = context ?? VerificationPolicyContext.Default;
 7226        SignatureVerificationResult? preflightResult = ValidateBeforeProvider(artifact, effectiveContext);
 27
 7228        if (preflightResult is not null)
 29        {
 3430            return VerificationPolicyEvaluator.Evaluate(artifact, preflightResult, options);
 31        }
 32
 33        try
 34        {
 3835            SignatureVerificationResult verificationResult = await verificationService
 3836                .VerifyAsync(
 3837                    new SignatureVerificationRequest(
 3838                        artifact.SigningHash,
 3839                        artifact.SigningMetadata,
 3840                        purpose: effectiveContext.Purpose ?? artifact.ArtifactType,
 3841                        metadata: effectiveContext.Metadata),
 3842                    cancellationToken)
 3843                .ConfigureAwait(false);
 44
 3045            return VerificationPolicyEvaluator.Evaluate(artifact, verificationResult, options);
 46        }
 447        catch (InvalidOperationException exception)
 48        {
 449            return CreateProviderUnavailableOutcome(artifact, options, exception);
 50        }
 251        catch (NotSupportedException exception)
 52        {
 253            return CreateProviderUnavailableOutcome(artifact, options, exception);
 54        }
 255        catch (TimeoutException exception)
 56        {
 257            return CreateProviderUnavailableOutcome(artifact, options, exception);
 58        }
 7259    }
 60
 61    private static VerificationPolicyOutcome CreateProviderUnavailableOutcome<TArtifact>(
 62        SignedGovernanceArtifact<TArtifact> artifact,
 63        VerificationPolicyOptions? options,
 64        Exception exception)
 65    {
 866        var providerUnavailableResult = SignatureVerificationResult.Failed(
 867            "signature.provider-unavailable",
 868            exception.GetType().Name);
 69
 870        return VerificationPolicyEvaluator.Evaluate(artifact, providerUnavailableResult, options);
 71    }
 72
 73    private static SignatureVerificationResult? ValidateBeforeProvider<TArtifact>(
 74        SignedGovernanceArtifact<TArtifact> artifact,
 75        VerificationPolicyContext context)
 76    {
 7277        SigningMetadata metadata = artifact.SigningMetadata;
 78
 7279        return artifact.HasNoSignature || !metadata.HasSignature
 7280            ? SignatureVerificationResult.MissingSignature("The governance artifact does not carry signature metadata.")
 7281            : string.IsNullOrWhiteSpace(metadata.SigningHash)
 7282            ? SignatureVerificationResult.MissingSignature("The governance artifact does not carry the hash that was sig
 7283            : !string.Equals(metadata.SigningHash, artifact.SigningHash, StringComparison.Ordinal)
 7284            ? SignatureVerificationResult.Failed(
 7285                "signature.hash-mismatch",
 7286                "The signing metadata hash does not match the canonical artifact hash.")
 7287            : metadata.HashAlgorithm is not null
 7288            && !string.Equals(metadata.HashAlgorithm, artifact.HashAlgorithm, StringComparison.OrdinalIgnoreCase)
 7289            ? SignatureVerificationResult.Failed(
 7290                "signature.hash-algorithm-unsupported",
 7291                "The signing metadata hash algorithm does not match the canonical artifact hash algorithm.")
 7292            : context.RequiredHashAlgorithm is not null
 7293            && !string.Equals(context.RequiredHashAlgorithm, artifact.HashAlgorithm, StringComparison.OrdinalIgnoreCase)
 7294            ? SignatureVerificationResult.Failed(
 7295                "signature.hash-algorithm-unsupported",
 7296                "The canonical artifact hash algorithm does not match the required verification policy algorithm.")
 7297            : !MatchesCanonicalMetadata(metadata, "artifact_id", artifact.ArtifactId)
 7298            || !MatchesCanonicalMetadata(metadata, "artifact_type", artifact.ArtifactType)
 7299            || !MatchesCanonicalMetadata(metadata, "canonicalization_version", artifact.CanonicalHash.CanonicalizationVe
 72100            || !MatchesCanonicalMetadata(metadata, "payload_schema_version", artifact.CanonicalHash.PayloadSchemaVersion
 72101            ? SignatureVerificationResult.Failed(
 72102                "signature.canonicalization-mismatch",
 72103                "The signing metadata canonical artifact descriptors do not match the artifact being verified.")
 72104            : context.ExpectedKeyId is not null
 72105            && !string.Equals(context.ExpectedKeyId, metadata.KeyId, StringComparison.Ordinal)
 72106            ? SignatureVerificationResult.Failed(
 72107                "signature.key-version-unknown",
 72108                "The signing key identifier does not match the verification policy expectation.")
 72109            : context.ExpectedKeyVersion is not null
 72110            && !string.Equals(context.ExpectedKeyVersion, metadata.KeyVersion, StringComparison.Ordinal)
 72111            ? SignatureVerificationResult.Failed(
 72112                "signature.key-version-unknown",
 72113                "The signing key version does not match the verification policy expectation.")
 72114            : context.RequiredProvider is not null
 72115            && !string.Equals(context.RequiredProvider, metadata.Provider, StringComparison.Ordinal)
 72116            ? SignatureVerificationResult.Failed(
 72117                "signature.provider-unavailable",
 72118                "The signing provider does not match the required verification policy provider.")
 72119            : !MatchesOptionalPolicyMetadata(metadata, "policy_version", context.ExpectedPolicyVersion)
 72120            || !MatchesOptionalPolicyMetadata(metadata, "policy_hash", context.ExpectedPolicyHash)
 72121            ? SignatureVerificationResult.Failed(
 72122                "signature.canonicalization-mismatch",
 72123                "The signing metadata policy context does not match the verification policy expectation.")
 72124            : null;
 125    }
 126
 127    private static bool MatchesCanonicalMetadata(SigningMetadata metadata, string key, string expectedValue)
 128    {
 228129        return !metadata.Metadata.TryGetValue(key, out string? value)
 228130            || string.Equals(value, expectedValue, StringComparison.Ordinal);
 131    }
 132
 133    private static bool MatchesOptionalPolicyMetadata(SigningMetadata metadata, string key, string? expectedValue)
 134    {
 82135        return expectedValue is null
 82136            || (metadata.Metadata.TryGetValue(key, out string? value)
 82137                && string.Equals(value, expectedValue, StringComparison.Ordinal));
 138    }
 139}