diff --git a/global.json b/global.json index 0d0362614d6..99cc9a5a013 100644 --- a/global.json +++ b/global.json @@ -1,10 +1,10 @@ { "sdk": { - "version": "9.0.104", + "version": "9.0.105", "rollForward": "latestFeature" }, "tools": { - "dotnet": "9.0.104" + "dotnet": "9.0.105" }, "msbuild-sdks": { "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24421.7", diff --git a/src/Microsoft.DotNet.Arcade.Sdk/src/DownloadFile.cs b/src/Microsoft.DotNet.Arcade.Sdk/src/DownloadFile.cs index d9890311f9c..cd1a18098d2 100644 --- a/src/Microsoft.DotNet.Arcade.Sdk/src/DownloadFile.cs +++ b/src/Microsoft.DotNet.Arcade.Sdk/src/DownloadFile.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Net; using System.Net.Http; +using System.Security.Cryptography.X509Certificates; using System.Threading; using Microsoft.Build.Framework; using Microsoft.Build.Utilities; @@ -123,7 +124,36 @@ private async Tasks.Task DownloadFromUriAsync(string uri) { Log.LogMessage($"Downloading '{uri}' to '{DestinationPath}'"); + // Configure the cert revocation check in a fail-open state to avoid intermittent failures + // on Mac if the endpoint is not available. This is only available on .NET Core, but has only been + // observed on Mac anyway. + +#if NET + using SocketsHttpHandler handler = new SocketsHttpHandler(); + handler.SslOptions.CertificateChainPolicy = new X509ChainPolicy + { + // Yes, check revocation. + // Yes, allow it to be downloaded if needed. + // Online is the default, but it doesn't hurt to be explicit. + RevocationMode = X509RevocationMode.Online, + // Roots never bother with revocation. + // ExcludeRoot is the default, but it doesn't hurt to be explicit. + RevocationFlag = X509RevocationFlag.ExcludeRoot, + // RevocationStatusUnknown at the EndEntity/Leaf certificate will not fail the chain build. + // RevocationStatusUnknown for any intermediate CA will not fail the chain build. + // IgnoreRootRevocationUnknown could also be specified, but it won't apply given ExcludeRoot above. + // The default is that all status codes are bad, this is not the default. + VerificationFlags = + X509VerificationFlags.IgnoreCertificateAuthorityRevocationUnknown | + X509VerificationFlags.IgnoreEndRevocationUnknown, + // Always use the "now" when building the chain, rather than the "now" of when this policy object was constructed. + VerificationTimeIgnored = true, + }; + + using (var httpClient = new HttpClient(handler)) +#else using (var httpClient = new HttpClient(new HttpClientHandler { CheckCertificateRevocationList = true })) +#endif { httpClient.Timeout = TimeSpan.FromSeconds(TimeoutInSeconds); try