Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Client certificates for Windows RT (windows 8.1/windows phone 8.1)

I am trying a new feature of windows 8.1 and windows phone 8.1 namely the certificate stores and possibility to use client certificates for client authentication on the server side. However I am having problems with this functionality.

I have a basic tested WCF service which runs on IIS express. IIS express is configured to support SSL and client certificates. In configuration file of IIS (configurationhost.config) I have set this:

<access sslFlags="SslRequireCert" /> (tried also SslNegotiateCert)
<clientCertificateMappingAuthentication enabled="true" />

I have added the client certificate within the Windows RT app as below:

//Install the self signed client cert to the user certificate store
string CACertificate = null;
try
{
    Uri uri = new Uri("ms-appx:///Assets/AdventureWorksTestClient1.pfx");
    var file = await Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(uri);
    IBuffer buffer = await FileIO.ReadBufferAsync(file);
    using (DataReader dataReader = DataReader.FromBuffer(buffer))
    {
       byte[] bytes = new byte[buffer.Length];
       dataReader.ReadBytes(bytes);
       // convert to Base64 for using with ImportPfx
       CACertificate = System.Convert.ToBase64String(bytes);
    }
    await CertificateEnrollmentManager.UserCertificateEnrollmentManager.ImportPfxDataAsync(
            CACertificate,
            "",
            ExportOption.Exportable,
            KeyProtectionLevel.NoConsent,
            InstallOptions.None,
            "ClientCert1");
 }
 catch (Exception ex)
 {...

Then I am using the HttpBaseProtocolFilter to which I add client certificate this way:

IReadOnlyCollection<Certificate> certs = await CertificateStores.FindAllAsync(query);

HttpBaseProtocolFilter bpf = new HttpBaseProtocolFilter();
if (certs.Count > 0)
{
    cert = certs.ElementAt(0);
    bpf.ClientCertificate = cert;
}
HttpClient httpClient = new HttpClient(bpf);
....

And then request:

var resp = await httpClient.GetAsync(new Uri(serviceURL));

This line of code is generating this exception:

{System.Exception: Exception from HRESULT: 0x80072F7D
  at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
  at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
  at JumpStartCertificateDemo.MainPage.<btnCallService_Click>d__0.MoveNext()}

I am 100% sure that I have imported right certificates also on localhost (local computer) and also on application side. Calling of service through browser is working properly. (I am prompted to provide client certificate), so there has to be some problem with providing client certificate in the application.

Can anyone help me on this one please? Thank you.

like image 685
marek_lani Avatar asked Sep 10 '14 11:09

marek_lani


People also ask

How do I enable client certificates?

On the taskbar, click Start, and then click Control Panel. In Control Panel, click Programs and Features, and then click Turn Windows Features on or off. Expand Internet Information Services, then select Client Certificate Mapping Authentication, and then click OK.


1 Answers

The problem could be related to the validity of the certificate that you are using it.

By default .Net refuses to establish https connection with invalid or not trusted certificate.

Usually the certificate is invalid because it is generate by a non-trusted authority (self signed certificate) or because the address of the site is not included in the valid addresses list for the certificate.

In .Net this limitation can be relaxed, see this discussion C# Ignore certificate errors?

like image 81
cristallo Avatar answered Oct 03 '22 04:10

cristallo