// TODO: Public when needed internal bool TryGetChannelBinding(ref ChannelBinding value) { if (!Request.IsHttps) { Logger.LogDebug("TryGetChannelBinding; Channel binding requires HTTPS."); return(false); } value = ClientCertLoader.GetChannelBindingFromTls(Server.RequestQueue, Request.UConnectionId, Logger); Debug.Assert(value != null, "GetChannelBindingFromTls returned null even though OS supposedly supports Extended Protection"); Logger.LogInformation("Channel binding retrieved."); return(value != null); }
// TODO: Public when needed internal bool TryGetChannelBinding(ref ChannelBinding?value) { if (!Request.IsHttps) { Log.ChannelBindingNeedsHttps(Logger); return(false); } value = ClientCertLoader.GetChannelBindingFromTls(Server.RequestQueue, Request.UConnectionId, Logger); Debug.Assert(value != null, "GetChannelBindingFromTls returned null even though OS supposedly supports Extended Protection"); Log.ChannelBindingRetrieved(Logger); return(value != null); }
private static unsafe void IOCompleted(ClientCertLoader asyncResult, uint errorCode, uint numBytes) { RequestContext requestContext = asyncResult.RequestContext; try { if (errorCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_MORE_DATA) { // There is a bug that has existed in http.sys since w2k3. Bytesreceived will only // return the size of the initial cert structure. To get the full size, // we need to add the certificate encoding size as well. HttpApiTypes.HTTP_SSL_CLIENT_CERT_INFO *pClientCertInfo = asyncResult.RequestBlob; asyncResult.Reset(numBytes + pClientCertInfo->CertEncodedSize); uint bytesReceived = 0; errorCode = HttpApi.HttpReceiveClientCertificate( requestContext.Server.RequestQueue.Handle, requestContext.Request.UConnectionId, (uint)HttpApiTypes.HTTP_FLAGS.NONE, asyncResult._memoryBlob, asyncResult._size, &bytesReceived, asyncResult._overlapped !); if (errorCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_IO_PENDING || (errorCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && !HttpSysListener.SkipIOCPCallbackOnSuccess)) { return; } } if (errorCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_NOT_FOUND) { // The client did not send a cert. asyncResult.Complete(0, null); } else if (errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS) { asyncResult.Fail(new HttpSysException((int)errorCode)); } else { HttpApiTypes.HTTP_SSL_CLIENT_CERT_INFO *pClientCertInfo = asyncResult._memoryBlob; if (pClientCertInfo == null) { asyncResult.Complete(0, null); } else { if (pClientCertInfo->pCertEncoded != null) { try { byte[] certEncoded = new byte[pClientCertInfo->CertEncodedSize]; Marshal.Copy((IntPtr)pClientCertInfo->pCertEncoded, certEncoded, 0, certEncoded.Length); asyncResult.Complete((int)pClientCertInfo->CertFlags, new X509Certificate2(certEncoded)); } catch (CryptographicException exception) { // TODO: Log asyncResult.Fail(exception); } catch (SecurityException exception) { // TODO: Log asyncResult.Fail(exception); } } } } } catch (Exception exception) { asyncResult.Fail(exception); } }