public static extern int AcceptSecurityContext(ref SecurityHandle phCredential,
     ref SecurityHandle phContext,
     ref SecurityBufferDesciption pInput,
     uint fContextReq,
     uint TargetDataRep,
     out SecurityHandle phNewContext,
     out SecurityBufferDesciption pOutput,
     out uint pfContextAttr,
     out SecurityInteger ptsTimeStamp);
 public static extern int AcquireCredentialsHandle(
     string pszPrincipal,
     string pszPackage,
     int fCredentialUse,
     IntPtr PAuthenticationID,
     IntPtr pAuthData,
     int pGetKeyFn,
     IntPtr pvGetKeyArgument,
     ref SecurityHandle phCredential,
     ref SecurityInteger ptsExpiry);
        /// <summary>
        /// Try to acquire the server challenge for this state
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public bool TryAcquireServerChallenge(ref byte[] message)
        {
            SecurityBufferDesciption clientToken = new SecurityBufferDesciption(message);
            SecurityBufferDesciption serverToken = new SecurityBufferDesciption(Common.MaximumTokenSize);

            try
            {
                int result;
                var lifetime = new SecurityInteger(0);

                result = Interop.AcquireCredentialsHandle(
                    null,
                    "NTLM",
                    Common.SecurityCredentialsInbound,
                    IntPtr.Zero,
                    IntPtr.Zero,
                    0,
                    IntPtr.Zero,
                    ref this.Credentials,
                    ref lifetime);

                if (result != Common.SuccessfulResult)
                {
                    // Credentials acquire operation failed.
                    return false;
                }

                uint contextAttributes;

                result = Interop.AcceptSecurityContext(
                    ref this.Credentials,                       // [in] handle to the credentials
                    IntPtr.Zero,                                // [in/out] handle of partially formed context.  Always NULL the first time through
                    ref clientToken,                            // [in] pointer to the input buffers
                    Common.StandardContextAttributes,           // [in] required context attributes
                    Common.SecurityNativeDataRepresentation,    // [in] data representation on the target
                    out this.Context,                           // [in/out] receives the new context handle    
                    out serverToken,                            // [in/out] pointer to the output buffers
                    out contextAttributes,                      // [out] receives the context attributes        
                    out lifetime);                              // [out] receives the life span of the security context

                if (result != Common.IntermediateResult)
                {
                    // Client challenge issue operation failed.
                    return false;
                }
            }
            finally
            {
                message = serverToken.GetBytes();
                clientToken.Dispose();
                serverToken.Dispose();
            }

            return true;
        }
        /// <summary>
        /// Validate the client response and fill the indentity of the token
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public bool IsClientResponseValid(byte[] message)
        {
            SecurityBufferDesciption clientToken = new SecurityBufferDesciption(message);
            SecurityBufferDesciption serverToken = new SecurityBufferDesciption(Common.MaximumTokenSize);
            IntPtr securityContextHandle = IntPtr.Zero;

            try
            {
                int result;
                uint contextAttributes;
                var lifetime = new SecurityInteger(0);

                result = Interop.AcceptSecurityContext(
                    ref this.Credentials,                       // [in] handle to the credentials
                    ref this.Context,                           // [in/out] handle of partially formed context.  Always NULL the first time through
                    ref clientToken,                            // [in] pointer to the input buffers
                    Common.StandardContextAttributes,           // [in] required context attributes
                    Common.SecurityNativeDataRepresentation,    // [in] data representation on the target
                    out this.Context,                           // [in/out] receives the new context handle    
                    out serverToken,                            // [in/out] pointer to the output buffers
                    out contextAttributes,                      // [out] receives the context attributes        
                    out lifetime);                              // [out] receives the life span of the security context

                if (result != Common.SuccessfulResult)
                {
                    return false;
                }
                                
                if (Interop.QuerySecurityContextToken(ref this.Context, ref securityContextHandle) != 0)
                {
                    return false;
                }

                var identity = new WindowsIdentity(securityContextHandle);

                if (identity == null)
                {
                    return false;
                }

                this.WindowsIdentity = identity;

            }
            finally
            {
                clientToken.Dispose();
                serverToken.Dispose();

                Interop.CloseHandle(securityContextHandle);

                this.Credentials.Reset();
                this.Context.Reset();
            }

            return true;
        }