dotnet / android

.NET for Android provides open-source bindings of the Android SDK for use with .NET managed languages such as C#
MIT License
1.94k stars 533 forks source link

AndroidMessageHandler seems to be ignoring ClientCertificates #9576

Open nk-alex opened 1 day ago

nk-alex commented 1 day ago

Description

I have an old .net framework 4.5 project using HttpClient with HttpClientHandler in order to load client certificate for query. This is the code I'm using. Works as expected:

var handler = new HttpClientHandler();
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
handler.SslProtocols = SslProtocols.Tls12;
handler.ClientCertificates.Add(new X509Certificate2(certificate, password));

using (var httpClient = new HttpClient(handler))
{
    var httpRequest = new HttpRequestMessage(HttpMethod.Post, uri)
    {
        Content = new StringContent(body, Encoding.UTF8, "text/xml")
    };
    httpRequest.Headers.Add("SOAPAction", action);
    var httpResponse = await httpClient.SendAsync(httpRequest);
}

Now I'm trying to recreate that code on my .net 8 MAUI project. I started with the Android specific code:

#if ANDROID
                var handler = new AndroidMessageHandler();
                handler.ClientCertificateOptions = ClientCertificateOption.Manual;
                handler.SslProtocols = SslProtocols.Tls12;
                handler.ClientCertificates = new X509CertificateCollection { new X509Certificate2(certificate,  password) };
#else

#endif

                using (var httpClient = new HttpClient(handler))
                {
                    var httpRequest = new HttpRequestMessage(HttpMethod.Post, uri)
                    {
                        Content = new StringContent(body, Encoding.UTF8, "text/xml")
                    };
                    httpRequest.Headers.Add("SOAPAction", action);
                    var httpResponse = await httpClient.SendAsync(httpRequest);
                }

But the web service I'm sending my request keeps on returning me 403 - No certificate detected.

Steps to Reproduce

-

Link to public reproduction project repository

No response

Version with bug

8.0.100 SR10

Is this a regression from previous behavior?

Not sure, did not test other versions

Last version that worked well

Unknown/Other

Affected platforms

Android

Affected platform versions

Android 14

Did you find any workaround?

-

Relevant log output

similar-issues-ai[bot] commented 1 day ago

We've found some similar issues:

If any of the above are duplicates, please consider closing this issue out and adding additional context in the original issue.

Note: You can give me feedback by 👍 or 👎 this comment.

jpobst commented 1 day ago

It looks like the fixed issue you reference was fixed in July 2024, so it would likely only be in .NET 9 and not .NET 8.

https://github.com/dotnet/android/pull/8961

Can you try on .NET 9 and see if it works there?

nk-alex commented 7 hours ago

Hi @jpobst, thanks for the answer.

I updated my project from .NET8 to .NET9 and now the certificate seems to be working as expected.

Since in .NET9 new X509Certificate2(certificate, password) is now obsolete: "Loading certificate data through the constructor or Import is obsolete. Use X509CertificateLoader instead to load certificates."

To load the certificate I had to use X509CertificateLoader.LoadPkcs12FromFile(certificate, password)

Just to know, are there any plans on implementing this solution also for .NET8?

jpobst commented 57 minutes ago

Just to know, are there any plans on implementing this solution also for .NET8?

I will defer to @simonrozsival and @jonpryor about the risk involved with backporting this to .NET 8.