private static void OnRequestSendingRequest(WinHttpRequestState state) { Debug.Assert(state != null, "OnRequestSendingRequest: state is null"); if (state.RequestMessage.RequestUri.Scheme != UriScheme.Https) { // Not SSL/TLS. return; } // Grab the channel binding token (CBT) information from the request handle and put it into // the TransportContext object. state.TransportContext.SetChannelBinding(state.RequestHandle); if (state.ServerCertificateValidationCallback != null) { IntPtr certHandle = IntPtr.Zero; uint certHandleSize = (uint)IntPtr.Size; if (!Interop.WinHttp.WinHttpQueryOption( state.RequestHandle, Interop.WinHttp.WINHTTP_OPTION_SERVER_CERT_CONTEXT, ref certHandle, ref certHandleSize)) { int lastError = Marshal.GetLastWin32Error(); throw WinHttpException.CreateExceptionUsingError(lastError); } // Create a managed wrapper around the certificate handle. Since this results in duplicating // the handle, we will close the original handle after creating the wrapper. var serverCertificate = new X509Certificate2(certHandle); Interop.Crypt32.CertFreeCertificateContext(certHandle); X509Chain chain = null; SslPolicyErrors sslPolicyErrors; try { WinHttpCertificateHelper.BuildChain( serverCertificate, state.RequestMessage.RequestUri.Host, state.CheckCertificateRevocationList, out chain, out sslPolicyErrors); bool result = state.ServerCertificateValidationCallback( state.RequestMessage, serverCertificate, chain, sslPolicyErrors); if (!result) { throw WinHttpException.CreateExceptionUsingError( (int)Interop.WinHttp.ERROR_WINHTTP_SECURE_FAILURE); } } finally { if (chain != null) { chain.Dispose(); } } } }
private static void OnRequestSendingRequest(WinHttpRequestState state) { Debug.Assert(state != null, "OnRequestSendingRequest: state is null"); Debug.Assert(state.RequestHandle != null, "OnRequestSendingRequest: state.RequestHandle is null"); if (state.RequestMessage.RequestUri.Scheme != UriScheme.Https) { // Not SSL/TLS. return; } // Grab the channel binding token (CBT) information from the request handle and put it into // the TransportContext object. state.TransportContext.SetChannelBinding(state.RequestHandle); if (state.ServerCertificateValidationCallback != null) { IntPtr certHandle = IntPtr.Zero; uint certHandleSize = (uint)IntPtr.Size; if (!Interop.WinHttp.WinHttpQueryOption( state.RequestHandle, Interop.WinHttp.WINHTTP_OPTION_SERVER_CERT_CONTEXT, ref certHandle, ref certHandleSize)) { int lastError = Marshal.GetLastWin32Error(); throw WinHttpException.CreateExceptionUsingError(lastError); } // Create a managed wrapper around the certificate handle. Since this results in duplicating // the handle, we will close the original handle after creating the wrapper. var serverCertificate = new X509Certificate2(certHandle); Interop.Crypt32.CertFreeCertificateContext(certHandle); X509Chain chain = null; SslPolicyErrors sslPolicyErrors; try { WinHttpCertificateHelper.BuildChain( serverCertificate, state.RequestMessage.RequestUri.Host, state.CheckCertificateRevocationList, out chain, out sslPolicyErrors); bool result = state.ServerCertificateValidationCallback( state.RequestMessage, serverCertificate, chain, sslPolicyErrors); if (!result) { throw WinHttpException.CreateExceptionUsingError( (int)Interop.WinHttp.ERROR_WINHTTP_SECURE_FAILURE); } } finally { if (chain != null) { chain.Dispose(); } serverCertificate.Dispose(); } } }
private static void OnRequestSendingRequest(WinHttpRequestState state) { Debug.Assert(state != null, "OnRequestSendingRequest: state is null"); Debug.Assert(state.RequestHandle != null, "OnRequestSendingRequest: state.RequestHandle is null"); if (state.RequestMessage.RequestUri.Scheme != UriScheme.Https) { // Not SSL/TLS. return; } // Grab the channel binding token (CBT) information from the request handle and put it into // the TransportContext object. state.TransportContext.SetChannelBinding(state.RequestHandle); if (state.ServerCertificateValidationCallback != null) { IntPtr certHandle = IntPtr.Zero; uint certHandleSize = (uint)IntPtr.Size; if (!Interop.WinHttp.WinHttpQueryOption( state.RequestHandle, Interop.WinHttp.WINHTTP_OPTION_SERVER_CERT_CONTEXT, ref certHandle, ref certHandleSize)) { int lastError = Marshal.GetLastWin32Error(); WinHttpTraceHelper.Trace( "OnRequestSendingRequest: Error getting WINHTTP_OPTION_SERVER_CERT_CONTEXT, {0}", lastError); if (lastError == Interop.WinHttp.ERROR_WINHTTP_INCORRECT_HANDLE_STATE) { // Not yet an SSL/TLS connection. This occurs while connecting thru a proxy where the // CONNECT verb hasn't yet been processed due to the proxy requiring authentication. // We need to ignore this notification. Another notification will be sent once the final // connection thru the proxy is completed. return; } throw WinHttpException.CreateExceptionUsingError(lastError); } // Get any additional certificates sent from the remote server during the TLS/SSL handshake. X509Certificate2Collection remoteCertificateStore = UnmanagedCertificateContext.GetRemoteCertificatesFromStoreContext(certHandle); // Create a managed wrapper around the certificate handle. Since this results in duplicating // the handle, we will close the original handle after creating the wrapper. var serverCertificate = new X509Certificate2(certHandle); Interop.Crypt32.CertFreeCertificateContext(certHandle); X509Chain chain = null; SslPolicyErrors sslPolicyErrors; bool result = false; try { WinHttpCertificateHelper.BuildChain( serverCertificate, remoteCertificateStore, state.RequestMessage.RequestUri.Host, state.CheckCertificateRevocationList, out chain, out sslPolicyErrors); result = state.ServerCertificateValidationCallback( state.RequestMessage, serverCertificate, chain, sslPolicyErrors); } catch (Exception ex) { throw WinHttpException.CreateExceptionUsingError( (int)Interop.WinHttp.ERROR_WINHTTP_SECURE_FAILURE, ex); } finally { if (chain != null) { chain.Dispose(); } serverCertificate.Dispose(); } if (!result) { throw WinHttpException.CreateExceptionUsingError( (int)Interop.WinHttp.ERROR_WINHTTP_SECURE_FAILURE); } } }
private static void OnRequestSendingRequest(WinHttpRequestState state) { Debug.Assert(state != null, "OnRequestSendingRequest: state is null"); Debug.Assert(state.RequestHandle != null, "OnRequestSendingRequest: state.RequestHandle is null"); if (state.RequestMessage.RequestUri.Scheme != UriScheme.Https) { // Not SSL/TLS. return; } // Grab the channel binding token (CBT) information from the request handle and put it into // the TransportContext object. state.TransportContext.SetChannelBinding(state.RequestHandle); if (state.ServerCertificateValidationCallback != null) { IntPtr certHandle = IntPtr.Zero; uint certHandleSize = (uint)IntPtr.Size; if (!Interop.WinHttp.WinHttpQueryOption( state.RequestHandle, Interop.WinHttp.WINHTTP_OPTION_SERVER_CERT_CONTEXT, ref certHandle, ref certHandleSize)) { int lastError = Marshal.GetLastWin32Error(); WinHttpTraceHelper.Trace( "OnRequestSendingRequest: Error getting WINHTTP_OPTION_SERVER_CERT_CONTEXT, {0}", lastError); if (lastError == Interop.WinHttp.ERROR_WINHTTP_INCORRECT_HANDLE_STATE) { // Not yet an SSL/TLS connection. This occurs while connecting thru a proxy where the // CONNECT verb hasn't yet been processed due to the proxy requiring authentication. // We need to ignore this notification. Another notification will be sent once the final // connection thru the proxy is completed. return; } throw WinHttpException.CreateExceptionUsingError(lastError); } // Create a managed wrapper around the certificate handle. Since this results in duplicating // the handle, we will close the original handle after creating the wrapper. var serverCertificate = new X509Certificate2(certHandle); Interop.Crypt32.CertFreeCertificateContext(certHandle); X509Chain chain = null; SslPolicyErrors sslPolicyErrors; try { WinHttpCertificateHelper.BuildChain( serverCertificate, state.RequestMessage.RequestUri.Host, state.CheckCertificateRevocationList, out chain, out sslPolicyErrors); bool result = state.ServerCertificateValidationCallback( state.RequestMessage, serverCertificate, chain, sslPolicyErrors); if (!result) { throw WinHttpException.CreateExceptionUsingError( (int)Interop.WinHttp.ERROR_WINHTTP_SECURE_FAILURE); } } finally { if (chain != null) { chain.Dispose(); } serverCertificate.Dispose(); } } }