using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using Tiku.Infrastructure.Security; namespace Tiku.UnitTests.Security; public sealed class DataProtectionKeyRingOptionsTests { [Fact] public void Development_allows_an_unencrypted_key_ring() { var options = new DataProtectionKeyRingOptions(); Assert.True(DataProtectionKeyRingOptions.BeValid(options, requireCertificate: false)); Assert.Null(options.LoadCertificate(requireCertificate: false)); } [Fact] public void Production_requires_a_certificate_path() { var options = new DataProtectionKeyRingOptions(); Assert.False(DataProtectionKeyRingOptions.BeValid(options, requireCertificate: true)); var exception = Assert.Throws(() => options.LoadCertificate(requireCertificate: true)); Assert.Contains("required outside Development", exception.Message, StringComparison.Ordinal); } [Fact] public void Application_name_is_always_required() { var options = new DataProtectionKeyRingOptions { ApplicationName = " ", CertificatePath = "/configured/key-ring.pfx" }; Assert.False(DataProtectionKeyRingOptions.BeValid(options, requireCertificate: false)); Assert.False(DataProtectionKeyRingOptions.BeValid(options, requireCertificate: true)); } [Fact] public void Configured_certificate_file_must_be_loadable() { var options = new DataProtectionKeyRingOptions { CertificatePath = Path.Combine( Path.GetTempPath(), $"missing-data-protection-{Guid.NewGuid():N}.pfx") }; Assert.True(DataProtectionKeyRingOptions.BeValid(options, requireCertificate: true)); var exception = Assert.Throws(() => options.LoadCertificate(requireCertificate: true)); Assert.Contains("could not be loaded", exception.Message, StringComparison.Ordinal); } [Fact] public void Password_protected_pkcs12_certificate_with_private_key_is_loaded() { const string password = "unit-test-certificate-password"; var certificatePath = Path.Combine( Path.GetTempPath(), $"data-protection-{Guid.NewGuid():N}.pfx"); try { using var rsa = RSA.Create(2048); var request = new CertificateRequest( "CN=Tiku Data Protection Unit Test", rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); using var certificate = request.CreateSelfSigned( DateTimeOffset.UtcNow.AddMinutes(-1), DateTimeOffset.UtcNow.AddDays(1)); File.WriteAllBytes(certificatePath, certificate.Export(X509ContentType.Pfx, password)); var options = new DataProtectionKeyRingOptions { CertificatePath = certificatePath, CertificatePassword = password }; using var loaded = options.LoadCertificate(requireCertificate: true); Assert.NotNull(loaded); Assert.True(loaded.HasPrivateKey); } finally { File.Delete(certificatePath); } } }