-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
android: Cannot detect when HTTPS server needs a client certificate with SocketsHttpHandler #109532
Comments
Tagging subscribers to this area: @dotnet/ncl |
I am not 100% sure how this behaves on Android, but on desktop platforms, the callback is called up to two times:
You should be able to distinguish between the two cases by looking at the |
Tagging subscribers to 'arch-android': @vitek-karas, @simonrozsival, @steveisok, @akoeplinger |
I modified my repro to add a LocalCertificateSelectionCallback.bool wasPrompted = false;
var handler = new SocketsHttpHandler();
handler.SslOptions.LocalCertificateSelectionCallback = (sender, host, localCerts, remoteCertificate, issuers) =>
{
Trace.WriteLine($"{sender}, {host}, {localCerts}, {remoteCertificate}, {issuers}");
if (remoteCertificate != null)
{
wasPrompted = true;
if (localCerts != null && localCerts.Count > 0)
{
return localCerts[0];
}
}
return null;
};
var client = new HttpClient(handler);
try
{
await client.GetAsync("https://your-pki-secured-server-here.com");
}
catch (Exception ex)
{
Trace.WriteLine(ex.Message);
}
Trace.WriteLine(wasPrompted.ToString()); I see that on Windows it is indeed called twice, just as you describe. But on Android it is only called once (with a null remoteCertificate).
|
As minimum, I think we should surface the native error code @simonrozsival. And ideally figure out why the certificate request is not propagated to .NET |
Description
I'm building a cross-platform auth library and I am stumped trying to detect a challenge for a client certificate (for PKI-secured HTTPS services). In the past the norm used to be to look for 401/Unauthorized replies, but these days 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.
On most platforms, I'm able to detect this. For example:
But with SocketsHttpHandler on Android, the inner exception (Interop+AndroidCrypto+SslException) the HResult is always just SecurityStatusPalErrorCode.InternalError (14). I bet there is more information available to the interop but there does not seem to be any way for me to access it.
Using LocalCertificateSelectionCallback also doesn't help because it just fires once for all HTTPS connections, with no way to know whether a client certificate is required or not.
Reproduction Steps
Use an HttpClient backed by SocketsHttpHandler to make an HTTPS request to a server that requires client certificate authentication:
Unfortunately I do not have a specific public-facing service to share, but it should be possible to set one up for testing.
Expected behavior
SocketsHttpHandler throws an informative exception, from which we can determine that the server needs a client certificate. Perhaps an HttpRequestException with HttpRequestError.UserAuthenticationError would work.
Actual behavior
SocketsHttpHandler throws a generic HttpRequestException with "Unknown" HttpRequestError.
The inner-most exception has a generic HResult of 14 ("internal error").
Regression?
Regression only if you compare the behavior to the old "managed" monodroid HttpClient.
Known Workarounds
Using AndroidMessageHandler instead of SocketsHttpHandler.
Configuration
No response
Other information
No response
The text was updated successfully, but these errors were encountered: