Untrusted HTTPS certificate

MartinStievenartMartinStievenart USMember, University

Hi,

I use System.Net.HttpClient to call my webservice in my PCL Forms project.
With HTTP everything works great, but now for the stagging environment the WS was passed in HTTPS with an untrusted certificate (it will be a trusted one in production).

I haven't seen any way online or in the forum to call an untrusted webservice in Xamarin.Forms.
The only thing i have seen is these kind of fix :

System.Net.ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(delegate { return true; });

But the ServicePointManager namespace is not available in PCL project.

Did anyone ever get that issue ? How did you solve it ?
Regards

Best Answer

Answers

  • MartinStievenartMartinStievenart USMember, University
    edited October 2015

    Thanks @AlessandroCaliaro for your answer.

    Do you think it's the only solution ?
    Cause for me it's not really a solution. Xamarin Forms is here to code WebServices call, database interaction only one for all platforms so with your solution i will lost that benefice.

    More the code i found for Android and iOS is just a callback, will it work if i implement it in every platform and call the depency service in the PCL and after make the regular httpclient call ?

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    Yes. Not all is PCL.
    HttpClient is PCL, other things aren't PCL.

    Don't be worried, I have used it and it works

  • MartinStievenartMartinStievenart USMember, University

    Ok @AlessandroCaliaro, i'll try this this morning and keep you aware of the result.

  • MartinStievenartMartinStievenart USMember, University

    I try your solution and as you said it worked.
    Thanks again @AlessandroCaliaro

  • JustinJoseph.8824JustinJoseph.8824 USMember ✭✭

    @AlessandroCaliaro The solution works like charm on Ios but it fails in Android. Is there any permission which needs to be added?

  • JustinJoseph.8824JustinJoseph.8824 USMember ✭✭

    @AlessandroCaliaro The solution works like charm on Ios but it fails in Android. Is there any permission which needs to be added

  • JustinJoseph.8824JustinJoseph.8824 USMember ✭✭

    @AlessandroCaliaro The solution works like charm on Ios but it fails in Android. Is there any permission which needs to be added?

  • zakzakzakzak INMember ✭✭

    Can you please share the code here to implement the same in PCL ? even i have this to do as Certificate Pinning.

  • Jarrod.LJarrod.L USMember

    @zakzak If you found an implementation for this, I would be very appreciative to see your implementation. I too need to implement certificate pinning via Xamarin Forms and I believe I need to implement validation on a per-platform basis. Here is a useful read if you haven't already found it: https://thomasbandt.com/certificate-and-public-key-pinning-with-xamarin

  • zakzakzakzak INMember ✭✭

    yes i do found implementation for this Certification Pinning, please find below the code.

    I have achieved this using Dependency service
    Basically my project is PCL

    So getting started with the code

    on iOS
    CertificateTrust.cs

    using System;
    using System.Net;
    using System.Security.Cryptography.X509Certificates;
    using System.Net.Security;
    using Xamarin.Forms;
    using CertificatePinning.iOS;
    
    [assembly: Dependency(typeof(CertificateTrust))]
    namespace CertificatePinning.iOS
    {
        public class CertificateTrust : ICertificateTrust
        {
            private static bool IsCertificateTrusted = false;
            public bool isCertificateTrusted()
            {
                //Certificate pinning code starts here
    
                // Set callback (deleagte)
                ServicePointManager.ServerCertificateValidationCallback = PinPublicKey;
    
                try
                {
                    // Request
                    WebRequest request = WebRequest.Create("https://news.google.com");
                    request.Timeout = 10000 /*milliseconds*/;
    
                    // Response
                    WebResponse response = request.GetResponse();
    
                }
                catch (Exception ex)
                {
    
                }
    
                return IsCertificateTrusted;
                //Certificate pinning code ends here
            }
    
            private static bool PinPublicKey(object sender, X509Certificate certificate, X509Chain chain,
                                    SslPolicyErrors sslPolicyErrors)
            {
                if (null == certificate)
                    return false;
    
                String pk = certificate.GetPublicKeyString();
                if (pk.Equals("04BD4D308546AD9ED3689DCB5A51D252CACD93D1FC3E21DCBF192D3177475622F88074A4C7AC5BB3DFEF4C4C3F194535356EC5A5DC19D2ED931E12839EC4565E6F"))
                {
                    IsCertificateTrusted = true;
                    return true;
                }
                else
                {
                    // Bad dog
                    IsCertificateTrusted = false;
                    return false;
                }
            }
        }
    }
    

    Creating Interface in PCL level
    ICertificateTrust.cs

    namespace CertificatePinning
    {
        public interface ICertificateTrust
        {
            bool isCertificateTrusted();
        }
    }
    

    and then in your PCL Login View or first view of the application code below
    LoginView.xaml.cs

    using System;
    using System.Linq;
    using System.Net;
    using Newtonsoft.Json;
    using Xamarin.Forms;
    using Plugin.Connectivity;
    using System.Threading.Tasks;
    using UIKit;
    
    namespace CertificatePinning.View
    {
        public partial class LoginView : ContentPage
        {
        public LoginView()
            {
            InitializeComponent();
                    BindingContext = this;
        }
    
        protected override void OnAppearing()
            {
                base.OnAppearing();
            CheckCertificateTrust();
        }
    
        private void CheckCertificateTrust()
            {
                if (Device.OS.Equals(TargetPlatform.iOS))
                {
                    var certificateValidate = DependencyService.Get<ICertificateTrust>();
                    if (certificateValidate != null)
                    {
                        if (!certificateValidate.isCertificateTrusted())
                        {
                            CertificateLabel.Text = "Certificate trust failed, Please try again later.";
                            Content = CertificateLayout;
                MainLayout.IsVisible = false;
                        }
                        else
                        {
                            MainLayout.IsVisible = true;
                        }
    
                    }
                }
            }
        }   
    }
    

    Hope the above implementation helps you., let me know if you guys have any issues implementing the same.

  • VegytzVegytz INMember

    Hi,
    I'm using System.Net.HttpClient for Http actions. I want to implement certificate validation. We are using xamarin forms but httpclient actions are in iOS and Android Project. I just implemented the ServicePointManager.ServerCertificateValidationCallback
    but the event is not firing. Can you help me please

    Thanks Arun

Sign In or Register to comment.