43

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.

Bharath theorare
  • 524
  • 7
  • 27
marek_lani
  • 3,895
  • 4
  • 29
  • 50
  • probably what you see is because the request for the cert is a WebException in C# that you need to handle by catching it. since you can't try catch you need to remove the await and use a task to validate the result in t.IsFaulted and check the t.Exception; – Pedro.The.Kid Sep 22 '14 at 14:05
  • Pedro thanks for the comment, but I am catching the exception (I know how to work with them), there is problem, that there should not be an exception because call of the get request should work as I am attaching the client cert and request works from the browser and also android. – marek_lani Sep 25 '14 at 06:39
  • No, In .Net depending on the request options a cert request throws an exception it is how it works, I have done it loads of times. WebException is thrown when you receive something in the 4XX response. Use fiddler to see what reply you get. – Pedro.The.Kid Sep 25 '14 at 09:43
  • I understand, but request should work. There should not be 4xx response. – marek_lani Oct 02 '14 at 20:14
  • that is basic HTTP protocol Every time you need to authenticate yourself you receive an authentication challenge it is a 4XX response turn on fiddler and open your email and see the 4XX messages. Sometimes you can pre authenticate but even in this case sometimes it takes several messages that's how HTTP works and there is no way around it. – Pedro.The.Kid Oct 06 '14 at 10:18
  • I am getting 403 response (forbiden), in browser request works, in android app request works, in WP app request does not works – marek_lani Oct 07 '14 at 20:56
  • Without more data I cant help you I recommend you install Microsoft Network Monitor and check the difference in each request, there WILL be several calls for each request, compare all. – Pedro.The.Kid Oct 08 '14 at 08:32
  • Did you get a solution to this? Is there a way to use the cert without installing it? – tofutim Jun 25 '15 at 21:37
  • @marek_lani, is this question still active? did you solve it, or should this remain open for investigation? – Kory Gill Jan 05 '16 at 23:46
  • Are you sure you will get success using Self-Signed Certificate? I mean, to conduct successfull checks in Certificates in my application Windows-forms, I had to utilize true certificates, because this way they are set also in MY Store and the Trusted Store... Perhaps the problem is related to that. – David BS Aug 10 '16 at 15:44

1 Answers1

1

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?

Community
  • 1
  • 1
cristallo
  • 1,951
  • 2
  • 25
  • 42