private async Task ApplyClientCertificateSettings() { if (ClientCertificateOptions == ClientCertificateOption.Manual) { if (_clientCertificates != null && _clientCertificates.Count > 0) { RTCertificate cert = await CertificateHelper.ConvertDotNetClientCertToWinRtClientCertAsync(_clientCertificates[0]); if (cert == null) { throw new PlatformNotSupportedException(string.Format(CultureInfo.InvariantCulture, SR.net_http_feature_UWPClientCertSupportRequiresCertInPersonalCertificateStore)); } _rtFilter.ClientCertificate = cert; } return; } // Get the certs that can be used for Client Authentication. var query = new RTCertificateQuery(); var ekus = query.EnhancedKeyUsages; ekus.Add(ClientAuthenticationOID); var clientCertificates = await RTCertificateStores.FindAllAsync(query).AsTask().ConfigureAwait(false); if (clientCertificates.Count > 0) { _rtFilter.ClientCertificate = clientCertificates[0]; } }
// There are currently only two ways to convert a .NET X509Certificate2 object into a WinRT Certificate without // losing its private keys, each with its own limitations: // // (1) Using the X509Certificate2.Export method with PKCS12/PFX to obtain a byte[] representation (including private // keys) that can then be passed into the IBuffer-based WinRT Certificate constructor. Unfortunately, the // X509Certificate2.Export operation will only succeed if the app-provided X509Certificate2 object was created // with the non-default X509KeyStorageFlags.Exportable flag. // // (2) Going through the certificate store. That is, retrieving the certificate represented by the X509Certificate2 // object as a WinRT Certificate via WinRT CertificateStores APIs. Of course, this requires the certificate to // have been added to a certificate store in the first place. // // Furthermore, WinRT WebSockets only support certificates that have been added to the personal certificate store // (i.e., "MY" store) due to other WinRT-specific private key limitations. With that in mind, approach (2) is the // most appropriate for our needs, as it guarantees that WinRT WebSockets will be able to handle the resulting // WinRT Certificate during ConnectAsync. internal static async Task <RTCertificate> ConvertDotNetClientCertToWinRtClientCertAsync(X509Certificate2 dotNetCertificate) { var query = new RTCertificateQuery { Thumbprint = dotNetCertificate.GetCertHash(), IncludeDuplicates = false, StoreName = "MY" }; IReadOnlyList <RTCertificate> certificates = await RTCertificateStores.FindAllAsync(query).AsTask().ConfigureAwait(false); if (certificates.Count > 0) { return(certificates[0]); } return(null); }
private async Task ApplyClientCertificateSettings() { if (ClientCertificateOptions == ClientCertificateOption.Manual) { return; } // Get the certs that can be used for Client Authentication. var query = new RTCertificateQuery(); var ekus = query.EnhancedKeyUsages; ekus.Add(ClientAuthenticationOID); var clientCertificates = await RTCertificateStores.FindAllAsync(query).AsTask().ConfigureAwait(false); if (clientCertificates.Count > 0) { _rtFilter.ClientCertificate = clientCertificates[0]; } }
// There are currently only two ways to convert a .NET X509Certificate2 object into a WinRT Certificate without // losing its private keys, each with its own limitations: // // (1) Using the X509Certificate2.Export method with PKCS12/PFX to obtain a byte[] representation (including private // keys) that can then be passed into the IBuffer-based WinRT Certificate constructor. Unfortunately, the // X509Certificate2.Export operation will only succeed if the app-provided X509Certificate2 object was created // with the non-default X509KeyStorageFlags.Exportable flag. // // (2) Going through the certificate store. That is, retrieving the certificate represented by the X509Certificate2 // object as a WinRT Certificate via WinRT CertificateStores APIs. Of course, this requires the certificate to // have been added to a certificate store in the first place. // // Furthermore, WinRT WebSockets only support certificates that have been added to the personal certificate store // (i.e., "MY" store) due to other WinRT-specific private key limitations. With that in mind, approach (2) is the // most appropriate for our needs, as it guarantees that WinRT WebSockets will be able to handle the resulting // WinRT Certificate during ConnectAsync. private static RTCertificate ConvertDotNetClientCertToWinRtClientCert(X509Certificate2 dotNetCertificate) { var query = new RTCertificateQuery { Thumbprint = dotNetCertificate.GetCertHash(), IncludeDuplicates = false, StoreName = "MY" }; IReadOnlyList <RTCertificate> certificates = RTCertificateStores.FindAllAsync(query).AsTask().GetAwaiter().GetResult(); if (certificates.Count > 0) { return(certificates[0]); } throw new PlatformNotSupportedException(string.Format( CultureInfo.InvariantCulture, SR.net_WebSockets_UWPClientCertSupportRequiresCertInPersonalCertificateStore)); }