stabilizaiton work - projects rework for maintenanceability and ui livening
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
using StellaOps.Cryptography;
|
||||
using System;
|
||||
|
||||
namespace StellaOps.Cryptography.Providers.OfflineVerification;
|
||||
|
||||
public sealed partial class OfflineVerificationCryptoProvider
|
||||
{
|
||||
private static string NormalizeAlgorithm(string algorithmId) => algorithmId.ToUpperInvariant();
|
||||
|
||||
private static bool IsSupportedSigningAlgorithm(string normalizedAlg)
|
||||
=> normalizedAlg is SignatureAlgorithms.Es256
|
||||
or SignatureAlgorithms.Es384
|
||||
or SignatureAlgorithms.Es512
|
||||
or SignatureAlgorithms.Rs256
|
||||
or SignatureAlgorithms.Rs384
|
||||
or SignatureAlgorithms.Rs512
|
||||
or SignatureAlgorithms.Ps256
|
||||
or SignatureAlgorithms.Ps384
|
||||
or SignatureAlgorithms.Ps512;
|
||||
|
||||
private static bool IsSupportedHashAlgorithm(string normalizedAlg)
|
||||
=> normalizedAlg is HashAlgorithms.Sha256
|
||||
or HashAlgorithms.Sha384
|
||||
or HashAlgorithms.Sha512
|
||||
or "SHA-256"
|
||||
or "SHA-384"
|
||||
or "SHA-512";
|
||||
|
||||
private static bool IsSupportedPasswordAlgorithm(string normalizedAlg)
|
||||
=> normalizedAlg is "PBKDF2"
|
||||
or "PBKDF2-SHA256"
|
||||
or "ARGON2ID"
|
||||
or "ARGON2";
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
using StellaOps.Cryptography;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace StellaOps.Cryptography.Providers.OfflineVerification;
|
||||
|
||||
public sealed partial class OfflineVerificationCryptoProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a signer for the specified algorithm and key.
|
||||
/// </summary>
|
||||
/// <param name="algorithmId">The signing algorithm identifier.</param>
|
||||
/// <param name="keyReference">The key reference.</param>
|
||||
/// <returns>An instance of <see cref="ICryptoSigner"/>.</returns>
|
||||
public ICryptoSigner GetSigner(string algorithmId, CryptoKeyReference keyReference)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(keyReference);
|
||||
|
||||
var normalizedAlg = NormalizeAlgorithm(algorithmId);
|
||||
|
||||
if (!IsSupportedSigningAlgorithm(normalizedAlg))
|
||||
{
|
||||
throw new InvalidOperationException($"Signing algorithm '{algorithmId}' is not supported by provider '{Name}'.");
|
||||
}
|
||||
|
||||
if (!_signingKeys.TryGetValue(keyReference.KeyId, out var signingKey))
|
||||
{
|
||||
throw new KeyNotFoundException($"Signing key '{keyReference.KeyId}' is not registered with provider '{Name}'.");
|
||||
}
|
||||
|
||||
if (!string.Equals(signingKey.AlgorithmId, normalizedAlg, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"Signing key '{keyReference.KeyId}' is registered for algorithm '{signingKey.AlgorithmId}', not '{algorithmId}'.");
|
||||
}
|
||||
|
||||
return EcdsaSigner.Create(signingKey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Upserts a signing key into the provider.
|
||||
/// </summary>
|
||||
/// <param name="signingKey">The signing key to add or update.</param>
|
||||
public void UpsertSigningKey(CryptoSigningKey signingKey)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(signingKey);
|
||||
|
||||
var normalizedAlg = NormalizeAlgorithm(signingKey.AlgorithmId);
|
||||
|
||||
if (!IsSupportedSigningAlgorithm(normalizedAlg))
|
||||
{
|
||||
throw new InvalidOperationException($"Signing algorithm '{signingKey.AlgorithmId}' is not supported by provider '{Name}'.");
|
||||
}
|
||||
|
||||
_signingKeys.AddOrUpdate(signingKey.Reference.KeyId, signingKey, (_, _) => signingKey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a signing key from the provider.
|
||||
/// </summary>
|
||||
/// <param name="keyId">The key identifier to remove.</param>
|
||||
/// <returns>True if the key was removed; otherwise, false.</returns>
|
||||
public bool RemoveSigningKey(string keyId)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(keyId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return _signingKeys.TryRemove(keyId, out _);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all signing keys stored in the provider.
|
||||
/// </summary>
|
||||
/// <returns>A read-only collection of signing keys.</returns>
|
||||
public IReadOnlyCollection<CryptoSigningKey> GetSigningKeys()
|
||||
=> _signingKeys.Values.ToArray();
|
||||
}
|
||||
@@ -1,8 +1,6 @@
|
||||
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using StellaOps.Cryptography;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace StellaOps.Cryptography.Providers.OfflineVerification;
|
||||
|
||||
@@ -10,9 +8,9 @@ namespace StellaOps.Cryptography.Providers.OfflineVerification;
|
||||
/// Offline verification-focused crypto provider using .NET built-in cryptography.
|
||||
/// Designed for air-gap scenarios where only verification operations are needed.
|
||||
/// </summary>
|
||||
public sealed class OfflineVerificationCryptoProvider : ICryptoProvider
|
||||
public sealed partial class OfflineVerificationCryptoProvider : ICryptoProvider
|
||||
{
|
||||
private readonly ConcurrentDictionary<string, CryptoSigningKey> signingKeys = new(StringComparer.OrdinalIgnoreCase);
|
||||
private readonly ConcurrentDictionary<string, CryptoSigningKey> _signingKeys = new(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the provider name.
|
||||
@@ -32,7 +30,7 @@ public sealed class OfflineVerificationCryptoProvider : ICryptoProvider
|
||||
return false;
|
||||
}
|
||||
|
||||
var normalizedAlg = algorithmId.ToUpperInvariant();
|
||||
var normalizedAlg = NormalizeAlgorithm(algorithmId);
|
||||
|
||||
return capability switch
|
||||
{
|
||||
@@ -50,7 +48,7 @@ public sealed class OfflineVerificationCryptoProvider : ICryptoProvider
|
||||
/// <returns>An instance of <see cref="IPasswordHasher"/>.</returns>
|
||||
public IPasswordHasher GetPasswordHasher(string algorithmId)
|
||||
{
|
||||
var normalizedAlg = algorithmId.ToUpperInvariant();
|
||||
var normalizedAlg = NormalizeAlgorithm(algorithmId);
|
||||
|
||||
return normalizedAlg switch
|
||||
{
|
||||
@@ -67,7 +65,7 @@ public sealed class OfflineVerificationCryptoProvider : ICryptoProvider
|
||||
/// <returns>An instance of <see cref="ICryptoHasher"/>.</returns>
|
||||
public ICryptoHasher GetHasher(string algorithmId)
|
||||
{
|
||||
var normalizedAlg = algorithmId.ToUpperInvariant();
|
||||
var normalizedAlg = NormalizeAlgorithm(algorithmId);
|
||||
|
||||
if (!IsSupportedHashAlgorithm(normalizedAlg))
|
||||
{
|
||||
@@ -76,100 +74,4 @@ public sealed class OfflineVerificationCryptoProvider : ICryptoProvider
|
||||
|
||||
return new DefaultCryptoHasher(normalizedAlg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a signer for the specified algorithm and key.
|
||||
/// </summary>
|
||||
/// <param name="algorithmId">The signing algorithm identifier.</param>
|
||||
/// <param name="keyReference">The key reference.</param>
|
||||
/// <returns>An instance of <see cref="ICryptoSigner"/>.</returns>
|
||||
public ICryptoSigner GetSigner(string algorithmId, CryptoKeyReference keyReference)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(keyReference);
|
||||
|
||||
var normalizedAlg = algorithmId.ToUpperInvariant();
|
||||
|
||||
if (!IsSupportedSigningAlgorithm(normalizedAlg))
|
||||
{
|
||||
throw new InvalidOperationException($"Signing algorithm '{algorithmId}' is not supported by provider '{Name}'.");
|
||||
}
|
||||
|
||||
if (!signingKeys.TryGetValue(keyReference.KeyId, out var signingKey))
|
||||
{
|
||||
throw new KeyNotFoundException($"Signing key '{keyReference.KeyId}' is not registered with provider '{Name}'.");
|
||||
}
|
||||
|
||||
if (!string.Equals(signingKey.AlgorithmId, normalizedAlg, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"Signing key '{keyReference.KeyId}' is registered for algorithm '{signingKey.AlgorithmId}', not '{algorithmId}'.");
|
||||
}
|
||||
|
||||
return EcdsaSigner.Create(signingKey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Upserts a signing key into the provider.
|
||||
/// </summary>
|
||||
/// <param name="signingKey">The signing key to add or update.</param>
|
||||
public void UpsertSigningKey(CryptoSigningKey signingKey)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(signingKey);
|
||||
|
||||
var normalizedAlg = signingKey.AlgorithmId.ToUpperInvariant();
|
||||
|
||||
if (!IsSupportedSigningAlgorithm(normalizedAlg))
|
||||
{
|
||||
throw new InvalidOperationException($"Signing algorithm '{signingKey.AlgorithmId}' is not supported by provider '{Name}'.");
|
||||
}
|
||||
|
||||
signingKeys.AddOrUpdate(signingKey.Reference.KeyId, signingKey, (_, _) => signingKey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a signing key from the provider.
|
||||
/// </summary>
|
||||
/// <param name="keyId">The key identifier to remove.</param>
|
||||
/// <returns>True if the key was removed; otherwise, false.</returns>
|
||||
public bool RemoveSigningKey(string keyId)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(keyId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return signingKeys.TryRemove(keyId, out _);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all signing keys stored in the provider.
|
||||
/// </summary>
|
||||
/// <returns>A read-only collection of signing keys.</returns>
|
||||
public IReadOnlyCollection<CryptoSigningKey> GetSigningKeys()
|
||||
=> signingKeys.Values.ToArray();
|
||||
|
||||
private static bool IsSupportedSigningAlgorithm(string normalizedAlg)
|
||||
=> normalizedAlg is SignatureAlgorithms.Es256
|
||||
or SignatureAlgorithms.Es384
|
||||
or SignatureAlgorithms.Es512
|
||||
or SignatureAlgorithms.Rs256
|
||||
or SignatureAlgorithms.Rs384
|
||||
or SignatureAlgorithms.Rs512
|
||||
or SignatureAlgorithms.Ps256
|
||||
or SignatureAlgorithms.Ps384
|
||||
or SignatureAlgorithms.Ps512;
|
||||
|
||||
private static bool IsSupportedHashAlgorithm(string normalizedAlg)
|
||||
=> normalizedAlg is HashAlgorithms.Sha256
|
||||
or HashAlgorithms.Sha384
|
||||
or HashAlgorithms.Sha512
|
||||
or "SHA-256"
|
||||
or "SHA-384"
|
||||
or "SHA-512";
|
||||
|
||||
private static bool IsSupportedPasswordAlgorithm(string normalizedAlg)
|
||||
=> normalizedAlg is "PBKDF2"
|
||||
or "PBKDF2-SHA256"
|
||||
or "ARGON2ID"
|
||||
or "ARGON2";
|
||||
}
|
||||
|
||||
@@ -9,3 +9,4 @@ Source of truth: `docs-archived/implplan/2025-12-29-csproj-audit/SPRINT_20251229
|
||||
| AUDIT-0070-T | DONE | Revalidated 2026-01-08; open findings tracked in audit report. |
|
||||
| AUDIT-0070-A | TODO | Revalidated 2026-01-08 (open findings). |
|
||||
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |
|
||||
| REMED-08 | DONE | Split OfflineVerificationCryptoProvider; added algorithm/signer tests. |
|
||||
|
||||
Reference in New Issue
Block a user