System.Net.Security.NegoState.StartSendBlob C# (CSharp) Method

StartSendBlob() private method

private StartSendBlob ( byte message, LazyAsyncResult lazyResult ) : void
message byte
lazyResult LazyAsyncResult
return void
        private void StartSendBlob(byte[] message, LazyAsyncResult lazyResult)
        {
            Exception exception = null;
            if (message != s_emptyMessage)
            {
                message = GetOutgoingBlob(message, ref exception);
            }

            if (exception != null)
            {
                // Signal remote side on a failed attempt.
                StartSendAuthResetSignal(lazyResult, message, exception);
                return;
            }

            if (HandshakeComplete)
            {
                if (_context.IsServer && !CheckSpn())
                {
                    exception = new AuthenticationException(SR.net_auth_bad_client_creds_or_target_mismatch);
                    int statusCode = ERROR_TRUST_FAILURE;
                    message = new byte[8];  //sizeof(long)

                    for (int i = message.Length - 1; i >= 0; --i)
                    {
                        message[i] = (byte)(statusCode & 0xFF);
                        statusCode = (int)((uint)statusCode >> 8);
                    }

                    StartSendAuthResetSignal(lazyResult, message, exception);
                    return;
                }

                if (PrivateImpersonationLevel < _expectedImpersonationLevel)
                {
                    exception = new AuthenticationException(SR.Format(SR.net_auth_context_expectation, _expectedImpersonationLevel.ToString(), PrivateImpersonationLevel.ToString()));
                    int statusCode = ERROR_TRUST_FAILURE;
                    message = new byte[8];  //sizeof(long)

                    for (int i = message.Length - 1; i >= 0; --i)
                    {
                        message[i] = (byte)(statusCode & 0xFF);
                        statusCode = (int)((uint)statusCode >> 8);
                    }

                    StartSendAuthResetSignal(lazyResult, message, exception);
                    return;
                }

                ProtectionLevel result = _context.IsConfidentialityFlag ? ProtectionLevel.EncryptAndSign : _context.IsIntegrityFlag ? ProtectionLevel.Sign : ProtectionLevel.None;

                if (result < _expectedProtectionLevel)
                {
                    exception = new AuthenticationException(SR.Format(SR.net_auth_context_expectation, result.ToString(), _expectedProtectionLevel.ToString()));
                    int statusCode = ERROR_TRUST_FAILURE;
                    message = new byte[8];  //sizeof(long)

                    for (int i = message.Length - 1; i >= 0; --i)
                    {
                        message[i] = (byte)(statusCode & 0xFF);
                        statusCode = (int)((uint)statusCode >> 8);
                    }

                    StartSendAuthResetSignal(lazyResult, message, exception);
                    return;
                }

                // Signal remote party that we are done
                _framer.WriteHeader.MessageId = FrameHeader.HandshakeDoneId;
                if (_context.IsServer)
                {
                    // Server may complete now because client SSPI would not complain at this point.
                    _remoteOk = true;

                    // However the client will wait for server to send this ACK
                    //Force signaling server OK to the client
                    if (message == null)
                    {
                        message = s_emptyMessage;
                    }
                }
            }
            else if (message == null || message == s_emptyMessage)
            {
                throw new InternalException();
            }

            if (message != null)
            {
                //even if we are completed, there could be a blob for sending.
                if (lazyResult == null)
                {
                    _framer.WriteMessage(message);
                }
                else
                {
                    IAsyncResult ar = _framer.BeginWriteMessage(message, s_writeCallback, lazyResult);
                    if (!ar.CompletedSynchronously)
                    {
                        return;
                    }
                    _framer.EndWriteMessage(ar);
                }
            }
            CheckCompletionBeforeNextReceive(lazyResult);
        }