diff --git a/eng/Versions.props b/eng/Versions.props index 2f968cec406018..9fb25e98c63da2 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -140,7 +140,7 @@ 1.0.0-prerelease.22415.6 1.0.0-prerelease.22415.6 - 16.11.27-beta1.23180.1 + 16.11.29-beta1.23404.4 2.0.0-beta4.22355.1 3.0.3 2.1.0 diff --git a/src/libraries/Common/src/System/Net/Http/X509ResourceClient.cs b/src/libraries/Common/src/System/Net/Http/X509ResourceClient.cs index ff5a237c3f3ae3..6a78f1945d96b8 100644 --- a/src/libraries/Common/src/System/Net/Http/X509ResourceClient.cs +++ b/src/libraries/Common/src/System/Net/Http/X509ResourceClient.cs @@ -12,6 +12,9 @@ namespace System.Net.Http { internal static partial class X509ResourceClient { + private const long DefaultAiaDownloadLimit = 100 * 1024 * 1024; + + private static long AiaDownloadLimit { get; } = GetValue("System.Security.Cryptography.AiaDownloadLimit", DefaultAiaDownloadLimit); private static readonly Func>? s_downloadBytes = CreateDownloadBytesFunc(); static partial void ReportNoClient(); @@ -115,6 +118,7 @@ internal static partial class X509ResourceClient ConstructorInfo? httpRequestMessageCtor = httpRequestMessageType.GetConstructor(Type.EmptyTypes); MethodInfo? sendMethod = httpClientType.GetMethod("Send", new Type[] { httpRequestMessageType, typeof(CancellationToken) }); MethodInfo? sendAsyncMethod = httpClientType.GetMethod("SendAsync", new Type[] { httpRequestMessageType, typeof(CancellationToken) }); + PropertyInfo? maxResponseContentBufferSizeProp = httpClientType.GetProperty("MaxResponseContentBufferSize"); PropertyInfo? responseContentProp = httpResponseMessageType.GetProperty("Content"); PropertyInfo? responseStatusCodeProp = httpResponseMessageType.GetProperty("StatusCode"); PropertyInfo? responseHeadersProp = httpResponseMessageType.GetProperty("Headers"); @@ -125,7 +129,7 @@ internal static partial class X509ResourceClient if (socketsHttpHandlerCtor == null || pooledConnectionIdleTimeoutProp == null || allowAutoRedirectProp == null || httpClientCtor == null || requestUriProp == null || httpRequestMessageCtor == null || - sendMethod == null || sendAsyncMethod == null || + sendMethod == null || sendAsyncMethod == null || maxResponseContentBufferSizeProp == null || responseContentProp == null || responseStatusCodeProp == null || responseHeadersProp == null || responseHeadersLocationProp == null || readAsStreamMethod == null || taskOfHttpResponseMessageResultProp == null) @@ -149,6 +153,7 @@ internal static partial class X509ResourceClient pooledConnectionIdleTimeoutProp.SetValue(socketsHttpHandler, TimeSpan.FromSeconds(PooledConnectionIdleTimeoutSeconds)); allowAutoRedirectProp.SetValue(socketsHttpHandler, false); object? httpClient = httpClientCtor.Invoke(new object?[] { socketsHttpHandler }); + maxResponseContentBufferSizeProp.SetValue(httpClient, AiaDownloadLimit); return async (string uriString, CancellationToken cancellationToken, bool async) => { @@ -306,5 +311,24 @@ private static bool IsAllowedScheme(string scheme) { return string.Equals(scheme, "http", StringComparison.OrdinalIgnoreCase); } + + private static long GetValue(string name, long defaultValue) + { + object? data = AppContext.GetData(name); + + if (data is null) + { + return defaultValue; + } + + try + { + return Convert.ToInt64(data); + } + catch + { + return defaultValue; + } + } } } diff --git a/src/libraries/Microsoft.Windows.Compatibility/src/Microsoft.Windows.Compatibility.csproj b/src/libraries/Microsoft.Windows.Compatibility/src/Microsoft.Windows.Compatibility.csproj index 96f3ffdb5a636b..1b55f563eeb999 100644 --- a/src/libraries/Microsoft.Windows.Compatibility/src/Microsoft.Windows.Compatibility.csproj +++ b/src/libraries/Microsoft.Windows.Compatibility/src/Microsoft.Windows.Compatibility.csproj @@ -5,8 +5,8 @@ false true - false - 4 + true + 5 $(NoWarn);NU5128 This Windows Compatibility Pack provides access to APIs that were previously available only for .NET Framework. It can be used from both .NET as well as .NET Standard. diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/tests/RevocationTests/AiaTests.cs b/src/libraries/System.Security.Cryptography.X509Certificates/tests/RevocationTests/AiaTests.cs index 753bec3b88b6bd..c2e70c7f150a86 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/tests/RevocationTests/AiaTests.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/tests/RevocationTests/AiaTests.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Security.Cryptography.X509Certificates.Tests.Common; +using Microsoft.DotNet.RemoteExecutor; using Test.Cryptography; using Xunit; @@ -177,5 +178,44 @@ public static void DisableAiaOptionWorks() }); } } + + [ActiveIssue("https://github.com/dotnet/runtime/issues/57506", typeof(PlatformDetection), nameof(PlatformDetection.IsMonoRuntime), nameof(PlatformDetection.IsMariner))] + [PlatformSpecific(TestPlatforms.Linux)] + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + public static void AiaIgnoresCertOverLimit() + { + RemoteExecutor.Invoke(() => + { + AppContext.SetData("System.Security.Cryptography.AiaDownloadLimit", 100); + CertificateAuthority.BuildPrivatePki( + PkiOptions.AllRevocation, + out RevocationResponder responder, + out CertificateAuthority root, + out CertificateAuthority intermediate, + out X509Certificate2 endEntity, + pkiOptionsInSubject: false, + testName: Guid.NewGuid().ToString()); + + using (responder) + using (root) + using (intermediate) + using (endEntity) + using (X509Certificate2 rootCert = root.CloneIssuerCert()) + { + responder.AiaResponseKind = AiaResponseKind.Cert; + + using (ChainHolder holder = new ChainHolder()) + { + X509Chain chain = holder.Chain; + chain.ChainPolicy.CustomTrustStore.Add(rootCert); + chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust; + chain.ChainPolicy.VerificationTime = endEntity.NotBefore.AddMinutes(1); + chain.ChainPolicy.UrlRetrievalTimeout = DynamicRevocationTests.s_urlRetrievalLimit; + + Assert.False(chain.Build(endEntity)); + } + } + }).Dispose(); + } } }