public void Dispose() { TestHelper.CleanupCertificates(this.GetType().Name); }
public async Task SslStream_ClientCertificate_SendsChain() { List <SslStream> streams = new List <SslStream>(); TestHelper.CleanupCertificates(); (X509Certificate2 clientCertificate, X509Certificate2Collection clientChain) = TestHelper.GenerateCertificates("SslStream_ClinetCertificate_SendsChain", serverCertificate: false); using (X509Store store = new X509Store(StoreName.CertificateAuthority, StoreLocation.CurrentUser)) { // add chain certificate so we can construct chain since there is no way how to pass intermediates directly. store.Open(OpenFlags.ReadWrite); store.AddRange(clientChain); store.Close(); } using (var chain = new X509Chain()) { chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags; chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; chain.ChainPolicy.DisableCertificateDownloads = false; bool chainStatus = chain.Build(clientCertificate); // Verify we can construct full chain if (chain.ChainElements.Count < clientChain.Count) { throw new SkipTestException($"chain cannot be built {chain.ChainElements.Count}"); } } var clientOptions = new SslClientAuthenticationOptions() { TargetHost = "localhost", }; clientOptions.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true; clientOptions.LocalCertificateSelectionCallback = (sender, target, certificates, remoteCertificate, issuers) => clientCertificate; var serverOptions = new SslServerAuthenticationOptions() { ClientCertificateRequired = true }; serverOptions.ServerCertificateContext = SslStreamCertificateContext.Create(Configuration.Certificates.GetServerCertificate(), null); serverOptions.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => { // Client should send chain without root CA. There is no good way how to know if the chain was built from certificates // from wire or from system store. However, SslStream adds certificates from wire to ExtraStore in RemoteCertificateValidationCallback. // So we verify the operation by checking the ExtraStore. On Windows, that includes leaf itself. _output.WriteLine("RemoteCertificateValidationCallback called with {0} and {1} extra certificates", sslPolicyErrors, chain.ChainPolicy.ExtraStore.Count); foreach (X509Certificate c in chain.ChainPolicy.ExtraStore) { _output.WriteLine("received {0}", c.Subject); } Assert.True(chain.ChainPolicy.ExtraStore.Count >= clientChain.Count - 1, "client did not sent expected chain"); return(true); }; // run the test multiple times while holding established SSL so we could hit credential cache. for (int i = 0; i < 3; i++) { (Stream clientStream, Stream serverStream) = TestHelper.GetConnectedStreams(); SslStream client = new SslStream(clientStream); SslStream server = new SslStream(serverStream); Task t1 = client.AuthenticateAsClientAsync(clientOptions, CancellationToken.None); Task t2 = server.AuthenticateAsServerAsync(serverOptions, CancellationToken.None); await Task.WhenAll(t1, t2).WaitAsync(TestConfiguration.PassingTestTimeout); // hold to the streams so they stay in credential cache streams.Add(client); streams.Add(server); } TestHelper.CleanupCertificates(); clientCertificate.Dispose(); foreach (X509Certificate c in clientChain) { c.Dispose(); } foreach (SslStream s in streams) { s.Dispose(); } }
static SslStreamNetworkStreamTest() { TestHelper.CleanupCertificates(nameof(SslStreamNetworkStreamTest)); (_serverCert, _serverChain) = TestHelper.GenerateCertificates("localhost", nameof(SslStreamNetworkStreamTest)); }
public CertificateSetup() { TestHelper.CleanupCertificates(nameof(SslStreamNetworkStreamTest)); (serverCert, serverChain) = TestHelper.GenerateCertificates("localhost", nameof(SslStreamNetworkStreamTest), longChain: true); }