internal static extern uint InitializeSecurityContext(
     ref SecurityHandle phCredential,
     IntPtr phContext,
     string pszTargetName,
     int fContextReq,
     int Reserved1,
     int TargetDataRep,
     ref SecurityBufferDesc serverTokenDesc,
     int Reserved2,
     out SecurityHandle phNewContext,
     out SecurityBufferDesc pOutput,
     out uint pfContextAttr,
     out SecurityInteger ptsExpiry);
        /// <summary>
        /// Initialize SecurityContext with a server token.
        /// </summary>
        /// <param name="serverToken">Server Token</param>
        /// <exception cref="SspiException">If Initialize fail, this exception will be thrown.</exception>
        public override void Initialize(byte[] serverToken)
        {
            uint hResult;

            SecurityBuffer[] securityBuffers;
            if (this.packageType == SecurityPackageType.CredSsp)
            {
                //On calls to this function after the initial call, there must be two buffers.
                securityBuffers = new SecurityBuffer[2];
                //The first has type SECBUFFER_TOKEN and contains the token received from the server.
                securityBuffers[0] = new SecurityBuffer(SecurityBufferType.Token, serverToken);
                //The second buffer has type SECBUFFER_EMPTY; set both the pvBuffer and cbBuffer members to zero.
                securityBuffers[1] = new SecurityBuffer(SecurityBufferType.Empty, new byte[0]);
            }
            else
            {
                securityBuffers = new SecurityBuffer[] { new SecurityBuffer(SecurityBufferType.Token, serverToken) };
            }


            SecurityBuffer outTokenBuffer = new SecurityBuffer(
                SecurityBufferType.Token,
                new byte[Consts.MAX_TOKEN_SIZE]);

            SecurityBufferDescWrapper serverTokenDescWrapper = new SecurityBufferDescWrapper(securityBuffers);
            SecurityBufferDescWrapper outBufferDescWrapper   = new SecurityBufferDescWrapper(outTokenBuffer);
            uint            outContextAttribute;
            SecurityInteger expiryTime = new SecurityInteger();

            if (serverToken == null)
            {
                hResult = NativeMethods.InitializeSecurityContext(
                    ref this.credentialHandle,
                    IntPtr.Zero,
                    this.serverPrincipalName,
                    (int)this.securityContextAttributes,
                    0,
                    (int)this.targetDataRepresentaion,
                    IntPtr.Zero,
                    0,
                    out this.contextHandle,
                    out outBufferDescWrapper.securityBufferDesc,
                    out outContextAttribute,
                    out expiryTime);
            }
            else
            {
                if (this.contextHandle.LowPart == IntPtr.Zero && this.contextHandle.HighPart == IntPtr.Zero)
                {
                    hResult = NativeMethods.InitializeSecurityContext(
                        ref this.credentialHandle,
                        IntPtr.Zero,
                        this.serverPrincipalName,
                        (int)this.securityContextAttributes,
                        0,
                        (int)this.targetDataRepresentaion,
                        ref serverTokenDescWrapper.securityBufferDesc,
                        0,
                        out this.contextHandle,
                        out outBufferDescWrapper.securityBufferDesc,
                        out outContextAttribute,
                        out expiryTime);
                }
                else
                {
                    hResult = NativeMethods.InitializeSecurityContext(
                        ref this.credentialHandle,
                        ref this.contextHandle,
                        this.serverPrincipalName,
                        (int)this.securityContextAttributes,
                        0,
                        (int)this.targetDataRepresentaion,
                        ref serverTokenDescWrapper.securityBufferDesc,
                        0,
                        out this.contextHandle,
                        out outBufferDescWrapper.securityBufferDesc,
                        out outContextAttribute,
                        out expiryTime);
                }
            }

            serverTokenDescWrapper.FreeSecurityBufferDesc();

            if (hResult == NativeMethods.SEC_E_OK)
            {
                this.needContinueProcessing = false;
            }
            else if (hResult == NativeMethods.SEC_I_CONTINUE_NEEDED)
            {
                this.needContinueProcessing = true;
            }
            else
            {
                throw new SspiException("Initialize failed.", hResult);
            }

            //Get token if success.
            this.token = null;
            SspiSecurityBuffer[] outBuffers = outBufferDescWrapper.securityBufferDesc.GetBuffers();
            for (int i = 0; i < outBuffers.Length; i++)
            {
                if (outBuffers[i].bufferType == (uint)SecurityBufferType.Token)
                {
                    if (outBuffers[i].bufferLength > 0)
                    {
                        this.token = new byte[outBuffers[i].bufferLength];
                        Marshal.Copy(outBuffers[i].pSecBuffer, this.token, 0, this.token.Length);
                    }
                    break;
                }
            }
            outBufferDescWrapper.FreeSecurityBufferDesc();
        }
 internal static extern uint InitializeSecurityContext(
     ref SecurityHandle phCredential,
     IntPtr phContext,
     string pszTargetName,
     int fContextReq,
     int Reserved1,
     int TargetDataRep,
     ref SecurityBufferDesc serverTokenDesc,
     int Reserved2,
     out SecurityHandle phNewContext,
     out SecurityBufferDesc pOutput,
     out uint pfContextAttr,
     out SecurityInteger ptsExpiry);
 internal static extern uint AcquireCredentialsHandle(
     string pszPrincipal,
     string pszPacket,
     uint fCredentialUse,
     IntPtr PAuthenticationID,
     IntPtr pAuthData,
     IntPtr pGetKeyFn,
     IntPtr pvGetKeyArgument,
     out SecurityHandle phCredential,
     out SecurityInteger ptsExpiry);
 internal static extern uint AcceptSecurityContext(
     ref SecurityHandle phCredential,
     ref SecurityHandle phContext,
     ref SecurityBufferDesc pInput,
     uint fContextReq,
     uint TargetDataRep,
     ref SecurityHandle phNewContext,
     out SecurityBufferDesc pOutput,
     out uint pfContextAttr,
     out SecurityInteger ptsExpiry);
        public override void Initialize(byte[] serverToken)
        {
            uint hResult;
            SecurityBuffer[] securityBuffers;
            if (this.packageType == SecurityPackageType.CredSsp)
            {
                //On calls to this function after the initial call, there must be two buffers.
                securityBuffers = new SecurityBuffer[2];
                //The first has type SECBUFFER_TOKEN and contains the token received from the server.
                securityBuffers[0] = new SecurityBuffer(SecurityBufferType.Token, serverToken);
                //The second buffer has type SECBUFFER_EMPTY; set both the pvBuffer and cbBuffer members to zero.
                securityBuffers[1] = new SecurityBuffer(SecurityBufferType.Empty, new byte[0]);
            }
            else
            {
                securityBuffers = new SecurityBuffer[] { new SecurityBuffer(SecurityBufferType.Token, serverToken) };
            }

            SecurityBuffer outTokenBuffer = new SecurityBuffer(
                SecurityBufferType.Token,
                new byte[NativeMethods.MAX_TOKEN_SIZE]);

            SecurityBufferDescWrapper serverTokenDescWrapper = new SecurityBufferDescWrapper(securityBuffers);
            SecurityBufferDescWrapper outBufferDescWrapper = new SecurityBufferDescWrapper(outTokenBuffer);
            uint outContextAttribute;
            SecurityInteger expiryTime = new SecurityInteger();

            if (serverToken == null)
            {
                hResult = NativeMethods.InitializeSecurityContext(
                    ref this.credentialHandle,
                    IntPtr.Zero,
                    this.serverPrincipalName,
                    (int)this.securityContextAttributes,
                    0,
                    (int)this.targetDataRepresentaion,
                    IntPtr.Zero,
                    0,
                    out this.contextHandle,
                    out outBufferDescWrapper.securityBufferDesc,
                    out outContextAttribute,
                    out expiryTime);
            }
            else
            {
                if (this.contextHandle.LowPart == IntPtr.Zero && this.contextHandle.HighPart == IntPtr.Zero)
                {
                    hResult = NativeMethods.InitializeSecurityContext(
                        ref this.credentialHandle,
                        IntPtr.Zero,
                        this.serverPrincipalName,
                        (int)this.securityContextAttributes,
                        0,
                        (int)this.targetDataRepresentaion,
                        ref serverTokenDescWrapper.securityBufferDesc,
                        0,
                        out this.contextHandle,
                        out outBufferDescWrapper.securityBufferDesc,
                        out outContextAttribute,
                        out expiryTime);
                }
                else
                {
                    hResult = NativeMethods.InitializeSecurityContext(
                        ref this.credentialHandle,
                        ref this.contextHandle,
                        this.serverPrincipalName,
                        (int)this.securityContextAttributes,
                        0,
                        (int)this.targetDataRepresentaion,
                        ref serverTokenDescWrapper.securityBufferDesc,
                        0,
                        out this.contextHandle,
                        out outBufferDescWrapper.securityBufferDesc,
                        out outContextAttribute,
                        out expiryTime);
                }
            }

            serverTokenDescWrapper.FreeSecurityBufferDesc();

            if (hResult == NativeMethods.SEC_E_OK)
            {
                this.needContinueProcessing = false;
            }
            else if (hResult == NativeMethods.SEC_I_CONTINUE_NEEDED)
            {
                this.needContinueProcessing = true;
            }
            else
            {
                throw new SspiException("Initialize failed.", hResult);
            }

            //Get token if success.
            this.token = null;
            SspiSecurityBuffer[] outBuffers = outBufferDescWrapper.securityBufferDesc.GetBuffers();
            for (int i = 0; i < outBuffers.Length; i++)
            {
                if (outBuffers[i].bufferType == (uint)SecurityBufferType.Token)
                {
                    if (outBuffers[i].bufferLength > 0)
                    {
                        this.token = new byte[outBuffers[i].bufferLength];
                        Marshal.Copy(outBuffers[i].pSecBuffer, this.token, 0, this.token.Length);
                    }
                    break;
                }
            }
            outBufferDescWrapper.FreeSecurityBufferDesc();
        }
        internal static void DtlsAcquireCredentialsHandle(
            SecurityPackageType packageType,
            CertificateCredential certificateCredential,
            string serverPrincipal,
            uint fCredentialUse,
            out SecurityHandle credentialHandle)
        {
            string stringPackage = SspiUtility.GetPackageStringName(packageType);
            SecurityInteger expiryTime = new SecurityInteger();
            uint enabledProtocols;

            if (fCredentialUse == NativeMethods.SECPKG_CRED_OUTBOUND)
            {
                enabledProtocols = NativeMethods.SP_PROT_DTLS_CLIENT;
            }
            else
            {
                enabledProtocols = NativeMethods.SP_PROT_DTLS_SERVER;
            }

            SchannelCred schannelCred = new SchannelCred(certificateCredential, enabledProtocols);
            CredSspCred sspCred = new CredSspCred();
            IntPtr pAuthData = IntPtr.Zero;

            if (packageType == SecurityPackageType.Schannel)
            {
                pAuthData = SspiUtility.CreateAuthData(schannelCred);
            }
            else if (packageType == SecurityPackageType.CredSsp)
            {
                sspCred.pSchannelCred = SspiUtility.CreateAuthData(schannelCred);
                sspCred.pSpnegoCred = IntPtr.Zero;
                sspCred.Type = CredSspSubmitType.CredsspSubmitBufferBoth;
                pAuthData = SspiUtility.CreateAuthData(sspCred);
            }

            uint result = NativeMethods.AcquireCredentialsHandle(
                null,
                stringPackage,
                fCredentialUse,
                IntPtr.Zero,
                pAuthData,
                IntPtr.Zero,
                IntPtr.Zero,
                out credentialHandle,
                out expiryTime);
            //Free memory
            SspiUtility.FreeSchannelCred(schannelCred);
            if (pAuthData != IntPtr.Zero)
            {
                if (packageType == SecurityPackageType.CredSsp)
                {
                    Marshal.FreeHGlobal(sspCred.pSchannelCred);
                }
                Marshal.FreeHGlobal(pAuthData);
            }

            if (result != NativeMethods.SEC_E_OK)
            {
                throw new SspiException("AquireCredentialsHandle fails.", result);
            }
        }