alexrainman / ModernHttpClient

ModernHttpClient
MIT License
126 stars 27 forks source link

System.NotSupportedException: cannot decode public key from unknown oid '1.2.840.10045.2.1' #71

Open Alex-Dobrynin opened 4 years ago

Alex-Dobrynin commented 4 years ago

when I use modernhttpclient.nativemessagehandler and trying to get access trough this link: https://restcountries.eu/data/ala.svg I get an exception mentioned in title of this issue. If I use httpclient without nativemessagehandler it is ok

YuliaLoyko commented 3 years ago

same issue here. plugin does not support ECDSA, which is a big issue

alexrainman commented 3 years ago

Let me se what i can do.

danieljgmaclean commented 3 years ago

Having the same problem. But I worked around it by setting TLSConfig and SSL Pinning. Not sure why this works.

YuliaLoyko commented 3 years ago

@alexrainman thank you! do you have any ETA for this? or do you need some help?

alexrainman commented 3 years ago

Is this iOS only?

Alex-Dobrynin commented 3 years ago

Is this iOS only?

no, it`s both

alexrainman commented 3 years ago

Well, i am facing this issue too so, i have to fix it :)

alexrainman commented 3 years ago

I cannot reproduce this. I can get https://restcountries.eu/data/ala.svg without any issues as soon as i provide the public key in the TLSConfig.

alexrainman commented 3 years ago

You can get that server public key running this code in Android:

var hostname = "restcountries.eu";

var certificatePinner = new Square.OkHttp3.CertificatePinner.Builder()
    .Add(hostname, "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")
    .Build();

var client = new OkHttpClient.Builder()
    .CertificatePinner(certificatePinner)
    .Build();

var request = new Request.Builder()
    .Url("https://" + hostname)
    .Build();

var call = client.NewCall(request);

var response = await call.ExecuteAsync();

Then provide it in the TLSConfig:

readonly HttpClient client = new HttpClient(new NativeMessageHandler(false, new TLSConfig()
{
    Pins = new List<Pin>()
    {
        new Pin()
        {
            Hostname = "restcountries.eu",
            PublicKeys = new string []
            {
                "sha256/wxgZ6Jx5WaNt5zAgUSDnLsK8E5uy+DUumAogHk4P7R8="
            }
        }
    },
    DangerousAcceptAnyServerCertificateValidator = false
})
{
    DisableCaching = true,
    Timeout = new TimeSpan(0, 0, 9)
});
Alex-Dobrynin commented 3 years ago

what about ios? and i provide this handler to FF Image Loading once at app startup, so i need to have universal approach. because the user may have different images or svgs from different hosts and from our backend during runtime.

so what i did, i just left default http client

image

alexrainman commented 3 years ago

It is universal.

You get the Public Key using that trick in Android, then configure TLS for both platforms in your shared code.

Also, i found where the library fails and this is not something i can fix unless i replace this piece of code:

if (!chain.Build(root))
{
    errors = SslPolicyErrors.RemoteCertificateChainErrors;
    PinningFailureMessage = FailureMessages.ChainError;
    goto sslErrorVerify;
}

With something like this:

var valid = chain.ChainElements.Cast<X509ChainElement>().All(x => x.Certificate.Thumbprint == root.Thumbprint);

if (!valid)
{
    errors = SslPolicyErrors.RemoteCertificateChainErrors;
    PinningFailureMessage = FailureMessages.ChainError;
    goto sslErrorVerify;
}

chain.Build(root) fails with ECDSA because it is not supported by Mono:

https://github.com/mono/mono/blob/1547af6a278321d5dbc56a63f18b2380c757608e/mcs/class/System/System.Security.Cryptography.X509Certificates/PublicKey.cs#L141

alexrainman commented 3 years ago

By the way, i have exactly the same use case where i need to share my single HttpClient instance with FFImageLoading but i want to use native handlers to make it faster so, i may apply this fix and release a new version.

alexrainman commented 3 years ago

same issue here. plugin does not support ECDSA, which is a big issue

chain.Build(root) fails with ECDSA because it is not supported by Mono:

https://github.com/mono/mono/blob/1547af6a278321d5dbc56a63f18b2380c757608e/mcs/class/System/System.Security.Cryptography.X509Certificates/PublicKey.cs#L141

Alex-Dobrynin commented 3 years ago

but why the default http client works well?

alexrainman commented 3 years ago

Because it doesn’t use PublicKey at all.

alexrainman commented 3 years ago

As i said, use Android to get server certificate public key, and once you have it, configure modernhttpclient with it for both platforms.

michelinaFolino commented 3 years ago

hi,

i have same problem. Is there any news on the update that fixes this crash?

thank you so much

InquisitorJax commented 2 years ago

Also ran into this issue. @alexrainman thanks for the code to discover the public keys! Interestingly enough - for me - this was only crashing on iOS.

AlonRom commented 1 year ago

Hi @alexrainman Can you estimate when there will be a fix for this in iOS?

NoamMani commented 1 year ago

Hi @alexrainman, we get this exception all the time, is there an update regarding this issue?

AlonRom commented 1 year ago

@alexrainman ??

alexrainman commented 1 year ago

I have been out for most of the year. Still recovering from surgery. But a new revamped version of the plugin will be out soon.

gcadmes-extron commented 1 year ago

Glad you’re on the mend!! When you do revamp the library, can you make it a . NET MAUI class library project as opposed to the classic xam plugin model

alexrainman commented 1 year ago

That's the plan. All my plugins will be out for .NET MAUI

AlonRom commented 1 year ago

@alexrainman Hope you are feeling well! Happy to hear that a version with fixes will be released soon, we have been waiting for it for quite a long time. a Xamarin.Forms version with this fix will be released as well, right?

alexrainman commented 1 year ago

Yes, XF will be released in a minor version while .NET MAUI will be a major release.

NoamMani commented 1 year ago

@alexrainman any update?