System.Net.HttpListener.GetChannelBindingFromTls C# (CSharp) Method

GetChannelBindingFromTls() private method

private GetChannelBindingFromTls ( ulong connectionId ) : ChannelBinding
connectionId ulong
return ChannelBinding
        internal ChannelBinding GetChannelBindingFromTls(ulong connectionId)
        {
            if (NetEventSource.IsEnabled) NetEventSource.Enter(this, $"connectionId: {connectionId}");

            // +128 since a CBT is usually <128 thus we need to call HRCC just once. If the CBT
            // is >128 we will get ERROR_MORE_DATA and call again
            int size = s_requestChannelBindStatusSize + 128;

            Debug.Assert(size >= 0);

            byte[] blob = null;
            Interop.HttpApi.SafeLocalFreeChannelBinding token = null;

            uint bytesReceived = 0;
            uint statusCode;

            do
            {
                blob = new byte[size];
                fixed (byte* blobPtr = blob)
                {
                    // Http.sys team: ServiceName will always be null if 
                    // HTTP_RECEIVE_SECURE_CHANNEL_TOKEN flag is set.
                    statusCode = Interop.HttpApi.HttpReceiveClientCertificate(
                        RequestQueueHandle,
                        connectionId,
                        (uint)Interop.HttpApi.HTTP_FLAGS.HTTP_RECEIVE_SECURE_CHANNEL_TOKEN,
                        blobPtr,
                        (uint)size,
                        &bytesReceived,
                        null);

                    if (statusCode == Interop.HttpApi.ERROR_SUCCESS)
                    {
                        int tokenOffset = GetTokenOffsetFromBlob((IntPtr)blobPtr);
                        int tokenSize = GetTokenSizeFromBlob((IntPtr)blobPtr);
                        Debug.Assert(tokenSize < Int32.MaxValue);

                        token = Interop.HttpApi.SafeLocalFreeChannelBinding.LocalAlloc(tokenSize);
                        if (token.IsInvalid)
                        {
                            throw new OutOfMemoryException();
                        }
                        Marshal.Copy(blob, tokenOffset, token.DangerousGetHandle(), tokenSize);
                    }
                    else if (statusCode == Interop.HttpApi.ERROR_MORE_DATA)
                    {
                        int tokenSize = GetTokenSizeFromBlob((IntPtr)blobPtr);
                        Debug.Assert(tokenSize < Int32.MaxValue);

                        size = s_requestChannelBindStatusSize + tokenSize;
                    }
                    else if (statusCode == Interop.HttpApi.ERROR_INVALID_PARAMETER)
                    {
                        if (NetEventSource.IsEnabled)
                        {
                            NetEventSource.Error(this, SR.net_ssp_dont_support_cbt);
                        }
                        return null; // old schannel library which doesn't support CBT
                    }
                    else
                    {
                        throw new HttpListenerException((int)statusCode);
                    }
                }
            } while (statusCode != Interop.HttpApi.ERROR_SUCCESS);

            return token;
        }