Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detecting certificate challenge in NSUrlSessionHandler #21688

Open
mstefarov opened this issue Nov 22, 2024 · 1 comment
Open

Detecting certificate challenge in NSUrlSessionHandler #21688

mstefarov opened this issue Nov 22, 2024 · 1 comment
Assignees
Labels
networking If an issue or pull request is related to networking
Milestone

Comments

@mstefarov
Copy link

mstefarov commented Nov 22, 2024

I'm building cross-platform auth components, which include client-certificate (PKI) authentication. Currently only SocketsHttpHandler is fully functional, but I would like to support NSUrlSessionHandler as well.

The work on #13856 got me most of the way there, but one problem remains: detecting when a server challenges my client for a client certificate. In the past the norm used to be to look for HTTP/401 or 403 replies, but now many TLS/SSLv3-secured services use error alerts instead. This happens when the connection is still negotiated so I have no HttpResponseMessage to work with — all I have is an HttpRequestException.

With SocketsHttpHandler on iOS, I have options. I can subscribe to LocalCertificateSelectionCallback and listen for events, or I can check HttpRequestException's InnerException (of type Interop+AppleCrypto+SslException) gives me a specific libsecurity error code via HResult. I can check if it matches e.g. errSSLPeerBadCert (-9825) and prompt user for a client certificate.

With vanilla NSUrlSession I can look for challenges with AuthenticationMethodClientCertificate protection space.

But with NSUrlSessionHandler, this challenge is doomed to fail unless I pre-load a correct certificate ahead of time, and I end up with a fairly generic "connection lost" HttpRequestException:

System.Net.Http.HttpRequestException: The network connection was lost.
 ---> Foundation.NSErrorException: Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost." UserInfo={_kCFStreamErrorCodeKey=-4, NSUnderlyingError=0x600000c4cd20 {Error Domain=kCFErrorDomainCFNetwork Code=-1005 "(null)" ...}
   --- End of inner exception stack trace ---
   at System.Net.Http.NSUrlSessionHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) in /Users/builder/azdo/_work/1/s/xamarin-macios/src/Foundation/NSUrlSessionHandler.cs:line 551
   at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken)

I might be able to workaround this by e.g. falling back to SocketHttpHandler when I see that "network connection lost" error to double-check if this is a certificate challenge. But my life would be a lot easier if NSUrlSessionHandler itself could help detect a challenge, either by providing a client-certificate-selection callback, or by providing a more detailed error message.

P.S. I also made a similar request for SocketHttpHandler-on-Android in dotnet/runtime#109532

@rolfbjarne rolfbjarne added the networking If an issue or pull request is related to networking label Nov 28, 2024
@rolfbjarne
Copy link
Member

@mandel-macaque can you look at this?

@rolfbjarne rolfbjarne added this to the Future milestone Nov 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
networking If an issue or pull request is related to networking
Projects
None yet
Development

No branches or pull requests

3 participants