public DtlsServerSecurityContext(
            SecurityPackageType packageType,
            CertificateCredential serverCredential,
            string serverPrincipal,
            ServerSecurityContextAttribute contextAttributes,
            SecurityTargetDataRepresentation targetDataRep)
        {
            this.packageType = packageType;
            this.serverPrincipalName = serverPrincipal;
            this.securityContextAttributes = contextAttributes;
            this.targetDataRepresentaion = targetDataRep;
            SspiUtility.DtlsAcquireCredentialsHandle(
                packageType,
                serverCredential,
                serverPrincipal,
                NativeMethods.SECPKG_CRED_INBOUND,
                out this.credentialHandle);

            bStreamSizes = false;
            hasMoreFragments = false;
        }
        public SspiClientSecurityContext(
            SecurityPackageType packageType,
            CertificateCredential clientCredential,
            string serverPrincipal,
            ClientSecurityContextAttribute contextAttributes,
            SecurityTargetDataRepresentation targetDataRep)
        {
            this.packageType = packageType;
            this.serverPrincipalName = serverPrincipal;
            this.securityContextAttributes = contextAttributes;
            this.targetDataRepresentaion = targetDataRep;

            SspiUtility.AcquireCredentialsHandle(
                packageType,
                clientCredential,
                serverPrincipal,
                NativeMethods.SECPKG_CRED_OUTBOUND,
                out this.credentialHandle);
        }
        /// <summary>
        /// Performs CredSSP authentication.
        /// </summary>
        /// <param name="x509Cert">The certificate used by TLS.</param>
        /// <exception cref="IOException">Raised when attempting to read from/write to the remote connection which
        /// has been closed</exception>
        /// <exception cref="EndOfStreamException">Raised when the username or password doesn't match or authentication
        /// fails</exception>
        public void Authenticate(X509Certificate x509Cert)
        {
            // Authenticated already, do nothing
            if (isAuthenticated)
            {
                return;
            }

            credential = new CertificateCredential(x509Cert);

            byte[] receivedBuffer = new byte[MaxBufferSize];
            int bytesReceived = 0;

            // Dispose the context as it may be timed out
            if (context != null)
            {
                context.Dispose();
            }

            context = new SspiServerSecurityContext(
                SecurityPackageType.CredSsp,
                credential,
                serverPrincipal,
                attribute,
                SecurityTargetDataRepresentation.SecurityNativeDrep);

            // Get first token
            byte[] token = context.Token;
            // Credssp handshake
            while (context.NeedContinueProcessing)
            {
                // Get handshake resopnse
                bytesReceived = serverStream.Read(receivedBuffer, 0, receivedBuffer.Length);
                // The remote connection has been closed
                if (bytesReceived == 0)
                {
                    throw new EndOfStreamException("Authentication failed: remote connection has been closed.");
                }

                byte[] inToken = new byte[bytesReceived];
                Array.Copy(receivedBuffer, inToken, bytesReceived);
                // Get next token from response
                context.Accept(inToken);
                token = context.Token;

                if (token != null)
                {
                    // Send handshake request
                    serverStream.Write(token, 0, token.Length);
                }
            }

            isAuthenticated = true;
        }
        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>
        /// Constructor.
        /// </summary>
        /// <param name="credential">Certificate credential</param>
        /// <param name="enabledProtocols">Enabled protocols</param>
        internal SchannelCred(CertificateCredential credential, uint enabledProtocols)
        {
            //There is 1 structures in the paCred array.
            const uint CountOfCred = 1;

            this.dwVersion = NativeMethods.SCHANNEL_CRED_VERSION;
            if (credential != null && credential.Certificate != null)
            {
                this.cCreds = CountOfCred;
                this.paCred = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)));
                Marshal.WriteIntPtr(this.paCred, credential.Certificate.Handle);
            }
            else
            {
                this.paCred = IntPtr.Zero;
                this.cCreds = 0;
            }
            this.hRootStore = IntPtr.Zero;
            this.cMappers = 0;
            this.aphMappers = IntPtr.Zero;
            this.cSupportedAlgs = 0;
            this.palgSupportedAlgs = IntPtr.Zero;
            this.grbitEnabledProtocols = enabledProtocols;
            this.dwMinimumCipherStrength = 0;
            this.dwMaximumCipherStrength = 0;
            this.dwSessionLifespan = 0;
            if (credential == null || credential.Certificate == null)
            {
                this.dwFlags = NativeMethods.SCH_CRED_MANUAL_CRED_VALIDATION | NativeMethods.SCH_CRED_NO_DEFAULT_CREDS;
            }
            else
            {
                this.dwFlags = 0;
            }
            this.dwCredFormat = 0;
        }