private async ValueTask <BodyWriter> ProcessNegotiationAsync(SspiNegotiationTokenAuthenticatorState negotiationState, Message incomingMessage, BinaryNegotiation incomingNego)
        {
            ISspiNegotiation sspiNegotiation = negotiationState.SspiNegotiation;

            byte[] outgoingBlob = sspiNegotiation.GetOutgoingBlob(incomingNego.GetNegotiationData(),
                                                                  SecurityUtils.GetChannelBindingFromMessage(incomingMessage),
                                                                  ExtendedProtectionPolicy);

            if (sspiNegotiation.IsValidContext == false)
            {
                throw TraceUtility.ThrowHelperError(new SecurityNegotiationException(SR.Format(SR.InvalidSspiNegotiation)), incomingMessage);
            }
            // if there is no blob to send back the nego must be complete from the server side
            if (outgoingBlob == null && sspiNegotiation.IsCompleted == false)
            {
                throw TraceUtility.ThrowHelperError(new SecurityNegotiationException(SR.Format(SR.NoBinaryNegoToSend)), incomingMessage);
            }
            BinaryNegotiation outgoingBinaryNegotiation;

            if (outgoingBlob != null)
            {
                outgoingBinaryNegotiation = GetOutgoingBinaryNegotiation(sspiNegotiation, outgoingBlob);
            }
            else
            {
                outgoingBinaryNegotiation = null;
            }
            BodyWriter replyBody;

            if (sspiNegotiation.IsCompleted)
            {
                ReadOnlyCollection <IAuthorizationPolicy> authorizationPolicies = await ValidateSspiNegotiationAsync(sspiNegotiation);

                SecurityContextSecurityToken serviceToken;
                WrappedKeySecurityToken      proofToken;
                int issuedKeySize;
                IssueServiceToken(negotiationState, authorizationPolicies, out serviceToken, out proofToken, out issuedKeySize);
                negotiationState.SetServiceToken(serviceToken);

                SecurityKeyIdentifierClause externalTokenReference = IssuedSecurityTokenParameters.CreateKeyIdentifierClause(serviceToken, SecurityTokenReferenceStyle.External);
                SecurityKeyIdentifierClause internalTokenReference = IssuedSecurityTokenParameters.CreateKeyIdentifierClause(serviceToken, SecurityTokenReferenceStyle.Internal);

                RequestSecurityTokenResponse dummyRstr = new RequestSecurityTokenResponse(StandardsManager)
                {
                    Context   = negotiationState.Context,
                    KeySize   = issuedKeySize,
                    TokenType = SecurityContextTokenUri
                };
                if (outgoingBinaryNegotiation != null)
                {
                    dummyRstr.SetBinaryNegotiation(outgoingBinaryNegotiation);
                }
                dummyRstr.RequestedUnattachedReference = externalTokenReference;
                dummyRstr.RequestedAttachedReference   = internalTokenReference;
                dummyRstr.SetLifetime(serviceToken.ValidFrom, serviceToken.ValidTo);
                if (negotiationState.AppliesTo != null)
                {
                    if (incomingMessage.Version.Addressing == AddressingVersion.WSAddressing10)
                    {
                        dummyRstr.SetAppliesTo <EndpointAddress10>(EndpointAddress10.FromEndpointAddress(
                                                                       negotiationState.AppliesTo),
                                                                   negotiationState.AppliesToSerializer);
                    }
                    else if (incomingMessage.Version.Addressing == AddressingVersion.WSAddressingAugust2004)
                    {
                        dummyRstr.SetAppliesTo <EndpointAddressAugust2004>(EndpointAddressAugust2004.FromEndpointAddress(
                                                                               negotiationState.AppliesTo),
                                                                           negotiationState.AppliesToSerializer);
                    }
                    else
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                                  new ProtocolException(SR.Format(SR.AddressingVersionNotSupported, incomingMessage.Version.Addressing)));
                    }
                }
                dummyRstr.MakeReadOnly();
                AddToDigest(negotiationState, dummyRstr, false);
                RequestSecurityTokenResponse negotiationRstr = new RequestSecurityTokenResponse(StandardsManager)
                {
                    RequestedSecurityToken = serviceToken,

                    RequestedProofToken = proofToken,
                    Context             = negotiationState.Context,
                    KeySize             = issuedKeySize,
                    TokenType           = SecurityContextTokenUri
                };
                if (outgoingBinaryNegotiation != null)
                {
                    negotiationRstr.SetBinaryNegotiation(outgoingBinaryNegotiation);
                }
                negotiationRstr.RequestedAttachedReference   = internalTokenReference;
                negotiationRstr.RequestedUnattachedReference = externalTokenReference;
                if (negotiationState.AppliesTo != null)
                {
                    if (incomingMessage.Version.Addressing == AddressingVersion.WSAddressing10)
                    {
                        negotiationRstr.SetAppliesTo <EndpointAddress10>(
                            EndpointAddress10.FromEndpointAddress(negotiationState.AppliesTo),
                            negotiationState.AppliesToSerializer);
                    }
                    else if (incomingMessage.Version.Addressing == AddressingVersion.WSAddressingAugust2004)
                    {
                        negotiationRstr.SetAppliesTo <EndpointAddressAugust2004>(
                            EndpointAddressAugust2004.FromEndpointAddress(negotiationState.AppliesTo),
                            negotiationState.AppliesToSerializer);
                    }
                    else
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                                  new ProtocolException(SR.Format(SR.AddressingVersionNotSupported, incomingMessage.Version.Addressing)));
                    }
                }
                negotiationRstr.MakeReadOnly();

                byte[] authenticator = ComputeAuthenticator(negotiationState, serviceToken.GetKeyBytes());
                RequestSecurityTokenResponse authenticatorRstr = new RequestSecurityTokenResponse(StandardsManager)
                {
                    Context = negotiationState.Context
                };
                authenticatorRstr.SetAuthenticator(authenticator);
                authenticatorRstr.MakeReadOnly();

                List <RequestSecurityTokenResponse> rstrList = new List <RequestSecurityTokenResponse>(2)
                {
                    negotiationRstr,
                    authenticatorRstr
                };
                replyBody = new RequestSecurityTokenResponseCollection(rstrList, StandardsManager);
            }
            else
            {
                RequestSecurityTokenResponse rstr = new RequestSecurityTokenResponse(StandardsManager)
                {
                    Context = negotiationState.Context
                };
                rstr.SetBinaryNegotiation(outgoingBinaryNegotiation);
                rstr.MakeReadOnly();
                AddToDigest(negotiationState, rstr, false);
                replyBody = rstr;
            }

            return(replyBody);
        }
        private BodyWriter ProcessNegotiation(SspiNegotiationTokenAuthenticatorState negotiationState, Message incomingMessage, BinaryNegotiation incomingNego)
        {
            BinaryNegotiation outgoingBinaryNegotiation;
            ISspiNegotiation  sspiNegotiation = negotiationState.SspiNegotiation;

            byte[] outgoingBlob = sspiNegotiation.GetOutgoingBlob(incomingNego.GetNegotiationData(), System.ServiceModel.Security.SecurityUtils.GetChannelBindingFromMessage(incomingMessage), this.extendedProtectionPolicy);
            if (!sspiNegotiation.IsValidContext)
            {
                throw TraceUtility.ThrowHelperError(new SecurityNegotiationException(System.ServiceModel.SR.GetString("InvalidSspiNegotiation")), incomingMessage);
            }
            if ((outgoingBlob == null) && !sspiNegotiation.IsCompleted)
            {
                throw TraceUtility.ThrowHelperError(new SecurityNegotiationException(System.ServiceModel.SR.GetString("NoBinaryNegoToSend")), incomingMessage);
            }
            if (outgoingBlob != null)
            {
                outgoingBinaryNegotiation = this.GetOutgoingBinaryNegotiation(sspiNegotiation, outgoingBlob);
            }
            else
            {
                outgoingBinaryNegotiation = null;
            }
            if (sspiNegotiation.IsCompleted)
            {
                SecurityContextSecurityToken token;
                WrappedKeySecurityToken      token2;
                int num;
                ReadOnlyCollection <IAuthorizationPolicy> authorizationPolicies = this.ValidateSspiNegotiation(sspiNegotiation);
                this.IssueServiceToken(negotiationState, authorizationPolicies, out token, out token2, out num);
                negotiationState.SetServiceToken(token);
                SecurityKeyIdentifierClause  clause   = base.IssuedSecurityTokenParameters.CreateKeyIdentifierClause(token, SecurityTokenReferenceStyle.External);
                SecurityKeyIdentifierClause  clause2  = base.IssuedSecurityTokenParameters.CreateKeyIdentifierClause(token, SecurityTokenReferenceStyle.Internal);
                RequestSecurityTokenResponse response = new RequestSecurityTokenResponse(base.StandardsManager)
                {
                    Context   = negotiationState.Context,
                    KeySize   = num,
                    TokenType = base.SecurityContextTokenUri
                };
                if (outgoingBinaryNegotiation != null)
                {
                    response.SetBinaryNegotiation(outgoingBinaryNegotiation);
                }
                response.RequestedUnattachedReference = clause;
                response.RequestedAttachedReference   = clause2;
                response.SetLifetime(token.ValidFrom, token.ValidTo);
                if (negotiationState.AppliesTo != null)
                {
                    if (incomingMessage.Version.Addressing != AddressingVersion.WSAddressing10)
                    {
                        if (incomingMessage.Version.Addressing != AddressingVersion.WSAddressingAugust2004)
                        {
                            throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ProtocolException(System.ServiceModel.SR.GetString("AddressingVersionNotSupported", new object[] { incomingMessage.Version.Addressing })));
                        }
                        response.SetAppliesTo <EndpointAddressAugust2004>(EndpointAddressAugust2004.FromEndpointAddress(negotiationState.AppliesTo), negotiationState.AppliesToSerializer);
                    }
                    else
                    {
                        response.SetAppliesTo <EndpointAddress10>(EndpointAddress10.FromEndpointAddress(negotiationState.AppliesTo), negotiationState.AppliesToSerializer);
                    }
                }
                response.MakeReadOnly();
                AddToDigest(negotiationState, response, false);
                RequestSecurityTokenResponse response2 = new RequestSecurityTokenResponse(base.StandardsManager)
                {
                    RequestedSecurityToken = token,
                    RequestedProofToken    = token2,
                    Context   = negotiationState.Context,
                    KeySize   = num,
                    TokenType = base.SecurityContextTokenUri
                };
                if (outgoingBinaryNegotiation != null)
                {
                    response2.SetBinaryNegotiation(outgoingBinaryNegotiation);
                }
                response2.RequestedAttachedReference   = clause2;
                response2.RequestedUnattachedReference = clause;
                if (negotiationState.AppliesTo != null)
                {
                    if (incomingMessage.Version.Addressing != AddressingVersion.WSAddressing10)
                    {
                        if (incomingMessage.Version.Addressing != AddressingVersion.WSAddressingAugust2004)
                        {
                            throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ProtocolException(System.ServiceModel.SR.GetString("AddressingVersionNotSupported", new object[] { incomingMessage.Version.Addressing })));
                        }
                        response2.SetAppliesTo <EndpointAddressAugust2004>(EndpointAddressAugust2004.FromEndpointAddress(negotiationState.AppliesTo), negotiationState.AppliesToSerializer);
                    }
                    else
                    {
                        response2.SetAppliesTo <EndpointAddress10>(EndpointAddress10.FromEndpointAddress(negotiationState.AppliesTo), negotiationState.AppliesToSerializer);
                    }
                }
                response2.MakeReadOnly();
                byte[] authenticator = ComputeAuthenticator(negotiationState, token.GetKeyBytes());
                RequestSecurityTokenResponse response3 = new RequestSecurityTokenResponse(base.StandardsManager)
                {
                    Context = negotiationState.Context
                };
                response3.SetAuthenticator(authenticator);
                response3.MakeReadOnly();
                return(new RequestSecurityTokenResponseCollection(new List <RequestSecurityTokenResponse>(2)
                {
                    response2, response3
                }, base.StandardsManager));
            }
            RequestSecurityTokenResponse rstr = new RequestSecurityTokenResponse(base.StandardsManager)
            {
                Context = negotiationState.Context
            };

            rstr.SetBinaryNegotiation(outgoingBinaryNegotiation);
            rstr.MakeReadOnly();
            AddToDigest(negotiationState, rstr, false);
            return(rstr);
        }