0

I am facing an issue regarding certificate pinning on Xamarin Forms, bot android and ios.

public static async Task<HttpResponseMessage> SendWebApiRequest(HttpRequestMessage msg)
    {
        try
        {
            int timeout = 60;
            var handler = new HttpClientHandler
            {
                UseProxy = true,
                AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
            };
            handler.SslProtocols = System.Security.Authentication.SslProtocols.Tls12;
            handler.ServerCertificateCustomValidationCallback = CheckCertificate;
            using (HttpClient client = new HttpClient(handler))
            {
                client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
                client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate"));
                using (CancellationTokenSource cts = new CancellationTokenSource())
                {
                    cts.CancelAfter(TimeSpan.FromSeconds(timeout));

                    HttpResponseMessage reply = await client.SendAsync(msg, cts.Token);
                    ProcessResponseStatus(reply);
                    if (reply.StatusCode == HttpStatusCode.Unauthorized)
                        throw new InvalidOperationException("The authentication failed. Please logout and logback in with a valid account");

                    return reply;
                }
            }
        }
        catch (InvalidOperationException) {
            throw new InvalidOperationException("There was an issue connecting with the server, please try again later or contact support.");
        }
        catch (WebApiServiceExceptions) { throw new WebApiServiceExceptions(WebApiServiceExceptionType.NoInternetAccess, "No internet connection detect! Please check your internet connection!"); }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            throw new Exception("There was an issue connecting with the server, please try again later or contact support.");
        }
    }

    private static bool CheckCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslpolicyerrors)
    {
        var publicKey = "MY PUBLIC KEY";
        return publicKey == certificate?.GetPublicKeyString();
    }

It was working fine but suddenly started throwing errors "The SSL connection could not be established, see inner exception."

On Android Ssl error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED Stack Trace: at Mono.Net.Security.MobileAuthenticatedStream.ProcessAuthentication (System.Boolean runSynchronously, Mono.Net.Security.MonoSslAuthenticationOptions options, System.Threading.CancellationToken cancellationToken) [0x0025c] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/System/Mono.Net.Security/MobileAuthenticatedStream.cs:310 at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore (System.IO.Stream stream, System.Net.Security.SslClientAuthenticationOptions sslOptions, System.Threading.CancellationToken cancellationToken) [0x0007b] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/external/corefx/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs:165

On iOS The authentication or decryption has failed. Stack Trace: at Mono.AppleTls.AppleTlsContext.EvaluateTrust () [0x000c7] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/mcs/class/System/Mono.AppleTls/AppleTlsContext.cs:307 at Mono.AppleTls.AppleTlsContext.ProcessHandshake () [0x00075] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/mcs/class/System/Mono.AppleTls/AppleTlsContext.cs:213 at Mono.Net.Security.MobileAuthenticatedStream.ProcessHandshake (Mono.Net.Security.AsyncOperationStatus status, System.Boolean renegotiate) [0x000da] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/mcs/class/System/Mono.Net.Security/MobileAuthenticatedStream.cs:715 at Mono.Net.Security.AsyncHandshakeRequest.Run (Mono.Net.Security.AsyncOperationStatus status) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/mcs/class/System/Mono.Net.Security/AsyncProtocolRequest.cs:289 at Mono.Net.Security.AsyncProtocolRequest.ProcessOperation (System.Threading.CancellationToken cancellationToken) [0x000fc] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/mcs/class/System/Mono.Net.Security/AsyncProtocolRequest.cs:223

P.S: It is an Azure function app certificate.

user5678
  • 17
  • 8
  • The easiest way to implement certificate pinning is using modernhttpclient. Here’s the steps you’d need to follow: https://stackoverflow.com/a/67135258/11104068 – Saamer Aug 29 '21 at 03:43
  • is your endpoint `http` or `https`? in case that is `http` only, you should add a network security config on Android and NSAppTransportSecurity in the `info.plist` for your iOS app. – FabriBertani Aug 29 '21 at 23:58
  • @FabriBertani it is https. I kinda figured the issue. After the deployment to the server, public key of the certificate was changed but became stable after sometime. Not sure what happened, maybe was changed to staging env at Microsoft end? – user5678 Aug 30 '21 at 00:23

1 Answers1

0

Bypass the certificate using this code:

HttpClientHandler clientHandler = new HttpClientHandler();
clientHandler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; };
HttpClient client = new HttpClient(clientHandler);
El0din
  • 3,208
  • 3
  • 20
  • 31