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