< Summary

Information
Class: AsiBackbone.Signing.ManagedKey.ManagedKeySigningService
Assembly: AsiBackbone.Signing.ManagedKey
File(s): /home/runner/work/AsiBackbone/AsiBackbone/src/AsiBackbone.Signing.ManagedKey/ManagedKeySigningService.cs
Line coverage
100%
Covered lines: 223
Uncovered lines: 0
Coverable lines: 223
Total lines: 493
Line coverage: 100%
Branch coverage
85%
Covered branches: 94
Total branches: 110
Branch coverage: 85.4%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

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

#LineLine coverage
 1using System.Globalization;
 2using System.Runtime.ExceptionServices;
 3using AsiBackbone.Core.Signing;
 4
 5namespace AsiBackbone.Signing.ManagedKey;
 6
 7/// <summary>
 8/// Provides managed-key signing for AsiBackbone signing abstractions through a host-owned managed-key client.
 9/// </summary>
 10/// <remarks>
 11/// This service signs precomputed hashes only. It never requests or handles raw private key material.
 12/// </remarks>
 13public sealed class ManagedKeySigningService : IGovernanceSigningService
 14{
 15    private const string ProviderKind = "managed-key";
 16
 17    private readonly ManagedKeySigningOptions options;
 18    private readonly IManagedKeySigningClient client;
 19    private readonly IManagedKeyRetryJitterSource jitterSource;
 20    private readonly IManagedKeyRetryDelay retryDelay;
 21
 22    /// <summary>
 23    /// Initializes a new instance of the <see cref="ManagedKeySigningService" /> class.
 24    /// </summary>
 25    public ManagedKeySigningService(ManagedKeySigningOptions options, IManagedKeySigningClient client)
 3926        : this(
 3927            options,
 3928            client,
 3929            SharedRandomManagedKeyRetryJitterSource.Instance,
 3930            SystemManagedKeyRetryDelay.Instance)
 31    {
 3932    }
 33
 4134    internal ManagedKeySigningService(
 4135        ManagedKeySigningOptions options,
 4136        IManagedKeySigningClient client,
 4137        IManagedKeyRetryJitterSource jitterSource,
 4138        IManagedKeyRetryDelay retryDelay)
 39    {
 4140        ArgumentNullException.ThrowIfNull(options);
 4141        ArgumentNullException.ThrowIfNull(client);
 4142        ArgumentNullException.ThrowIfNull(jitterSource);
 4143        ArgumentNullException.ThrowIfNull(retryDelay);
 44
 4145        options.Validate();
 4146        this.options = options;
 4147        this.client = client;
 4148        this.jitterSource = jitterSource;
 4149        this.retryDelay = retryDelay;
 4150    }
 51
 52    /// <inheritdoc />
 53    public async ValueTask<SigningResult> SignAsync(
 54        SigningRequest request,
 55        CancellationToken cancellationToken = default)
 56    {
 3257        ArgumentNullException.ThrowIfNull(request);
 3258        cancellationToken.ThrowIfCancellationRequested();
 59
 3260        ManagedKeySigningAttemptDiagnostics diagnostics = CreateAttemptDiagnostics();
 3261        string? validationFailure = ValidateSigningRequest(request);
 3262        if (validationFailure is not null)
 63        {
 664            return HandleValidationFailure(request, validationFailure, diagnostics);
 65        }
 66
 2667        int attempt = 0;
 68
 69        while (true)
 70        {
 71            try
 72            {
 3473                ManagedKeySignResult managedResult = await client
 3474                    .SignAsync(CreateManagedKeyRequest(request), cancellationToken)
 3475                    .ConfigureAwait(false);
 76
 1777                ManagedKeyResponseMismatch? mismatch = ValidateSigningResponse(request, managedResult);
 78
 1779                return mismatch is not null
 1780                    ? HandleFailure(
 1781                        request,
 1782                        mismatch.FailureCode,
 1783                        mismatch.Message,
 1784                        attempt,
 1785                        diagnostics,
 1786                        new ManagedKeySigningException(mismatch.FailureCode, mismatch.Message, isRetryable: false))
 1787                    : CreateSignedResult(request, managedResult, attempt, diagnostics);
 88            }
 1389            catch (ManagedKeySigningException exception) when (exception.IsRetryable && attempt < options.MaxRetryAttemp
 90            {
 891                diagnostics.RecordRetry(exception);
 892                attempt++;
 893                await DelayForRetryAsync(attempt, diagnostics, cancellationToken).ConfigureAwait(false);
 894            }
 595            catch (ManagedKeySigningException exception)
 96            {
 597                return HandleFailure(request, exception.FailureCode, exception.Message, attempt, diagnostics, exception)
 98            }
 199            catch (TimeoutException exception)
 100            {
 1101                return HandleFailure(request, "managedkey.signing.provider-unavailable", exception.GetType().Name, attem
 102            }
 2103            catch (InvalidOperationException exception)
 104            {
 2105                return HandleFailure(request, "managedkey.signing.failed", exception.GetType().Name, attempt, diagnostic
 106            }
 1107            catch (NotSupportedException exception)
 108            {
 1109                return HandleFailure(request, "managedkey.signing.unsupported", exception.GetType().Name, attempt, diagn
 110            }
 111        }
 29112    }
 113
 114    private SigningResult HandleValidationFailure(
 115        SigningRequest request,
 116        string failureCode,
 117        ManagedKeySigningAttemptDiagnostics diagnostics)
 118    {
 6119        diagnostics.RecordValidationFailure();
 120
 6121        return !options.ReturnUnsignedOnFailure
 6122            ? throw new ManagedKeySigningException(failureCode, failureCode)
 6123            : CreateUnsignedFailureResult(request, failureCode, failureCode, retryAttempts: 0, diagnostics);
 124    }
 125
 126    private SigningResult HandleFailure(
 127        SigningRequest request,
 128        string failureCode,
 129        string failureMessage,
 130        int retryAttempts,
 131        ManagedKeySigningAttemptDiagnostics diagnostics,
 132        Exception exception)
 133    {
 12134        diagnostics.RecordFailure(exception);
 135
 12136        if (!options.ReturnUnsignedOnFailure)
 137        {
 2138            ExceptionDispatchInfo.Capture(exception).Throw();
 139        }
 140
 10141        return CreateUnsignedFailureResult(request, failureCode, failureMessage, retryAttempts, diagnostics);
 142    }
 143
 144    private ManagedKeySignRequest CreateManagedKeyRequest(SigningRequest request)
 145    {
 34146        return new ManagedKeySignRequest(
 34147            request.SigningHash,
 34148            NormalizeHashAlgorithm(request.HashAlgorithm),
 34149            NormalizeRequired(options.SignatureAlgorithm, ManagedKeySigningOptions.DefaultSignatureAlgorithm),
 34150            ResolveKeyId(request),
 34151            ResolveKeyVersion(request),
 34152            request.Purpose,
 34153            request.Metadata)
 34154        {
 34155            SignatureInput = request.SignatureInput
 34156        };
 157    }
 158
 159    /// <summary>
 160    /// Rejects a provider response whose key identity or signature algorithm differs from what was requested.
 161    /// </summary>
 162    /// <remarks>
 163    /// The signed result copies the provider's key identifier, key version, and signature algorithm into signing metada
 164    /// Without this comparison a provider that signed under a different key, a different key version, or a different
 165    /// algorithm produced an artifact that recorded the substitution as though it had been requested, and the artifact
 166    /// could also carry two disagreeing algorithm descriptors because the configured value is written separately.
 167    /// A key version is only compared when the request or configuration pinned one, so ordinary version resolution by t
 168    /// provider is still accepted.
 169    /// </remarks>
 170    private ManagedKeyResponseMismatch? ValidateSigningResponse(SigningRequest request, ManagedKeySignResult managedResu
 171    {
 17172        string requestedKeyId = ResolveKeyId(request);
 173
 17174        if (!string.IsNullOrWhiteSpace(managedResult.KeyId)
 17175            && !string.Equals(managedResult.KeyId, requestedKeyId, StringComparison.Ordinal))
 176        {
 1177            return new ManagedKeyResponseMismatch(
 1178                "managedkey.signing.key-mismatch",
 1179                "The managed key provider signed with a different key identifier than the one requested.");
 180        }
 181
 16182        string? requestedKeyVersion = ResolveKeyVersion(request);
 183
 16184        if (requestedKeyVersion is not null
 16185            && !string.IsNullOrWhiteSpace(managedResult.KeyVersion)
 16186            && !string.Equals(managedResult.KeyVersion, requestedKeyVersion, StringComparison.Ordinal))
 187        {
 1188            return new ManagedKeyResponseMismatch(
 1189                "managedkey.signing.key-version-mismatch",
 1190                "The managed key provider signed with a different key version than the one requested.");
 191        }
 192
 15193        string configuredAlgorithm = NormalizeRequired(options.SignatureAlgorithm, ManagedKeySigningOptions.DefaultSigna
 194
 15195        return !string.IsNullOrWhiteSpace(managedResult.SignatureAlgorithm)
 15196            && !string.Equals(managedResult.SignatureAlgorithm, configuredAlgorithm, StringComparison.Ordinal)
 15197            ? new ManagedKeyResponseMismatch(
 15198                "managedkey.signing.algorithm-mismatch",
 15199                "The managed key provider signed with a different signature algorithm than the configured one.")
 15200            : null;
 201    }
 202
 203    private sealed record ManagedKeyResponseMismatch(string FailureCode, string Message);
 204
 205    private SigningResult CreateSignedResult(
 206        SigningRequest request,
 207        ManagedKeySignResult managedResult,
 208        int retryAttempts,
 209        ManagedKeySigningAttemptDiagnostics diagnostics)
 210    {
 14211        string resolvedKeyVersion = managedResult.KeyVersion ?? ResolveKeyVersion(request) ?? string.Empty;
 14212        Dictionary<string, string> metadata = CreateBaseMetadata(request, retryAttempts, providerAttempts: retryAttempts
 14213        metadata["signing_status"] = "signed";
 214
 14215        if (managedResult.ProviderOperationId is not null)
 216        {
 7217            metadata["provider_operation_id"] = managedResult.ProviderOperationId;
 218        }
 219
 42220        foreach (KeyValuePair<string, string> item in managedResult.Metadata)
 221        {
 7222            if (!IsSafeProviderMetadataKey(item.Key) || IsReservedDiagnosticMetadataKey(item.Key))
 223            {
 224                continue;
 225            }
 226
 7227            metadata[item.Key.Trim()] = item.Value?.Trim() ?? string.Empty;
 228        }
 229
 14230        var signingMetadata = SigningMetadata.Create(
 14231            signingHash: request.SigningHash,
 14232            hashAlgorithm: NormalizeHashAlgorithm(request.HashAlgorithm),
 14233            signature: managedResult.Signature,
 14234            signatureAlgorithm: managedResult.SignatureAlgorithm,
 14235            keyId: managedResult.KeyId,
 14236            keyVersion: string.IsNullOrWhiteSpace(resolvedKeyVersion) ? null : resolvedKeyVersion,
 14237            provider: NormalizeRequired(options.ProviderName, ManagedKeySigningOptions.DefaultProviderName),
 14238            signedUtc: managedResult.SignedUtc,
 14239            metadata: metadata);
 240
 14241        return SigningResult.FromMetadata(signingMetadata);
 242    }
 243
 244    private SigningResult CreateUnsignedFailureResult(
 245        SigningRequest request,
 246        string failureCode,
 247        string failureMessage,
 248        int retryAttempts,
 249        ManagedKeySigningAttemptDiagnostics diagnostics)
 250    {
 15251        int providerAttempts = diagnostics.HasValidationFailure ? 0 : retryAttempts + 1;
 15252        Dictionary<string, string> metadata = CreateBaseMetadata(request, retryAttempts, providerAttempts, diagnostics);
 15253        metadata["signing_status"] = "failed";
 15254        metadata["failure_code"] = failureCode;
 15255        metadata["failure_message"] = failureMessage;
 256
 15257        var signingMetadata = SigningMetadata.Create(
 15258            signingHash: request.SigningHash,
 15259            hashAlgorithm: NormalizeHashAlgorithm(request.HashAlgorithm),
 15260            keyId: ResolveKeyId(request),
 15261            keyVersion: ResolveKeyVersion(request),
 15262            provider: NormalizeRequired(options.ProviderName, ManagedKeySigningOptions.DefaultProviderName),
 15263            metadata: metadata);
 264
 15265        return SigningResult.FromMetadata(signingMetadata);
 266    }
 267
 268    private Dictionary<string, string> CreateBaseMetadata(
 269        SigningRequest request,
 270        int retryAttempts,
 271        int providerAttempts,
 272        ManagedKeySigningAttemptDiagnostics diagnostics)
 273    {
 29274        Dictionary<string, string> metadata = new(StringComparer.Ordinal);
 275
 128276        foreach (KeyValuePair<string, string> item in request.Metadata)
 277        {
 35278            if (string.IsNullOrWhiteSpace(item.Key) || IsReservedDiagnosticMetadataKey(item.Key))
 279            {
 280                continue;
 281            }
 282
 10283            metadata[item.Key.Trim()] = item.Value?.Trim() ?? string.Empty;
 284        }
 285
 29286        metadata["provider_kind"] = ProviderKind;
 29287        metadata["remote_key_material"] = "true";
 29288        metadata["raw_private_key_loaded"] = "false";
 29289        metadata["retry_attempts"] = retryAttempts.ToString(CultureInfo.InvariantCulture);
 29290        metadata["provider_attempts"] = providerAttempts.ToString(CultureInfo.InvariantCulture);
 29291        metadata["max_retry_attempts"] = diagnostics.MaxRetryAttempts.ToString(CultureInfo.InvariantCulture);
 29292        metadata["retry_delay_milliseconds"] = diagnostics.BaseRetryDelay.TotalMilliseconds.ToString("0.###", CultureInf
 29293        metadata["max_retry_delay_milliseconds"] = diagnostics.MaxRetryDelay.TotalMilliseconds.ToString("0.###", Culture
 29294        metadata["last_retry_delay_milliseconds"] = diagnostics.LastRetryDelay.TotalMilliseconds.ToString("0.###", Cultu
 29295        metadata["total_retry_delay_milliseconds"] = diagnostics.TotalRetryDelay.TotalMilliseconds.ToString("0.###", Cul
 29296        metadata["retry_delay_count"] = diagnostics.RetryDelayCount.ToString(CultureInfo.InvariantCulture);
 29297        metadata["retry_backoff_strategy"] = ManagedKeyRetryBackoff.StrategyName;
 29298        metadata["retry_delay_configured"] = ToMetadataBoolean(diagnostics.BaseRetryDelay > TimeSpan.Zero);
 29299        metadata["retry_delay_applied"] = ToMetadataBoolean(diagnostics.RetryDelayCount > 0);
 29300        metadata["signature_algorithm"] = NormalizeRequired(options.SignatureAlgorithm, ManagedKeySigningOptions.Default
 301
 29302        if (diagnostics.LastRetryFailureCode is not null)
 303        {
 6304            metadata["last_retry_failure_code"] = diagnostics.LastRetryFailureCode;
 305        }
 306
 29307        if (diagnostics.LastRetryFailureExceptionType is not null)
 308        {
 6309            metadata["last_retry_failure_exception_type"] = diagnostics.LastRetryFailureExceptionType;
 310        }
 311
 29312        if (diagnostics.FailureExceptionType is not null)
 313        {
 10314            metadata["failure_exception_type"] = diagnostics.FailureExceptionType;
 315        }
 316
 29317        if (diagnostics.FailureRetryable is not null)
 318        {
 10319            metadata["failure_retryable"] = ToMetadataBoolean(diagnostics.FailureRetryable.Value);
 320        }
 321
 29322        if (request.Purpose is not null)
 323        {
 14324            metadata["purpose"] = request.Purpose;
 325        }
 326
 29327        return metadata;
 328    }
 329
 330    private string? ValidateSigningRequest(SigningRequest request)
 331    {
 32332        if (!IsSupportedHashAlgorithm(request.HashAlgorithm))
 333        {
 2334            return "managedkey.signing.hash-algorithm-unsupported";
 335        }
 336
 30337        string configuredKeyId = NormalizeRequired(options.KeyId, string.Empty);
 30338        if (request.KeyId is not null && !string.Equals(request.KeyId, configuredKeyId, StringComparison.Ordinal))
 339        {
 1340            return "managedkey.signing.key-mismatch";
 341        }
 342
 29343        string? configuredKeyVersion = NormalizeOptional(options.KeyVersion);
 29344        return options.RequireKeyVersion && request.KeyVersion is null && configuredKeyVersion is null
 29345            ? "managedkey.signing.key-version-missing"
 29346            : request.KeyVersion is not null
 29347            && configuredKeyVersion is not null
 29348            && !string.Equals(request.KeyVersion, configuredKeyVersion, StringComparison.Ordinal)
 29349            ? "managedkey.signing.key-version-mismatch"
 29350            : null;
 351    }
 352
 353    private string ResolveKeyId(SigningRequest request)
 354    {
 66355        return request.KeyId ?? NormalizeRequired(options.KeyId, string.Empty);
 356    }
 357
 358    private string? ResolveKeyVersion(SigningRequest request)
 359    {
 66360        return request.KeyVersion ?? NormalizeOptional(options.KeyVersion);
 361    }
 362
 363    private string NormalizeHashAlgorithm(string? hashAlgorithm)
 364    {
 127365        string normalized = string.IsNullOrWhiteSpace(hashAlgorithm)
 127366            ? options.HashAlgorithm
 127367            : hashAlgorithm.Trim();
 368
 127369        return normalized.Equals("SHA256", StringComparison.OrdinalIgnoreCase)
 127370            ? ManagedKeySigningOptions.DefaultHashAlgorithm
 127371            : normalized.Equals(ManagedKeySigningOptions.DefaultHashAlgorithm, StringComparison.OrdinalIgnoreCase)
 127372                ? ManagedKeySigningOptions.DefaultHashAlgorithm
 127373                : normalized;
 374    }
 375
 376    private bool IsSupportedHashAlgorithm(string? hashAlgorithm)
 377    {
 32378        return NormalizeHashAlgorithm(hashAlgorithm).Equals(
 32379            NormalizeHashAlgorithm(options.HashAlgorithm),
 32380            StringComparison.OrdinalIgnoreCase);
 381    }
 382
 383    private async ValueTask DelayForRetryAsync(
 384        int retryAttempt,
 385        ManagedKeySigningAttemptDiagnostics diagnostics,
 386        CancellationToken cancellationToken)
 387    {
 8388        TimeSpan delay = ManagedKeyRetryBackoff.CalculateDelay(
 8389            options.RetryDelay,
 8390            options.MaxRetryDelay,
 8391            retryAttempt,
 8392            jitterSource.NextDouble(),
 8393            diagnostics.LastRetryDelay);
 394
 8395        if (delay <= TimeSpan.Zero)
 396        {
 3397            return;
 398        }
 399
 5400        diagnostics.RecordRetryDelay(delay);
 5401        await retryDelay.DelayAsync(delay, cancellationToken).ConfigureAwait(false);
 8402    }
 403
 404    private ManagedKeySigningAttemptDiagnostics CreateAttemptDiagnostics()
 405    {
 32406        return new ManagedKeySigningAttemptDiagnostics(
 32407            options.MaxRetryAttempts,
 32408            options.RetryDelay,
 32409            options.MaxRetryDelay);
 410    }
 411
 412    private static bool IsSafeProviderMetadataKey(string key)
 413    {
 7414        return !string.IsNullOrWhiteSpace(key)
 7415            && !key.Contains("secret", StringComparison.OrdinalIgnoreCase)
 7416            && !key.Contains("token", StringComparison.OrdinalIgnoreCase)
 7417            && !key.Contains("credential", StringComparison.OrdinalIgnoreCase)
 7418            && !key.Contains("private", StringComparison.OrdinalIgnoreCase)
 7419            && !key.Contains("connection", StringComparison.OrdinalIgnoreCase);
 420    }
 421
 422    private static bool IsReservedDiagnosticMetadataKey(string key)
 423    {
 42424        return ManagedKeyDiagnosticMetadataKeyClassifier.IsReserved(key);
 425    }
 426
 427    private static string NormalizeRequired(string? value, string fallback)
 428    {
 137429        return string.IsNullOrWhiteSpace(value) ? fallback : value.Trim();
 430    }
 431
 432    private static string? NormalizeOptional(string? value)
 433    {
 36434        return string.IsNullOrWhiteSpace(value) ? null : value.Trim();
 435    }
 436
 437    private static string ToMetadataBoolean(bool value)
 438    {
 68439        return value ? "true" : "false";
 440    }
 441
 32442    private sealed class ManagedKeySigningAttemptDiagnostics(
 32443        int maxRetryAttempts,
 32444        TimeSpan baseRetryDelay,
 32445        TimeSpan maxRetryDelay)
 446    {
 447        public int MaxRetryAttempts { get; } = maxRetryAttempts;
 448
 449        public TimeSpan BaseRetryDelay { get; } = baseRetryDelay;
 450
 451        public TimeSpan MaxRetryDelay { get; } = maxRetryDelay;
 452
 453        public TimeSpan LastRetryDelay { get; private set; }
 454
 455        public TimeSpan TotalRetryDelay { get; private set; }
 456
 457        public int RetryDelayCount { get; private set; }
 458
 459        public bool HasValidationFailure { get; private set; }
 460
 461        public string? LastRetryFailureCode { get; private set; }
 462
 463        public string? LastRetryFailureExceptionType { get; private set; }
 464
 465        public string? FailureExceptionType { get; private set; }
 466
 467        public bool? FailureRetryable { get; private set; }
 468
 469        public void RecordValidationFailure()
 470        {
 6471            HasValidationFailure = true;
 6472        }
 473
 474        public void RecordRetry(ManagedKeySigningException exception)
 475        {
 8476            LastRetryFailureCode = exception.FailureCode;
 8477            LastRetryFailureExceptionType = exception.GetType().Name;
 8478        }
 479
 480        public void RecordRetryDelay(TimeSpan delay)
 481        {
 5482            LastRetryDelay = delay;
 5483            TotalRetryDelay += delay;
 5484            RetryDelayCount++;
 5485        }
 486
 487        public void RecordFailure(Exception exception)
 488        {
 12489            FailureExceptionType = exception.GetType().Name;
 12490            FailureRetryable = exception is ManagedKeySigningException managedKeyException && managedKeyException.IsRetr
 12491        }
 492    }
 493}

Methods/Properties

.ctor(AsiBackbone.Signing.ManagedKey.ManagedKeySigningOptions,AsiBackbone.Signing.ManagedKey.IManagedKeySigningClient)
.ctor(AsiBackbone.Signing.ManagedKey.ManagedKeySigningOptions,AsiBackbone.Signing.ManagedKey.IManagedKeySigningClient,AsiBackbone.Signing.ManagedKey.IManagedKeyRetryJitterSource,AsiBackbone.Signing.ManagedKey.IManagedKeyRetryDelay)
SignAsync()
HandleValidationFailure(AsiBackbone.Core.Signing.SigningRequest,System.String,AsiBackbone.Signing.ManagedKey.ManagedKeySigningService/ManagedKeySigningAttemptDiagnostics)
HandleFailure(AsiBackbone.Core.Signing.SigningRequest,System.String,System.String,System.Int32,AsiBackbone.Signing.ManagedKey.ManagedKeySigningService/ManagedKeySigningAttemptDiagnostics,System.Exception)
CreateManagedKeyRequest(AsiBackbone.Core.Signing.SigningRequest)
ValidateSigningResponse(AsiBackbone.Core.Signing.SigningRequest,AsiBackbone.Signing.ManagedKey.ManagedKeySignResult)
CreateSignedResult(AsiBackbone.Core.Signing.SigningRequest,AsiBackbone.Signing.ManagedKey.ManagedKeySignResult,System.Int32,AsiBackbone.Signing.ManagedKey.ManagedKeySigningService/ManagedKeySigningAttemptDiagnostics)
CreateUnsignedFailureResult(AsiBackbone.Core.Signing.SigningRequest,System.String,System.String,System.Int32,AsiBackbone.Signing.ManagedKey.ManagedKeySigningService/ManagedKeySigningAttemptDiagnostics)
CreateBaseMetadata(AsiBackbone.Core.Signing.SigningRequest,System.Int32,System.Int32,AsiBackbone.Signing.ManagedKey.ManagedKeySigningService/ManagedKeySigningAttemptDiagnostics)
ValidateSigningRequest(AsiBackbone.Core.Signing.SigningRequest)
ResolveKeyId(AsiBackbone.Core.Signing.SigningRequest)
ResolveKeyVersion(AsiBackbone.Core.Signing.SigningRequest)
NormalizeHashAlgorithm(System.String)
IsSupportedHashAlgorithm(System.String)
DelayForRetryAsync()
CreateAttemptDiagnostics()
IsSafeProviderMetadataKey(System.String)
IsReservedDiagnosticMetadataKey(System.String)
NormalizeRequired(System.String,System.String)
NormalizeOptional(System.String)
ToMetadataBoolean(System.Boolean)
.ctor(System.Int32,System.TimeSpan,System.TimeSpan)
RecordValidationFailure()
RecordRetry(AsiBackbone.Signing.ManagedKey.ManagedKeySigningException)
RecordRetryDelay(System.TimeSpan)
RecordFailure(System.Exception)