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);
 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 VerifySignature(
     ref SecurityHandle phContext,
     ref SecurityBufferDesc pMessage,
     uint MessageSeqNo,
     out uint pfQOP);
        internal static byte[] QuerySessionKey(SecurityPackageType packageType, ref SecurityHandle contextHandle)
        {
            IntPtr pSessionKey = IntPtr.Zero;
            byte[] sessionKey = null;

            if (packageType == SecurityPackageType.Schannel || packageType == SecurityPackageType.CredSsp)
            {
                pSessionKey = Marshal.AllocHGlobal(SchannelKeySize + SchannelIvSize);
                uint hResult = NativeMethods.QueryContextAttributes(
                    ref contextHandle,
                    NativeMethods.SECPKG_ATTR_EAP_KEY_BLOCK,
                    pSessionKey);
                if (hResult == NativeMethods.SEC_E_OK)
                {
                    if (pSessionKey != IntPtr.Zero)
                    {
                        sessionKey = new byte[SchannelKeySize];
                        Marshal.Copy(pSessionKey, sessionKey, 0, SchannelKeySize);
                    }
                }
                Marshal.FreeHGlobal(pSessionKey);
            }
            else
            {
                pSessionKey = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SecurityPackageContextSessionKey)));
                uint hResult = NativeMethods.QueryContextAttributes(
                    ref contextHandle,
                    NativeMethods.SECPKG_ATTR_SESSION_KEY,
                    pSessionKey);
                if (hResult == NativeMethods.SEC_E_OK)
                {
                    if (pSessionKey != IntPtr.Zero)
                    {
                        SecurityPackageContextSessionKey contextSessionKey = (SecurityPackageContextSessionKey)
                            Marshal.PtrToStructure(pSessionKey, typeof(SecurityPackageContextSessionKey));

                        sessionKey = new byte[contextSessionKey.SessionKeyLength];
                        Marshal.Copy(contextSessionKey.SessionKey, sessionKey, 0, sessionKey.Length);
                        NativeMethods.FreeContextBuffer(contextSessionKey.SessionKey);
                    }
                }
                Marshal.FreeHGlobal(pSessionKey);
            }

            return sessionKey;
        }
 internal static extern uint MakeSignature(
     ref SecurityHandle phContext,
     uint fQOP,
     ref SecurityBufferDesc pMessage,
     uint MessageSeqNo);
        internal static bool Decrypt(
            ref SecurityHandle contextHandle,
            uint sequenceNumber,
            params SecurityBuffer[] securityBuffers)
        {
            SecurityBufferDescWrapper decryptBufferDescWrapper = new SecurityBufferDescWrapper(securityBuffers);
            //A variable of type ULONG that receives package-specific flags that indicate the quality of protection.
            //Only for out parameter.
            uint pfQop;

            uint hResult = NativeMethods.DecryptMessage(
                ref contextHandle,
                ref decryptBufferDescWrapper.securityBufferDesc,
                sequenceNumber,
                out pfQop);
            if (hResult == NativeMethods.SEC_E_OK)
            {
                SspiSecurityBuffer[] buffers = decryptBufferDescWrapper.securityBufferDesc.GetBuffers();
                for (int i = 0; i < securityBuffers.Length; i++)
                {
                    securityBuffers[i].Buffer = new byte[buffers[i].bufferLength];
                    if (buffers[i].pSecBuffer != IntPtr.Zero)
                    {
                        Marshal.Copy(buffers[i].pSecBuffer,
                            securityBuffers[i].Buffer,
                            0,
                            securityBuffers[i].Buffer.Length);
                        securityBuffers[i].BufferType = (SecurityBufferType)buffers[i].bufferType;
                    }
                }
                decryptBufferDescWrapper.FreeSecurityBufferDesc();
                return true;
            }
            else
            {
                decryptBufferDescWrapper.FreeSecurityBufferDesc();
                throw new SspiException("Decrypt failed.", hResult);
            }
        }
 internal static extern uint QueryContextAttributes(
     ref SecurityHandle phContext,
     uint ulAttribute,
     IntPtr pBuffer);
 internal static extern uint DeleteSecurityContext(ref SecurityHandle phContext);
 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 object QueryContextAttributes(ref SecurityHandle contextHandle, string contextAttribute)
        {
            uint attribute = 0;
            IntPtr pBuffer = IntPtr.Zero;
            string stringAttribute = contextAttribute.ToUpper(CultureInfo.InvariantCulture);

            switch (stringAttribute)
            {
                case SECPKG_ATTR_SIZES:
                    attribute = NativeMethods.SECPKG_ATTR_SIZES;
                    pBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SecurityPackageContextSizes)));
                    break;
                case SECPKG_ATTR_LIFESPAN:
                    attribute = NativeMethods.SECPKG_ATTR_LIFESPAN;
                    pBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SecurityPackageContextLifespan)));
                    break;
                case SECPKG_ATTR_STREAM_SIZES:
                    attribute = NativeMethods.SECPKG_ATTR_STREAM_SIZES;
                    pBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SecurityPackageContextStreamSizes)));
                    break;
                case SECPKG_ATTR_KEY_INFO:
                    attribute = NativeMethods.SECPKG_ATTR_KEY_INFO;
                    pBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SspiSecurityPackageContextKeyInfo)));
                    break;
                case SECPKG_ATTR_AUTHORITY:
                    attribute = NativeMethods.SECPKG_ATTR_AUTHORITY;
                    pBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SecurityPackageContextAuthority)));
                    break;
                case SECPKG_ATTR_PASSWORD_EXPIRY:
                    attribute = NativeMethods.SECPKG_ATTR_PASSWORD_EXPIRY;
                    pBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SecurityInteger)));
                    break;
                case SECPKG_ATTR_SESSION_KEY:
                    attribute = NativeMethods.SECPKG_ATTR_SESSION_KEY;
                    pBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SecurityPackageContextSessionKey)));
                    break;
                case SECPKG_ATTR_PACKAGE_INFO:
                    attribute = NativeMethods.SECPKG_ATTR_PACKAGE_INFO;
                    pBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)));
                    break;
                case SECPKG_ATTR_NEGOTIATION_INFO:
                    attribute = NativeMethods.SECPKG_ATTR_NEGOTIATION_INFO;
                    pBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SspiSecurityPackageContextNegotiationInfo)));
                    break;
                case SECPKG_ATTR_NATIVE_NAMES:
                    attribute = NativeMethods.SECPKG_ATTR_NATIVE_NAMES;
                    pBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SspiSecurityPackageContextNativeNames)));
                    break;
                case SECPKG_ATTR_FLAGS:
                    attribute = NativeMethods.SECPKG_ATTR_FLAGS;
                    pBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(uint)));
                    break;
                case SECPKG_ATTR_TARGET_INFORMATION:
                    attribute = NativeMethods.SECPKG_ATTR_TARGET_INFORMATION;
                    pBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SecurityPackageContextTargetInformation)));
                    break;
                case SECPKG_ATTR_REMOTE_CERT_CONTEXT:
                    attribute = NativeMethods.SECPKG_ATTR_REMOTE_CERT_CONTEXT;
                    pBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)));
                    break;
                case SECPKG_ATTR_LOCAL_CERT_CONTEXT:
                    attribute = NativeMethods.SECPKG_ATTR_LOCAL_CERT_CONTEXT;
                    pBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)));
                    break;
                case SECPKG_ATTR_ROOT_STORE:
                    attribute = NativeMethods.SECPKG_ATTR_ROOT_STORE;
                    pBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)));
                    break;
                case SECPKG_ATTR_ISSUER_LIST_EX:
                    attribute = NativeMethods.SECPKG_ATTR_ISSUER_LIST_EX;
                    pBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SspiSecurityPackageContextIssuerListInfo)));
                    break;
                case SECPKG_ATTR_CONNECTION_INFO:
                    attribute = NativeMethods.SECPKG_ATTR_CONNECTION_INFO;
                    pBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SecurityPackageContextConnectionInfo)));
                    break;
                case SECPKG_ATTR_EAP_KEY_BLOCK:
                    attribute = NativeMethods.SECPKG_ATTR_EAP_KEY_BLOCK;
                    pBuffer = Marshal.AllocHGlobal(SchannelKeySize + SchannelIvSize);
                    break;
                case SECPKG_ATTR_APP_DATA:
                    attribute = NativeMethods.SECPKG_ATTR_APP_DATA;
                    pBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SecurityPackageContextSessionAppData)));
                    break;
                default:
                    throw new ArgumentException("Error context attribute name.", "contextAttribute");
            }

            uint hResult = NativeMethods.QueryContextAttributes(ref contextHandle, attribute, pBuffer);
            if (hResult == NativeMethods.SEC_E_OK)
            {
                object attributeValue;
                switch (stringAttribute)
                {
                    case SECPKG_ATTR_SIZES:
                        attributeValue = Marshal.PtrToStructure(pBuffer, typeof(SecurityPackageContextSizes));
                        break;
                    case SECPKG_ATTR_LIFESPAN:
                        attributeValue = Marshal.PtrToStructure(pBuffer, typeof(SecurityPackageContextLifespan));
                        break;
                    case SECPKG_ATTR_STREAM_SIZES:
                        attributeValue = Marshal.PtrToStructure(pBuffer, typeof(SecurityPackageContextStreamSizes));
                        break;
                    case SECPKG_ATTR_KEY_INFO:
                        SspiSecurityPackageContextKeyInfo keyInfo;

                        keyInfo = (SspiSecurityPackageContextKeyInfo)Marshal.PtrToStructure(
                            pBuffer,
                            typeof(SspiSecurityPackageContextKeyInfo));
                        attributeValue = new SecurityPackageContextKeyInfo(keyInfo);
                        Marshal.FreeHGlobal(keyInfo.sSignatureAlgorithmName);
                        Marshal.FreeHGlobal(keyInfo.sEncryptAlgorithmName);
                        break;
                    case SECPKG_ATTR_AUTHORITY:
                        SecurityPackageContextAuthority authority;

                        authority = (SecurityPackageContextAuthority)Marshal.PtrToStructure(
                            pBuffer,
                            typeof(SecurityPackageContextAuthority));
                        attributeValue = Marshal.PtrToStringUni(authority.sAuthorityName);
                        break;
                    case SECPKG_ATTR_PASSWORD_EXPIRY:
                        attributeValue = Marshal.PtrToStructure(pBuffer, typeof(SecurityInteger));
                        break;
                    case SECPKG_ATTR_SESSION_KEY:
                        SecurityPackageContextSessionKey sessionKey;

                        sessionKey = (SecurityPackageContextSessionKey)Marshal.PtrToStructure(
                            pBuffer,
                            typeof(SecurityPackageContextSessionKey));
                        attributeValue = sessionKey.GetSessionKey();
                        Marshal.FreeHGlobal(sessionKey.SessionKey);
                        break;
                    case SECPKG_ATTR_PACKAGE_INFO:
                        SspiSecurityPackageInformation packageInfo;

                        packageInfo = (SspiSecurityPackageInformation)Marshal.PtrToStructure(
                            Marshal.ReadIntPtr(pBuffer),
                            typeof(SspiSecurityPackageInformation));
                        attributeValue = new SecurityPackageInformation(packageInfo);
                        break;
                    case SECPKG_ATTR_NEGOTIATION_INFO:
                        SspiSecurityPackageContextNegotiationInfo negotiationInfo;

                        negotiationInfo = (SspiSecurityPackageContextNegotiationInfo)Marshal.PtrToStructure(
                            pBuffer,
                            typeof(SspiSecurityPackageContextNegotiationInfo));
                        attributeValue = new SecurityPackageContextNegotiationInfo(negotiationInfo);
                        Marshal.FreeHGlobal(negotiationInfo.PackageInfo);
                        break;
                    case SECPKG_ATTR_NATIVE_NAMES:
                        SspiSecurityPackageContextNativeNames nativeNames;

                        nativeNames = (SspiSecurityPackageContextNativeNames)Marshal.PtrToStructure(
                            pBuffer,
                            typeof(SspiSecurityPackageContextNativeNames));
                        attributeValue = new SecurityPackageContextNativeNames(nativeNames);
                        break;
                    case SECPKG_ATTR_FLAGS:
                        attributeValue = (uint)Marshal.ReadInt32(pBuffer);
                        break;
                    case SECPKG_ATTR_TARGET_INFORMATION:
                        SecurityPackageContextTargetInformation targetInformation;

                        targetInformation = (SecurityPackageContextTargetInformation)Marshal.PtrToStructure(
                            pBuffer,
                            typeof(SecurityPackageContextTargetInformation));
                        attributeValue = targetInformation.GetTargetInfo();
                        Marshal.FreeHGlobal(targetInformation.MarshalledTargetInfo);
                        break;
                    case SECPKG_ATTR_REMOTE_CERT_CONTEXT:
                        SspiCertContext remoteCertContext;

                        remoteCertContext = (SspiCertContext)Marshal.PtrToStructure(
                            Marshal.ReadIntPtr(pBuffer),
                            typeof(SspiCertContext));
                        attributeValue = new CertContext(remoteCertContext);
                        Marshal.FreeHGlobal(remoteCertContext.pbCertEncoded);
                        break;
                    case SECPKG_ATTR_LOCAL_CERT_CONTEXT:
                        SspiCertContext localCertContext;

                        localCertContext = (SspiCertContext)Marshal.PtrToStructure(
                            Marshal.ReadIntPtr(pBuffer),
                            typeof(SspiCertContext));
                        attributeValue = new CertContext(localCertContext);
                        Marshal.FreeHGlobal(localCertContext.pbCertEncoded);
                        break;
                    case SECPKG_ATTR_ROOT_STORE:
                        attributeValue = Marshal.ReadIntPtr(pBuffer);
                        break;
                    case SECPKG_ATTR_ISSUER_LIST_EX:
                        SspiSecurityPackageContextIssuerListInfo issuerList;

                        issuerList = (SspiSecurityPackageContextIssuerListInfo)Marshal.PtrToStructure(
                            pBuffer,
                            typeof(SspiSecurityPackageContextIssuerListInfo));
                        attributeValue = new SecurityPackageContextIssuerListInfo(issuerList);
                        NativeMethods.FreeContextBuffer(issuerList.aIssuers);
                        break;
                    case SECPKG_ATTR_CONNECTION_INFO:
                        SecurityPackageContextConnectionInfo connectionInfo;

                        connectionInfo = (SecurityPackageContextConnectionInfo)Marshal.PtrToStructure(
                            pBuffer,
                            typeof(SecurityPackageContextConnectionInfo));
                        attributeValue = connectionInfo;
                        break;
                    case SECPKG_ATTR_EAP_KEY_BLOCK:
                        SecurityPackageContextEapKeyBlock eapKeyBlock = new SecurityPackageContextEapKeyBlock();

                        eapKeyBlock.rgbKeys = new byte[SchannelKeySize];
                        Marshal.Copy(pBuffer, eapKeyBlock.rgbKeys, 0, SchannelKeySize);
                        eapKeyBlock.rgbIVs = new byte[SchannelIvSize];
                        Marshal.Copy(new IntPtr(pBuffer.ToInt64() + SchannelKeySize),
                            eapKeyBlock.rgbIVs,
                            0,
                            SchannelIvSize);
                        attributeValue = eapKeyBlock;
                        break;
                    case SECPKG_ATTR_APP_DATA:
                        SecurityPackageContextSessionAppData sessionAppData;

                        sessionAppData = (SecurityPackageContextSessionAppData)Marshal.PtrToStructure(
                            pBuffer,
                            typeof(SecurityPackageContextSessionAppData));
                        attributeValue = sessionAppData.GetAppData();
                        Marshal.FreeHGlobal(sessionAppData.pbAppData);
                        break;
                    default:
                        throw new ArgumentException("Error context attribute name.", "contextAttribute");
                }
                Marshal.FreeHGlobal(pBuffer);

                return attributeValue;
            }
            else
            {
                Marshal.FreeHGlobal(pBuffer);
                throw new SspiException("QueryContextAttributes failed.", hResult);
            }
        }
        internal static bool VerifySignature(
            ref SecurityHandle contextHandle,
            uint sequenceNumber,
            params SecurityBuffer[] securityBuffers)
        {
            SecurityBufferDescWrapper securityBufferDescWrapper = new SecurityBufferDescWrapper(securityBuffers);
            uint pfQop;

            uint hResult = NativeMethods.VerifySignature(
                ref contextHandle,
                ref securityBufferDescWrapper.securityBufferDesc,
                sequenceNumber,
                out pfQop);
            securityBufferDescWrapper.FreeSecurityBufferDesc();
            if (hResult == NativeMethods.SEC_E_OK)
            {
                return true;
            }
            else
            {
                throw new SspiException("Verify failed.", hResult);
            }
        }
 /// <summary>
 /// Free credential handle
 /// </summary>
 /// <param name="credentialHandle">credential handle</param>
 internal static void FreeCredentialsHandle(ref SecurityHandle credentialHandle)
 {
     uint hResult = NativeMethods.FreeCredentialsHandle(ref credentialHandle);
     if (hResult == NativeMethods.SEC_E_OK)
     {
         credentialHandle.HighPart = IntPtr.Zero;
         credentialHandle.LowPart = IntPtr.Zero;
     }
 }
        internal static void MakeSignature(
            ref SecurityHandle contextHandle,
            uint sequenceNumber,
            params SecurityBuffer[] securityBuffers)
        {
            SecurityBufferDescWrapper securityBufferDescWrapper = new SecurityBufferDescWrapper(securityBuffers);

            uint hResult = NativeMethods.MakeSignature(
                ref contextHandle,
                0,
                ref securityBufferDescWrapper.securityBufferDesc,
                sequenceNumber);
            if (hResult != NativeMethods.SEC_E_OK)
            {
                securityBufferDescWrapper.FreeSecurityBufferDesc();
                throw new SspiException("Sign failed.", hResult);
            }
            else
            {
                SspiSecurityBuffer[] buffers = securityBufferDescWrapper.securityBufferDesc.GetBuffers();
                if (buffers != null)
                {
                    for (int i = 0; i < buffers.Length; i++)
                    {
                        if (securityBuffers[i].BufferType == SecurityBufferType.Token)
                        {
                            securityBuffers[i].Buffer = new byte[buffers[i].bufferLength];
                            Marshal.Copy(
                                buffers[i].pSecBuffer,
                                securityBuffers[i].Buffer,
                                0,
                                (int)buffers[i].bufferLength);
                        }
                    }
                }
                securityBufferDescWrapper.FreeSecurityBufferDesc();
            }
        }
        internal static void Encrypt(
            ref SecurityHandle contextHandle,
            uint sequenceNumber,
            SECQOP_WRAP qualityOfProtection,
            params SecurityBuffer[] securityBuffers)
        {
            SecurityBufferDescWrapper encryptBufferDescWrapper = new SecurityBufferDescWrapper(securityBuffers);

            uint hResult = NativeMethods.EncryptMessage(
                ref contextHandle,
                (uint)qualityOfProtection,
                ref encryptBufferDescWrapper.securityBufferDesc,
                sequenceNumber);
            if (hResult == NativeMethods.SEC_E_OK)
            {
                SspiSecurityBuffer[] buffers = encryptBufferDescWrapper.securityBufferDesc.GetBuffers();
                for (int i = 0; i < securityBuffers.Length; i++)
                {
                    securityBuffers[i].Buffer = new byte[buffers[i].bufferLength];
                    if (buffers[i].pSecBuffer != IntPtr.Zero)
                    {
                        Marshal.Copy(buffers[i].pSecBuffer,
                            securityBuffers[i].Buffer,
                            0,
                            securityBuffers[i].Buffer.Length);
                    }
                }
                encryptBufferDescWrapper.FreeSecurityBufferDesc();
            }
            else
            {
                encryptBufferDescWrapper.FreeSecurityBufferDesc();
                throw new SspiException("Encrypt failed.", hResult);
            }
        }
        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);
            }
        }
 /// <summary>
 /// Delete context handle
 /// </summary>
 /// <param name="contextHandle">context handle</param>
 internal static void DeleteSecurityContext(ref SecurityHandle contextHandle)
 {
     uint hResult = NativeMethods.DeleteSecurityContext(ref contextHandle);
     if (hResult == NativeMethods.SEC_E_OK)
     {
         contextHandle.LowPart = IntPtr.Zero;
         contextHandle.HighPart = IntPtr.Zero;
     }
 }
 internal static extern uint QueryContextAttributes(
     ref SecurityHandle phContext,
     uint ulAttribute,
     IntPtr pBuffer);
 internal static extern uint DecryptMessage(
     ref SecurityHandle phContext,
     ref SecurityBufferDesc pMessage,
     uint MessageSeqNo,
     out uint pfQOP);
 internal static extern uint FreeCredentialsHandle(ref SecurityHandle phCredential);
 internal static extern uint EncryptMessage(
     ref SecurityHandle phContext,
     uint fQOP,
     ref SecurityBufferDesc pMessage,
     uint MessageSeqNo);
 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);
 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 CompleteAuthToken(
     ref SecurityHandle phContext,
     ref SecurityBufferDesc SecBufferDesc);
        internal static void AcquireCredentialsHandle(
            SecurityPackageType packageType,
            AccountCredential accountCredential,
            string serverPrincipal,
            uint fCredentialUse,
            out SecurityHandle credentialHandle)
        {
            string stringPackage = SspiUtility.GetPackageStringName(packageType);

            SecurityInteger expiryTime;
            SecurityWinntAuthIdentity authIdentity = new SecurityWinntAuthIdentity(accountCredential);
            IntPtr pAuthData = IntPtr.Zero;
            SchannelCred schannelCred = new SchannelCred();
            schannelCred.dwVersion = NativeMethods.SCHANNEL_CRED_VERSION;
            schannelCred.cCreds = 0;
            schannelCred.paCred = IntPtr.Zero;
            CredSspCred credSsp = new CredSspCred();

            switch (packageType)
            {
                case SecurityPackageType.Ntlm:
                case SecurityPackageType.Kerberos:
                case SecurityPackageType.Negotiate:
                    pAuthData = SspiUtility.CreateAuthData(authIdentity);
                    break;
                case SecurityPackageType.Schannel:
                    pAuthData = SspiUtility.CreateAuthData(schannelCred);
                    break;
                case SecurityPackageType.CredSsp:
                    credSsp.Type = CredSspSubmitType.CredsspSubmitBufferBoth;
                    credSsp.pSchannelCred = CreateAuthData(schannelCred);
                    credSsp.pSpnegoCred = CreateAuthData(authIdentity);
                    pAuthData = CreateAuthData(credSsp);
                    break;
                //default, if other values, exception will be thrown by GetPackageStringName.
                default:
                    throw new ArgumentException("Invlid packageType value.", "packageType");
            }

            uint result = NativeMethods.AcquireCredentialsHandle(
                serverPrincipal,
                stringPackage,
                fCredentialUse,
                IntPtr.Zero,
                pAuthData,
                IntPtr.Zero,
                IntPtr.Zero,
                out credentialHandle,
                out expiryTime);
            //Free memory
            switch (packageType)
            {
                case SecurityPackageType.Ntlm:
                case SecurityPackageType.Kerberos:
                case SecurityPackageType.Negotiate:
                    SspiUtility.FreeSecurityWinntAuthIdentity(authIdentity);
                    break;
                case SecurityPackageType.Schannel:
                    stringPackage = Schannel;
                    SspiUtility.FreeSchannelCred(schannelCred);
                    break;
                case SecurityPackageType.CredSsp:
                    SspiUtility.FreeSecurityWinntAuthIdentity(authIdentity);
                    SspiUtility.FreeSchannelCred(schannelCred);
                    SspiUtility.FreeCredSspCred(credSsp);
                    break;
                //default, if other values, exception will be thrown by GetPackageStringName.
                default:
                    throw new ArgumentException("Invlid packageType value.", "packageType");
            }
            Marshal.FreeHGlobal(pAuthData);

            if (result != NativeMethods.SEC_E_OK)
            {
                throw new SspiException("AquireCredentialsHandle failed", result);
            }
        }
 internal static extern uint DeleteSecurityContext(ref SecurityHandle phContext);
 internal static extern uint CompleteAuthToken(
     ref SecurityHandle phContext,
     ref SecurityBufferDesc SecBufferDesc);
 internal static extern uint FreeCredentialsHandle(ref SecurityHandle phCredential);
 internal static extern uint EncryptMessage(
     ref SecurityHandle phContext,
     uint fQOP,
     ref SecurityBufferDesc pMessage,
     uint MessageSeqNo);
 internal static extern uint MakeSignature(
     ref SecurityHandle phContext,
     uint fQOP,
     ref SecurityBufferDesc pMessage,
     uint MessageSeqNo);
 internal static extern uint DecryptMessage(
     ref SecurityHandle phContext,
     ref SecurityBufferDesc pMessage,
     uint MessageSeqNo,
     out uint pfQOP);
 internal static extern uint VerifySignature(
     ref SecurityHandle phContext,
     ref SecurityBufferDesc pMessage,
     uint MessageSeqNo,
     out uint pfQOP);
        internal static SecurityPackageContextSizes QueryContextSizes(ref SecurityHandle contextHandle)
        {
            IntPtr pContextSizes = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SecurityPackageContextSizes)));

            uint hResult = NativeMethods.QueryContextAttributes(
                ref contextHandle,
                NativeMethods.SECPKG_ATTR_SIZES,
                pContextSizes);

            if (hResult == NativeMethods.SEC_E_OK)
            {
                SecurityPackageContextSizes contextSizes = (SecurityPackageContextSizes)Marshal.PtrToStructure(
                        pContextSizes,
                        typeof(SecurityPackageContextSizes));
                Marshal.FreeHGlobal(pContextSizes);
                return contextSizes;
            }
            else
            {
                Marshal.FreeHGlobal(pContextSizes);
                throw new SspiException("Query ContextSizes failed.", hResult);
            }
        }