1 //-----------------------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //-----------------------------------------------------------------------------
4 namespace System.ServiceModel.Channels
5 {
6     using System;
7     using System.Diagnostics;
8     using System.Collections.Generic;
9     using System.Collections.ObjectModel;
10     using System.Globalization;
11     using System.IdentityModel.Selectors;
12     using System.IdentityModel.Tokens;
13     using System.Net.Security;
14     using System.Runtime;
15     using System.Security.Authentication.ExtendedProtection;
16     using System.ServiceModel;
17     using System.ServiceModel.Configuration;
18     using System.ServiceModel.Diagnostics;
19     using System.ServiceModel.Description;
20     using System.ServiceModel.Security;
21     using System.ServiceModel.Security.Tokens;
22     using System.Text;
23     using System.Xml;
24 
25     public abstract class SecurityBindingElement : BindingElement
26     {
27         internal const string defaultAlgorithmSuiteString = ConfigurationStrings.Default;
28         internal static readonly SecurityAlgorithmSuite defaultDefaultAlgorithmSuite = SecurityAlgorithmSuite.Default;
29         internal const bool defaultIncludeTimestamp = true;
30         internal const bool defaultAllowInsecureTransport = false;
31         internal const MessageProtectionOrder defaultMessageProtectionOrder = MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature;
32         internal const bool defaultRequireSignatureConfirmation = false;
33         internal const bool defaultEnableUnsecuredResponse = false;
34         internal const bool defaultProtectTokens = false;
35 
36         SecurityAlgorithmSuite defaultAlgorithmSuite;
37         SupportingTokenParameters endpointSupportingTokenParameters;
38         SupportingTokenParameters optionalEndpointSupportingTokenParameters;
39         bool includeTimestamp;
40         SecurityKeyEntropyMode keyEntropyMode;
41         Dictionary<string, SupportingTokenParameters> operationSupportingTokenParameters;
42         Dictionary<string, SupportingTokenParameters> optionalOperationSupportingTokenParameters;
43         LocalClientSecuritySettings localClientSettings;
44         LocalServiceSecuritySettings localServiceSettings;
45         MessageSecurityVersion messageSecurityVersion;
46         SecurityHeaderLayout securityHeaderLayout;
47         InternalDuplexBindingElement internalDuplexBindingElement;
48         long maxReceivedMessageSize = TransportDefaults.MaxReceivedMessageSize;
49         XmlDictionaryReaderQuotas readerQuotas;
50         bool doNotEmitTrust = false; // true if user create a basic http standard binding, the custombinding equivalent will not set this flag
51         bool supportsExtendedProtectionPolicy;
52         bool allowInsecureTransport;
53         bool enableUnsecuredResponse;
54         bool protectTokens = defaultProtectTokens;
55 
SecurityBindingElement()56         internal SecurityBindingElement()
57             : base()
58         {
59             this.messageSecurityVersion = MessageSecurityVersion.Default;
60             this.keyEntropyMode = AcceleratedTokenProvider.defaultKeyEntropyMode;
61             this.includeTimestamp = defaultIncludeTimestamp;
62             this.defaultAlgorithmSuite = defaultDefaultAlgorithmSuite;
63             this.localClientSettings = new LocalClientSecuritySettings();
64             this.localServiceSettings = new LocalServiceSecuritySettings();
65             this.endpointSupportingTokenParameters = new SupportingTokenParameters();
66             this.optionalEndpointSupportingTokenParameters = new SupportingTokenParameters();
67             this.operationSupportingTokenParameters = new Dictionary<string, SupportingTokenParameters>();
68             this.optionalOperationSupportingTokenParameters = new Dictionary<string, SupportingTokenParameters>();
69             this.securityHeaderLayout = SecurityProtocolFactory.defaultSecurityHeaderLayout;
70             this.allowInsecureTransport = defaultAllowInsecureTransport;
71             this.enableUnsecuredResponse = defaultEnableUnsecuredResponse;
72             this.protectTokens = defaultProtectTokens;
73         }
74 
SecurityBindingElement(SecurityBindingElement elementToBeCloned)75         internal SecurityBindingElement(SecurityBindingElement elementToBeCloned)
76             : base(elementToBeCloned)
77         {
78             if (elementToBeCloned == null)
79                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("elementToBeCloned");
80 
81             this.defaultAlgorithmSuite = elementToBeCloned.defaultAlgorithmSuite;
82             this.includeTimestamp = elementToBeCloned.includeTimestamp;
83             this.keyEntropyMode = elementToBeCloned.keyEntropyMode;
84             this.messageSecurityVersion = elementToBeCloned.messageSecurityVersion;
85             this.securityHeaderLayout = elementToBeCloned.securityHeaderLayout;
86             this.endpointSupportingTokenParameters = (SupportingTokenParameters)elementToBeCloned.endpointSupportingTokenParameters.Clone();
87             this.optionalEndpointSupportingTokenParameters = (SupportingTokenParameters)elementToBeCloned.optionalEndpointSupportingTokenParameters.Clone();
88             this.operationSupportingTokenParameters = new Dictionary<string, SupportingTokenParameters>();
89             foreach (string key in elementToBeCloned.operationSupportingTokenParameters.Keys)
90             {
91                 this.operationSupportingTokenParameters[key] = (SupportingTokenParameters)elementToBeCloned.operationSupportingTokenParameters[key].Clone();
92             }
93             this.optionalOperationSupportingTokenParameters = new Dictionary<string, SupportingTokenParameters>();
94             foreach (string key in elementToBeCloned.optionalOperationSupportingTokenParameters.Keys)
95             {
96                 this.optionalOperationSupportingTokenParameters[key] = (SupportingTokenParameters)elementToBeCloned.optionalOperationSupportingTokenParameters[key].Clone();
97             }
98             this.localClientSettings = (LocalClientSecuritySettings)elementToBeCloned.localClientSettings.Clone();
99             this.localServiceSettings = (LocalServiceSecuritySettings)elementToBeCloned.localServiceSettings.Clone();
100             this.internalDuplexBindingElement = elementToBeCloned.internalDuplexBindingElement;
101             this.maxReceivedMessageSize = elementToBeCloned.maxReceivedMessageSize;
102             this.readerQuotas = elementToBeCloned.readerQuotas;
103             this.doNotEmitTrust = elementToBeCloned.doNotEmitTrust;
104             this.allowInsecureTransport = elementToBeCloned.allowInsecureTransport;
105             this.enableUnsecuredResponse = elementToBeCloned.enableUnsecuredResponse;
106             this.supportsExtendedProtectionPolicy = elementToBeCloned.supportsExtendedProtectionPolicy;
107             this.protectTokens = elementToBeCloned.protectTokens;
108         }
109 
110         internal bool SupportsExtendedProtectionPolicy
111         {
112             get { return this.supportsExtendedProtectionPolicy; }
113             set { this.supportsExtendedProtectionPolicy = value; }
114         }
115 
116         public SupportingTokenParameters EndpointSupportingTokenParameters
117         {
118             get
119             {
120                 return this.endpointSupportingTokenParameters;
121             }
122         }
123 
124         public SupportingTokenParameters OptionalEndpointSupportingTokenParameters
125         {
126             get
127             {
128                 return this.optionalEndpointSupportingTokenParameters;
129             }
130         }
131 
132 
133         public IDictionary<string, SupportingTokenParameters> OperationSupportingTokenParameters
134         {
135             get
136             {
137                 return this.operationSupportingTokenParameters;
138             }
139         }
140 
141         public IDictionary<string, SupportingTokenParameters> OptionalOperationSupportingTokenParameters
142         {
143             get
144             {
145                 return this.optionalOperationSupportingTokenParameters;
146             }
147         }
148 
149         public SecurityHeaderLayout SecurityHeaderLayout
150         {
151             get
152             {
153                 return this.securityHeaderLayout;
154             }
155             set
156             {
157                 if (!SecurityHeaderLayoutHelper.IsDefined(value))
158                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value"));
159 
160                 this.securityHeaderLayout = value;
161             }
162         }
163 
164         public MessageSecurityVersion MessageSecurityVersion
165         {
166             get
167             {
168                 return this.messageSecurityVersion;
169             }
170             set
171             {
172                 if (value == null)
173                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("value"));
174                 this.messageSecurityVersion = value;
175             }
176         }
177 
178         public bool EnableUnsecuredResponse
179         {
180             get
181             {
182                 return this.enableUnsecuredResponse;
183             }
184             set
185             {
186                 this.enableUnsecuredResponse = value;
187             }
188         }
189 
190         public bool IncludeTimestamp
191         {
192             get
193             {
194                 return this.includeTimestamp;
195             }
196             set
197             {
198                 this.includeTimestamp = value;
199             }
200         }
201 
202         public bool AllowInsecureTransport
203         {
204             get
205             {
206                 return this.allowInsecureTransport;
207             }
208             set
209             {
210                 this.allowInsecureTransport = value;
211             }
212         }
213 
214         public SecurityAlgorithmSuite DefaultAlgorithmSuite
215         {
216             get
217             {
218                 return this.defaultAlgorithmSuite;
219             }
220             set
221             {
222                 if (value == null)
223                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("value"));
224                 this.defaultAlgorithmSuite = value;
225             }
226         }
227 
228         public bool ProtectTokens
229         {
230             get
231             {
232                 return this.protectTokens;
233             }
234             set
235             {
236                 this.protectTokens = value;
237             }
238         }
239 
240         public LocalClientSecuritySettings LocalClientSettings
241         {
242             get
243             {
244                 return this.localClientSettings;
245             }
246         }
247 
248         public LocalServiceSecuritySettings LocalServiceSettings
249         {
250             get
251             {
252                 return this.localServiceSettings;
253             }
254         }
255 
256         public SecurityKeyEntropyMode KeyEntropyMode
257         {
258             get
259             {
260                 return this.keyEntropyMode;
261             }
262             set
263             {
264                 if (!SecurityKeyEntropyModeHelper.IsDefined(value))
265                 {
266                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value"));
267                 }
268                 this.keyEntropyMode = value;
269             }
270         }
271 
272         internal virtual bool SessionMode
273         {
274             get { return false; }
275         }
276 
277         internal virtual bool SupportsDuplex
278         {
279             get { return false; }
280         }
281 
282         internal virtual bool SupportsRequestReply
283         {
284             get { return false; }
285         }
286 
287         internal long MaxReceivedMessageSize
288         {
289             get { return this.maxReceivedMessageSize; }
290             set { this.maxReceivedMessageSize = value; }
291         }
292 
293         internal bool DoNotEmitTrust
294         {
295             get { return this.doNotEmitTrust; }
296             set { this.doNotEmitTrust = value; }
297         }
298 
299         internal XmlDictionaryReaderQuotas ReaderQuotas
300         {
301             get { return this.readerQuotas; }
302             set { this.readerQuotas = value; }
303         }
304 
GetSupportingTokensCapabilities(ICollection<SecurityTokenParameters> parameters, out bool supportsClientAuth, out bool supportsWindowsIdentity)305         void GetSupportingTokensCapabilities(ICollection<SecurityTokenParameters> parameters, out bool supportsClientAuth, out bool supportsWindowsIdentity)
306         {
307             supportsClientAuth = false;
308             supportsWindowsIdentity = false;
309             foreach (SecurityTokenParameters p in parameters)
310             {
311                 if (p.SupportsClientAuthentication)
312                     supportsClientAuth = true;
313                 if (p.SupportsClientWindowsIdentity)
314                     supportsWindowsIdentity = true;
315             }
316         }
317 
GetSupportingTokensCapabilities(SupportingTokenParameters requirements, out bool supportsClientAuth, out bool supportsWindowsIdentity)318         void GetSupportingTokensCapabilities(SupportingTokenParameters requirements, out bool supportsClientAuth, out bool supportsWindowsIdentity)
319         {
320             supportsClientAuth = false;
321             supportsWindowsIdentity = false;
322             bool tmpSupportsClientAuth;
323             bool tmpSupportsWindowsIdentity;
324             this.GetSupportingTokensCapabilities(requirements.Endorsing, out tmpSupportsClientAuth, out tmpSupportsWindowsIdentity);
325             supportsClientAuth = supportsClientAuth || tmpSupportsClientAuth;
326             supportsWindowsIdentity = supportsWindowsIdentity || tmpSupportsWindowsIdentity;
327 
328             this.GetSupportingTokensCapabilities(requirements.SignedEndorsing, out tmpSupportsClientAuth, out tmpSupportsWindowsIdentity);
329             supportsClientAuth = supportsClientAuth || tmpSupportsClientAuth;
330             supportsWindowsIdentity = supportsWindowsIdentity || tmpSupportsWindowsIdentity;
331 
332             this.GetSupportingTokensCapabilities(requirements.SignedEncrypted, out tmpSupportsClientAuth, out tmpSupportsWindowsIdentity);
333             supportsClientAuth = supportsClientAuth || tmpSupportsClientAuth;
334             supportsWindowsIdentity = supportsWindowsIdentity || tmpSupportsWindowsIdentity;
335         }
336 
GetSupportingTokensCapabilities(out bool supportsClientAuth, out bool supportsWindowsIdentity)337         internal void GetSupportingTokensCapabilities(out bool supportsClientAuth, out bool supportsWindowsIdentity)
338         {
339             this.GetSupportingTokensCapabilities(this.EndpointSupportingTokenParameters, out supportsClientAuth, out supportsWindowsIdentity);
340         }
341 
342         // SecureConversation needs a demuxer below security to 1) demux between the security sessions and 2) demux the SCT issue and renewal messages
343         // to the authenticator
AddDemuxerForSecureConversation(ChannelBuilder builder, BindingContext secureConversationBindingContext)344         internal void AddDemuxerForSecureConversation(ChannelBuilder builder, BindingContext secureConversationBindingContext)
345         {
346             // add a demuxer element  right below security unless there's a demuxer already present below and the only
347             // binding elements between security and the demuxer are "ancillary" binding elements like message encoding element and
348             // stream-security upgrade element. We could always add the channel demuxer below security but not doing so in the ancillary
349             // binding elements case improves perf
350             int numChannelDemuxersBelowSecurity = 0;
351             bool doesBindingHaveShapeChangingElements = false;
352             for (int i = 0; i < builder.Binding.Elements.Count; ++i)
353             {
354                 if ((builder.Binding.Elements[i] is MessageEncodingBindingElement) || (builder.Binding.Elements[i] is StreamUpgradeBindingElement))
355                 {
356                     continue;
357                 }
358                 if (builder.Binding.Elements[i] is ChannelDemuxerBindingElement)
359                 {
360                     ++numChannelDemuxersBelowSecurity;
361                 }
362                 else if (builder.Binding.Elements[i] is TransportBindingElement)
363                 {
364                     break;
365                 }
366                 else
367                 {
368                     doesBindingHaveShapeChangingElements = true;
369                 }
370             }
371             if (numChannelDemuxersBelowSecurity == 1 && !doesBindingHaveShapeChangingElements)
372             {
373                 return;
374             }
375 
376             ChannelDemuxerBindingElement demuxer = new ChannelDemuxerBindingElement(false);
377             demuxer.MaxPendingSessions = this.LocalServiceSettings.MaxPendingSessions;
378             demuxer.PeekTimeout = this.LocalServiceSettings.NegotiationTimeout;
379 
380             builder.Binding.Elements.Insert(0, demuxer);
381             secureConversationBindingContext.RemainingBindingElements.Insert(0, demuxer);
382         }
383 
ApplyPropertiesOnDemuxer(ChannelBuilder builder, BindingContext context)384         internal void ApplyPropertiesOnDemuxer(ChannelBuilder builder, BindingContext context)
385         {
386             Collection<ChannelDemuxerBindingElement> demuxerElements = builder.Binding.Elements.FindAll<ChannelDemuxerBindingElement>();
387             foreach (ChannelDemuxerBindingElement element in demuxerElements)
388             {
389                 if (element != null)
390                 {
391                     element.MaxPendingSessions = this.LocalServiceSettings.MaxPendingSessions;
392                     element.PeekTimeout = this.LocalServiceSettings.NegotiationTimeout;
393                 }
394             }
395         }
396 
CreateIssuerBindingContextForNegotiation(BindingContext issuerBindingContext)397         static BindingContext CreateIssuerBindingContextForNegotiation(BindingContext issuerBindingContext)
398         {
399             TransportBindingElement transport = issuerBindingContext.RemainingBindingElements.Find<TransportBindingElement>();
400             if (transport == null)
401             {
402                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.TransportBindingElementNotFound)));
403             }
404             ChannelDemuxerBindingElement demuxer = null;
405             // pick the demuxer above transport (i.e. the last demuxer in the array)
406             for (int i = 0; i < issuerBindingContext.RemainingBindingElements.Count; ++i)
407             {
408                 if (issuerBindingContext.RemainingBindingElements[i] is ChannelDemuxerBindingElement)
409                 {
410                     demuxer = (ChannelDemuxerBindingElement) issuerBindingContext.RemainingBindingElements[i];
411                 }
412             }
413             if (demuxer == null)
414             {
415                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ChannelDemuxerBindingElementNotFound)));
416             }
417             BindingElementCollection negotiationBindingElements = new BindingElementCollection();
418             negotiationBindingElements.Add(demuxer.Clone());
419             negotiationBindingElements.Add(transport.Clone());
420             CustomBinding binding = new CustomBinding(negotiationBindingElements);
421             binding.OpenTimeout = issuerBindingContext.Binding.OpenTimeout;
422             binding.CloseTimeout = issuerBindingContext.Binding.CloseTimeout;
423             binding.SendTimeout = issuerBindingContext.Binding.SendTimeout;
424             binding.ReceiveTimeout = issuerBindingContext.Binding.ReceiveTimeout;
425             if (issuerBindingContext.ListenUriBaseAddress != null)
426             {
427                 return new BindingContext(binding, new BindingParameterCollection(issuerBindingContext.BindingParameters), issuerBindingContext.ListenUriBaseAddress,
428                     issuerBindingContext.ListenUriRelativeAddress, issuerBindingContext.ListenUriMode);
429             }
430             else
431             {
432                 return new BindingContext(binding, new BindingParameterCollection(issuerBindingContext.BindingParameters));
433             }
434         }
435 
SetIssuerBindingContextIfRequired(SecurityTokenParameters parameters, BindingContext issuerBindingContext)436         protected static void SetIssuerBindingContextIfRequired(SecurityTokenParameters parameters, BindingContext issuerBindingContext)
437         {
438             if (parameters is SslSecurityTokenParameters)
439             {
440                 ((SslSecurityTokenParameters)parameters).IssuerBindingContext = CreateIssuerBindingContextForNegotiation(issuerBindingContext);
441             }
442             else if (parameters is SspiSecurityTokenParameters)
443             {
444                 ((SspiSecurityTokenParameters)parameters).IssuerBindingContext = CreateIssuerBindingContextForNegotiation(issuerBindingContext);
445             }
446         }
447 
SetIssuerBindingContextIfRequired(SupportingTokenParameters supportingParameters, BindingContext issuerBindingContext)448         static void SetIssuerBindingContextIfRequired(SupportingTokenParameters supportingParameters, BindingContext issuerBindingContext)
449         {
450             for (int i = 0; i < supportingParameters.Endorsing.Count; ++i)
451             {
452                 SetIssuerBindingContextIfRequired(supportingParameters.Endorsing[i], issuerBindingContext);
453             }
454             for (int i = 0; i < supportingParameters.SignedEndorsing.Count; ++i)
455             {
456                 SetIssuerBindingContextIfRequired(supportingParameters.SignedEndorsing[i], issuerBindingContext);
457             }
458             for (int i = 0; i < supportingParameters.Signed.Count; ++i)
459             {
460                 SetIssuerBindingContextIfRequired(supportingParameters.Signed[i], issuerBindingContext);
461             }
462             for (int i = 0; i < supportingParameters.SignedEncrypted.Count; ++i)
463             {
464                 SetIssuerBindingContextIfRequired(supportingParameters.SignedEncrypted[i], issuerBindingContext);
465             }
466         }
467 
SetIssuerBindingContextIfRequired(BindingContext issuerBindingContext)468         void SetIssuerBindingContextIfRequired(BindingContext issuerBindingContext)
469         {
470             SetIssuerBindingContextIfRequired(this.EndpointSupportingTokenParameters, issuerBindingContext);
471             SetIssuerBindingContextIfRequired(this.OptionalEndpointSupportingTokenParameters, issuerBindingContext);
472             foreach (SupportingTokenParameters parameters in this.OperationSupportingTokenParameters.Values)
473             {
474                 SetIssuerBindingContextIfRequired(parameters, issuerBindingContext);
475             }
476             foreach (SupportingTokenParameters parameters in this.OptionalOperationSupportingTokenParameters.Values)
477             {
478                 SetIssuerBindingContextIfRequired(parameters, issuerBindingContext);
479             }
480         }
481 
RequiresChannelDemuxer(SecurityTokenParameters parameters)482         internal bool RequiresChannelDemuxer(SecurityTokenParameters parameters)
483         {
484             return ((parameters is SecureConversationSecurityTokenParameters)
485                     || (parameters is SslSecurityTokenParameters)
486                     || (parameters is SspiSecurityTokenParameters));
487         }
488 
RequiresChannelDemuxer()489         internal virtual bool RequiresChannelDemuxer()
490         {
491             foreach (SecurityTokenParameters parameters in EndpointSupportingTokenParameters.Endorsing)
492             {
493                 if (RequiresChannelDemuxer(parameters))
494                 {
495                     return true;
496                 }
497             }
498             foreach (SecurityTokenParameters parameters in EndpointSupportingTokenParameters.SignedEndorsing)
499             {
500                 if (RequiresChannelDemuxer(parameters))
501                 {
502                     return true;
503                 }
504             }
505             foreach (SecurityTokenParameters parameters in OptionalEndpointSupportingTokenParameters.Endorsing)
506             {
507                 if (RequiresChannelDemuxer(parameters))
508                 {
509                     return true;
510                 }
511             }
512             foreach (SecurityTokenParameters parameters in OptionalEndpointSupportingTokenParameters.SignedEndorsing)
513             {
514                 if (RequiresChannelDemuxer(parameters))
515                 {
516                     return true;
517                 }
518             }
519             foreach (SupportingTokenParameters supportingParameters in OperationSupportingTokenParameters.Values)
520             {
521                 foreach (SecurityTokenParameters parameters in supportingParameters.Endorsing)
522                 {
523                     if (RequiresChannelDemuxer(parameters))
524                     {
525                         return true;
526                     }
527                 }
528                 foreach (SecurityTokenParameters parameters in supportingParameters.SignedEndorsing)
529                 {
530                     if (RequiresChannelDemuxer(parameters))
531                     {
532                         return true;
533                     }
534                 }
535             }
536             foreach (SupportingTokenParameters supportingParameters in OptionalOperationSupportingTokenParameters.Values)
537             {
538                 foreach (SecurityTokenParameters parameters in supportingParameters.Endorsing)
539                 {
540                     if (RequiresChannelDemuxer(parameters))
541                     {
542                         return true;
543                     }
544                 }
545                 foreach (SecurityTokenParameters parameters in supportingParameters.SignedEndorsing)
546                 {
547                     if (RequiresChannelDemuxer(parameters))
548                     {
549                         return true;
550                     }
551                 }
552             }
553             return false;
554         }
555 
IsUnderlyingListenerDuplex(BindingContext context)556         internal bool IsUnderlyingListenerDuplex<TChannel>(BindingContext context)
557         {
558             return ((typeof(TChannel) == typeof(IDuplexSessionChannel)) && context.CanBuildInnerChannelListener<IDuplexChannel>()
559                 && !context.CanBuildInnerChannelListener<IDuplexSessionChannel>());
560         }
561 
SetPrivacyNoticeUriIfRequired(SecurityProtocolFactory factory, Binding binding)562         void SetPrivacyNoticeUriIfRequired(SecurityProtocolFactory factory, Binding binding)
563         {
564             PrivacyNoticeBindingElement privacyElement = binding.CreateBindingElements().Find<PrivacyNoticeBindingElement>();
565             if (privacyElement != null)
566             {
567                 factory.PrivacyNoticeUri = privacyElement.Url;
568                 factory.PrivacyNoticeVersion = privacyElement.Version;
569             }
570         }
571 
ConfigureProtocolFactory(SecurityProtocolFactory factory, SecurityCredentialsManager credentialsManager, bool isForService, BindingContext issuerBindingContext, Binding binding)572         internal void ConfigureProtocolFactory(SecurityProtocolFactory factory, SecurityCredentialsManager credentialsManager, bool isForService, BindingContext issuerBindingContext, Binding binding)
573         {
574             if (factory == null)
575                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("factory"));
576             if (credentialsManager == null)
577                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("credentialsManager"));
578 
579             factory.AddTimestamp = this.IncludeTimestamp;
580             factory.IncomingAlgorithmSuite = this.DefaultAlgorithmSuite;
581             factory.OutgoingAlgorithmSuite = this.DefaultAlgorithmSuite;
582             factory.SecurityHeaderLayout = this.SecurityHeaderLayout;
583 
584             if (!isForService)
585             {
586                 factory.TimestampValidityDuration = this.LocalClientSettings.TimestampValidityDuration;
587                 factory.DetectReplays = this.LocalClientSettings.DetectReplays;
588                 factory.MaxCachedNonces = this.LocalClientSettings.ReplayCacheSize;
589                 factory.MaxClockSkew = this.LocalClientSettings.MaxClockSkew;
590                 factory.ReplayWindow = this.LocalClientSettings.ReplayWindow;
591 
592                 if (this.LocalClientSettings.DetectReplays)
593                 {
594                   factory.NonceCache = this.LocalClientSettings.NonceCache;
595                 }
596             }
597             else
598             {
599                 factory.TimestampValidityDuration = this.LocalServiceSettings.TimestampValidityDuration;
600                 factory.DetectReplays = this.LocalServiceSettings.DetectReplays;
601                 factory.MaxCachedNonces = this.LocalServiceSettings.ReplayCacheSize;
602                 factory.MaxClockSkew = this.LocalServiceSettings.MaxClockSkew;
603                 factory.ReplayWindow = this.LocalServiceSettings.ReplayWindow;
604 
605                 if (this.LocalServiceSettings.DetectReplays)
606                 {
607                    factory.NonceCache = this.LocalServiceSettings.NonceCache;
608                 }
609             }
610 
611             factory.SecurityBindingElement = (SecurityBindingElement) this.Clone();
612             factory.SecurityBindingElement.SetIssuerBindingContextIfRequired(issuerBindingContext);
613             factory.SecurityTokenManager = credentialsManager.CreateSecurityTokenManager();
614             SecurityTokenSerializer tokenSerializer = factory.SecurityTokenManager.CreateSecurityTokenSerializer(this.messageSecurityVersion.SecurityTokenVersion);
615             factory.StandardsManager = new SecurityStandardsManager(this.messageSecurityVersion, tokenSerializer);
616             if (!isForService)
617             {
618                 SetPrivacyNoticeUriIfRequired(factory, binding);
619             }
620         }
621 
CreateSecurityProtocolFactory(BindingContext context, SecurityCredentialsManager credentialsManager, bool isForService, BindingContext issuanceBindingContext)622         internal abstract SecurityProtocolFactory CreateSecurityProtocolFactory<TChannel>(BindingContext context, SecurityCredentialsManager credentialsManager,
623         bool isForService, BindingContext issuanceBindingContext);
624 
BuildChannelFactory(BindingContext context)625         public override IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context)
626         {
627             if (context == null)
628                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
629 
630             if (!this.CanBuildChannelFactory<TChannel>(context))
631             {
632                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.ChannelTypeNotSupported, typeof(TChannel)), "TChannel"));
633             }
634 
635             this.readerQuotas = context.GetInnerProperty<XmlDictionaryReaderQuotas>();
636             if (readerQuotas == null)
637             {
638                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.EncodingBindingElementDoesNotHandleReaderQuotas)));
639             }
640 
641             TransportBindingElement transportBindingElement = null;
642 
643             if (context.RemainingBindingElements != null)
644                 transportBindingElement = context.RemainingBindingElements.Find<TransportBindingElement>();
645 
646             if (transportBindingElement != null)
647                 this.maxReceivedMessageSize = transportBindingElement.MaxReceivedMessageSize;
648 
649             IChannelFactory<TChannel> result = this.BuildChannelFactoryCore<TChannel>(context);
650 
651             // attach the ExtendedProtectionPolicy to the securityProtcolFactory so it will be
652             // available when building the channel.
653             if (transportBindingElement != null)
654             {
655                 SecurityChannelFactory<TChannel> scf = result as SecurityChannelFactory<TChannel>;
656                 if (scf != null && scf.SecurityProtocolFactory != null)
657                 {
658                     scf.SecurityProtocolFactory.ExtendedProtectionPolicy = transportBindingElement.GetProperty<ExtendedProtectionPolicy>(context);
659                 }
660             }
661 
662             return result;
663 
664         }
665 
BuildChannelFactoryCore(BindingContext context)666         protected abstract IChannelFactory<TChannel> BuildChannelFactoryCore<TChannel>(BindingContext context);
667 
CanBuildChannelFactory(BindingContext context)668         public override bool CanBuildChannelFactory<TChannel>(BindingContext context)
669         {
670             if (context == null)
671                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
672 
673             InternalDuplexBindingElement.AddDuplexFactorySupport(context, ref this.internalDuplexBindingElement);
674 
675             if (this.SessionMode)
676             {
677                 return this.CanBuildSessionChannelFactory<TChannel>(context);
678             }
679 
680             if (!context.CanBuildInnerChannelFactory<TChannel>())
681             {
682                 return false;
683             }
684 
685             return typeof(TChannel) == typeof(IOutputChannel) || typeof(TChannel) == typeof(IOutputSessionChannel) ||
686                 (this.SupportsDuplex && (typeof(TChannel) == typeof(IDuplexChannel) || typeof(TChannel) == typeof(IDuplexSessionChannel))) ||
687                 (this.SupportsRequestReply && (typeof(TChannel) == typeof(IRequestChannel) || typeof(TChannel) == typeof(IRequestSessionChannel)));
688         }
689 
CanBuildSessionChannelFactory(BindingContext context)690         bool CanBuildSessionChannelFactory<TChannel>(BindingContext context)
691         {
692             if (!(context.CanBuildInnerChannelFactory<IRequestChannel>()
693                 || context.CanBuildInnerChannelFactory<IRequestSessionChannel>()
694                 || context.CanBuildInnerChannelFactory<IDuplexChannel>()
695                 || context.CanBuildInnerChannelFactory<IDuplexSessionChannel>()))
696             {
697                 return false;
698             }
699 
700             if (typeof(TChannel) == typeof(IRequestSessionChannel))
701             {
702                 return (context.CanBuildInnerChannelFactory<IRequestChannel>() || context.CanBuildInnerChannelFactory<IRequestSessionChannel>());
703             }
704             else if (typeof(TChannel) == typeof(IDuplexSessionChannel))
705             {
706                 return (context.CanBuildInnerChannelFactory<IDuplexChannel>() || context.CanBuildInnerChannelFactory<IDuplexSessionChannel>());
707             }
708             else
709             {
710                 return false;
711             }
712         }
713 
BuildChannelListener(BindingContext context)714         public override IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context)
715         {
716             if (context == null)
717                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
718 
719             if (!this.CanBuildChannelListener<TChannel>(context))
720             {
721                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.ChannelTypeNotSupported, typeof(TChannel)), "TChannel"));
722             }
723 
724             this.readerQuotas = context.GetInnerProperty<XmlDictionaryReaderQuotas>();
725             if (readerQuotas == null)
726             {
727                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.EncodingBindingElementDoesNotHandleReaderQuotas)));
728             }
729 
730             TransportBindingElement transportBindingElement = null;
731             if (context.RemainingBindingElements != null)
732                 transportBindingElement = context.RemainingBindingElements.Find<TransportBindingElement>();
733 
734             if (transportBindingElement != null)
735                 this.maxReceivedMessageSize = transportBindingElement.MaxReceivedMessageSize;
736 
737             return this.BuildChannelListenerCore<TChannel>(context);
738         }
739 
740         protected abstract IChannelListener<TChannel> BuildChannelListenerCore<TChannel>(BindingContext context)
741             where TChannel : class, IChannel;
742 
CanBuildChannelListener(BindingContext context)743         public override bool CanBuildChannelListener<TChannel>(BindingContext context)
744         {
745             if (context == null)
746                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
747 
748             InternalDuplexBindingElement.AddDuplexListenerSupport(context, ref this.internalDuplexBindingElement);
749 
750             if (this.SessionMode)
751             {
752                 return this.CanBuildSessionChannelListener<TChannel>(context);
753             }
754 
755             if (!context.CanBuildInnerChannelListener<TChannel>())
756             {
757                 return false;
758             }
759 
760             return typeof(TChannel) == typeof(IInputChannel) || typeof(TChannel) == typeof(IInputSessionChannel) ||
761                 (this.SupportsDuplex && (typeof(TChannel) == typeof(IDuplexChannel) || typeof(TChannel) == typeof(IDuplexSessionChannel))) ||
762                 (this.SupportsRequestReply && (typeof(TChannel) == typeof(IReplyChannel) || typeof(TChannel) == typeof(IReplySessionChannel)));
763         }
764 
765         bool CanBuildSessionChannelListener<TChannel>(BindingContext context)
766             where TChannel : class, IChannel
767         {
768             if (!(context.CanBuildInnerChannelListener<IReplyChannel>()
769                 || context.CanBuildInnerChannelListener<IReplySessionChannel>()
770                 || context.CanBuildInnerChannelListener<IDuplexChannel>()
771                 || context.CanBuildInnerChannelListener<IDuplexSessionChannel>()))
772             {
773                 return false;
774             }
775 
776             if (typeof(TChannel) == typeof(IReplySessionChannel))
777             {
778                 return (context.CanBuildInnerChannelListener<IReplyChannel>() || context.CanBuildInnerChannelListener<IReplySessionChannel>());
779             }
780             else if (typeof(TChannel) == typeof(IDuplexSessionChannel))
781             {
782                 return (context.CanBuildInnerChannelListener<IDuplexChannel>() || context.CanBuildInnerChannelListener<IDuplexSessionChannel>());
783             }
784             else
785             {
786                 return false;
787             }
788         }
789 
SetKeyDerivation(bool requireDerivedKeys)790         public virtual void SetKeyDerivation(bool requireDerivedKeys)
791         {
792             this.EndpointSupportingTokenParameters.SetKeyDerivation(requireDerivedKeys);
793             this.OptionalEndpointSupportingTokenParameters.SetKeyDerivation(requireDerivedKeys);
794             foreach (SupportingTokenParameters t in this.OperationSupportingTokenParameters.Values)
795                 t.SetKeyDerivation(requireDerivedKeys);
796             foreach (SupportingTokenParameters t in this.OptionalOperationSupportingTokenParameters.Values)
797             {
798                 t.SetKeyDerivation(requireDerivedKeys);
799             }
800         }
801 
IsSetKeyDerivation(bool requireDerivedKeys)802         internal virtual bool IsSetKeyDerivation(bool requireDerivedKeys)
803         {
804             if (!this.EndpointSupportingTokenParameters.IsSetKeyDerivation(requireDerivedKeys))
805                 return false;
806 
807             if (!this.OptionalEndpointSupportingTokenParameters.IsSetKeyDerivation(requireDerivedKeys))
808                 return false;
809 
810             foreach (SupportingTokenParameters t in this.OperationSupportingTokenParameters.Values)
811             {
812                 if (!t.IsSetKeyDerivation(requireDerivedKeys))
813                     return false;
814             }
815             foreach (SupportingTokenParameters t in this.OptionalOperationSupportingTokenParameters.Values)
816             {
817                 if (!t.IsSetKeyDerivation(requireDerivedKeys))
818                     return false;
819             }
820             return true;
821         }
822 
GetProtectionRequirements(AddressingVersion addressing, ProtectionLevel defaultProtectionLevel)823         internal ChannelProtectionRequirements GetProtectionRequirements(AddressingVersion addressing, ProtectionLevel defaultProtectionLevel)
824         {
825             if (addressing == null)
826                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("addressing");
827 
828             ChannelProtectionRequirements result = new ChannelProtectionRequirements();
829             ProtectionLevel supportedRequestProtectionLevel = this.GetIndividualProperty<ISecurityCapabilities>().SupportedRequestProtectionLevel;
830             ProtectionLevel supportedResponseProtectionLevel = this.GetIndividualProperty<ISecurityCapabilities>().SupportedResponseProtectionLevel;
831 
832             bool canSupportMoreThanTheDefault =
833                 (ProtectionLevelHelper.IsStrongerOrEqual(supportedRequestProtectionLevel, defaultProtectionLevel)
834                 && ProtectionLevelHelper.IsStrongerOrEqual(supportedResponseProtectionLevel, defaultProtectionLevel));
835             if (canSupportMoreThanTheDefault)
836             {
837                 MessagePartSpecification signedParts = new MessagePartSpecification();
838                 MessagePartSpecification encryptedParts = new MessagePartSpecification();
839                 if (defaultProtectionLevel != ProtectionLevel.None)
840                 {
841                     signedParts.IsBodyIncluded = true;
842                     if (defaultProtectionLevel == ProtectionLevel.EncryptAndSign)
843                     {
844                         encryptedParts.IsBodyIncluded = true;
845                     }
846                 }
847                 signedParts.MakeReadOnly();
848                 encryptedParts.MakeReadOnly();
849                 if (addressing.FaultAction != null)
850                 {
851                     // Addressing faults
852                     result.IncomingSignatureParts.AddParts(signedParts, addressing.FaultAction);
853                     result.OutgoingSignatureParts.AddParts(signedParts, addressing.FaultAction);
854                     result.IncomingEncryptionParts.AddParts(encryptedParts, addressing.FaultAction);
855                     result.OutgoingEncryptionParts.AddParts(encryptedParts, addressing.FaultAction);
856                 }
857                 if (addressing.DefaultFaultAction != null)
858                 {
859                     // Faults that do not specify a particular action
860                     result.IncomingSignatureParts.AddParts(signedParts, addressing.DefaultFaultAction);
861                     result.OutgoingSignatureParts.AddParts(signedParts, addressing.DefaultFaultAction);
862                     result.IncomingEncryptionParts.AddParts(encryptedParts, addressing.DefaultFaultAction);
863                     result.OutgoingEncryptionParts.AddParts(encryptedParts, addressing.DefaultFaultAction);
864                 }
865                 // Infrastructure faults
866                 result.IncomingSignatureParts.AddParts(signedParts, FaultCodeConstants.Actions.NetDispatcher);
867                 result.OutgoingSignatureParts.AddParts(signedParts, FaultCodeConstants.Actions.NetDispatcher);
868                 result.IncomingEncryptionParts.AddParts(encryptedParts, FaultCodeConstants.Actions.NetDispatcher);
869                 result.OutgoingEncryptionParts.AddParts(encryptedParts, FaultCodeConstants.Actions.NetDispatcher);
870             }
871 
872             return result;
873         }
874 
GetProperty(BindingContext context)875         public override T GetProperty<T>(BindingContext context)
876         {
877             if (context == null)
878             {
879                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
880             }
881             if (typeof(T) == typeof(ISecurityCapabilities))
882             {
883                 return (T)(object)GetSecurityCapabilities(context);
884             }
885             else if (typeof(T) == typeof(IdentityVerifier))
886             {
887                 return (T)(object)this.localClientSettings.IdentityVerifier;
888             }
889             else
890             {
891                 return context.GetInnerProperty<T>();
892             }
893         }
894 
GetIndividualISecurityCapabilities()895         internal abstract ISecurityCapabilities GetIndividualISecurityCapabilities();
896 
GetSecurityCapabilities(BindingContext context)897         ISecurityCapabilities GetSecurityCapabilities(BindingContext context)
898         {
899             ISecurityCapabilities thisSecurityCapability = this.GetIndividualISecurityCapabilities();
900             ISecurityCapabilities lowerSecurityCapability = context.GetInnerProperty<ISecurityCapabilities>();
901             if (lowerSecurityCapability == null)
902             {
903                 return thisSecurityCapability;
904             }
905             else
906             {
907                 bool supportsClientAuth = thisSecurityCapability.SupportsClientAuthentication;
908                 bool supportsClientWindowsIdentity = thisSecurityCapability.SupportsClientWindowsIdentity;
909                 bool supportsServerAuth = thisSecurityCapability.SupportsServerAuthentication || lowerSecurityCapability.SupportsServerAuthentication;
910                 ProtectionLevel requestProtectionLevel = ProtectionLevelHelper.Max(thisSecurityCapability.SupportedRequestProtectionLevel, lowerSecurityCapability.SupportedRequestProtectionLevel);
911                 ProtectionLevel responseProtectionLevel = ProtectionLevelHelper.Max(thisSecurityCapability.SupportedResponseProtectionLevel, lowerSecurityCapability.SupportedResponseProtectionLevel);
912                 return new SecurityCapabilities(supportsClientAuth, supportsServerAuth, supportsClientWindowsIdentity, requestProtectionLevel, responseProtectionLevel);
913             }
914         }
915 
916         // If any changes are made to this method, please make sure that they are
917         // reflected in the corresponding IsMutualCertificateBinding() method.
CreateMutualCertificateBindingElement()918         static public SecurityBindingElement CreateMutualCertificateBindingElement()
919         {
920             return CreateMutualCertificateBindingElement(MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11);
921         }
922 
923         // this method reverses CreateMutualCertificateBindingElement() logic
IsMutualCertificateBinding(SecurityBindingElement sbe)924         internal static bool IsMutualCertificateBinding(SecurityBindingElement sbe)
925         {
926             return IsMutualCertificateBinding(sbe, false);
927         }
928 
CreateCertificateSignatureBindingElement()929         static public AsymmetricSecurityBindingElement CreateCertificateSignatureBindingElement()
930         {
931             AsymmetricSecurityBindingElement result;
932 
933             result = new AsymmetricSecurityBindingElement(
934                 new X509SecurityTokenParameters( // recipient
935                     X509KeyIdentifierClauseType.Any,
936                     SecurityTokenInclusionMode.Never, false),
937                 new X509SecurityTokenParameters( // initiator
938                     X509KeyIdentifierClauseType.Any,
939                     SecurityTokenInclusionMode.AlwaysToRecipient, false));
940 
941             // this is a one way binding so the client cannot detect replays
942             result.IsCertificateSignatureBinding = true;
943             result.LocalClientSettings.DetectReplays = false;
944             result.MessageProtectionOrder = MessageProtectionOrder.SignBeforeEncrypt;
945 
946             return result;
947         }
948 
949         // If any changes are made to this method, please make sure that they are
950         // reflected in the corresponding IsMutualCertificateBinding() method.
CreateMutualCertificateBindingElement(MessageSecurityVersion version)951         static public SecurityBindingElement CreateMutualCertificateBindingElement(MessageSecurityVersion version)
952         {
953             return CreateMutualCertificateBindingElement(version, false);
954         }
955 
956         // If any changes are made to this method, please make sure that they are
957         // reflected in the corresponding IsMutualCertificateBinding() method.
CreateMutualCertificateBindingElement(MessageSecurityVersion version, bool allowSerializedSigningTokenOnReply)958         static public SecurityBindingElement CreateMutualCertificateBindingElement(MessageSecurityVersion version, bool allowSerializedSigningTokenOnReply)
959         {
960             if (version == null)
961             {
962                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("version");
963             }
964             SecurityBindingElement result;
965 
966             if (version.SecurityVersion == SecurityVersion.WSSecurity10)
967             {
968                 result = new AsymmetricSecurityBindingElement(
969                     new X509SecurityTokenParameters( // recipient
970                         X509KeyIdentifierClauseType.Any,
971                         SecurityTokenInclusionMode.Never,
972                         false),
973                     new X509SecurityTokenParameters( // initiator
974                         X509KeyIdentifierClauseType.Any,
975                         SecurityTokenInclusionMode.AlwaysToRecipient, false),
976                     allowSerializedSigningTokenOnReply);
977             }
978             else
979             {
980                 result = new SymmetricSecurityBindingElement(
981                     new X509SecurityTokenParameters( // protection
982                         X509KeyIdentifierClauseType.Thumbprint,
983                         SecurityTokenInclusionMode.Never));
984                 result.EndpointSupportingTokenParameters.Endorsing.Add(
985                     new X509SecurityTokenParameters(
986                         X509KeyIdentifierClauseType.Thumbprint,
987                         SecurityTokenInclusionMode.AlwaysToRecipient,
988                         false));
989                 ((SymmetricSecurityBindingElement)result).RequireSignatureConfirmation = true;
990             }
991 
992             result.MessageSecurityVersion = version;
993 
994             return result;
995         }
996 
997         // this method reverses CreateMutualCertificateDuplexBindingElement() logic
998 
IsMutualCertificateDuplexBinding(SecurityBindingElement sbe)999         internal static bool IsMutualCertificateDuplexBinding(SecurityBindingElement sbe)
1000         {
1001 
1002             // Do not check MessageSecurityVersion: it maybe changed by the wrapper element and gets checked later in the SecuritySection.AreBindingsMatching()
1003 
1004             AsymmetricSecurityBindingElement asbe = sbe as AsymmetricSecurityBindingElement;
1005             if (asbe != null)
1006             {
1007                 X509SecurityTokenParameters recipient = asbe.RecipientTokenParameters as X509SecurityTokenParameters;
1008                 if (recipient == null || (recipient.X509ReferenceStyle != X509KeyIdentifierClauseType.Any  && recipient.X509ReferenceStyle != X509KeyIdentifierClauseType.Thumbprint) || recipient.InclusionMode != SecurityTokenInclusionMode.AlwaysToInitiator)
1009                     return false;
1010 
1011                 X509SecurityTokenParameters initiator = asbe.InitiatorTokenParameters as X509SecurityTokenParameters;
1012                 if (initiator == null || (initiator.X509ReferenceStyle != X509KeyIdentifierClauseType.Any && initiator.X509ReferenceStyle != X509KeyIdentifierClauseType.Thumbprint) || initiator.InclusionMode != SecurityTokenInclusionMode.AlwaysToRecipient)
1013                     return false;
1014 
1015                 if (!sbe.EndpointSupportingTokenParameters.IsEmpty())
1016                     return false;
1017 
1018                 return true;
1019             }
1020             else
1021             {
1022                 return false;
1023             }
1024         }
1025 
1026         // this method reverses CreateMutualCertificateBindingElement() logic
IsMutualCertificateBinding(SecurityBindingElement sbe, bool allowSerializedSigningTokenOnReply)1027         internal static bool IsMutualCertificateBinding(SecurityBindingElement sbe, bool allowSerializedSigningTokenOnReply)
1028         {
1029 
1030             // Do not check MessageSecurityVersion: it maybe changed by the wrapper element and gets checked later in the SecuritySection.AreBindingsMatching()
1031 
1032             AsymmetricSecurityBindingElement asbe = sbe as AsymmetricSecurityBindingElement;
1033             if (asbe != null)
1034             {
1035                 X509SecurityTokenParameters recipient = asbe.RecipientTokenParameters as X509SecurityTokenParameters;
1036                 if (recipient == null || recipient.X509ReferenceStyle != X509KeyIdentifierClauseType.Any || recipient.InclusionMode != SecurityTokenInclusionMode.Never)
1037                     return false;
1038 
1039                 X509SecurityTokenParameters initiator = asbe.InitiatorTokenParameters as X509SecurityTokenParameters;
1040                 if (initiator == null || initiator.X509ReferenceStyle != X509KeyIdentifierClauseType.Any || initiator.InclusionMode != SecurityTokenInclusionMode.AlwaysToRecipient)
1041                     return false;
1042 
1043                 if (!sbe.EndpointSupportingTokenParameters.IsEmpty())
1044                     return false;
1045             }
1046             else
1047             {
1048                 SymmetricSecurityBindingElement ssbe = sbe as SymmetricSecurityBindingElement;
1049                 if (ssbe == null)
1050                     return false;
1051 
1052                 X509SecurityTokenParameters x509Parameters = ssbe.ProtectionTokenParameters as X509SecurityTokenParameters;
1053                 if (x509Parameters == null || x509Parameters.X509ReferenceStyle != X509KeyIdentifierClauseType.Thumbprint || x509Parameters.InclusionMode != SecurityTokenInclusionMode.Never)
1054                     return false;
1055 
1056                 SupportingTokenParameters parameters = sbe.EndpointSupportingTokenParameters;
1057                 if (parameters.Signed.Count != 0 || parameters.SignedEncrypted.Count != 0 || parameters.Endorsing.Count != 1 || parameters.SignedEndorsing.Count != 0)
1058                     return false;
1059 
1060                 x509Parameters = parameters.Endorsing[0] as X509SecurityTokenParameters;
1061                 if (x509Parameters == null || x509Parameters.X509ReferenceStyle != X509KeyIdentifierClauseType.Thumbprint || x509Parameters.InclusionMode != SecurityTokenInclusionMode.AlwaysToRecipient)
1062                     return false;
1063 
1064                 if (!ssbe.RequireSignatureConfirmation)
1065                     return false;
1066 
1067             }
1068             return true;
1069         }
1070 
1071         // If any changes are made to this method, please make sure that they are
1072         // reflected in the corresponding IsAnonymousForCertificateBinding() method.
CreateAnonymousForCertificateBindingElement()1073         static public SymmetricSecurityBindingElement CreateAnonymousForCertificateBindingElement()
1074         {
1075             SymmetricSecurityBindingElement result;
1076 
1077             result = new SymmetricSecurityBindingElement(
1078                 new X509SecurityTokenParameters( // protection
1079                     X509KeyIdentifierClauseType.Thumbprint,
1080                     SecurityTokenInclusionMode.Never));
1081             result.MessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11;
1082             result.RequireSignatureConfirmation = true;
1083 
1084             return result;
1085         }
1086 
1087         // this method reverses CreateAnonymousForCertificateBindingElement() logic
IsAnonymousForCertificateBinding(SecurityBindingElement sbe)1088         internal static bool IsAnonymousForCertificateBinding(SecurityBindingElement sbe)
1089         {
1090             SymmetricSecurityBindingElement ssbe = sbe as SymmetricSecurityBindingElement;
1091             if (ssbe == null)
1092                 return false;
1093 
1094             if (!ssbe.RequireSignatureConfirmation)
1095                 return false;
1096 
1097             // Do not check MessageSecurityVersion: it maybe changed by the wrapper element and gets checked later in the SecuritySection.AreBindingsMatching()
1098 
1099             X509SecurityTokenParameters x509Parameters = ssbe.ProtectionTokenParameters as X509SecurityTokenParameters;
1100             if (x509Parameters == null || x509Parameters.X509ReferenceStyle != X509KeyIdentifierClauseType.Thumbprint || x509Parameters.InclusionMode != SecurityTokenInclusionMode.Never)
1101                 return false;
1102 
1103             if (!sbe.EndpointSupportingTokenParameters.IsEmpty())
1104                 return false;
1105 
1106             return true;
1107         }
1108 
CreateMutualCertificateDuplexBindingElement()1109         static public AsymmetricSecurityBindingElement CreateMutualCertificateDuplexBindingElement()
1110         {
1111             return CreateMutualCertificateDuplexBindingElement(MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11);
1112         }
1113 
CreateMutualCertificateDuplexBindingElement(MessageSecurityVersion version)1114         static public AsymmetricSecurityBindingElement CreateMutualCertificateDuplexBindingElement(MessageSecurityVersion version)
1115         {
1116             if (version == null)
1117             {
1118                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("version");
1119             }
1120             AsymmetricSecurityBindingElement result;
1121 
1122             if (version.SecurityVersion == SecurityVersion.WSSecurity10)
1123             {
1124                 result = new AsymmetricSecurityBindingElement(
1125                     new X509SecurityTokenParameters( // recipient
1126                         X509KeyIdentifierClauseType.Any,
1127                         SecurityTokenInclusionMode.AlwaysToInitiator,
1128                         false),
1129                     new X509SecurityTokenParameters( // initiator
1130                         X509KeyIdentifierClauseType.Any,
1131                         SecurityTokenInclusionMode.AlwaysToRecipient,
1132                         false));
1133             }
1134             else
1135             {
1136                 result = new AsymmetricSecurityBindingElement(
1137                     new X509SecurityTokenParameters( // recipient
1138                         X509KeyIdentifierClauseType.Thumbprint,
1139                         SecurityTokenInclusionMode.AlwaysToInitiator,
1140                         false),
1141                     new X509SecurityTokenParameters( // initiator
1142                         X509KeyIdentifierClauseType.Thumbprint,
1143                         SecurityTokenInclusionMode.AlwaysToRecipient,
1144                         false));
1145             }
1146 
1147             result.MessageSecurityVersion = version;
1148 
1149             return result;
1150         }
1151 
1152         // If any changes are made to this method, please make sure that they are
1153         // reflected in the corresponding IsUserNameForCertificateBinding() method.
CreateUserNameForCertificateBindingElement()1154         static public SymmetricSecurityBindingElement CreateUserNameForCertificateBindingElement()
1155         {
1156             SymmetricSecurityBindingElement result = new SymmetricSecurityBindingElement(
1157                 new X509SecurityTokenParameters(
1158                     X509KeyIdentifierClauseType.Thumbprint,
1159                     SecurityTokenInclusionMode.Never));
1160             result.EndpointSupportingTokenParameters.SignedEncrypted.Add(
1161                 new UserNameSecurityTokenParameters());
1162             result.MessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11;
1163 
1164             return result;
1165         }
1166 
1167         // this method reverses CreateMutualCertificateBindingElement() logic
IsUserNameForCertificateBinding(SecurityBindingElement sbe)1168         internal static bool IsUserNameForCertificateBinding(SecurityBindingElement sbe)
1169         {
1170             // Do not check MessageSecurityVersion: it maybe changed by the wrapper element and gets checked later in the SecuritySection.AreBindingsMatching()
1171 
1172             SymmetricSecurityBindingElement ssbe = sbe as SymmetricSecurityBindingElement;
1173             if (ssbe == null)
1174                 return false;
1175 
1176             X509SecurityTokenParameters x509Parameters = ssbe.ProtectionTokenParameters as X509SecurityTokenParameters;
1177             if (x509Parameters == null || x509Parameters.X509ReferenceStyle != X509KeyIdentifierClauseType.Thumbprint || x509Parameters.InclusionMode != SecurityTokenInclusionMode.Never)
1178                 return false;
1179 
1180             SupportingTokenParameters parameters = sbe.EndpointSupportingTokenParameters;
1181             if (parameters.Signed.Count != 0 || parameters.SignedEncrypted.Count != 1 || parameters.Endorsing.Count != 0 || parameters.SignedEndorsing.Count != 0)
1182                 return false;
1183 
1184             UserNameSecurityTokenParameters userNameParameters = parameters.SignedEncrypted[0] as UserNameSecurityTokenParameters;
1185             if (userNameParameters == null)
1186                 return false;
1187 
1188             return true;
1189         }
1190 
1191         // If any changes are made to this method, please make sure that they are
1192         // reflected in the corresponding IsKerberosBinding() method.
CreateKerberosBindingElement()1193         static public SymmetricSecurityBindingElement CreateKerberosBindingElement()
1194         {
1195             SymmetricSecurityBindingElement result = new SymmetricSecurityBindingElement(
1196                 new KerberosSecurityTokenParameters());
1197             result.DefaultAlgorithmSuite = SecurityAlgorithmSuite.KerberosDefault;
1198             return result;
1199         }
1200 
1201         // this method reverses CreateMutualCertificateBindingElement() logic
IsKerberosBinding(SecurityBindingElement sbe)1202         internal static bool IsKerberosBinding(SecurityBindingElement sbe)
1203         {
1204             // do not check DefaultAlgorithmSuite match: it is often changed by the caller of CreateKerberosBindingElement
1205             SymmetricSecurityBindingElement ssbe = sbe as SymmetricSecurityBindingElement;
1206             if (ssbe == null)
1207                 return false;
1208 
1209             KerberosSecurityTokenParameters parameters = ssbe.ProtectionTokenParameters as KerberosSecurityTokenParameters;
1210             if (parameters == null)
1211                 return false;
1212 
1213             if (!sbe.EndpointSupportingTokenParameters.IsEmpty())
1214                 return false;
1215 
1216             return true;
1217         }
1218 
CreateSspiNegotiationBindingElement()1219         static public SymmetricSecurityBindingElement CreateSspiNegotiationBindingElement()
1220         {
1221             return CreateSspiNegotiationBindingElement(SspiSecurityTokenParameters.defaultRequireCancellation);
1222         }
1223 
1224         // If any changes are made to this method, please make sure that they are
1225         // reflected in the corresponding IsSspiNegotiationBinding() method.
CreateSspiNegotiationBindingElement(bool requireCancellation)1226         static public SymmetricSecurityBindingElement CreateSspiNegotiationBindingElement(bool requireCancellation)
1227         {
1228             SymmetricSecurityBindingElement result = new SymmetricSecurityBindingElement(
1229                 new SspiSecurityTokenParameters(requireCancellation));
1230             return result;
1231         }
1232 
1233         // this method reverses CreateMutualCertificateBindingElement() logic
IsSspiNegotiationBinding(SecurityBindingElement sbe, bool requireCancellation)1234         internal static bool IsSspiNegotiationBinding(SecurityBindingElement sbe, bool requireCancellation)
1235         {
1236             SymmetricSecurityBindingElement ssbe  = sbe as SymmetricSecurityBindingElement;
1237 
1238             if (ssbe == null)
1239                 return false;
1240 
1241             if (!sbe.EndpointSupportingTokenParameters.IsEmpty())
1242                 return false;
1243 
1244             SspiSecurityTokenParameters sspiParameters = ssbe.ProtectionTokenParameters as SspiSecurityTokenParameters;
1245             if (sspiParameters == null)
1246                 return false;
1247 
1248             return sspiParameters.RequireCancellation == requireCancellation;
1249         }
1250 
1251 
CreateSslNegotiationBindingElement(bool requireClientCertificate)1252         static public SymmetricSecurityBindingElement CreateSslNegotiationBindingElement(bool requireClientCertificate)
1253         {
1254             return CreateSslNegotiationBindingElement(requireClientCertificate, SslSecurityTokenParameters.defaultRequireCancellation);
1255         }
1256 
1257         // If any changes are made to this method, please make sure that they are
1258         // reflected in the corresponding IsSslNegotiationBinding() method.
CreateSslNegotiationBindingElement(bool requireClientCertificate, bool requireCancellation)1259         static public SymmetricSecurityBindingElement CreateSslNegotiationBindingElement(bool requireClientCertificate, bool requireCancellation)
1260         {
1261             SymmetricSecurityBindingElement result = new SymmetricSecurityBindingElement(
1262                 new SslSecurityTokenParameters(requireClientCertificate, requireCancellation));
1263             return result;
1264         }
1265 
1266         // this method reverses CreateMutualCertificateBindingElement() logic
IsSslNegotiationBinding(SecurityBindingElement sbe, bool requireClientCertificate, bool requireCancellation)1267         internal static bool IsSslNegotiationBinding(SecurityBindingElement sbe, bool requireClientCertificate, bool requireCancellation)
1268         {
1269             SymmetricSecurityBindingElement ssbe = sbe as SymmetricSecurityBindingElement;
1270             if (ssbe == null)
1271                 return false;
1272 
1273             if (!sbe.EndpointSupportingTokenParameters.IsEmpty())
1274                 return false;
1275 
1276             SslSecurityTokenParameters sslParameters = ssbe.ProtectionTokenParameters as SslSecurityTokenParameters;
1277             if (sslParameters == null)
1278                 return false;
1279 
1280             return sslParameters.RequireClientCertificate == requireClientCertificate && sslParameters.RequireCancellation == requireCancellation;
1281 
1282         }
CreateIssuedTokenBindingElement(IssuedSecurityTokenParameters issuedTokenParameters)1283         static public SymmetricSecurityBindingElement CreateIssuedTokenBindingElement(IssuedSecurityTokenParameters issuedTokenParameters)
1284         {
1285             if (issuedTokenParameters == null)
1286                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("issuedTokenParameters");
1287             if (issuedTokenParameters.KeyType != SecurityKeyType.SymmetricKey)
1288                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.IssuedTokenAuthenticationModeRequiresSymmetricIssuedKey));
1289             SymmetricSecurityBindingElement result = new SymmetricSecurityBindingElement(issuedTokenParameters);
1290             return result;
1291         }
1292 
1293         // If any changes are made to this method, please make sure that they are
1294         // reflected in the corresponding IsIssuedTokenForCertificateBinding() method.
CreateIssuedTokenForCertificateBindingElement(IssuedSecurityTokenParameters issuedTokenParameters)1295         static public SymmetricSecurityBindingElement CreateIssuedTokenForCertificateBindingElement(IssuedSecurityTokenParameters issuedTokenParameters)
1296         {
1297             if (issuedTokenParameters == null)
1298                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("issuedTokenParameters");
1299 
1300             SymmetricSecurityBindingElement result = new SymmetricSecurityBindingElement(
1301                 new X509SecurityTokenParameters(
1302                     X509KeyIdentifierClauseType.Thumbprint,
1303                     SecurityTokenInclusionMode.Never));
1304             if (issuedTokenParameters.KeyType == SecurityKeyType.BearerKey)
1305             {
1306                 result.EndpointSupportingTokenParameters.SignedEncrypted.Add(issuedTokenParameters);
1307                 result.MessageSecurityVersion = MessageSecurityVersion.WSSXDefault;
1308             }
1309             else
1310             {
1311                 result.EndpointSupportingTokenParameters.Endorsing.Add(issuedTokenParameters);
1312                 result.MessageSecurityVersion = MessageSecurityVersion.Default;
1313             }
1314             result.RequireSignatureConfirmation = true;
1315             return result;
1316         }
1317 
1318         // this method reverses CreateMutualCertificateBindingElement() logic
IsIssuedTokenForCertificateBinding(SecurityBindingElement sbe, out IssuedSecurityTokenParameters issuedTokenParameters)1319         internal static bool IsIssuedTokenForCertificateBinding(SecurityBindingElement sbe, out IssuedSecurityTokenParameters issuedTokenParameters)
1320         {
1321             issuedTokenParameters = null;
1322             SymmetricSecurityBindingElement ssbe = sbe as SymmetricSecurityBindingElement;
1323             if (ssbe == null)
1324                 return false;
1325 
1326             if (!ssbe.RequireSignatureConfirmation)
1327                 return false;
1328 
1329             // Do not check MessageSecurityVersion: it maybe changed by the wrapper element and gets checked later in the SecuritySection.AreBindingsMatching()
1330 
1331             X509SecurityTokenParameters x509Parameters = ssbe.ProtectionTokenParameters as X509SecurityTokenParameters;
1332             if (x509Parameters == null || x509Parameters.X509ReferenceStyle != X509KeyIdentifierClauseType.Thumbprint || x509Parameters.InclusionMode != SecurityTokenInclusionMode.Never)
1333                 return false;
1334 
1335             SupportingTokenParameters parameters = ssbe.EndpointSupportingTokenParameters;
1336             if (parameters.Signed.Count != 0 || (parameters.SignedEncrypted.Count == 0 && parameters.Endorsing.Count == 0) || parameters.SignedEndorsing.Count != 0)
1337                 return false;
1338 
1339             if ((parameters.SignedEncrypted.Count == 1) && (parameters.Endorsing.Count == 0))
1340             {
1341                 issuedTokenParameters = parameters.SignedEncrypted[0] as IssuedSecurityTokenParameters;
1342                 if (issuedTokenParameters != null && issuedTokenParameters.KeyType != SecurityKeyType.BearerKey)
1343                     return false;
1344             }
1345             else if ((parameters.Endorsing.Count == 1) && (parameters.SignedEncrypted.Count == 0))
1346             {
1347                 issuedTokenParameters = parameters.Endorsing[0] as IssuedSecurityTokenParameters;
1348                 if (issuedTokenParameters != null && (issuedTokenParameters.KeyType != SecurityKeyType.SymmetricKey && issuedTokenParameters.KeyType != SecurityKeyType.AsymmetricKey))
1349                     return false;
1350             }
1351             return (issuedTokenParameters != null);
1352         }
1353 
1354         // If any changes are made to this method, please make sure that they are
1355         // reflected in the corresponding IsIssuedTokenForSslBinding() method.
CreateIssuedTokenForSslBindingElement(IssuedSecurityTokenParameters issuedTokenParameters)1356         static public SymmetricSecurityBindingElement CreateIssuedTokenForSslBindingElement(IssuedSecurityTokenParameters issuedTokenParameters)
1357         {
1358             return CreateIssuedTokenForSslBindingElement(issuedTokenParameters, SslSecurityTokenParameters.defaultRequireCancellation);
1359         }
1360 
1361         // this method reverses CreateMutualCertificateBindingElement() logic
IsIssuedTokenForSslBinding(SecurityBindingElement sbe, out IssuedSecurityTokenParameters issuedTokenParameters)1362         internal static bool IsIssuedTokenForSslBinding(SecurityBindingElement sbe, out IssuedSecurityTokenParameters issuedTokenParameters)
1363         {
1364             return IsIssuedTokenForSslBinding(sbe, SslSecurityTokenParameters.defaultRequireCancellation, out issuedTokenParameters);
1365         }
1366 
1367         // If any changes are made to this method, please make sure that they are
1368         // reflected in the corresponding IsIssuedTokenForSslBinding() method.
CreateIssuedTokenForSslBindingElement(IssuedSecurityTokenParameters issuedTokenParameters, bool requireCancellation)1369         static public SymmetricSecurityBindingElement CreateIssuedTokenForSslBindingElement(IssuedSecurityTokenParameters issuedTokenParameters, bool requireCancellation)
1370         {
1371             if (issuedTokenParameters == null)
1372                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("issuedTokenParameters");
1373 
1374             SymmetricSecurityBindingElement result = new SymmetricSecurityBindingElement(
1375                 new SslSecurityTokenParameters(false, requireCancellation));
1376             if (issuedTokenParameters.KeyType == SecurityKeyType.BearerKey)
1377             {
1378                 result.EndpointSupportingTokenParameters.SignedEncrypted.Add(issuedTokenParameters);
1379                 result.MessageSecurityVersion = MessageSecurityVersion.WSSXDefault;
1380             }
1381             else
1382             {
1383                 result.EndpointSupportingTokenParameters.Endorsing.Add(issuedTokenParameters);
1384                 result.MessageSecurityVersion = MessageSecurityVersion.Default;
1385             }
1386             result.RequireSignatureConfirmation = true;
1387             return result;
1388         }
1389 
1390         // this method reverses CreateMutualCertificateBindingElement() logic
IsIssuedTokenForSslBinding(SecurityBindingElement sbe, bool requireCancellation, out IssuedSecurityTokenParameters issuedTokenParameters)1391         internal static bool IsIssuedTokenForSslBinding(SecurityBindingElement sbe, bool requireCancellation, out IssuedSecurityTokenParameters issuedTokenParameters)
1392         {
1393             issuedTokenParameters = null;
1394             SymmetricSecurityBindingElement ssbe = sbe as SymmetricSecurityBindingElement;
1395             if (ssbe == null)
1396                 return false;
1397 
1398             if (!ssbe.RequireSignatureConfirmation)
1399                 return false;
1400 
1401             // Do not check MessageSecurityVersion: it maybe changed by the wrapper element and gets checked later in the SecuritySection.AreBindingsMatching()
1402 
1403             SslSecurityTokenParameters sslParameters = ssbe.ProtectionTokenParameters as SslSecurityTokenParameters;
1404             if (sslParameters == null)
1405                 return false;
1406 
1407             if (sslParameters.RequireClientCertificate || sslParameters.RequireCancellation != requireCancellation)
1408                 return false;
1409 
1410             SupportingTokenParameters parameters = ssbe.EndpointSupportingTokenParameters;
1411             if (parameters.Signed.Count != 0 || (parameters.SignedEncrypted.Count == 0 && parameters.Endorsing.Count == 0) || parameters.SignedEndorsing.Count != 0)
1412                 return false;
1413 
1414             if ((parameters.SignedEncrypted.Count == 1) && (parameters.Endorsing.Count == 0))
1415             {
1416                 issuedTokenParameters = parameters.SignedEncrypted[0] as IssuedSecurityTokenParameters;
1417                 if (issuedTokenParameters != null && issuedTokenParameters.KeyType != SecurityKeyType.BearerKey)
1418                     return false;
1419             }
1420             else if ((parameters.Endorsing.Count == 1) && (parameters.SignedEncrypted.Count == 0))
1421             {
1422                 issuedTokenParameters = parameters.Endorsing[0] as IssuedSecurityTokenParameters;
1423                 if (issuedTokenParameters != null && (issuedTokenParameters.KeyType != SecurityKeyType.SymmetricKey && issuedTokenParameters.KeyType != SecurityKeyType.AsymmetricKey))
1424                     return false;
1425             }
1426             return (issuedTokenParameters != null);
1427         }
1428 
CreateUserNameForSslBindingElement()1429         static public SymmetricSecurityBindingElement CreateUserNameForSslBindingElement()
1430         {
1431             return CreateUserNameForSslBindingElement(SslSecurityTokenParameters.defaultRequireCancellation);
1432         }
1433 
1434         // If any changes are made to this method, please make sure that they are
1435         // reflected in the corresponding IsUserNameForSslBinding() method.
CreateUserNameForSslBindingElement(bool requireCancellation)1436         static public SymmetricSecurityBindingElement CreateUserNameForSslBindingElement(bool requireCancellation)
1437         {
1438             SymmetricSecurityBindingElement result = new SymmetricSecurityBindingElement(
1439                 new SslSecurityTokenParameters(false, requireCancellation));
1440             result.EndpointSupportingTokenParameters.SignedEncrypted.Add(
1441                 new UserNameSecurityTokenParameters());
1442             result.MessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11;
1443 
1444             return result;
1445         }
1446 
1447         // this method reverses CreateMutualCertificateBindingElement() logic
IsUserNameForSslBinding(SecurityBindingElement sbe, bool requireCancellation)1448         internal static bool IsUserNameForSslBinding(SecurityBindingElement sbe, bool requireCancellation)
1449         {
1450             // Do not check MessageSecurityVersion: it maybe changed by the wrapper element and gets checked later in the SecuritySection.AreBindingsMatching()
1451 
1452             SymmetricSecurityBindingElement ssbe = sbe as SymmetricSecurityBindingElement;
1453             if (ssbe == null)
1454                 return false;
1455 
1456             SupportingTokenParameters parameters = sbe.EndpointSupportingTokenParameters;
1457             if (parameters.Signed.Count != 0 || parameters.SignedEncrypted.Count != 1 || parameters.Endorsing.Count != 0 || parameters.SignedEndorsing.Count != 0)
1458                 return false;
1459 
1460             if (!(parameters.SignedEncrypted[0] is UserNameSecurityTokenParameters))
1461                 return false;
1462 
1463             SslSecurityTokenParameters sslParameters = ssbe.ProtectionTokenParameters as SslSecurityTokenParameters;
1464             if (sslParameters == null)
1465                 return false;
1466 
1467             return sslParameters.RequireCancellation == requireCancellation && !sslParameters.RequireClientCertificate;
1468         }
1469 
1470         // If any changes are made to this method, please make sure that they are
1471         // reflected in the corresponding IsUserNameOverTransportBinding() method.
CreateUserNameOverTransportBindingElement()1472         static public TransportSecurityBindingElement CreateUserNameOverTransportBindingElement()
1473         {
1474             TransportSecurityBindingElement result = new TransportSecurityBindingElement();
1475             result.EndpointSupportingTokenParameters.SignedEncrypted.Add(
1476                 new UserNameSecurityTokenParameters());
1477             result.IncludeTimestamp = true;
1478             result.LocalClientSettings.DetectReplays = false;
1479             result.LocalServiceSettings.DetectReplays = false;
1480             return result;
1481         }
1482 
1483         // this method reverses CreateMutualCertificateBindingElement() logic
IsUserNameOverTransportBinding(SecurityBindingElement sbe)1484         internal static bool IsUserNameOverTransportBinding(SecurityBindingElement sbe)
1485         {
1486             // do not check local settings: sbe.LocalServiceSettings and sbe.LocalClientSettings
1487             if (!sbe.IncludeTimestamp)
1488                 return false;
1489 
1490             if (!(sbe is TransportSecurityBindingElement))
1491                 return false;
1492 
1493             SupportingTokenParameters parameters = sbe.EndpointSupportingTokenParameters;
1494             if (parameters.Signed.Count != 0 || parameters.SignedEncrypted.Count != 1 || parameters.Endorsing.Count != 0 || parameters.SignedEndorsing.Count != 0)
1495                 return false;
1496 
1497             UserNameSecurityTokenParameters userNameParameters = parameters.SignedEncrypted[0] as UserNameSecurityTokenParameters;
1498             if (userNameParameters == null)
1499                 return false;
1500 
1501             return true;
1502         }
1503 
1504         // If any changes are made to this method, please make sure that they are
1505         // reflected in the corresponding IsCertificateOverTransportBinding() method.
CreateCertificateOverTransportBindingElement()1506         static public TransportSecurityBindingElement CreateCertificateOverTransportBindingElement()
1507         {
1508             return CreateCertificateOverTransportBindingElement(MessageSecurityVersion.Default);
1509         }
1510 
1511         // If any changes are made to this method, please make sure that they are
1512         // reflected in the corresponding IsCertificateOverTransportBinding() method.
CreateCertificateOverTransportBindingElement(MessageSecurityVersion version)1513         static public TransportSecurityBindingElement CreateCertificateOverTransportBindingElement(MessageSecurityVersion version)
1514         {
1515             if (version == null)
1516             {
1517                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("version");
1518             }
1519             X509KeyIdentifierClauseType x509ReferenceType;
1520 
1521             if (version.SecurityVersion == SecurityVersion.WSSecurity10)
1522             {
1523                 x509ReferenceType = X509KeyIdentifierClauseType.Any;
1524             }
1525             else
1526             {
1527                 x509ReferenceType = X509KeyIdentifierClauseType.Thumbprint;
1528             }
1529 
1530             TransportSecurityBindingElement result = new TransportSecurityBindingElement();
1531             X509SecurityTokenParameters x509Parameters = new X509SecurityTokenParameters(
1532                     x509ReferenceType,
1533                     SecurityTokenInclusionMode.AlwaysToRecipient,
1534                     false);
1535             result.EndpointSupportingTokenParameters.Endorsing.Add(
1536                 x509Parameters
1537                 );
1538             result.IncludeTimestamp = true;
1539             result.LocalClientSettings.DetectReplays = false;
1540             result.LocalServiceSettings.DetectReplays = false;
1541             result.MessageSecurityVersion = version;
1542 
1543             return result;
1544         }
1545 
1546         // this method reverses CreateMutualCertificateBindingElement() logic
IsCertificateOverTransportBinding(SecurityBindingElement sbe)1547         internal static bool IsCertificateOverTransportBinding(SecurityBindingElement sbe)
1548         {
1549             // do not check local settings: sbe.LocalServiceSettings and sbe.LocalClientSettings
1550             if (!sbe.IncludeTimestamp)
1551                 return false;
1552 
1553             if (!(sbe is TransportSecurityBindingElement))
1554                 return false;
1555 
1556             SupportingTokenParameters parameters = sbe.EndpointSupportingTokenParameters;
1557             if (parameters.Signed.Count != 0 || parameters.SignedEncrypted.Count != 0 || parameters.Endorsing.Count != 1 || parameters.SignedEndorsing.Count != 0)
1558                 return false;
1559 
1560             X509SecurityTokenParameters x509Parameters = parameters.Endorsing[0] as X509SecurityTokenParameters;
1561             if (x509Parameters == null)
1562                 return false;
1563 
1564             if (x509Parameters.InclusionMode != SecurityTokenInclusionMode.AlwaysToRecipient)
1565                 return false;
1566 
1567             return x509Parameters.X509ReferenceStyle == X509KeyIdentifierClauseType.Any || x509Parameters.X509ReferenceStyle == X509KeyIdentifierClauseType.Thumbprint;
1568         }
1569 
CreateKerberosOverTransportBindingElement()1570         static public TransportSecurityBindingElement CreateKerberosOverTransportBindingElement()
1571         {
1572             TransportSecurityBindingElement result = new TransportSecurityBindingElement();
1573             KerberosSecurityTokenParameters kerberosParameters = new KerberosSecurityTokenParameters();
1574             kerberosParameters.RequireDerivedKeys = false;
1575             result.EndpointSupportingTokenParameters.Endorsing.Add(
1576                 kerberosParameters);
1577             result.IncludeTimestamp = true;
1578             result.LocalClientSettings.DetectReplays = false;
1579             result.LocalServiceSettings.DetectReplays = false;
1580             result.DefaultAlgorithmSuite = SecurityAlgorithmSuite.KerberosDefault;
1581             result.SupportsExtendedProtectionPolicy = true;
1582 
1583             return result;
1584         }
1585 #if NO
1586         // this is reversing of the CreateKerberosOverTransportBindingElement() logic
IsKerberosOverTransportBinding(SecurityBindingElement sbe)1587         static bool IsKerberosOverTransportBinding(SecurityBindingElement sbe)
1588         {
1589             if (sbe.DefaultAlgorithmSuite != SecurityAlgorithmSuite.KerberosDefault)
1590                 return false;
1591 
1592             // do not check local settings: sbe.LocalServiceSettings and sbe.LocalClientSettings
1593 
1594             if (!sbe.IncludeTimestamp)
1595                 return false;
1596 
1597             if (!(sbe is TransportSecurityBindingElement))
1598                 return false;
1599 
1600             SupportingTokenParameters parameters = sbe.EndpointSupportingTokenParameters;
1601             if (parameters.Signed.Count != 0 || parameters.SignedEncrypted.Count != 0 || parameters.Endorsing.Count != 1 || parameters.SignedEndorsing.Count != 0)
1602                 return false;
1603 
1604             KerberosSecurityTokenParameters kerberosParameters = parameters.Endorsing[0] as KerberosSecurityTokenParameters;
1605             if (kerberosParameters == null)
1606                 return false;
1607 
1608             if (kerberosParameters.RequireDerivedKeys)
1609                 return false;
1610 
1611             return true;
1612         }
1613 #endif
CreateSspiNegotiationOverTransportBindingElement()1614         static public TransportSecurityBindingElement CreateSspiNegotiationOverTransportBindingElement()
1615         {
1616             return CreateSspiNegotiationOverTransportBindingElement(true);
1617         }
1618 
1619         // If any changes are made to this method, please make sure that they are
1620         // reflected in the corresponding IsSspiNegotiationOverTransportBinding() method.
CreateSspiNegotiationOverTransportBindingElement(bool requireCancellation)1621         static public TransportSecurityBindingElement CreateSspiNegotiationOverTransportBindingElement(bool requireCancellation)
1622         {
1623             TransportSecurityBindingElement result = new TransportSecurityBindingElement();
1624             SspiSecurityTokenParameters sspiParameters = new SspiSecurityTokenParameters(requireCancellation);
1625             sspiParameters.RequireDerivedKeys = false;
1626             result.EndpointSupportingTokenParameters.Endorsing.Add(
1627                 sspiParameters);
1628             result.IncludeTimestamp = true;
1629             result.LocalClientSettings.DetectReplays = false;
1630             result.LocalServiceSettings.DetectReplays = false;
1631             result.SupportsExtendedProtectionPolicy = true;
1632 
1633             return result;
1634         }
1635 
1636         // this method reverses CreateSspiNegotiationOverTransportBindingElement() logic
IsSspiNegotiationOverTransportBinding(SecurityBindingElement sbe, bool requireCancellation)1637         internal static bool IsSspiNegotiationOverTransportBinding(SecurityBindingElement sbe, bool requireCancellation)
1638         {
1639             // do not check local settings: sbe.LocalServiceSettings and sbe.LocalClientSettings
1640 
1641             if (!sbe.IncludeTimestamp)
1642                 return false;
1643 
1644             SupportingTokenParameters parameters = sbe.EndpointSupportingTokenParameters;
1645             if (parameters.Signed.Count != 0 || parameters.SignedEncrypted.Count != 0 || parameters.Endorsing.Count != 1 || parameters.SignedEndorsing.Count != 0)
1646                 return false;
1647             SspiSecurityTokenParameters sspiParameters = parameters.Endorsing[0] as SspiSecurityTokenParameters;
1648             if (sspiParameters == null)
1649                 return false;
1650 
1651             if (sspiParameters.RequireDerivedKeys)
1652                 return false;
1653 
1654             if (sspiParameters.RequireCancellation != requireCancellation)
1655                 return false;
1656 
1657             if (!(sbe is TransportSecurityBindingElement))
1658                 return false;
1659 
1660             return true;
1661         }
1662 
1663         // If any changes are made to this method, please make sure that they are
1664         // reflected in the corresponding IsIssuedTokenOverTransportBinding() method.
CreateIssuedTokenOverTransportBindingElement(IssuedSecurityTokenParameters issuedTokenParameters)1665         static public TransportSecurityBindingElement CreateIssuedTokenOverTransportBindingElement(IssuedSecurityTokenParameters issuedTokenParameters)
1666         {
1667             if (issuedTokenParameters == null)
1668                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("issuedTokenParameters");
1669 
1670             issuedTokenParameters.RequireDerivedKeys = false;
1671             TransportSecurityBindingElement result = new TransportSecurityBindingElement();
1672             if (issuedTokenParameters.KeyType == SecurityKeyType.BearerKey)
1673             {
1674                 result.EndpointSupportingTokenParameters.Signed.Add(issuedTokenParameters);
1675                 result.MessageSecurityVersion = MessageSecurityVersion.WSSXDefault;
1676             }
1677             else
1678             {
1679                 result.EndpointSupportingTokenParameters.Endorsing.Add(issuedTokenParameters);
1680                 result.MessageSecurityVersion = MessageSecurityVersion.Default;
1681             }
1682             result.LocalClientSettings.DetectReplays = false;
1683             result.LocalServiceSettings.DetectReplays = false;
1684             result.IncludeTimestamp = true;
1685 
1686             return result;
1687         }
1688 
1689         // this method reverses CreateIssuedTokenOverTransportBindingElement() logic
IsIssuedTokenOverTransportBinding(SecurityBindingElement sbe, out IssuedSecurityTokenParameters issuedTokenParameters)1690         internal static bool IsIssuedTokenOverTransportBinding(SecurityBindingElement sbe, out IssuedSecurityTokenParameters issuedTokenParameters)
1691         {
1692             issuedTokenParameters = null;
1693             if (!(sbe is TransportSecurityBindingElement))
1694                 return false;
1695 
1696             if (!sbe.IncludeTimestamp)
1697                 return false;
1698 
1699             // do not check local settings: sbe.LocalServiceSettings and sbe.LocalClientSettings
1700 
1701             SupportingTokenParameters parameters = sbe.EndpointSupportingTokenParameters;
1702             if (parameters.SignedEncrypted.Count != 0 || (parameters.Signed.Count == 0 && parameters.Endorsing.Count == 0) || parameters.SignedEndorsing.Count != 0)
1703                 return false;
1704             if ((parameters.Signed.Count == 1) && (parameters.Endorsing.Count == 0))
1705             {
1706                 issuedTokenParameters = parameters.Signed[0] as IssuedSecurityTokenParameters;
1707                 if (issuedTokenParameters != null && issuedTokenParameters.KeyType != SecurityKeyType.BearerKey)
1708                     return false;
1709             }
1710             else if ((parameters.Endorsing.Count == 1) && (parameters.Signed.Count == 0))
1711             {
1712                 issuedTokenParameters = parameters.Endorsing[0] as IssuedSecurityTokenParameters;
1713                 if (issuedTokenParameters != null && (issuedTokenParameters.KeyType != SecurityKeyType.SymmetricKey && issuedTokenParameters.KeyType != SecurityKeyType.AsymmetricKey))
1714                     return false;
1715             }
1716             if (issuedTokenParameters == null)
1717                 return false;
1718             if (issuedTokenParameters.RequireDerivedKeys)
1719                 return false;
1720 
1721             return true;
1722         }
1723 
1724         // If any changes are made to this method, please make sure that they are
1725         // reflected in the corresponding IsSecureConversationBinding() method.
CreateSecureConversationBindingElement(SecurityBindingElement bootstrapSecurity)1726         static public SecurityBindingElement CreateSecureConversationBindingElement(SecurityBindingElement bootstrapSecurity)
1727         {
1728             return CreateSecureConversationBindingElement(bootstrapSecurity, SecureConversationSecurityTokenParameters.defaultRequireCancellation, null);
1729         }
1730 
1731         // this method reverses CreateSecureConversationBindingElement() logic
IsSecureConversationBinding(SecurityBindingElement sbe, out SecurityBindingElement bootstrapSecurity)1732         internal static bool IsSecureConversationBinding(SecurityBindingElement sbe, out SecurityBindingElement bootstrapSecurity)
1733         {
1734             return IsSecureConversationBinding(sbe, SecureConversationSecurityTokenParameters.defaultRequireCancellation, out bootstrapSecurity);
1735         }
1736 
CreateSecureConversationBindingElement(SecurityBindingElement bootstrapSecurity, bool requireCancellation)1737         static public SecurityBindingElement CreateSecureConversationBindingElement(SecurityBindingElement bootstrapSecurity, bool requireCancellation)
1738         {
1739             return CreateSecureConversationBindingElement(bootstrapSecurity, requireCancellation, null);
1740         }
1741 
1742         // If any changes are made to this method, please make sure that they are
1743         // reflected in the corresponding IsSecureConversationBinding() method.
CreateSecureConversationBindingElement(SecurityBindingElement bootstrapSecurity, bool requireCancellation, ChannelProtectionRequirements bootstrapProtectionRequirements)1744         static public SecurityBindingElement CreateSecureConversationBindingElement(SecurityBindingElement bootstrapSecurity, bool requireCancellation, ChannelProtectionRequirements bootstrapProtectionRequirements)
1745         {
1746             if (bootstrapSecurity == null)
1747                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("bootstrapBinding");
1748 
1749             SecurityBindingElement result;
1750 
1751             if (bootstrapSecurity is TransportSecurityBindingElement)
1752             {
1753                 // there is no need to do replay detection or key derivation for transport bindings
1754                 TransportSecurityBindingElement primary = new TransportSecurityBindingElement();
1755                 SecureConversationSecurityTokenParameters scParameters = new SecureConversationSecurityTokenParameters(
1756                         bootstrapSecurity,
1757                         requireCancellation,
1758                         bootstrapProtectionRequirements);
1759                 scParameters.RequireDerivedKeys = false;
1760                 primary.EndpointSupportingTokenParameters.Endorsing.Add(
1761                     scParameters);
1762                 primary.LocalClientSettings.DetectReplays = false;
1763                 primary.LocalServiceSettings.DetectReplays = false;
1764                 primary.IncludeTimestamp = true;
1765                 result = primary;
1766             }
1767             else // Symmetric- or AsymmetricSecurityBindingElement
1768             {
1769                 SymmetricSecurityBindingElement primary = new SymmetricSecurityBindingElement(
1770                     new SecureConversationSecurityTokenParameters(
1771                         bootstrapSecurity,
1772                         requireCancellation,
1773                         bootstrapProtectionRequirements));
1774                 // there is no need for signature confirmation on the steady state binding
1775                 primary.RequireSignatureConfirmation = false;
1776                 result = primary;
1777             }
1778 
1779             return result;
1780         }
1781 
1782         // this method reverses CreateSecureConversationBindingElement() logic
IsSecureConversationBinding(SecurityBindingElement sbe, bool requireCancellation, out SecurityBindingElement bootstrapSecurity)1783         internal static bool IsSecureConversationBinding(SecurityBindingElement sbe, bool requireCancellation, out SecurityBindingElement bootstrapSecurity)
1784         {
1785             bootstrapSecurity = null;
1786             SymmetricSecurityBindingElement ssbe = sbe as SymmetricSecurityBindingElement;
1787             if (ssbe != null)
1788             {
1789                 if (ssbe.RequireSignatureConfirmation)
1790                     return false;
1791 
1792                 SecureConversationSecurityTokenParameters parameters = ssbe.ProtectionTokenParameters as SecureConversationSecurityTokenParameters;
1793                 if (parameters == null)
1794                     return false;
1795                 if (parameters.RequireCancellation != requireCancellation)
1796                     return false;
1797                 bootstrapSecurity = parameters.BootstrapSecurityBindingElement;
1798             }
1799             else
1800             {
1801                 if (!sbe.IncludeTimestamp)
1802                     return false;
1803 
1804                 // do not check local settings: sbe.LocalServiceSettings and sbe.LocalClientSettings
1805 
1806                 if (!(sbe is TransportSecurityBindingElement))
1807                     return false;
1808 
1809                 SupportingTokenParameters parameters = sbe.EndpointSupportingTokenParameters;
1810                 if (parameters.Signed.Count != 0 || parameters.SignedEncrypted.Count != 0 || parameters.Endorsing.Count != 1 || parameters.SignedEndorsing.Count != 0)
1811                     return false;
1812                 SecureConversationSecurityTokenParameters scParameters = parameters.Endorsing[0] as SecureConversationSecurityTokenParameters;
1813                 if (scParameters == null)
1814                     return false;
1815 
1816                 if (scParameters.RequireCancellation != requireCancellation)
1817                     return false;
1818 
1819                 bootstrapSecurity = scParameters.BootstrapSecurityBindingElement;
1820 
1821             }
1822 
1823             if (bootstrapSecurity != null && bootstrapSecurity.SecurityHeaderLayout != SecurityProtocolFactory.defaultSecurityHeaderLayout)
1824                 return false;
1825 
1826             return bootstrapSecurity != null;
1827         }
1828 
ToString()1829         public override string ToString()
1830         {
1831             StringBuilder sb = new StringBuilder();
1832 
1833             sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "{0}:", this.GetType().ToString()));
1834             sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "DefaultAlgorithmSuite: {0}", this.defaultAlgorithmSuite.ToString()));
1835             sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "IncludeTimestamp: {0}", this.includeTimestamp.ToString()));
1836             sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "KeyEntropyMode: {0}", this.keyEntropyMode.ToString()));
1837             sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "MessageSecurityVersion: {0}", this.MessageSecurityVersion.ToString()));
1838             sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "SecurityHeaderLayout: {0}", this.securityHeaderLayout.ToString()));
1839             sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "ProtectTokens: {0}", this.protectTokens.ToString()));
1840             sb.AppendLine("EndpointSupportingTokenParameters:");
1841             sb.AppendLine("  " + this.EndpointSupportingTokenParameters.ToString().Trim().Replace("\n", "\n  "));
1842             sb.AppendLine("OptionalEndpointSupportingTokenParameters:");
1843             sb.AppendLine("  " + this.OptionalEndpointSupportingTokenParameters.ToString().Trim().Replace("\n", "\n  "));
1844             if (this.operationSupportingTokenParameters.Count == 0)
1845             {
1846                 sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "OperationSupportingTokenParameters: none"));
1847             }
1848             else
1849             {
1850                 foreach (string requestAction in this.OperationSupportingTokenParameters.Keys)
1851                 {
1852                     sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "OperationSupportingTokenParameters[\"{0}\"]:", requestAction));
1853                     sb.AppendLine("  " + this.OperationSupportingTokenParameters[requestAction].ToString().Trim().Replace("\n", "\n  "));
1854                 }
1855             }
1856             if (this.optionalOperationSupportingTokenParameters.Count == 0)
1857             {
1858                 sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "OptionalOperationSupportingTokenParameters: none"));
1859             }
1860             else
1861             {
1862                 foreach (string requestAction in this.OptionalOperationSupportingTokenParameters.Keys)
1863                 {
1864                     sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "OptionalOperationSupportingTokenParameters[\"{0}\"]:", requestAction));
1865                     sb.AppendLine("  " + this.OptionalOperationSupportingTokenParameters[requestAction].ToString().Trim().Replace("\n", "\n  "));
1866                 }
1867             }
1868 
1869             return sb.ToString().Trim();
1870         }
1871 
1872 
ComputeProtectionRequirements(SecurityBindingElement security, BindingParameterCollection parameterCollection, BindingElementCollection bindingElements, bool isForService)1873         internal static ChannelProtectionRequirements ComputeProtectionRequirements(SecurityBindingElement security, BindingParameterCollection parameterCollection, BindingElementCollection bindingElements, bool isForService)
1874         {
1875             if (parameterCollection == null)
1876                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("parameterCollection");
1877             if (bindingElements == null)
1878                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("bindingElements");
1879             if (security == null)
1880             {
1881                 return null;
1882             }
1883 
1884             ChannelProtectionRequirements result = null;
1885             if ((security is SymmetricSecurityBindingElement) || (security is AsymmetricSecurityBindingElement))
1886             {
1887                 result = new ChannelProtectionRequirements();
1888                 ChannelProtectionRequirements contractRequirements = parameterCollection.Find<ChannelProtectionRequirements>();
1889 
1890                 if (contractRequirements != null)
1891                     result.Add(contractRequirements);
1892 
1893                 AddBindingProtectionRequirements(result, bindingElements, !isForService);
1894             }
1895 
1896             return result;
1897         }
1898 
AddBindingProtectionRequirements(ChannelProtectionRequirements requirements, BindingElementCollection bindingElements, bool isForChannel)1899         static void AddBindingProtectionRequirements(ChannelProtectionRequirements requirements, BindingElementCollection bindingElements, bool isForChannel)
1900         {
1901             // Gather custom requirements from bindingElements
1902             CustomBinding binding = new CustomBinding(bindingElements);
1903             BindingContext context = new BindingContext(binding, new BindingParameterCollection());
1904             // In theory, we can just do
1905             //     context.GetInnerProperty<ChannelProtectionRequirements>()
1906             // but that relies on each binding element to correctly union-up its own requirements with
1907             // those of the rest of the stack.  So instead, we ask each BE individually, and we do the
1908             // work of combining the results.  This protects us against this scenario: someone authors "FooBE"
1909             // with a a GetProperty implementation that always returns null (oops), and puts FooBE on the
1910             // top of the stack, and so FooBE "hides" important protection requirements that inner BEs
1911             // require, resulting in an insecure binding.
1912             foreach (BindingElement bindingElement in bindingElements)
1913             {
1914                 if (bindingElement != null)
1915                 {
1916                     // ask each element individually for its requirements
1917                     context.RemainingBindingElements.Clear();
1918                     context.RemainingBindingElements.Add(bindingElement);
1919                     ChannelProtectionRequirements s = context.GetInnerProperty<ChannelProtectionRequirements>();
1920                     if (s != null)
1921                     {
1922                         //if (isForChannel)
1923                         //{
1924                         //    requirements.Add(s.CreateInverse());
1925                         //}
1926                         //else
1927                         //{
1928                             requirements.Add(s);
1929                         //}
1930                     }
1931                 }
1932             }
1933         }
1934 
ApplyAuditBehaviorSettings(BindingContext context, SecurityProtocolFactory factory)1935         internal void ApplyAuditBehaviorSettings(BindingContext context, SecurityProtocolFactory factory)
1936         {
1937             ServiceSecurityAuditBehavior auditBehavior = context.BindingParameters.Find<ServiceSecurityAuditBehavior>();
1938             if (auditBehavior != null)
1939             {
1940                 factory.AuditLogLocation = auditBehavior.AuditLogLocation;
1941                 factory.SuppressAuditFailure = auditBehavior.SuppressAuditFailure;
1942                 factory.ServiceAuthorizationAuditLevel = auditBehavior.ServiceAuthorizationAuditLevel;
1943                 factory.MessageAuthenticationAuditLevel = auditBehavior.MessageAuthenticationAuditLevel;
1944             }
1945             else
1946             {
1947                 factory.AuditLogLocation = ServiceSecurityAuditBehavior.defaultAuditLogLocation;
1948                 factory.SuppressAuditFailure = ServiceSecurityAuditBehavior.defaultSuppressAuditFailure;
1949                 factory.ServiceAuthorizationAuditLevel = ServiceSecurityAuditBehavior.defaultServiceAuthorizationAuditLevel;
1950                 factory.MessageAuthenticationAuditLevel = ServiceSecurityAuditBehavior.defaultMessageAuthenticationAuditLevel;
1951             }
1952         }
1953 
IsMatch(BindingElement b)1954         internal override bool IsMatch(BindingElement b)
1955         {
1956             if (b == null)
1957                 return false;
1958 
1959             SecurityBindingElement security = b as SecurityBindingElement;
1960             if (security == null)
1961                 return false;
1962             return SecurityElement.AreBindingsMatching(this, security);
1963         }
1964 
AddAssertionIfNotNull(PolicyConversionContext policyContext, XmlElement assertion)1965         static void AddAssertionIfNotNull(PolicyConversionContext policyContext, XmlElement assertion)
1966         {
1967             if (policyContext != null && assertion != null)
1968             {
1969                 policyContext.GetBindingAssertions().Add(assertion);
1970             }
1971         }
1972 
AddAssertionIfNotNull(PolicyConversionContext policyContext, Collection<XmlElement> assertions)1973         static void AddAssertionIfNotNull(PolicyConversionContext policyContext, Collection<XmlElement> assertions)
1974         {
1975             if (policyContext != null && assertions != null)
1976             {
1977                 PolicyAssertionCollection existingAssertions = policyContext.GetBindingAssertions();
1978                 for (int i = 0; i < assertions.Count; ++i)
1979                     existingAssertions.Add(assertions[i]);
1980             }
1981         }
1982 
AddAssertionIfNotNull(PolicyConversionContext policyContext, OperationDescription operation, XmlElement assertion)1983         static void AddAssertionIfNotNull(PolicyConversionContext policyContext, OperationDescription operation, XmlElement assertion)
1984         {
1985             if (policyContext != null && assertion != null)
1986             {
1987                 policyContext.GetOperationBindingAssertions(operation).Add(assertion);
1988             }
1989         }
1990 
AddAssertionIfNotNull(PolicyConversionContext policyContext, OperationDescription operation, Collection<XmlElement> assertions)1991         static void AddAssertionIfNotNull(PolicyConversionContext policyContext, OperationDescription operation, Collection<XmlElement> assertions)
1992         {
1993             if (policyContext != null && assertions != null)
1994             {
1995                 PolicyAssertionCollection existingAssertions = policyContext.GetOperationBindingAssertions(operation);
1996                 for (int i = 0; i < assertions.Count; ++i)
1997                     existingAssertions.Add(assertions[i]);
1998             }
1999         }
2000 
AddAssertionIfNotNull(PolicyConversionContext policyContext, MessageDescription message, XmlElement assertion)2001         static void AddAssertionIfNotNull(PolicyConversionContext policyContext, MessageDescription message, XmlElement assertion)
2002         {
2003             if (policyContext != null && assertion != null)
2004             {
2005                 policyContext.GetMessageBindingAssertions(message).Add(assertion);
2006             }
2007         }
2008 
AddAssertionIfNotNull(PolicyConversionContext policyContext, FaultDescription message, XmlElement assertion)2009         static void AddAssertionIfNotNull(PolicyConversionContext policyContext, FaultDescription message, XmlElement assertion)
2010         {
2011             if (policyContext != null && assertion != null)
2012             {
2013                 policyContext.GetFaultBindingAssertions(message).Add(assertion);
2014             }
2015         }
2016 
ExportPolicy(MetadataExporter exporter, PolicyConversionContext context)2017         internal static void ExportPolicy(MetadataExporter exporter, PolicyConversionContext context)
2018         {
2019             if (exporter == null)
2020             {
2021                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("exporter");
2022             }
2023 
2024             if (context == null)
2025             {
2026                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
2027             }
2028 
2029             SecurityTraceRecordHelper.TraceExportChannelBindingEntry();
2030 
2031             SecurityBindingElement binding = null;
2032             ITransportTokenAssertionProvider transportTokenAssertionProvider = null;
2033             BindingElementCollection bindingElementsBelowSecurity = new BindingElementCollection();
2034             if ((context != null) && (context.BindingElements != null))
2035             {
2036                 foreach (BindingElement be in context.BindingElements)
2037                 {
2038                     if (be is SecurityBindingElement)
2039                     {
2040                         binding = (SecurityBindingElement)be;
2041                     }
2042                     else
2043                     {
2044                         if (binding != null || be is MessageEncodingBindingElement || be is ITransportTokenAssertionProvider)
2045                         {
2046                             bindingElementsBelowSecurity.Add(be);
2047                         }
2048                         if (be is ITransportTokenAssertionProvider)
2049                         {
2050                             transportTokenAssertionProvider = (ITransportTokenAssertionProvider)be;
2051                         }
2052                     }
2053                 }
2054             }
2055 
2056             // this is used when exporting bootstrap policy for secure conversation in SecurityPolicy11.CreateWsspBootstrapPolicyAssertion
2057             exporter.State[SecurityPolicyStrings.SecureConversationBootstrapBindingElementsBelowSecurityKey] = bindingElementsBelowSecurity;
2058 
2059             bool hasCompletedSuccessfully = false;
2060             try
2061             {
2062                 if (binding is SymmetricSecurityBindingElement)
2063                 {
2064                     ExportSymmetricSecurityBindingElement((SymmetricSecurityBindingElement)binding, exporter, context);
2065                     ExportOperationScopeSupportingTokensPolicy(binding, exporter, context);
2066                     ExportMessageScopeProtectionPolicy(binding, exporter, context);
2067                 }
2068                 else if (binding is AsymmetricSecurityBindingElement)
2069                 {
2070                     ExportAsymmetricSecurityBindingElement((AsymmetricSecurityBindingElement)binding, exporter, context);
2071                     ExportOperationScopeSupportingTokensPolicy(binding, exporter, context);
2072                     ExportMessageScopeProtectionPolicy(binding, exporter, context);
2073                 }
2074 
2075                 hasCompletedSuccessfully = true;
2076             }
2077             finally
2078             {
2079                 try
2080                 {
2081                     exporter.State.Remove(SecurityPolicyStrings.SecureConversationBootstrapBindingElementsBelowSecurityKey);
2082                 }
2083                 catch (Exception e)
2084                 {
2085                     // Always immediately rethrow fatal exceptions.
2086                     if (hasCompletedSuccessfully || Fx.IsFatal(e)) throw;
2087                 }
2088             }
2089         }
2090 
ExportPolicyForTransportTokenAssertionProviders(MetadataExporter exporter, PolicyConversionContext context)2091         internal static void ExportPolicyForTransportTokenAssertionProviders(MetadataExporter exporter, PolicyConversionContext context)
2092         {
2093             if (exporter == null)
2094             {
2095                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("exporter");
2096             }
2097 
2098             if (context == null)
2099             {
2100                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
2101             }
2102 
2103             SecurityTraceRecordHelper.TraceExportChannelBindingEntry();
2104 
2105             SecurityBindingElement binding = null;
2106             ITransportTokenAssertionProvider transportTokenAssertionProvider = null;
2107             BindingElementCollection bindingElementsBelowSecurity = new BindingElementCollection();
2108             if ((context != null) && (context.BindingElements != null))
2109             {
2110                 foreach (BindingElement be in context.BindingElements)
2111                 {
2112                     if (be is SecurityBindingElement)
2113                     {
2114                         binding = (SecurityBindingElement)be;
2115                     }
2116                     else
2117                     {
2118                         if (binding != null || be is MessageEncodingBindingElement || be is ITransportTokenAssertionProvider)
2119                         {
2120                             bindingElementsBelowSecurity.Add(be);
2121                         }
2122                         if (be is ITransportTokenAssertionProvider)
2123                         {
2124                             transportTokenAssertionProvider = (ITransportTokenAssertionProvider)be;
2125                         }
2126                     }
2127                 }
2128             }
2129 
2130             // this is used when exporting bootstrap policy for secure conversation in SecurityPolicy11.CreateWsspBootstrapPolicyAssertion
2131             exporter.State[SecurityPolicyStrings.SecureConversationBootstrapBindingElementsBelowSecurityKey] = bindingElementsBelowSecurity;
2132 
2133             bool hasCompletedSuccessfully = false;
2134             try
2135             {
2136                 if (binding is TransportSecurityBindingElement)
2137                 {
2138                     if (transportTokenAssertionProvider == null && !binding.AllowInsecureTransport)
2139                     {
2140                         throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ExportOfBindingWithTransportSecurityBindingElementAndNoTransportSecurityNotSupported)));
2141                     }
2142 
2143                     ExportTransportSecurityBindingElement((TransportSecurityBindingElement)binding, transportTokenAssertionProvider, exporter, context);
2144                     ExportOperationScopeSupportingTokensPolicy(binding, exporter, context);
2145                 }
2146                 else if (transportTokenAssertionProvider != null)
2147                 {
2148                     TransportSecurityBindingElement dummyTransportBindingElement = new TransportSecurityBindingElement();
2149                     if (binding == null)
2150                     {
2151                         dummyTransportBindingElement.IncludeTimestamp = false;
2152                     }
2153 
2154                     // In order to generate the right sp assertion without SBE.
2155                     // scenario: WSxHttpBinding with SecurityMode.Transport.
2156                     // See CSD 3105 for detail
2157                     HttpsTransportBindingElement httpsBinding = transportTokenAssertionProvider as HttpsTransportBindingElement;
2158                     if (httpsBinding != null && httpsBinding.MessageSecurityVersion != null)
2159                     {
2160                         dummyTransportBindingElement.MessageSecurityVersion = httpsBinding.MessageSecurityVersion;
2161                     }
2162 
2163                     ExportTransportSecurityBindingElement(dummyTransportBindingElement, transportTokenAssertionProvider, exporter, context);
2164                 }
2165 
2166                 hasCompletedSuccessfully = true;
2167             }
2168             finally
2169             {
2170                 try
2171                 {
2172                     exporter.State.Remove(SecurityPolicyStrings.SecureConversationBootstrapBindingElementsBelowSecurityKey);
2173                 }
2174                 catch (Exception e)
2175                 {
2176                     // Always immediately rethrow fatal exceptions.
2177                     if (hasCompletedSuccessfully || Fx.IsFatal(e)) throw;
2178                 }
2179             }
2180         }
2181 
2182         //
2183         // We will emit the wssp trust 10 assertion for all the case except for the basic http binding
2184         // created through the BasicHttpBinding class.  The reason for this exception is to allow better
2185         // interop with third party when the third party doesn't understand the trust ----erion
2186         //
RequiresWsspTrust(SecurityBindingElement sbe)2187         static bool RequiresWsspTrust(SecurityBindingElement sbe)
2188         {
2189             if (sbe == null)
2190                 return false;
2191 
2192             return !(sbe.doNotEmitTrust);
2193         }
2194 
ExportAsymmetricSecurityBindingElement(AsymmetricSecurityBindingElement binding, MetadataExporter exporter, PolicyConversionContext policyContext)2195         static void ExportAsymmetricSecurityBindingElement(AsymmetricSecurityBindingElement binding, MetadataExporter exporter, PolicyConversionContext policyContext)
2196         {
2197             WSSecurityPolicy sp = WSSecurityPolicy.GetSecurityPolicyDriver(binding.MessageSecurityVersion);
2198 
2199             AddAssertionIfNotNull(policyContext, sp.CreateWsspAsymmetricBindingAssertion(exporter, policyContext, binding));
2200 
2201             AddAssertionIfNotNull(policyContext, sp.CreateWsspSupportingTokensAssertion(
2202                 exporter,
2203                 binding.EndpointSupportingTokenParameters.Signed,
2204                 binding.EndpointSupportingTokenParameters.SignedEncrypted,
2205                 binding.EndpointSupportingTokenParameters.Endorsing,
2206                 binding.EndpointSupportingTokenParameters.SignedEndorsing,
2207                 binding.OptionalEndpointSupportingTokenParameters.Signed,
2208                 binding.OptionalEndpointSupportingTokenParameters.SignedEncrypted,
2209                 binding.OptionalEndpointSupportingTokenParameters.Endorsing,
2210                 binding.OptionalEndpointSupportingTokenParameters.SignedEndorsing));
2211 
2212             AddAssertionIfNotNull(policyContext, sp.CreateWsspWssAssertion(exporter, binding));
2213 
2214             if (RequiresWsspTrust(binding))
2215             {
2216                 AddAssertionIfNotNull(policyContext, sp.CreateWsspTrustAssertion(exporter, binding.KeyEntropyMode));
2217             }
2218         }
2219 
ExportTransportSecurityBindingElement(TransportSecurityBindingElement binding, ITransportTokenAssertionProvider transportTokenAssertionProvider, MetadataExporter exporter, PolicyConversionContext policyContext)2220         static void ExportTransportSecurityBindingElement(TransportSecurityBindingElement binding, ITransportTokenAssertionProvider transportTokenAssertionProvider, MetadataExporter exporter, PolicyConversionContext policyContext)
2221         {
2222             WSSecurityPolicy sp = WSSecurityPolicy.GetSecurityPolicyDriver(binding.MessageSecurityVersion);
2223 
2224             if (transportTokenAssertionProvider == null && binding.AllowInsecureTransport)
2225             {
2226                 if ((policyContext != null) && (policyContext.BindingElements != null))
2227                 {
2228                     foreach (BindingElement be in policyContext.BindingElements)
2229                     {
2230                         if (be is HttpTransportBindingElement)
2231                         {
2232                             transportTokenAssertionProvider = new HttpsTransportBindingElement();
2233                             break;
2234                         }
2235 
2236                         if (be is TcpTransportBindingElement)
2237                         {
2238                             transportTokenAssertionProvider = new SslStreamSecurityBindingElement();
2239                             break;
2240                         }
2241                     }
2242                 }
2243             }
2244 
2245             XmlElement transportTokenAssertion = transportTokenAssertionProvider.GetTransportTokenAssertion();
2246 
2247             if (transportTokenAssertion == null)
2248             {
2249                 if (transportTokenAssertionProvider is HttpsTransportBindingElement)
2250                 {
2251                     transportTokenAssertion = sp.CreateWsspHttpsTokenAssertion(exporter, (HttpsTransportBindingElement)transportTokenAssertionProvider);
2252                 }
2253 
2254                 if (transportTokenAssertion == null)
2255                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.NoTransportTokenAssertionProvided, transportTokenAssertionProvider.GetType().ToString())));
2256             }
2257 
2258             AddressingVersion addressingVersion = AddressingVersion.WSAddressing10;
2259             MessageEncodingBindingElement messageEncoderBindingElement = policyContext.BindingElements.Find<MessageEncodingBindingElement>();
2260             if (messageEncoderBindingElement != null)
2261             {
2262                 addressingVersion = messageEncoderBindingElement.MessageVersion.Addressing;
2263             }
2264 
2265             AddAssertionIfNotNull(policyContext, sp.CreateWsspTransportBindingAssertion(exporter, binding, transportTokenAssertion));
2266 
2267             Collection<XmlElement> supportingTokenAssertions = sp.CreateWsspSupportingTokensAssertion(
2268                 exporter,
2269                 binding.EndpointSupportingTokenParameters.Signed,
2270                 binding.EndpointSupportingTokenParameters.SignedEncrypted,
2271                 binding.EndpointSupportingTokenParameters.Endorsing,
2272                 binding.EndpointSupportingTokenParameters.SignedEndorsing,
2273                 binding.OptionalEndpointSupportingTokenParameters.Signed,
2274                 binding.OptionalEndpointSupportingTokenParameters.SignedEncrypted,
2275                 binding.OptionalEndpointSupportingTokenParameters.Endorsing,
2276                 binding.OptionalEndpointSupportingTokenParameters.SignedEndorsing,
2277                 addressingVersion);
2278 
2279             AddAssertionIfNotNull(policyContext, supportingTokenAssertions);
2280 
2281             if (supportingTokenAssertions.Count > 0
2282                 || HasEndorsingSupportingTokensAtOperationScope(binding))
2283             {
2284                 AddAssertionIfNotNull(policyContext, sp.CreateWsspWssAssertion(exporter, binding));
2285                 if (RequiresWsspTrust(binding))
2286                 {
2287                     AddAssertionIfNotNull(policyContext, sp.CreateWsspTrustAssertion(exporter, binding.KeyEntropyMode));
2288                 }
2289             }
2290         }
2291 
HasEndorsingSupportingTokensAtOperationScope(SecurityBindingElement binding)2292         static bool HasEndorsingSupportingTokensAtOperationScope(SecurityBindingElement binding)
2293         {
2294             foreach (SupportingTokenParameters r in binding.OperationSupportingTokenParameters.Values)
2295             {
2296                 if (r.Endorsing.Count > 0 || r.SignedEndorsing.Count > 0)
2297                 {
2298                     return true;
2299                 }
2300             }
2301 
2302             return false;
2303         }
2304 
ExportSymmetricSecurityBindingElement(SymmetricSecurityBindingElement binding, MetadataExporter exporter, PolicyConversionContext policyContext)2305         static void ExportSymmetricSecurityBindingElement(SymmetricSecurityBindingElement binding, MetadataExporter exporter, PolicyConversionContext policyContext)
2306         {
2307             WSSecurityPolicy sp = WSSecurityPolicy.GetSecurityPolicyDriver(binding.MessageSecurityVersion);
2308 
2309             AddAssertionIfNotNull(policyContext, sp.CreateWsspSymmetricBindingAssertion(exporter, policyContext, binding));
2310 
2311             AddAssertionIfNotNull(policyContext, sp.CreateWsspSupportingTokensAssertion(
2312                 exporter,
2313                 binding.EndpointSupportingTokenParameters.Signed,
2314                 binding.EndpointSupportingTokenParameters.SignedEncrypted,
2315                 binding.EndpointSupportingTokenParameters.Endorsing,
2316                 binding.EndpointSupportingTokenParameters.SignedEndorsing,
2317                 binding.OptionalEndpointSupportingTokenParameters.Signed,
2318                 binding.OptionalEndpointSupportingTokenParameters.SignedEncrypted,
2319                 binding.OptionalEndpointSupportingTokenParameters.Endorsing,
2320                 binding.OptionalEndpointSupportingTokenParameters.SignedEndorsing));
2321 
2322             AddAssertionIfNotNull(policyContext, sp.CreateWsspWssAssertion(exporter, binding));
2323 
2324             if (RequiresWsspTrust(binding))
2325             {
2326                 AddAssertionIfNotNull(policyContext, sp.CreateWsspTrustAssertion(exporter, binding.KeyEntropyMode));
2327             }
2328         }
2329 
ExportMessageScopeProtectionPolicy(SecurityBindingElement security, MetadataExporter exporter, PolicyConversionContext policyContext)2330         static void ExportMessageScopeProtectionPolicy(SecurityBindingElement security, MetadataExporter exporter, PolicyConversionContext policyContext)
2331         {
2332             BindingParameterCollection bindingParameters = new BindingParameterCollection();
2333             bindingParameters.Add(ChannelProtectionRequirements.CreateFromContract(policyContext.Contract, policyContext.BindingElements.Find<SecurityBindingElement>().GetIndividualProperty<ISecurityCapabilities>(), false));
2334             ChannelProtectionRequirements protectionRequirements = SecurityBindingElement.ComputeProtectionRequirements(security, bindingParameters, policyContext.BindingElements, true);
2335             protectionRequirements.MakeReadOnly();
2336 
2337             WSSecurityPolicy sp = WSSecurityPolicy.GetSecurityPolicyDriver(security.MessageSecurityVersion);
2338 
2339             foreach (OperationDescription operation in policyContext.Contract.Operations)
2340             {
2341                 // export policy for application messages
2342                 foreach (MessageDescription message in operation.Messages)
2343                 {
2344                     MessagePartSpecification parts;
2345                     ScopedMessagePartSpecification scopedParts;
2346 
2347                     // integrity
2348                     if (message.Direction == MessageDirection.Input)
2349                     {
2350                         scopedParts = protectionRequirements.IncomingSignatureParts;
2351                     }
2352                     else
2353                     {
2354                         scopedParts = protectionRequirements.OutgoingSignatureParts;
2355                     }
2356 
2357                     if (scopedParts.TryGetParts(message.Action, out parts))
2358                     {
2359                         AddAssertionIfNotNull(policyContext, message, sp.CreateWsspSignedPartsAssertion(parts));
2360                     }
2361 
2362                     // confidentiality
2363                     if (message.Direction == MessageDirection.Input)
2364                     {
2365                         scopedParts = protectionRequirements.IncomingEncryptionParts;
2366                     }
2367                     else
2368                     {
2369                         scopedParts = protectionRequirements.OutgoingEncryptionParts;
2370                     }
2371 
2372                     if (scopedParts.TryGetParts(message.Action, out parts))
2373                     {
2374                         AddAssertionIfNotNull(policyContext, message, sp.CreateWsspEncryptedPartsAssertion(parts));
2375                     }
2376                 }
2377 
2378                 // export policy for faults
2379                 foreach (FaultDescription fault in operation.Faults)
2380                 {
2381                     MessagePartSpecification parts;
2382 
2383                     // integrity
2384                     if (protectionRequirements.OutgoingSignatureParts.TryGetParts(fault.Action, out parts))
2385                     {
2386                         AddAssertionIfNotNull(policyContext, fault, sp.CreateWsspSignedPartsAssertion(parts));
2387                     }
2388 
2389                     // confidentiality
2390                     if (protectionRequirements.OutgoingEncryptionParts.TryGetParts(fault.Action, out parts))
2391                     {
2392                         AddAssertionIfNotNull(policyContext, fault, sp.CreateWsspEncryptedPartsAssertion(parts));
2393                     }
2394                 }
2395             }
2396         }
2397 
ExportOperationScopeSupportingTokensPolicy(SecurityBindingElement binding, MetadataExporter exporter, PolicyConversionContext policyContext)2398         static void ExportOperationScopeSupportingTokensPolicy(SecurityBindingElement binding, MetadataExporter exporter, PolicyConversionContext policyContext)
2399         {
2400             WSSecurityPolicy sp = WSSecurityPolicy.GetSecurityPolicyDriver(binding.MessageSecurityVersion);
2401 
2402             if (binding.OperationSupportingTokenParameters.Count == 0 && binding.OptionalOperationSupportingTokenParameters.Count == 0)
2403             {
2404                 return;
2405             }
2406 
2407             foreach (OperationDescription operation in policyContext.Contract.Operations)
2408             {
2409                 foreach (MessageDescription message in operation.Messages)
2410                 {
2411 
2412                     if (message.Direction == MessageDirection.Input)
2413                     {
2414                         SupportingTokenParameters requirements = null;
2415                         SupportingTokenParameters optionalRequirements = null;
2416 
2417                         if (binding.OperationSupportingTokenParameters.ContainsKey(message.Action))
2418                         {
2419                             requirements = binding.OperationSupportingTokenParameters[message.Action];
2420                         }
2421                         if (binding.OptionalOperationSupportingTokenParameters.ContainsKey(message.Action))
2422                         {
2423                             optionalRequirements = binding.OptionalOperationSupportingTokenParameters[message.Action];
2424                         }
2425 
2426                         if (requirements == null && optionalRequirements == null)
2427                         {
2428                             continue;
2429                         }
2430 
2431                         AddAssertionIfNotNull(policyContext, operation, sp.CreateWsspSupportingTokensAssertion(
2432                             exporter,
2433                             requirements == null ? null : requirements.Signed,
2434                             requirements == null ? null : requirements.SignedEncrypted,
2435                             requirements == null ? null : requirements.Endorsing,
2436                             requirements == null ? null : requirements.SignedEndorsing,
2437                             optionalRequirements == null ? null : optionalRequirements.Signed,
2438                             optionalRequirements == null ? null : optionalRequirements.SignedEncrypted,
2439                             optionalRequirements == null ? null : optionalRequirements.Endorsing,
2440                             optionalRequirements == null ? null : optionalRequirements.SignedEndorsing));
2441                     }
2442                 }
2443             }
2444         }
2445     }
2446 }
2447