/
githubmirror
/
aspnetcore
Обзор
Документация
Войти
/
githubmirror
/
aspnetcore
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Servers/Kestrel/shared/test/CertHelper.cs
191 строка
7 KB
William Godbe
Rename Microsoft.Aspnetcore.Testing to Microsoft.AspNetCore.InternalTesting (#51713)
02 ноя 2023, 03:15
Не верифицирован
02 ноя 2023, 03:15
fc8deca
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Net; using System.Net.Sockets; using System.Runtime.CompilerServices; using System.Security.Authentication; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; namespace Microsoft.AspNetCore.InternalTesting; #nullable enable // Copied from https://github.com/dotnet/runtime/main/src/libraries/System.Net.Security/tests/FunctionalTests/TestHelper.cs public static class CertHelper { private static readonly X509KeyUsageExtension s_eeKeyUsage = new X509KeyUsageExtension( X509KeyUsageFlags.DigitalSignature | X509KeyUsageFlags.KeyEncipherment | X509KeyUsageFlags.DataEncipherment, critical: false); private static readonly X509EnhancedKeyUsageExtension s_tlsServerEku = new X509EnhancedKeyUsageExtension( new OidCollection { new Oid("1.3.6.1.5.5.7.3.1", null) }, false); private static readonly X509EnhancedKeyUsageExtension s_tlsClientEku = new X509EnhancedKeyUsageExtension( new OidCollection { new Oid("1.3.6.1.5.5.7.3.2", null) }, false); private static readonly X509BasicConstraintsExtension s_eeConstraints = new X509BasicConstraintsExtension(false, false, 0, false); public static bool AllowAnyServerCertificate(object sender, X509Certificate certificate, X509Chain chain) { return true; } internal static (NetworkStream ClientStream, NetworkStream ServerStream) GetConnectedTcpStreams() { using (Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { listener.Bind(new IPEndPoint(IPAddress.Loopback, 0)); listener.Listen(1); var clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); clientSocket.Connect(listener.LocalEndPoint!); Socket serverSocket = listener.Accept(); serverSocket.NoDelay = true; clientSocket.NoDelay = true; return (new NetworkStream(clientSocket, ownsSocket: true), new NetworkStream(serverSocket, ownsSocket: true)); } } internal static void CleanupCertificates([CallerMemberName] string? testName = null) { string caName = $"O={testName}"; try { using (X509Store store = new X509Store(StoreName.CertificateAuthority, StoreLocation.LocalMachine)) { store.Open(OpenFlags.ReadWrite); foreach (X509Certificate2 cert in store.Certificates) { if (cert.Subject.Contains(caName)) { store.Remove(cert); } cert.Dispose(); } } } catch { }; try { using (X509Store store = new X509Store(StoreName.CertificateAuthority, StoreLocation.CurrentUser)) { store.Open(OpenFlags.ReadWrite); foreach (X509Certificate2 cert in store.Certificates) { if (cert.Subject.Contains(caName)) { store.Remove(cert); } cert.Dispose(); } } } catch { }; } internal static X509ExtensionCollection BuildTlsServerCertExtensions(string serverName) { return BuildTlsCertExtensions(serverName, true); } private static X509ExtensionCollection BuildTlsCertExtensions(string targetName, bool serverCertificate) { X509ExtensionCollection extensions = new X509ExtensionCollection(); SubjectAlternativeNameBuilder builder = new SubjectAlternativeNameBuilder(); builder.AddDnsName(targetName); extensions.Add(builder.Build()); extensions.Add(s_eeConstraints); extensions.Add(s_eeKeyUsage); extensions.Add(serverCertificate ? s_tlsServerEku : s_tlsClientEku); return extensions; } internal static (X509Certificate2 certificate, X509Certificate2Collection) GenerateCertificates(string targetName, [CallerMemberName] string? testName = null, bool longChain = false, bool serverCertificate = true) { const int keySize = 2048; if (OperatingSystem.IsWindows() && testName != null) { CleanupCertificates(testName); } X509Certificate2Collection chain = new X509Certificate2Collection(); X509ExtensionCollection extensions = BuildTlsCertExtensions(targetName, serverCertificate); CertificateAuthority.BuildPrivatePki( PkiOptions.IssuerRevocationViaCrl, out RevocationResponder responder, out CertificateAuthority root, out CertificateAuthority[] intermediates, out X509Certificate2 endEntity, intermediateAuthorityCount: longChain ? 3 : 1, subjectName: targetName, testName: testName, keySize: keySize, extensions: extensions); // Walk the intermediates backwards so we build the chain collection as // Issuer3 // Issuer2 // Issuer1 // Root for (int i = intermediates.Length - 1; i >= 0; i--) { CertificateAuthority authority = intermediates[i]; chain.Add(authority.CloneIssuerCert()); authority.Dispose(); } chain.Add(root.CloneIssuerCert()); responder.Dispose(); root.Dispose(); if (OperatingSystem.IsWindows()) { X509Certificate2 ephemeral = endEntity; endEntity = new X509Certificate2(endEntity.Export(X509ContentType.Pfx), (string?)null, X509KeyStorageFlags.Exportable); ephemeral.Dispose(); } return (endEntity, chain); } internal static string GetTestSNIName(string testMethodName, params SslProtocols?[] protocols) { static string ProtocolToString(SslProtocols? protocol) { return (protocol?.ToString() ?? "null").Replace(", ", "-"); } var args = string.Join(".", protocols.Select(p => ProtocolToString(p))); var name = testMethodName.Length > 63 ? testMethodName.Substring(0, 63) : testMethodName; name = $"{name}.{args}"; if (OperatingSystem.IsAndroid()) { // Android does not support underscores in host names name = name.Replace("_", string.Empty); } return name; } }