private bool GenServerContext(AuthenticationToken token)
        {
            bool new_context = _new_context;

            _new_context = false;
            using (DisposableList list = new DisposableList())
            {
                SecBuffer     out_sec_buffer  = list.AddResource(new SecBuffer(SecBufferType.Token, 64 * 1024));
                SecBufferDesc out_buffer_desc = list.AddResource(new SecBufferDesc(out_sec_buffer));

                List <SecBuffer> buffers = new List <SecBuffer>();
                buffers.Add(list.AddResource(new SecBuffer(SecBufferType.Token, token.ToArray())));
                if (_channel_binding != null)
                {
                    buffers.Add(list.AddResource(SecBuffer.CreateForChannelBinding(_channel_binding)));
                }
                SecBufferDesc in_buffer_desc = list.AddResource(new SecBufferDesc(buffers.ToArray()));

                LargeInteger  expiry = new LargeInteger();
                SecStatusCode result = SecurityNativeMethods.AcceptSecurityContext(_creds.CredHandle, new_context ? null : _context,
                                                                                   in_buffer_desc, _req_flags, _data_rep, _context, out_buffer_desc, out AcceptContextRetFlags context_attr, expiry).CheckResult();
                Flags  = context_attr;
                Expiry = expiry.QuadPart;
                if (result == SecStatusCode.CompleteNeeded || result == SecStatusCode.CompleteAndContinue)
                {
                    SecurityNativeMethods.CompleteAuthToken(_context, out_buffer_desc).CheckResult();
                }

                Token = AuthenticationToken.Parse(_creds.PackageName, _token_count++, false, out_buffer_desc.ToArray()[0].ToArray());
                return(!(result == SecStatusCode.ContinueNeeded || result == SecStatusCode.CompleteAndContinue));
            }
        }
        internal static SecStatusCode InitializeSecurityContext(
            CredentialHandle credential,
            SecHandle context,
            string target_name,
            InitializeContextReqFlags req_attributes,
            SecDataRep data_rep,
            IList <SecurityBuffer> input,
            SecHandle new_context,
            IList <SecurityBuffer> output,
            out InitializeContextRetFlags ret_attributes,
            LargeInteger expiry,
            bool throw_on_error)
        {
            using (DisposableList list = new DisposableList())
            {
                var input_buffers  = input?.ToBufferList(list);
                var output_buffers = output?.ToBufferList(list);

                var in_buffer_desc  = input_buffers.ToDesc(list);
                var out_buffer_desc = output_buffers.ToDesc(list);

                var result = SecurityNativeMethods.InitializeSecurityContext(credential.CredHandle,
                                                                             context, target_name, req_attributes, 0, data_rep, in_buffer_desc, 0,
                                                                             new_context, out_buffer_desc, out ret_attributes, expiry).CheckResult(throw_on_error);
                if (!result.IsSuccess())
                {
                    return(result);
                }

                try
                {
                    if (result == SecStatusCode.SEC_I_COMPLETE_NEEDED || result == SecStatusCode.SEC_I_COMPLETE_AND_CONTINUE)
                    {
                        var comp_result = SecurityNativeMethods.CompleteAuthToken(new_context, out_buffer_desc).CheckResult(throw_on_error);
                        if (!comp_result.IsSuccess())
                        {
                            return(comp_result);
                        }
                    }
                }
                finally
                {
                    if (result.IsSuccess())
                    {
                        output?.UpdateBuffers(out_buffer_desc);
                    }
                }

                return(result);
            }
        }
        private bool GenClientContext(AuthenticationToken token)
        {
            using (DisposableList list = new DisposableList())
            {
                SecStatusCode result = 0;

                SecBuffer     out_sec_buffer  = list.AddResource(new SecBuffer(SecBufferType.Token, 64 * 1024));
                SecBufferDesc out_buffer_desc = list.AddResource(new SecBufferDesc(out_sec_buffer));

                InitializeContextRetFlags flags;
                LargeInteger expiry = new LargeInteger();
                if (token != null)
                {
                    List <SecBuffer> buffers = new List <SecBuffer>();
                    buffers.Add(list.AddResource(new SecBuffer(SecBufferType.Token, token.ToArray())));
                    if (_channel_binding != null)
                    {
                        buffers.Add(list.AddResource(SecBuffer.CreateForChannelBinding(_channel_binding)));
                    }
                    SecBufferDesc in_buffer_desc = list.AddResource(new SecBufferDesc(buffers.ToArray()));
                    result = SecurityNativeMethods.InitializeSecurityContext(_creds.CredHandle, _context, _target, _req_attributes, 0,
                                                                             _data_rep, in_buffer_desc, 0, _context, out_buffer_desc, out flags, expiry).CheckResult();
                    Flags = flags;
                }
                else
                {
                    SecBufferDesc    in_buffer_desc = null;
                    List <SecBuffer> buffers        = new List <SecBuffer>();
                    if (_channel_binding != null)
                    {
                        buffers.Add(list.AddResource(SecBuffer.CreateForChannelBinding(_channel_binding)));
                        in_buffer_desc = list.AddResource(new SecBufferDesc(buffers.ToArray()));
                    }

                    result = SecurityNativeMethods.InitializeSecurityContext(_creds.CredHandle, null, _target,
                                                                             _req_attributes, 0, _data_rep, in_buffer_desc, 0, _context,
                                                                             out_buffer_desc, out flags, expiry).CheckResult();
                }

                Expiry = expiry.QuadPart;
                Flags  = flags;
                if (result == SecStatusCode.CompleteNeeded || result == SecStatusCode.CompleteAndContinue)
                {
                    SecurityNativeMethods.CompleteAuthToken(_context, out_buffer_desc).CheckResult();
                }

                Token = AuthenticationToken.Parse(_creds.PackageName, _token_count++, true, out_buffer_desc.ToArray()[0].ToArray());
                return(!(result == SecStatusCode.ContinueNeeded || result == SecStatusCode.CompleteAndContinue));
            }
        }