Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit d35bab8

Browse files
committed
Avoid mutating SslClientAuthenticationOptions in SslState
We shouldn't be mutating the options bag supplied by the caller. This a) will leak back to the caller, and b) will result in problematic race conditions if the options bag is used with multiple SslStreams, such as if a cached instance is used.
1 parent 2a1d941 commit d35bab8

File tree

5 files changed

+12
-24
lines changed

5 files changed

+12
-24
lines changed

src/System.Net.Security/src/System/Net/Security/SslAuthenticationOptions.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ namespace System.Net.Security
1111
{
1212
internal class SslAuthenticationOptions
1313
{
14-
internal SslAuthenticationOptions(SslClientAuthenticationOptions sslClientAuthenticationOptions)
14+
internal SslAuthenticationOptions(SslClientAuthenticationOptions sslClientAuthenticationOptions, RemoteCertValidationCallback remoteCallback, LocalCertSelectionCallback localCallback)
1515
{
1616
// Common options.
1717
AllowRenegotiation = sslClientAuthenticationOptions.AllowRenegotiation;
1818
ApplicationProtocols = sslClientAuthenticationOptions.ApplicationProtocols;
19-
CertValidationDelegate = sslClientAuthenticationOptions._certValidationDelegate;
19+
CertValidationDelegate = remoteCallback;
2020
CheckCertName = true;
2121
EnabledSslProtocols = sslClientAuthenticationOptions.EnabledSslProtocols;
2222
EncryptionPolicy = sslClientAuthenticationOptions.EncryptionPolicy;
@@ -26,7 +26,7 @@ internal SslAuthenticationOptions(SslClientAuthenticationOptions sslClientAuthen
2626
TargetHost = sslClientAuthenticationOptions.TargetHost;
2727

2828
// Client specific options.
29-
CertSelectionDelegate = sslClientAuthenticationOptions._certSelectionDelegate;
29+
CertSelectionDelegate = localCallback;
3030
CertificateRevocationCheckMode = sslClientAuthenticationOptions.CertificateRevocationCheckMode;
3131
ClientCertificates = sslClientAuthenticationOptions.ClientCertificates;
3232
LocalCertificateSelectionCallback = sslClientAuthenticationOptions.LocalCertificateSelectionCallback;

src/System.Net.Security/src/System/Net/Security/SslClientAuthenticationOptions.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@ public class SslClientAuthenticationOptions
1616
private SslProtocols _enabledSslProtocols = SecurityProtocol.SystemDefaultSecurityProtocols;
1717
private bool _allowRenegotiation = true;
1818

19-
internal RemoteCertValidationCallback _certValidationDelegate;
20-
internal LocalCertSelectionCallback _certSelectionDelegate;
21-
2219
public bool AllowRenegotiation
2320
{
2421
get => _allowRenegotiation;

src/System.Net.Security/src/System/Net/Security/SslState.cs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ private void ThrowIfExceptional()
9797
}
9898
}
9999

100-
internal void ValidateCreateContext(SslClientAuthenticationOptions sslClientAuthenticationOptions)
100+
internal void ValidateCreateContext(SslClientAuthenticationOptions sslClientAuthenticationOptions, RemoteCertValidationCallback remoteCallback, LocalCertSelectionCallback localCallback)
101101
{
102102
ThrowIfExceptional();
103103

@@ -116,15 +116,14 @@ internal void ValidateCreateContext(SslClientAuthenticationOptions sslClientAuth
116116
throw new ArgumentNullException(nameof(sslClientAuthenticationOptions.TargetHost));
117117
}
118118

119-
if (sslClientAuthenticationOptions.TargetHost.Length == 0)
120-
{
121-
sslClientAuthenticationOptions.TargetHost = "?" + Interlocked.Increment(ref s_uniqueNameInteger).ToString(NumberFormatInfo.InvariantInfo);
122-
}
123-
124119
_exception = null;
125120
try
126121
{
127-
_sslAuthenticationOptions = new SslAuthenticationOptions(sslClientAuthenticationOptions);
122+
_sslAuthenticationOptions = new SslAuthenticationOptions(sslClientAuthenticationOptions, remoteCallback, localCallback);
123+
if (_sslAuthenticationOptions.TargetHost.Length == 0)
124+
{
125+
_sslAuthenticationOptions.TargetHost = "?" + Interlocked.Increment(ref s_uniqueNameInteger).ToString(NumberFormatInfo.InvariantInfo);
126+
}
128127
_context = new SecureChannel(_sslAuthenticationOptions);
129128
}
130129
catch (Win32Exception e)

src/System.Net.Security/src/System/Net/Security/SslStream.cs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -178,11 +178,7 @@ internal virtual IAsyncResult BeginAuthenticateAsClient(SslClientAuthenticationO
178178
SetAndVerifyValidationCallback(sslClientAuthenticationOptions.RemoteCertificateValidationCallback);
179179
SetAndVerifySelectionCallback(sslClientAuthenticationOptions.LocalCertificateSelectionCallback);
180180

181-
// Set the delegates on the options.
182-
sslClientAuthenticationOptions._certValidationDelegate = _certValidationDelegate;
183-
sslClientAuthenticationOptions._certSelectionDelegate = _certSelectionDelegate;
184-
185-
_sslState.ValidateCreateContext(sslClientAuthenticationOptions);
181+
_sslState.ValidateCreateContext(sslClientAuthenticationOptions, _certValidationDelegate, _certSelectionDelegate);
186182

187183
LazyAsyncResult result = new LazyAsyncResult(_sslState, asyncState, asyncCallback);
188184
_sslState.ProcessAuthentication(result);
@@ -302,11 +298,7 @@ private void AuthenticateAsClient(SslClientAuthenticationOptions sslClientAuthen
302298
SetAndVerifyValidationCallback(sslClientAuthenticationOptions.RemoteCertificateValidationCallback);
303299
SetAndVerifySelectionCallback(sslClientAuthenticationOptions.LocalCertificateSelectionCallback);
304300

305-
// Set the delegates on the options.
306-
sslClientAuthenticationOptions._certValidationDelegate = _certValidationDelegate;
307-
sslClientAuthenticationOptions._certSelectionDelegate = _certSelectionDelegate;
308-
309-
_sslState.ValidateCreateContext(sslClientAuthenticationOptions);
301+
_sslState.ValidateCreateContext(sslClientAuthenticationOptions, _certValidationDelegate, _certSelectionDelegate);
310302
_sslState.ProcessAuthentication(null);
311303
}
312304

src/System.Net.Security/tests/UnitTests/Fakes/FakeSslState.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ internal SslState(Stream innerStream)
2121
{
2222
}
2323

24-
internal void ValidateCreateContext(SslClientAuthenticationOptions sslClientAuthenticationOptions)
24+
internal void ValidateCreateContext(SslClientAuthenticationOptions sslClientAuthenticationOptions, RemoteCertValidationCallback remoteCallback, LocalCertSelectionCallback localCallback)
2525
{
2626
}
2727

0 commit comments

Comments
 (0)