private X509Certificate2 ConvertPublicKeyCertificate(RTCertificate cert) { // Convert Windows X509v2 cert to .NET X509v2 cert. RTIBuffer blob = cert.GetCertificateBlob(); return(new X509Certificate2(blob.ToArray())); }
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]; } }
private async Task ApplyClientCertificateSettings() { if (ClientCertificateOptions == ClientCertificateOption.Manual) { if (_clientCertificates != null && _clientCertificates.Count > 0) { X509Certificate2 clientCert = CertificateHelper.GetEligibleClientCertificate(_clientCertificates); if (clientCert == null) { return; } RTCertificate rtClientCert = await CertificateHelper.ConvertDotNetClientCertToWinRtClientCertAsync(clientCert).ConfigureAwait(false); if (rtClientCert == null) { throw new PlatformNotSupportedException(SR.Format(CultureInfo.InvariantCulture, SR.net_http_feature_UWPClientCertSupportRequiresCertInPersonalCertificateStore)); } _rtFilter.ClientCertificate = rtClientCert; } return; } else { X509Certificate2 clientCert = CertificateHelper.GetEligibleClientCertificate(); if (clientCert == null) { return; } // Unlike in the .Manual case above, the conversion to WinRT Certificate should always work; // so we just use an Assert. All the possible client certs were enumerated from that store and // filtered down to a single client cert. RTCertificate rtClientCert = await CertificateHelper.ConvertDotNetClientCertToWinRtClientCertAsync(clientCert).ConfigureAwait(false); Debug.Assert(rtClientCert != null); _rtFilter.ClientCertificate = rtClientCert; } }
public async Task ConnectAsync(Uri uri, CancellationToken cancellationToken, ClientWebSocketOptions options) { InterlockedCheckAndUpdateState(WebSocketState.Connecting, s_validConnectStates); CheckValidState(s_validConnectingStates); _messageWebSocket = new MessageWebSocket(); foreach (var header in options.RequestHeaders) { _messageWebSocket.SetRequestHeader((string)header, options.RequestHeaders[(string)header]); } string cookies = options.Cookies == null ? null : options.Cookies.GetCookieHeader(uri); if (!string.IsNullOrEmpty(cookies)) { _messageWebSocket.SetRequestHeader(HeaderNameCookie, cookies); } var websocketControl = _messageWebSocket.Control; foreach (var subProtocol in options.RequestedSubProtocols) { websocketControl.SupportedProtocols.Add(subProtocol); } if (options.ClientCertificates.Count > 0) { if (!MessageWebSocketClientCertificateSupported) { throw new PlatformNotSupportedException(string.Format(CultureInfo.InvariantCulture, SR.net_WebSockets_UWPClientCertSupportRequiresWindows10GreaterThan1703)); } X509Certificate2 dotNetClientCert = CertificateHelper.GetEligibleClientCertificate(options.ClientCertificates); if (dotNetClientCert != null) { RTCertificate winRtClientCert = await CertificateHelper.ConvertDotNetClientCertToWinRtClientCertAsync(dotNetClientCert).ConfigureAwait(false); if (winRtClientCert == null) { throw new PlatformNotSupportedException(string.Format( CultureInfo.InvariantCulture, SR.net_WebSockets_UWPClientCertSupportRequiresCertInPersonalCertificateStore)); } websocketControl.ClientCertificate = winRtClientCert; } } // Try to opt into PartialMessage receive mode so that we can hand partial data back to the app as it arrives. // If the MessageWebSocketControl.ReceiveMode API surface is not available, the MessageWebSocket.MessageReceived // event will only get triggered when an entire WebSocket message has been received. This results in large memory // footprint and prevents "streaming" scenarios (e.g., WCF) from working properly. if (MessageWebSocketReceiveModeSupported) { // Always enable partial message receive mode if the WinRT API supports it. _messageWebSocket.Control.ReceiveMode = MessageWebSocketReceiveMode.PartialMessage; } try { _receiveAsyncBufferTcs = new TaskCompletionSource <ArraySegment <byte> >(); _closeWebSocketReceiveResultTcs = new TaskCompletionSource <WebSocketReceiveResult>(); _messageWebSocket.MessageReceived += OnMessageReceived; _messageWebSocket.Closed += OnCloseReceived; await _messageWebSocket.ConnectAsync(uri).AsTask(cancellationToken).ConfigureAwait(false); _subProtocol = _messageWebSocket.Information.Protocol; _messageWriter = new DataWriter(_messageWebSocket.OutputStream); } catch (Exception) { UpdateState(WebSocketState.Closed); throw; } UpdateState(WebSocketState.Open); }
private bool RTServerCertificateCallbackHelper( RTHttpRequestMessage requestMessage, RTCertificate cert, IReadOnlyList <RTCertificate> intermediateCerts, IReadOnlyList <RTChainValidationResult> certErrors) { // Convert WinRT certificate to .NET certificate. X509Certificate2 serverCert = CertificateHelper.ConvertPublicKeyCertificate(cert); // Create .NET X509Chain from the WinRT information. We need to rebuild the chain since WinRT only // gives us an array of intermediate certificates and not a X509Chain object. var serverChain = new X509Chain(); SslPolicyErrors sslPolicyErrors = SslPolicyErrors.None; foreach (RTCertificate intermediateCert in intermediateCerts) { serverChain.ChainPolicy.ExtraStore.Add(CertificateHelper.ConvertPublicKeyCertificate(cert)); } serverChain.ChainPolicy.RevocationMode = X509RevocationMode.Online; // WinRT always checks revocation. serverChain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot; // Authenticate the remote party: (e.g. when operating in client mode, authenticate the server). serverChain.ChainPolicy.ApplicationPolicy.Add(s_serverAuthOid); if (!serverChain.Build(serverCert)) { sslPolicyErrors |= SslPolicyErrors.RemoteCertificateChainErrors; } // Determine name-mismatch error from the existing WinRT information since .NET X509Chain.Build does not // return that in the X509Chain.ChainStatus fields. foreach (RTChainValidationResult result in certErrors) { if (result == RTChainValidationResult.InvalidName) { sslPolicyErrors |= SslPolicyErrors.RemoteCertificateNameMismatch; break; } } // Get the .NET HttpRequestMessage we saved in the property bag of the WinRT HttpRequestMessage. HttpRequestMessage request = (HttpRequestMessage)requestMessage.Properties[RequestMessageLookupKey]; // Call the .NET callback. bool success = false; try { success = _serverCertificateCustomValidationCallback(request, serverCert, serverChain, sslPolicyErrors); } catch (Exception ex) { // Save the exception info. We will return it later via the SendAsync response processing. requestMessage.Properties.Add( SavedExceptionDispatchInfoLookupKey, ExceptionDispatchInfo.Capture(ex)); } finally { serverChain.Dispose(); serverCert.Dispose(); } return(success); }