0

I have this Android app that is already published to the store, and was working just fine. Suddenly, it began to throw some exceptions, which I already explained and solved here. After solvind this issue, the app began to throw java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. After some research, I found out that I had to create a HttpClientHandler to reference my certificate. So, here's my Login method, which is the first API call ever made in the app:

public static async Task<Usuario> Login(UsuarioLogin login)
{
    try
    {
        var handler = new HttpClientHandler();
        handler.ClientCertificateOptions = ClientCertificateOption.Manual;
        handler.SslProtocols = System.Security.Authentication.SslProtocols.Tls12;
        handler.ClientCertificates.Add(new X509Certificate2(Resources.certificadopem)); // certificadopem is my PEM format certificate file

        using (HttpClient client = new HttpClient(handler))
        {
            var json = JsonConvert.SerializeObject(login);
            var content = new StringContent(json, Encoding.UTF8, "application/json");
            var response = await client.PostAsync(ModelUrl, content); // exception is thrown when debugger tries to execute this line
            var response2 = await response.Content.ReadAsStringAsync();

            return JsonConvert.DeserializeObject<Usuario>(response2);
        }
    }
    catch (Exception e)
    {
        Console.WriteLine(e.Message);
        throw new Exception(e.Message);
    }
}

But now I am getting this exception: System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.

The inner exception is: {System.Security.Authentication.AuthenticationException} and the message says: Authentication failed, see inner exception.

The second inner exception is: Mono.Btls.MonoBtlsException and the message says: Ssl error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED at /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/external/boringssl/ssl/handshake_client.c:1132

I ran this openssl command openssl s_client -connect apigraos.copercana.com.br:443 to check the certificate authorities and this is the result:

C:\WINDOWS\system32>openssl s_client -connect apigraos.copercana.com.br:443
CONNECTED(000001B8)
depth=0 C = BR, ST = S\C3\A3o Paulo, L = Sert\C3\A3ozinho, O = COOPERATIVA DOS PLANTADORES DE CANA DO OESTE DO ESTADO SAO PAULO, CN = *.copercana.com.br
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 C = BR, ST = S\C3\A3o Paulo, L = Sert\C3\A3ozinho, O = COOPERATIVA DOS PLANTADORES DE CANA DO OESTE DO ESTADO SAO PAULO, CN = *.copercana.com.br
verify error:num=21:unable to verify the first certificate
verify return:1
depth=0 C = BR, ST = S\C3\A3o Paulo, L = Sert\C3\A3ozinho, O = COOPERATIVA DOS PLANTADORES DE CANA DO OESTE DO ESTADO SAO PAULO, CN = *.copercana.com.br
verify return:1
---
Certificate chain
 0 s:C = BR, ST = S\C3\A3o Paulo, L = Sert\C3\A3ozinho, O = COOPERATIVA DOS PLANTADORES DE CANA DO OESTE DO ESTADO SAO PAULO, CN = *.copercana.com.br
   i:C = US, O = DigiCert Inc, OU = www.digicert.com, CN = Thawte TLS RSA CA G1
   a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
   v:NotBefore: Apr  3 00:00:00 2023 GMT; NotAfter: Apr  5 23:59:59 2024 GMT
 1 s:C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
   i:C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
   a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA1
   v:NotBefore: Nov 10 00:00:00 2006 GMT; NotAfter: Nov 10 00:00:00 2031 GMT
 2 s:C = US, O = DigiCert Inc, OU = www.digicert.com, CN = Thawte RSA CA 2018
   i:C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
   a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
   v:NotBefore: Nov  6 12:23:52 2017 GMT; NotAfter: Nov  6 12:23:52 2027 GMT
---

How can I fix this issue without ignoring all the security stuff?

Gabic
  • 484
  • 1
  • 6
  • 15
  • 1
    **That server is sending the wrong chain cert**; note in your `openssl s_client` that `0 i:` is different from `2 s:` (and even more from `1 s:`), hence the error 20. With real OpenSSL 1.0.2 up if you add to your local truststore the correct chain cert, which you can get using AIA.caissuers from the leaf cert, it will be used for validation and succeed; I don't know if BoringSSL (which in case you don't know started as a fork of OpenSSL) has this, but it is probably worth trying. If you have a relationship with the site, you should also request they correct the server. – dave_thompson_085 Apr 17 '23 at 19:03
  • I spoke to our server manager about the differences you quoted, so he re-uploaded the root and intermediate certificates, and it is (kinda) working now. The API calls are returning 404, but I think that's another issue, and we will try to reach the host admin about it. Do you want to elaborate a complete answer, so I can accept it? – Gabic Apr 17 '23 at 20:48

0 Answers0