Add unit tests for RabbitMq and Udp transport servers and clients
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
- Implemented comprehensive unit tests for RabbitMqTransportServer, covering constructor, disposal, connection management, event handlers, and exception handling. - Added configuration tests for RabbitMqTransportServer to validate SSL, durable queues, auto-recovery, and custom virtual host options. - Created unit tests for UdpFrameProtocol, including frame parsing and serialization, header size validation, and round-trip data preservation. - Developed tests for UdpTransportClient, focusing on connection handling, event subscriptions, and exception scenarios. - Established tests for UdpTransportServer, ensuring proper start/stop behavior, connection state management, and event handling. - Included tests for UdpTransportOptions to verify default values and modification capabilities. - Enhanced service registration tests for Udp transport services in the dependency injection container.
This commit is contained in:
252
src/__Libraries/StellaOps.Cryptography/ComplianceProfiles.cs
Normal file
252
src/__Libraries/StellaOps.Cryptography/ComplianceProfiles.cs
Normal file
@@ -0,0 +1,252 @@
|
||||
namespace StellaOps.Cryptography;
|
||||
|
||||
/// <summary>
|
||||
/// Built-in compliance profiles for different jurisdictional crypto requirements.
|
||||
/// </summary>
|
||||
public static class ComplianceProfiles
|
||||
{
|
||||
/// <summary>
|
||||
/// Default/World profile using BLAKE3 for graph hashing, SHA-256 for everything else.
|
||||
/// Suitable for international deployments without specific compliance requirements.
|
||||
/// </summary>
|
||||
public static readonly ComplianceProfile World = new()
|
||||
{
|
||||
ProfileId = "world",
|
||||
StandardName = "ISO/Default",
|
||||
Description = "Default profile using BLAKE3 for graph content-addressing, SHA-256 for symbol/content hashing.",
|
||||
PurposeAlgorithms = new Dictionary<string, string>
|
||||
{
|
||||
[HashPurpose.Graph] = HashAlgorithms.Blake3_256,
|
||||
[HashPurpose.Symbol] = HashAlgorithms.Sha256,
|
||||
[HashPurpose.Content] = HashAlgorithms.Sha256,
|
||||
[HashPurpose.Merkle] = HashAlgorithms.Sha256,
|
||||
[HashPurpose.Attestation] = HashAlgorithms.Sha256,
|
||||
[HashPurpose.Interop] = HashAlgorithms.Sha256,
|
||||
[HashPurpose.Secret] = PasswordHashAlgorithms.Argon2id,
|
||||
},
|
||||
HashPrefixes = new Dictionary<string, string>
|
||||
{
|
||||
[HashPurpose.Graph] = "blake3:",
|
||||
[HashPurpose.Symbol] = "sha256:",
|
||||
[HashPurpose.Content] = "sha256:",
|
||||
[HashPurpose.Merkle] = "sha256:",
|
||||
[HashPurpose.Attestation] = "sha256:",
|
||||
[HashPurpose.Interop] = "sha256:",
|
||||
[HashPurpose.Secret] = "argon2id:",
|
||||
},
|
||||
AllowInteropOverride = true,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// FIPS 140-3 (US Federal) compliance profile.
|
||||
/// Uses only FIPS-approved algorithms: SHA-256, SHA-384, SHA-512, PBKDF2.
|
||||
/// Note: BLAKE3 is not FIPS-approved, so SHA-256 is used for graph hashing.
|
||||
/// </summary>
|
||||
public static readonly ComplianceProfile Fips = new()
|
||||
{
|
||||
ProfileId = "fips",
|
||||
StandardName = "FIPS 140-3",
|
||||
Description = "US Federal Information Processing Standard 140-3. Uses only FIPS-approved algorithms.",
|
||||
PurposeAlgorithms = new Dictionary<string, string>
|
||||
{
|
||||
[HashPurpose.Graph] = HashAlgorithms.Sha256, // BLAKE3 not FIPS-approved
|
||||
[HashPurpose.Symbol] = HashAlgorithms.Sha256,
|
||||
[HashPurpose.Content] = HashAlgorithms.Sha256,
|
||||
[HashPurpose.Merkle] = HashAlgorithms.Sha256,
|
||||
[HashPurpose.Attestation] = HashAlgorithms.Sha256,
|
||||
[HashPurpose.Interop] = HashAlgorithms.Sha256,
|
||||
[HashPurpose.Secret] = PasswordHashAlgorithms.Pbkdf2Sha256,
|
||||
},
|
||||
HashPrefixes = new Dictionary<string, string>
|
||||
{
|
||||
[HashPurpose.Graph] = "sha256:",
|
||||
[HashPurpose.Symbol] = "sha256:",
|
||||
[HashPurpose.Content] = "sha256:",
|
||||
[HashPurpose.Merkle] = "sha256:",
|
||||
[HashPurpose.Attestation] = "sha256:",
|
||||
[HashPurpose.Interop] = "sha256:",
|
||||
[HashPurpose.Secret] = "pbkdf2:",
|
||||
},
|
||||
AllowInteropOverride = true,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// GOST R 34.11-2012 (Russian) compliance profile.
|
||||
/// Uses GOST Stribog hash for all purposes except Interop (which remains SHA-256 for external compatibility).
|
||||
/// </summary>
|
||||
public static readonly ComplianceProfile Gost = new()
|
||||
{
|
||||
ProfileId = "gost",
|
||||
StandardName = "GOST R 34.11-2012",
|
||||
Description = "Russian GOST R 34.11-2012 (Stribog) hash standard. Interop uses SHA-256 for external tool compatibility.",
|
||||
PurposeAlgorithms = new Dictionary<string, string>
|
||||
{
|
||||
[HashPurpose.Graph] = HashAlgorithms.Gost3411_2012_256,
|
||||
[HashPurpose.Symbol] = HashAlgorithms.Gost3411_2012_256,
|
||||
[HashPurpose.Content] = HashAlgorithms.Gost3411_2012_256,
|
||||
[HashPurpose.Merkle] = HashAlgorithms.Gost3411_2012_256,
|
||||
[HashPurpose.Attestation] = HashAlgorithms.Gost3411_2012_256,
|
||||
[HashPurpose.Interop] = HashAlgorithms.Sha256, // Override for external compatibility
|
||||
[HashPurpose.Secret] = PasswordHashAlgorithms.Argon2id,
|
||||
},
|
||||
HashPrefixes = new Dictionary<string, string>
|
||||
{
|
||||
[HashPurpose.Graph] = "gost3411:",
|
||||
[HashPurpose.Symbol] = "gost3411:",
|
||||
[HashPurpose.Content] = "gost3411:",
|
||||
[HashPurpose.Merkle] = "gost3411:",
|
||||
[HashPurpose.Attestation] = "gost3411:",
|
||||
[HashPurpose.Interop] = "sha256:",
|
||||
[HashPurpose.Secret] = "argon2id:",
|
||||
},
|
||||
AllowInteropOverride = true,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// GB/T SM3 (Chinese) compliance profile.
|
||||
/// Uses SM3 hash for all purposes except Interop (which remains SHA-256 for external compatibility).
|
||||
/// </summary>
|
||||
public static readonly ComplianceProfile Sm = new()
|
||||
{
|
||||
ProfileId = "sm",
|
||||
StandardName = "GB/T (SM3)",
|
||||
Description = "Chinese GB/T 32905-2016 SM3 cryptographic hash standard. Interop uses SHA-256 for external tool compatibility.",
|
||||
PurposeAlgorithms = new Dictionary<string, string>
|
||||
{
|
||||
[HashPurpose.Graph] = HashAlgorithms.Sm3,
|
||||
[HashPurpose.Symbol] = HashAlgorithms.Sm3,
|
||||
[HashPurpose.Content] = HashAlgorithms.Sm3,
|
||||
[HashPurpose.Merkle] = HashAlgorithms.Sm3,
|
||||
[HashPurpose.Attestation] = HashAlgorithms.Sm3,
|
||||
[HashPurpose.Interop] = HashAlgorithms.Sha256, // Override for external compatibility
|
||||
[HashPurpose.Secret] = PasswordHashAlgorithms.Argon2id,
|
||||
},
|
||||
HashPrefixes = new Dictionary<string, string>
|
||||
{
|
||||
[HashPurpose.Graph] = "sm3:",
|
||||
[HashPurpose.Symbol] = "sm3:",
|
||||
[HashPurpose.Content] = "sm3:",
|
||||
[HashPurpose.Merkle] = "sm3:",
|
||||
[HashPurpose.Attestation] = "sm3:",
|
||||
[HashPurpose.Interop] = "sha256:",
|
||||
[HashPurpose.Secret] = "argon2id:",
|
||||
},
|
||||
AllowInteropOverride = true,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// KCMVP (Korea Cryptographic Module Validation Program) compliance profile.
|
||||
/// Uses SHA-256 for hashing. Note: ARIA/SEED/LEA are for encryption, KCDSA for signatures.
|
||||
/// </summary>
|
||||
public static readonly ComplianceProfile Kcmvp = new()
|
||||
{
|
||||
ProfileId = "kcmvp",
|
||||
StandardName = "KCMVP (Korea)",
|
||||
Description = "Korea Cryptographic Module Validation Program. Uses SHA-256 for hashing.",
|
||||
PurposeAlgorithms = new Dictionary<string, string>
|
||||
{
|
||||
[HashPurpose.Graph] = HashAlgorithms.Sha256,
|
||||
[HashPurpose.Symbol] = HashAlgorithms.Sha256,
|
||||
[HashPurpose.Content] = HashAlgorithms.Sha256,
|
||||
[HashPurpose.Merkle] = HashAlgorithms.Sha256,
|
||||
[HashPurpose.Attestation] = HashAlgorithms.Sha256,
|
||||
[HashPurpose.Interop] = HashAlgorithms.Sha256,
|
||||
[HashPurpose.Secret] = PasswordHashAlgorithms.Argon2id,
|
||||
},
|
||||
HashPrefixes = new Dictionary<string, string>
|
||||
{
|
||||
[HashPurpose.Graph] = "sha256:",
|
||||
[HashPurpose.Symbol] = "sha256:",
|
||||
[HashPurpose.Content] = "sha256:",
|
||||
[HashPurpose.Merkle] = "sha256:",
|
||||
[HashPurpose.Attestation] = "sha256:",
|
||||
[HashPurpose.Interop] = "sha256:",
|
||||
[HashPurpose.Secret] = "argon2id:",
|
||||
},
|
||||
AllowInteropOverride = true,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// eIDAS/ETSI TS 119 312 (European) compliance profile.
|
||||
/// Uses SHA-256 for hashing per ETSI cryptographic suites specification.
|
||||
/// </summary>
|
||||
public static readonly ComplianceProfile Eidas = new()
|
||||
{
|
||||
ProfileId = "eidas",
|
||||
StandardName = "eIDAS/ETSI TS 119 312",
|
||||
Description = "European eIDAS regulation with ETSI TS 119 312 cryptographic suites. Uses SHA-256/384 for hashing.",
|
||||
PurposeAlgorithms = new Dictionary<string, string>
|
||||
{
|
||||
[HashPurpose.Graph] = HashAlgorithms.Sha256,
|
||||
[HashPurpose.Symbol] = HashAlgorithms.Sha256,
|
||||
[HashPurpose.Content] = HashAlgorithms.Sha256,
|
||||
[HashPurpose.Merkle] = HashAlgorithms.Sha256,
|
||||
[HashPurpose.Attestation] = HashAlgorithms.Sha256,
|
||||
[HashPurpose.Interop] = HashAlgorithms.Sha256,
|
||||
[HashPurpose.Secret] = PasswordHashAlgorithms.Argon2id,
|
||||
},
|
||||
HashPrefixes = new Dictionary<string, string>
|
||||
{
|
||||
[HashPurpose.Graph] = "sha256:",
|
||||
[HashPurpose.Symbol] = "sha256:",
|
||||
[HashPurpose.Content] = "sha256:",
|
||||
[HashPurpose.Merkle] = "sha256:",
|
||||
[HashPurpose.Attestation] = "sha256:",
|
||||
[HashPurpose.Interop] = "sha256:",
|
||||
[HashPurpose.Secret] = "argon2id:",
|
||||
},
|
||||
AllowInteropOverride = true,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// All built-in profiles indexed by profile ID.
|
||||
/// </summary>
|
||||
public static readonly IReadOnlyDictionary<string, ComplianceProfile> All =
|
||||
new Dictionary<string, ComplianceProfile>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
[World.ProfileId] = World,
|
||||
[Fips.ProfileId] = Fips,
|
||||
[Gost.ProfileId] = Gost,
|
||||
[Sm.ProfileId] = Sm,
|
||||
[Kcmvp.ProfileId] = Kcmvp,
|
||||
[Eidas.ProfileId] = Eidas,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Gets a profile by ID, returning the World profile if not found.
|
||||
/// </summary>
|
||||
/// <param name="profileId">The profile ID to look up.</param>
|
||||
/// <returns>The matching profile, or World if not found.</returns>
|
||||
public static ComplianceProfile GetProfile(string? profileId)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(profileId))
|
||||
{
|
||||
return World;
|
||||
}
|
||||
|
||||
return All.TryGetValue(profileId, out var profile) ? profile : World;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a profile by ID, throwing if not found.
|
||||
/// </summary>
|
||||
/// <param name="profileId">The profile ID to look up.</param>
|
||||
/// <returns>The matching profile.</returns>
|
||||
/// <exception cref="ArgumentException">Thrown when the profile ID is not found.</exception>
|
||||
public static ComplianceProfile GetProfileOrThrow(string profileId)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(profileId))
|
||||
{
|
||||
throw new ArgumentException("Profile ID cannot be null or empty.", nameof(profileId));
|
||||
}
|
||||
|
||||
if (!All.TryGetValue(profileId, out var profile))
|
||||
{
|
||||
throw new ArgumentException(
|
||||
$"Unknown compliance profile '{profileId}'. Valid profiles: {string.Join(", ", All.Keys)}",
|
||||
nameof(profileId));
|
||||
}
|
||||
|
||||
return profile;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user