1 //------------------------------------------------------------------------------ 2 // Copyright (c) Microsoft Corporation. All rights reserved. 3 //------------------------------------------------------------------------------ 4 5 namespace System.ServiceModel.Configuration 6 { 7 using System.Collections.Generic; 8 using System.Collections.ObjectModel; 9 using System.ComponentModel; 10 using System.Configuration; 11 using System.IdentityModel.Tokens; 12 using System.Runtime; 13 using System.ServiceModel.Channels; 14 using System.ServiceModel.Security; 15 using System.ServiceModel.Security.Tokens; 16 using System.Xml; 17 using System.Linq; 18 19 public partial class SecurityElementBase : BindingElementExtensionElement 20 { 21 internal const AuthenticationMode defaultAuthenticationMode = AuthenticationMode.SspiNegotiated; 22 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; 27 SecurityElementBase()28 internal SecurityElementBase() 29 { 30 } 31 32 internal bool HasImportFailed { get { return this.failedSecurityBindingElement != null; } } 33 34 internal bool IsSecurityElementBootstrap { get; set; } // Used in serialization path to optimize Xml representation 35 36 [ConfigurationProperty(ConfigurationStrings.DefaultAlgorithmSuite, DefaultValue = SecurityBindingElement.defaultAlgorithmSuiteString)] 37 [TypeConverter(typeof(SecurityAlgorithmSuiteConverter))] 38 public SecurityAlgorithmSuite DefaultAlgorithmSuite 39 { 40 get { return (SecurityAlgorithmSuite)base[ConfigurationStrings.DefaultAlgorithmSuite]; } 41 set { base[ConfigurationStrings.DefaultAlgorithmSuite] = value; } 42 } 43 44 [ConfigurationProperty(ConfigurationStrings.AllowSerializedSigningTokenOnReply, DefaultValue = AsymmetricSecurityBindingElement.defaultAllowSerializedSigningTokenOnReply)] 45 public bool AllowSerializedSigningTokenOnReply 46 { 47 get { return (bool)base[ConfigurationStrings.AllowSerializedSigningTokenOnReply]; } 48 set { base[ConfigurationStrings.AllowSerializedSigningTokenOnReply] = value; } 49 } 50 51 [ConfigurationProperty(ConfigurationStrings.EnableUnsecuredResponse, DefaultValue = SecurityBindingElement.defaultEnableUnsecuredResponse)] 52 public bool EnableUnsecuredResponse 53 { 54 get { return (bool)base[ConfigurationStrings.EnableUnsecuredResponse]; } 55 set { base[ConfigurationStrings.EnableUnsecuredResponse] = value; } 56 } 57 58 [ConfigurationProperty(ConfigurationStrings.AuthenticationMode, DefaultValue = defaultAuthenticationMode)] 59 [ServiceModelEnumValidator(typeof(AuthenticationModeHelper))] 60 public AuthenticationMode AuthenticationMode 61 { 62 get { return (AuthenticationMode)base[ConfigurationStrings.AuthenticationMode]; } 63 set { base[ConfigurationStrings.AuthenticationMode] = value; } 64 } 65 66 public override Type BindingElementType 67 { 68 get { return typeof(SecurityBindingElement); } 69 } 70 71 [ConfigurationProperty(ConfigurationStrings.RequireDerivedKeys, DefaultValue = SecurityTokenParameters.defaultRequireDerivedKeys)] 72 public bool RequireDerivedKeys 73 { 74 get { return (bool)base[ConfigurationStrings.RequireDerivedKeys]; } 75 set { base[ConfigurationStrings.RequireDerivedKeys] = value; } 76 } 77 78 [ConfigurationProperty(ConfigurationStrings.SecurityHeaderLayout, DefaultValue = SecurityProtocolFactory.defaultSecurityHeaderLayout)] 79 [ServiceModelEnumValidator(typeof(SecurityHeaderLayoutHelper))] 80 public SecurityHeaderLayout SecurityHeaderLayout 81 { 82 get { return (SecurityHeaderLayout)base[ConfigurationStrings.SecurityHeaderLayout]; } 83 set { base[ConfigurationStrings.SecurityHeaderLayout] = value; } 84 } 85 86 [ConfigurationProperty(ConfigurationStrings.IncludeTimestamp, DefaultValue = SecurityBindingElement.defaultIncludeTimestamp)] 87 public bool IncludeTimestamp 88 { 89 get { return (bool)base[ConfigurationStrings.IncludeTimestamp]; } 90 set { base[ConfigurationStrings.IncludeTimestamp] = value; } 91 } 92 93 [ConfigurationProperty(ConfigurationStrings.AllowInsecureTransport, DefaultValue = SecurityBindingElement.defaultAllowInsecureTransport)] 94 public bool AllowInsecureTransport 95 { 96 get { return (bool)base[ConfigurationStrings.AllowInsecureTransport]; } 97 set { base[ConfigurationStrings.AllowInsecureTransport] = value; } 98 } 99 100 [ConfigurationProperty(ConfigurationStrings.KeyEntropyMode, DefaultValue = System.ServiceModel.Security.AcceleratedTokenProvider.defaultKeyEntropyMode)] 101 [ServiceModelEnumValidator(typeof(SecurityKeyEntropyModeHelper))] 102 public SecurityKeyEntropyMode KeyEntropyMode 103 { 104 get { return (SecurityKeyEntropyMode)base[ConfigurationStrings.KeyEntropyMode]; } 105 set { base[ConfigurationStrings.KeyEntropyMode] = value; } 106 } 107 108 [ConfigurationProperty(ConfigurationStrings.IssuedTokenParameters)] 109 public IssuedTokenParametersElement IssuedTokenParameters 110 { 111 get { return (IssuedTokenParametersElement)base[ConfigurationStrings.IssuedTokenParameters]; } 112 } 113 114 [ConfigurationProperty(ConfigurationStrings.LocalClientSettings)] 115 public LocalClientSecuritySettingsElement LocalClientSettings 116 { 117 get { return (LocalClientSecuritySettingsElement)base[ConfigurationStrings.LocalClientSettings]; } 118 } 119 120 [ConfigurationProperty(ConfigurationStrings.LocalServiceSettings)] 121 public LocalServiceSecuritySettingsElement LocalServiceSettings 122 { 123 get { return (LocalServiceSecuritySettingsElement)base[ConfigurationStrings.LocalServiceSettings]; } 124 } 125 126 [ConfigurationProperty(ConfigurationStrings.MessageProtectionOrder, DefaultValue = SecurityBindingElement.defaultMessageProtectionOrder)] 127 [ServiceModelEnumValidator(typeof(MessageProtectionOrderHelper))] 128 public MessageProtectionOrder MessageProtectionOrder 129 { 130 get { return (MessageProtectionOrder)base[ConfigurationStrings.MessageProtectionOrder]; } 131 set { base[ConfigurationStrings.MessageProtectionOrder] = value; } 132 } 133 134 [ConfigurationProperty(ConfigurationStrings.ProtectTokens, DefaultValue = false)] 135 public bool ProtectTokens 136 { 137 get { return (bool)base[ConfigurationStrings.ProtectTokens]; } 138 set { base[ConfigurationStrings.ProtectTokens] = value; } 139 } 140 141 [ConfigurationProperty(ConfigurationStrings.MessageSecurityVersion, DefaultValue = ConfigurationStrings.Default)] 142 [TypeConverter(typeof(MessageSecurityVersionConverter))] 143 public MessageSecurityVersion MessageSecurityVersion 144 { 145 get { return (MessageSecurityVersion)base[ConfigurationStrings.MessageSecurityVersion]; } 146 set { base[ConfigurationStrings.MessageSecurityVersion] = value; } 147 } 148 149 [ConfigurationProperty(ConfigurationStrings.RequireSecurityContextCancellation, DefaultValue = SecureConversationSecurityTokenParameters.defaultRequireCancellation)] 150 public bool RequireSecurityContextCancellation 151 { 152 get { return (bool)base[ConfigurationStrings.RequireSecurityContextCancellation]; } 153 set { base[ConfigurationStrings.RequireSecurityContextCancellation] = value; } 154 } 155 156 [ConfigurationProperty(ConfigurationStrings.RequireSignatureConfirmation, DefaultValue = SecurityBindingElement.defaultRequireSignatureConfirmation)] 157 public bool RequireSignatureConfirmation 158 { 159 get { return (bool)base[ConfigurationStrings.RequireSignatureConfirmation]; } 160 set { base[ConfigurationStrings.RequireSignatureConfirmation] = value; } 161 } 162 163 [ConfigurationProperty(ConfigurationStrings.CanRenewSecurityContextToken, DefaultValue = SecureConversationSecurityTokenParameters.defaultCanRenewSession)] 164 public bool CanRenewSecurityContextToken 165 { 166 get { return (bool)base[ConfigurationStrings.CanRenewSecurityContextToken]; } 167 set { base[ConfigurationStrings.CanRenewSecurityContextToken] = value; } 168 } 169 ApplyConfiguration(BindingElement bindingElement)170 public override void ApplyConfiguration(BindingElement bindingElement) 171 { 172 base.ApplyConfiguration(bindingElement); 173 174 SecurityBindingElement sbe = (SecurityBindingElement)bindingElement; 175 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 196 197 SymmetricSecurityBindingElement ssbe = sbe as SymmetricSecurityBindingElement; 198 199 if (ssbe != null) 200 { 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) 207 { 208 scParameters.CanRenewSession = this.CanRenewSecurityContextToken; 209 } 210 } 211 212 AsymmetricSecurityBindingElement asbe = sbe as AsymmetricSecurityBindingElement; 213 214 if (asbe != null) 215 { 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; 222 } 223 224 TransportSecurityBindingElement tsbe = sbe as TransportSecurityBindingElement; 225 226 if (tsbe != null) 227 { 228 if (tsbe.EndpointSupportingTokenParameters.Endorsing.Count == 1) 229 { 230 SecureConversationSecurityTokenParameters scParameters = tsbe.EndpointSupportingTokenParameters.Endorsing[0] as SecureConversationSecurityTokenParameters; 231 if (scParameters != null) 232 { 233 scParameters.CanRenewSession = this.CanRenewSecurityContextToken; 234 } 235 } 236 } 237 238 if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.LocalClientSettings].ValueOrigin) 239 { 240 this.LocalClientSettings.ApplyConfiguration(sbe.LocalClientSettings); 241 } 242 243 if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.LocalServiceSettings].ValueOrigin) 244 { 245 this.LocalServiceSettings.ApplyConfiguration(sbe.LocalServiceSettings); 246 } 247 } 248 CopyFrom(ServiceModelExtensionElement from)249 public override void CopyFrom(ServiceModelExtensionElement from) 250 { 251 base.CopyFrom(from); 252 253 SecurityElementBase source = (SecurityElementBase)from; 254 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); 289 290 this.failedSecurityBindingElement = source.failedSecurityBindingElement; 291 this.willX509IssuerReferenceAssertionBeWritten = source.willX509IssuerReferenceAssertionBeWritten; 292 } 293 CreateBindingElement()294 protected internal override BindingElement CreateBindingElement() 295 { 296 return this.CreateBindingElement(false); 297 } 298 CreateBindingElement(bool createTemplateOnly)299 protected internal virtual BindingElement CreateBindingElement(bool createTemplateOnly) 300 { 301 SecurityBindingElement result; 302 switch (this.AuthenticationMode) 303 { 304 case AuthenticationMode.AnonymousForCertificate: 305 result = SecurityBindingElement.CreateAnonymousForCertificateBindingElement(); 306 break; 307 case AuthenticationMode.AnonymousForSslNegotiated: 308 result = SecurityBindingElement.CreateSslNegotiationBindingElement(false, this.RequireSecurityContextCancellation); 309 break; 310 case AuthenticationMode.CertificateOverTransport: 311 result = SecurityBindingElement.CreateCertificateOverTransportBindingElement(this.MessageSecurityVersion); 312 break; 313 case AuthenticationMode.IssuedToken: 314 result = SecurityBindingElement.CreateIssuedTokenBindingElement(this.IssuedTokenParameters.Create(createTemplateOnly, this.templateKeyType)); 315 break; 316 case AuthenticationMode.IssuedTokenForCertificate: 317 result = SecurityBindingElement.CreateIssuedTokenForCertificateBindingElement(this.IssuedTokenParameters.Create(createTemplateOnly, this.templateKeyType)); 318 break; 319 case AuthenticationMode.IssuedTokenForSslNegotiated: 320 result = SecurityBindingElement.CreateIssuedTokenForSslBindingElement(this.IssuedTokenParameters.Create(createTemplateOnly, this.templateKeyType), this.RequireSecurityContextCancellation); 321 break; 322 case AuthenticationMode.IssuedTokenOverTransport: 323 result = SecurityBindingElement.CreateIssuedTokenOverTransportBindingElement(this.IssuedTokenParameters.Create(createTemplateOnly, this.templateKeyType)); 324 break; 325 case AuthenticationMode.Kerberos: 326 result = SecurityBindingElement.CreateKerberosBindingElement(); 327 break; 328 case AuthenticationMode.KerberosOverTransport: 329 result = SecurityBindingElement.CreateKerberosOverTransportBindingElement(); 330 break; 331 case AuthenticationMode.MutualCertificateDuplex: 332 result = SecurityBindingElement.CreateMutualCertificateDuplexBindingElement(this.MessageSecurityVersion); 333 break; 334 case AuthenticationMode.MutualCertificate: 335 result = SecurityBindingElement.CreateMutualCertificateBindingElement(this.MessageSecurityVersion); 336 break; 337 case AuthenticationMode.MutualSslNegotiated: 338 result = SecurityBindingElement.CreateSslNegotiationBindingElement(true, this.RequireSecurityContextCancellation); 339 break; 340 case AuthenticationMode.SspiNegotiated: 341 result = SecurityBindingElement.CreateSspiNegotiationBindingElement(this.RequireSecurityContextCancellation); 342 break; 343 case AuthenticationMode.UserNameForCertificate: 344 result = SecurityBindingElement.CreateUserNameForCertificateBindingElement(); 345 break; 346 case AuthenticationMode.UserNameForSslNegotiated: 347 result = SecurityBindingElement.CreateUserNameForSslBindingElement(this.RequireSecurityContextCancellation); 348 break; 349 case AuthenticationMode.UserNameOverTransport: 350 result = SecurityBindingElement.CreateUserNameOverTransportBindingElement(); 351 break; 352 case AuthenticationMode.SspiNegotiatedOverTransport: 353 result = SecurityBindingElement.CreateSspiNegotiationOverTransportBindingElement(this.RequireSecurityContextCancellation); 354 break; 355 default: 356 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidEnumArgumentException("AuthenticationMode", (int)this.AuthenticationMode, typeof(AuthenticationMode))); 357 } 358 359 this.ApplyConfiguration(result); 360 361 return result; 362 } 363 AddBindingTemplate(Dictionary<AuthenticationMode, SecurityBindingElement> bindingTemplates, AuthenticationMode mode)364 protected void AddBindingTemplate(Dictionary<AuthenticationMode, SecurityBindingElement> bindingTemplates, AuthenticationMode mode) 365 { 366 this.AuthenticationMode = mode; 367 try 368 { 369 bindingTemplates[mode] = (SecurityBindingElement)this.CreateBindingElement(true); 370 } 371 #pragma warning suppress 56500 // covered by FxCOP 372 catch (Exception e) 373 { 374 if (Fx.IsFatal(e)) 375 { 376 throw; 377 } 378 } 379 } 380 AreTokenParametersMatching(SecurityTokenParameters p1, SecurityTokenParameters p2, bool skipRequireDerivedKeysComparison, bool exactMessageSecurityVersion)381 static bool AreTokenParametersMatching(SecurityTokenParameters p1, SecurityTokenParameters p2, bool skipRequireDerivedKeysComparison, bool exactMessageSecurityVersion) 382 { 383 if (p1 == null || p2 == null) 384 return false; 385 386 if (p1.GetType() != p2.GetType()) 387 return false; 388 389 if (p1.InclusionMode != p2.InclusionMode) 390 return false; 391 392 if (skipRequireDerivedKeysComparison == false && p1.RequireDerivedKeys != p2.RequireDerivedKeys) 393 return false; 394 395 if (p1.ReferenceStyle != p2.ReferenceStyle) 396 return false; 397 398 // mutual ssl and anonymous ssl differ in the client cert requirement 399 if (p1 is SslSecurityTokenParameters) 400 { 401 if (((SslSecurityTokenParameters)p1).RequireClientCertificate != ((SslSecurityTokenParameters)p2).RequireClientCertificate) 402 return false; 403 } 404 else if (p1 is SecureConversationSecurityTokenParameters) 405 { 406 SecureConversationSecurityTokenParameters sc1 = (SecureConversationSecurityTokenParameters)p1; 407 SecureConversationSecurityTokenParameters sc2 = (SecureConversationSecurityTokenParameters)p2; 408 409 if (sc1.RequireCancellation != sc2.RequireCancellation) 410 return false; 411 412 if (sc1.CanRenewSession != sc2.CanRenewSession) 413 return false; 414 415 416 if (!AreBindingsMatching(sc1.BootstrapSecurityBindingElement, sc2.BootstrapSecurityBindingElement, exactMessageSecurityVersion)) 417 return false; 418 } 419 else if (p1 is IssuedSecurityTokenParameters) 420 { 421 if (((IssuedSecurityTokenParameters)p1).KeyType != ((IssuedSecurityTokenParameters)p2).KeyType) 422 return false; 423 } 424 425 return true; 426 } 427 AreTokenParameterCollectionsMatching(Collection<SecurityTokenParameters> c1, Collection<SecurityTokenParameters> c2, bool exactMessageSecurityVersion)428 static bool AreTokenParameterCollectionsMatching(Collection<SecurityTokenParameters> c1, Collection<SecurityTokenParameters> c2, bool exactMessageSecurityVersion) 429 { 430 if (c1.Count != c2.Count) 431 return false; 432 433 for (int i = 0; i < c1.Count; i++) 434 if (!AreTokenParametersMatching(c1[i], c2[i], true, exactMessageSecurityVersion)) 435 return false; 436 437 return true; 438 } 439 AreBindingsMatching(SecurityBindingElement b1, SecurityBindingElement b2)440 internal static bool AreBindingsMatching(SecurityBindingElement b1, SecurityBindingElement b2) 441 { 442 return AreBindingsMatching(b1, b2, true); 443 } 444 AreBindingsMatching(SecurityBindingElement b1, SecurityBindingElement b2, bool exactMessageSecurityVersion)445 internal static bool AreBindingsMatching(SecurityBindingElement b1, SecurityBindingElement b2, bool exactMessageSecurityVersion) 446 { 447 if (b1 == null || b2 == null) 448 return b1 == b2; 449 450 if (b1.GetType() != b2.GetType()) 451 return false; 452 453 if (b1.MessageSecurityVersion != b2.MessageSecurityVersion) 454 { 455 // exactMessageSecurityVersion meant that BSP mismatch could be ignored 456 if (exactMessageSecurityVersion) 457 return false; 458 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) 463 { 464 return false; 465 } 466 } 467 468 if (b1.SecurityHeaderLayout != b2.SecurityHeaderLayout) 469 return false; 470 471 if (b1.DefaultAlgorithmSuite != b2.DefaultAlgorithmSuite) 472 return false; 473 474 if (b1.IncludeTimestamp != b2.IncludeTimestamp) 475 return false; 476 477 if (b1.SecurityHeaderLayout != b2.SecurityHeaderLayout) 478 return false; 479 480 if (b1.KeyEntropyMode != b2.KeyEntropyMode) 481 return false; 482 483 if (!AreTokenParameterCollectionsMatching(b1.EndpointSupportingTokenParameters.Endorsing, b2.EndpointSupportingTokenParameters.Endorsing, exactMessageSecurityVersion)) 484 return false; 485 486 if (!AreTokenParameterCollectionsMatching(b1.EndpointSupportingTokenParameters.SignedEncrypted, b2.EndpointSupportingTokenParameters.SignedEncrypted, exactMessageSecurityVersion)) 487 return false; 488 489 if (!AreTokenParameterCollectionsMatching(b1.EndpointSupportingTokenParameters.Signed, b2.EndpointSupportingTokenParameters.Signed, exactMessageSecurityVersion)) 490 return false; 491 492 if (!AreTokenParameterCollectionsMatching(b1.EndpointSupportingTokenParameters.SignedEndorsing, b2.EndpointSupportingTokenParameters.SignedEndorsing, exactMessageSecurityVersion)) 493 return false; 494 495 if (b1.OperationSupportingTokenParameters.Count != b2.OperationSupportingTokenParameters.Count) 496 return false; 497 498 foreach (KeyValuePair<string, SupportingTokenParameters> operation1 in b1.OperationSupportingTokenParameters) 499 { 500 if (!b2.OperationSupportingTokenParameters.ContainsKey(operation1.Key)) 501 return false; 502 503 SupportingTokenParameters stp2 = b2.OperationSupportingTokenParameters[operation1.Key]; 504 505 if (!AreTokenParameterCollectionsMatching(operation1.Value.Endorsing, stp2.Endorsing, exactMessageSecurityVersion)) 506 return false; 507 508 if (!AreTokenParameterCollectionsMatching(operation1.Value.SignedEncrypted, stp2.SignedEncrypted, exactMessageSecurityVersion)) 509 return false; 510 511 if (!AreTokenParameterCollectionsMatching(operation1.Value.Signed, stp2.Signed, exactMessageSecurityVersion)) 512 return false; 513 514 if (!AreTokenParameterCollectionsMatching(operation1.Value.SignedEndorsing, stp2.SignedEndorsing, exactMessageSecurityVersion)) 515 return false; 516 } 517 518 SymmetricSecurityBindingElement ssbe1 = b1 as SymmetricSecurityBindingElement; 519 if (ssbe1 != null) 520 { 521 SymmetricSecurityBindingElement ssbe2 = (SymmetricSecurityBindingElement)b2; 522 523 if (ssbe1.MessageProtectionOrder != ssbe2.MessageProtectionOrder) 524 return false; 525 526 if (!AreTokenParametersMatching(ssbe1.ProtectionTokenParameters, ssbe2.ProtectionTokenParameters, false, exactMessageSecurityVersion)) 527 return false; 528 } 529 530 AsymmetricSecurityBindingElement asbe1 = b1 as AsymmetricSecurityBindingElement; 531 if (asbe1 != null) 532 { 533 AsymmetricSecurityBindingElement asbe2 = (AsymmetricSecurityBindingElement)b2; 534 535 if (asbe1.MessageProtectionOrder != asbe2.MessageProtectionOrder) 536 return false; 537 538 if (asbe1.RequireSignatureConfirmation != asbe2.RequireSignatureConfirmation) 539 return false; 540 541 if (!AreTokenParametersMatching(asbe1.InitiatorTokenParameters, asbe2.InitiatorTokenParameters, true, exactMessageSecurityVersion) 542 || !AreTokenParametersMatching(asbe1.RecipientTokenParameters, asbe2.RecipientTokenParameters, true, exactMessageSecurityVersion)) 543 return false; 544 } 545 546 return true; 547 } 548 AddBindingTemplates(Dictionary<AuthenticationMode, SecurityBindingElement> bindingTemplates)549 protected virtual void AddBindingTemplates(Dictionary<AuthenticationMode, SecurityBindingElement> bindingTemplates) 550 { 551 AddBindingTemplate(bindingTemplates, AuthenticationMode.AnonymousForCertificate); 552 AddBindingTemplate(bindingTemplates, AuthenticationMode.AnonymousForSslNegotiated); 553 AddBindingTemplate(bindingTemplates, AuthenticationMode.CertificateOverTransport); 554 if (this.templateKeyType == SecurityKeyType.SymmetricKey) 555 { 556 AddBindingTemplate(bindingTemplates, AuthenticationMode.IssuedToken); 557 } 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); 571 } 572 TryInitializeAuthenticationMode(SecurityBindingElement sbe)573 bool TryInitializeAuthenticationMode(SecurityBindingElement sbe) 574 { 575 bool result; 576 577 if (sbe.OperationSupportingTokenParameters.Count > 0) 578 result = false; 579 else 580 { 581 SetIssuedTokenKeyType(sbe); 582 583 Dictionary<AuthenticationMode, SecurityBindingElement> bindingTemplates = new Dictionary<AuthenticationMode, SecurityBindingElement>(); 584 this.AddBindingTemplates(bindingTemplates); 585 586 result = false; 587 foreach (AuthenticationMode mode in bindingTemplates.Keys) 588 { 589 SecurityBindingElement candidate = bindingTemplates[mode]; 590 if (AreBindingsMatching(sbe, candidate)) 591 { 592 this.AuthenticationMode = mode; 593 result = true; 594 break; 595 } 596 } 597 } 598 599 return result; 600 } 601 SetIssuedTokenKeyType(SecurityBindingElement sbe)602 void SetIssuedTokenKeyType(SecurityBindingElement sbe) 603 { 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) 608 { 609 this.templateKeyType = ((IssuedSecurityTokenParameters)sbe.EndpointSupportingTokenParameters.Endorsing[0]).KeyType; 610 } 611 else if (sbe.EndpointSupportingTokenParameters.Signed.Count > 0 && 612 sbe.EndpointSupportingTokenParameters.Signed[0] is IssuedSecurityTokenParameters) 613 { 614 this.templateKeyType = ((IssuedSecurityTokenParameters)sbe.EndpointSupportingTokenParameters.Signed[0]).KeyType; 615 } 616 else if (sbe.EndpointSupportingTokenParameters.SignedEncrypted.Count > 0 && 617 sbe.EndpointSupportingTokenParameters.SignedEncrypted[0] is IssuedSecurityTokenParameters) 618 { 619 this.templateKeyType = ((IssuedSecurityTokenParameters)sbe.EndpointSupportingTokenParameters.SignedEncrypted[0]).KeyType; 620 } 621 else 622 { 623 this.templateKeyType = IssuedSecurityTokenParameters.defaultKeyType; 624 } 625 } 626 InitializeNestedTokenParameterSettings(SecurityTokenParameters sp, bool initializeNestedBindings)627 protected virtual void InitializeNestedTokenParameterSettings(SecurityTokenParameters sp, bool initializeNestedBindings) 628 { 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); 635 } 636 InitializeFrom(BindingElement bindingElement, bool initializeNestedBindings)637 internal void InitializeFrom(BindingElement bindingElement, bool initializeNestedBindings) 638 { 639 if (bindingElement == null) 640 { 641 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("bindingElement"); 642 } 643 SecurityBindingElement sbe = (SecurityBindingElement)bindingElement; 644 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) 649 { 650 this.MessageSecurityVersion = sbe.MessageSecurityVersion; 651 } 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); 658 659 660 Nullable<bool> requireDerivedKeys = new Nullable<bool>(); 661 662 if (sbe.EndpointSupportingTokenParameters.Endorsing.Count == 1) 663 { 664 this.InitializeNestedTokenParameterSettings(sbe.EndpointSupportingTokenParameters.Endorsing[0], initializeNestedBindings); 665 } 666 else if (sbe.EndpointSupportingTokenParameters.SignedEncrypted.Count == 1) 667 { 668 this.InitializeNestedTokenParameterSettings(sbe.EndpointSupportingTokenParameters.SignedEncrypted[0], initializeNestedBindings); 669 } 670 else if (sbe.EndpointSupportingTokenParameters.Signed.Count == 1) 671 { 672 this.InitializeNestedTokenParameterSettings(sbe.EndpointSupportingTokenParameters.Signed[0], initializeNestedBindings); 673 } 674 675 bool initializationFailure = false; 676 677 foreach (SecurityTokenParameters t in sbe.EndpointSupportingTokenParameters.Endorsing) 678 { 679 if (t.HasAsymmetricKey == false) 680 { 681 if (requireDerivedKeys.HasValue && requireDerivedKeys.Value != t.RequireDerivedKeys) 682 initializationFailure = true; 683 else 684 requireDerivedKeys = t.RequireDerivedKeys; 685 } 686 } 687 688 SymmetricSecurityBindingElement ssbe = sbe as SymmetricSecurityBindingElement; 689 if ( ssbe != null ) 690 { 691 SetPropertyValueIfNotDefaultValue(ConfigurationStrings.MessageProtectionOrder, ssbe.MessageProtectionOrder); 692 this.RequireSignatureConfirmation = ssbe.RequireSignatureConfirmation; 693 if ( ssbe.ProtectionTokenParameters != null ) 694 { 695 this.InitializeNestedTokenParameterSettings( ssbe.ProtectionTokenParameters, initializeNestedBindings ); 696 if ( requireDerivedKeys.HasValue && requireDerivedKeys.Value != ssbe.ProtectionTokenParameters.RequireDerivedKeys ) 697 initializationFailure = true; 698 else 699 requireDerivedKeys = ssbe.ProtectionTokenParameters.RequireDerivedKeys; 700 701 } 702 } 703 else 704 { 705 AsymmetricSecurityBindingElement asbe = sbe as AsymmetricSecurityBindingElement; 706 if ( asbe != null ) 707 { 708 SetPropertyValueIfNotDefaultValue(ConfigurationStrings.MessageProtectionOrder, asbe.MessageProtectionOrder); 709 this.RequireSignatureConfirmation = asbe.RequireSignatureConfirmation; 710 if ( asbe.InitiatorTokenParameters != null ) 711 { 712 this.InitializeNestedTokenParameterSettings( asbe.InitiatorTokenParameters, initializeNestedBindings ); 713 714 // 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 717 // 718 if ( requireDerivedKeys.HasValue && requireDerivedKeys.Value != asbe.InitiatorTokenParameters.RequireDerivedKeys ) 719 initializationFailure = true; 720 else 721 requireDerivedKeys = asbe.InitiatorTokenParameters.RequireDerivedKeys; 722 } 723 } 724 } 725 726 this.willX509IssuerReferenceAssertionBeWritten = DoesSecurityBindingElementContainClauseTypeofIssuerSerial(sbe); 727 this.RequireDerivedKeys = requireDerivedKeys.GetValueOrDefault(SecurityTokenParameters.defaultRequireDerivedKeys); 728 this.LocalClientSettings.InitializeFrom(sbe.LocalClientSettings); 729 this.LocalServiceSettings.InitializeFrom(sbe.LocalServiceSettings); 730 731 if (!initializationFailure) 732 initializationFailure = !this.TryInitializeAuthenticationMode(sbe); 733 734 if (initializationFailure) 735 this.failedSecurityBindingElement = sbe; 736 } 737 InitializeFrom(BindingElement bindingElement)738 protected internal override void InitializeFrom(BindingElement bindingElement) 739 { 740 this.InitializeFrom(bindingElement, true); 741 } 742 743 /// <summary> 744 /// returns true if one of the xxxSupportingTokenParameters.yyy is of type IssuerSerial 745 /// </summary> 746 /// <param name="sbe"></param> 747 /// <returns></returns> DoesSecurityBindingElementContainClauseTypeofIssuerSerial( SecurityBindingElement sbe )748 bool DoesSecurityBindingElementContainClauseTypeofIssuerSerial( SecurityBindingElement sbe ) 749 { 750 if ( sbe == null ) 751 return false; 752 753 if ( sbe is SymmetricSecurityBindingElement ) 754 { 755 X509SecurityTokenParameters tokenParamameters = ( (SymmetricSecurityBindingElement)sbe ).ProtectionTokenParameters as X509SecurityTokenParameters; 756 if ( tokenParamameters != null && tokenParamameters.X509ReferenceStyle == X509KeyIdentifierClauseType.IssuerSerial ) 757 return true; 758 } 759 else if ( sbe is AsymmetricSecurityBindingElement ) 760 { 761 X509SecurityTokenParameters initiatorParamameters = ( (AsymmetricSecurityBindingElement)sbe ).InitiatorTokenParameters as X509SecurityTokenParameters; 762 if ( initiatorParamameters != null && initiatorParamameters.X509ReferenceStyle == X509KeyIdentifierClauseType.IssuerSerial ) 763 return true; 764 765 X509SecurityTokenParameters recepientParamameters = ( (AsymmetricSecurityBindingElement)sbe ).RecipientTokenParameters as X509SecurityTokenParameters; 766 if ( recepientParamameters != null && recepientParamameters.X509ReferenceStyle == X509KeyIdentifierClauseType.IssuerSerial ) 767 return true; 768 } 769 770 if ( DoesX509TokenParametersContainClauseTypeofIssuerSerial( sbe.EndpointSupportingTokenParameters.Endorsing ) ) 771 return true; 772 773 if ( DoesX509TokenParametersContainClauseTypeofIssuerSerial( sbe.EndpointSupportingTokenParameters.Signed ) ) 774 return true; 775 776 if ( DoesX509TokenParametersContainClauseTypeofIssuerSerial( sbe.EndpointSupportingTokenParameters.SignedEncrypted ) ) 777 return true; 778 779 if ( DoesX509TokenParametersContainClauseTypeofIssuerSerial( sbe.EndpointSupportingTokenParameters.SignedEndorsing ) ) 780 return true; 781 782 if ( DoesX509TokenParametersContainClauseTypeofIssuerSerial( sbe.OptionalEndpointSupportingTokenParameters.Endorsing ) ) 783 return true; 784 785 if ( DoesX509TokenParametersContainClauseTypeofIssuerSerial( sbe.OptionalEndpointSupportingTokenParameters.Signed ) ) 786 return true; 787 788 if ( DoesX509TokenParametersContainClauseTypeofIssuerSerial( sbe.OptionalEndpointSupportingTokenParameters.SignedEncrypted ) ) 789 return true; 790 791 if ( DoesX509TokenParametersContainClauseTypeofIssuerSerial( sbe.OptionalEndpointSupportingTokenParameters.SignedEndorsing ) ) 792 return true; 793 794 return false; 795 } 796 DoesX509TokenParametersContainClauseTypeofIssuerSerial( Collection<SecurityTokenParameters> tokenParameters )797 bool DoesX509TokenParametersContainClauseTypeofIssuerSerial( Collection<SecurityTokenParameters> tokenParameters ) 798 { 799 foreach ( SecurityTokenParameters tokenParameter in tokenParameters ) 800 { 801 X509SecurityTokenParameters x509TokenParameter = tokenParameter as X509SecurityTokenParameters; 802 if ( x509TokenParameter != null ) 803 { 804 if ( x509TokenParameter.X509ReferenceStyle == X509KeyIdentifierClauseType.IssuerSerial ) 805 return true; 806 } 807 } 808 809 return false; 810 } 811 SerializeToXmlElement(XmlWriter writer, String elementName)812 protected override bool SerializeToXmlElement(XmlWriter writer, String elementName) 813 { 814 bool result; 815 816 if (this.failedSecurityBindingElement != null && writer != null) 817 { 818 writer.WriteComment(SR.GetString(SR.ConfigurationSchemaInsuffientForSecurityBindingElementInstance)); 819 writer.WriteComment(this.failedSecurityBindingElement.ToString()); 820 result = true; 821 } 822 else 823 { 824 if ( writer != null && this.willX509IssuerReferenceAssertionBeWritten ) 825 writer.WriteComment( SR.GetString(SR.ConfigurationSchemaContainsX509IssuerSerialReference)); 826 827 result = base.SerializeToXmlElement(writer, elementName); 828 } 829 830 return result; 831 } 832 SerializeElement(XmlWriter writer, bool serializeCollectionKey)833 protected override bool SerializeElement(XmlWriter writer, bool serializeCollectionKey) 834 { 835 bool nontrivial = base.SerializeElement(writer, serializeCollectionKey); 836 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)) 841 { 842 nontrivial = false; 843 } 844 return nontrivial; 845 } 846 847 Unmerge(ConfigurationElement sourceElement, ConfigurationElement parentElement, ConfigurationSaveMode saveMode)848 protected override void Unmerge(ConfigurationElement sourceElement, ConfigurationElement parentElement, ConfigurationSaveMode saveMode) 849 { 850 if ( sourceElement is SecurityElementBase ) 851 { 852 this.failedSecurityBindingElement = ( (SecurityElementBase)sourceElement ).failedSecurityBindingElement; 853 this.willX509IssuerReferenceAssertionBeWritten = ( (SecurityElementBase)sourceElement ).willX509IssuerReferenceAssertionBeWritten; 854 } 855 856 base.Unmerge(sourceElement, parentElement, saveMode); 857 } 858 } 859 } 860 861 862 863