internal override SecurityProtocolFactory CreateSecurityProtocolFactory <TChannel>(BindingContext context, SecurityCredentialsManager credentialsManager, bool isForService, BindingContext issuerBindingContext)
        {
            if (context == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
            }
            if (credentialsManager == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("credentialsManager");
            }
            if (this.InitiatorTokenParameters == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(System.ServiceModel.SR.GetString("AsymmetricSecurityBindingElementNeedsInitiatorTokenParameters", new object[] { this.ToString() })));
            }
            if (this.RecipientTokenParameters == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(System.ServiceModel.SR.GetString("AsymmetricSecurityBindingElementNeedsRecipientTokenParameters", new object[] { this.ToString() })));
            }
            bool flag = !this.isCertificateSignatureBinding && ((typeof(IDuplexChannel) == typeof(TChannel)) || (typeof(IDuplexSessionChannel) == typeof(TChannel)));
            AsymmetricSecurityProtocolFactory factory = new AsymmetricSecurityProtocolFactory();

            factory.ProtectionRequirements.Add(SecurityBindingElement.ComputeProtectionRequirements(this, context.BindingParameters, context.Binding.Elements, isForService));
            factory.RequireConfidentiality = this.HasProtectionRequirements(factory.ProtectionRequirements.IncomingEncryptionParts);
            factory.RequireIntegrity       = this.HasProtectionRequirements(factory.ProtectionRequirements.IncomingSignatureParts);
            if (this.isCertificateSignatureBinding)
            {
                if (isForService)
                {
                    factory.ApplyIntegrity = factory.ApplyConfidentiality = false;
                }
                else
                {
                    factory.ApplyConfidentiality = factory.RequireIntegrity = false;
                }
            }
            else
            {
                factory.ApplyIntegrity       = this.HasProtectionRequirements(factory.ProtectionRequirements.OutgoingSignatureParts);
                factory.ApplyConfidentiality = this.HasProtectionRequirements(factory.ProtectionRequirements.OutgoingEncryptionParts);
            }
            if (isForService)
            {
                base.ApplyAuditBehaviorSettings(context, factory);
                if (factory.RequireConfidentiality || (!this.isCertificateSignatureBinding && factory.ApplyIntegrity))
                {
                    factory.AsymmetricTokenParameters = this.RecipientTokenParameters.Clone();
                }
                else
                {
                    factory.AsymmetricTokenParameters = null;
                }
                factory.CryptoTokenParameters = this.InitiatorTokenParameters.Clone();
                SecurityBindingElement.SetIssuerBindingContextIfRequired(factory.CryptoTokenParameters, issuerBindingContext);
            }
            else
            {
                if (factory.ApplyConfidentiality || (!this.isCertificateSignatureBinding && factory.RequireIntegrity))
                {
                    factory.AsymmetricTokenParameters = this.RecipientTokenParameters.Clone();
                }
                else
                {
                    factory.AsymmetricTokenParameters = null;
                }
                factory.CryptoTokenParameters = this.InitiatorTokenParameters.Clone();
                SecurityBindingElement.SetIssuerBindingContextIfRequired(factory.CryptoTokenParameters, issuerBindingContext);
            }
            if (flag)
            {
                if (isForService)
                {
                    factory.ApplyConfidentiality = factory.ApplyIntegrity = false;
                }
                else
                {
                    factory.RequireIntegrity = factory.RequireConfidentiality = false;
                }
            }
            else if (!isForService)
            {
                factory.AllowSerializedSigningTokenOnReply = this.AllowSerializedSigningTokenOnReply;
            }
            factory.IdentityVerifier = base.LocalClientSettings.IdentityVerifier;
            factory.DoRequestSignatureConfirmation = this.RequireSignatureConfirmation;
            factory.MessageProtectionOrder         = this.MessageProtectionOrder;
            base.ConfigureProtocolFactory(factory, credentialsManager, isForService, issuerBindingContext, context.Binding);
            if (!factory.RequireIntegrity)
            {
                factory.DetectReplays = false;
            }
            if (!flag)
            {
                return(factory);
            }
            AsymmetricSecurityProtocolFactory factory3 = new AsymmetricSecurityProtocolFactory();

            if (isForService)
            {
                factory3.AsymmetricTokenParameters = this.InitiatorTokenParameters.Clone();
                factory3.AsymmetricTokenParameters.ReferenceStyle = SecurityTokenReferenceStyle.External;
                factory3.AsymmetricTokenParameters.InclusionMode  = SecurityTokenInclusionMode.Never;
                factory3.CryptoTokenParameters = this.RecipientTokenParameters.Clone();
                factory3.CryptoTokenParameters.ReferenceStyle = SecurityTokenReferenceStyle.Internal;
                factory3.CryptoTokenParameters.InclusionMode  = SecurityTokenInclusionMode.AlwaysToRecipient;
                factory3.IdentityVerifier = null;
            }
            else
            {
                factory3.AsymmetricTokenParameters = this.InitiatorTokenParameters.Clone();
                factory3.AsymmetricTokenParameters.ReferenceStyle = SecurityTokenReferenceStyle.External;
                factory3.AsymmetricTokenParameters.InclusionMode  = SecurityTokenInclusionMode.Never;
                factory3.CryptoTokenParameters = this.RecipientTokenParameters.Clone();
                factory3.CryptoTokenParameters.ReferenceStyle = SecurityTokenReferenceStyle.Internal;
                factory3.CryptoTokenParameters.InclusionMode  = SecurityTokenInclusionMode.AlwaysToRecipient;
                factory3.IdentityVerifier = base.LocalClientSettings.IdentityVerifier;
            }
            factory3.DoRequestSignatureConfirmation = this.RequireSignatureConfirmation;
            factory3.MessageProtectionOrder         = this.MessageProtectionOrder;
            factory3.ProtectionRequirements.Add(SecurityBindingElement.ComputeProtectionRequirements(this, context.BindingParameters, context.Binding.Elements, isForService));
            if (isForService)
            {
                factory3.ApplyConfidentiality = this.HasProtectionRequirements(factory3.ProtectionRequirements.OutgoingEncryptionParts);
                factory3.ApplyIntegrity       = true;
                factory3.RequireIntegrity     = factory3.RequireConfidentiality = false;
            }
            else
            {
                factory3.RequireConfidentiality = this.HasProtectionRequirements(factory3.ProtectionRequirements.IncomingEncryptionParts);
                factory3.RequireIntegrity       = true;
                factory3.ApplyIntegrity         = factory3.ApplyConfidentiality = false;
            }
            base.ConfigureProtocolFactory(factory3, credentialsManager, !isForService, issuerBindingContext, context.Binding);
            if (!factory3.RequireIntegrity)
            {
                factory3.DetectReplays = false;
            }
            factory3.IsDuplexReply = true;
            return(new DuplexSecurityProtocolFactory {
                ForwardProtocolFactory = factory, ReverseProtocolFactory = factory3
            });
        }
 public AsymmetricSecurityProtocol(AsymmetricSecurityProtocolFactory factory,
    EndpointAddress target, Uri via)
     : base(factory, target, via)
 {
 }
        internal override SecurityProtocolFactory CreateSecurityProtocolFactory <TChannel>(BindingContext context, SecurityCredentialsManager credentialsManager, bool isForService, BindingContext issuerBindingContext)
        {
            if (context == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
            }
            if (credentialsManager == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("credentialsManager");
            }

            if (this.InitiatorTokenParameters == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.AsymmetricSecurityBindingElementNeedsInitiatorTokenParameters, this.ToString())));
            }
            if (this.RecipientTokenParameters == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.AsymmetricSecurityBindingElementNeedsRecipientTokenParameters, this.ToString())));
            }

            bool isDuplexSecurity = !this.isCertificateSignatureBinding && (typeof(IDuplexChannel) == typeof(TChannel) || typeof(IDuplexSessionChannel) == typeof(TChannel));

            SecurityProtocolFactory protocolFactory;

            AsymmetricSecurityProtocolFactory forward = new AsymmetricSecurityProtocolFactory();

            forward.ProtectionRequirements.Add(SecurityBindingElement.ComputeProtectionRequirements(this, context.BindingParameters, context.Binding.Elements, isForService));
            forward.RequireConfidentiality = this.HasProtectionRequirements(forward.ProtectionRequirements.IncomingEncryptionParts);
            forward.RequireIntegrity       = this.HasProtectionRequirements(forward.ProtectionRequirements.IncomingSignatureParts);
            if (this.isCertificateSignatureBinding)
            {
                if (isForService)
                {
                    forward.ApplyIntegrity = forward.ApplyConfidentiality = false;
                }
                else
                {
                    forward.ApplyConfidentiality = forward.RequireIntegrity = false;
                }
            }
            else
            {
                forward.ApplyIntegrity       = this.HasProtectionRequirements(forward.ProtectionRequirements.OutgoingSignatureParts);
                forward.ApplyConfidentiality = this.HasProtectionRequirements(forward.ProtectionRequirements.OutgoingEncryptionParts);
            }
            if (isForService)
            {
                base.ApplyAuditBehaviorSettings(context, forward);
                if (forward.RequireConfidentiality || (!this.isCertificateSignatureBinding && forward.ApplyIntegrity))
                {
                    forward.AsymmetricTokenParameters = (SecurityTokenParameters)this.RecipientTokenParameters.Clone();
                }
                else
                {
                    forward.AsymmetricTokenParameters = null;
                }
                forward.CryptoTokenParameters = this.InitiatorTokenParameters.Clone();
                SetIssuerBindingContextIfRequired(forward.CryptoTokenParameters, issuerBindingContext);
            }
            else
            {
                if (forward.ApplyConfidentiality || (!this.isCertificateSignatureBinding && forward.RequireIntegrity))
                {
                    forward.AsymmetricTokenParameters = (SecurityTokenParameters)this.RecipientTokenParameters.Clone();
                }
                else
                {
                    forward.AsymmetricTokenParameters = null;
                }
                forward.CryptoTokenParameters = this.InitiatorTokenParameters.Clone();
                SetIssuerBindingContextIfRequired(forward.CryptoTokenParameters, issuerBindingContext);
            }
            if (isDuplexSecurity)
            {
                if (isForService)
                {
                    forward.ApplyConfidentiality = forward.ApplyIntegrity = false;
                }
                else
                {
                    forward.RequireIntegrity = forward.RequireConfidentiality = false;
                }
            }
            else
            {
                if (!isForService)
                {
                    forward.AllowSerializedSigningTokenOnReply = this.AllowSerializedSigningTokenOnReply;
                }
            }

            forward.IdentityVerifier = this.LocalClientSettings.IdentityVerifier;
            forward.DoRequestSignatureConfirmation = this.RequireSignatureConfirmation;
            forward.MessageProtectionOrder         = this.MessageProtectionOrder;
            base.ConfigureProtocolFactory(forward, credentialsManager, isForService, issuerBindingContext, context.Binding);
            if (!forward.RequireIntegrity)
            {
                forward.DetectReplays = false;
            }

            if (isDuplexSecurity)
            {
                AsymmetricSecurityProtocolFactory reverse = new AsymmetricSecurityProtocolFactory();
                if (isForService)
                {
                    reverse.AsymmetricTokenParameters = this.InitiatorTokenParameters.Clone();
                    reverse.AsymmetricTokenParameters.ReferenceStyle = SecurityTokenReferenceStyle.External;
                    reverse.AsymmetricTokenParameters.InclusionMode  = SecurityTokenInclusionMode.Never;
                    reverse.CryptoTokenParameters = (SecurityTokenParameters)this.RecipientTokenParameters.Clone();
                    reverse.CryptoTokenParameters.ReferenceStyle = SecurityTokenReferenceStyle.Internal;
                    reverse.CryptoTokenParameters.InclusionMode  = SecurityTokenInclusionMode.AlwaysToRecipient;
                    reverse.IdentityVerifier = null;
                }
                else
                {
                    reverse.AsymmetricTokenParameters = this.InitiatorTokenParameters.Clone();
                    reverse.AsymmetricTokenParameters.ReferenceStyle = SecurityTokenReferenceStyle.External;
                    reverse.AsymmetricTokenParameters.InclusionMode  = SecurityTokenInclusionMode.Never;
                    reverse.CryptoTokenParameters = (SecurityTokenParameters)this.RecipientTokenParameters.Clone();
                    reverse.CryptoTokenParameters.ReferenceStyle = SecurityTokenReferenceStyle.Internal;
                    reverse.CryptoTokenParameters.InclusionMode  = SecurityTokenInclusionMode.AlwaysToRecipient;
                    reverse.IdentityVerifier = this.LocalClientSettings.IdentityVerifier;
                }
                reverse.DoRequestSignatureConfirmation = this.RequireSignatureConfirmation;
                reverse.MessageProtectionOrder         = this.MessageProtectionOrder;
                reverse.ProtectionRequirements.Add(SecurityBindingElement.ComputeProtectionRequirements(this, context.BindingParameters, context.Binding.Elements, isForService));
                if (isForService)
                {
                    reverse.ApplyConfidentiality = this.HasProtectionRequirements(reverse.ProtectionRequirements.OutgoingEncryptionParts);
                    reverse.ApplyIntegrity       = true;
                    reverse.RequireIntegrity     = reverse.RequireConfidentiality = false;
                }
                else
                {
                    reverse.RequireConfidentiality = this.HasProtectionRequirements(reverse.ProtectionRequirements.IncomingEncryptionParts);
                    reverse.RequireIntegrity       = true;
                    reverse.ApplyIntegrity         = reverse.ApplyConfidentiality = false;
                }
                base.ConfigureProtocolFactory(reverse, credentialsManager, !isForService, issuerBindingContext, context.Binding);
                if (!reverse.RequireIntegrity)
                {
                    reverse.DetectReplays = false;
                }

                // setup reverse here
                reverse.IsDuplexReply = true;

                DuplexSecurityProtocolFactory duplex = new DuplexSecurityProtocolFactory();
                duplex.ForwardProtocolFactory = forward;
                duplex.ReverseProtocolFactory = reverse;
                protocolFactory = duplex;
            }
            else
            {
                protocolFactory = forward;
            }

            return(protocolFactory);
        }