Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Channels / SecurityBindingElement.cs / 1 / SecurityBindingElement.cs
//------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- namespace System.ServiceModel.Channels { using System; using System.ServiceModel; using System.ServiceModel.Description; using System.ServiceModel.Dispatcher; using System.Xml; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Globalization; using System.IdentityModel.Selectors; using System.IdentityModel.Tokens; using System.Runtime.Serialization; using System.ServiceModel.Security; using System.Net.Security; using System.ServiceModel.Security.Tokens; using System.Text; using System.ServiceModel.Configuration; using System.ServiceModel.Diagnostics; public abstract class SecurityBindingElement : BindingElement { internal const string defaultAlgorithmSuiteString = System.ServiceModel.Configuration.ConfigurationStrings.Default; internal static readonly SecurityAlgorithmSuite defaultDefaultAlgorithmSuite = SecurityAlgorithmSuite.Default; internal const bool defaultIncludeTimestamp = true; internal const MessageProtectionOrder defaultMessageProtectionOrder = MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature; internal const bool defaultRequireSignatureConfirmation = false; SecurityAlgorithmSuite defaultAlgorithmSuite; SupportingTokenParameters endpointSupportingTokenParameters; SupportingTokenParameters optionalEndpointSupportingTokenParameters; bool includeTimestamp; SecurityKeyEntropyMode keyEntropyMode; DictionaryoperationSupportingTokenParameters; Dictionary optionalOperationSupportingTokenParameters; LocalClientSecuritySettings localClientSettings; LocalServiceSecuritySettings localServiceSettings; MessageSecurityVersion messageSecurityVersion; SecurityHeaderLayout securityHeaderLayout; InternalDuplexBindingElement internalDuplexBindingElement; long maxReceivedMessageSize = TransportDefaults.MaxReceivedMessageSize; XmlDictionaryReaderQuotas readerQuotas; bool doNotEmitTrust = false; // true if user create a basic http standard binding, the custombinding equivalent will not set this flag internal SecurityBindingElement() : base() { this.messageSecurityVersion = MessageSecurityVersion.Default; this.keyEntropyMode = AcceleratedTokenProvider.defaultKeyEntropyMode; this.includeTimestamp = defaultIncludeTimestamp; this.defaultAlgorithmSuite = defaultDefaultAlgorithmSuite; this.localClientSettings = new LocalClientSecuritySettings(); this.localServiceSettings = new LocalServiceSecuritySettings(); this.endpointSupportingTokenParameters = new SupportingTokenParameters(); this.optionalEndpointSupportingTokenParameters = new SupportingTokenParameters(); this.operationSupportingTokenParameters = new Dictionary (); this.optionalOperationSupportingTokenParameters = new Dictionary (); this.securityHeaderLayout = SecurityProtocolFactory.defaultSecurityHeaderLayout; } internal SecurityBindingElement(SecurityBindingElement elementToBeCloned) : base(elementToBeCloned) { if (elementToBeCloned == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("elementToBeCloned"); this.defaultAlgorithmSuite = elementToBeCloned.defaultAlgorithmSuite; this.includeTimestamp = elementToBeCloned.includeTimestamp; this.keyEntropyMode = elementToBeCloned.keyEntropyMode; this.messageSecurityVersion = elementToBeCloned.messageSecurityVersion; this.securityHeaderLayout = elementToBeCloned.securityHeaderLayout; this.endpointSupportingTokenParameters = (SupportingTokenParameters)elementToBeCloned.endpointSupportingTokenParameters.Clone(); this.optionalEndpointSupportingTokenParameters = (SupportingTokenParameters)elementToBeCloned.optionalEndpointSupportingTokenParameters.Clone(); this.operationSupportingTokenParameters = new Dictionary (); foreach (string key in elementToBeCloned.operationSupportingTokenParameters.Keys) this.operationSupportingTokenParameters[key] = (SupportingTokenParameters)elementToBeCloned.operationSupportingTokenParameters[key].Clone(); this.optionalOperationSupportingTokenParameters = new Dictionary (); foreach (string key in elementToBeCloned.optionalOperationSupportingTokenParameters.Keys) this.optionalOperationSupportingTokenParameters[key] = (SupportingTokenParameters)elementToBeCloned.optionalOperationSupportingTokenParameters[key].Clone(); this.localClientSettings = (LocalClientSecuritySettings)elementToBeCloned.localClientSettings.Clone(); this.localServiceSettings = (LocalServiceSecuritySettings)elementToBeCloned.localServiceSettings.Clone(); this.internalDuplexBindingElement = elementToBeCloned.internalDuplexBindingElement; this.maxReceivedMessageSize = elementToBeCloned.maxReceivedMessageSize; this.readerQuotas = elementToBeCloned.readerQuotas; this.doNotEmitTrust = elementToBeCloned.doNotEmitTrust; } public SupportingTokenParameters EndpointSupportingTokenParameters { get { return this.endpointSupportingTokenParameters; } } public SupportingTokenParameters OptionalEndpointSupportingTokenParameters { get { return this.optionalEndpointSupportingTokenParameters; } } public IDictionary OperationSupportingTokenParameters { get { return this.operationSupportingTokenParameters; } } public IDictionary OptionalOperationSupportingTokenParameters { get { return this.optionalOperationSupportingTokenParameters; } } public SecurityHeaderLayout SecurityHeaderLayout { get { return this.securityHeaderLayout; } set { if (!SecurityHeaderLayoutHelper.IsDefined(value)) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value")); this.securityHeaderLayout = value; } } public MessageSecurityVersion MessageSecurityVersion { get { return this.messageSecurityVersion; } set { if (value == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("value")); this.messageSecurityVersion = value; } } public bool IncludeTimestamp { get { return this.includeTimestamp; } set { this.includeTimestamp = value; } } public SecurityAlgorithmSuite DefaultAlgorithmSuite { get { return this.defaultAlgorithmSuite; } set { if (value == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("value")); this.defaultAlgorithmSuite = value; } } public LocalClientSecuritySettings LocalClientSettings { get { return this.localClientSettings; } } public LocalServiceSecuritySettings LocalServiceSettings { get { return this.localServiceSettings; } } public SecurityKeyEntropyMode KeyEntropyMode { get { return this.keyEntropyMode; } set { if (!SecurityKeyEntropyModeHelper.IsDefined(value)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value")); } this.keyEntropyMode = value; } } internal virtual bool SessionMode { get { return false; } } internal virtual bool SupportsDuplex { get { return false; } } internal virtual bool SupportsRequestReply { get { return false; } } internal long MaxReceivedMessageSize { get { return this.maxReceivedMessageSize; } set { this.maxReceivedMessageSize = value; } } internal bool DoNotEmitTrust { get { return this.doNotEmitTrust; } set { this.doNotEmitTrust = value; } } internal XmlDictionaryReaderQuotas ReaderQuotas { get { return this.readerQuotas; } set { this.readerQuotas = value; } } void GetSupportingTokensCapabilities(ICollection parameters, out bool supportsClientAuth, out bool supportsWindowsIdentity) { supportsClientAuth = false; supportsWindowsIdentity = false; foreach (SecurityTokenParameters p in parameters) { if (p.SupportsClientAuthentication) supportsClientAuth = true; if (p.SupportsClientWindowsIdentity) supportsWindowsIdentity = true; } } void GetSupportingTokensCapabilities(SupportingTokenParameters requirements, out bool supportsClientAuth, out bool supportsWindowsIdentity) { supportsClientAuth = false; supportsWindowsIdentity = false; bool tmpSupportsClientAuth; bool tmpSupportsWindowsIdentity; this.GetSupportingTokensCapabilities(requirements.Endorsing, out tmpSupportsClientAuth, out tmpSupportsWindowsIdentity); supportsClientAuth = supportsClientAuth || tmpSupportsClientAuth; supportsWindowsIdentity = supportsWindowsIdentity || tmpSupportsWindowsIdentity; this.GetSupportingTokensCapabilities(requirements.SignedEndorsing, out tmpSupportsClientAuth, out tmpSupportsWindowsIdentity); supportsClientAuth = supportsClientAuth || tmpSupportsClientAuth; supportsWindowsIdentity = supportsWindowsIdentity || tmpSupportsWindowsIdentity; this.GetSupportingTokensCapabilities(requirements.SignedEncrypted, out tmpSupportsClientAuth, out tmpSupportsWindowsIdentity); supportsClientAuth = supportsClientAuth || tmpSupportsClientAuth; supportsWindowsIdentity = supportsWindowsIdentity || tmpSupportsWindowsIdentity; } internal void GetSupportingTokensCapabilities(out bool supportsClientAuth, out bool supportsWindowsIdentity) { this.GetSupportingTokensCapabilities(this.EndpointSupportingTokenParameters, out supportsClientAuth, out supportsWindowsIdentity); } // SecureConversation needs a demuxer below security to 1) demux between the security sessions and 2) demux the SCT issue and renewal messages // to the authenticator internal static void AddDemuxerForSecureConversation(ChannelBuilder builder, BindingContext secureConversationBindingContext) { // add a demuxer element right below security unless there's a demuxer already present below and the only // binding elements between security and the demuxer are "ancillary" binding elements like message encoding element and // stream-security upgrade element. We could always add the channel demuxer below security but not doing so in the ancillary // binding elements case improves perf int numChannelDemuxersBelowSecurity = 0; bool doesBindingHaveShapeChangingElements = false; for (int i = 0; i < builder.Binding.Elements.Count; ++i) { if ((builder.Binding.Elements[i] is MessageEncodingBindingElement) || (builder.Binding.Elements[i] is StreamUpgradeBindingElement)) { continue; } if (builder.Binding.Elements[i] is ChannelDemuxerBindingElement) { ++numChannelDemuxersBelowSecurity; } else if (builder.Binding.Elements[i] is TransportBindingElement) { break; } else { doesBindingHaveShapeChangingElements = true; } } if (numChannelDemuxersBelowSecurity == 1 && !doesBindingHaveShapeChangingElements) { return; } ChannelDemuxerBindingElement demuxer = new ChannelDemuxerBindingElement(false); builder.Binding.Elements.Insert(0, demuxer); secureConversationBindingContext.RemainingBindingElements.Insert(0, demuxer); } static BindingContext CreateIssuerBindingContextForNegotiation(BindingContext issuerBindingContext) { TransportBindingElement transport = issuerBindingContext.RemainingBindingElements.Find (); if (transport == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.TransportBindingElementNotFound))); } ChannelDemuxerBindingElement demuxer = null; // pick the demuxer above transport (i.e. the last demuxer in the array) for (int i = 0; i < issuerBindingContext.RemainingBindingElements.Count; ++i) { if (issuerBindingContext.RemainingBindingElements[i] is ChannelDemuxerBindingElement) { demuxer = (ChannelDemuxerBindingElement) issuerBindingContext.RemainingBindingElements[i]; } } if (demuxer == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ChannelDemuxerBindingElementNotFound))); } BindingElementCollection negotiationBindingElements = new BindingElementCollection(); negotiationBindingElements.Add(demuxer.Clone()); negotiationBindingElements.Add(transport.Clone()); CustomBinding binding = new CustomBinding(negotiationBindingElements); binding.OpenTimeout = issuerBindingContext.Binding.OpenTimeout; binding.CloseTimeout = issuerBindingContext.Binding.CloseTimeout; binding.SendTimeout = issuerBindingContext.Binding.SendTimeout; binding.ReceiveTimeout = issuerBindingContext.Binding.ReceiveTimeout; if (issuerBindingContext.ListenUriBaseAddress != null) { return new BindingContext(binding, new BindingParameterCollection(issuerBindingContext.BindingParameters), issuerBindingContext.ListenUriBaseAddress, issuerBindingContext.ListenUriRelativeAddress, issuerBindingContext.ListenUriMode); } else { return new BindingContext(binding, new BindingParameterCollection(issuerBindingContext.BindingParameters)); } } protected static void SetIssuerBindingContextIfRequired(SecurityTokenParameters parameters, BindingContext issuerBindingContext) { if (parameters is SslSecurityTokenParameters) { ((SslSecurityTokenParameters)parameters).IssuerBindingContext = CreateIssuerBindingContextForNegotiation(issuerBindingContext); } else if (parameters is SspiSecurityTokenParameters) { ((SspiSecurityTokenParameters)parameters).IssuerBindingContext = CreateIssuerBindingContextForNegotiation(issuerBindingContext); } } static void SetIssuerBindingContextIfRequired(SupportingTokenParameters supportingParameters, BindingContext issuerBindingContext) { for (int i = 0; i < supportingParameters.Endorsing.Count; ++i) { SetIssuerBindingContextIfRequired(supportingParameters.Endorsing[i], issuerBindingContext); } for (int i = 0; i < supportingParameters.SignedEndorsing.Count; ++i) { SetIssuerBindingContextIfRequired(supportingParameters.SignedEndorsing[i], issuerBindingContext); } for (int i = 0; i < supportingParameters.Signed.Count; ++i) { SetIssuerBindingContextIfRequired(supportingParameters.Signed[i], issuerBindingContext); } for (int i = 0; i < supportingParameters.SignedEncrypted.Count; ++i) { SetIssuerBindingContextIfRequired(supportingParameters.SignedEncrypted[i], issuerBindingContext); } } void SetIssuerBindingContextIfRequired(BindingContext issuerBindingContext) { SetIssuerBindingContextIfRequired(this.EndpointSupportingTokenParameters, issuerBindingContext); SetIssuerBindingContextIfRequired(this.OptionalEndpointSupportingTokenParameters, issuerBindingContext); foreach (SupportingTokenParameters parameters in this.OperationSupportingTokenParameters.Values) { SetIssuerBindingContextIfRequired(parameters, issuerBindingContext); } foreach (SupportingTokenParameters parameters in this.OptionalOperationSupportingTokenParameters.Values) { SetIssuerBindingContextIfRequired(parameters, issuerBindingContext); } } internal bool RequiresChannelDemuxer(SecurityTokenParameters parameters) { return ((parameters is SecureConversationSecurityTokenParameters) || (parameters is SslSecurityTokenParameters) || (parameters is SspiSecurityTokenParameters)); } internal virtual bool RequiresChannelDemuxer() { foreach (SecurityTokenParameters parameters in EndpointSupportingTokenParameters.Endorsing) { if (RequiresChannelDemuxer(parameters)) { return true; } } foreach (SecurityTokenParameters parameters in EndpointSupportingTokenParameters.SignedEndorsing) { if (RequiresChannelDemuxer(parameters)) { return true; } } foreach (SecurityTokenParameters parameters in OptionalEndpointSupportingTokenParameters.Endorsing) { if (RequiresChannelDemuxer(parameters)) { return true; } } foreach (SecurityTokenParameters parameters in OptionalEndpointSupportingTokenParameters.SignedEndorsing) { if (RequiresChannelDemuxer(parameters)) { return true; } } foreach (SupportingTokenParameters supportingParameters in OperationSupportingTokenParameters.Values) { foreach (SecurityTokenParameters parameters in supportingParameters.Endorsing) { if (RequiresChannelDemuxer(parameters)) { return true; } } foreach (SecurityTokenParameters parameters in supportingParameters.SignedEndorsing) { if (RequiresChannelDemuxer(parameters)) { return true; } } } foreach (SupportingTokenParameters supportingParameters in OptionalOperationSupportingTokenParameters.Values) { foreach (SecurityTokenParameters parameters in supportingParameters.Endorsing) { if (RequiresChannelDemuxer(parameters)) { return true; } } foreach (SecurityTokenParameters parameters in supportingParameters.SignedEndorsing) { if (RequiresChannelDemuxer(parameters)) { return true; } } } return false; } internal bool IsUnderlyingListenerDuplex (BindingContext context) { return ((typeof(TChannel) == typeof(IDuplexSessionChannel)) && context.CanBuildInnerChannelListener () && !context.CanBuildInnerChannelListener ()); } void SetPrivacyNoticeUriIfRequired(SecurityProtocolFactory factory, Binding binding) { PrivacyNoticeBindingElement privacyElement = binding.CreateBindingElements().Find (); if (privacyElement != null) { factory.PrivacyNoticeUri = privacyElement.Url; factory.PrivacyNoticeVersion = privacyElement.Version; } } internal void ConfigureProtocolFactory(SecurityProtocolFactory factory, SecurityCredentialsManager credentialsManager, bool isForService, BindingContext issuerBindingContext, Binding binding) { if (factory == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("factory")); if (credentialsManager == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("credentialsManager")); factory.AddTimestamp = this.IncludeTimestamp; factory.IncomingAlgorithmSuite = this.DefaultAlgorithmSuite; factory.OutgoingAlgorithmSuite = this.DefaultAlgorithmSuite; factory.SecurityHeaderLayout = this.SecurityHeaderLayout; if (!isForService) { factory.TimestampValidityDuration = this.LocalClientSettings.TimestampValidityDuration; factory.DetectReplays = this.LocalClientSettings.DetectReplays; factory.MaxCachedNonces = this.LocalClientSettings.ReplayCacheSize; factory.MaxClockSkew = this.LocalClientSettings.MaxClockSkew; factory.ReplayWindow = this.LocalClientSettings.ReplayWindow; } else { factory.TimestampValidityDuration = this.LocalServiceSettings.TimestampValidityDuration; factory.DetectReplays = this.LocalServiceSettings.DetectReplays; factory.MaxCachedNonces = this.LocalServiceSettings.ReplayCacheSize; factory.MaxClockSkew = this.LocalServiceSettings.MaxClockSkew; factory.ReplayWindow = this.LocalServiceSettings.ReplayWindow; } factory.SecurityBindingElement = (SecurityBindingElement) this.Clone(); factory.SecurityBindingElement.SetIssuerBindingContextIfRequired(issuerBindingContext); factory.SecurityTokenManager = credentialsManager.CreateSecurityTokenManager(); SecurityTokenSerializer tokenSerializer = factory.SecurityTokenManager.CreateSecurityTokenSerializer(this.messageSecurityVersion.SecurityTokenVersion); factory.StandardsManager = new SecurityStandardsManager(this.messageSecurityVersion, tokenSerializer); if (!isForService) { SetPrivacyNoticeUriIfRequired(factory, binding); } } internal abstract SecurityProtocolFactory CreateSecurityProtocolFactory (BindingContext context, SecurityCredentialsManager credentialsManager, bool isForService, BindingContext issuanceBindingContext); public override IChannelFactory BuildChannelFactory (BindingContext context) { if (context == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context"); if (!this.CanBuildChannelFactory (context)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.ChannelTypeNotSupported, typeof(TChannel)), "TChannel")); } this.readerQuotas = context.GetInnerProperty (); if (readerQuotas == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.EncodingBindingElementDoesNotHandleReaderQuotas))); } TransportBindingElement transportBindingElement = null; if (context.RemainingBindingElements != null) transportBindingElement = context.RemainingBindingElements.Find (); if (transportBindingElement != null) this.maxReceivedMessageSize = transportBindingElement.MaxReceivedMessageSize; return this.BuildChannelFactoryCore (context); } protected abstract IChannelFactory BuildChannelFactoryCore (BindingContext context); public override bool CanBuildChannelFactory (BindingContext context) { if (context == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context"); InternalDuplexBindingElement.AddDuplexFactorySupport(context, ref this.internalDuplexBindingElement); if (this.SessionMode) { return this.CanBuildSessionChannelFactory (context); } if (!context.CanBuildInnerChannelFactory ()) { return false; } return typeof(TChannel) == typeof(IOutputChannel) || typeof(TChannel) == typeof(IOutputSessionChannel) || (this.SupportsDuplex && (typeof(TChannel) == typeof(IDuplexChannel) || typeof(TChannel) == typeof(IDuplexSessionChannel))) || (this.SupportsRequestReply && (typeof(TChannel) == typeof(IRequestChannel) || typeof(TChannel) == typeof(IRequestSessionChannel))); } bool CanBuildSessionChannelFactory (BindingContext context) { if (!(context.CanBuildInnerChannelFactory () || context.CanBuildInnerChannelFactory () || context.CanBuildInnerChannelFactory () || context.CanBuildInnerChannelFactory ())) { return false; } if (typeof(TChannel) == typeof(IRequestSessionChannel)) { return (context.CanBuildInnerChannelFactory () || context.CanBuildInnerChannelFactory ()); } else if (typeof(TChannel) == typeof(IDuplexSessionChannel)) { return (context.CanBuildInnerChannelFactory () || context.CanBuildInnerChannelFactory ()); } else { return false; } } public override IChannelListener BuildChannelListener (BindingContext context) { if (context == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context"); if (!this.CanBuildChannelListener (context)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.ChannelTypeNotSupported, typeof(TChannel)), "TChannel")); } this.readerQuotas = context.GetInnerProperty (); if (readerQuotas == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.EncodingBindingElementDoesNotHandleReaderQuotas))); } TransportBindingElement transportBindingElement = null; if (context.RemainingBindingElements != null) transportBindingElement = context.RemainingBindingElements.Find (); if (transportBindingElement != null) this.maxReceivedMessageSize = transportBindingElement.MaxReceivedMessageSize; return this.BuildChannelListenerCore (context); } protected abstract IChannelListener BuildChannelListenerCore (BindingContext context) where TChannel : class, IChannel; public override bool CanBuildChannelListener (BindingContext context) { if (context == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context"); InternalDuplexBindingElement.AddDuplexListenerSupport(context, ref this.internalDuplexBindingElement); if (this.SessionMode) { return this.CanBuildSessionChannelListener (context); } if (!context.CanBuildInnerChannelListener ()) { return false; } return typeof(TChannel) == typeof(IInputChannel) || typeof(TChannel) == typeof(IInputSessionChannel) || (this.SupportsDuplex && (typeof(TChannel) == typeof(IDuplexChannel) || typeof(TChannel) == typeof(IDuplexSessionChannel))) || (this.SupportsRequestReply && (typeof(TChannel) == typeof(IReplyChannel) || typeof(TChannel) == typeof(IReplySessionChannel))); } bool CanBuildSessionChannelListener (BindingContext context) where TChannel : class, IChannel { if (!(context.CanBuildInnerChannelListener () || context.CanBuildInnerChannelListener () || context.CanBuildInnerChannelListener () || context.CanBuildInnerChannelListener ())) { return false; } if (typeof(TChannel) == typeof(IReplySessionChannel)) { return (context.CanBuildInnerChannelListener () || context.CanBuildInnerChannelListener ()); } else if (typeof(TChannel) == typeof(IDuplexSessionChannel)) { return (context.CanBuildInnerChannelListener () || context.CanBuildInnerChannelListener ()); } else { return false; } } public virtual void SetKeyDerivation(bool requireDerivedKeys) { this.EndpointSupportingTokenParameters.SetKeyDerivation(requireDerivedKeys); this.OptionalEndpointSupportingTokenParameters.SetKeyDerivation(requireDerivedKeys); foreach (SupportingTokenParameters t in this.OperationSupportingTokenParameters.Values) t.SetKeyDerivation(requireDerivedKeys); foreach (SupportingTokenParameters t in this.OptionalOperationSupportingTokenParameters.Values) { t.SetKeyDerivation(requireDerivedKeys); } } internal virtual bool IsSetKeyDerivation(bool requireDerivedKeys) { if (!this.EndpointSupportingTokenParameters.IsSetKeyDerivation(requireDerivedKeys)) return false; if (!this.OptionalEndpointSupportingTokenParameters.IsSetKeyDerivation(requireDerivedKeys)) return false; foreach (SupportingTokenParameters t in this.OperationSupportingTokenParameters.Values) { if (!t.IsSetKeyDerivation(requireDerivedKeys)) return false; } foreach (SupportingTokenParameters t in this.OptionalOperationSupportingTokenParameters.Values) { if (!t.IsSetKeyDerivation(requireDerivedKeys)) return false; } return true; } internal ChannelProtectionRequirements GetProtectionRequirements(AddressingVersion addressing, ProtectionLevel defaultProtectionLevel) { if (addressing == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("addressing"); ChannelProtectionRequirements result = new ChannelProtectionRequirements(); ProtectionLevel supportedRequestProtectionLevel = this.GetIndividualProperty ().SupportedRequestProtectionLevel; ProtectionLevel supportedResponseProtectionLevel = this.GetIndividualProperty ().SupportedResponseProtectionLevel; bool canSupportMoreThanTheDefault = (ProtectionLevelHelper.IsStrongerOrEqual(supportedRequestProtectionLevel, defaultProtectionLevel) && ProtectionLevelHelper.IsStrongerOrEqual(supportedResponseProtectionLevel, defaultProtectionLevel)); if (canSupportMoreThanTheDefault) { MessagePartSpecification signedParts = new MessagePartSpecification(); MessagePartSpecification encryptedParts = new MessagePartSpecification(); if (defaultProtectionLevel != ProtectionLevel.None) { signedParts.IsBodyIncluded = true; if (defaultProtectionLevel == ProtectionLevel.EncryptAndSign) { encryptedParts.IsBodyIncluded = true; } } signedParts.MakeReadOnly(); encryptedParts.MakeReadOnly(); if (addressing.FaultAction != null) { // Addressing faults result.IncomingSignatureParts.AddParts(signedParts, addressing.FaultAction); result.OutgoingSignatureParts.AddParts(signedParts, addressing.FaultAction); result.IncomingEncryptionParts.AddParts(encryptedParts, addressing.FaultAction); result.OutgoingEncryptionParts.AddParts(encryptedParts, addressing.FaultAction); } if (addressing.DefaultFaultAction != null) { // Faults that do not specify a particular action result.IncomingSignatureParts.AddParts(signedParts, addressing.DefaultFaultAction); result.OutgoingSignatureParts.AddParts(signedParts, addressing.DefaultFaultAction); result.IncomingEncryptionParts.AddParts(encryptedParts, addressing.DefaultFaultAction); result.OutgoingEncryptionParts.AddParts(encryptedParts, addressing.DefaultFaultAction); } // Infrastructure faults result.IncomingSignatureParts.AddParts(signedParts, FaultCodeConstants.Actions.NetDispatcher); result.OutgoingSignatureParts.AddParts(signedParts, FaultCodeConstants.Actions.NetDispatcher); result.IncomingEncryptionParts.AddParts(encryptedParts, FaultCodeConstants.Actions.NetDispatcher); result.OutgoingEncryptionParts.AddParts(encryptedParts, FaultCodeConstants.Actions.NetDispatcher); } return result; } public override T GetProperty (BindingContext context) { if (context == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context"); } if (typeof(T) == typeof(ISecurityCapabilities)) { return (T)(object)GetSecurityCapabilities(context); } else if (typeof(T) == typeof(IdentityVerifier)) { return (T)(object)this.localClientSettings.IdentityVerifier; } else { return context.GetInnerProperty (); } } internal abstract ISecurityCapabilities GetIndividualISecurityCapabilities(); ISecurityCapabilities GetSecurityCapabilities(BindingContext context) { ISecurityCapabilities thisSecurityCapability = this.GetIndividualISecurityCapabilities(); ISecurityCapabilities lowerSecurityCapability = context.GetInnerProperty (); if (lowerSecurityCapability == null) { return thisSecurityCapability; } else { bool supportsClientAuth = thisSecurityCapability.SupportsClientAuthentication; bool supportsClientWindowsIdentity = thisSecurityCapability.SupportsClientWindowsIdentity; bool supportsServerAuth = thisSecurityCapability.SupportsServerAuthentication || lowerSecurityCapability.SupportsServerAuthentication; ProtectionLevel requestProtectionLevel = ProtectionLevelHelper.Max(thisSecurityCapability.SupportedRequestProtectionLevel, lowerSecurityCapability.SupportedRequestProtectionLevel); ProtectionLevel responseProtectionLevel = ProtectionLevelHelper.Max(thisSecurityCapability.SupportedResponseProtectionLevel, lowerSecurityCapability.SupportedResponseProtectionLevel); return new SecurityCapabilities(supportsClientAuth, supportsServerAuth, supportsClientWindowsIdentity, requestProtectionLevel, responseProtectionLevel); } } // If any changes are made to this method, please make sure that they are // reflected in the corresponding IsMutualCertificateBinding() method. static public SecurityBindingElement CreateMutualCertificateBindingElement() { return CreateMutualCertificateBindingElement(MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11); } // this method reverses CreateMutualCertificateBindingElement() logic internal static bool IsMutualCertificateBinding(SecurityBindingElement sbe) { return IsMutualCertificateBinding(sbe, false); } static public AsymmetricSecurityBindingElement CreateCertificateSignatureBindingElement() { AsymmetricSecurityBindingElement result; result = new AsymmetricSecurityBindingElement( new X509SecurityTokenParameters( // recipient X509KeyIdentifierClauseType.Any, SecurityTokenInclusionMode.Never, false), new X509SecurityTokenParameters( // initiator X509KeyIdentifierClauseType.Any, SecurityTokenInclusionMode.AlwaysToRecipient, false)); // this is a one way binding so the client cannot detect replays result.IsCertificateSignatureBinding = true; result.LocalClientSettings.DetectReplays = false; result.MessageProtectionOrder = MessageProtectionOrder.SignBeforeEncrypt; return result; } // If any changes are made to this method, please make sure that they are // reflected in the corresponding IsMutualCertificateBinding() method. static public SecurityBindingElement CreateMutualCertificateBindingElement(MessageSecurityVersion version) { return CreateMutualCertificateBindingElement(version, false); } // If any changes are made to this method, please make sure that they are // reflected in the corresponding IsMutualCertificateBinding() method. static public SecurityBindingElement CreateMutualCertificateBindingElement(MessageSecurityVersion version, bool allowSerializedSigningTokenOnReply) { if (version == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("version"); } SecurityBindingElement result; if (version.SecurityVersion == SecurityVersion.WSSecurity10) { result = new AsymmetricSecurityBindingElement( new X509SecurityTokenParameters( // recipient X509KeyIdentifierClauseType.Any, SecurityTokenInclusionMode.Never, false), new X509SecurityTokenParameters( // initiator X509KeyIdentifierClauseType.Any, SecurityTokenInclusionMode.AlwaysToRecipient, false), allowSerializedSigningTokenOnReply); } else { result = new SymmetricSecurityBindingElement( new X509SecurityTokenParameters( // protection X509KeyIdentifierClauseType.Thumbprint, SecurityTokenInclusionMode.Never)); result.EndpointSupportingTokenParameters.Endorsing.Add( new X509SecurityTokenParameters( X509KeyIdentifierClauseType.Thumbprint, SecurityTokenInclusionMode.AlwaysToRecipient, false)); ((SymmetricSecurityBindingElement)result).RequireSignatureConfirmation = true; } result.MessageSecurityVersion = version; return result; } // this method reverses CreateMutualCertificateDuplexBindingElement() logic internal static bool IsMutualCertificateDuplexBinding(SecurityBindingElement sbe) { // Do not check MessageSecurityVersion: it maybe changed by the wrapper element and gets checked later in the SecuritySection.AreBindingsMatching() AsymmetricSecurityBindingElement asbe = sbe as AsymmetricSecurityBindingElement; if (asbe != null) { X509SecurityTokenParameters recipient = asbe.RecipientTokenParameters as X509SecurityTokenParameters; if (recipient == null || (recipient.X509ReferenceStyle != X509KeyIdentifierClauseType.Any && recipient.X509ReferenceStyle != X509KeyIdentifierClauseType.Thumbprint)|| recipient.InclusionMode != SecurityTokenInclusionMode.AlwaysToInitiator) return false; X509SecurityTokenParameters initiator = asbe.InitiatorTokenParameters as X509SecurityTokenParameters; if (initiator == null || (initiator.X509ReferenceStyle != X509KeyIdentifierClauseType.Any && initiator.X509ReferenceStyle != X509KeyIdentifierClauseType.Thumbprint) || initiator.InclusionMode != SecurityTokenInclusionMode.AlwaysToRecipient) return false; if (!sbe.EndpointSupportingTokenParameters.IsEmpty()) return false; return true; } else { return false; } } // this method reverses CreateMutualCertificateBindingElement() logic internal static bool IsMutualCertificateBinding(SecurityBindingElement sbe, bool allowSerializedSigningTokenOnReply) { // Do not check MessageSecurityVersion: it maybe changed by the wrapper element and gets checked later in the SecuritySection.AreBindingsMatching() AsymmetricSecurityBindingElement asbe = sbe as AsymmetricSecurityBindingElement; if (asbe != null) { X509SecurityTokenParameters recipient = asbe.RecipientTokenParameters as X509SecurityTokenParameters; if (recipient == null || recipient.X509ReferenceStyle != X509KeyIdentifierClauseType.Any || recipient.InclusionMode != SecurityTokenInclusionMode.Never) return false; X509SecurityTokenParameters initiator = asbe.InitiatorTokenParameters as X509SecurityTokenParameters; if (initiator == null || initiator.X509ReferenceStyle != X509KeyIdentifierClauseType.Any || initiator.InclusionMode != SecurityTokenInclusionMode.AlwaysToRecipient) return false; if (!sbe.EndpointSupportingTokenParameters.IsEmpty()) return false; } else { SymmetricSecurityBindingElement ssbe = sbe as SymmetricSecurityBindingElement; if (ssbe == null) return false; X509SecurityTokenParameters x509Parameters = ssbe.ProtectionTokenParameters as X509SecurityTokenParameters; if (x509Parameters == null || x509Parameters.X509ReferenceStyle != X509KeyIdentifierClauseType.Thumbprint || x509Parameters.InclusionMode != SecurityTokenInclusionMode.Never) return false; SupportingTokenParameters parameters = sbe.EndpointSupportingTokenParameters; if (parameters.Signed.Count != 0 || parameters.SignedEncrypted.Count != 0 || parameters.Endorsing.Count != 1 || parameters.SignedEndorsing.Count != 0) return false; x509Parameters = parameters.Endorsing[0] as X509SecurityTokenParameters; if (x509Parameters == null || x509Parameters.X509ReferenceStyle != X509KeyIdentifierClauseType.Thumbprint || x509Parameters.InclusionMode != SecurityTokenInclusionMode.AlwaysToRecipient) return false; if (!ssbe.RequireSignatureConfirmation) return false; } return true; } // If any changes are made to this method, please make sure that they are // reflected in the corresponding IsAnonymousForCertificateBinding() method. static public SymmetricSecurityBindingElement CreateAnonymousForCertificateBindingElement() { SymmetricSecurityBindingElement result; result = new SymmetricSecurityBindingElement( new X509SecurityTokenParameters( // protection X509KeyIdentifierClauseType.Thumbprint, SecurityTokenInclusionMode.Never)); result.MessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11; result.RequireSignatureConfirmation = true; return result; } // this method reverses CreateAnonymousForCertificateBindingElement() logic internal static bool IsAnonymousForCertificateBinding(SecurityBindingElement sbe) { SymmetricSecurityBindingElement ssbe = sbe as SymmetricSecurityBindingElement; if (ssbe == null) return false; if (!ssbe.RequireSignatureConfirmation) return false; // Do not check MessageSecurityVersion: it maybe changed by the wrapper element and gets checked later in the SecuritySection.AreBindingsMatching() X509SecurityTokenParameters x509Parameters = ssbe.ProtectionTokenParameters as X509SecurityTokenParameters; if (x509Parameters == null || x509Parameters.X509ReferenceStyle != X509KeyIdentifierClauseType.Thumbprint || x509Parameters.InclusionMode != SecurityTokenInclusionMode.Never) return false; if (!sbe.EndpointSupportingTokenParameters.IsEmpty()) return false; return true; } static public AsymmetricSecurityBindingElement CreateMutualCertificateDuplexBindingElement() { return CreateMutualCertificateDuplexBindingElement(MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11); } static public AsymmetricSecurityBindingElement CreateMutualCertificateDuplexBindingElement(MessageSecurityVersion version) { if (version == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("version"); } AsymmetricSecurityBindingElement result; if (version.SecurityVersion == SecurityVersion.WSSecurity10) { result = new AsymmetricSecurityBindingElement( new X509SecurityTokenParameters( // recipient X509KeyIdentifierClauseType.Any, SecurityTokenInclusionMode.AlwaysToInitiator, false), new X509SecurityTokenParameters( // initiator X509KeyIdentifierClauseType.Any, SecurityTokenInclusionMode.AlwaysToRecipient, false)); } else { result = new AsymmetricSecurityBindingElement( new X509SecurityTokenParameters( // recipient X509KeyIdentifierClauseType.Thumbprint, SecurityTokenInclusionMode.AlwaysToInitiator, false), new X509SecurityTokenParameters( // initiator X509KeyIdentifierClauseType.Thumbprint, SecurityTokenInclusionMode.AlwaysToRecipient, false)); } result.MessageSecurityVersion = version; return result; } // If any changes are made to this method, please make sure that they are // reflected in the corresponding IsUserNameForCertificateBinding() method. static public SymmetricSecurityBindingElement CreateUserNameForCertificateBindingElement() { SymmetricSecurityBindingElement result = new SymmetricSecurityBindingElement( new X509SecurityTokenParameters( X509KeyIdentifierClauseType.Thumbprint, SecurityTokenInclusionMode.Never)); result.EndpointSupportingTokenParameters.SignedEncrypted.Add( new UserNameSecurityTokenParameters()); result.MessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11; return result; } // this method reverses CreateMutualCertificateBindingElement() logic internal static bool IsUserNameForCertificateBinding(SecurityBindingElement sbe) { // Do not check MessageSecurityVersion: it maybe changed by the wrapper element and gets checked later in the SecuritySection.AreBindingsMatching() SymmetricSecurityBindingElement ssbe = sbe as SymmetricSecurityBindingElement; if (ssbe == null) return false; X509SecurityTokenParameters x509Parameters = ssbe.ProtectionTokenParameters as X509SecurityTokenParameters; if (x509Parameters == null || x509Parameters.X509ReferenceStyle != X509KeyIdentifierClauseType.Thumbprint || x509Parameters.InclusionMode != SecurityTokenInclusionMode.Never) return false; SupportingTokenParameters parameters = sbe.EndpointSupportingTokenParameters; if (parameters.Signed.Count != 0 || parameters.SignedEncrypted.Count != 1 || parameters.Endorsing.Count != 0 || parameters.SignedEndorsing.Count != 0) return false; UserNameSecurityTokenParameters userNameParameters = parameters.SignedEncrypted[0] as UserNameSecurityTokenParameters; if (userNameParameters == null) return false; return true; } // If any changes are made to this method, please make sure that they are // reflected in the corresponding IsKerberosBinding() method. static public SymmetricSecurityBindingElement CreateKerberosBindingElement() { SymmetricSecurityBindingElement result = new SymmetricSecurityBindingElement( new KerberosSecurityTokenParameters()); result.DefaultAlgorithmSuite = SecurityAlgorithmSuite.KerberosDefault; return result; } // this method reverses CreateMutualCertificateBindingElement() logic internal static bool IsKerberosBinding(SecurityBindingElement sbe) { // do not check DefaultAlgorithmSuite match: it is often changed by the caller of CreateKerberosBindingElement SymmetricSecurityBindingElement ssbe = sbe as SymmetricSecurityBindingElement; if (ssbe == null) return false; KerberosSecurityTokenParameters parameters = ssbe.ProtectionTokenParameters as KerberosSecurityTokenParameters; if (parameters == null) return false; if (!sbe.EndpointSupportingTokenParameters.IsEmpty()) return false; return true; } static public SymmetricSecurityBindingElement CreateSspiNegotiationBindingElement() { return CreateSspiNegotiationBindingElement(SspiSecurityTokenParameters.defaultRequireCancellation); } // If any changes are made to this method, please make sure that they are // reflected in the corresponding IsSspiNegotiationBinding() method. static public SymmetricSecurityBindingElement CreateSspiNegotiationBindingElement(bool requireCancellation) { SymmetricSecurityBindingElement result = new SymmetricSecurityBindingElement( new SspiSecurityTokenParameters(requireCancellation)); return result; } // this method reverses CreateMutualCertificateBindingElement() logic internal static bool IsSspiNegotiationBinding(SecurityBindingElement sbe, bool requireCancellation) { SymmetricSecurityBindingElement ssbe = sbe as SymmetricSecurityBindingElement; if (ssbe == null) return false; if (!sbe.EndpointSupportingTokenParameters.IsEmpty()) return false; SspiSecurityTokenParameters sspiParameters = ssbe.ProtectionTokenParameters as SspiSecurityTokenParameters; if (sspiParameters == null) return false; return sspiParameters.RequireCancellation == requireCancellation; } static public SymmetricSecurityBindingElement CreateSslNegotiationBindingElement(bool requireClientCertificate) { return CreateSslNegotiationBindingElement(requireClientCertificate, SslSecurityTokenParameters.defaultRequireCancellation); } // If any changes are made to this method, please make sure that they are // reflected in the corresponding IsSslNegotiationBinding() method. static public SymmetricSecurityBindingElement CreateSslNegotiationBindingElement(bool requireClientCertificate, bool requireCancellation) { SymmetricSecurityBindingElement result = new SymmetricSecurityBindingElement( new SslSecurityTokenParameters(requireClientCertificate, requireCancellation)); return result; } // this method reverses CreateMutualCertificateBindingElement() logic internal static bool IsSslNegotiationBinding(SecurityBindingElement sbe, bool requireClientCertificate, bool requireCancellation) { SymmetricSecurityBindingElement ssbe = sbe as SymmetricSecurityBindingElement; if (ssbe == null) return false; if (!sbe.EndpointSupportingTokenParameters.IsEmpty()) return false; SslSecurityTokenParameters sslParameters = ssbe.ProtectionTokenParameters as SslSecurityTokenParameters; if (sslParameters == null) return false; return sslParameters.RequireClientCertificate == requireClientCertificate && sslParameters.RequireCancellation == requireCancellation; } static public SymmetricSecurityBindingElement CreateIssuedTokenBindingElement(IssuedSecurityTokenParameters issuedTokenParameters) { if (issuedTokenParameters == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("issuedTokenParameters"); if (issuedTokenParameters.KeyType != SecurityKeyType.SymmetricKey) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.IssuedTokenAuthenticationModeRequiresSymmetricIssuedKey)); SymmetricSecurityBindingElement result = new SymmetricSecurityBindingElement(issuedTokenParameters); return result; } // If any changes are made to this method, please make sure that they are // reflected in the corresponding IsIssuedTokenForCertificateBinding() method. static public SymmetricSecurityBindingElement CreateIssuedTokenForCertificateBindingElement(IssuedSecurityTokenParameters issuedTokenParameters) { if (issuedTokenParameters == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("issuedTokenParameters"); SymmetricSecurityBindingElement result = new SymmetricSecurityBindingElement( new X509SecurityTokenParameters( X509KeyIdentifierClauseType.Thumbprint, SecurityTokenInclusionMode.Never)); if (issuedTokenParameters.KeyType == SecurityKeyType.BearerKey) { result.EndpointSupportingTokenParameters.SignedEncrypted.Add(issuedTokenParameters); result.MessageSecurityVersion = MessageSecurityVersion.WSSXDefault; } else { result.EndpointSupportingTokenParameters.Endorsing.Add(issuedTokenParameters); result.MessageSecurityVersion = MessageSecurityVersion.Default; } result.RequireSignatureConfirmation = true; return result; } // this method reverses CreateMutualCertificateBindingElement() logic internal static bool IsIssuedTokenForCertificateBinding(SecurityBindingElement sbe, out IssuedSecurityTokenParameters issuedTokenParameters) { issuedTokenParameters = null; SymmetricSecurityBindingElement ssbe = sbe as SymmetricSecurityBindingElement; if (ssbe == null) return false; if (!ssbe.RequireSignatureConfirmation) return false; // Do not check MessageSecurityVersion: it maybe changed by the wrapper element and gets checked later in the SecuritySection.AreBindingsMatching() X509SecurityTokenParameters x509Parameters = ssbe.ProtectionTokenParameters as X509SecurityTokenParameters; if (x509Parameters == null || x509Parameters.X509ReferenceStyle != X509KeyIdentifierClauseType.Thumbprint || x509Parameters.InclusionMode != SecurityTokenInclusionMode.Never) return false; SupportingTokenParameters parameters = ssbe.EndpointSupportingTokenParameters; if (parameters.Signed.Count != 0 || (parameters.SignedEncrypted.Count == 0 && parameters.Endorsing.Count == 0) || parameters.SignedEndorsing.Count != 0) return false; if ((parameters.SignedEncrypted.Count == 1) && (parameters.Endorsing.Count == 0)) { issuedTokenParameters = parameters.SignedEncrypted[0] as IssuedSecurityTokenParameters; if (issuedTokenParameters != null && issuedTokenParameters.KeyType != SecurityKeyType.BearerKey) return false; } else if ((parameters.Endorsing.Count == 1) && (parameters.SignedEncrypted.Count == 0)) { issuedTokenParameters = parameters.Endorsing[0] as IssuedSecurityTokenParameters; if (issuedTokenParameters != null && (issuedTokenParameters.KeyType != SecurityKeyType.SymmetricKey && issuedTokenParameters.KeyType != SecurityKeyType.AsymmetricKey)) return false; } return (issuedTokenParameters != null); } // If any changes are made to this method, please make sure that they are // reflected in the corresponding IsIssuedTokenForSslBinding() method. static public SymmetricSecurityBindingElement CreateIssuedTokenForSslBindingElement(IssuedSecurityTokenParameters issuedTokenParameters) { return CreateIssuedTokenForSslBindingElement(issuedTokenParameters, SslSecurityTokenParameters.defaultRequireCancellation); } // this method reverses CreateMutualCertificateBindingElement() logic internal static bool IsIssuedTokenForSslBinding(SecurityBindingElement sbe, out IssuedSecurityTokenParameters issuedTokenParameters) { return IsIssuedTokenForSslBinding(sbe, SslSecurityTokenParameters.defaultRequireCancellation, out issuedTokenParameters); } // If any changes are made to this method, please make sure that they are // reflected in the corresponding IsIssuedTokenForSslBinding() method. static public SymmetricSecurityBindingElement CreateIssuedTokenForSslBindingElement(IssuedSecurityTokenParameters issuedTokenParameters, bool requireCancellation) { if (issuedTokenParameters == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("issuedTokenParameters"); SymmetricSecurityBindingElement result = new SymmetricSecurityBindingElement( new SslSecurityTokenParameters(false, requireCancellation)); if (issuedTokenParameters.KeyType == SecurityKeyType.BearerKey) { result.EndpointSupportingTokenParameters.SignedEncrypted.Add(issuedTokenParameters); result.MessageSecurityVersion = MessageSecurityVersion.WSSXDefault; } else { result.EndpointSupportingTokenParameters.Endorsing.Add(issuedTokenParameters); result.MessageSecurityVersion = MessageSecurityVersion.Default; } result.RequireSignatureConfirmation = true; return result; } // this method reverses CreateMutualCertificateBindingElement() logic internal static bool IsIssuedTokenForSslBinding(SecurityBindingElement sbe, bool requireCancellation, out IssuedSecurityTokenParameters issuedTokenParameters) { issuedTokenParameters = null; SymmetricSecurityBindingElement ssbe = sbe as SymmetricSecurityBindingElement; if (ssbe == null) return false; if (!ssbe.RequireSignatureConfirmation) return false; // Do not check MessageSecurityVersion: it maybe changed by the wrapper element and gets checked later in the SecuritySection.AreBindingsMatching() SslSecurityTokenParameters sslParameters = ssbe.ProtectionTokenParameters as SslSecurityTokenParameters; if (sslParameters == null) return false; if (sslParameters.RequireClientCertificate || sslParameters.RequireCancellation != requireCancellation) return false; SupportingTokenParameters parameters = ssbe.EndpointSupportingTokenParameters; if (parameters.Signed.Count != 0 || (parameters.SignedEncrypted.Count == 0 && parameters.Endorsing.Count == 0) || parameters.SignedEndorsing.Count != 0) return false; if ((parameters.SignedEncrypted.Count == 1) && (parameters.Endorsing.Count == 0)) { issuedTokenParameters = parameters.SignedEncrypted[0] as IssuedSecurityTokenParameters; if (issuedTokenParameters != null && issuedTokenParameters.KeyType != SecurityKeyType.BearerKey) return false; } else if ((parameters.Endorsing.Count == 1) && (parameters.SignedEncrypted.Count == 0)) { issuedTokenParameters = parameters.Endorsing[0] as IssuedSecurityTokenParameters; if (issuedTokenParameters != null && (issuedTokenParameters.KeyType != SecurityKeyType.SymmetricKey && issuedTokenParameters.KeyType != SecurityKeyType.AsymmetricKey)) return false; } return (issuedTokenParameters != null); } static public SymmetricSecurityBindingElement CreateUserNameForSslBindingElement() { return CreateUserNameForSslBindingElement(SslSecurityTokenParameters.defaultRequireCancellation); } // If any changes are made to this method, please make sure that they are // reflected in the corresponding IsUserNameForSslBinding() method. static public SymmetricSecurityBindingElement CreateUserNameForSslBindingElement(bool requireCancellation) { SymmetricSecurityBindingElement result = new SymmetricSecurityBindingElement( new SslSecurityTokenParameters(false, requireCancellation)); result.EndpointSupportingTokenParameters.SignedEncrypted.Add( new UserNameSecurityTokenParameters()); result.MessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11; return result; } // this method reverses CreateMutualCertificateBindingElement() logic internal static bool IsUserNameForSslBinding(SecurityBindingElement sbe, bool requireCancellation) { // Do not check MessageSecurityVersion: it maybe changed by the wrapper element and gets checked later in the SecuritySection.AreBindingsMatching() SymmetricSecurityBindingElement ssbe = sbe as SymmetricSecurityBindingElement; if (ssbe == null) return false; SupportingTokenParameters parameters = sbe.EndpointSupportingTokenParameters; if (parameters.Signed.Count != 0 || parameters.SignedEncrypted.Count != 1 || parameters.Endorsing.Count != 0 || parameters.SignedEndorsing.Count != 0) return false; if (!(parameters.SignedEncrypted[0] is UserNameSecurityTokenParameters)) return false; SslSecurityTokenParameters sslParameters = ssbe.ProtectionTokenParameters as SslSecurityTokenParameters; if (sslParameters == null) return false; return sslParameters.RequireCancellation == requireCancellation && !sslParameters.RequireClientCertificate; } // If any changes are made to this method, please make sure that they are // reflected in the corresponding IsUserNameOverTransportBinding() method. static public TransportSecurityBindingElement CreateUserNameOverTransportBindingElement() { TransportSecurityBindingElement result = new TransportSecurityBindingElement(); result.EndpointSupportingTokenParameters.SignedEncrypted.Add( new UserNameSecurityTokenParameters()); result.IncludeTimestamp = true; result.LocalClientSettings.DetectReplays = false; result.LocalServiceSettings.DetectReplays = false; return result; } // this method reverses CreateMutualCertificateBindingElement() logic internal static bool IsUserNameOverTransportBinding(SecurityBindingElement sbe) { // do not check local settings: sbe.LocalServiceSettings and sbe.LocalClientSettings if (!sbe.IncludeTimestamp) return false; if (!(sbe is TransportSecurityBindingElement)) return false; SupportingTokenParameters parameters = sbe.EndpointSupportingTokenParameters; if (parameters.Signed.Count != 0 || parameters.SignedEncrypted.Count != 1 || parameters.Endorsing.Count != 0 || parameters.SignedEndorsing.Count != 0) return false; UserNameSecurityTokenParameters userNameParameters = parameters.SignedEncrypted[0] as UserNameSecurityTokenParameters; if (userNameParameters == null) return false; return true; } // If any changes are made to this method, please make sure that they are // reflected in the corresponding IsCertificateOverTransportBinding() method. static public TransportSecurityBindingElement CreateCertificateOverTransportBindingElement() { return CreateCertificateOverTransportBindingElement(MessageSecurityVersion.Default); } // If any changes are made to this method, please make sure that they are // reflected in the corresponding IsCertificateOverTransportBinding() method. static public TransportSecurityBindingElement CreateCertificateOverTransportBindingElement(MessageSecurityVersion version) { if (version == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("version"); } X509KeyIdentifierClauseType x509ReferenceType; if (version.SecurityVersion == SecurityVersion.WSSecurity10) { x509ReferenceType = X509KeyIdentifierClauseType.Any; } else { x509ReferenceType = X509KeyIdentifierClauseType.Thumbprint; } TransportSecurityBindingElement result = new TransportSecurityBindingElement(); X509SecurityTokenParameters x509Parameters = new X509SecurityTokenParameters( x509ReferenceType, SecurityTokenInclusionMode.AlwaysToRecipient, false); result.EndpointSupportingTokenParameters.Endorsing.Add( x509Parameters ); result.IncludeTimestamp = true; result.LocalClientSettings.DetectReplays = false; result.LocalServiceSettings.DetectReplays = false; result.MessageSecurityVersion = version; return result; } // this method reverses CreateMutualCertificateBindingElement() logic internal static bool IsCertificateOverTransportBinding(SecurityBindingElement sbe) { // do not check local settings: sbe.LocalServiceSettings and sbe.LocalClientSettings if (!sbe.IncludeTimestamp) return false; if (!(sbe is TransportSecurityBindingElement)) return false; SupportingTokenParameters parameters = sbe.EndpointSupportingTokenParameters; if (parameters.Signed.Count != 0 || parameters.SignedEncrypted.Count != 0 || parameters.Endorsing.Count != 1 || parameters.SignedEndorsing.Count != 0) return false; X509SecurityTokenParameters x509Parameters = parameters.Endorsing[0] as X509SecurityTokenParameters; if (x509Parameters == null) return false; if (x509Parameters.InclusionMode != SecurityTokenInclusionMode.AlwaysToRecipient) return false; return x509Parameters.X509ReferenceStyle == X509KeyIdentifierClauseType.Any || x509Parameters.X509ReferenceStyle == X509KeyIdentifierClauseType.Thumbprint; } static public TransportSecurityBindingElement CreateKerberosOverTransportBindingElement() { TransportSecurityBindingElement result = new TransportSecurityBindingElement(); KerberosSecurityTokenParameters kerberosParameters = new KerberosSecurityTokenParameters(); kerberosParameters.RequireDerivedKeys = false; result.EndpointSupportingTokenParameters.Endorsing.Add( kerberosParameters); result.IncludeTimestamp = true; result.LocalClientSettings.DetectReplays = false; result.LocalServiceSettings.DetectReplays = false; result.DefaultAlgorithmSuite = SecurityAlgorithmSuite.KerberosDefault; return result; } #if NO // this is reversing of the CreateKerberosOverTransportBindingElement() logic static bool IsKerberosOverTransportBinding(SecurityBindingElement sbe) { if (sbe.DefaultAlgorithmSuite != SecurityAlgorithmSuite.KerberosDefault) return false; // do not check local settings: sbe.LocalServiceSettings and sbe.LocalClientSettings if (!sbe.IncludeTimestamp) return false; if (!(sbe is TransportSecurityBindingElement)) return false; SupportingTokenParameters parameters = sbe.EndpointSupportingTokenParameters; if (parameters.Signed.Count != 0 || parameters.SignedEncrypted.Count != 0 || parameters.Endorsing.Count != 1 || parameters.SignedEndorsing.Count != 0) return false; KerberosSecurityTokenParameters kerberosParameters = parameters.Endorsing[0] as KerberosSecurityTokenParameters; if (kerberosParameters == null) return false; if (kerberosParameters.RequireDerivedKeys) return false; return true; } #endif static public TransportSecurityBindingElement CreateSspiNegotiationOverTransportBindingElement() { return CreateSspiNegotiationOverTransportBindingElement(true); } // If any changes are made to this method, please make sure that they are // reflected in the corresponding IsSspiNegotiationOverTransportBinding() method. static public TransportSecurityBindingElement CreateSspiNegotiationOverTransportBindingElement(bool requireCancellation) { TransportSecurityBindingElement result = new TransportSecurityBindingElement(); SspiSecurityTokenParameters sspiParameters = new SspiSecurityTokenParameters(requireCancellation); sspiParameters.RequireDerivedKeys = false; result.EndpointSupportingTokenParameters.Endorsing.Add( sspiParameters); result.IncludeTimestamp = true; result.LocalClientSettings.DetectReplays = false; result.LocalServiceSettings.DetectReplays = false; return result; } // this method reverses CreateSspiNegotiationOverTransportBindingElement() logic internal static bool IsSspiNegotiationOverTransportBinding(SecurityBindingElement sbe, bool requireCancellation) { // do not check local settings: sbe.LocalServiceSettings and sbe.LocalClientSettings if (!sbe.IncludeTimestamp) return false; SupportingTokenParameters parameters = sbe.EndpointSupportingTokenParameters; if (parameters.Signed.Count != 0 || parameters.SignedEncrypted.Count != 0 || parameters.Endorsing.Count != 1 || parameters.SignedEndorsing.Count != 0) return false; SspiSecurityTokenParameters sspiParameters = parameters.Endorsing[0] as SspiSecurityTokenParameters; if (sspiParameters == null) return false; if (sspiParameters.RequireDerivedKeys) return false; if (sspiParameters.RequireCancellation != requireCancellation) return false; if (!(sbe is TransportSecurityBindingElement)) return false; return true; } // If any changes are made to this method, please make sure that they are // reflected in the corresponding IsIssuedTokenOverTransportBinding() method. static public TransportSecurityBindingElement CreateIssuedTokenOverTransportBindingElement(IssuedSecurityTokenParameters issuedTokenParameters) { if (issuedTokenParameters == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("issuedTokenParameters"); issuedTokenParameters.RequireDerivedKeys = false; TransportSecurityBindingElement result = new TransportSecurityBindingElement(); if (issuedTokenParameters.KeyType == SecurityKeyType.BearerKey) { result.EndpointSupportingTokenParameters.Signed.Add(issuedTokenParameters); result.MessageSecurityVersion = MessageSecurityVersion.WSSXDefault; } else { result.EndpointSupportingTokenParameters.Endorsing.Add(issuedTokenParameters); result.MessageSecurityVersion = MessageSecurityVersion.Default; } result.LocalClientSettings.DetectReplays = false; result.LocalServiceSettings.DetectReplays = false; result.IncludeTimestamp = true; return result; } // this method reverses CreateIssuedTokenOverTransportBindingElement() logic internal static bool IsIssuedTokenOverTransportBinding(SecurityBindingElement sbe, out IssuedSecurityTokenParameters issuedTokenParameters) { issuedTokenParameters = null; if (!(sbe is TransportSecurityBindingElement)) return false; if (!sbe.IncludeTimestamp) return false; // do not check local settings: sbe.LocalServiceSettings and sbe.LocalClientSettings SupportingTokenParameters parameters = sbe.EndpointSupportingTokenParameters; if (parameters.SignedEncrypted.Count != 0 || (parameters.Signed.Count == 0 && parameters.Endorsing.Count == 0) || parameters.SignedEndorsing.Count != 0) return false; if ((parameters.Signed.Count == 1) && (parameters.Endorsing.Count == 0)) { issuedTokenParameters = parameters.Signed[0] as IssuedSecurityTokenParameters; if (issuedTokenParameters != null && issuedTokenParameters.KeyType != SecurityKeyType.BearerKey) return false; } else if ((parameters.Endorsing.Count == 1) && (parameters.Signed.Count == 0)) { issuedTokenParameters = parameters.Endorsing[0] as IssuedSecurityTokenParameters; if (issuedTokenParameters != null && (issuedTokenParameters.KeyType != SecurityKeyType.SymmetricKey && issuedTokenParameters.KeyType != SecurityKeyType.AsymmetricKey)) return false; } if (issuedTokenParameters == null) return false; if (issuedTokenParameters.RequireDerivedKeys) return false; return true; } // If any changes are made to this method, please make sure that they are // reflected in the corresponding IsSecureConversationBinding() method. static public SecurityBindingElement CreateSecureConversationBindingElement(SecurityBindingElement bootstrapSecurity) { return CreateSecureConversationBindingElement(bootstrapSecurity, SecureConversationSecurityTokenParameters.defaultRequireCancellation, null); } // this method reverses CreateSecureConversationBindingElement() logic internal static bool IsSecureConversationBinding(SecurityBindingElement sbe, out SecurityBindingElement bootstrapSecurity) { return IsSecureConversationBinding(sbe, SecureConversationSecurityTokenParameters.defaultRequireCancellation, out bootstrapSecurity); } static public SecurityBindingElement CreateSecureConversationBindingElement(SecurityBindingElement bootstrapSecurity, bool requireCancellation) { return CreateSecureConversationBindingElement(bootstrapSecurity, requireCancellation, null); } // If any changes are made to this method, please make sure that they are // reflected in the corresponding IsSecureConversationBinding() method. static public SecurityBindingElement CreateSecureConversationBindingElement(SecurityBindingElement bootstrapSecurity, bool requireCancellation, ChannelProtectionRequirements bootstrapProtectionRequirements) { if (bootstrapSecurity == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("bootstrapBinding"); SecurityBindingElement result; if (bootstrapSecurity is TransportSecurityBindingElement) { // there is no need to do replay detection or key derivation for transport bindings TransportSecurityBindingElement primary = new TransportSecurityBindingElement(); SecureConversationSecurityTokenParameters scParameters = new SecureConversationSecurityTokenParameters( bootstrapSecurity, requireCancellation, bootstrapProtectionRequirements); scParameters.RequireDerivedKeys = false; primary.EndpointSupportingTokenParameters.Endorsing.Add( scParameters); primary.LocalClientSettings.DetectReplays = false; primary.LocalServiceSettings.DetectReplays = false; primary.IncludeTimestamp = true; result = primary; } else // Symmetric- or AsymmetricSecurityBindingElement { SymmetricSecurityBindingElement primary = new SymmetricSecurityBindingElement( new SecureConversationSecurityTokenParameters( bootstrapSecurity, requireCancellation, bootstrapProtectionRequirements)); // there is no need for signature confirmation on the steady state binding primary.RequireSignatureConfirmation = false; result = primary; } return result; } // this method reverses CreateSecureConversationBindingElement() logic internal static bool IsSecureConversationBinding(SecurityBindingElement sbe, bool requireCancellation, out SecurityBindingElement bootstrapSecurity) { bootstrapSecurity = null; SymmetricSecurityBindingElement ssbe = sbe as SymmetricSecurityBindingElement; if (ssbe != null) { if (ssbe.RequireSignatureConfirmation) return false; SecureConversationSecurityTokenParameters parameters = ssbe.ProtectionTokenParameters as SecureConversationSecurityTokenParameters; if (parameters == null) return false; if (parameters.RequireCancellation != requireCancellation) return false; bootstrapSecurity = parameters.BootstrapSecurityBindingElement; } else { if (!sbe.IncludeTimestamp) return false; // do not check local settings: sbe.LocalServiceSettings and sbe.LocalClientSettings if (!(sbe is TransportSecurityBindingElement)) return false; SupportingTokenParameters parameters = sbe.EndpointSupportingTokenParameters; if (parameters.Signed.Count != 0 || parameters.SignedEncrypted.Count != 0 || parameters.Endorsing.Count != 1 || parameters.SignedEndorsing.Count != 0) return false; SecureConversationSecurityTokenParameters scParameters = parameters.Endorsing[0] as SecureConversationSecurityTokenParameters; if (scParameters == null) return false; if (scParameters.RequireCancellation != requireCancellation) return false; bootstrapSecurity = scParameters.BootstrapSecurityBindingElement; } if (bootstrapSecurity != null && bootstrapSecurity.SecurityHeaderLayout != SecurityProtocolFactory.defaultSecurityHeaderLayout) return false; return bootstrapSecurity != null; } public override string ToString() { StringBuilder sb = new StringBuilder(); sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "{0}:", this.GetType().ToString())); sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "DefaultAlgorithmSuite: {0}", this.defaultAlgorithmSuite.ToString())); sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "IncludeTimestamp: {0}", this.includeTimestamp.ToString())); sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "KeyEntropyMode: {0}", this.keyEntropyMode.ToString())); sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "MessageSecurityVersion: {0}", this.MessageSecurityVersion.ToString())); sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "SecurityHeaderLayout: {0}", this.securityHeaderLayout.ToString())); sb.AppendLine("EndpointSupportingTokenParameters:"); sb.AppendLine(" " + this.EndpointSupportingTokenParameters.ToString().Trim().Replace("\n", "\n ")); sb.AppendLine("OptionalEndpointSupportingTokenParameters:"); sb.AppendLine(" " + this.OptionalEndpointSupportingTokenParameters.ToString().Trim().Replace("\n", "\n ")); if (this.operationSupportingTokenParameters.Count == 0) { sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "OperationSupportingTokenParameters: none")); } else { foreach (string requestAction in this.OperationSupportingTokenParameters.Keys) { sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "OperationSupportingTokenParameters[\"{0}\"]:", requestAction)); sb.AppendLine(" " + this.OperationSupportingTokenParameters[requestAction].ToString().Trim().Replace("\n", "\n ")); } } if (this.optionalOperationSupportingTokenParameters.Count == 0) { sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "OptionalOperationSupportingTokenParameters: none")); } else { foreach (string requestAction in this.OptionalOperationSupportingTokenParameters.Keys) { sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "OptionalOperationSupportingTokenParameters[\"{0}\"]:", requestAction)); sb.AppendLine(" " + this.OptionalOperationSupportingTokenParameters[requestAction].ToString().Trim().Replace("\n", "\n ")); } } return sb.ToString().Trim(); } internal static ChannelProtectionRequirements ComputeProtectionRequirements(SecurityBindingElement security, BindingParameterCollection parameterCollection, BindingElementCollection bindingElements, bool isForService) { if (parameterCollection == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("parameterCollection"); if (bindingElements == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("bindingElements"); if (security == null) { return null; } ChannelProtectionRequirements result = null; if ((security is SymmetricSecurityBindingElement) || (security is AsymmetricSecurityBindingElement)) { result = new ChannelProtectionRequirements(); ChannelProtectionRequirements contractRequirements = parameterCollection.Find (); if (contractRequirements != null) result.Add(contractRequirements); AddBindingProtectionRequirements(result, bindingElements, !isForService); } return result; } static void AddBindingProtectionRequirements(ChannelProtectionRequirements requirements, BindingElementCollection bindingElements, bool isForChannel) { // Gather custom requirements from bindingElements CustomBinding binding = new CustomBinding(bindingElements); BindingContext context = new BindingContext(binding, new BindingParameterCollection()); // In theory, we can just do // context.GetInnerProperty () // but that relies on each binding element to correctly union-up its own requirements with // those of the rest of the stack. So instead, we ask each BE individually, and we do the // work of combining the results. This protects us against this scenario: someone authors "FooBE" // with a a GetProperty implementation that always returns null (oops), and puts FooBE on the // top of the stack, and so FooBE "hides" important protection requirements that inner BEs // require, resulting in an insecure binding. foreach (BindingElement bindingElement in bindingElements) { if (bindingElement != null) { // ask each element individually for its requirements context.RemainingBindingElements.Clear(); context.RemainingBindingElements.Add(bindingElement); ChannelProtectionRequirements s = context.GetInnerProperty (); if (s != null) { //if (isForChannel) //{ // requirements.Add(s.CreateInverse()); //} //else //{ requirements.Add(s); //} } } } } internal void ApplyAuditBehaviorSettings(BindingContext context, SecurityProtocolFactory factory) { ServiceSecurityAuditBehavior auditBehavior = context.BindingParameters.Find (); if (auditBehavior != null) { factory.AuditLogLocation = auditBehavior.AuditLogLocation; factory.SuppressAuditFailure = auditBehavior.SuppressAuditFailure; factory.ServiceAuthorizationAuditLevel = auditBehavior.ServiceAuthorizationAuditLevel; factory.MessageAuthenticationAuditLevel = auditBehavior.MessageAuthenticationAuditLevel; } else { factory.AuditLogLocation = ServiceSecurityAuditBehavior.defaultAuditLogLocation; factory.SuppressAuditFailure = ServiceSecurityAuditBehavior.defaultSuppressAuditFailure; factory.ServiceAuthorizationAuditLevel = ServiceSecurityAuditBehavior.defaultServiceAuthorizationAuditLevel; factory.MessageAuthenticationAuditLevel = ServiceSecurityAuditBehavior.defaultMessageAuthenticationAuditLevel; } } internal override bool IsMatch(BindingElement b) { if (b == null) return false; SecurityBindingElement security = b as SecurityBindingElement; if (security == null) return false; return SecurityElement.AreBindingsMatching(this, security); } static void AddAssertionIfNotNull(PolicyConversionContext policyContext, XmlElement assertion) { if (policyContext != null && assertion != null) { policyContext.GetBindingAssertions().Add(assertion); } } static void AddAssertionIfNotNull(PolicyConversionContext policyContext, Collection assertions) { if (policyContext != null && assertions != null) { PolicyAssertionCollection existingAssertions = policyContext.GetBindingAssertions(); for (int i = 0 ; i < assertions.Count; ++i) existingAssertions.Add(assertions[i]); } } static void AddAssertionIfNotNull(PolicyConversionContext policyContext, OperationDescription operation, XmlElement assertion) { if (policyContext != null && assertion != null) { policyContext.GetOperationBindingAssertions(operation).Add(assertion); } } static void AddAssertionIfNotNull(PolicyConversionContext policyContext, OperationDescription operation, Collection assertions) { if (policyContext != null && assertions != null) { PolicyAssertionCollection existingAssertions = policyContext.GetOperationBindingAssertions(operation); for (int i = 0; i < assertions.Count; ++i) existingAssertions.Add(assertions[i]); } } static void AddAssertionIfNotNull(PolicyConversionContext policyContext, MessageDescription message, XmlElement assertion) { if (policyContext != null && assertion != null) { policyContext.GetMessageBindingAssertions(message).Add(assertion); } } static void AddAssertionIfNotNull(PolicyConversionContext policyContext, FaultDescription message, XmlElement assertion) { if (policyContext != null && assertion != null) { policyContext.GetFaultBindingAssertions(message).Add(assertion); } } internal static void ExportPolicy(MetadataExporter exporter, PolicyConversionContext context) { if (exporter == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("exporter"); } if (context == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context"); } SecurityTraceRecordHelper.TraceExportChannelBindingEntry(); SecurityBindingElement binding = null; ITransportTokenAssertionProvider transportTokenAssertionProvider = null; BindingElementCollection bindingElementsBelowSecurity = new BindingElementCollection(); if ((context != null) && (context.BindingElements != null)) { foreach (BindingElement be in context.BindingElements) { if (be is SecurityBindingElement) { binding = (SecurityBindingElement)be; } else { if (binding != null || be is MessageEncodingBindingElement || be is ITransportTokenAssertionProvider) { bindingElementsBelowSecurity.Add(be); } if (be is ITransportTokenAssertionProvider) { transportTokenAssertionProvider = (ITransportTokenAssertionProvider)be; } } } } // this is used when exporting bootstrap policy for secure conversation in SecurityPolicy11.CreateWsspBootstrapPolicyAssertion exporter.State[SecurityPolicyStrings.SecureConversationBootstrapBindingElementsBelowSecurityKey] = bindingElementsBelowSecurity; bool hasCompletedSuccessfuly = false; try { if (binding is SymmetricSecurityBindingElement) { if (transportTokenAssertionProvider != null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ExportOfBindingWithSymmetricAndTransportSecurityNotSupported))); } ExportSymmetricSecurityBindingElement((SymmetricSecurityBindingElement)binding, exporter, context); ExportOperationScopeSupportingTokensPolicy(binding, exporter, context); ExportMessageScopeProtectionPolicy(binding, exporter, context); } else if (binding is AsymmetricSecurityBindingElement) { if (transportTokenAssertionProvider != null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ExportOfBindingWithAsymmetricAndTransportSecurityNotSupported))); } ExportAsymmetricSecurityBindingElement((AsymmetricSecurityBindingElement)binding, exporter, context); ExportOperationScopeSupportingTokensPolicy(binding, exporter, context); ExportMessageScopeProtectionPolicy(binding, exporter, context); } else if (binding is TransportSecurityBindingElement) { if (transportTokenAssertionProvider == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ExportOfBindingWithTransportSecurityBindingElementAndNoTransportSecurityNotSupported))); } ExportTransportSecurityBindingElement((TransportSecurityBindingElement)binding, transportTokenAssertionProvider, exporter, context); ExportOperationScopeSupportingTokensPolicy(binding, exporter, context); } else if (binding == null && transportTokenAssertionProvider != null) { TransportSecurityBindingElement dummyTransportBindingElement = new TransportSecurityBindingElement(); dummyTransportBindingElement.IncludeTimestamp = false; // In order to generate the right sp assertion without SBE. // scenario: WSxHttpBinding with SecurityMode.Transport. // See CSD 3105 for detail HttpsTransportBindingElement httpsBinding = transportTokenAssertionProvider as HttpsTransportBindingElement; if (httpsBinding != null && httpsBinding.MessageSecurityVersion != null) { dummyTransportBindingElement.MessageSecurityVersion = httpsBinding.MessageSecurityVersion; } ExportTransportSecurityBindingElement(dummyTransportBindingElement, transportTokenAssertionProvider, exporter, context); } hasCompletedSuccessfuly = true; } finally { try { exporter.State.Remove(SecurityPolicyStrings.SecureConversationBootstrapBindingElementsBelowSecurityKey); } catch (Exception e) { // Always immediately rethrow fatal exceptions. if (hasCompletedSuccessfuly || DiagnosticUtility.IsFatal(e)) throw; } } } // // We will emit the wssp trust 10 assertion for all the case except for the basic http binding // created through the BasicHttpBinding class. The reason for this exception is to allow better // interop with third party when the third party doesn't understand the trust asserion // static bool RequiresWsspTrust(SecurityBindingElement sbe) { if (sbe == null) return false; return !(sbe.doNotEmitTrust); } static void ExportAsymmetricSecurityBindingElement(AsymmetricSecurityBindingElement binding, MetadataExporter exporter, PolicyConversionContext policyContext) { WSSecurityPolicy sp = WSSecurityPolicy.GetSecurityPolicyDriver(binding.MessageSecurityVersion); AddAssertionIfNotNull(policyContext, sp.CreateWsspAsymmetricBindingAssertion(exporter, policyContext, binding)); AddAssertionIfNotNull(policyContext, sp.CreateWsspSupportingTokensAssertion( exporter, binding.EndpointSupportingTokenParameters.Signed, binding.EndpointSupportingTokenParameters.SignedEncrypted, binding.EndpointSupportingTokenParameters.Endorsing, binding.EndpointSupportingTokenParameters.SignedEndorsing, binding.OptionalEndpointSupportingTokenParameters.Signed, binding.OptionalEndpointSupportingTokenParameters.SignedEncrypted, binding.OptionalEndpointSupportingTokenParameters.Endorsing, binding.OptionalEndpointSupportingTokenParameters.SignedEndorsing)); AddAssertionIfNotNull(policyContext, sp.CreateWsspWssAssertion(exporter, binding)); if (RequiresWsspTrust(binding)) { AddAssertionIfNotNull(policyContext, sp.CreateWsspTrustAssertion(exporter, binding.KeyEntropyMode)); } } static void ExportTransportSecurityBindingElement(TransportSecurityBindingElement binding, ITransportTokenAssertionProvider transportTokenAssertionProvider, MetadataExporter exporter, PolicyConversionContext policyContext) { WSSecurityPolicy sp = WSSecurityPolicy.GetSecurityPolicyDriver(binding.MessageSecurityVersion); XmlElement transportTokenAssertion = transportTokenAssertionProvider.GetTransportTokenAssertion(); if (transportTokenAssertion == null) { if (transportTokenAssertionProvider is HttpsTransportBindingElement) { transportTokenAssertion = sp.CreateWsspHttpsTokenAssertion(exporter, (HttpsTransportBindingElement)transportTokenAssertionProvider); } if (transportTokenAssertion == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.NoTransportTokenAssertionProvided, transportTokenAssertionProvider.GetType().ToString()))); } AddressingVersion addressingVersion = AddressingVersion.WSAddressing10; MessageEncodingBindingElement messageEncoderBindingElement = policyContext.BindingElements.Find (); if (messageEncoderBindingElement != null) { addressingVersion = messageEncoderBindingElement.MessageVersion.Addressing; } AddAssertionIfNotNull(policyContext, sp.CreateWsspTransportBindingAssertion(exporter, binding, transportTokenAssertion)); Collection supportingTokenAssertions = sp.CreateWsspSupportingTokensAssertion( exporter, binding.EndpointSupportingTokenParameters.Signed, binding.EndpointSupportingTokenParameters.SignedEncrypted, binding.EndpointSupportingTokenParameters.Endorsing, binding.EndpointSupportingTokenParameters.SignedEndorsing, binding.OptionalEndpointSupportingTokenParameters.Signed, binding.OptionalEndpointSupportingTokenParameters.SignedEncrypted, binding.OptionalEndpointSupportingTokenParameters.Endorsing, binding.OptionalEndpointSupportingTokenParameters.SignedEndorsing, addressingVersion); AddAssertionIfNotNull(policyContext, supportingTokenAssertions); if (supportingTokenAssertions.Count > 0 || HasEndorsingSupportingTokensAtOperationScope(binding)) { AddAssertionIfNotNull(policyContext, sp.CreateWsspWssAssertion(exporter, binding)); if (RequiresWsspTrust(binding)) { AddAssertionIfNotNull(policyContext, sp.CreateWsspTrustAssertion(exporter, binding.KeyEntropyMode)); } } } static bool HasEndorsingSupportingTokensAtOperationScope(SecurityBindingElement binding) { foreach (SupportingTokenParameters r in binding.OperationSupportingTokenParameters.Values) { if (r.Endorsing.Count > 0 || r.SignedEndorsing.Count > 0) { return true; } } return false; } static void ExportSymmetricSecurityBindingElement(SymmetricSecurityBindingElement binding, MetadataExporter exporter, PolicyConversionContext policyContext) { WSSecurityPolicy sp = WSSecurityPolicy.GetSecurityPolicyDriver(binding.MessageSecurityVersion); AddAssertionIfNotNull(policyContext, sp.CreateWsspSymmetricBindingAssertion(exporter, policyContext, binding)); AddAssertionIfNotNull(policyContext, sp.CreateWsspSupportingTokensAssertion( exporter, binding.EndpointSupportingTokenParameters.Signed, binding.EndpointSupportingTokenParameters.SignedEncrypted, binding.EndpointSupportingTokenParameters.Endorsing, binding.EndpointSupportingTokenParameters.SignedEndorsing, binding.OptionalEndpointSupportingTokenParameters.Signed, binding.OptionalEndpointSupportingTokenParameters.SignedEncrypted, binding.OptionalEndpointSupportingTokenParameters.Endorsing, binding.OptionalEndpointSupportingTokenParameters.SignedEndorsing)); AddAssertionIfNotNull(policyContext, sp.CreateWsspWssAssertion(exporter, binding)); if (RequiresWsspTrust(binding)) { AddAssertionIfNotNull(policyContext, sp.CreateWsspTrustAssertion(exporter, binding.KeyEntropyMode)); } } static void ExportMessageScopeProtectionPolicy(SecurityBindingElement security, MetadataExporter exporter, PolicyConversionContext policyContext) { BindingParameterCollection bindingParameters = new BindingParameterCollection(); bindingParameters.Add(ChannelProtectionRequirements.CreateFromContract(policyContext.Contract, policyContext.BindingElements.Find ().GetIndividualProperty (), false)); ChannelProtectionRequirements protectionRequirements = SecurityBindingElement.ComputeProtectionRequirements(security, bindingParameters, policyContext.BindingElements, true); protectionRequirements.MakeReadOnly(); WSSecurityPolicy sp = WSSecurityPolicy.GetSecurityPolicyDriver(security.MessageSecurityVersion); foreach (OperationDescription operation in policyContext.Contract.Operations) { // export policy for application messages foreach (MessageDescription message in operation.Messages) { MessagePartSpecification parts; ScopedMessagePartSpecification scopedParts; // integrity if (message.Direction == MessageDirection.Input) { scopedParts = protectionRequirements.IncomingSignatureParts; } else { scopedParts = protectionRequirements.OutgoingSignatureParts; } if (scopedParts.TryGetParts(message.Action, out parts)) { AddAssertionIfNotNull(policyContext, message, sp.CreateWsspSignedPartsAssertion(parts)); } // confidentiality if (message.Direction == MessageDirection.Input) { scopedParts = protectionRequirements.IncomingEncryptionParts; } else { scopedParts = protectionRequirements.OutgoingEncryptionParts; } if (scopedParts.TryGetParts(message.Action, out parts)) { AddAssertionIfNotNull(policyContext, message, sp.CreateWsspEncryptedPartsAssertion(parts)); } } // export policy for faults foreach (FaultDescription fault in operation.Faults) { MessagePartSpecification parts; // integrity if (protectionRequirements.OutgoingSignatureParts.TryGetParts(fault.Action, out parts)) { AddAssertionIfNotNull(policyContext, fault, sp.CreateWsspSignedPartsAssertion(parts)); } // confidentiality if (protectionRequirements.OutgoingEncryptionParts.TryGetParts(fault.Action, out parts)) { AddAssertionIfNotNull(policyContext, fault, sp.CreateWsspEncryptedPartsAssertion(parts)); } } } } static void ExportOperationScopeSupportingTokensPolicy(SecurityBindingElement binding, MetadataExporter exporter, PolicyConversionContext policyContext) { WSSecurityPolicy sp = WSSecurityPolicy.GetSecurityPolicyDriver(binding.MessageSecurityVersion); if (binding.OperationSupportingTokenParameters.Count == 0 && binding.OptionalOperationSupportingTokenParameters.Count == 0) { return; } foreach (OperationDescription operation in policyContext.Contract.Operations) { foreach (MessageDescription message in operation.Messages) { if (message.Direction == MessageDirection.Input) { SupportingTokenParameters requirements = null; SupportingTokenParameters optionalRequirements = null; if (binding.OperationSupportingTokenParameters.ContainsKey(message.Action)) { requirements = binding.OperationSupportingTokenParameters[message.Action]; } if (binding.OptionalOperationSupportingTokenParameters.ContainsKey(message.Action)) { optionalRequirements = binding.OptionalOperationSupportingTokenParameters[message.Action]; } if (requirements == null && optionalRequirements == null) { continue; } AddAssertionIfNotNull(policyContext, operation, sp.CreateWsspSupportingTokensAssertion( exporter, requirements == null ? null : requirements.Signed, requirements == null ? null : requirements.SignedEncrypted, requirements == null ? null : requirements.Endorsing, requirements == null ? null : requirements.SignedEndorsing, optionalRequirements == null ? null : optionalRequirements.Signed, optionalRequirements == null ? null : optionalRequirements.SignedEncrypted, optionalRequirements == null ? null : optionalRequirements.Endorsing, optionalRequirements == null ? null : optionalRequirements.SignedEndorsing)); } } } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ImageDrawing.cs
- FunctionImportElement.cs
- EventLogConfiguration.cs
- SafeNativeMemoryHandle.cs
- HttpClientChannel.cs
- HttpPostClientProtocol.cs
- VisualSerializer.cs
- FontUnitConverter.cs
- WindowsSlider.cs
- TypeElement.cs
- ReferenceEqualityComparer.cs
- XamlTemplateSerializer.cs
- MatrixIndependentAnimationStorage.cs
- RoutedUICommand.cs
- HitTestParameters.cs
- IIS7UserPrincipal.cs
- UnmanagedHandle.cs
- TextPointer.cs
- WebServicesSection.cs
- HttpWebRequestElement.cs
- LocalBuilder.cs
- Sql8ConformanceChecker.cs
- TargetConverter.cs
- FixedStringLookup.cs
- EntityStoreSchemaFilterEntry.cs
- SelectionService.cs
- ConnectionOrientedTransportElement.cs
- HttpModulesSection.cs
- ScriptingWebServicesSectionGroup.cs
- GridViewRowPresenter.cs
- StaticContext.cs
- XPathItem.cs
- EntityDataSourceMemberPath.cs
- CssClassPropertyAttribute.cs
- TextCharacters.cs
- MarkupProperty.cs
- HtmlControlPersistable.cs
- WorkflowRuntimeSection.cs
- IgnoreSectionHandler.cs
- MembershipAdapter.cs
- XamlBrushSerializer.cs
- InlineCollection.cs
- Zone.cs
- SessionSwitchEventArgs.cs
- MessageDecoder.cs
- RectValueSerializer.cs
- TraceListeners.cs
- StateDesigner.Helpers.cs
- MobileTemplatedControlDesigner.cs
- WsatEtwTraceListener.cs
- RegexFCD.cs
- UniqueIdentifierService.cs
- DateTimeParse.cs
- unsafenativemethodstextservices.cs
- CellNormalizer.cs
- StreamInfo.cs
- MessageQueueAccessControlEntry.cs
- ClientBuildManager.cs
- LineInfo.cs
- CircleHotSpot.cs
- DataServiceKeyAttribute.cs
- ElementHost.cs
- ResourceDictionary.cs
- SqlFacetAttribute.cs
- HttpCachePolicyElement.cs
- RegistrySecurity.cs
- ToolStripOverflowButton.cs
- HtmlTernaryTree.cs
- HttpRuntimeSection.cs
- ConnectAlgorithms.cs
- DateTimeValueSerializer.cs
- CodeExpressionStatement.cs
- UnsafeNativeMethods.cs
- ConfigXmlAttribute.cs
- XpsFilter.cs
- SafeRegistryHandle.cs
- LicenseProviderAttribute.cs
- TaiwanCalendar.cs
- ColumnWidthChangingEvent.cs
- ChannelBinding.cs
- MenuItem.cs
- WindowsGraphicsCacheManager.cs
- ConfigurationManager.cs
- XhtmlBasicTextViewAdapter.cs
- ElementNotAvailableException.cs
- AccessDataSourceView.cs
- EntityClientCacheEntry.cs
- PersistenceProviderFactory.cs
- DataSourceHelper.cs
- OpCopier.cs
- BitmapEffectCollection.cs
- ProcessExitedException.cs
- X509Utils.cs
- SegmentInfo.cs
- DetailsViewDeletedEventArgs.cs
- SafeHandle.cs
- Menu.cs
- ReaderOutput.cs
- Vector3DCollection.cs
- TabControlAutomationPeer.cs