From 4aa29f43fd15e0217ecaae5a06d1e355d0471bb0 Mon Sep 17 00:00:00 2001 From: Tomas Weinfurt Date: Sat, 12 Jun 2021 16:26:08 +0200 Subject: [PATCH] fix ConnectWithCertificateChain quic test (#54026) --- .../Implementations/MsQuic/MsQuicConnection.cs | 22 +++++--------------- .../tests/FunctionalTests/MsQuicTests.cs | 24 ++++++++++++++++++++-- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicConnection.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicConnection.cs index 6324acd..f31dfc3 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicConnection.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicConnection.cs @@ -345,27 +345,18 @@ namespace System.Net.Quic.Implementations.MsQuic { unsafe { - ReadOnlySpan quicBuffer; + ReadOnlySpan quicBuffer = new ReadOnlySpan((void*)connectionEvent.Data.PeerCertificateReceived.PlatformCertificateHandle, sizeof(QuicBuffer)); + certificate = new X509Certificate2(new ReadOnlySpan(quicBuffer[0].Buffer, (int)quicBuffer[0].Length)); + if (connectionEvent.Data.PeerCertificateReceived.PlatformCertificateChainHandle != IntPtr.Zero) { quicBuffer = new ReadOnlySpan((void*)connectionEvent.Data.PeerCertificateReceived.PlatformCertificateChainHandle, sizeof(QuicBuffer)); if (quicBuffer[0].Length != 0 && quicBuffer[0].Buffer != null) { - ReadOnlySpan asn1 = new ReadOnlySpan(quicBuffer[0].Buffer, (int)quicBuffer[0].Length); additionalCertificates = new X509Certificate2Collection(); - additionalCertificates.Import(asn1); - if (additionalCertificates.Count > 0) - { - certificate = additionalCertificates[additionalCertificates.Count - 1]; - } + additionalCertificates.Import(new ReadOnlySpan(quicBuffer[0].Buffer, (int)quicBuffer[0].Length)); } } - else - { - quicBuffer = new ReadOnlySpan((void*)connectionEvent.Data.PeerCertificateReceived.PlatformCertificateHandle, sizeof(QuicBuffer)); - ReadOnlySpan asn1 = new ReadOnlySpan(quicBuffer[0].Buffer, (int)quicBuffer[0].Length); - certificate = new X509Certificate2(asn1); - } } } } @@ -384,10 +375,7 @@ namespace System.Net.Quic.Implementations.MsQuic if (additionalCertificates != null && additionalCertificates.Count > 1) { - for (int i = 0; i < additionalCertificates.Count - 1; i++) - { - chain.ChainPolicy.ExtraStore.Add(additionalCertificates[i]); - } + chain.ChainPolicy.ExtraStore.AddRange(additionalCertificates); } if (!chain.Build(certificate)) diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs index 58fd895..612da52 100644 --- a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs @@ -10,14 +10,21 @@ using System.Security.Cryptography.X509Certificates; using System.Text; using System.Threading.Tasks; using Xunit; +using Xunit.Abstractions; namespace System.Net.Quic.Tests { [ConditionalClass(typeof(QuicTestBase), nameof(IsSupported))] public class MsQuicTests : QuicTestBase { + readonly ITestOutputHelper _output; private static ReadOnlyMemory s_data = Encoding.UTF8.GetBytes("Hello world!"); + public MsQuicTests(ITestOutputHelper output) + { + _output = output; + } + [Fact] public async Task UnidirectionalAndBidirectionalStreamCountsWork() { @@ -83,9 +90,22 @@ namespace System.Net.Quic.Tests // With trusted root, we should be able to build chain. chain.ChainPolicy.CustomTrustStore.Add(rootCA); chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust; - Assert.True(chain.Build(certificate)); + bool ret = chain.Build(certificate); + if (!ret) + { + _output.WriteLine("Chain build failed with {0} elements", chain.ChainElements); + foreach (X509ChainElement element in chain.ChainElements) + { + _output.WriteLine("Element subject {0} and issuer {1}", element.Certificate.Subject, element.Certificate.Issuer); + _output.WriteLine("Element status len {0}", element.ChainElementStatus.Length); + foreach (X509ChainStatus status in element.ChainElementStatus) + { + _output.WriteLine($"Status: {status.Status}: {status.StatusInformation}"); + } + } + } - return true; + return ret; }; using QuicConnection clientConnection = new QuicConnection(QuicImplementationProviders.MsQuic, options); -- 2.7.4