locked
Using installCertificateAsync to trust a server certificate before connecting RRS feed

  • Question

  • I'm trying to trust a server certificate before connecting with limited luck and am wondering if this is a supported workflow.  I have a .cer file on my Desktop that if I import it into "Trusted Root Certification Authorities", my connections to the server hostname with a SSL StreamSocket succeed.  But if I remove that from my trusted root certification authorities and try and programmatically trust it, I still get certificate verification errors.  I got this .cer file from connecting to the server in Internet Explorer in Desktop Mode, viewing the certificate, selecting "Copy to File...", and selecting "DER encoded binary X.509 (.CER)".

    Here is some sample code where I ask the user to select the .cer file, read it, base64-encode it, and pass the buffer into installCertificateAsync.  All of this code succeeds but my next call to connect to the server with SSL still fails with an invalid certificate error, even though the hostname I use matches the hostname of the certificate.

    var openPicker = new Windows.Storage.Pickers.FileOpenPicker(); 
    openPicker.viewMode = Windows.Storage.Pickers.PickerViewMode.thumbnail; 
    openPicker.suggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.desktop;
    openPicker.fileTypeFilter.replaceAll([".cer"]); 
     
    // Open the picker for the user to pick a file 
    openPicker.pickSingleFileAsync().then(function (file) {
       Windows.Storage.FileIO.readBufferAsync(file).then(
          function readSuccess(buffer) {
             var cert = Windows.Security.Cryptography.CryptographicBuffer.encodeToBase64String(buffer);
    
             mgr.installCertificateAsync(cert, 0).then(
                function certSuccess() {
                   var socket = new Windows.Networking.Sockets.StreamSocket();
                   socket.connectAsync(new Windows.Networking.HostName("broker.domain.int"), "443", Windows.Networking.Sockets.SocketProtectionLevel.ssl).then(
                      function success() {
                         // Blah.
                      },
                      function error(reason) {
                         // This is where the code gets to.
                      });
                },
                function certFailure(reason) {
                   // Blah.
                });
          },
          function readFailure(reason) {
             //Blah.
          });
    });

    Is this even supposed to work?  Or do I have to find a way to get the .pfx data instead and use importPfxDataAsync instead?

    Wednesday, August 8, 2012 6:55 PM

All replies

  • Is the certificate for the server known ahead of time?  If so you simply include it in your manifest and app data like this (see the last post):

    http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/4a776e8c-0e10-4f03-908f-7f765d914080

    -Jeff


    Jeff Sanders (MSFT)

    Thursday, August 9, 2012 5:32 PM
    Moderator
  • No, it's not known ahead of time.  I'm just trying to explore any possible solutions for a design where I'm already connected to a trusted server whose certificate is verifiable and then that server tells me to also connect to a different one, likely with a self-signed certificate.  I'm trying to figure out whether if the server sends me the certificate of the other server, I have some way to tell Windows that I trust that certificate so I will be able to connect.
    Thursday, August 9, 2012 5:50 PM
  • Bottom line,

    The mgr.installCertificateAsync should work.  Let me throw together a simple sample and give you some debugging hints.

    -Jeff


    Jeff Sanders (MSFT)

    Thursday, August 9, 2012 6:06 PM
    Moderator
  • Hi Jeff, any updates on this issue?  Thanks.
    Wednesday, August 15, 2012 5:49 PM
  • Adam,

    It appears this interface is for installing client certificates.  The import does import the cert but sets it in the CA store not the trusted root.  I am looking for verification form the product team but this does appear to be what that function does.

    -Jeff


    Jeff Sanders (MSFT)

    Wednesday, August 15, 2012 6:23 PM
    Moderator
  • Thanks for the answer.  That would appear to be consistent with the documentation, which says that the certificate info needs to have come from a createCertificateAsync function.  I would like to hear from them whether the only way to trust a server certificate dynamically in the program is to get the pfx certificate data and use importPfxDataAsync.  I sure would hope not, as that seems unnecessarily restrictive.
    Wednesday, August 15, 2012 6:44 PM
  • Hi Jeff,

    I'm in need of the exact same functionality as Adam (need to be able to make an SSL connection to a server whose certificate was not signed by a well known CA which I will also not know ahead of time and also in a Windows Store App that is nearing completion). I noticed that Adam's question dates from August so I thought I'd ask if any progress on this issue has been made since then. While I can certainly understand the need for a user's consent, not allowing SSL connections to an unknown CA at all seems restrictive.

    Thanks in advance for any reply,

    Markus.

    Tuesday, January 15, 2013 4:19 AM
  • Hi Markus,

    No, no change.    You may be able to find 3rd party libraries however if you need to do this.  I cannot recommend any however.

    -Jeff


    Jeff Sanders (MSFT)

    Wednesday, January 23, 2013 7:14 PM
    Moderator