< Summary

Information
Class: AsiBackbone.Signing.ManagedKey.ManagedKeySignRequest
Assembly: AsiBackbone.Signing.ManagedKey
File(s): /home/runner/work/AsiBackbone/AsiBackbone/src/AsiBackbone.Signing.ManagedKey/ManagedKeySignRequest.cs
Line coverage
100%
Covered lines: 33
Uncovered lines: 0
Coverable lines: 33
Total lines: 125
Line coverage: 100%
Branch coverage
90%
Covered branches: 18
Total branches: 20
Branch coverage: 90%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%11100%
.ctor(...)100%11100%
get_SignatureInput()50%22100%
set_SignatureInput(...)50%22100%
NormalizeRequired(...)100%11100%
NormalizeOptional(...)100%22100%
NormalizeMetadata(...)100%1414100%

File(s)

/home/runner/work/AsiBackbone/AsiBackbone/src/AsiBackbone.Signing.ManagedKey/ManagedKeySignRequest.cs

#LineLine coverage
 1using System.Collections.ObjectModel;
 2using AsiBackbone.Core.Signing;
 3
 4namespace AsiBackbone.Signing.ManagedKey;
 5
 6/// <summary>
 7/// Represents a managed-key client request to sign a precomputed governance artifact hash.
 8/// </summary>
 9public sealed class ManagedKeySignRequest
 10{
 11    private readonly byte[]? signatureInput;
 12
 113    private static readonly ReadOnlyDictionary<string, string> EmptyMetadata =
 114        new(new Dictionary<string, string>(StringComparer.Ordinal));
 15
 16    /// <summary>
 17    /// Initializes a new instance of the <see cref="ManagedKeySignRequest" /> class.
 18    /// </summary>
 5319    public ManagedKeySignRequest(
 5320        string signingHash,
 5321        string hashAlgorithm,
 5322        string signatureAlgorithm,
 5323        string keyId,
 5324        string? keyVersion = null,
 5325        string? purpose = null,
 5326        IReadOnlyDictionary<string, string>? metadata = null)
 27    {
 5328        ArgumentException.ThrowIfNullOrWhiteSpace(signingHash);
 5029        ArgumentException.ThrowIfNullOrWhiteSpace(hashAlgorithm);
 4730        ArgumentException.ThrowIfNullOrWhiteSpace(signatureAlgorithm);
 4431        ArgumentException.ThrowIfNullOrWhiteSpace(keyId);
 32
 4133        SigningHash = signingHash.Trim();
 4134        HashAlgorithm = NormalizeRequired(hashAlgorithm);
 4135        SignatureAlgorithm = NormalizeRequired(signatureAlgorithm);
 4136        KeyId = NormalizeRequired(keyId);
 4137        KeyVersion = NormalizeOptional(keyVersion);
 4138        Purpose = NormalizeOptional(purpose);
 4139        Metadata = NormalizeMetadata(metadata);
 4140    }
 41
 42    /// <summary>
 43    /// Gets the precomputed hash to sign.
 44    /// </summary>
 45    public string SigningHash { get; }
 46
 47    /// <summary>
 48    /// Gets the hash algorithm descriptor associated with <see cref="SigningHash" />.
 49    /// </summary>
 50    public string HashAlgorithm { get; }
 51
 52    /// <summary>
 53    /// Gets the requested provider-neutral signature algorithm descriptor.
 54    /// </summary>
 55    public string SignatureAlgorithm { get; }
 56
 57    /// <summary>
 58    /// Gets the managed key identifier or key URI reference.
 59    /// </summary>
 60    public string KeyId { get; }
 61
 62    /// <summary>
 63    /// Gets the managed key version, when supplied.
 64    /// </summary>
 65    public string? KeyVersion { get; }
 66
 67    /// <summary>
 68    /// Gets the host-defined signing purpose, when supplied.
 69    /// </summary>
 70    public string? Purpose { get; }
 71
 72    /// <summary>
 73    /// Gets provider-neutral request metadata.
 74    /// </summary>
 75    public IReadOnlyDictionary<string, string> Metadata { get; }
 76
 77    /// <summary>
 78    /// Gets the exact bytes the managed key must sign.
 79    /// </summary>
 80    /// <remarks>
 81    /// <see cref="ManagedKeySigningService" /> copies <see cref="SigningRequest.SignatureInput" /> here. For artifacts
 82    /// signed through <see cref="GovernanceArtifactSigner" /> this is the version 1 input that binds the canonical
 83    /// descriptors, hash, and signing policy context. Clients must sign these bytes, not <see cref="SigningHash" />: pa
 84    /// them as the message to a message-signing API, or hash them with the key's digest algorithm before calling a
 85    /// digest-signing API. A client that signs the hash text produces signatures that fail version 1 verification. When
 86    /// input was supplied, this returns the pre-6.0 hash-only input. The supplied value is copied.
 87    /// </remarks>
 88    public ReadOnlyMemory<byte> SignatureInput
 89    {
 90#pragma warning disable ASIB902 // Retained internal fallback for pre-6.0 provider-request compatibility.
 891        get => signatureInput ?? GovernanceSignatureInput.CreateLegacy(SigningHash);
 92#pragma warning restore ASIB902
 3493        init => signatureInput = value.IsEmpty ? null : [.. value.Span];
 94    }
 95
 96    private static string NormalizeRequired(string value)
 97    {
 12398        return value.Trim();
 99    }
 100
 101    private static string? NormalizeOptional(string? value)
 102    {
 82103        return string.IsNullOrWhiteSpace(value) ? null : value.Trim();
 104    }
 105
 106    private static ReadOnlyDictionary<string, string> NormalizeMetadata(IReadOnlyDictionary<string, string>? metadata)
 107    {
 41108        if (metadata is null || metadata.Count == 0)
 109        {
 35110            return EmptyMetadata;
 111        }
 112
 6113        Dictionary<string, string> normalized = new(StringComparer.Ordinal);
 114
 98115        foreach (KeyValuePair<string, string> item in metadata)
 116        {
 43117            if (!string.IsNullOrWhiteSpace(item.Key))
 118            {
 40119                normalized[item.Key.Trim()] = item.Value?.Trim() ?? string.Empty;
 120            }
 121        }
 122
 6123        return normalized.Count == 0 ? EmptyMetadata : new ReadOnlyDictionary<string, string>(normalized);
 124    }
 125}