Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@ public partial class SslStream
{
private const string DisableTlsResumeCtxSwitch = "System.Net.Security.DisableTlsResume";
private const string DisableTlsResumeEnvironmentVariable = "DOTNET_SYSTEM_NET_SECURITY_DISABLETLSRESUME";
private const string EnableServerAiaDownloadsCtxSwitch = "System.Net.Security.EnableServerAiaDownloads";
private const string EnableServerAiaDownloadsEnvironmentVariable = "DOTNET_SYSTEM_NET_SECURITY_ENABLESERVERAIADOWNLOADS";

private static volatile int s_disableTlsResume = -1;
private static volatile int s_enableServerAiaDownloads = -1;

internal static bool DisableTlsResume
{
Expand Down Expand Up @@ -48,6 +51,33 @@ internal static bool DisableTlsResume
}
}

internal static bool EnableServerAiaDownloads
{
get
{
int enableServerAiaDownloads = s_enableServerAiaDownloads;
if (enableServerAiaDownloads != -1)
{
return enableServerAiaDownloads != 0;
}

// First check for the AppContext switch, giving it priority over the environment variable.
if (AppContext.TryGetSwitch(EnableServerAiaDownloadsCtxSwitch, out bool value))
{
s_enableServerAiaDownloads = value ? 1 : 0;
}
else
{
// AppContext switch wasn't used. Check the environment variable.
s_enableServerAiaDownloads =
Environment.GetEnvironmentVariable(EnableServerAiaDownloadsEnvironmentVariable) is string envVar &&
(envVar == "1" || envVar.Equals("true", StringComparison.OrdinalIgnoreCase)) ? 1 : 0;
}

return s_enableServerAiaDownloads != 0;
}
}


private SafeFreeCredentials? _credentialsHandle;

Expand Down Expand Up @@ -1087,6 +1117,11 @@ internal bool VerifyRemoteCertificate(RemoteCertificateValidationCallback? remot
chain.ChainPolicy.RevocationMode = _sslAuthenticationOptions.CertificateRevocationCheckMode;
chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;

if (_sslAuthenticationOptions.IsServer && !EnableServerAiaDownloads)
{
chain.ChainPolicy.DisableCertificateDownloads = true;
}

if (trust != null)
{
chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,5 +159,64 @@ await TestConfiguration.WhenAllOrAnyFailedWithTimeout(
}
}
}

[ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
[InlineData(true, true, false)]
[InlineData(true, false, false)]
[InlineData(false, true, true)]
[InlineData(false, false, true)]
[InlineData(null, true, false)]
[InlineData(null, false, true)]
public async Task SslStream_ServerDisablesCertificateDownloads_DefaultAndCompatSwitch(bool? appCtxSwitchValue, bool envVarSet, bool shouldDisableDownloads)
{
var psi = new ProcessStartInfo
{
Environment = { { "DOTNET_SYSTEM_NET_SECURITY_ENABLESERVERAIADOWNLOADS", envVarSet ? "1" : "0" } }
};

await RemoteExecutor.Invoke(async (appCtxSwitchValueString, shouldDisableDownloadsString) =>
{
if (bool.TryParse(appCtxSwitchValueString, out bool value))
{
AppContext.SetSwitch("System.Net.Security.EnableServerAiaDownloads", value);
}

bool? disableCertificateDownloadsObserved = false;
(Stream clientStream, Stream serverStream) = TestHelper.GetConnectedStreams();
using (clientStream)
using (serverStream)
using (var client = new SslStream(clientStream))
using (var server = new SslStream(serverStream, false, (sender, certificate, chain, sslPolicyErrors) =>
{
Assert.NotNull(chain);
disableCertificateDownloadsObserved = chain.ChainPolicy.DisableCertificateDownloads;
return true;
}))

using (X509Certificate2 certificate = Configuration.Certificates.GetServerCertificate())
using (X509Certificate2 clientCertificate = Configuration.Certificates.GetClientCertificate())
{
SslClientAuthenticationOptions clientOptions = new SslClientAuthenticationOptions
{
RemoteCertificateValidationCallback = delegate { return true; },
ClientCertificates = new X509Certificate2Collection(clientCertificate),
TargetHost = certificate.GetNameInfo(X509NameType.SimpleName, false),
};

SslServerAuthenticationOptions serverOptions = new SslServerAuthenticationOptions
{
ServerCertificate = certificate,
ClientCertificateRequired = true,
};

await TestConfiguration.WhenAllOrAnyFailedWithTimeout(
client.AuthenticateAsClientAsync(clientOptions),
server.AuthenticateAsServerAsync(serverOptions));

bool expectDisabled = bool.Parse(shouldDisableDownloadsString);
Assert.Equal(expectDisabled, disableCertificateDownloadsObserved);
}
}, appCtxSwitchValue.ToString(), shouldDisableDownloads.ToString(), new RemoteInvokeOptions { StartInfo = psi }).DisposeAsync();
}
}
}
Loading