středa 13. srpna 2014

Ignore certificate errors on Windows & Windows Phone

Introduction

Our team is also currently working on .NET version of secured messaging application Babel. To put it simply, main goal is to port great and useful Android & iOS app to Windows desktop (Vista, 7, 8), Windows 8.1 (Metro) and Windows Phone 8.1 - both known as "Universal apps".
At first, I'll try to explain the problem. Except the mentioned Babel, we've got also the second version, targeted to corporations and called Babel Bussiness Edition. This one is based on fact, that every company owns their private server and all communication comes through this one, so there is no third-party server. There is an authentication based on certificate, which is signed by our company. Essentialy, when user connects to server we needs to verify server identity and depending on that enable or disable the communi- cation. Of course, .NET framework does not trust certificates, which he cannot find or successfully compare with any from root trusted certification authorities. When you will try to initialize server connection secured with these type of certs, an exception will be raised. In this blog post, I will try to describe how to easily ignore certificate errors on:

  • Windows desktop client (WPF, WinForms etc.)
  • Win 8 (Metro), Windows Phone 7, WP8, WP8.1 Silverlight
  • Windows 8.1, Windows Phone 8.1 RT - Universal apps

Windows desktop client

Pretty easy, well known stuff:
//Set certificate validation delegate
private void SetCertValidationDel()
{
  //you can use ServicePointManager class
  System.Net.ServicePointManager.ServerCertificateValidationCallback += CertValidation;
}

//This method will be raised, when initializing https connection
private static bool CertValidation(
object sender,
System.Security.Cryptography.X509Certificates.X509Certificate cert,
System.Security.Cryptography.X509Certificates.X509Chain chain,
System.Net.Security.SslPolicyErrors sslPolicyErrors)
    {
      return true;
      //All cert will be considered as valid - recommended for testing.
      //Or your own implementation of cert validation.
    }
}

Win 8, WP7, WP8, WP8.1 (Silverlight)

You simply cannot use previous example, because missing some classes like ServicePointManager, X509Chain etc. I've found two solutions for this problem:
  • Install certificate to root cert. store of device.
Upload the certificate somewhere on the internet (mail, cloud service etc.) and access it directly from concrete device. The cert will be installed automatically to device root certification store.
  • Install certificate to root store of application.
Using certificate extensions destribed here.
You'll need to export server cert to DER file, copy to application, set build action to "Content" and always copy to output directory. The last step is to edit package.appxmanifest file.

Windows 8.1, WP8.1 RT - Universal apps

Up until Windows 8.1 & WP8.1 you could not ignore certificate errors in Windows Store apps with classic System.Net.Http.HttpClient class. Now you can do this with new  namespace Windows.Web.Http and Windows.Web.Http.Filters.
//Initialize new instance of HttpBaseProtocolFilter, which implements IHttpFilter.
var filter = new HttpBaseProtocolFilter();
//Untrusted and Expired cert. errors will be ignored in this example:
filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.Untrusted);
filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.Expired);
//Initialize new instance of HttpClient with IHttpFilter parameter.
var httpClient = new Windows.Web.Http.HttpClient(filter);
The ChainValidationResult is simple Enum and a list of possible values can be found here. Note that you should use this technique only in very limited type of scenarios (tests etc.). You should ever ensure that target you are hitting is the correct endpoint instead of ignore certificate errors.

Žádné komentáře:

Okomentovat