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

Commit d0cb451

Browse files
authored
Fix SocketsNetHttpHandler TLS client cert handling (#27753)
SocketNetHttpHandler was not filtering down the client certificates when sending in "Manual" mode. This caused a client certificate to be sent to a server when it didn't have the proper EKU OID for "Client Authentication". Changed this so that both "Manual" and "Automatic" modes will use the CertificateHelper GetEligibleCertificate() API. Fixes #23128
1 parent 513e453 commit d0cb451

File tree

3 files changed

+13
-14
lines changed

3 files changed

+13
-14
lines changed

src/System.Net.Http/src/System/Net/Http/HttpClientHandler.Unix.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public partial class HttpClientHandler : HttpMessageHandler
1717
private readonly CurlHandler _curlHandler;
1818
private readonly SocketsHttpHandler _socketsHttpHandler;
1919
private readonly DiagnosticsHandler _diagnosticsHandler;
20+
private ClientCertificateOption _clientCertificateOptions;
2021

2122
public HttpClientHandler() : this(UseSocketsHttpHandler) { }
2223

@@ -26,6 +27,7 @@ public HttpClientHandler() : this(UseSocketsHttpHandler) { }
2627
{
2728
_socketsHttpHandler = new SocketsHttpHandler();
2829
_diagnosticsHandler = new DiagnosticsHandler(_socketsHttpHandler);
30+
ClientCertificateOptions = ClientCertificateOption.Manual;
2931
}
3032
else
3133
{
@@ -91,9 +93,7 @@ public ClientCertificateOption ClientCertificateOptions
9193
}
9294
else
9395
{
94-
return _socketsHttpHandler.SslOptions.LocalCertificateSelectionCallback != null ?
95-
ClientCertificateOption.Automatic :
96-
ClientCertificateOption.Manual;
96+
return _clientCertificateOptions;
9797
}
9898
}
9999
set
@@ -108,11 +108,13 @@ public ClientCertificateOption ClientCertificateOptions
108108
{
109109
case ClientCertificateOption.Manual:
110110
ThrowForModifiedManagedSslOptionsIfStarted();
111-
_socketsHttpHandler.SslOptions.LocalCertificateSelectionCallback = null;
111+
_clientCertificateOptions = value;
112+
_socketsHttpHandler.SslOptions.LocalCertificateSelectionCallback = (sender, targetHost, localCertificates, remoteCertificate, acceptableIssuers) => CertificateHelper.GetEligibleClientCertificate(ClientCertificates);
112113
break;
113114

114115
case ClientCertificateOption.Automatic:
115116
ThrowForModifiedManagedSslOptionsIfStarted();
117+
_clientCertificateOptions = value;
116118
_socketsHttpHandler.SslOptions.LocalCertificateSelectionCallback = (sender, targetHost, localCertificates, remoteCertificate, acceptableIssuers) => CertificateHelper.GetEligibleClientCertificate();
117119
break;
118120

src/System.Net.Http/src/System/Net/Http/HttpClientHandler.Windows.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ public partial class HttpClientHandler : HttpMessageHandler
1919
private readonly SocketsHttpHandler _socketsHttpHandler;
2020
private readonly DiagnosticsHandler _diagnosticsHandler;
2121
private bool _useProxy;
22+
private ClientCertificateOption _clientCertificateOptions;
2223

2324
public HttpClientHandler() : this(UseSocketsHttpHandler) { }
2425

@@ -28,6 +29,8 @@ public HttpClientHandler() : this(UseSocketsHttpHandler) { }
2829
{
2930
_socketsHttpHandler = new SocketsHttpHandler();
3031
_diagnosticsHandler = new DiagnosticsHandler(_socketsHttpHandler);
32+
ClientCertificateOptions = ClientCertificateOption.Manual;
33+
3134
}
3235
else
3336
{
@@ -319,9 +322,7 @@ public ClientCertificateOption ClientCertificateOptions
319322
}
320323
else
321324
{
322-
return _socketsHttpHandler.SslOptions.LocalCertificateSelectionCallback != null ?
323-
ClientCertificateOption.Automatic :
324-
ClientCertificateOption.Manual;
325+
return _clientCertificateOptions;
325326
}
326327
}
327328
set
@@ -336,11 +337,13 @@ public ClientCertificateOption ClientCertificateOptions
336337
{
337338
case ClientCertificateOption.Manual:
338339
ThrowForModifiedManagedSslOptionsIfStarted();
339-
_socketsHttpHandler.SslOptions.LocalCertificateSelectionCallback = null;
340+
_clientCertificateOptions = value;
341+
_socketsHttpHandler.SslOptions.LocalCertificateSelectionCallback = (sender, targetHost, localCertificates, remoteCertificate, acceptableIssuers) => CertificateHelper.GetEligibleClientCertificate(ClientCertificates);
340342
break;
341343

342344
case ClientCertificateOption.Automatic:
343345
ThrowForModifiedManagedSslOptionsIfStarted();
346+
_clientCertificateOptions = value;
344347
_socketsHttpHandler.SslOptions.LocalCertificateSelectionCallback = (sender, targetHost, localCertificates, remoteCertificate, acceptableIssuers) => CertificateHelper.GetEligibleClientCertificate();
345348
break;
346349

src/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.ClientCertificates.cs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -142,12 +142,6 @@ public void Manual_SendClientCertificateWithClientAuthEKUToRemoteServer_OK()
142142
[Fact]
143143
public void Manual_SendClientCertificateWithServerAuthEKUToRemoteServer_Forbidden()
144144
{
145-
if (UseSocketsHttpHandler)
146-
{
147-
// TODO #23128: SocketsHttpHandler is currently sending out client certificates when it shouldn't.
148-
return;
149-
}
150-
151145
if (!CanTestClientCertificates) // can't use [Conditional*] right now as it's evaluated at the wrong time for SocketsHttpHandler
152146
{
153147
_output.WriteLine($"Skipping {nameof(Manual_SendClientCertificateWithServerAuthEKUToRemoteServer_Forbidden)}()");

0 commit comments

Comments
 (0)