You've already forked linux-packaging-mono
2447 lines
118 KiB
C#
2447 lines
118 KiB
C#
![]() |
//-----------------------------------------------------------------------------
|
||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
namespace System.ServiceModel.Channels
|
||
|
{
|
||
|
using System;
|
||
|
using System.Diagnostics;
|
||
|
using System.Collections.Generic;
|
||
|
using System.Collections.ObjectModel;
|
||
|
using System.Globalization;
|
||
|
using System.IdentityModel.Selectors;
|
||
|
using System.IdentityModel.Tokens;
|
||
|
using System.Net.Security;
|
||
|
using System.Runtime;
|
||
|
using System.Security.Authentication.ExtendedProtection;
|
||
|
using System.ServiceModel;
|
||
|
using System.ServiceModel.Configuration;
|
||
|
using System.ServiceModel.Diagnostics;
|
||
|
using System.ServiceModel.Description;
|
||
|
using System.ServiceModel.Security;
|
||
|
using System.ServiceModel.Security.Tokens;
|
||
|
using System.Text;
|
||
|
using System.Xml;
|
||
|
|
||
|
public abstract class SecurityBindingElement : BindingElement
|
||
|
{
|
||
|
internal const string defaultAlgorithmSuiteString = ConfigurationStrings.Default;
|
||
|
internal static readonly SecurityAlgorithmSuite defaultDefaultAlgorithmSuite = SecurityAlgorithmSuite.Default;
|
||
|
internal const bool defaultIncludeTimestamp = true;
|
||
|
internal const bool defaultAllowInsecureTransport = false;
|
||
|
internal const MessageProtectionOrder defaultMessageProtectionOrder = MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature;
|
||
|
internal const bool defaultRequireSignatureConfirmation = false;
|
||
|
internal const bool defaultEnableUnsecuredResponse = false;
|
||
|
internal const bool defaultProtectTokens = false;
|
||
|
|
||
|
SecurityAlgorithmSuite defaultAlgorithmSuite;
|
||
|
SupportingTokenParameters endpointSupportingTokenParameters;
|
||
|
SupportingTokenParameters optionalEndpointSupportingTokenParameters;
|
||
|
bool includeTimestamp;
|
||
|
SecurityKeyEntropyMode keyEntropyMode;
|
||
|
Dictionary<string, SupportingTokenParameters> operationSupportingTokenParameters;
|
||
|
Dictionary<string, SupportingTokenParameters> 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
|
||
|
bool supportsExtendedProtectionPolicy;
|
||
|
bool allowInsecureTransport;
|
||
|
bool enableUnsecuredResponse;
|
||
|
bool protectTokens = defaultProtectTokens;
|
||
|
|
||
|
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<string, SupportingTokenParameters>();
|
||
|
this.optionalOperationSupportingTokenParameters = new Dictionary<string, SupportingTokenParameters>();
|
||
|
this.securityHeaderLayout = SecurityProtocolFactory.defaultSecurityHeaderLayout;
|
||
|
this.allowInsecureTransport = defaultAllowInsecureTransport;
|
||
|
this.enableUnsecuredResponse = defaultEnableUnsecuredResponse;
|
||
|
this.protectTokens = defaultProtectTokens;
|
||
|
}
|
||
|
|
||
|
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<string, SupportingTokenParameters>();
|
||
|
foreach (string key in elementToBeCloned.operationSupportingTokenParameters.Keys)
|
||
|
{
|
||
|
this.operationSupportingTokenParameters[key] = (SupportingTokenParameters)elementToBeCloned.operationSupportingTokenParameters[key].Clone();
|
||
|
}
|
||
|
this.optionalOperationSupportingTokenParameters = new Dictionary<string, SupportingTokenParameters>();
|
||
|
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;
|
||
|
this.allowInsecureTransport = elementToBeCloned.allowInsecureTransport;
|
||
|
this.enableUnsecuredResponse = elementToBeCloned.enableUnsecuredResponse;
|
||
|
this.supportsExtendedProtectionPolicy = elementToBeCloned.supportsExtendedProtectionPolicy;
|
||
|
this.protectTokens = elementToBeCloned.protectTokens;
|
||
|
}
|
||
|
|
||
|
internal bool SupportsExtendedProtectionPolicy
|
||
|
{
|
||
|
get { return this.supportsExtendedProtectionPolicy; }
|
||
|
set { this.supportsExtendedProtectionPolicy = value; }
|
||
|
}
|
||
|
|
||
|
public SupportingTokenParameters EndpointSupportingTokenParameters
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return this.endpointSupportingTokenParameters;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public SupportingTokenParameters OptionalEndpointSupportingTokenParameters
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return this.optionalEndpointSupportingTokenParameters;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
public IDictionary<string, SupportingTokenParameters> OperationSupportingTokenParameters
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return this.operationSupportingTokenParameters;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public IDictionary<string, SupportingTokenParameters> 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 EnableUnsecuredResponse
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return this.enableUnsecuredResponse;
|
||
|
}
|
||
|
set
|
||
|
{
|
||
|
this.enableUnsecuredResponse = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public bool IncludeTimestamp
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return this.includeTimestamp;
|
||
|
}
|
||
|
set
|
||
|
{
|
||
|
this.includeTimestamp = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public bool AllowInsecureTransport
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return this.allowInsecureTransport;
|
||
|
}
|
||
|
set
|
||
|
{
|
||
|
this.allowInsecureTransport = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public SecurityAlgorithmSuite DefaultAlgorithmSuite
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return this.defaultAlgorithmSuite;
|
||
|
}
|
||
|
set
|
||
|
{
|
||
|
if (value == null)
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("value"));
|
||
|
this.defaultAlgorithmSuite = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public bool ProtectTokens
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return this.protectTokens;
|
||
|
}
|
||
|
set
|
||
|
{
|
||
|
this.protectTokens = 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<SecurityTokenParameters> 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 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);
|
||
|
demuxer.MaxPendingSessions = this.LocalServiceSettings.MaxPendingSessions;
|
||
|
demuxer.PeekTimeout = this.LocalServiceSettings.NegotiationTimeout;
|
||
|
|
||
|
builder.Binding.Elements.Insert(0, demuxer);
|
||
|
secureConversationBindingContext.RemainingBindingElements.Insert(0, demuxer);
|
||
|
}
|
||
|
|
||
|
internal void ApplyPropertiesOnDemuxer(ChannelBuilder builder, BindingContext context)
|
||
|
{
|
||
|
Collection<ChannelDemuxerBindingElement> demuxerElements = builder.Binding.Elements.FindAll<ChannelDemuxerBindingElement>();
|
||
|
foreach (ChannelDemuxerBindingElement element in demuxerElements)
|
||
|
{
|
||
|
if (element != null)
|
||
|
{
|
||
|
element.MaxPendingSessions = this.LocalServiceSettings.MaxPendingSessions;
|
||
|
element.PeekTimeout = this.LocalServiceSettings.NegotiationTimeout;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static BindingContext CreateIssuerBindingContextForNegotiation(BindingContext issuerBindingContext)
|
||
|
{
|
||
|
TransportBindingElement transport = issuerBindingContext.RemainingBindingElements.Find<TransportBindingElement>();
|
||
|
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<TChannel>(BindingContext context)
|
||
|
{
|
||
|
return ((typeof(TChannel) == typeof(IDuplexSessionChannel)) && context.CanBuildInnerChannelListener<IDuplexChannel>()
|
||
|
&& !context.CanBuildInnerChannelListener<IDuplexSessionChannel>());
|
||
|
}
|
||
|
|
||
|
void SetPrivacyNoticeUriIfRequired(SecurityProtocolFactory factory, Binding binding)
|
||
|
{
|
||
|
PrivacyNoticeBindingElement privacyElement = binding.CreateBindingElements().Find<PrivacyNoticeBindingElement>();
|
||
|
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;
|
||
|
|
||
|
if (this.LocalClientSettings.DetectReplays)
|
||
|
{
|
||
|
factory.NonceCache = this.LocalClientSettings.NonceCache;
|
||
|
}
|
||
|
}
|
||
|
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;
|
||
|
|
||
|
if (this.LocalServiceSettings.DetectReplays)
|
||
|
{
|
||
|
factory.NonceCache = this.LocalServiceSettings.NonceCache;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
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<TChannel>(BindingContext context, SecurityCredentialsManager credentialsManager,
|
||
|
bool isForService, BindingContext issuanceBindingContext);
|
||
|
|
||
|
public override IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context)
|
||
|
{
|
||
|
if (context == null)
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
|
||
|
|
||
|
if (!this.CanBuildChannelFactory<TChannel>(context))
|
||
|
{
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.ChannelTypeNotSupported, typeof(TChannel)), "TChannel"));
|
||
|
}
|
||
|
|
||
|
this.readerQuotas = context.GetInnerProperty<XmlDictionaryReaderQuotas>();
|
||
|
if (readerQuotas == null)
|
||
|
{
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.EncodingBindingElementDoesNotHandleReaderQuotas)));
|
||
|
}
|
||
|
|
||
|
TransportBindingElement transportBindingElement = null;
|
||
|
|
||
|
if (context.RemainingBindingElements != null)
|
||
|
transportBindingElement = context.RemainingBindingElements.Find<TransportBindingElement>();
|
||
|
|
||
|
if (transportBindingElement != null)
|
||
|
this.maxReceivedMessageSize = transportBindingElement.MaxReceivedMessageSize;
|
||
|
|
||
|
IChannelFactory<TChannel> result = this.BuildChannelFactoryCore<TChannel>(context);
|
||
|
|
||
|
// attach the ExtendedProtectionPolicy to the securityProtcolFactory so it will be
|
||
|
// available when building the channel.
|
||
|
if (transportBindingElement != null)
|
||
|
{
|
||
|
SecurityChannelFactory<TChannel> scf = result as SecurityChannelFactory<TChannel>;
|
||
|
if (scf != null && scf.SecurityProtocolFactory != null)
|
||
|
{
|
||
|
scf.SecurityProtocolFactory.ExtendedProtectionPolicy = transportBindingElement.GetProperty<ExtendedProtectionPolicy>(context);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
|
||
|
}
|
||
|
|
||
|
protected abstract IChannelFactory<TChannel> BuildChannelFactoryCore<TChannel>(BindingContext context);
|
||
|
|
||
|
public override bool CanBuildChannelFactory<TChannel>(BindingContext context)
|
||
|
{
|
||
|
if (context == null)
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
|
||
|
|
||
|
InternalDuplexBindingElement.AddDuplexFactorySupport(context, ref this.internalDuplexBindingElement);
|
||
|
|
||
|
if (this.SessionMode)
|
||
|
{
|
||
|
return this.CanBuildSessionChannelFactory<TChannel>(context);
|
||
|
}
|
||
|
|
||
|
if (!context.CanBuildInnerChannelFactory<TChannel>())
|
||
|
{
|
||
|
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<TChannel>(BindingContext context)
|
||
|
{
|
||
|
if (!(context.CanBuildInnerChannelFactory<IRequestChannel>()
|
||
|
|| context.CanBuildInnerChannelFactory<IRequestSessionChannel>()
|
||
|
|| context.CanBuildInnerChannelFactory<IDuplexChannel>()
|
||
|
|| context.CanBuildInnerChannelFactory<IDuplexSessionChannel>()))
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if (typeof(TChannel) == typeof(IRequestSessionChannel))
|
||
|
{
|
||
|
return (context.CanBuildInnerChannelFactory<IRequestChannel>() || context.CanBuildInnerChannelFactory<IRequestSessionChannel>());
|
||
|
}
|
||
|
else if (typeof(TChannel) == typeof(IDuplexSessionChannel))
|
||
|
{
|
||
|
return (context.CanBuildInnerChannelFactory<IDuplexChannel>() || context.CanBuildInnerChannelFactory<IDuplexSessionChannel>());
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public override IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context)
|
||
|
{
|
||
|
if (context == null)
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
|
||
|
|
||
|
if (!this.CanBuildChannelListener<TChannel>(context))
|
||
|
{
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.ChannelTypeNotSupported, typeof(TChannel)), "TChannel"));
|
||
|
}
|
||
|
|
||
|
this.readerQuotas = context.GetInnerProperty<XmlDictionaryReaderQuotas>();
|
||
|
if (readerQuotas == null)
|
||
|
{
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.EncodingBindingElementDoesNotHandleReaderQuotas)));
|
||
|
}
|
||
|
|
||
|
TransportBindingElement transportBindingElement = null;
|
||
|
if (context.RemainingBindingElements != null)
|
||
|
transportBindingElement = context.RemainingBindingElements.Find<TransportBindingElement>();
|
||
|
|
||
|
if (transportBindingElement != null)
|
||
|
this.maxReceivedMessageSize = transportBindingElement.MaxReceivedMessageSize;
|
||
|
|
||
|
return this.BuildChannelListenerCore<TChannel>(context);
|
||
|
}
|
||
|
|
||
|
protected abstract IChannelListener<TChannel> BuildChannelListenerCore<TChannel>(BindingContext context)
|
||
|
where TChannel : class, IChannel;
|
||
|
|
||
|
public override bool CanBuildChannelListener<TChannel>(BindingContext context)
|
||
|
{
|
||
|
if (context == null)
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
|
||
|
|
||
|
InternalDuplexBindingElement.AddDuplexListenerSupport(context, ref this.internalDuplexBindingElement);
|
||
|
|
||
|
if (this.SessionMode)
|
||
|
{
|
||
|
return this.CanBuildSessionChannelListener<TChannel>(context);
|
||
|
}
|
||
|
|
||
|
if (!context.CanBuildInnerChannelListener<TChannel>())
|
||
|
{
|
||
|
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<TChannel>(BindingContext context)
|
||
|
where TChannel : class, IChannel
|
||
|
{
|
||
|
if (!(context.CanBuildInnerChannelListener<IReplyChannel>()
|
||
|
|| context.CanBuildInnerChannelListener<IReplySessionChannel>()
|
||
|
|| context.CanBuildInnerChannelListener<IDuplexChannel>()
|
||
|
|| context.CanBuildInnerChannelListener<IDuplexSessionChannel>()))
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if (typeof(TChannel) == typeof(IReplySessionChannel))
|
||
|
{
|
||
|
return (context.CanBuildInnerChannelListener<IReplyChannel>() || context.CanBuildInnerChannelListener<IReplySessionChannel>());
|
||
|
}
|
||
|
else if (typeof(TChannel) == typeof(IDuplexSessionChannel))
|
||
|
{
|
||
|
return (context.CanBuildInnerChannelListener<IDuplexChannel>() || context.CanBuildInnerChannelListener<IDuplexSessionChannel>());
|
||
|
}
|
||
|
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<ISecurityCapabilities>().SupportedRequestProtectionLevel;
|
||
|
ProtectionLevel supportedResponseProtectionLevel = this.GetIndividualProperty<ISecurityCapabilities>().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<T>(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<T>();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal abstract ISecurityCapabilities GetIndividualISecurityCapabilities();
|
||
|
|
||
|
ISecurityCapabilities GetSecurityCapabilities(BindingContext context)
|
||
|
{
|
||
|
ISecurityCapabilities thisSecurityCapability = this.GetIndividualISecurityCapabilities();
|
||
|
ISecurityCapabilities lowerSecurityCapability = context.GetInnerProperty<ISecurityCapabilities>();
|
||
|
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;
|
||
|
result.SupportsExtendedProtectionPolicy = true;
|
||
|
|
||
|
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;
|
||
|
result.SupportsExtendedProtectionPolicy = true;
|
||
|
|
||
|
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(String.Format(CultureInfo.InvariantCulture, "ProtectTokens: {0}", this.protectTokens.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<ChannelProtectionRequirements>();
|
||
|
|
||
|
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<ChannelProtectionRequirements>()
|
||
|
// 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<ChannelProtectionRequirements>();
|
||
|
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<ServiceSecurityAuditBehavior>();
|
||
|
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<XmlElement> 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<XmlElement> 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 hasCompletedSuccessfully = false;
|
||
|
try
|
||
|
{
|
||
|
if (binding is SymmetricSecurityBindingElement)
|
||
|
{
|
||
|
ExportSymmetricSecurityBindingElement((SymmetricSecurityBindingElement)binding, exporter, context);
|
||
|
ExportOperationScopeSupportingTokensPolicy(binding, exporter, context);
|
||
|
ExportMessageScopeProtectionPolicy(binding, exporter, context);
|
||
|
}
|
||
|
else if (binding is AsymmetricSecurityBindingElement)
|
||
|
{
|
||
|
ExportAsymmetricSecurityBindingElement((AsymmetricSecurityBindingElement)binding, exporter, context);
|
||
|
ExportOperationScopeSupportingTokensPolicy(binding, exporter, context);
|
||
|
ExportMessageScopeProtectionPolicy(binding, exporter, context);
|
||
|
}
|
||
|
|
||
|
hasCompletedSuccessfully = true;
|
||
|
}
|
||
|
finally
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
exporter.State.Remove(SecurityPolicyStrings.SecureConversationBootstrapBindingElementsBelowSecurityKey);
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
// Always immediately rethrow fatal exceptions.
|
||
|
if (hasCompletedSuccessfully || Fx.IsFatal(e)) throw;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal static void ExportPolicyForTransportTokenAssertionProviders(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 hasCompletedSuccessfully = false;
|
||
|
try
|
||
|
{
|
||
|
if (binding is TransportSecurityBindingElement)
|
||
|
{
|
||
|
if (transportTokenAssertionProvider == null && !binding.AllowInsecureTransport)
|
||
|
{
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ExportOfBindingWithTransportSecurityBindingElementAndNoTransportSecurityNotSupported)));
|
||
|
}
|
||
|
|
||
|
ExportTransportSecurityBindingElement((TransportSecurityBindingElement)binding, transportTokenAssertionProvider, exporter, context);
|
||
|
ExportOperationScopeSupportingTokensPolicy(binding, exporter, context);
|
||
|
}
|
||
|
else if (transportTokenAssertionProvider != null)
|
||
|
{
|
||
|
TransportSecurityBindingElement dummyTransportBindingElement = new TransportSecurityBindingElement();
|
||
|
if (binding == null)
|
||
|
{
|
||
|
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);
|
||
|
}
|
||
|
|
||
|
hasCompletedSuccessfully = true;
|
||
|
}
|
||
|
finally
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
exporter.State.Remove(SecurityPolicyStrings.SecureConversationBootstrapBindingElementsBelowSecurityKey);
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
// Always immediately rethrow fatal exceptions.
|
||
|
if (hasCompletedSuccessfully || Fx.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 ----erion
|
||
|
//
|
||
|
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);
|
||
|
|
||
|
if (transportTokenAssertionProvider == null && binding.AllowInsecureTransport)
|
||
|
{
|
||
|
if ((policyContext != null) && (policyContext.BindingElements != null))
|
||
|
{
|
||
|
foreach (BindingElement be in policyContext.BindingElements)
|
||
|
{
|
||
|
if (be is HttpTransportBindingElement)
|
||
|
{
|
||
|
transportTokenAssertionProvider = new HttpsTransportBindingElement();
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (be is TcpTransportBindingElement)
|
||
|
{
|
||
|
transportTokenAssertionProvider = new SslStreamSecurityBindingElement();
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
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<MessageEncodingBindingElement>();
|
||
|
if (messageEncoderBindingElement != null)
|
||
|
{
|
||
|
addressingVersion = messageEncoderBindingElement.MessageVersion.Addressing;
|
||
|
}
|
||
|
|
||
|
AddAssertionIfNotNull(policyContext, sp.CreateWsspTransportBindingAssertion(exporter, binding, transportTokenAssertion));
|
||
|
|
||
|
Collection<XmlElement> 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<SecurityBindingElement>().GetIndividualProperty<ISecurityCapabilities>(), 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));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|