Solution to Xamarin.Forms Android CERTIFICATE_VERIFY_FAILED

For those of you receiving the following error on Xamarin.Forms or .NET related apps using HttpClient along with a back-end using Certbot, I have found a fairly simple solution and a few workarounds.

I have been working on a Xamarin based app for the past few months. Lets Encrypt has made it a blast, however these past few days have not been. I was greeted with this error while trying to demonstrate my app:

Mono.Btls.MonoBtlsException: Ssl error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED

I checked to make sure my cert was renewed (it was), then I used SSL Checker to ensure my chain was correct (it was)

Update

Device Info:

  • Google Pixel 3a XL
  • Lineage OS 9 (Might be why the expired ca was not removed)

Server Info:

  • Nginx
  • Renewing certs with certbot

Solutions & Workarounds
So far in the GitHub thread, courtesy of Dalton, I have seen this solution for servers using certbot. There is an argument to prefer the new ISRG Root X1 CA:

--preferred-chain "ISRG Root X1"

Example:

certbot renew --preferred-chain "ISRG Root X1"

One thing to keep in mind is that when ISRG Root X1 inevitably expires September 30th 2024, you might need to modify the preferred chain to a new one.

After doing this, my new chain looks like this:

If this does not work, two workarounds are available.
One user on the GitHub says that manually removing the expired cert from the chain your server provides will fix the issue. Keep in mind you may have to manually update the fullchain when you renew your cert, unless you set the preferred CA.

The other workaround, that may or may not be viable, is to manually disable the expired DST Root CA X3 cert in the device settings. Trusted CAs are generally located here in the device settings:

Settings -> Security -> Encryption -> Trusted Credentials
2 Likes

Interesting but app users aren't going to do that to get stuff working. Can you provide an example API domain? If so I could check the cert chain being served.

2 Likes

My api domain is spiretown.fun

Running my domain through several certificate chain checking websites, all of them say my chain is correct, however I'm no expert and I might be reading the details wrong.

Update:
I updated the cached keychain on the ssl checker. My website is now sending a certificate chain without the expired CA. My solution was to change Certbot's preferred CA argument to be ISRG Root X1.
My new working cert chain:
https://www.sslshopper.com/ssl-checker.html#hostname=spiretown.fun

Some more info around Xamarin.Android for anyone looking into it:
I posted the exception that occurs when trying to connect using SignalR here.

Perhaps it has to do with the version of BoringSSL that Xamarin.Android or Mono is using? I don't know the implementation details.

This was happening with the ISRG Root X1 cert, issued to my kubernetes cluster through cert-manager.

Thanks for the link, hopefully this debacle will get sorted. For those who don't want to click and read for themselves, one suggestion is to remove the expired cert from your fullchain.pem, however I can't vouch for the validity of this claim. I plan to try it tomorrow morning.

2 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.