diff --git a/src/Servers/Kestrel/Core/src/Internal/Certificates/CertificateConfigLoader.cs b/src/Servers/Kestrel/Core/src/Internal/Certificates/CertificateConfigLoader.cs index d0239122fcde..b74353fe8246 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Certificates/CertificateConfigLoader.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Certificates/CertificateConfigLoader.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; @@ -96,6 +97,23 @@ private static X509Certificate2 LoadCertificateKey(X509Certificate2 certificate, const string DSAOid = "1.2.840.10040.4.1"; const string ECDsaOid = "1.2.840.10045.2.1"; + const string MLDsa44Oid = "2.16.840.1.101.3.4.3.17"; + const string MLDsa65Oid = "2.16.840.1.101.3.4.3.18"; + const string MLDsa87Oid = "2.16.840.1.101.3.4.3.19"; + + const string SlhDsaSha2_128sOid = "2.16.840.1.101.3.4.3.20"; + const string SlhDsaSha2_128fOid = "2.16.840.1.101.3.4.3.21"; + const string SlhDsaSha2_192sOid = "2.16.840.1.101.3.4.3.22"; + const string SlhDsaSha2_192fOid = "2.16.840.1.101.3.4.3.23"; + const string SlhDsaSha2_256sOid = "2.16.840.1.101.3.4.3.24"; + const string SlhDsaSha2_256fOid = "2.16.840.1.101.3.4.3.25"; + const string SlhDsaShake_128sOid = "2.16.840.1.101.3.4.3.26"; + const string SlhDsaShake_128fOid = "2.16.840.1.101.3.4.3.27"; + const string SlhDsaShake_192sOid = "2.16.840.1.101.3.4.3.28"; + const string SlhDsaShake_192fOid = "2.16.840.1.101.3.4.3.29"; + const string SlhDsaShake_256sOid = "2.16.840.1.101.3.4.3.30"; + const string SlhDsaShake_256fOid = "2.16.840.1.101.3.4.3.31"; + // Duplication is required here because there are separate CopyWithPrivateKey methods for each algorithm. var keyText = File.ReadAllText(keyPath); switch (certificate.PublicKey.Oid.Value) @@ -142,6 +160,47 @@ private static X509Certificate2 LoadCertificateKey(X509Certificate2 certificate, throw CreateErrorGettingPrivateKeyException(keyPath, ex); } } + case MLDsa44Oid: + case MLDsa65Oid: + case MLDsa87Oid: + { +#pragma warning disable SYSLIB5006 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + using var mlDsa = ImportMLDsaKeyFromFile(keyText, password); + + try + { + return certificate.CopyWithPrivateKey(mlDsa); + } + catch (Exception ex) + { + throw CreateErrorGettingPrivateKeyException(keyPath, ex); + } + } + case SlhDsaSha2_128sOid: + case SlhDsaSha2_128fOid: + case SlhDsaSha2_192sOid: + case SlhDsaSha2_192fOid: + case SlhDsaSha2_256sOid: + case SlhDsaSha2_256fOid: + case SlhDsaShake_128sOid: + case SlhDsaShake_128fOid: + case SlhDsaShake_192sOid: + case SlhDsaShake_192fOid: + case SlhDsaShake_256sOid: + case SlhDsaShake_256fOid: + { + using var slhDsa = ImportSlhDsaKeyFromFile(keyText, password); + + try + { + return certificate.CopyWithPrivateKey(slhDsa); + } + catch (Exception ex) + { + throw CreateErrorGettingPrivateKeyException(keyPath, ex); + } + } +#pragma warning restore SYSLIB5006 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. default: throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, CoreStrings.UnrecognizedCertificateKeyOid, certificate.PublicKey.Oid.Value)); } @@ -174,6 +233,32 @@ private static void ImportKeyFromFile(AsymmetricAlgorithm asymmetricAlgorithm, s } } + [Experimental("SYSLIB5006")] + private static MLDsa ImportMLDsaKeyFromFile(string keyText, string? password) + { + if (password == null) + { + return MLDsa.ImportFromPem(keyText); + } + else + { + return MLDsa.ImportFromEncryptedPem(keyText, password); + } + } + + [Experimental("SYSLIB5006")] + private static SlhDsa ImportSlhDsaKeyFromFile(string keyText, string? password) + { + if (password == null) + { + return SlhDsa.ImportFromPem(keyText); + } + else + { + return SlhDsa.ImportFromEncryptedPem(keyText, password); + } + } + private static X509Certificate2 LoadFromStoreCert(CertificateConfig certInfo) { var subject = certInfo.Subject!; diff --git a/src/Servers/Kestrel/Kestrel/test/KestrelConfigurationLoaderTests.cs b/src/Servers/Kestrel/Kestrel/test/KestrelConfigurationLoaderTests.cs index b4a55423038b..02f18df74672 100644 --- a/src/Servers/Kestrel/Kestrel/test/KestrelConfigurationLoaderTests.cs +++ b/src/Servers/Kestrel/Kestrel/test/KestrelConfigurationLoaderTests.cs @@ -683,46 +683,275 @@ public void ConfigureEndpoint_ThrowsWhen_The_KeyIsPublic() Assert.IsAssignableFrom(ex.InnerException); } + public static TheoryData GetPemCertificateTestData() + { + var data = new TheoryData(); + List algorithms = [ + "RSA", + "ECDsa", + "DSA", + ]; + +#pragma warning disable SYSLIB5006 + if (MLDsa.IsSupported) + { + algorithms.AddRange([ + "MLDsa44", + "MLDsa65", + "MLDsa87", + ]); + } + + if (SlhDsa.IsSupported) + { + algorithms.AddRange([ + "SlhDsaSha2_128s", + "SlhDsaSha2_128f", + "SlhDsaSha2_192s", + "SlhDsaSha2_192f", + "SlhDsaSha2_256s", + "SlhDsaSha2_256f", + "SlhDsaShake_128s", + "SlhDsaShake_128f", + "SlhDsaShake_192s", + "SlhDsaShake_192f", + "SlhDsaShake_256s", + "SlhDsaShake_256f" + ]); + } +#pragma warning restore SYSLIB5006 + + foreach (var algorithm in algorithms) + { + // Test with no password + data.Add(algorithm, null, ".pem"); + data.Add(algorithm, null, ".crt"); + + // Test with password + data.Add(algorithm, "test", ".pem"); + data.Add(algorithm, "test", ".crt"); + } + + return data; + } + [Theory] - [InlineData("https-rsa.pem", "https-rsa.key", null)] - [InlineData("https-rsa.pem", "https-rsa-protected.key", "aspnetcore")] - [InlineData("https-rsa.crt", "https-rsa.key", null)] - [InlineData("https-rsa.crt", "https-rsa-protected.key", "aspnetcore")] - [InlineData("https-ecdsa.pem", "https-ecdsa.key", null)] - [InlineData("https-ecdsa.pem", "https-ecdsa-protected.key", "aspnetcore")] - [InlineData("https-ecdsa.crt", "https-ecdsa.key", null)] - [InlineData("https-ecdsa.crt", "https-ecdsa-protected.key", "aspnetcore")] - [InlineData("https-dsa.pem", "https-dsa.key", null)] - [InlineData("https-dsa.pem", "https-dsa-protected.key", "test")] - [InlineData("https-dsa.crt", "https-dsa.key", null)] - [InlineData("https-dsa.crt", "https-dsa-protected.key", "test")] - public void ConfigureEndpoint_CanLoadPemCertificates(string certificateFile, string certificateKey, string password) + [MemberData(nameof(GetPemCertificateTestData))] + public void ConfigureEndpoint_CanLoadPemCertificates(string algorithmType, string keyPassword, string extension) { var serverOptions = CreateServerOptions(); - var certificate = new X509Certificate2(TestResources.GetCertPath(Path.ChangeExtension(certificateFile, "crt"))); + X509Certificate2 certificate; + string certificateFilePath; + string certificateKeyPath; + string tempDir = null; - var ran1 = false; - var config = new ConfigurationBuilder().AddInMemoryCollection(new[] + // For DSA, we rely on a pre-generated certificate since CertificateRequest APIs don't directly + // support DSA keys. + if (algorithmType == "DSA") { - new KeyValuePair("Endpoints:End1:Url", "https://*:5001"), - new KeyValuePair("Certificates:Default:Path", Path.Combine("shared", "TestCertificates", certificateFile)), - new KeyValuePair("Certificates:Default:KeyPath", Path.Combine("shared", "TestCertificates", certificateKey)), + var baseName = keyPassword == null ? "https-dsa" : "https-dsa"; + var keyName = keyPassword == null ? "https-dsa.key" : "https-dsa-protected.key"; + + certificate = new X509Certificate2(TestResources.GetCertPath("https-dsa.crt")); + certificateFilePath = TestResources.GetCertPath(baseName + extension); + certificateKeyPath = TestResources.GetCertPath(keyName); + } + else + { + // For all other algorithms, we generate the certificate and key dynamically, saving them + // in a temporary directory. + tempDir = Directory.CreateTempSubdirectory().FullName; + try + { + certificateFilePath = Path.Combine(tempDir, $"test{extension}"); + certificateKeyPath = Path.Combine(tempDir, "test.key"); + certificate = GenerateTestCertificateWithAlgorithm(algorithmType, keyPassword, certificateFilePath, certificateKeyPath); + } + catch + { + if (Directory.Exists(tempDir)) + { + Directory.Delete(tempDir, recursive: true); + } + throw; + } } - .Concat(password != null ? new[] { new KeyValuePair("Certificates:Default:Password", password) } : Array.Empty>())) - .Build(); - serverOptions - .Configure(config) - .Endpoint("End1", opt => + try + { + var ran1 = false; + var config = new ConfigurationBuilder().AddInMemoryCollection(new[] { - ran1 = true; - Assert.True(opt.IsHttps); - Assert.Equal(opt.HttpsOptions.ServerCertificate.SerialNumber, certificate.SerialNumber); - }).Load(); + new KeyValuePair("Endpoints:End1:Url", "https://*:5001"), + new KeyValuePair("Certificates:Default:Path", certificateFilePath), + new KeyValuePair("Certificates:Default:KeyPath", certificateKeyPath), + } + .Concat(keyPassword != null ? [new KeyValuePair("Certificates:Default:Password", keyPassword)] : Array.Empty>())) + .Build(); - Assert.True(ran1); - Assert.Null(serverOptions.DevelopmentCertificate); // Not used since configuration cert is present + serverOptions + .Configure(config) + .Endpoint("End1", opt => + { + ran1 = true; + Assert.True(opt.IsHttps); + Assert.Equal(certificate.SerialNumber, opt.HttpsOptions.ServerCertificate.SerialNumber); + }).Load(); + + Assert.True(ran1); + Assert.Null(serverOptions.DevelopmentCertificate); // Not used since configuration cert is present + } + finally + { + // Clean up generated certificate directory if it exists. + if (tempDir is not null && Directory.Exists(tempDir)) + { + Directory.Delete(tempDir, recursive: true); + } + } + } + + private static X509Certificate2 GenerateTestCertificateWithAlgorithm(string algorithmType, string keyPassword, string certificatePath, string keyPath) + { + var distinguishedName = new X500DistinguishedName($"CN=test.{algorithmType}.local"); + var sanBuilder = new SubjectAlternativeNameBuilder(); + sanBuilder.AddDnsName($"test.{algorithmType}.local"); + + X509Certificate2 certificate; + string keyPem; + + switch (algorithmType) + { + case "RSA": + using (var rsa = RSA.Create(2048)) + { + var request = new CertificateRequest(distinguishedName, rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); + certificate = CreateTestCertificate(request, sanBuilder); + keyPem = ExportKeyToPem(rsa, keyPassword); + } + break; + + case "ECDsa": + using (var ecdsa = ECDsa.Create(ECCurve.NamedCurves.nistP256)) + { + var request = new CertificateRequest(distinguishedName, ecdsa, HashAlgorithmName.SHA256); + certificate = CreateTestCertificate(request, sanBuilder); + keyPem = ExportKeyToPem(ecdsa, keyPassword); + } + break; + + case "MLDsa44": + case "MLDsa65": + case "MLDsa87": +#pragma warning disable SYSLIB5006 + var mlDsaAlgorithm = algorithmType switch + { + "MLDsa44" => MLDsaAlgorithm.MLDsa44, + "MLDsa65" => MLDsaAlgorithm.MLDsa65, + "MLDsa87" => MLDsaAlgorithm.MLDsa87, + _ => throw new ArgumentException($"Unknown ML-DSA variant: {algorithmType}") + }; + using (var mlDsa = MLDsa.GenerateKey(mlDsaAlgorithm)) + { + var request = new CertificateRequest(distinguishedName, mlDsa); + certificate = CreateTestCertificate(request, sanBuilder); + keyPem = ExportMLDsaKeyToPem(mlDsa, keyPassword); + } +#pragma warning restore SYSLIB5006 + break; + + case "SlhDsaSha2_128s": + case "SlhDsaSha2_128f": + case "SlhDsaSha2_192s": + case "SlhDsaSha2_192f": + case "SlhDsaSha2_256s": + case "SlhDsaSha2_256f": + case "SlhDsaShake_128s": + case "SlhDsaShake_128f": + case "SlhDsaShake_192s": + case "SlhDsaShake_192f": + case "SlhDsaShake_256s": + case "SlhDsaShake_256f": +#pragma warning disable SYSLIB5006 + var slhDsaAlgorithm = algorithmType switch + { + "SlhDsaSha2_128s" => SlhDsaAlgorithm.SlhDsaSha2_128s, + "SlhDsaSha2_128f" => SlhDsaAlgorithm.SlhDsaSha2_128f, + "SlhDsaSha2_192s" => SlhDsaAlgorithm.SlhDsaSha2_192s, + "SlhDsaSha2_192f" => SlhDsaAlgorithm.SlhDsaSha2_192f, + "SlhDsaSha2_256s" => SlhDsaAlgorithm.SlhDsaSha2_256s, + "SlhDsaSha2_256f" => SlhDsaAlgorithm.SlhDsaSha2_256f, + "SlhDsaShake_128s" => SlhDsaAlgorithm.SlhDsaShake128s, + "SlhDsaShake_128f" => SlhDsaAlgorithm.SlhDsaShake128f, + "SlhDsaShake_192s" => SlhDsaAlgorithm.SlhDsaShake192s, + "SlhDsaShake_192f" => SlhDsaAlgorithm.SlhDsaShake192f, + "SlhDsaShake_256s" => SlhDsaAlgorithm.SlhDsaShake256s, + "SlhDsaShake_256f" => SlhDsaAlgorithm.SlhDsaShake256f, + _ => throw new ArgumentException($"Unknown SLH-DSA variant: {algorithmType}") + }; + using (var slhDsa = SlhDsa.GenerateKey(slhDsaAlgorithm)) + { + var request = new CertificateRequest(distinguishedName, slhDsa); + certificate = CreateTestCertificate(request, sanBuilder); + keyPem = ExportSlhDsaKeyToPem(slhDsa, keyPassword); + } +#pragma warning restore SYSLIB5006 + break; + + default: + throw new ArgumentException($"Unknown algorithm type: {algorithmType}"); + } + + if (certificatePath.EndsWith(".pem", StringComparison.OrdinalIgnoreCase)) + { + // Export the certificate in PEM format + File.WriteAllText(certificatePath, certificate.ExportCertificatePem()); + } + else + { + // Export the certificate in DER format + File.WriteAllBytes(certificatePath, certificate.Export(X509ContentType.Cert)); + } + + File.WriteAllText(keyPath, keyPem); + + return certificate; + } + + private static X509Certificate2 CreateTestCertificate(CertificateRequest request, SubjectAlternativeNameBuilder sanBuilder) + { + request.CertificateExtensions.Add(sanBuilder.Build()); + request.CertificateExtensions.Add(new X509KeyUsageExtension(X509KeyUsageFlags.DigitalSignature | X509KeyUsageFlags.KeyEncipherment, critical: true)); + request.CertificateExtensions.Add(new X509EnhancedKeyUsageExtension([new Oid("1.3.6.1.5.5.7.3.1")], critical: false)); // Server Authentication + + var notBefore = DateTimeOffset.UtcNow.AddDays(-1); + var notAfter = DateTimeOffset.UtcNow.AddYears(1); + + return request.CreateSelfSigned(notBefore, notAfter); + } + + private static string ExportKeyToPem(AsymmetricAlgorithm key, string password) + { + return password is null + ? key.ExportPkcs8PrivateKeyPem() + : key.ExportEncryptedPkcs8PrivateKeyPem(password.AsSpan(), new PbeParameters(PbeEncryptionAlgorithm.Aes256Cbc, HashAlgorithmName.SHA256, 100_000)); + } + +#pragma warning disable SYSLIB5006 + private static string ExportMLDsaKeyToPem(MLDsa mlDsa, string password) + { + return password is null + ? mlDsa.ExportPkcs8PrivateKeyPem() + : mlDsa.ExportEncryptedPkcs8PrivateKeyPem(password.AsSpan(), new PbeParameters(PbeEncryptionAlgorithm.Aes256Cbc, HashAlgorithmName.SHA256, 100_000)); + } + + private static string ExportSlhDsaKeyToPem(SlhDsa slhDsa, string password) + { + return password is null + ? slhDsa.ExportPkcs8PrivateKeyPem() + : slhDsa.ExportEncryptedPkcs8PrivateKeyPem(password.AsSpan(), new PbeParameters(PbeEncryptionAlgorithm.Aes256Cbc, HashAlgorithmName.SHA256, 100_000)); } +#pragma warning restore SYSLIB5006 [Fact] public void ConfigureEndpointDevelopmentCertificateGetsIgnoredIfPasswordIsNotCorrect() diff --git a/src/Shared/TestCertificates/https-rsa-protected.key b/src/Shared/TestCertificates/https-rsa-protected.key deleted file mode 100644 index 34fba0f776de..000000000000 --- a/src/Shared/TestCertificates/https-rsa-protected.key +++ /dev/null @@ -1,30 +0,0 @@ ------BEGIN ENCRYPTED PRIVATE KEY----- -MIIFNjBgBgkqhkiG9w0BBQ0wUzAyBgkqhkiG9w0BBQwwJQQQ93oRxzJ5UoNOb/zN -x5cdsAIDAYagMAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBAuHsE18X/Z9ZVe -aBl7C55nBIIE0AABqjc9ERcLYNpCRpA6c/TFG62m4Mr9J4dU4g1WD07t7uLxZiRi -Pl0YOjCulljMsevAW5PlLxi4ffJ+I0/UB1WOfzEMhcj7o1qG0Uv55B7WRuWKw1Zr -jo0bDY5Man48ZjpqMMBdnWhyHdIDm+WD0OyN98mpsN6SCQMjvx91M+klrsp7LOMM -88HHS0RFVKGF9hYSy6rCwMJWf+7QGO2wXfq+MKvJ/bBgPGDLwN4phUCyocnR0swD -/XZNiiw0xIC8OxAKhc6BV4AJkjNs32THdBOCGY6B4P/9Zo5W29S3ja/hGsMQAA27 -QtIDg74HpX7TgIyqoc1oiLNIWW/+jUHSEYJsTPlg5VYWsXUfSHZpz8EJvKt2tyvt -vBGOCLDDZD4GVXhPigKG6zJSJeTe94/VlwPhNSEucKeaALdax5t3HvPNzWKFX57E -aC82/IxRrjgHmgsGSZdMi08HY6K9GAVBFpIGvXOGtRq7w8zO/KagAvSwAOLLtOs7 -iEuAQxD+cKLRT59c4E7r5W7BT+faq85ovqdXe5Edtl3cT81zsl27pZvQrcrTPbZe -4OeIdWxOmOnC/bXvRHNd9XuYadXXazBoFbe9yPwjqnflEh39CyvlOZXeaQXSdsEM -1IBhddRTorO/I8M/znu9glqIa5ya1NA+4ujmf4OnJLtsrlKQa65VPVTrFdeYuMr0 -VfOuuIye2OdyJ6jS0a1PYQm4bEEz6UR88dnmnhDx6i8/l2wW5+CArA/x8IBYboBM -NJpJY9bHpic1AhjnjnTtFz2s4uYPi5g9peBizarZn+6OJvgYqs4a8SI92dA3E2o4 -a/1j7xlLlgXnVRLBMibxqzjMt4Zt7Nj+BaN1owrB/q04AWS2M4TSQz+NYOZwNFxB -dzb+fysTLK5XNEYq6rSg+0i+EKZl8Jb/t4d8SLPVr/tdfDt9BtZ0nTgjvy1HWy1p -kQdm13XfK1/9KsePH/Jb6dvN/u6ubV+ZqI7Bc7VyTi0bKMdpH2K8/dtopNyDZ/P+ -/IsyyDYTorgJB/klSih/W0hqpSBbEAmlSBfBxP1/ozBEGR2oF20JOCFyD6UXQR/1 -V7r2KtplpyfXaIWh4fABitAMHz7VgmEIQ2H9cB4Ey9jdRPQ/1p+OgGjfaFJQ0uYM -987TDtjkuukJYnPZNIIx0Yv3iAX16XmhzJixWSMUIJiWfSiz0aTjBxsPQVPTQV+M -6BgFf3riBApZYlVVJsGIie2XTvu/tHRhfQrxccl63HN7yAeJheQnoscin6Z5TKN/ -U8Ouy/QGiATatKUEUjr4lN+BYySf8F6e3cAAeAx/ZnFvGw5z8fwNYBjVWg/83bTw -9rS+tSk8VsvTdkcKoNbbDtw+SwYfZSbMUBFm0B13190iJZoyWI+5ZKPnZ2CvOZhX -PjGTOnh6Diq907l2Q7S/v8SLe0bCHCHVBy+CcPWVDZ6Z7V5cJ/W8TvFPcSGw1UCl -tKPp862uDaPKvGxqGDq0vGouEUrtJKZ279Lnrtz1n8raUj0Gxa+KXqLACh8dXCzK -ZgCTPhfAjZcYgA73edW0whNNH9MNInDGulT/arCK3HTkFPczD+7wA8Ojw/LxKFJs -0d8vtILbmLv46CO+wvIdWrW1c7PCrGJDf9Zuw06vIH7hpW9swSM55k9/ ------END ENCRYPTED PRIVATE KEY----- \ No newline at end of file diff --git a/src/Shared/TestCertificates/https-rsa.crt b/src/Shared/TestCertificates/https-rsa.crt deleted file mode 100644 index 0421f377734d..000000000000 Binary files a/src/Shared/TestCertificates/https-rsa.crt and /dev/null differ diff --git a/src/Shared/TestCertificates/https-rsa.key b/src/Shared/TestCertificates/https-rsa.key deleted file mode 100644 index 3462b060b3d5..000000000000 --- a/src/Shared/TestCertificates/https-rsa.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCwK6M1tIuVqrKn -JDT/uBvEz+dMR5dExiWh9Df0aHVL6ZIQs2upwiqoViJSduE3rvSdjZMpvOzE1YUO -Mh8dAsHrcTkXzeF77yF4GnR8XA6FNvIWYhiCxSM1f/cOdLDv0wmaANHoNYHYtr9W -nofuH4QQzI+njLWIE3ZEl95+YXM80nnP+L4ggD46nu2Dd5LRBcpFP6FkCthF+iN+ -IUMdVHylsxhRPY3Dj+xEccPmAUZvCchWXWgGwsW0UygFECqLhWupt0Ysd8rKGRTx -HaI7z/5S1c8VlUgk4Q7FRxq7HiiNdbkrViJkES3ghJ2LbKYMwkGXmfbnam1qRagO -BWnYnnZpAgMBAAECggEBAKlBs7Pke3tXHf/RnI3XX+6OZMX3vlDYIs3f6maKea9u -f+RFzXmyz/MdliouhyFNmT1KCQq/tadDEWvbIeNog9Fl3ZmON0YwMLLIkAPvGhBJ -AvwYUT5KkxJSmJWt7VTtKDtq8EEuL0t8AIcDFsvkQak2MAqk+L/9GtK6Koy3qdTT -Nx0to6jcSvAz6cBC/WY4u2fmGJb6RoQR0K7KWdovkhb60/5PF+tI5afDF4zO6UzD -c7qxb9/rPqhsqomC1isS+MdRWl6edW28RYzhZNxtux0KKy+HYfbrlya41HIYOdCN -h9IEc46tOuEZ4aARHq0eNkLr8oBARcjHUlfPnBpmDGUCgYEA1DYAd45N13DTAITd -MIwiKLHDH5XLmKdCGPk/LNd0asyw7Yw0ffJ2LUtCKt1HyvVKaRsCjzmC7pN1d/JG -Sni+zDgdip9f9vERVF/F/sA9h+zH+Qwx5DUDhu6a4naey3t3t2hyRSbH+e+M7+1b -4/i0nlsD35/lmwwfM7zgSZSmCIcCgYEA1IXOATUURWPilI9HoHt7yhGEvgXvquXC -KF4K+1XNnC7AXO2jwz62xg6rnkFBxiPtvnN+fCVajMusyxCwarc/QyuctcQEm8jK -+vOI1dJM4Qgy+MNzcat7MjJCBpi6oFXAKDu3CGzfUw0SKNepc9cST8x9FsMgcC8K -OKbLWLK2dY8CgYAIgMlwAPG5ijnKMYizY0oTG1xYLaZkzX7mhUY0w8VUajNEsXOB -AHAfzH4wPYGc7ks2/vARURqf+KSiU8DhRwlOIYl9fnlX6bzqBpRmasmMYr54ijaN -kFo909286Uffm2jmnnbFspIcv66EBpzB+7sxBTCYi02l8sxlRFIwYJZujQKBgAO5 -2NPCl3lj9+v82xegMppnVjlypzIK1y2YAH9JkNJFK5A1hmJ87f1o8m9S25FavedR -5QzOJtlDFON2hnFIhy5pTFUPe7kzewONU3/UMQ7c8u/TlWmPxRgrM2ckNFltR3It -Idde+UdeekwHA+yI/8QwZJ0KjL4KxRYbLoN+lp5XAoGAbVNfX57Hjc/TxrC7nTyQ -0Mqi8S1t7Yo/Je/5Ow/8W3zVrzMYTipwJyBrAMhhhOTuvWc6lnJFW6XkyftQPwI6 -RDD3i9DELPhIPhh4kz7ID5OPtRnf3hrvXDOyucSV66RpxSSb5l7i92a8wTFWeGlN -nLbTYpaPuX1fCIbRnigXI3A= ------END PRIVATE KEY----- diff --git a/src/Shared/TestCertificates/https-rsa.pem b/src/Shared/TestCertificates/https-rsa.pem deleted file mode 100644 index 2a2d0312f342..000000000000 --- a/src/Shared/TestCertificates/https-rsa.pem +++ /dev/null @@ -1,19 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDDDCCAfSgAwIBAgIIS+Mx2/wTMMQwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UE -AxMJbG9jYWxob3N0MB4XDTIwMDcwMTE5MjcwOVoXDTIxMDcwMTE5MjcwOVowFDES -MBAGA1UEAxMJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEAsCujNbSLlaqypyQ0/7gbxM/nTEeXRMYlofQ39Gh1S+mSELNrqcIqqFYiUnbh -N670nY2TKbzsxNWFDjIfHQLB63E5F83he+8heBp0fFwOhTbyFmIYgsUjNX/3DnSw -79MJmgDR6DWB2La/Vp6H7h+EEMyPp4y1iBN2RJfefmFzPNJ5z/i+IIA+Op7tg3eS -0QXKRT+hZArYRfojfiFDHVR8pbMYUT2Nw4/sRHHD5gFGbwnIVl1oBsLFtFMoBRAq -i4VrqbdGLHfKyhkU8R2iO8/+UtXPFZVIJOEOxUcaux4ojXW5K1YiZBEt4ISdi2ym -DMJBl5n252ptakWoDgVp2J52aQIDAQABo2IwYDAMBgNVHRMBAf8EAjAAMA4GA1Ud -DwEB/wQEAwIFoDAWBgNVHSUBAf8EDDAKBggrBgEFBQcDATAXBgNVHREBAf8EDTAL -gglsb2NhbGhvc3QwDwYKKwYBBAGCN1QBAQQBATANBgkqhkiG9w0BAQsFAAOCAQEA -ZD9JA++dIuBke7GYYlJuKTMHJB0Sm1Ug2idNi1JiocXYsCVzY05sd4Qh+34PcED7 -B6592o1h47bgOh1ISolrOkt/23VjJweWGsa9rqt1zMdmmCulmPPFOiWWzMSm1OkN -Q/Q5pzWXojxp/ArWLZbrghA44t+A4WJpWyEpEKKu5pD+ufG6dX6oPgz7yRXpkyJw -rln219tjGACm2pXLgTO/WQdesaaquv6v2MEb5jJcxFeK5cQN/anYFqhjJvth1Wr0 -FQwbO4drt1lD+a30r6VjL/sEIlKK2Mi68rHQzeHug+663GLTtw2bZyvAoMwZoxo4 -Vwy3e5F7dw23onqQB92IoQ== ------END CERTIFICATE-----