Beispiel #1
0
    // 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);
    }
Beispiel #2
0
    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);
        }
    }