Refactor code structure and optimize performance across multiple modules

This commit is contained in:
StellaOps Bot
2025-12-26 20:03:22 +02:00
parent c786faae84
commit b4fc66feb6
3353 changed files with 88254 additions and 1590657 deletions

View File

@@ -2,13 +2,15 @@ using System;
using StellaOps.Cryptography;
using Xunit;
using StellaOps.TestKit;
namespace StellaOps.Cryptography.Tests;
public class Argon2idPasswordHasherTests
{
private readonly Argon2idPasswordHasher hasher = new();
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void Hash_ProducesPhcEncodedString()
{
var options = new PasswordHashOptions();
@@ -17,7 +19,8 @@ public class Argon2idPasswordHasherTests
Assert.StartsWith("$argon2id$", encoded, StringComparison.Ordinal);
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void Verify_ReturnsTrue_ForCorrectPassword()
{
var options = new PasswordHashOptions();
@@ -27,7 +30,8 @@ public class Argon2idPasswordHasherTests
Assert.False(hasher.Verify("wrong", encoded));
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void NeedsRehash_ReturnsTrue_WhenParametersChange()
{
var options = new PasswordHashOptions();

View File

@@ -5,11 +5,14 @@ using StellaOps.Cryptography.DependencyInjection;
using StellaOps.Cryptography.Plugin.BouncyCastle;
using Xunit;
using StellaOps.TestKit;
namespace StellaOps.Cryptography.Tests;
public sealed class BouncyCastleEd25519CryptoProviderTests
{
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task SignAndVerify_WithBouncyCastleProvider_Succeeds()
{
var configuration = new ConfigurationBuilder().Build();

View File

@@ -7,11 +7,14 @@ using StellaOps.Cryptography;
using StellaOps.Cryptography.Plugin.CryptoPro;
using Xunit;
using StellaOps.TestKit;
namespace StellaOps.Cryptography.Tests;
public class CryptoProGostSignerTests
{
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void ExportPublicJsonWebKey_ContainsCertificateChain()
{
if (!OperatingSystem.IsWindows())

View File

@@ -6,11 +6,13 @@ using Microsoft.IdentityModel.Tokens;
using StellaOps.Cryptography;
using Xunit;
using StellaOps.TestKit;
namespace StellaOps.Cryptography.Tests;
public class CryptoProviderRegistryTests
{
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void ResolveOrThrow_RespectsPreferredProviderOrder()
{
var providerA = new FakeCryptoProvider("providerA")
@@ -28,7 +30,8 @@ public class CryptoProviderRegistryTests
Assert.Same(providerB, resolved);
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void ResolveSigner_UsesPreferredProviderHint()
{
var providerA = new FakeCryptoProvider("providerA")
@@ -59,7 +62,8 @@ public class CryptoProviderRegistryTests
Assert.Equal("key-a", fallbackResolution.Signer.KeyId);
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void RegistryOptions_UsesActiveProfileOrder()
{
var options = new StellaOps.Cryptography.DependencyInjection.CryptoProviderRegistryOptions();

View File

@@ -8,13 +8,16 @@ using Org.BouncyCastle.Crypto.Digests;
using StellaOps.Cryptography;
using Xunit;
using StellaOps.TestKit;
namespace StellaOps.Cryptography.Tests;
public sealed class DefaultCryptoHashTests
{
private static readonly byte[] Sample = Encoding.UTF8.GetBytes("The quick brown fox jumps over the lazy dog");
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void ComputeHash_Sha256_MatchesBcl()
{
var hash = CryptoHashFactory.CreateDefault();
@@ -23,7 +26,8 @@ public sealed class DefaultCryptoHashTests
Assert.Equal(Convert.ToHexStringLower(expected), Convert.ToHexStringLower(actual));
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void ComputeHash_Sha512_MatchesBcl()
{
var hash = CryptoHashFactory.CreateDefault();
@@ -32,7 +36,8 @@ public sealed class DefaultCryptoHashTests
Assert.Equal(Convert.ToHexStringLower(expected), Convert.ToHexStringLower(actual));
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void ComputeHash_Gost256_MatchesBouncyCastle()
{
var hash = CryptoHashFactory.CreateDefault();
@@ -41,7 +46,8 @@ public sealed class DefaultCryptoHashTests
Assert.Equal(Convert.ToHexStringLower(expected), Convert.ToHexStringLower(actual));
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void ComputeHash_Gost512_MatchesBouncyCastle()
{
var hash = CryptoHashFactory.CreateDefault();
@@ -50,7 +56,8 @@ public sealed class DefaultCryptoHashTests
Assert.Equal(Convert.ToHexStringLower(expected), Convert.ToHexStringLower(actual));
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task ComputeHashAsync_Stream_MatchesBuffer()
{
var hash = CryptoHashFactory.CreateDefault();
@@ -60,7 +67,8 @@ public sealed class DefaultCryptoHashTests
Assert.Equal(Convert.ToHexString(bufferDigest), Convert.ToHexString(streamDigest));
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void ComputeHashHex_Sha256_MatchesBclLowerHex()
{
var hash = CryptoHashFactory.CreateDefault();
@@ -69,7 +77,8 @@ public sealed class DefaultCryptoHashTests
Assert.Equal(expected, actual);
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task ComputeHashHexAsync_Sha256_MatchesBclLowerHex()
{
var hash = CryptoHashFactory.CreateDefault();

View File

@@ -6,6 +6,8 @@ using System.Threading.Tasks;
using StellaOps.Cryptography;
using Xunit;
using StellaOps.TestKit;
namespace StellaOps.Cryptography.Tests;
public sealed class DefaultCryptoHmacTests
@@ -13,7 +15,8 @@ public sealed class DefaultCryptoHmacTests
private static readonly byte[] Sample = Encoding.UTF8.GetBytes("The quick brown fox jumps over the lazy dog");
private static readonly byte[] Key = Encoding.UTF8.GetBytes("test-key");
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void ComputeHmacHexForPurpose_WebhookInterop_MatchesBclLowerHex()
{
var hmac = DefaultCryptoHmac.CreateForTests();
@@ -22,7 +25,8 @@ public sealed class DefaultCryptoHmacTests
Assert.Equal(expected, actual);
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task ComputeHmacHexForPurposeAsync_WebhookInterop_MatchesBclLowerHex()
{
var hmac = DefaultCryptoHmac.CreateForTests();

View File

@@ -7,11 +7,14 @@ using Microsoft.IdentityModel.Tokens;
using StellaOps.Cryptography;
using Xunit;
using StellaOps.TestKit;
namespace StellaOps.Cryptography.Tests;
public class DefaultCryptoProviderSigningTests
{
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task UpsertSigningKey_AllowsSignAndVerifyEs256()
{
var provider = new DefaultCryptoProvider();
@@ -52,7 +55,8 @@ public class DefaultCryptoProviderSigningTests
Assert.False(tamperedResult);
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void RemoveSigningKey_PreventsRetrieval()
{
var provider = new DefaultCryptoProvider();

View File

@@ -5,11 +5,13 @@ using System.Security.Cryptography;
using StellaOps.Cryptography.Plugin.CryptoPro;
using Xunit;
using StellaOps.TestKit;
namespace StellaOps.Cryptography.Tests;
public class GostSignatureEncodingTests
{
[Theory]
[Trait("Category", TestCategories.Unit)]
[Theory]
[InlineData(32)]
[InlineData(64)]
public void RawAndDer_RoundTrip(int coordinateLength)
@@ -25,14 +27,16 @@ public class GostSignatureEncodingTests
Assert.Equal(raw, roundTrip);
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void ToDer_Throws_When_Length_Invalid()
{
var raw = new byte[10];
Assert.Throws<CryptographicException>(() => GostSignatureEncoding.ToDer(raw, coordinateLength: 32));
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void ToRaw_Throws_When_Not_Der()
{
var raw = new byte[64];

View File

@@ -5,11 +5,14 @@ using System.Text;
using System.Threading.Tasks;
using Xunit;
using StellaOps.TestKit;
namespace StellaOps.Cryptography.Tests;
public class LibsodiumCryptoProviderTests
{
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task LibsodiumProvider_SignsAndVerifiesEs256()
{
var provider = new LibsodiumCryptoProvider();

View File

@@ -3,6 +3,7 @@ using StellaOps.Cryptography;
using StellaOps.Cryptography.Plugin.OfflineVerification;
using Xunit;
using StellaOps.TestKit;
namespace StellaOps.Cryptography.Tests;
public sealed class OfflineVerificationCryptoProviderTests
@@ -14,7 +15,8 @@ public sealed class OfflineVerificationCryptoProviderTests
_provider = new OfflineVerificationCryptoProvider();
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void Name_ReturnsOfflineVerification()
{
// Act
@@ -24,7 +26,8 @@ public sealed class OfflineVerificationCryptoProviderTests
name.Should().Be("offline-verification");
}
[Theory]
[Trait("Category", TestCategories.Unit)]
[Theory]
[InlineData("ES256")]
[InlineData("ES384")]
[InlineData("ES512")]
@@ -43,7 +46,8 @@ public sealed class OfflineVerificationCryptoProviderTests
supports.Should().BeTrue($"{algorithmId} should be supported for signing");
}
[Theory]
[Trait("Category", TestCategories.Unit)]
[Theory]
[InlineData("ES256")]
[InlineData("ES384")]
[InlineData("ES512")]
@@ -62,7 +66,8 @@ public sealed class OfflineVerificationCryptoProviderTests
supports.Should().BeTrue($"{algorithmId} should be supported for verification");
}
[Theory]
[Trait("Category", TestCategories.Unit)]
[Theory]
[InlineData("SHA-256")]
[InlineData("SHA-384")]
[InlineData("SHA-512")]
@@ -78,7 +83,8 @@ public sealed class OfflineVerificationCryptoProviderTests
supports.Should().BeTrue($"{algorithmId} should be supported for content hashing");
}
[Theory]
[Trait("Category", TestCategories.Unit)]
[Theory]
[InlineData("PBKDF2")]
[InlineData("Argon2id")]
public void Supports_PasswordHashingAlgorithms_ReturnsTrue(string algorithmId)
@@ -90,7 +96,8 @@ public sealed class OfflineVerificationCryptoProviderTests
supports.Should().BeTrue($"{algorithmId} should be reported as supported for password hashing");
}
[Theory]
[Trait("Category", TestCategories.Unit)]
[Theory]
[InlineData("ES256K")]
[InlineData("EdDSA")]
[InlineData("UNKNOWN")]
@@ -103,7 +110,8 @@ public sealed class OfflineVerificationCryptoProviderTests
supports.Should().BeFalse($"{algorithmId} should not be supported");
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void Supports_SymmetricEncryption_ReturnsFalse()
{
// Act
@@ -113,7 +121,8 @@ public sealed class OfflineVerificationCryptoProviderTests
supports.Should().BeFalse("Symmetric encryption should not be supported");
}
[Theory]
[Trait("Category", TestCategories.Unit)]
[Theory]
[InlineData("SHA-256")]
[InlineData("SHA-384")]
[InlineData("SHA-512")]
@@ -130,7 +139,8 @@ public sealed class OfflineVerificationCryptoProviderTests
hasher.AlgorithmId.Should().NotBeNullOrWhiteSpace();
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void GetHasher_UnsupportedAlgorithm_ThrowsNotSupportedException()
{
// Act
@@ -141,7 +151,8 @@ public sealed class OfflineVerificationCryptoProviderTests
.WithMessage("*MD5*");
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void GetHasher_SHA256_ComputesCorrectHash()
{
// Arrange
@@ -156,7 +167,8 @@ public sealed class OfflineVerificationCryptoProviderTests
hash.Length.Should().Be(32); // SHA-256 produces 32 bytes
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void GetHasher_SHA256_ProducesDeterministicOutput()
{
// Arrange
@@ -172,7 +184,8 @@ public sealed class OfflineVerificationCryptoProviderTests
hash1.Should().Equal(hash2, "Same data should produce same hash");
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void GetPasswordHasher_ThrowsNotSupportedException()
{
// Act
@@ -183,7 +196,8 @@ public sealed class OfflineVerificationCryptoProviderTests
.WithMessage("*not supported*");
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void GetSigner_UnsupportedAlgorithm_ThrowsNotSupportedException()
{
// Arrange
@@ -197,7 +211,8 @@ public sealed class OfflineVerificationCryptoProviderTests
.WithMessage("*UNKNOWN*");
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void CreateEphemeralVerifier_UnsupportedAlgorithm_ThrowsNotSupportedException()
{
// Arrange
@@ -211,7 +226,8 @@ public sealed class OfflineVerificationCryptoProviderTests
.WithMessage("*UNKNOWN*");
}
[Theory]
[Trait("Category", TestCategories.Unit)]
[Theory]
[InlineData("ES256")]
[InlineData("ES384")]
[InlineData("ES512")]

View File

@@ -11,11 +11,13 @@ using StellaOps.Cryptography;
using StellaOps.Cryptography.Plugin.OpenSslGost;
using Xunit;
using StellaOps.TestKit;
namespace StellaOps.Cryptography.Tests;
public class OpenSslGostSignerTests
{
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task SignAndVerify_WithManagedProvider_Succeeds()
{
var keyPair = GenerateKeyPair();

View File

@@ -1,17 +1,20 @@
using StellaOps.Cryptography;
using StellaOps.TestKit;
namespace StellaOps.Cryptography.Tests;
public class PasswordHashOptionsTests
{
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void Validate_DoesNotThrow_ForDefaults()
{
var options = new PasswordHashOptions();
options.Validate();
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void Validate_Throws_WhenMemoryInvalid()
{
var options = new PasswordHashOptions

View File

@@ -2,13 +2,15 @@ using System;
using StellaOps.Cryptography;
using Xunit;
using StellaOps.TestKit;
namespace StellaOps.Cryptography.Tests;
public class Pbkdf2PasswordHasherTests
{
private readonly Pbkdf2PasswordHasher hasher = new();
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void Hash_ProducesLegacyFormat()
{
var options = new PasswordHashOptions
@@ -22,7 +24,8 @@ public class Pbkdf2PasswordHasherTests
Assert.StartsWith("PBKDF2.", encoded, StringComparison.Ordinal);
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void Verify_Succeeds_ForCorrectPassword()
{
var options = new PasswordHashOptions
@@ -37,7 +40,8 @@ public class Pbkdf2PasswordHasherTests
Assert.False(hasher.Verify("other", encoded));
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void NeedsRehash_DetectsIterationChange()
{
var options = new PasswordHashOptions

View File

@@ -7,11 +7,14 @@ using StellaOps.Cryptography;
using StellaOps.Cryptography.Plugin.Pkcs11Gost;
using Xunit;
using StellaOps.TestKit;
namespace StellaOps.Cryptography.Tests;
public class Pkcs11GostProviderTests
{
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void DescribeKeys_ExposesLibraryPathAndThumbprint()
{
if (!string.Equals(Environment.GetEnvironmentVariable("STELLAOPS_PKCS11_ENABLED"), "1", StringComparison.Ordinal))

View File

@@ -4,18 +4,21 @@ using StellaOps.Cryptography;
using StellaOps.Cryptography.Digests;
using Xunit;
using StellaOps.TestKit;
namespace StellaOps.Cryptography.Tests;
public sealed class Sha256DigestTests
{
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void Normalize_AllowsBareHex_WhenPrefixNotRequired()
{
var hex = new string('a', Sha256Digest.HexLength);
Assert.Equal($"sha256:{hex}", Sha256Digest.Normalize(hex));
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void Normalize_NormalizesPrefixAndHexToLower()
{
var hexUpper = new string('A', Sha256Digest.HexLength);
@@ -24,7 +27,8 @@ public sealed class Sha256DigestTests
Sha256Digest.Normalize($"SHA256:{hexUpper}"));
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void Normalize_RequiresPrefix_WhenConfigured()
{
var hex = new string('a', Sha256Digest.HexLength);
@@ -33,14 +37,16 @@ public sealed class Sha256DigestTests
Assert.Contains("sha256:", ex.Message, StringComparison.Ordinal);
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void ExtractHex_ReturnsLowercaseHex()
{
var hexUpper = new string('A', Sha256Digest.HexLength);
Assert.Equal(new string('a', Sha256Digest.HexLength), Sha256Digest.ExtractHex($"sha256:{hexUpper}"));
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void Compute_UsesCryptoHashStack()
{
var hash = CryptoHashFactory.CreateDefault();

View File

@@ -13,6 +13,7 @@ using StellaOps.Cryptography;
using StellaOps.Cryptography.Plugin.SmSoft;
using Xunit;
using StellaOps.TestKit;
namespace StellaOps.Cryptography.Tests;
public class SmSoftCryptoProviderTests : IDisposable
@@ -25,7 +26,8 @@ public class SmSoftCryptoProviderTests : IDisposable
Environment.SetEnvironmentVariable("SM_SOFT_ALLOWED", "1");
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task SignAndVerify_Sm2_Works()
{
var provider = new SmSoftCryptoProvider();
@@ -47,7 +49,8 @@ public class SmSoftCryptoProviderTests : IDisposable
Assert.False(string.IsNullOrEmpty(jwk.Y));
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void Hash_Sm3_Works()
{
var provider = new SmSoftCryptoProvider();

View File

@@ -21,5 +21,6 @@
<ProjectReference Include="..\..\StellaOps.Cryptography.Plugin.OfflineVerification\StellaOps.Cryptography.Plugin.OfflineVerification.csproj" />
<ProjectReference Include="..\..\StellaOps.Cryptography.Plugin.OpenSslGost\StellaOps.Cryptography.Plugin.OpenSslGost.csproj" />
<ProjectReference Include="..\..\StellaOps.Cryptography.Plugin.SmSoft\StellaOps.Cryptography.Plugin.SmSoft.csproj" />
<ProjectReference Include="../../StellaOps.TestKit/StellaOps.TestKit.csproj" />
</ItemGroup>
</Project>