< Summary

Information
Class: AsiBackbone.Core.Signing.VerificationPolicyEvaluator
Assembly: AsiBackbone.Core
File(s): /home/runner/work/AsiBackbone/AsiBackbone/src/AsiBackbone.Core/Signing/VerificationPolicyEvaluator.cs
Line coverage
100%
Covered lines: 48
Uncovered lines: 0
Coverable lines: 48
Total lines: 117
Line coverage: 100%
Branch coverage
95%
Covered branches: 21
Total branches: 22
Branch coverage: 95.4%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%11100%
Evaluate(...)100%11100%
Categorize(...)91.67%1212100%
Matches(...)100%11100%
IsMatch(...)100%1010100%

File(s)

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

#LineLine coverage
 1namespace AsiBackbone.Core.Signing;
 2
 3/// <summary>
 4/// Evaluates provider-neutral signature verification results against host verification policy.
 5/// </summary>
 6public static class VerificationPolicyEvaluator
 7{
 18    private static readonly CategoryRule[] FailureCodeCategoryRules =
 19    [
 110        new(SignatureVerificationCategory.MissingSignature, ["missing"]),
 111        new(SignatureVerificationCategory.HashMismatch, ["hash"]),
 112        new(SignatureVerificationCategory.CanonicalizationMismatch, ["canonicalization", "payload-schema", "artifact"]),
 113        new(SignatureVerificationCategory.UnsupportedAlgorithm, ["unsupported", "algorithm"]),
 114        new(SignatureVerificationCategory.RevokedKey, ["revoked", "disabled"]),
 115        new(SignatureVerificationCategory.UntrustedKey, ["key-not-trusted", "key.mismatch", "key-mismatch"]),
 116        new(SignatureVerificationCategory.UntrustedSigningContext, ["provider-not-trusted", "policy-context-not-trusted"
 117        new(
 118            SignatureVerificationCategory.UnknownKeyVersion,
 119            ["key-version"],
 120            ["unknown", "key"]),
 121        new(SignatureVerificationCategory.ProviderUnavailable, ["provider-unavailable", "unavailable", "timeout", "netwo
 122        new(SignatureVerificationCategory.InvalidSignature, ["invalid", "malformed", "signature"])
 123    ];
 24
 25    /// <summary>
 26    /// Evaluates a signed governance artifact and verification result against verification policy.
 27    /// </summary>
 28    public static VerificationPolicyOutcome Evaluate<TArtifact>(
 29        SignedGovernanceArtifact<TArtifact> artifact,
 30        SignatureVerificationResult verificationResult,
 31        VerificationPolicyOptions? options = null)
 32    {
 6233        ArgumentNullException.ThrowIfNull(artifact);
 6234        ArgumentNullException.ThrowIfNull(verificationResult);
 35
 6236        return VerificationPolicyOutcome.CreateCore(
 6237            artifact.ArtifactType,
 6238            artifact.ArtifactId,
 6239            artifact.SigningHash,
 6240            artifact.HashAlgorithm,
 6241            artifact.SigningMetadata,
 6242            verificationResult,
 6243            options);
 44    }
 45
 46    /// <summary>
 47    /// Maps a provider-neutral verification result to a stable verification category.
 48    /// </summary>
 49    public static SignatureVerificationCategory Categorize(SignatureVerificationResult verificationResult)
 50    {
 11051        ArgumentNullException.ThrowIfNull(verificationResult);
 52
 10953        if (verificationResult.IsValid)
 54        {
 2255            return SignatureVerificationCategory.Valid;
 56        }
 57
 8758        if (Matches(verificationResult.Status, "MissingSignature"))
 59        {
 660            return SignatureVerificationCategory.MissingSignature;
 61        }
 62
 8163        if (verificationResult.Category is SignatureVerificationCategory explicitCategory)
 64        {
 3565            return explicitCategory;
 66        }
 67
 4668        string failureCode = verificationResult.FailureCode ?? string.Empty;
 69
 65970        foreach (CategoryRule rule in FailureCodeCategoryRules)
 71        {
 30572            if (rule.IsMatch(failureCode))
 73            {
 4374                return rule.Category;
 75            }
 76        }
 77
 378        return SignatureVerificationCategory.Failed;
 79    }
 80
 81    private static bool Matches(string value, string pattern)
 82    {
 70883        return value.Contains(pattern, StringComparison.OrdinalIgnoreCase);
 84    }
 85
 86    private readonly record struct CategoryRule(
 87        SignatureVerificationCategory Category,
 88        string[] AnyPatterns,
 89        string[]? AllPatterns = null)
 90    {
 91        public bool IsMatch(string failureCode)
 92        {
 176593            foreach (string pattern in AnyPatterns)
 94            {
 59895                if (Matches(failureCode, pattern))
 96                {
 4197                    return true;
 98                }
 99            }
 100
 264101            if (AllPatterns is null)
 102            {
 244103                return false;
 104            }
 105
 68106            foreach (string pattern in AllPatterns)
 107            {
 23108                if (!Matches(failureCode, pattern))
 109                {
 18110                    return false;
 111                }
 112            }
 113
 2114            return AllPatterns.Length > 0;
 115        }
 116    }
 117}