internal static (X509Certificate2 certificate, X509Certificate2Collection) GenerateCertificates(string targetName, [CallerMemberName] string?testName = null, bool longChain = false, bool serverCertificate = true) { const int keySize = 2048; if (PlatformDetection.IsWindows && testName != null) { CleanupCertificates(testName); } X509Certificate2Collection chain = new X509Certificate2Collection(); 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); CertificateAuthority.BuildPrivatePki( PkiOptions.IssuerRevocationViaCrl, out RevocationResponder responder, out CertificateAuthority root, out CertificateAuthority intermediate, out X509Certificate2 endEntity, subjectName: targetName, testName: testName, keySize: keySize, extensions: extensions); if (longChain) { using (RSA intermedKey2 = RSA.Create(keySize)) using (RSA intermedKey3 = RSA.Create(keySize)) { X509Certificate2 intermedPub2 = intermediate.CreateSubordinateCA( $"CN=\"A SSL Test CA 2\", O=\"testName\"", intermedKey2); X509Certificate2 intermedCert2 = intermedPub2.CopyWithPrivateKey(intermedKey2); intermedPub2.Dispose(); CertificateAuthority intermediateAuthority2 = new CertificateAuthority(intermedCert2, null, null, null); X509Certificate2 intermedPub3 = intermediateAuthority2.CreateSubordinateCA( $"CN=\"A SSL Test CA 3\", O=\"testName\"", intermedKey3); X509Certificate2 intermedCert3 = intermedPub3.CopyWithPrivateKey(intermedKey3); intermedPub3.Dispose(); CertificateAuthority intermediateAuthority3 = new CertificateAuthority(intermedCert3, null, null, null); RSA eeKey = (RSA)endEntity.PrivateKey; endEntity = intermediateAuthority3.CreateEndEntity( $"CN=\"A SSL Test\", O=\"testName\"", eeKey, extensions); endEntity = endEntity.CopyWithPrivateKey(eeKey); chain.Add(intermedCert3); chain.Add(intermedCert2); } } chain.Add(intermediate.CloneIssuerCert()); chain.Add(root.CloneIssuerCert()); responder.Dispose(); root.Dispose(); intermediate.Dispose(); if (PlatformDetection.IsWindows) { endEntity = new X509Certificate2(endEntity.Export(X509ContentType.Pfx)); } return(endEntity, chain); }