Search code examples
c#wcfxamarin.formsxamarin.uwpcertificate-pinning

Certificate Pinning on UWP


We have a Xamarin.Forms project that is currently compiled for Android, iOS and UWP using .NET Standard 2.0 for the shared project.

The communications is performed through a WCF Service Contract.

In order to pin the certificate we implemented the following code as per examples. This works correctly on Android and iOS after making sure that are using the necessary HttpClient implementations under their project properties.

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
ServicePointManager.ServerCertificateValidationCallback = ValidateServerCertificate;

private bool ValidateServerCertificate(object sender,
                                       X509Certificate certificate,
                                       X509Chain chain,
                                       SslPolicyErrors sslPolicyErrors)
{
    // Make sure we have a certificate to check.
    if (certificate == null)
    {
        return false;
    }

    if (sslPolicyErrors != SslPolicyErrors.None)
    {
        return false;
    }

    return this.KnownKeys.Contains(certificate.GetCertHashString(), 
                                   StringComparer.Ordinal);
}

UWP however is proving to be rather stubborn. I am unable to get the callback to fire at any stage of the communications.

I have also looked in to implementing our own X509CertificateValidator and supplying it to the WCF config however that also does nothing.

Questions

  1. Do I need to/Am I able to specify a HttpClient implementation under UWP much like you can for Android and iOS that will fix this?
  2. Is there another approach that I am currently missing?

Solution

  • I would suggest you to use the HttpBaseProtocolFilter Class in the Windows.Web.Http Namespace in you UWP app. With the HttpBaseProtocolFilter instance, you can subscribe HttpBaseProtocolFilter.ServerCustomValidationRequested event. In this event handler, you can perform extra validation (in addition to the OS default) of the server SSL certificate.