1 //------------------------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation. All rights reserved.
3 //------------------------------------------------------------------------------
5 namespace System.ServiceModel.Configuration
7 using System.Collections.Generic;
8 using System.Collections.ObjectModel;
9 using System.ComponentModel;
10 using System.Configuration;
11 using System.IdentityModel.Tokens;
13 using System.ServiceModel.Channels;
14 using System.ServiceModel.Security;
15 using System.ServiceModel.Security.Tokens;
19 public partial class SecurityElementBase : BindingElementExtensionElement
21 internal const AuthenticationMode defaultAuthenticationMode = AuthenticationMode.SspiNegotiated;
23 // if you add another variable, make sure to adjust: CopyFrom and UnMerge methods.
24 SecurityBindingElement failedSecurityBindingElement = null;
25 bool willX509IssuerReferenceAssertionBeWritten;
26 SecurityKeyType templateKeyType = IssuedSecurityTokenParameters.defaultKeyType;
28 internal SecurityElementBase()
32 internal bool HasImportFailed { get { return this.failedSecurityBindingElement != null; } }
34 internal bool IsSecurityElementBootstrap { get; set; } // Used in serialization path to optimize Xml representation
36 [ConfigurationProperty(ConfigurationStrings.DefaultAlgorithmSuite, DefaultValue = SecurityBindingElement.defaultAlgorithmSuiteString)]
37 [TypeConverter(typeof(SecurityAlgorithmSuiteConverter))]
38 public SecurityAlgorithmSuite DefaultAlgorithmSuite
40 get { return (SecurityAlgorithmSuite)base[ConfigurationStrings.DefaultAlgorithmSuite]; }
41 set { base[ConfigurationStrings.DefaultAlgorithmSuite] = value; }
44 [ConfigurationProperty(ConfigurationStrings.AllowSerializedSigningTokenOnReply, DefaultValue = AsymmetricSecurityBindingElement.defaultAllowSerializedSigningTokenOnReply)]
45 public bool AllowSerializedSigningTokenOnReply
47 get { return (bool)base[ConfigurationStrings.AllowSerializedSigningTokenOnReply]; }
48 set { base[ConfigurationStrings.AllowSerializedSigningTokenOnReply] = value; }
51 [ConfigurationProperty(ConfigurationStrings.EnableUnsecuredResponse, DefaultValue = SecurityBindingElement.defaultEnableUnsecuredResponse)]
52 public bool EnableUnsecuredResponse
54 get { return (bool)base[ConfigurationStrings.EnableUnsecuredResponse]; }
55 set { base[ConfigurationStrings.EnableUnsecuredResponse] = value; }
58 [ConfigurationProperty(ConfigurationStrings.AuthenticationMode, DefaultValue = defaultAuthenticationMode)]
59 [ServiceModelEnumValidator(typeof(AuthenticationModeHelper))]
60 public AuthenticationMode AuthenticationMode
62 get { return (AuthenticationMode)base[ConfigurationStrings.AuthenticationMode]; }
63 set { base[ConfigurationStrings.AuthenticationMode] = value; }
66 public override Type BindingElementType
68 get { return typeof(SecurityBindingElement); }
71 [ConfigurationProperty(ConfigurationStrings.RequireDerivedKeys, DefaultValue = SecurityTokenParameters.defaultRequireDerivedKeys)]
72 public bool RequireDerivedKeys
74 get { return (bool)base[ConfigurationStrings.RequireDerivedKeys]; }
75 set { base[ConfigurationStrings.RequireDerivedKeys] = value; }
78 [ConfigurationProperty(ConfigurationStrings.SecurityHeaderLayout, DefaultValue = SecurityProtocolFactory.defaultSecurityHeaderLayout)]
79 [ServiceModelEnumValidator(typeof(SecurityHeaderLayoutHelper))]
80 public SecurityHeaderLayout SecurityHeaderLayout
82 get { return (SecurityHeaderLayout)base[ConfigurationStrings.SecurityHeaderLayout]; }
83 set { base[ConfigurationStrings.SecurityHeaderLayout] = value; }
86 [ConfigurationProperty(ConfigurationStrings.IncludeTimestamp, DefaultValue = SecurityBindingElement.defaultIncludeTimestamp)]
87 public bool IncludeTimestamp
89 get { return (bool)base[ConfigurationStrings.IncludeTimestamp]; }
90 set { base[ConfigurationStrings.IncludeTimestamp] = value; }
93 [ConfigurationProperty(ConfigurationStrings.AllowInsecureTransport, DefaultValue = SecurityBindingElement.defaultAllowInsecureTransport)]
94 public bool AllowInsecureTransport
96 get { return (bool)base[ConfigurationStrings.AllowInsecureTransport]; }
97 set { base[ConfigurationStrings.AllowInsecureTransport] = value; }
100 [ConfigurationProperty(ConfigurationStrings.KeyEntropyMode, DefaultValue = System.ServiceModel.Security.AcceleratedTokenProvider.defaultKeyEntropyMode)]
101 [ServiceModelEnumValidator(typeof(SecurityKeyEntropyModeHelper))]
102 public SecurityKeyEntropyMode KeyEntropyMode
104 get { return (SecurityKeyEntropyMode)base[ConfigurationStrings.KeyEntropyMode]; }
105 set { base[ConfigurationStrings.KeyEntropyMode] = value; }
108 [ConfigurationProperty(ConfigurationStrings.IssuedTokenParameters)]
109 public IssuedTokenParametersElement IssuedTokenParameters
111 get { return (IssuedTokenParametersElement)base[ConfigurationStrings.IssuedTokenParameters]; }
114 [ConfigurationProperty(ConfigurationStrings.LocalClientSettings)]
115 public LocalClientSecuritySettingsElement LocalClientSettings
117 get { return (LocalClientSecuritySettingsElement)base[ConfigurationStrings.LocalClientSettings]; }
120 [ConfigurationProperty(ConfigurationStrings.LocalServiceSettings)]
121 public LocalServiceSecuritySettingsElement LocalServiceSettings
123 get { return (LocalServiceSecuritySettingsElement)base[ConfigurationStrings.LocalServiceSettings]; }
126 [ConfigurationProperty(ConfigurationStrings.MessageProtectionOrder, DefaultValue = SecurityBindingElement.defaultMessageProtectionOrder)]
127 [ServiceModelEnumValidator(typeof(MessageProtectionOrderHelper))]
128 public MessageProtectionOrder MessageProtectionOrder
130 get { return (MessageProtectionOrder)base[ConfigurationStrings.MessageProtectionOrder]; }
131 set { base[ConfigurationStrings.MessageProtectionOrder] = value; }
134 [ConfigurationProperty(ConfigurationStrings.ProtectTokens, DefaultValue = false)]
135 public bool ProtectTokens
137 get { return (bool)base[ConfigurationStrings.ProtectTokens]; }
138 set { base[ConfigurationStrings.ProtectTokens] = value; }
141 [ConfigurationProperty(ConfigurationStrings.MessageSecurityVersion, DefaultValue = ConfigurationStrings.Default)]
142 [TypeConverter(typeof(MessageSecurityVersionConverter))]
143 public MessageSecurityVersion MessageSecurityVersion
145 get { return (MessageSecurityVersion)base[ConfigurationStrings.MessageSecurityVersion]; }
146 set { base[ConfigurationStrings.MessageSecurityVersion] = value; }
149 [ConfigurationProperty(ConfigurationStrings.RequireSecurityContextCancellation, DefaultValue = SecureConversationSecurityTokenParameters.defaultRequireCancellation)]
150 public bool RequireSecurityContextCancellation
152 get { return (bool)base[ConfigurationStrings.RequireSecurityContextCancellation]; }
153 set { base[ConfigurationStrings.RequireSecurityContextCancellation] = value; }
156 [ConfigurationProperty(ConfigurationStrings.RequireSignatureConfirmation, DefaultValue = SecurityBindingElement.defaultRequireSignatureConfirmation)]
157 public bool RequireSignatureConfirmation
159 get { return (bool)base[ConfigurationStrings.RequireSignatureConfirmation]; }
160 set { base[ConfigurationStrings.RequireSignatureConfirmation] = value; }
163 [ConfigurationProperty(ConfigurationStrings.CanRenewSecurityContextToken, DefaultValue = SecureConversationSecurityTokenParameters.defaultCanRenewSession)]
164 public bool CanRenewSecurityContextToken
166 get { return (bool)base[ConfigurationStrings.CanRenewSecurityContextToken]; }
167 set { base[ConfigurationStrings.CanRenewSecurityContextToken] = value; }
170 public override void ApplyConfiguration(BindingElement bindingElement)
172 base.ApplyConfiguration(bindingElement);
174 SecurityBindingElement sbe = (SecurityBindingElement)bindingElement;
176 #pragma warning disable 56506 //Microsoft; base.CopyFrom() checks for 'from' being null
177 if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.DefaultAlgorithmSuite].ValueOrigin)
178 sbe.DefaultAlgorithmSuite = this.DefaultAlgorithmSuite;
179 if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.IncludeTimestamp].ValueOrigin)
180 sbe.IncludeTimestamp = this.IncludeTimestamp;
181 if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.MessageSecurityVersion].ValueOrigin)
182 sbe.MessageSecurityVersion = this.MessageSecurityVersion;
183 if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.KeyEntropyMode].ValueOrigin)
184 sbe.KeyEntropyMode = this.KeyEntropyMode;
185 if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.SecurityHeaderLayout].ValueOrigin)
186 sbe.SecurityHeaderLayout = this.SecurityHeaderLayout;
187 if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.RequireDerivedKeys].ValueOrigin)
188 sbe.SetKeyDerivation(this.RequireDerivedKeys);
189 if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.AllowInsecureTransport].ValueOrigin)
190 sbe.AllowInsecureTransport = this.AllowInsecureTransport;
191 if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.EnableUnsecuredResponse].ValueOrigin)
192 sbe.EnableUnsecuredResponse = this.EnableUnsecuredResponse;
193 if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.ProtectTokens].ValueOrigin)
194 sbe.ProtectTokens = this.ProtectTokens;
195 #pragma warning restore
197 SymmetricSecurityBindingElement ssbe = sbe as SymmetricSecurityBindingElement;
201 if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.MessageProtectionOrder].ValueOrigin)
202 ssbe.MessageProtectionOrder = this.MessageProtectionOrder;
203 if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.RequireSignatureConfirmation].ValueOrigin)
204 ssbe.RequireSignatureConfirmation = this.RequireSignatureConfirmation;
205 SecureConversationSecurityTokenParameters scParameters = ssbe.ProtectionTokenParameters as SecureConversationSecurityTokenParameters;
206 if (scParameters != null)
208 scParameters.CanRenewSession = this.CanRenewSecurityContextToken;
212 AsymmetricSecurityBindingElement asbe = sbe as AsymmetricSecurityBindingElement;
216 if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.MessageProtectionOrder].ValueOrigin)
217 asbe.MessageProtectionOrder = this.MessageProtectionOrder;
218 if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.RequireSignatureConfirmation].ValueOrigin)
219 asbe.RequireSignatureConfirmation = this.RequireSignatureConfirmation;
220 if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.AllowSerializedSigningTokenOnReply].ValueOrigin)
221 asbe.AllowSerializedSigningTokenOnReply = this.AllowSerializedSigningTokenOnReply;
224 TransportSecurityBindingElement tsbe = sbe as TransportSecurityBindingElement;
228 if (tsbe.EndpointSupportingTokenParameters.Endorsing.Count == 1)
230 SecureConversationSecurityTokenParameters scParameters = tsbe.EndpointSupportingTokenParameters.Endorsing[0] as SecureConversationSecurityTokenParameters;
231 if (scParameters != null)
233 scParameters.CanRenewSession = this.CanRenewSecurityContextToken;
238 if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.LocalClientSettings].ValueOrigin)
240 this.LocalClientSettings.ApplyConfiguration(sbe.LocalClientSettings);
243 if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.LocalServiceSettings].ValueOrigin)
245 this.LocalServiceSettings.ApplyConfiguration(sbe.LocalServiceSettings);
249 public override void CopyFrom(ServiceModelExtensionElement from)
253 SecurityElementBase source = (SecurityElementBase)from;
255 if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.AllowSerializedSigningTokenOnReply].ValueOrigin)
256 this.AllowSerializedSigningTokenOnReply = source.AllowSerializedSigningTokenOnReply;
257 if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.DefaultAlgorithmSuite].ValueOrigin)
258 this.DefaultAlgorithmSuite = source.DefaultAlgorithmSuite;
259 if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.EnableUnsecuredResponse].ValueOrigin)
260 this.EnableUnsecuredResponse = source.EnableUnsecuredResponse;
261 if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.AllowInsecureTransport].ValueOrigin)
262 this.AllowInsecureTransport = source.AllowInsecureTransport;
263 if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.RequireDerivedKeys].ValueOrigin)
264 this.RequireDerivedKeys = source.RequireDerivedKeys;
265 if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.IncludeTimestamp].ValueOrigin)
266 this.IncludeTimestamp = source.IncludeTimestamp;
267 if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.IssuedTokenParameters].ValueOrigin)
268 this.IssuedTokenParameters.Copy(source.IssuedTokenParameters);
269 if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.MessageProtectionOrder].ValueOrigin)
270 this.MessageProtectionOrder = source.MessageProtectionOrder;
271 if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.ProtectTokens].ValueOrigin)
272 this.ProtectTokens = source.ProtectTokens;
273 if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.MessageSecurityVersion].ValueOrigin)
274 this.MessageSecurityVersion = source.MessageSecurityVersion;
275 if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.RequireSignatureConfirmation].ValueOrigin)
276 this.RequireSignatureConfirmation = source.RequireSignatureConfirmation;
277 if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.RequireSecurityContextCancellation].ValueOrigin)
278 this.RequireSecurityContextCancellation = source.RequireSecurityContextCancellation;
279 if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.CanRenewSecurityContextToken].ValueOrigin)
280 this.CanRenewSecurityContextToken = source.CanRenewSecurityContextToken;
281 if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.KeyEntropyMode].ValueOrigin)
282 this.KeyEntropyMode = source.KeyEntropyMode;
283 if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.SecurityHeaderLayout].ValueOrigin)
284 this.SecurityHeaderLayout = source.SecurityHeaderLayout;
285 if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.LocalClientSettings].ValueOrigin)
286 this.LocalClientSettings.CopyFrom(source.LocalClientSettings);
287 if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.LocalServiceSettings].ValueOrigin)
288 this.LocalServiceSettings.CopyFrom(source.LocalServiceSettings);
290 this.failedSecurityBindingElement = source.failedSecurityBindingElement;
291 this.willX509IssuerReferenceAssertionBeWritten = source.willX509IssuerReferenceAssertionBeWritten;
294 protected internal override BindingElement CreateBindingElement()
296 return this.CreateBindingElement(false);
299 protected internal virtual BindingElement CreateBindingElement(bool createTemplateOnly)
301 SecurityBindingElement result;
302 switch (this.AuthenticationMode)
304 case AuthenticationMode.AnonymousForCertificate:
305 result = SecurityBindingElement.CreateAnonymousForCertificateBindingElement();
307 case AuthenticationMode.AnonymousForSslNegotiated:
308 result = SecurityBindingElement.CreateSslNegotiationBindingElement(false, this.RequireSecurityContextCancellation);
310 case AuthenticationMode.CertificateOverTransport:
311 result = SecurityBindingElement.CreateCertificateOverTransportBindingElement(this.MessageSecurityVersion);
313 case AuthenticationMode.IssuedToken:
314 result = SecurityBindingElement.CreateIssuedTokenBindingElement(this.IssuedTokenParameters.Create(createTemplateOnly, this.templateKeyType));
316 case AuthenticationMode.IssuedTokenForCertificate:
317 result = SecurityBindingElement.CreateIssuedTokenForCertificateBindingElement(this.IssuedTokenParameters.Create(createTemplateOnly, this.templateKeyType));
319 case AuthenticationMode.IssuedTokenForSslNegotiated:
320 result = SecurityBindingElement.CreateIssuedTokenForSslBindingElement(this.IssuedTokenParameters.Create(createTemplateOnly, this.templateKeyType), this.RequireSecurityContextCancellation);
322 case AuthenticationMode.IssuedTokenOverTransport:
323 result = SecurityBindingElement.CreateIssuedTokenOverTransportBindingElement(this.IssuedTokenParameters.Create(createTemplateOnly, this.templateKeyType));
325 case AuthenticationMode.Kerberos:
326 result = SecurityBindingElement.CreateKerberosBindingElement();
328 case AuthenticationMode.KerberosOverTransport:
329 result = SecurityBindingElement.CreateKerberosOverTransportBindingElement();
331 case AuthenticationMode.MutualCertificateDuplex:
332 result = SecurityBindingElement.CreateMutualCertificateDuplexBindingElement(this.MessageSecurityVersion);
334 case AuthenticationMode.MutualCertificate:
335 result = SecurityBindingElement.CreateMutualCertificateBindingElement(this.MessageSecurityVersion);
337 case AuthenticationMode.MutualSslNegotiated:
338 result = SecurityBindingElement.CreateSslNegotiationBindingElement(true, this.RequireSecurityContextCancellation);
340 case AuthenticationMode.SspiNegotiated:
341 result = SecurityBindingElement.CreateSspiNegotiationBindingElement(this.RequireSecurityContextCancellation);
343 case AuthenticationMode.UserNameForCertificate:
344 result = SecurityBindingElement.CreateUserNameForCertificateBindingElement();
346 case AuthenticationMode.UserNameForSslNegotiated:
347 result = SecurityBindingElement.CreateUserNameForSslBindingElement(this.RequireSecurityContextCancellation);
349 case AuthenticationMode.UserNameOverTransport:
350 result = SecurityBindingElement.CreateUserNameOverTransportBindingElement();
352 case AuthenticationMode.SspiNegotiatedOverTransport:
353 result = SecurityBindingElement.CreateSspiNegotiationOverTransportBindingElement(this.RequireSecurityContextCancellation);
356 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidEnumArgumentException("AuthenticationMode", (int)this.AuthenticationMode, typeof(AuthenticationMode)));
359 this.ApplyConfiguration(result);
364 protected void AddBindingTemplate(Dictionary<AuthenticationMode, SecurityBindingElement> bindingTemplates, AuthenticationMode mode)
366 this.AuthenticationMode = mode;
369 bindingTemplates[mode] = (SecurityBindingElement)this.CreateBindingElement(true);
371 #pragma warning suppress 56500 // covered by FxCOP
381 static bool AreTokenParametersMatching(SecurityTokenParameters p1, SecurityTokenParameters p2, bool skipRequireDerivedKeysComparison, bool exactMessageSecurityVersion)
383 if (p1 == null || p2 == null)
386 if (p1.GetType() != p2.GetType())
389 if (p1.InclusionMode != p2.InclusionMode)
392 if (skipRequireDerivedKeysComparison == false && p1.RequireDerivedKeys != p2.RequireDerivedKeys)
395 if (p1.ReferenceStyle != p2.ReferenceStyle)
398 // mutual ssl and anonymous ssl differ in the client cert requirement
399 if (p1 is SslSecurityTokenParameters)
401 if (((SslSecurityTokenParameters)p1).RequireClientCertificate != ((SslSecurityTokenParameters)p2).RequireClientCertificate)
404 else if (p1 is SecureConversationSecurityTokenParameters)
406 SecureConversationSecurityTokenParameters sc1 = (SecureConversationSecurityTokenParameters)p1;
407 SecureConversationSecurityTokenParameters sc2 = (SecureConversationSecurityTokenParameters)p2;
409 if (sc1.RequireCancellation != sc2.RequireCancellation)
412 if (sc1.CanRenewSession != sc2.CanRenewSession)
416 if (!AreBindingsMatching(sc1.BootstrapSecurityBindingElement, sc2.BootstrapSecurityBindingElement, exactMessageSecurityVersion))
419 else if (p1 is IssuedSecurityTokenParameters)
421 if (((IssuedSecurityTokenParameters)p1).KeyType != ((IssuedSecurityTokenParameters)p2).KeyType)
428 static bool AreTokenParameterCollectionsMatching(Collection<SecurityTokenParameters> c1, Collection<SecurityTokenParameters> c2, bool exactMessageSecurityVersion)
430 if (c1.Count != c2.Count)
433 for (int i = 0; i < c1.Count; i++)
434 if (!AreTokenParametersMatching(c1[i], c2[i], true, exactMessageSecurityVersion))
440 internal static bool AreBindingsMatching(SecurityBindingElement b1, SecurityBindingElement b2)
442 return AreBindingsMatching(b1, b2, true);
445 internal static bool AreBindingsMatching(SecurityBindingElement b1, SecurityBindingElement b2, bool exactMessageSecurityVersion)
447 if (b1 == null || b2 == null)
450 if (b1.GetType() != b2.GetType())
453 if (b1.MessageSecurityVersion != b2.MessageSecurityVersion)
455 // exactMessageSecurityVersion meant that BSP mismatch could be ignored
456 if (exactMessageSecurityVersion)
459 if (b1.MessageSecurityVersion.SecurityVersion != b2.MessageSecurityVersion.SecurityVersion
460 || b1.MessageSecurityVersion.TrustVersion != b2.MessageSecurityVersion.TrustVersion
461 || b1.MessageSecurityVersion.SecureConversationVersion != b2.MessageSecurityVersion.SecureConversationVersion
462 || b1.MessageSecurityVersion.SecurityPolicyVersion != b2.MessageSecurityVersion.SecurityPolicyVersion)
468 if (b1.SecurityHeaderLayout != b2.SecurityHeaderLayout)
471 if (b1.DefaultAlgorithmSuite != b2.DefaultAlgorithmSuite)
474 if (b1.IncludeTimestamp != b2.IncludeTimestamp)
477 if (b1.SecurityHeaderLayout != b2.SecurityHeaderLayout)
480 if (b1.KeyEntropyMode != b2.KeyEntropyMode)
483 if (!AreTokenParameterCollectionsMatching(b1.EndpointSupportingTokenParameters.Endorsing, b2.EndpointSupportingTokenParameters.Endorsing, exactMessageSecurityVersion))
486 if (!AreTokenParameterCollectionsMatching(b1.EndpointSupportingTokenParameters.SignedEncrypted, b2.EndpointSupportingTokenParameters.SignedEncrypted, exactMessageSecurityVersion))
489 if (!AreTokenParameterCollectionsMatching(b1.EndpointSupportingTokenParameters.Signed, b2.EndpointSupportingTokenParameters.Signed, exactMessageSecurityVersion))
492 if (!AreTokenParameterCollectionsMatching(b1.EndpointSupportingTokenParameters.SignedEndorsing, b2.EndpointSupportingTokenParameters.SignedEndorsing, exactMessageSecurityVersion))
495 if (b1.OperationSupportingTokenParameters.Count != b2.OperationSupportingTokenParameters.Count)
498 foreach (KeyValuePair<string, SupportingTokenParameters> operation1 in b1.OperationSupportingTokenParameters)
500 if (!b2.OperationSupportingTokenParameters.ContainsKey(operation1.Key))
503 SupportingTokenParameters stp2 = b2.OperationSupportingTokenParameters[operation1.Key];
505 if (!AreTokenParameterCollectionsMatching(operation1.Value.Endorsing, stp2.Endorsing, exactMessageSecurityVersion))
508 if (!AreTokenParameterCollectionsMatching(operation1.Value.SignedEncrypted, stp2.SignedEncrypted, exactMessageSecurityVersion))
511 if (!AreTokenParameterCollectionsMatching(operation1.Value.Signed, stp2.Signed, exactMessageSecurityVersion))
514 if (!AreTokenParameterCollectionsMatching(operation1.Value.SignedEndorsing, stp2.SignedEndorsing, exactMessageSecurityVersion))
518 SymmetricSecurityBindingElement ssbe1 = b1 as SymmetricSecurityBindingElement;
521 SymmetricSecurityBindingElement ssbe2 = (SymmetricSecurityBindingElement)b2;
523 if (ssbe1.MessageProtectionOrder != ssbe2.MessageProtectionOrder)
526 if (!AreTokenParametersMatching(ssbe1.ProtectionTokenParameters, ssbe2.ProtectionTokenParameters, false, exactMessageSecurityVersion))
530 AsymmetricSecurityBindingElement asbe1 = b1 as AsymmetricSecurityBindingElement;
533 AsymmetricSecurityBindingElement asbe2 = (AsymmetricSecurityBindingElement)b2;
535 if (asbe1.MessageProtectionOrder != asbe2.MessageProtectionOrder)
538 if (asbe1.RequireSignatureConfirmation != asbe2.RequireSignatureConfirmation)
541 if (!AreTokenParametersMatching(asbe1.InitiatorTokenParameters, asbe2.InitiatorTokenParameters, true, exactMessageSecurityVersion)
542 || !AreTokenParametersMatching(asbe1.RecipientTokenParameters, asbe2.RecipientTokenParameters, true, exactMessageSecurityVersion))
549 protected virtual void AddBindingTemplates(Dictionary<AuthenticationMode, SecurityBindingElement> bindingTemplates)
551 AddBindingTemplate(bindingTemplates, AuthenticationMode.AnonymousForCertificate);
552 AddBindingTemplate(bindingTemplates, AuthenticationMode.AnonymousForSslNegotiated);
553 AddBindingTemplate(bindingTemplates, AuthenticationMode.CertificateOverTransport);
554 if (this.templateKeyType == SecurityKeyType.SymmetricKey)
556 AddBindingTemplate(bindingTemplates, AuthenticationMode.IssuedToken);
558 AddBindingTemplate(bindingTemplates, AuthenticationMode.IssuedTokenForCertificate);
559 AddBindingTemplate(bindingTemplates, AuthenticationMode.IssuedTokenForSslNegotiated);
560 AddBindingTemplate(bindingTemplates, AuthenticationMode.IssuedTokenOverTransport);
561 AddBindingTemplate(bindingTemplates, AuthenticationMode.Kerberos);
562 AddBindingTemplate(bindingTemplates, AuthenticationMode.KerberosOverTransport);
563 AddBindingTemplate(bindingTemplates, AuthenticationMode.MutualCertificate);
564 AddBindingTemplate(bindingTemplates, AuthenticationMode.MutualCertificateDuplex);
565 AddBindingTemplate(bindingTemplates, AuthenticationMode.MutualSslNegotiated);
566 AddBindingTemplate(bindingTemplates, AuthenticationMode.SspiNegotiated);
567 AddBindingTemplate(bindingTemplates, AuthenticationMode.UserNameForCertificate);
568 AddBindingTemplate(bindingTemplates, AuthenticationMode.UserNameForSslNegotiated);
569 AddBindingTemplate(bindingTemplates, AuthenticationMode.UserNameOverTransport);
570 AddBindingTemplate(bindingTemplates, AuthenticationMode.SspiNegotiatedOverTransport);
573 bool TryInitializeAuthenticationMode(SecurityBindingElement sbe)
577 if (sbe.OperationSupportingTokenParameters.Count > 0)
581 SetIssuedTokenKeyType(sbe);
583 Dictionary<AuthenticationMode, SecurityBindingElement> bindingTemplates = new Dictionary<AuthenticationMode, SecurityBindingElement>();
584 this.AddBindingTemplates(bindingTemplates);
587 foreach (AuthenticationMode mode in bindingTemplates.Keys)
589 SecurityBindingElement candidate = bindingTemplates[mode];
590 if (AreBindingsMatching(sbe, candidate))
592 this.AuthenticationMode = mode;
602 void SetIssuedTokenKeyType(SecurityBindingElement sbe)
604 // Set the keyType for building the template for IssuedToken binding.
605 // The reason is the different supporting token is defined depending on keyType.
606 if (sbe.EndpointSupportingTokenParameters.Endorsing.Count > 0 &&
607 sbe.EndpointSupportingTokenParameters.Endorsing[0] is IssuedSecurityTokenParameters)
609 this.templateKeyType = ((IssuedSecurityTokenParameters)sbe.EndpointSupportingTokenParameters.Endorsing[0]).KeyType;
611 else if (sbe.EndpointSupportingTokenParameters.Signed.Count > 0 &&
612 sbe.EndpointSupportingTokenParameters.Signed[0] is IssuedSecurityTokenParameters)
614 this.templateKeyType = ((IssuedSecurityTokenParameters)sbe.EndpointSupportingTokenParameters.Signed[0]).KeyType;
616 else if (sbe.EndpointSupportingTokenParameters.SignedEncrypted.Count > 0 &&
617 sbe.EndpointSupportingTokenParameters.SignedEncrypted[0] is IssuedSecurityTokenParameters)
619 this.templateKeyType = ((IssuedSecurityTokenParameters)sbe.EndpointSupportingTokenParameters.SignedEncrypted[0]).KeyType;
623 this.templateKeyType = IssuedSecurityTokenParameters.defaultKeyType;
627 protected virtual void InitializeNestedTokenParameterSettings(SecurityTokenParameters sp, bool initializeNestedBindings)
629 if (sp is SspiSecurityTokenParameters)
630 SetPropertyValueIfNotDefaultValue(ConfigurationStrings.RequireSecurityContextCancellation, ((SspiSecurityTokenParameters)sp).RequireCancellation);
631 else if (sp is SslSecurityTokenParameters)
632 SetPropertyValueIfNotDefaultValue(ConfigurationStrings.RequireSecurityContextCancellation, ((SslSecurityTokenParameters)sp).RequireCancellation);
633 else if (sp is IssuedSecurityTokenParameters)
634 this.IssuedTokenParameters.InitializeFrom((IssuedSecurityTokenParameters)sp, initializeNestedBindings);
637 internal void InitializeFrom(BindingElement bindingElement, bool initializeNestedBindings)
639 if (bindingElement == null)
641 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("bindingElement");
643 SecurityBindingElement sbe = (SecurityBindingElement)bindingElement;
645 // Can't apply default value optimization to properties like DefaultAlgorithmSuite because the defaults are computed at runtime and don't match config defaults
646 this.DefaultAlgorithmSuite = sbe.DefaultAlgorithmSuite;
647 this.IncludeTimestamp = sbe.IncludeTimestamp;
648 if (sbe.MessageSecurityVersion != MessageSecurityVersion.Default)
650 this.MessageSecurityVersion = sbe.MessageSecurityVersion;
652 // Still safe to apply the optimization here because the runtime defaults are the same as config defaults in all cases
653 SetPropertyValueIfNotDefaultValue(ConfigurationStrings.KeyEntropyMode, sbe.KeyEntropyMode);
654 SetPropertyValueIfNotDefaultValue(ConfigurationStrings.SecurityHeaderLayout, sbe.SecurityHeaderLayout);
655 SetPropertyValueIfNotDefaultValue(ConfigurationStrings.ProtectTokens, sbe.ProtectTokens);
656 SetPropertyValueIfNotDefaultValue(ConfigurationStrings.AllowInsecureTransport, sbe.AllowInsecureTransport);
657 SetPropertyValueIfNotDefaultValue(ConfigurationStrings.EnableUnsecuredResponse, sbe.EnableUnsecuredResponse);
660 Nullable<bool> requireDerivedKeys = new Nullable<bool>();
662 if (sbe.EndpointSupportingTokenParameters.Endorsing.Count == 1)
664 this.InitializeNestedTokenParameterSettings(sbe.EndpointSupportingTokenParameters.Endorsing[0], initializeNestedBindings);
666 else if (sbe.EndpointSupportingTokenParameters.SignedEncrypted.Count == 1)
668 this.InitializeNestedTokenParameterSettings(sbe.EndpointSupportingTokenParameters.SignedEncrypted[0], initializeNestedBindings);
670 else if (sbe.EndpointSupportingTokenParameters.Signed.Count == 1)
672 this.InitializeNestedTokenParameterSettings(sbe.EndpointSupportingTokenParameters.Signed[0], initializeNestedBindings);
675 bool initializationFailure = false;
677 foreach (SecurityTokenParameters t in sbe.EndpointSupportingTokenParameters.Endorsing)
679 if (t.HasAsymmetricKey == false)
681 if (requireDerivedKeys.HasValue && requireDerivedKeys.Value != t.RequireDerivedKeys)
682 initializationFailure = true;
684 requireDerivedKeys = t.RequireDerivedKeys;
688 SymmetricSecurityBindingElement ssbe = sbe as SymmetricSecurityBindingElement;
691 SetPropertyValueIfNotDefaultValue(ConfigurationStrings.MessageProtectionOrder, ssbe.MessageProtectionOrder);
692 this.RequireSignatureConfirmation = ssbe.RequireSignatureConfirmation;
693 if ( ssbe.ProtectionTokenParameters != null )
695 this.InitializeNestedTokenParameterSettings( ssbe.ProtectionTokenParameters, initializeNestedBindings );
696 if ( requireDerivedKeys.HasValue && requireDerivedKeys.Value != ssbe.ProtectionTokenParameters.RequireDerivedKeys )
697 initializationFailure = true;
699 requireDerivedKeys = ssbe.ProtectionTokenParameters.RequireDerivedKeys;
705 AsymmetricSecurityBindingElement asbe = sbe as AsymmetricSecurityBindingElement;
708 SetPropertyValueIfNotDefaultValue(ConfigurationStrings.MessageProtectionOrder, asbe.MessageProtectionOrder);
709 this.RequireSignatureConfirmation = asbe.RequireSignatureConfirmation;
710 if ( asbe.InitiatorTokenParameters != null )
712 this.InitializeNestedTokenParameterSettings( asbe.InitiatorTokenParameters, initializeNestedBindings );
715 // Copy the derived key token bool flag from the token parameters. The token parameter was set from
716 // importing WSDL during SecurityBindingElementImporter.ImportPolicy time
718 if ( requireDerivedKeys.HasValue && requireDerivedKeys.Value != asbe.InitiatorTokenParameters.RequireDerivedKeys )
719 initializationFailure = true;
721 requireDerivedKeys = asbe.InitiatorTokenParameters.RequireDerivedKeys;
726 this.willX509IssuerReferenceAssertionBeWritten = DoesSecurityBindingElementContainClauseTypeofIssuerSerial(sbe);
727 this.RequireDerivedKeys = requireDerivedKeys.GetValueOrDefault(SecurityTokenParameters.defaultRequireDerivedKeys);
728 this.LocalClientSettings.InitializeFrom(sbe.LocalClientSettings);
729 this.LocalServiceSettings.InitializeFrom(sbe.LocalServiceSettings);
731 if (!initializationFailure)
732 initializationFailure = !this.TryInitializeAuthenticationMode(sbe);
734 if (initializationFailure)
735 this.failedSecurityBindingElement = sbe;
738 protected internal override void InitializeFrom(BindingElement bindingElement)
740 this.InitializeFrom(bindingElement, true);
744 /// returns true if one of the xxxSupportingTokenParameters.yyy is of type IssuerSerial
746 /// <param name="sbe"></param>
747 /// <returns></returns>
748 bool DoesSecurityBindingElementContainClauseTypeofIssuerSerial( SecurityBindingElement sbe )
753 if ( sbe is SymmetricSecurityBindingElement )
755 X509SecurityTokenParameters tokenParamameters = ( (SymmetricSecurityBindingElement)sbe ).ProtectionTokenParameters as X509SecurityTokenParameters;
756 if ( tokenParamameters != null && tokenParamameters.X509ReferenceStyle == X509KeyIdentifierClauseType.IssuerSerial )
759 else if ( sbe is AsymmetricSecurityBindingElement )
761 X509SecurityTokenParameters initiatorParamameters = ( (AsymmetricSecurityBindingElement)sbe ).InitiatorTokenParameters as X509SecurityTokenParameters;
762 if ( initiatorParamameters != null && initiatorParamameters.X509ReferenceStyle == X509KeyIdentifierClauseType.IssuerSerial )
765 X509SecurityTokenParameters recepientParamameters = ( (AsymmetricSecurityBindingElement)sbe ).RecipientTokenParameters as X509SecurityTokenParameters;
766 if ( recepientParamameters != null && recepientParamameters.X509ReferenceStyle == X509KeyIdentifierClauseType.IssuerSerial )
770 if ( DoesX509TokenParametersContainClauseTypeofIssuerSerial( sbe.EndpointSupportingTokenParameters.Endorsing ) )
773 if ( DoesX509TokenParametersContainClauseTypeofIssuerSerial( sbe.EndpointSupportingTokenParameters.Signed ) )
776 if ( DoesX509TokenParametersContainClauseTypeofIssuerSerial( sbe.EndpointSupportingTokenParameters.SignedEncrypted ) )
779 if ( DoesX509TokenParametersContainClauseTypeofIssuerSerial( sbe.EndpointSupportingTokenParameters.SignedEndorsing ) )
782 if ( DoesX509TokenParametersContainClauseTypeofIssuerSerial( sbe.OptionalEndpointSupportingTokenParameters.Endorsing ) )
785 if ( DoesX509TokenParametersContainClauseTypeofIssuerSerial( sbe.OptionalEndpointSupportingTokenParameters.Signed ) )
788 if ( DoesX509TokenParametersContainClauseTypeofIssuerSerial( sbe.OptionalEndpointSupportingTokenParameters.SignedEncrypted ) )
791 if ( DoesX509TokenParametersContainClauseTypeofIssuerSerial( sbe.OptionalEndpointSupportingTokenParameters.SignedEndorsing ) )
797 bool DoesX509TokenParametersContainClauseTypeofIssuerSerial( Collection<SecurityTokenParameters> tokenParameters )
799 foreach ( SecurityTokenParameters tokenParameter in tokenParameters )
801 X509SecurityTokenParameters x509TokenParameter = tokenParameter as X509SecurityTokenParameters;
802 if ( x509TokenParameter != null )
804 if ( x509TokenParameter.X509ReferenceStyle == X509KeyIdentifierClauseType.IssuerSerial )
812 protected override bool SerializeToXmlElement(XmlWriter writer, String elementName)
816 if (this.failedSecurityBindingElement != null && writer != null)
818 writer.WriteComment(SR.GetString(SR.ConfigurationSchemaInsuffientForSecurityBindingElementInstance));
819 writer.WriteComment(this.failedSecurityBindingElement.ToString());
824 if ( writer != null && this.willX509IssuerReferenceAssertionBeWritten )
825 writer.WriteComment( SR.GetString(SR.ConfigurationSchemaContainsX509IssuerSerialReference));
827 result = base.SerializeToXmlElement(writer, elementName);
833 protected override bool SerializeElement(XmlWriter writer, bool serializeCollectionKey)
835 bool nontrivial = base.SerializeElement(writer, serializeCollectionKey);
837 // A SecurityElement can copy properties from a "bootstrap" SecurityBaseElement.
838 // In this case, a trivial bootstrap (no properties set) is equivalent to not having one at all so we can omit it.
839 Func<PropertyInformation, bool> nontrivialProperty = property => property.ValueOrigin == PropertyValueOrigin.SetHere;
840 if (this.IsSecurityElementBootstrap && !this.ElementInformation.Properties.OfType<PropertyInformation>().Any(nontrivialProperty))
848 protected override void Unmerge(ConfigurationElement sourceElement, ConfigurationElement parentElement, ConfigurationSaveMode saveMode)
850 if ( sourceElement is SecurityElementBase )
852 this.failedSecurityBindingElement = ( (SecurityElementBase)sourceElement ).failedSecurityBindingElement;
853 this.willX509IssuerReferenceAssertionBeWritten = ( (SecurityElementBase)sourceElement ).willX509IssuerReferenceAssertionBeWritten;
856 base.Unmerge(sourceElement, parentElement, saveMode);