1 //---------------------------------------------------------- 2 // Copyright (c) Microsoft Corporation. All rights reserved. 3 //------------------------------------------------------------ 4 5 namespace System.ServiceModel.Security 6 { 7 using System.Collections.Generic; 8 using System.Collections.ObjectModel; 9 using System.Diagnostics; 10 using System.IdentityModel.Policy; 11 using System.IdentityModel.Selectors; 12 using System.IdentityModel.Tokens; 13 using System.Security.Authentication.ExtendedProtection; 14 using System.Security.Cryptography.X509Certificates; 15 using System.ServiceModel; 16 using System.ServiceModel.Channels; 17 using System.ServiceModel.Description; 18 using System.ServiceModel.Security.Tokens; 19 using System.ServiceModel.Diagnostics; 20 using System.Runtime; 21 using System.Xml; 22 using ISignatureValueSecurityElement = System.IdentityModel.ISignatureValueSecurityElement; 23 using SignatureResourcePool = System.IdentityModel.SignatureResourcePool; 24 using SignedXml = System.IdentityModel.SignedXml; 25 using System.Runtime.Diagnostics; 26 using System.ServiceModel.Diagnostics.Application; 27 28 abstract class ReceiveSecurityHeader : SecurityHeader 29 { 30 // client->server symmetric binding case: only primaryTokenAuthenticator is set 31 // server->client symmetric binding case: only primary token is set 32 // asymmetric binding case: primaryTokenAuthenticator and wrapping token is set 33 34 SecurityTokenAuthenticator primaryTokenAuthenticator; 35 bool allowFirstTokenMismatch; 36 SecurityToken outOfBandPrimaryToken; 37 IList<SecurityToken> outOfBandPrimaryTokenCollection; 38 SecurityTokenParameters primaryTokenParameters; 39 TokenTracker primaryTokenTracker; 40 SecurityToken wrappingToken; 41 SecurityTokenParameters wrappingTokenParameters; 42 SecurityToken expectedEncryptionToken; 43 SecurityTokenParameters expectedEncryptionTokenParameters; 44 SecurityTokenAuthenticator derivedTokenAuthenticator; 45 // assumes that the caller has done the check for uniqueness of types 46 IList<SupportingTokenAuthenticatorSpecification> supportingTokenAuthenticators; 47 ChannelBinding channelBinding; 48 ExtendedProtectionPolicy extendedProtectionPolicy; 49 50 bool expectEncryption = true; 51 // caller should precompute and set expectations 52 bool expectBasicTokens; 53 bool expectSignedTokens; 54 bool expectEndorsingTokens; 55 bool expectSignature = true; 56 bool requireSignedPrimaryToken; 57 bool expectSignatureConfirmation; 58 // maps from token to wire form (for basic and signed), and also tracks operations done 59 // maps from supporting token parameter to the operations done for that token type 60 List<TokenTracker> supportingTokenTrackers; 61 62 SignatureConfirmations receivedSignatureValues; 63 SignatureConfirmations receivedSignatureConfirmations; 64 List<SecurityTokenAuthenticator> allowedAuthenticators; 65 66 SecurityTokenAuthenticator pendingSupportingTokenAuthenticator; 67 68 WrappedKeySecurityToken wrappedKeyToken; 69 Collection<SecurityToken> basicTokens; 70 Collection<SecurityToken> signedTokens; 71 Collection<SecurityToken> endorsingTokens; 72 Collection<SecurityToken> signedEndorsingTokens; 73 Dictionary<SecurityToken, ReadOnlyCollection<IAuthorizationPolicy>> tokenPoliciesMapping; 74 List<SecurityTokenAuthenticator> wrappedKeyAuthenticator; 75 SecurityTimestamp timestamp; 76 SecurityHeaderTokenResolver universalTokenResolver; 77 SecurityHeaderTokenResolver primaryTokenResolver; 78 ReadOnlyCollection<SecurityTokenResolver> outOfBandTokenResolver; 79 SecurityTokenResolver combinedUniversalTokenResolver; 80 SecurityTokenResolver combinedPrimaryTokenResolver; 81 82 readonly int headerIndex; 83 XmlAttributeHolder[] securityElementAttributes; 84 OrderTracker orderTracker = new OrderTracker(); 85 OperationTracker signatureTracker = new OperationTracker(); 86 OperationTracker encryptionTracker = new OperationTracker(); 87 88 ReceiveSecurityHeaderElementManager elementManager; 89 90 int maxDerivedKeys; 91 int numDerivedKeys; 92 int maxDerivedKeyLength; 93 bool enforceDerivedKeyRequirement = true; 94 95 NonceCache nonceCache; 96 TimeSpan replayWindow; 97 TimeSpan clockSkew; 98 byte[] primarySignatureValue; 99 TimeoutHelper timeoutHelper; 100 SecurityVerifiedMessage securityVerifiedMessage; 101 long maxReceivedMessageSize = TransportDefaults.MaxReceivedMessageSize; 102 XmlDictionaryReaderQuotas readerQuotas; 103 MessageProtectionOrder protectionOrder; 104 bool hasAtLeastOneSupportingTokenExpectedToBeSigned; 105 bool hasEndorsingOrSignedEndorsingSupportingTokens; 106 SignatureResourcePool resourcePool; 107 bool replayDetectionEnabled = false; 108 109 bool hasAtLeastOneItemInsideSecurityHeaderEncrypted = false; 110 111 const int AppendPosition = -1; 112 113 EventTraceActivity eventTraceActivity; 114 ReceiveSecurityHeader(Message message, string actor, bool mustUnderstand, bool relay, SecurityStandardsManager standardsManager, SecurityAlgorithmSuite algorithmSuite, int headerIndex, MessageDirection direction)115 protected ReceiveSecurityHeader(Message message, string actor, bool mustUnderstand, bool relay, 116 SecurityStandardsManager standardsManager, 117 SecurityAlgorithmSuite algorithmSuite, 118 int headerIndex, 119 MessageDirection direction) 120 : base(message, actor, mustUnderstand, relay, standardsManager, algorithmSuite, direction) 121 { 122 this.headerIndex = headerIndex; 123 this.elementManager = new ReceiveSecurityHeaderElementManager(this); 124 } 125 126 public Collection<SecurityToken> BasicSupportingTokens 127 { 128 get 129 { 130 return this.basicTokens; 131 } 132 } 133 134 public Collection<SecurityToken> SignedSupportingTokens 135 { 136 get 137 { 138 return this.signedTokens; 139 } 140 } 141 142 public Collection<SecurityToken> EndorsingSupportingTokens 143 { 144 get 145 { 146 return this.endorsingTokens; 147 } 148 } 149 150 public ReceiveSecurityHeaderElementManager ElementManager 151 { 152 get 153 { 154 return this.elementManager; 155 } 156 } 157 158 public Collection<SecurityToken> SignedEndorsingSupportingTokens 159 { 160 get 161 { 162 return this.signedEndorsingTokens; 163 } 164 } 165 166 public SecurityTokenAuthenticator DerivedTokenAuthenticator 167 { 168 get 169 { 170 return this.derivedTokenAuthenticator; 171 } 172 set 173 { 174 ThrowIfProcessingStarted(); 175 this.derivedTokenAuthenticator = value; 176 } 177 } 178 179 public List<SecurityTokenAuthenticator> WrappedKeySecurityTokenAuthenticator 180 { 181 get 182 { 183 return this.wrappedKeyAuthenticator; 184 } 185 set 186 { 187 ThrowIfProcessingStarted(); 188 this.wrappedKeyAuthenticator = value; 189 } 190 } 191 192 public bool EnforceDerivedKeyRequirement 193 { 194 get 195 { 196 return this.enforceDerivedKeyRequirement; 197 } 198 set 199 { 200 ThrowIfProcessingStarted(); 201 this.enforceDerivedKeyRequirement = value; 202 } 203 } 204 205 public byte[] PrimarySignatureValue 206 { 207 get { return this.primarySignatureValue; } 208 } 209 210 public bool EncryptBeforeSignMode 211 { 212 get { return this.orderTracker.EncryptBeforeSignMode; } 213 } 214 215 public SecurityToken EncryptionToken 216 { 217 get { return this.encryptionTracker.Token; } 218 } 219 220 public bool ExpectBasicTokens 221 { 222 get { return this.expectBasicTokens; } 223 set 224 { 225 ThrowIfProcessingStarted(); 226 this.expectBasicTokens = value; 227 } 228 } 229 230 public bool ReplayDetectionEnabled 231 { 232 get { return this.replayDetectionEnabled; } 233 set 234 { 235 ThrowIfProcessingStarted(); 236 this.replayDetectionEnabled = value; 237 } 238 } 239 240 public bool ExpectEncryption 241 { 242 get { return this.expectEncryption; } 243 set 244 { 245 ThrowIfProcessingStarted(); 246 this.expectEncryption = value; 247 } 248 } 249 250 public bool ExpectSignature 251 { 252 get { return this.expectSignature; } 253 set 254 { 255 ThrowIfProcessingStarted(); 256 this.expectSignature = value; 257 } 258 } 259 260 public bool ExpectSignatureConfirmation 261 { 262 get { return this.expectSignatureConfirmation; } 263 set 264 { 265 ThrowIfProcessingStarted(); 266 this.expectSignatureConfirmation = value; 267 } 268 } 269 270 public bool ExpectSignedTokens 271 { 272 get { return this.expectSignedTokens; } 273 set 274 { 275 ThrowIfProcessingStarted(); 276 this.expectSignedTokens = value; 277 } 278 } 279 280 public bool RequireSignedPrimaryToken 281 { 282 get { return this.requireSignedPrimaryToken; } 283 set 284 { 285 ThrowIfProcessingStarted(); 286 this.requireSignedPrimaryToken = value; 287 } 288 } 289 290 public bool ExpectEndorsingTokens 291 { 292 get { return this.expectEndorsingTokens; } 293 set 294 { 295 ThrowIfProcessingStarted(); 296 this.expectEndorsingTokens = value; 297 } 298 } 299 300 public bool HasAtLeastOneItemInsideSecurityHeaderEncrypted 301 { 302 get { return this.hasAtLeastOneItemInsideSecurityHeaderEncrypted; } 303 set { this.hasAtLeastOneItemInsideSecurityHeaderEncrypted = value; } 304 } 305 306 public SecurityHeaderTokenResolver PrimaryTokenResolver 307 { 308 get 309 { 310 return this.primaryTokenResolver; 311 } 312 } 313 314 public SecurityTokenResolver CombinedUniversalTokenResolver 315 { 316 get { return this.combinedUniversalTokenResolver; } 317 } 318 319 public SecurityTokenResolver CombinedPrimaryTokenResolver 320 { 321 get { return this.combinedPrimaryTokenResolver; } 322 } 323 324 protected EventTraceActivity EventTraceActivity 325 { 326 get 327 { 328 if (this.eventTraceActivity == null && FxTrace.Trace.IsEnd2EndActivityTracingEnabled) 329 { 330 this.eventTraceActivity = EventTraceActivityHelper.TryExtractActivity((OperationContext.Current != null) ? OperationContext.Current.IncomingMessage : null); 331 } 332 333 return this.eventTraceActivity; 334 } 335 } 336 VerifySignatureEncryption()337 protected void VerifySignatureEncryption() 338 { 339 if ((this.protectionOrder == MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature) && 340 (!this.orderTracker.AllSignaturesEncrypted)) 341 { 342 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException( 343 SR.GetString(SR.PrimarySignatureIsRequiredToBeEncrypted))); 344 } 345 } 346 347 internal int HeaderIndex 348 { 349 get { return this.headerIndex; } 350 } 351 352 internal long MaxReceivedMessageSize 353 { 354 get 355 { 356 return this.maxReceivedMessageSize; 357 } 358 set 359 { 360 ThrowIfProcessingStarted(); 361 this.maxReceivedMessageSize = value; 362 } 363 } 364 365 internal XmlDictionaryReaderQuotas ReaderQuotas 366 { 367 get { return this.readerQuotas; } 368 set 369 { 370 ThrowIfProcessingStarted(); 371 372 if (value == null) 373 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value"); 374 375 this.readerQuotas = value; 376 } 377 } 378 379 public override string Name 380 { 381 get { return this.StandardsManager.SecurityVersion.HeaderName.Value; } 382 } 383 384 public override string Namespace 385 { 386 get { return this.StandardsManager.SecurityVersion.HeaderNamespace.Value; } 387 } 388 389 public Message ProcessedMessage 390 { 391 get { return this.Message; } 392 } 393 394 public MessagePartSpecification RequiredEncryptionParts 395 { 396 get { return this.encryptionTracker.Parts; } 397 set 398 { 399 ThrowIfProcessingStarted(); 400 if (value == null) 401 { 402 throw TraceUtility.ThrowHelperError(new ArgumentNullException("value"), this.Message); 403 } 404 if (!value.IsReadOnly) 405 { 406 throw TraceUtility.ThrowHelperError(new InvalidOperationException( 407 SR.GetString(SR.MessagePartSpecificationMustBeImmutable)), this.Message); 408 } 409 this.encryptionTracker.Parts = value; 410 } 411 } 412 413 public MessagePartSpecification RequiredSignatureParts 414 { 415 get { return this.signatureTracker.Parts; } 416 set 417 { 418 ThrowIfProcessingStarted(); 419 if (value == null) 420 { 421 throw TraceUtility.ThrowHelperError(new ArgumentNullException("value"), this.Message); 422 } 423 if (!value.IsReadOnly) 424 { 425 throw TraceUtility.ThrowHelperError(new InvalidOperationException( 426 SR.GetString(SR.MessagePartSpecificationMustBeImmutable)), this.Message); 427 } 428 this.signatureTracker.Parts = value; 429 } 430 } 431 432 protected SignatureResourcePool ResourcePool 433 { 434 get 435 { 436 if (this.resourcePool == null) 437 { 438 this.resourcePool = new SignatureResourcePool(); 439 } 440 return this.resourcePool; 441 } 442 } 443 444 internal SecurityVerifiedMessage SecurityVerifiedMessage 445 { 446 get 447 { 448 return this.securityVerifiedMessage; 449 } 450 } 451 452 public SecurityToken SignatureToken 453 { 454 get { return this.signatureTracker.Token; } 455 } 456 457 public Dictionary<SecurityToken, ReadOnlyCollection<IAuthorizationPolicy>> SecurityTokenAuthorizationPoliciesMapping 458 { 459 get 460 { 461 if (this.tokenPoliciesMapping == null) 462 { 463 this.tokenPoliciesMapping = new Dictionary<SecurityToken, ReadOnlyCollection<IAuthorizationPolicy>>(); 464 } 465 return this.tokenPoliciesMapping; 466 } 467 } 468 469 public SecurityTimestamp Timestamp 470 { 471 get { return this.timestamp; } 472 } 473 474 public int MaxDerivedKeyLength 475 { 476 get 477 { 478 return this.maxDerivedKeyLength; 479 } 480 } 481 CreateSecurityHeaderReader()482 internal XmlDictionaryReader CreateSecurityHeaderReader() 483 { 484 return this.securityVerifiedMessage.GetReaderAtSecurityHeader(); 485 } 486 GetSentSignatureConfirmations()487 public SignatureConfirmations GetSentSignatureConfirmations() 488 { 489 return this.receivedSignatureConfirmations; 490 } 491 ConfigureSymmetricBindingServerReceiveHeader(SecurityTokenAuthenticator primaryTokenAuthenticator, SecurityTokenParameters primaryTokenParameters, IList<SupportingTokenAuthenticatorSpecification> supportingTokenAuthenticators)492 public void ConfigureSymmetricBindingServerReceiveHeader(SecurityTokenAuthenticator primaryTokenAuthenticator, SecurityTokenParameters primaryTokenParameters, IList<SupportingTokenAuthenticatorSpecification> supportingTokenAuthenticators) 493 { 494 this.primaryTokenAuthenticator = primaryTokenAuthenticator; 495 this.primaryTokenParameters = primaryTokenParameters; 496 this.supportingTokenAuthenticators = supportingTokenAuthenticators; 497 } 498 499 // encrypted key case ConfigureSymmetricBindingServerReceiveHeader(SecurityToken wrappingToken, SecurityTokenParameters wrappingTokenParameters, IList<SupportingTokenAuthenticatorSpecification> supportingTokenAuthenticators)500 public void ConfigureSymmetricBindingServerReceiveHeader(SecurityToken wrappingToken, SecurityTokenParameters wrappingTokenParameters, IList<SupportingTokenAuthenticatorSpecification> supportingTokenAuthenticators) 501 { 502 this.wrappingToken = wrappingToken; 503 this.wrappingTokenParameters = wrappingTokenParameters; 504 this.supportingTokenAuthenticators = supportingTokenAuthenticators; 505 } 506 ConfigureAsymmetricBindingServerReceiveHeader(SecurityTokenAuthenticator primaryTokenAuthenticator, SecurityTokenParameters primaryTokenParameters, SecurityToken wrappingToken, SecurityTokenParameters wrappingTokenParameters, IList<SupportingTokenAuthenticatorSpecification> supportingTokenAuthenticators)507 public void ConfigureAsymmetricBindingServerReceiveHeader(SecurityTokenAuthenticator primaryTokenAuthenticator, SecurityTokenParameters primaryTokenParameters, SecurityToken wrappingToken, SecurityTokenParameters wrappingTokenParameters, IList<SupportingTokenAuthenticatorSpecification> supportingTokenAuthenticators) 508 { 509 this.primaryTokenAuthenticator = primaryTokenAuthenticator; 510 this.primaryTokenParameters = primaryTokenParameters; 511 this.wrappingToken = wrappingToken; 512 this.wrappingTokenParameters = wrappingTokenParameters; 513 this.supportingTokenAuthenticators = supportingTokenAuthenticators; 514 } 515 ConfigureTransportBindingServerReceiveHeader(IList<SupportingTokenAuthenticatorSpecification> supportingTokenAuthenticators)516 public void ConfigureTransportBindingServerReceiveHeader(IList<SupportingTokenAuthenticatorSpecification> supportingTokenAuthenticators) 517 { 518 this.supportingTokenAuthenticators = supportingTokenAuthenticators; 519 } 520 ConfigureAsymmetricBindingClientReceiveHeader(SecurityToken primaryToken, SecurityTokenParameters primaryTokenParameters, SecurityToken encryptionToken, SecurityTokenParameters encryptionTokenParameters, SecurityTokenAuthenticator primaryTokenAuthenticator)521 public void ConfigureAsymmetricBindingClientReceiveHeader(SecurityToken primaryToken, SecurityTokenParameters primaryTokenParameters, SecurityToken encryptionToken, SecurityTokenParameters encryptionTokenParameters, SecurityTokenAuthenticator primaryTokenAuthenticator) 522 { 523 this.outOfBandPrimaryToken = primaryToken; 524 this.primaryTokenParameters = primaryTokenParameters; 525 this.primaryTokenAuthenticator = primaryTokenAuthenticator; 526 this.allowFirstTokenMismatch = primaryTokenAuthenticator != null; 527 if (encryptionToken != null && !SecurityUtils.HasSymmetricSecurityKey(encryptionToken)) 528 { 529 this.wrappingToken = encryptionToken; 530 this.wrappingTokenParameters = encryptionTokenParameters; 531 } 532 else 533 { 534 this.expectedEncryptionToken = encryptionToken; 535 this.expectedEncryptionTokenParameters = encryptionTokenParameters; 536 } 537 } 538 ConfigureSymmetricBindingClientReceiveHeader(SecurityToken primaryToken, SecurityTokenParameters primaryTokenParameters)539 public void ConfigureSymmetricBindingClientReceiveHeader(SecurityToken primaryToken, SecurityTokenParameters primaryTokenParameters) 540 { 541 this.outOfBandPrimaryToken = primaryToken; 542 this.primaryTokenParameters = primaryTokenParameters; 543 } 544 ConfigureSymmetricBindingClientReceiveHeader(IList<SecurityToken> primaryTokens, SecurityTokenParameters primaryTokenParameters)545 public void ConfigureSymmetricBindingClientReceiveHeader(IList<SecurityToken> primaryTokens, SecurityTokenParameters primaryTokenParameters) 546 { 547 this.outOfBandPrimaryTokenCollection = primaryTokens; 548 this.primaryTokenParameters = primaryTokenParameters; 549 } 550 ConfigureOutOfBandTokenResolver(ReadOnlyCollection<SecurityTokenResolver> outOfBandResolvers)551 public void ConfigureOutOfBandTokenResolver(ReadOnlyCollection<SecurityTokenResolver> outOfBandResolvers) 552 { 553 if (outOfBandResolvers == null) 554 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("outOfBandResolvers"); 555 if (outOfBandResolvers.Count == 0) 556 { 557 return; 558 } 559 this.outOfBandTokenResolver = outOfBandResolvers; 560 } 561 ReadSecurityHeaderEncryptedItem(XmlDictionaryReader reader, bool readXmlreferenceKeyInfoClause)562 protected abstract EncryptedData ReadSecurityHeaderEncryptedItem(XmlDictionaryReader reader, bool readXmlreferenceKeyInfoClause); 563 DecryptSecurityHeaderElement(EncryptedData encryptedData, WrappedKeySecurityToken wrappedKeyToken, out SecurityToken encryptionToken)564 protected abstract byte[] DecryptSecurityHeaderElement(EncryptedData encryptedData, WrappedKeySecurityToken wrappedKeyToken, out SecurityToken encryptionToken); 565 DecryptWrappedKey(XmlDictionaryReader reader)566 protected abstract WrappedKeySecurityToken DecryptWrappedKey(XmlDictionaryReader reader); 567 GetSentSignatureValues()568 public SignatureConfirmations GetSentSignatureValues() 569 { 570 return this.receivedSignatureValues; 571 } 572 IsReaderAtEncryptedKey(XmlDictionaryReader reader)573 protected abstract bool IsReaderAtEncryptedKey(XmlDictionaryReader reader); 574 IsReaderAtEncryptedData(XmlDictionaryReader reader)575 protected abstract bool IsReaderAtEncryptedData(XmlDictionaryReader reader); 576 IsReaderAtReferenceList(XmlDictionaryReader reader)577 protected abstract bool IsReaderAtReferenceList(XmlDictionaryReader reader); 578 IsReaderAtSignature(XmlDictionaryReader reader)579 protected abstract bool IsReaderAtSignature(XmlDictionaryReader reader); 580 IsReaderAtSecurityTokenReference(XmlDictionaryReader reader)581 protected abstract bool IsReaderAtSecurityTokenReference(XmlDictionaryReader reader); 582 OnDecryptionOfSecurityHeaderItemRequiringReferenceListEntry(string id)583 protected abstract void OnDecryptionOfSecurityHeaderItemRequiringReferenceListEntry(string id); 584 MarkHeaderAsUnderstood()585 void MarkHeaderAsUnderstood() 586 { 587 // header decryption does not reorder or delete headers 588 MessageHeaderInfo header = this.Message.Headers[this.headerIndex]; 589 Fx.Assert(header.Name == this.Name && header.Namespace == this.Namespace && header.Actor == this.Actor, "security header index mismatch"); 590 Message.Headers.UnderstoodHeaders.Add(header); 591 } 592 OnWriteStartHeader(XmlDictionaryWriter writer, MessageVersion messageVersion)593 protected override void OnWriteStartHeader(XmlDictionaryWriter writer, MessageVersion messageVersion) 594 { 595 this.StandardsManager.SecurityVersion.WriteStartHeader(writer); 596 XmlAttributeHolder[] attributes = this.securityElementAttributes; 597 for (int i = 0; i < attributes.Length; ++i) 598 { 599 writer.WriteAttributeString(attributes[i].Prefix, attributes[i].LocalName, attributes[i].NamespaceUri, attributes[i].Value); 600 } 601 } 602 OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)603 protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion) 604 { 605 XmlDictionaryReader securityHeaderReader = GetReaderAtSecurityHeader(); 606 securityHeaderReader.ReadStartElement(); 607 for (int i = 0; i < this.ElementManager.Count; ++i) 608 { 609 ReceiveSecurityHeaderEntry entry; 610 this.ElementManager.GetElementEntry(i, out entry); 611 XmlDictionaryReader reader = null; 612 if (entry.encrypted) 613 { 614 reader = this.ElementManager.GetReader(i, false); 615 writer.WriteNode(reader, false); 616 reader.Close(); 617 securityHeaderReader.Skip(); 618 } 619 else 620 { 621 writer.WriteNode(securityHeaderReader, false); 622 } 623 } 624 securityHeaderReader.Close(); 625 } 626 GetReaderAtSecurityHeader()627 XmlDictionaryReader GetReaderAtSecurityHeader() 628 { 629 XmlDictionaryReader reader = this.SecurityVerifiedMessage.GetReaderAtFirstHeader(); 630 for (int i = 0; i < this.HeaderIndex; ++i) 631 { 632 reader.Skip(); 633 } 634 635 return reader; 636 } 637 EnsureSupportingTokens(ref Collection<SecurityToken> list)638 Collection<SecurityToken> EnsureSupportingTokens(ref Collection<SecurityToken> list) 639 { 640 if (list == null) 641 list = new Collection<SecurityToken>(); 642 return list; 643 } 644 VerifySupportingToken(TokenTracker tracker)645 void VerifySupportingToken(TokenTracker tracker) 646 { 647 if (tracker == null) 648 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("tracker"); 649 650 Fx.Assert(tracker.spec != null, "Supporting token trackers cannot have null specification."); 651 652 SupportingTokenAuthenticatorSpecification spec = tracker.spec; 653 654 if (tracker.token == null) 655 { 656 if (spec.IsTokenOptional) 657 return; 658 else 659 throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.SupportingTokenNotProvided, spec.TokenParameters, spec.SecurityTokenAttachmentMode))); 660 } 661 switch (spec.SecurityTokenAttachmentMode) 662 { 663 case SecurityTokenAttachmentMode.Endorsing: 664 if (!tracker.IsEndorsing) 665 { 666 throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.SupportingTokenIsNotEndorsing, spec.TokenParameters))); 667 } 668 if (this.EnforceDerivedKeyRequirement && spec.TokenParameters.RequireDerivedKeys && !spec.TokenParameters.HasAsymmetricKey && !tracker.IsDerivedFrom) 669 { 670 throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.SupportingSignatureIsNotDerivedFrom, spec.TokenParameters))); 671 } 672 EnsureSupportingTokens(ref endorsingTokens).Add(tracker.token); 673 break; 674 case SecurityTokenAttachmentMode.Signed: 675 if (!tracker.IsSigned && this.RequireMessageProtection) 676 { 677 throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.SupportingTokenIsNotSigned, spec.TokenParameters))); 678 } 679 EnsureSupportingTokens(ref signedTokens).Add(tracker.token); 680 break; 681 case SecurityTokenAttachmentMode.SignedEncrypted: 682 if (!tracker.IsSigned && this.RequireMessageProtection) 683 { 684 throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.SupportingTokenIsNotSigned, spec.TokenParameters))); 685 } 686 if (!tracker.IsEncrypted && this.RequireMessageProtection) 687 { 688 throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.SupportingTokenIsNotEncrypted, spec.TokenParameters))); 689 } 690 EnsureSupportingTokens(ref basicTokens).Add(tracker.token); 691 break; 692 case SecurityTokenAttachmentMode.SignedEndorsing: 693 if (!tracker.IsSigned && this.RequireMessageProtection) 694 { 695 throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.SupportingTokenIsNotSigned, spec.TokenParameters))); 696 } 697 if (!tracker.IsEndorsing) 698 { 699 throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.SupportingTokenIsNotEndorsing, spec.TokenParameters))); 700 } 701 if (this.EnforceDerivedKeyRequirement && spec.TokenParameters.RequireDerivedKeys && !spec.TokenParameters.HasAsymmetricKey && !tracker.IsDerivedFrom) 702 { 703 throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.SupportingSignatureIsNotDerivedFrom, spec.TokenParameters))); 704 } 705 EnsureSupportingTokens(ref signedEndorsingTokens).Add(tracker.token); 706 break; 707 708 default: 709 Fx.Assert("Unknown token attachment mode " + spec.SecurityTokenAttachmentMode); 710 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.UnknownTokenAttachmentMode, spec.SecurityTokenAttachmentMode))); 711 } 712 } 713 714 // replay detection done if enableReplayDetection is set to true. SetTimeParameters(NonceCache nonceCache, TimeSpan replayWindow, TimeSpan clockSkew)715 public void SetTimeParameters(NonceCache nonceCache, TimeSpan replayWindow, TimeSpan clockSkew) 716 { 717 this.nonceCache = nonceCache; 718 this.replayWindow = replayWindow; 719 this.clockSkew = clockSkew; 720 } 721 Process(TimeSpan timeout, ChannelBinding channelBinding, ExtendedProtectionPolicy extendedProtectionPolicy)722 public void Process(TimeSpan timeout, ChannelBinding channelBinding, ExtendedProtectionPolicy extendedProtectionPolicy) 723 { 724 Fx.Assert(this.ReaderQuotas != null, "Reader quotas must be set before processing"); 725 MessageProtectionOrder actualProtectionOrder = this.protectionOrder; 726 bool wasProtectionOrderDowngraded = false; 727 if (this.protectionOrder == MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature) 728 { 729 if (this.RequiredEncryptionParts == null || !this.RequiredEncryptionParts.IsBodyIncluded) 730 { 731 // Let's downgrade for now. If after signature verification we find a header that 732 // is signed and encrypted, we will check for signature encryption too. 733 actualProtectionOrder = MessageProtectionOrder.SignBeforeEncrypt; 734 wasProtectionOrderDowngraded = true; 735 } 736 } 737 738 this.channelBinding = channelBinding; 739 this.extendedProtectionPolicy = extendedProtectionPolicy; 740 this.orderTracker.SetRequiredProtectionOrder(actualProtectionOrder); 741 742 SetProcessingStarted(); 743 this.timeoutHelper = new TimeoutHelper(timeout); 744 this.Message = this.securityVerifiedMessage = new SecurityVerifiedMessage(this.Message, this); 745 XmlDictionaryReader reader = CreateSecurityHeaderReader(); 746 reader.MoveToStartElement(); 747 if (reader.IsEmptyElement) 748 { 749 throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.SecurityHeaderIsEmpty)), this.Message); 750 } 751 if (this.RequireMessageProtection) 752 { 753 this.securityElementAttributes = XmlAttributeHolder.ReadAttributes(reader); 754 } 755 else 756 { 757 this.securityElementAttributes = XmlAttributeHolder.emptyArray; 758 } 759 reader.ReadStartElement(); 760 761 if (this.primaryTokenParameters != null) 762 { 763 this.primaryTokenTracker = new TokenTracker(null, this.outOfBandPrimaryToken, this.allowFirstTokenMismatch); 764 } 765 // universalTokenResolver is used for resolving tokens 766 universalTokenResolver = new SecurityHeaderTokenResolver(this); 767 // primary token resolver is used for resolving primary signature and decryption 768 primaryTokenResolver = new SecurityHeaderTokenResolver(this); 769 if (this.outOfBandPrimaryToken != null) 770 { 771 universalTokenResolver.Add(this.outOfBandPrimaryToken, SecurityTokenReferenceStyle.External, this.primaryTokenParameters); 772 primaryTokenResolver.Add(this.outOfBandPrimaryToken, SecurityTokenReferenceStyle.External, this.primaryTokenParameters); 773 } 774 else if (this.outOfBandPrimaryTokenCollection != null) 775 { 776 for (int i = 0; i < this.outOfBandPrimaryTokenCollection.Count; ++i) 777 { 778 universalTokenResolver.Add(this.outOfBandPrimaryTokenCollection[i], SecurityTokenReferenceStyle.External, this.primaryTokenParameters); 779 primaryTokenResolver.Add(this.outOfBandPrimaryTokenCollection[i], SecurityTokenReferenceStyle.External, this.primaryTokenParameters); 780 } 781 } 782 if (this.wrappingToken != null) 783 { 784 universalTokenResolver.ExpectedWrapper = this.wrappingToken; 785 universalTokenResolver.ExpectedWrapperTokenParameters = this.wrappingTokenParameters; 786 primaryTokenResolver.ExpectedWrapper = this.wrappingToken; 787 primaryTokenResolver.ExpectedWrapperTokenParameters = this.wrappingTokenParameters; 788 } 789 else if (expectedEncryptionToken != null) 790 { 791 universalTokenResolver.Add(expectedEncryptionToken, SecurityTokenReferenceStyle.External, expectedEncryptionTokenParameters); 792 primaryTokenResolver.Add(expectedEncryptionToken, SecurityTokenReferenceStyle.External, expectedEncryptionTokenParameters); 793 } 794 795 if (this.outOfBandTokenResolver == null) 796 { 797 this.combinedUniversalTokenResolver = this.universalTokenResolver; 798 this.combinedPrimaryTokenResolver = this.primaryTokenResolver; 799 } 800 else 801 { 802 this.combinedUniversalTokenResolver = new AggregateSecurityHeaderTokenResolver(this.universalTokenResolver, this.outOfBandTokenResolver); 803 this.combinedPrimaryTokenResolver = new AggregateSecurityHeaderTokenResolver(this.primaryTokenResolver, this.outOfBandTokenResolver); 804 } 805 806 allowedAuthenticators = new List<SecurityTokenAuthenticator>(); 807 if (this.primaryTokenAuthenticator != null) 808 { 809 allowedAuthenticators.Add(this.primaryTokenAuthenticator); 810 } 811 if (this.DerivedTokenAuthenticator != null) 812 { 813 allowedAuthenticators.Add(this.DerivedTokenAuthenticator); 814 } 815 pendingSupportingTokenAuthenticator = null; 816 int numSupportingTokensRequiringDerivation = 0; 817 if (this.supportingTokenAuthenticators != null && this.supportingTokenAuthenticators.Count > 0) 818 { 819 this.supportingTokenTrackers = new List<TokenTracker>(this.supportingTokenAuthenticators.Count); 820 for (int i = 0; i < this.supportingTokenAuthenticators.Count; ++i) 821 { 822 SupportingTokenAuthenticatorSpecification spec = this.supportingTokenAuthenticators[i]; 823 switch (spec.SecurityTokenAttachmentMode) 824 { 825 case SecurityTokenAttachmentMode.Endorsing: 826 this.hasEndorsingOrSignedEndorsingSupportingTokens = true; 827 break; 828 case SecurityTokenAttachmentMode.Signed: 829 this.hasAtLeastOneSupportingTokenExpectedToBeSigned = true; 830 break; 831 case SecurityTokenAttachmentMode.SignedEndorsing: 832 this.hasEndorsingOrSignedEndorsingSupportingTokens = true; 833 this.hasAtLeastOneSupportingTokenExpectedToBeSigned = true; 834 break; 835 case SecurityTokenAttachmentMode.SignedEncrypted: 836 this.hasAtLeastOneSupportingTokenExpectedToBeSigned = true; 837 break; 838 } 839 840 if ((this.primaryTokenAuthenticator != null) && (this.primaryTokenAuthenticator.GetType().Equals(spec.TokenAuthenticator.GetType()))) 841 { 842 pendingSupportingTokenAuthenticator = spec.TokenAuthenticator; 843 } 844 else 845 { 846 allowedAuthenticators.Add(spec.TokenAuthenticator); 847 } 848 if (spec.TokenParameters.RequireDerivedKeys && !spec.TokenParameters.HasAsymmetricKey && 849 (spec.SecurityTokenAttachmentMode == SecurityTokenAttachmentMode.Endorsing || spec.SecurityTokenAttachmentMode == SecurityTokenAttachmentMode.SignedEndorsing)) 850 { 851 ++numSupportingTokensRequiringDerivation; 852 } 853 this.supportingTokenTrackers.Add(new TokenTracker(spec)); 854 } 855 } 856 857 if (this.DerivedTokenAuthenticator != null) 858 { 859 // we expect key derivation. Compute quotas for derived keys 860 int maxKeyDerivationLengthInBits = this.AlgorithmSuite.DefaultEncryptionKeyDerivationLength >= this.AlgorithmSuite.DefaultSignatureKeyDerivationLength ? 861 this.AlgorithmSuite.DefaultEncryptionKeyDerivationLength : this.AlgorithmSuite.DefaultSignatureKeyDerivationLength; 862 this.maxDerivedKeyLength = maxKeyDerivationLengthInBits / 8; 863 // the upper bound of derived keys is (1 for primary signature + 1 for encryption + supporting token signatures requiring derivation)*2 864 // the multiplication by 2 is to take care of interop scenarios that may arise that require more derived keys than the lower bound. 865 this.maxDerivedKeys = (1 + 1 + numSupportingTokensRequiringDerivation) * 2; 866 } 867 868 SecurityHeaderElementInferenceEngine engine = SecurityHeaderElementInferenceEngine.GetInferenceEngine(this.Layout); 869 engine.ExecuteProcessingPasses(this, reader); 870 if (this.RequireMessageProtection) 871 { 872 this.ElementManager.EnsureAllRequiredSecurityHeaderTargetsWereProtected(); 873 ExecuteMessageProtectionPass(this.hasAtLeastOneSupportingTokenExpectedToBeSigned); 874 if (this.RequiredSignatureParts != null && this.SignatureToken == null) 875 { 876 throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.RequiredSignatureMissing)), this.Message); 877 } 878 } 879 880 EnsureDecryptionComplete(); 881 882 this.signatureTracker.SetDerivationSourceIfRequired(); 883 this.encryptionTracker.SetDerivationSourceIfRequired(); 884 if (this.EncryptionToken != null) 885 { 886 if (wrappingToken != null) 887 { 888 if (!(this.EncryptionToken is WrappedKeySecurityToken) || ((WrappedKeySecurityToken)this.EncryptionToken).WrappingToken != this.wrappingToken) 889 { 890 throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.EncryptedKeyWasNotEncryptedWithTheRequiredEncryptingToken, this.wrappingToken))); 891 } 892 } 893 else if (expectedEncryptionToken != null) 894 { 895 if (this.EncryptionToken != expectedEncryptionToken) 896 { 897 throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.MessageWasNotEncryptedWithTheRequiredEncryptingToken))); 898 } 899 } 900 else if (this.SignatureToken != null && this.EncryptionToken != this.SignatureToken) 901 { 902 throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.SignatureAndEncryptionTokenMismatch, this.SignatureToken, this.EncryptionToken))); 903 } 904 } 905 906 // ensure that the primary signature was signed with derived keys if required 907 if (this.EnforceDerivedKeyRequirement) 908 { 909 if (this.SignatureToken != null) 910 { 911 if (this.primaryTokenParameters != null) 912 { 913 if (this.primaryTokenParameters.RequireDerivedKeys && !this.primaryTokenParameters.HasAsymmetricKey && !this.primaryTokenTracker.IsDerivedFrom) 914 { 915 throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.PrimarySignatureWasNotSignedByDerivedKey, this.primaryTokenParameters))); 916 } 917 } 918 else if (this.wrappingTokenParameters != null && this.wrappingTokenParameters.RequireDerivedKeys) 919 { 920 if (!this.signatureTracker.IsDerivedToken) 921 { 922 throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.PrimarySignatureWasNotSignedByDerivedWrappedKey, this.wrappingTokenParameters))); 923 } 924 } 925 } 926 927 // verify that the encryption is using key derivation 928 if (this.EncryptionToken != null) 929 { 930 if (wrappingTokenParameters != null) 931 { 932 if (wrappingTokenParameters.RequireDerivedKeys && !this.encryptionTracker.IsDerivedToken) 933 { 934 throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.MessageWasNotEncryptedByDerivedWrappedKey, this.wrappingTokenParameters))); 935 } 936 } 937 else if (expectedEncryptionTokenParameters != null) 938 { 939 if (expectedEncryptionTokenParameters.RequireDerivedKeys && !this.encryptionTracker.IsDerivedToken) 940 { 941 throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.MessageWasNotEncryptedByDerivedEncryptionToken, this.expectedEncryptionTokenParameters))); 942 } 943 } 944 else if (primaryTokenParameters != null && !primaryTokenParameters.HasAsymmetricKey && primaryTokenParameters.RequireDerivedKeys && !this.encryptionTracker.IsDerivedToken) 945 { 946 throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.MessageWasNotEncryptedByDerivedEncryptionToken, this.primaryTokenParameters))); 947 } 948 } 949 } 950 951 if (wasProtectionOrderDowngraded && (this.BasicSupportingTokens != null) && (this.BasicSupportingTokens.Count > 0)) 952 { 953 // Basic tokens are always signed and encrypted. So check if Signatures 954 // are encrypted as well. 955 this.VerifySignatureEncryption(); 956 } 957 958 // verify all supporting token parameters have their requirements met 959 if (this.supportingTokenTrackers != null) 960 { 961 for (int i = 0; i < this.supportingTokenTrackers.Count; ++i) 962 { 963 VerifySupportingToken(this.supportingTokenTrackers[i]); 964 } 965 } 966 967 if (this.replayDetectionEnabled) 968 { 969 if (this.timestamp == null) 970 { 971 throw TraceUtility.ThrowHelperError(new MessageSecurityException( 972 SR.GetString(SR.NoTimestampAvailableInSecurityHeaderToDoReplayDetection)), this.Message); 973 } 974 if (this.primarySignatureValue == null) 975 { 976 throw TraceUtility.ThrowHelperError(new MessageSecurityException( 977 SR.GetString(SR.NoSignatureAvailableInSecurityHeaderToDoReplayDetection)), this.Message); 978 } 979 980 AddNonce(this.nonceCache, this.primarySignatureValue); 981 982 // if replay detection is on, redo creation range checks to ensure full coverage 983 this.timestamp.ValidateFreshness(this.replayWindow, this.clockSkew); 984 } 985 986 if (this.ExpectSignatureConfirmation) 987 { 988 this.ElementManager.VerifySignatureConfirmationWasFound(); 989 } 990 991 MarkHeaderAsUnderstood(); 992 } 993 AddNonce(NonceCache cache, byte[] nonce)994 static void AddNonce(NonceCache cache, byte[] nonce) 995 { 996 if (!cache.TryAddNonce(nonce)) 997 { 998 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.InvalidOrReplayedNonce), true)); 999 } 1000 } 1001 CheckNonce(NonceCache cache, byte[] nonce)1002 static void CheckNonce(NonceCache cache, byte[] nonce) 1003 { 1004 if (cache.CheckNonce(nonce)) 1005 { 1006 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.InvalidOrReplayedNonce), true)); 1007 } 1008 } 1009 EnsureDecryptionComplete()1010 protected abstract void EnsureDecryptionComplete(); 1011 ExecuteMessageProtectionPass(bool hasAtLeastOneSupportingTokenExpectedToBeSigned)1012 protected abstract void ExecuteMessageProtectionPass(bool hasAtLeastOneSupportingTokenExpectedToBeSigned); 1013 ExecuteSignatureEncryptionProcessingPass()1014 internal void ExecuteSignatureEncryptionProcessingPass() 1015 { 1016 for (int position = 0; position < this.elementManager.Count; position++) 1017 { 1018 ReceiveSecurityHeaderEntry entry; 1019 this.elementManager.GetElementEntry(position, out entry); 1020 switch (entry.elementCategory) 1021 { 1022 case ReceiveSecurityHeaderElementCategory.Signature: 1023 if (entry.bindingMode == ReceiveSecurityHeaderBindingModes.Primary) 1024 { 1025 ProcessPrimarySignature((SignedXml)entry.element, entry.encrypted); 1026 } 1027 else 1028 { 1029 ProcessSupportingSignature((SignedXml)entry.element, entry.encrypted); 1030 } 1031 break; 1032 case ReceiveSecurityHeaderElementCategory.ReferenceList: 1033 ProcessReferenceList((ReferenceList)entry.element); 1034 break; 1035 case ReceiveSecurityHeaderElementCategory.Token: 1036 WrappedKeySecurityToken wrappedKeyToken = entry.element as WrappedKeySecurityToken; 1037 if ((wrappedKeyToken != null) && (wrappedKeyToken.ReferenceList != null)) 1038 { 1039 Fx.Assert(this.Layout != SecurityHeaderLayout.Strict, "Invalid Calling sequence. This method assumes it will be called only during Lax mode."); 1040 // ExecuteSignatureEncryptionProcessingPass is called only durng Lax mode. In this 1041 // case when we have a EncryptedKey with a ReferencList inside it, we would not 1042 // have processed the ReferenceList during reading pass. Process this here. 1043 ProcessReferenceList(wrappedKeyToken.ReferenceList, wrappedKeyToken); 1044 } 1045 break; 1046 case ReceiveSecurityHeaderElementCategory.Timestamp: 1047 case ReceiveSecurityHeaderElementCategory.EncryptedKey: 1048 case ReceiveSecurityHeaderElementCategory.EncryptedData: 1049 case ReceiveSecurityHeaderElementCategory.SignatureConfirmation: 1050 case ReceiveSecurityHeaderElementCategory.SecurityTokenReference: 1051 // no op 1052 break; 1053 default: 1054 Fx.Assert("invalid element category"); 1055 break; 1056 } 1057 } 1058 } 1059 ExecuteSubheaderDecryptionPass()1060 internal void ExecuteSubheaderDecryptionPass() 1061 { 1062 for (int position = 0; position < this.elementManager.Count; position++) 1063 { 1064 if (this.elementManager.GetElementCategory(position) == ReceiveSecurityHeaderElementCategory.EncryptedData) 1065 { 1066 EncryptedData encryptedData = this.elementManager.GetElement<EncryptedData>(position); 1067 bool dummy = false; 1068 ProcessEncryptedData(encryptedData, this.timeoutHelper.RemainingTime(), position, false, ref dummy); 1069 } 1070 } 1071 } 1072 ExecuteReadingPass(XmlDictionaryReader reader)1073 internal void ExecuteReadingPass(XmlDictionaryReader reader) 1074 { 1075 int position = 0; 1076 while (reader.IsStartElement()) 1077 { 1078 if (IsReaderAtSignature(reader)) 1079 { 1080 ReadSignature(reader, AppendPosition, null); 1081 } 1082 else if (IsReaderAtReferenceList(reader)) 1083 { 1084 ReadReferenceList(reader); 1085 } 1086 else if (this.StandardsManager.WSUtilitySpecificationVersion.IsReaderAtTimestamp(reader)) 1087 { 1088 ReadTimestamp(reader); 1089 } 1090 else if (IsReaderAtEncryptedKey(reader)) 1091 { 1092 ReadEncryptedKey(reader, false); 1093 } 1094 else if (IsReaderAtEncryptedData(reader)) 1095 { 1096 ReadEncryptedData(reader); 1097 } 1098 else if (this.StandardsManager.SecurityVersion.IsReaderAtSignatureConfirmation(reader)) 1099 { 1100 ReadSignatureConfirmation(reader, AppendPosition, null); 1101 } 1102 else if (IsReaderAtSecurityTokenReference(reader)) 1103 { 1104 ReadSecurityTokenReference(reader); 1105 } 1106 else 1107 { 1108 ReadToken(reader, AppendPosition, null, null, null, this.timeoutHelper.RemainingTime()); 1109 } 1110 position++; 1111 } 1112 1113 reader.ReadEndElement(); // wsse:Security 1114 reader.Close(); 1115 } 1116 ExecuteFullPass(XmlDictionaryReader reader)1117 internal void ExecuteFullPass(XmlDictionaryReader reader) 1118 { 1119 bool primarySignatureFound = !this.RequireMessageProtection; 1120 int position = 0; 1121 while (reader.IsStartElement()) 1122 { 1123 if (IsReaderAtSignature(reader)) 1124 { 1125 SignedXml signedXml = ReadSignature(reader, AppendPosition, null); 1126 if (primarySignatureFound) 1127 { 1128 this.elementManager.SetBindingMode(position, ReceiveSecurityHeaderBindingModes.Endorsing); 1129 ProcessSupportingSignature(signedXml, false); 1130 } 1131 else 1132 { 1133 primarySignatureFound = true; 1134 this.elementManager.SetBindingMode(position, ReceiveSecurityHeaderBindingModes.Primary); 1135 ProcessPrimarySignature(signedXml, false); 1136 } 1137 } 1138 else if (IsReaderAtReferenceList(reader)) 1139 { 1140 ReferenceList referenceList = ReadReferenceList(reader); 1141 ProcessReferenceList(referenceList); 1142 } 1143 else if (this.StandardsManager.WSUtilitySpecificationVersion.IsReaderAtTimestamp(reader)) 1144 { 1145 ReadTimestamp(reader); 1146 } 1147 else if (IsReaderAtEncryptedKey(reader)) 1148 { 1149 ReadEncryptedKey(reader, true); 1150 } 1151 else if (IsReaderAtEncryptedData(reader)) 1152 { 1153 EncryptedData encryptedData = ReadEncryptedData(reader); 1154 ProcessEncryptedData(encryptedData, this.timeoutHelper.RemainingTime(), position, true, ref primarySignatureFound); 1155 } 1156 else if (this.StandardsManager.SecurityVersion.IsReaderAtSignatureConfirmation(reader)) 1157 { 1158 ReadSignatureConfirmation(reader, AppendPosition, null); 1159 } 1160 else if (IsReaderAtSecurityTokenReference(reader)) 1161 { 1162 ReadSecurityTokenReference(reader); 1163 } 1164 else 1165 { 1166 ReadToken(reader, AppendPosition, null, null, null, this.timeoutHelper.RemainingTime()); 1167 } 1168 position++; 1169 } 1170 1171 reader.ReadEndElement(); // wsse:Security 1172 reader.Close(); 1173 } 1174 EnsureDerivedKeyLimitNotReached()1175 internal void EnsureDerivedKeyLimitNotReached() 1176 { 1177 ++this.numDerivedKeys; 1178 if (this.numDerivedKeys > this.maxDerivedKeys) 1179 { 1180 throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.DerivedKeyLimitExceeded, maxDerivedKeys))); 1181 } 1182 } 1183 ExecuteDerivedKeyTokenStubPass(bool isFinalPass)1184 internal void ExecuteDerivedKeyTokenStubPass(bool isFinalPass) 1185 { 1186 for (int position = 0; position < this.elementManager.Count; position++) 1187 { 1188 if (this.elementManager.GetElementCategory(position) == ReceiveSecurityHeaderElementCategory.Token) 1189 { 1190 DerivedKeySecurityTokenStub stub = this.elementManager.GetElement(position) as DerivedKeySecurityTokenStub; 1191 if (stub != null) 1192 { 1193 SecurityToken sourceToken = null; 1194 this.universalTokenResolver.TryResolveToken(stub.TokenToDeriveIdentifier, out sourceToken); 1195 if (sourceToken != null) 1196 { 1197 EnsureDerivedKeyLimitNotReached(); 1198 DerivedKeySecurityToken derivedKeyToken = stub.CreateToken(sourceToken, this.maxDerivedKeyLength); 1199 this.elementManager.SetElement(position, derivedKeyToken); 1200 AddDerivedKeyTokenToResolvers(derivedKeyToken); 1201 } 1202 else if (isFinalPass) 1203 { 1204 throw TraceUtility.ThrowHelperError(new MessageSecurityException( 1205 SR.GetString(SR.UnableToResolveKeyInfoClauseInDerivedKeyToken, stub.TokenToDeriveIdentifier)), this.Message); 1206 } 1207 } 1208 } 1209 } 1210 } 1211 GetRootToken(SecurityToken token)1212 SecurityToken GetRootToken(SecurityToken token) 1213 { 1214 if (token is DerivedKeySecurityToken) 1215 { 1216 return ((DerivedKeySecurityToken)token).TokenToDerive; 1217 } 1218 else 1219 { 1220 return token; 1221 } 1222 } 1223 RecordEncryptionTokenAndRemoveReferenceListEntry(string id, SecurityToken encryptionToken)1224 void RecordEncryptionTokenAndRemoveReferenceListEntry(string id, SecurityToken encryptionToken) 1225 { 1226 if (id == null) 1227 { 1228 throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.MissingIdInEncryptedElement)), this.Message); 1229 } 1230 1231 OnDecryptionOfSecurityHeaderItemRequiringReferenceListEntry(id); 1232 RecordEncryptionToken(encryptionToken); 1233 } 1234 ReadEncryptedData(XmlDictionaryReader reader)1235 EncryptedData ReadEncryptedData(XmlDictionaryReader reader) 1236 { 1237 EncryptedData encryptedData = ReadSecurityHeaderEncryptedItem(reader, this.MessageDirection == MessageDirection.Output); 1238 1239 this.elementManager.AppendEncryptedData(encryptedData); 1240 return encryptedData; 1241 } 1242 CreateDecryptedReader(byte[] decryptedBuffer)1243 internal XmlDictionaryReader CreateDecryptedReader(byte[] decryptedBuffer) 1244 { 1245 return ContextImportHelper.CreateSplicedReader( 1246 decryptedBuffer, 1247 this.SecurityVerifiedMessage.GetEnvelopeAttributes(), 1248 this.SecurityVerifiedMessage.GetHeaderAttributes(), 1249 this.securityElementAttributes, 1250 this.ReaderQuotas 1251 ); 1252 } 1253 ProcessEncryptedData(EncryptedData encryptedData, TimeSpan timeout, int position, bool eagerMode, ref bool primarySignatureFound)1254 void ProcessEncryptedData(EncryptedData encryptedData, TimeSpan timeout, int position, bool eagerMode, ref bool primarySignatureFound) 1255 { 1256 if (TD.EncryptedDataProcessingStartIsEnabled()) 1257 { 1258 TD.EncryptedDataProcessingStart(this.EventTraceActivity); 1259 } 1260 1261 string id = encryptedData.Id; 1262 1263 SecurityToken encryptionToken; 1264 byte[] decryptedBuffer = DecryptSecurityHeaderElement(encryptedData, this.wrappedKeyToken, out encryptionToken); 1265 1266 XmlDictionaryReader decryptedReader = CreateDecryptedReader(decryptedBuffer); 1267 1268 if (IsReaderAtSignature(decryptedReader)) 1269 { 1270 RecordEncryptionTokenAndRemoveReferenceListEntry(id, encryptionToken); 1271 SignedXml signedXml = ReadSignature(decryptedReader, position, decryptedBuffer); 1272 if (eagerMode) 1273 { 1274 if (primarySignatureFound) 1275 { 1276 this.elementManager.SetBindingMode(position, ReceiveSecurityHeaderBindingModes.Endorsing); 1277 ProcessSupportingSignature(signedXml, true); 1278 } 1279 else 1280 { 1281 primarySignatureFound = true; 1282 this.elementManager.SetBindingMode(position, ReceiveSecurityHeaderBindingModes.Primary); 1283 ProcessPrimarySignature(signedXml, true); 1284 } 1285 } 1286 } 1287 else if (this.StandardsManager.SecurityVersion.IsReaderAtSignatureConfirmation(decryptedReader)) 1288 { 1289 RecordEncryptionTokenAndRemoveReferenceListEntry(id, encryptionToken); 1290 ReadSignatureConfirmation(decryptedReader, position, decryptedBuffer); 1291 } 1292 else 1293 { 1294 if (IsReaderAtEncryptedData(decryptedReader)) 1295 { 1296 1297 // The purpose of this code is to process a token that arrived at a client as encryptedData. 1298 1299 // This is a common scenario for supporting tokens. 1300 1301 // We pass readXmlReferenceKeyIdentifierClause as false here because we do not expect the client 1302 // to receive an encrypted token for itself from the service. The encrypted token is encrypted for some other service. 1303 // Hence we assume that the KeyInfoClause entry in it is not an XMLReference entry that the client is supposed to understand. 1304 1305 // What if the service sends its authentication token as an EncryptedData to the client? 1306 1307 EncryptedData ed = ReadSecurityHeaderEncryptedItem(decryptedReader, false); 1308 SecurityToken securityToken; 1309 byte[] db = DecryptSecurityHeaderElement(ed, this.wrappedKeyToken, out securityToken); 1310 XmlDictionaryReader dr = CreateDecryptedReader(db); 1311 1312 1313 // read the actual token and put it into the system 1314 ReadToken(dr, position, db, encryptionToken, id, timeout); 1315 1316 ReceiveSecurityHeaderEntry rshe; 1317 this.ElementManager.GetElementEntry(position, out rshe); 1318 1319 // In EncryptBeforeSignMode, we have encrypted the outer token, remember the right id. 1320 // The reason why I have both id's is in that case that one or the other is passed 1321 // we won't have a problem with which one. SHP accounting should ensure each item has 1322 // the correct hash. 1323 if (this.EncryptBeforeSignMode) 1324 { 1325 rshe.encryptedFormId = encryptedData.Id; 1326 rshe.encryptedFormWsuId = encryptedData.WsuId; 1327 } 1328 else 1329 { 1330 rshe.encryptedFormId = ed.Id; 1331 rshe.encryptedFormWsuId = ed.WsuId; 1332 } 1333 1334 rshe.decryptedBuffer = decryptedBuffer; 1335 1336 // setting this to true, will allow a different id match in ReceiveSecurityHeaderEntry.Match 1337 // to one of the ids set above as the token id will not match what the signature reference is looking for. 1338 1339 rshe.doubleEncrypted = true; 1340 1341 this.ElementManager.ReplaceHeaderEntry(position, rshe); 1342 } 1343 else 1344 ReadToken(decryptedReader, position, decryptedBuffer, encryptionToken, id, timeout); 1345 } 1346 1347 if (TD.EncryptedDataProcessingSuccessIsEnabled()) 1348 { 1349 TD.EncryptedDataProcessingSuccess(this.EventTraceActivity); 1350 } 1351 } 1352 ReadEncryptedKey(XmlDictionaryReader reader, bool processReferenceListIfPresent)1353 void ReadEncryptedKey(XmlDictionaryReader reader, bool processReferenceListIfPresent) 1354 { 1355 this.orderTracker.OnEncryptedKey(); 1356 1357 WrappedKeySecurityToken wrappedKeyToken = DecryptWrappedKey(reader); 1358 if (wrappedKeyToken.WrappingToken != this.wrappingToken) 1359 { 1360 throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.EncryptedKeyWasNotEncryptedWithTheRequiredEncryptingToken, this.wrappingToken))); 1361 } 1362 this.universalTokenResolver.Add(wrappedKeyToken); 1363 this.primaryTokenResolver.Add(wrappedKeyToken); 1364 if (wrappedKeyToken.ReferenceList != null) 1365 { 1366 if (!this.EncryptedKeyContainsReferenceList) 1367 { 1368 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.EncryptedKeyWithReferenceListNotAllowed))); 1369 } 1370 if (!this.ExpectEncryption) 1371 { 1372 throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.EncryptionNotExpected)), this.Message); 1373 } 1374 if (processReferenceListIfPresent) 1375 { 1376 ProcessReferenceList(wrappedKeyToken.ReferenceList, wrappedKeyToken); 1377 } 1378 this.wrappedKeyToken = wrappedKeyToken; 1379 } 1380 this.elementManager.AppendToken(wrappedKeyToken, ReceiveSecurityHeaderBindingModes.Primary, null); 1381 } 1382 ReadReferenceList(XmlDictionaryReader reader)1383 ReferenceList ReadReferenceList(XmlDictionaryReader reader) 1384 { 1385 if (!this.ExpectEncryption) 1386 { 1387 throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.EncryptionNotExpected)), this.Message); 1388 } 1389 ReferenceList referenceList = ReadReferenceListCore(reader); 1390 this.elementManager.AppendReferenceList(referenceList); 1391 return referenceList; 1392 } 1393 ReadReferenceListCore(XmlDictionaryReader reader)1394 protected abstract ReferenceList ReadReferenceListCore(XmlDictionaryReader reader); 1395 ProcessReferenceList(ReferenceList referenceList)1396 void ProcessReferenceList(ReferenceList referenceList) 1397 { 1398 ProcessReferenceList(referenceList, null); 1399 } 1400 ProcessReferenceList(ReferenceList referenceList, WrappedKeySecurityToken wrappedKeyToken)1401 void ProcessReferenceList(ReferenceList referenceList, WrappedKeySecurityToken wrappedKeyToken) 1402 { 1403 this.orderTracker.OnProcessReferenceList(); 1404 ProcessReferenceListCore(referenceList, wrappedKeyToken); 1405 } 1406 ProcessReferenceListCore(ReferenceList referenceList, WrappedKeySecurityToken wrappedKeyToken)1407 protected abstract void ProcessReferenceListCore(ReferenceList referenceList, WrappedKeySecurityToken wrappedKeyToken); 1408 ReadSignature(XmlDictionaryReader reader, int position, byte[] decryptedBuffer)1409 SignedXml ReadSignature(XmlDictionaryReader reader, int position, byte[] decryptedBuffer) 1410 { 1411 Fx.Assert((position == AppendPosition) == (decryptedBuffer == null), "inconsistent position, decryptedBuffer parameters"); 1412 if (!this.ExpectSignature) 1413 { 1414 throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.SignatureNotExpected)), this.Message); 1415 } 1416 SignedXml signedXml = ReadSignatureCore(reader); 1417 signedXml.Signature.SignedInfo.ReaderProvider = this.ElementManager; 1418 int readerIndex; 1419 if (decryptedBuffer == null) 1420 { 1421 this.elementManager.AppendSignature(signedXml); 1422 readerIndex = this.elementManager.Count - 1; 1423 } 1424 else 1425 { 1426 this.elementManager.SetSignatureAfterDecryption(position, signedXml, decryptedBuffer); 1427 readerIndex = position; 1428 } 1429 signedXml.Signature.SignedInfo.SignatureReaderProviderCallbackContext = (object)(readerIndex); 1430 return signedXml; 1431 } 1432 ReadSecurityTokenReference(XmlDictionaryReader reader)1433 protected abstract void ReadSecurityTokenReference(XmlDictionaryReader reader); 1434 ProcessPrimarySignature(SignedXml signedXml, bool isFromDecryptedSource)1435 void ProcessPrimarySignature(SignedXml signedXml, bool isFromDecryptedSource) 1436 { 1437 this.orderTracker.OnProcessSignature(isFromDecryptedSource); 1438 1439 this.primarySignatureValue = signedXml.GetSignatureValue(); 1440 if (this.replayDetectionEnabled) 1441 { 1442 CheckNonce(this.nonceCache, this.primarySignatureValue); 1443 } 1444 1445 SecurityToken signingToken = VerifySignature(signedXml, true, this.primaryTokenResolver, null, null); 1446 // verify that the signing token is the same as the primary token 1447 SecurityToken rootSigningToken = GetRootToken(signingToken); 1448 bool isDerivedKeySignature = signingToken is DerivedKeySecurityToken; 1449 if (this.primaryTokenTracker != null) 1450 { 1451 this.primaryTokenTracker.RecordToken(rootSigningToken); 1452 this.primaryTokenTracker.IsDerivedFrom = isDerivedKeySignature; 1453 } 1454 this.AddIncomingSignatureValue(signedXml.GetSignatureValue(), isFromDecryptedSource); 1455 } 1456 ReadSignatureConfirmation(XmlDictionaryReader reader, int position, byte[] decryptedBuffer)1457 void ReadSignatureConfirmation(XmlDictionaryReader reader, int position, byte[] decryptedBuffer) 1458 { 1459 Fx.Assert((position == AppendPosition) == (decryptedBuffer == null), "inconsistent position, decryptedBuffer parameters"); 1460 if (!this.ExpectSignatureConfirmation) 1461 { 1462 throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.SignatureConfirmationsNotExpected)), this.Message); 1463 } 1464 if (this.orderTracker.PrimarySignatureDone) 1465 { 1466 throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.SignatureConfirmationsOccursAfterPrimarySignature)), this.Message); 1467 } 1468 ISignatureValueSecurityElement sigConfElement = this.StandardsManager.SecurityVersion.ReadSignatureConfirmation(reader); 1469 if (decryptedBuffer == null) 1470 { 1471 this.AddIncomingSignatureConfirmation(sigConfElement.GetSignatureValue(), false); 1472 this.elementManager.AppendSignatureConfirmation(sigConfElement); 1473 } 1474 else 1475 { 1476 this.AddIncomingSignatureConfirmation(sigConfElement.GetSignatureValue(), true); 1477 this.elementManager.SetSignatureConfirmationAfterDecryption(position, sigConfElement, decryptedBuffer); 1478 } 1479 } 1480 GetSupportingTokenTracker(SecurityToken token)1481 TokenTracker GetSupportingTokenTracker(SecurityToken token) 1482 { 1483 if (this.supportingTokenTrackers == null) 1484 return null; 1485 for (int i = 0; i < this.supportingTokenTrackers.Count; ++i) 1486 { 1487 if (supportingTokenTrackers[i].token == token) 1488 return supportingTokenTrackers[i]; 1489 } 1490 return null; 1491 } 1492 GetSupportingTokenTracker(SecurityTokenAuthenticator tokenAuthenticator, out SupportingTokenAuthenticatorSpecification spec)1493 protected TokenTracker GetSupportingTokenTracker(SecurityTokenAuthenticator tokenAuthenticator, out SupportingTokenAuthenticatorSpecification spec) 1494 { 1495 spec = null; 1496 if (this.supportingTokenAuthenticators == null) 1497 return null; 1498 for (int i = 0; i < this.supportingTokenAuthenticators.Count; ++i) 1499 { 1500 if (supportingTokenAuthenticators[i].TokenAuthenticator == tokenAuthenticator) 1501 { 1502 spec = supportingTokenAuthenticators[i]; 1503 return supportingTokenTrackers[i]; 1504 } 1505 } 1506 return null; 1507 } 1508 1509 protected TAuthenticator FindAllowedAuthenticator<TAuthenticator>(bool removeIfPresent) 1510 where TAuthenticator : SecurityTokenAuthenticator 1511 { 1512 if (this.allowedAuthenticators == null) 1513 { 1514 return null; 1515 } 1516 for (int i = 0; i < this.allowedAuthenticators.Count; ++i) 1517 { 1518 if (allowedAuthenticators[i] is TAuthenticator) 1519 { 1520 TAuthenticator result = (TAuthenticator)allowedAuthenticators[i]; 1521 if (removeIfPresent) 1522 { 1523 this.allowedAuthenticators.RemoveAt(i); 1524 } 1525 return result; 1526 } 1527 } 1528 return null; 1529 } 1530 ProcessSupportingSignature(SignedXml signedXml, bool isFromDecryptedSource)1531 void ProcessSupportingSignature(SignedXml signedXml, bool isFromDecryptedSource) 1532 { 1533 if (!this.ExpectEndorsingTokens) 1534 { 1535 throw TraceUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SupportingTokenSignaturesNotExpected)), this.Message); 1536 } 1537 string id; 1538 XmlDictionaryReader reader; 1539 object signatureTarget; 1540 if (!this.RequireMessageProtection) 1541 { 1542 if (this.timestamp == null) 1543 { 1544 throw TraceUtility.ThrowHelperError(new MessageSecurityException( 1545 SR.GetString(SR.SigningWithoutPrimarySignatureRequiresTimestamp)), this.Message); 1546 } 1547 reader = null; 1548 id = this.timestamp.Id; 1549 // We would have pre-computed the timestamp digest, if the transport reader 1550 // was capable of canonicalization. If we were not able to compute the digest 1551 // before hand then the signature verification step will get a new reader 1552 // and will recompute the digest. 1553 signatureTarget = null; 1554 } 1555 else 1556 { 1557 this.elementManager.GetPrimarySignature(out reader, out id); 1558 if (reader == null) 1559 { 1560 throw TraceUtility.ThrowHelperError(new MessageSecurityException( 1561 SR.GetString(SR.NoPrimarySignatureAvailableForSupportingTokenSignatureVerification)), this.Message); 1562 } 1563 signatureTarget = reader; 1564 } 1565 SecurityToken signingToken = VerifySignature(signedXml, false, this.universalTokenResolver, signatureTarget, id); 1566 if (reader != null) 1567 { 1568 reader.Close(); 1569 } 1570 if (signingToken == null) 1571 { 1572 throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.SignatureVerificationFailed)), this.Message); 1573 } 1574 SecurityToken rootSigningToken = GetRootToken(signingToken); 1575 TokenTracker tracker = GetSupportingTokenTracker(rootSigningToken); 1576 if (tracker == null) 1577 { 1578 throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.UnknownSupportingToken, signingToken))); 1579 } 1580 1581 if (tracker.AlreadyReadEndorsingSignature) 1582 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.MoreThanOneSupportingSignature, signingToken))); 1583 1584 tracker.IsEndorsing = true; 1585 tracker.AlreadyReadEndorsingSignature = true; 1586 tracker.IsDerivedFrom = (signingToken is DerivedKeySecurityToken); 1587 AddIncomingSignatureValue(signedXml.GetSignatureValue(), isFromDecryptedSource); 1588 } 1589 ReadTimestamp(XmlDictionaryReader reader)1590 void ReadTimestamp(XmlDictionaryReader reader) 1591 { 1592 if (this.timestamp != null) 1593 { 1594 throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.DuplicateTimestampInSecurityHeader)), this.Message); 1595 } 1596 bool expectTimestampToBeSigned = this.RequireMessageProtection || this.hasEndorsingOrSignedEndorsingSupportingTokens; 1597 string expectedDigestAlgorithm = expectTimestampToBeSigned ? this.AlgorithmSuite.DefaultDigestAlgorithm : null; 1598 SignatureResourcePool resourcePool = expectTimestampToBeSigned ? this.ResourcePool : null; 1599 this.timestamp = this.StandardsManager.WSUtilitySpecificationVersion.ReadTimestamp(reader, expectedDigestAlgorithm, resourcePool); 1600 this.timestamp.ValidateRangeAndFreshness(this.replayWindow, this.clockSkew); 1601 this.elementManager.AppendTimestamp(this.timestamp); 1602 } 1603 IsPrimaryToken(SecurityToken token)1604 bool IsPrimaryToken(SecurityToken token) 1605 { 1606 bool result = (token == outOfBandPrimaryToken 1607 || (primaryTokenTracker != null && token == primaryTokenTracker.token) 1608 || (token == expectedEncryptionToken) 1609 || ((token is WrappedKeySecurityToken) && ((WrappedKeySecurityToken)token).WrappingToken == this.wrappingToken)); 1610 if (!result && this.outOfBandPrimaryTokenCollection != null) 1611 { 1612 for (int i = 0; i < this.outOfBandPrimaryTokenCollection.Count; ++i) 1613 { 1614 if (this.outOfBandPrimaryTokenCollection[i] == token) 1615 { 1616 result = true; 1617 break; 1618 } 1619 } 1620 } 1621 return result; 1622 } 1623 ReadToken(XmlDictionaryReader reader, int position, byte[] decryptedBuffer, SecurityToken encryptionToken, string idInEncryptedForm, TimeSpan timeout)1624 void ReadToken(XmlDictionaryReader reader, int position, byte[] decryptedBuffer, 1625 SecurityToken encryptionToken, string idInEncryptedForm, TimeSpan timeout) 1626 { 1627 Fx.Assert((position == AppendPosition) == (decryptedBuffer == null), "inconsistent position, decryptedBuffer parameters"); 1628 Fx.Assert((position == AppendPosition) == (encryptionToken == null), "inconsistent position, encryptionToken parameters"); 1629 string localName = reader.LocalName; 1630 string namespaceUri = reader.NamespaceURI; 1631 string valueType = reader.GetAttribute(XD.SecurityJan2004Dictionary.ValueType, null); 1632 1633 SecurityTokenAuthenticator usedTokenAuthenticator; 1634 SecurityToken token = ReadToken(reader, this.CombinedUniversalTokenResolver, allowedAuthenticators, out usedTokenAuthenticator); 1635 if (token == null) 1636 { 1637 throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.TokenManagerCouldNotReadToken, localName, namespaceUri, valueType)), this.Message); 1638 } 1639 DerivedKeySecurityToken derivedKeyToken = token as DerivedKeySecurityToken; 1640 if (derivedKeyToken != null) 1641 { 1642 EnsureDerivedKeyLimitNotReached(); 1643 derivedKeyToken.InitializeDerivedKey(this.maxDerivedKeyLength); 1644 } 1645 1646 if ((usedTokenAuthenticator is SspiNegotiationTokenAuthenticator) || 1647 (usedTokenAuthenticator == this.primaryTokenAuthenticator)) 1648 { 1649 this.allowedAuthenticators.Remove(usedTokenAuthenticator); 1650 } 1651 1652 ReceiveSecurityHeaderBindingModes mode; 1653 TokenTracker supportingTokenTracker = null; 1654 if (usedTokenAuthenticator == this.primaryTokenAuthenticator) 1655 { 1656 // this is the primary token. Add to resolver as such 1657 this.universalTokenResolver.Add(token, SecurityTokenReferenceStyle.Internal, this.primaryTokenParameters); 1658 this.primaryTokenResolver.Add(token, SecurityTokenReferenceStyle.Internal, this.primaryTokenParameters); 1659 if (this.pendingSupportingTokenAuthenticator != null) 1660 { 1661 this.allowedAuthenticators.Add(this.pendingSupportingTokenAuthenticator); 1662 this.pendingSupportingTokenAuthenticator = null; 1663 } 1664 this.primaryTokenTracker.RecordToken(token); 1665 mode = ReceiveSecurityHeaderBindingModes.Primary; 1666 } 1667 else if (usedTokenAuthenticator == this.DerivedTokenAuthenticator) 1668 { 1669 if (token is DerivedKeySecurityTokenStub) 1670 { 1671 if (this.Layout == SecurityHeaderLayout.Strict) 1672 { 1673 DerivedKeySecurityTokenStub tmpToken = (DerivedKeySecurityTokenStub)token; 1674 throw TraceUtility.ThrowHelperError(new MessageSecurityException( 1675 SR.GetString(SR.UnableToResolveKeyInfoClauseInDerivedKeyToken, tmpToken.TokenToDeriveIdentifier)), this.Message); 1676 } 1677 } 1678 else 1679 { 1680 AddDerivedKeyTokenToResolvers(token); 1681 } 1682 mode = ReceiveSecurityHeaderBindingModes.Unknown; 1683 } 1684 else 1685 { 1686 SupportingTokenAuthenticatorSpecification supportingTokenSpec; 1687 supportingTokenTracker = GetSupportingTokenTracker(usedTokenAuthenticator, out supportingTokenSpec); 1688 if (supportingTokenTracker == null) 1689 { 1690 throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.UnknownTokenAuthenticatorUsedInTokenProcessing, usedTokenAuthenticator))); 1691 } 1692 if (supportingTokenTracker.token != null) 1693 { 1694 supportingTokenTracker = new TokenTracker(supportingTokenSpec); 1695 this.supportingTokenTrackers.Add(supportingTokenTracker); 1696 } 1697 1698 supportingTokenTracker.RecordToken(token); 1699 if (encryptionToken != null) 1700 { 1701 supportingTokenTracker.IsEncrypted = true; 1702 } 1703 1704 bool isBasic; 1705 bool isSignedButNotBasic; 1706 SecurityTokenAttachmentModeHelper.Categorize(supportingTokenSpec.SecurityTokenAttachmentMode, 1707 out isBasic, out isSignedButNotBasic, out mode); 1708 if (isBasic) 1709 { 1710 if (!this.ExpectBasicTokens) 1711 { 1712 throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.BasicTokenNotExpected))); 1713 } 1714 1715 // only basic tokens have to be part of the reference list. Encrypted Saml tokens dont for example 1716 if (this.RequireMessageProtection && encryptionToken != null) 1717 { 1718 RecordEncryptionTokenAndRemoveReferenceListEntry(idInEncryptedForm, encryptionToken); 1719 } 1720 } 1721 if (isSignedButNotBasic && !this.ExpectSignedTokens) 1722 { 1723 throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.SignedSupportingTokenNotExpected))); 1724 } 1725 this.universalTokenResolver.Add(token, SecurityTokenReferenceStyle.Internal, supportingTokenSpec.TokenParameters); 1726 } 1727 if (position == AppendPosition) 1728 { 1729 this.elementManager.AppendToken(token, mode, supportingTokenTracker); 1730 } 1731 else 1732 { 1733 this.elementManager.SetTokenAfterDecryption(position, token, mode, decryptedBuffer, supportingTokenTracker); 1734 } 1735 } 1736 ReadToken(XmlReader reader, SecurityTokenResolver tokenResolver, IList<SecurityTokenAuthenticator> allowedTokenAuthenticators, out SecurityTokenAuthenticator usedTokenAuthenticator)1737 SecurityToken ReadToken(XmlReader reader, SecurityTokenResolver tokenResolver, IList<SecurityTokenAuthenticator> allowedTokenAuthenticators, out SecurityTokenAuthenticator usedTokenAuthenticator) 1738 { 1739 SecurityToken token = this.StandardsManager.SecurityTokenSerializer.ReadToken(reader, tokenResolver); 1740 if (token is DerivedKeySecurityTokenStub) 1741 { 1742 if (this.DerivedTokenAuthenticator == null) 1743 { 1744 // No Authenticator registered for DerivedKeySecurityToken 1745 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException( 1746 SR.GetString(SR.UnableToFindTokenAuthenticator, typeof(DerivedKeySecurityToken)))); 1747 } 1748 1749 // This is just the stub. Nothing to Validate. Set the usedTokenAuthenticator to 1750 // DerivedKeySecurityTokenAuthenticator. 1751 usedTokenAuthenticator = this.DerivedTokenAuthenticator; 1752 return token; 1753 } 1754 1755 for (int i = 0; i < allowedTokenAuthenticators.Count; ++i) 1756 { 1757 SecurityTokenAuthenticator tokenAuthenticator = allowedTokenAuthenticators[i]; 1758 if (tokenAuthenticator.CanValidateToken(token)) 1759 { 1760 ReadOnlyCollection<IAuthorizationPolicy> authorizationPolicies; 1761 ServiceCredentialsSecurityTokenManager.KerberosSecurityTokenAuthenticatorWrapper kerbTokenAuthenticator = 1762 tokenAuthenticator as ServiceCredentialsSecurityTokenManager.KerberosSecurityTokenAuthenticatorWrapper; 1763 if (kerbTokenAuthenticator != null) 1764 { 1765 authorizationPolicies = kerbTokenAuthenticator.ValidateToken(token, this.channelBinding, this.extendedProtectionPolicy); 1766 } 1767 else 1768 { 1769 authorizationPolicies = tokenAuthenticator.ValidateToken(token); 1770 } 1771 SecurityTokenAuthorizationPoliciesMapping.Add(token, authorizationPolicies); 1772 usedTokenAuthenticator = tokenAuthenticator; 1773 return token; 1774 } 1775 } 1776 1777 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException( 1778 SR.GetString(SR.UnableToFindTokenAuthenticator, token.GetType()))); 1779 } 1780 1781 AddDerivedKeyTokenToResolvers(SecurityToken token)1782 void AddDerivedKeyTokenToResolvers(SecurityToken token) 1783 { 1784 this.universalTokenResolver.Add(token); 1785 // add it to the primary token resolver only if its root is primary 1786 SecurityToken rootToken = GetRootToken(token); 1787 if (IsPrimaryToken(rootToken)) 1788 { 1789 primaryTokenResolver.Add(token); 1790 } 1791 } 1792 AddIncomingSignatureConfirmation(byte[] signatureValue, bool isFromDecryptedSource)1793 void AddIncomingSignatureConfirmation(byte[] signatureValue, bool isFromDecryptedSource) 1794 { 1795 if (this.MaintainSignatureConfirmationState) 1796 { 1797 if (this.receivedSignatureConfirmations == null) 1798 { 1799 this.receivedSignatureConfirmations = new SignatureConfirmations(); 1800 } 1801 this.receivedSignatureConfirmations.AddConfirmation(signatureValue, isFromDecryptedSource); 1802 } 1803 } 1804 AddIncomingSignatureValue(byte[] signatureValue, bool isFromDecryptedSource)1805 void AddIncomingSignatureValue(byte[] signatureValue, bool isFromDecryptedSource) 1806 { 1807 // cache incoming signatures only on the server side 1808 if (this.MaintainSignatureConfirmationState && !this.ExpectSignatureConfirmation) 1809 { 1810 if (this.receivedSignatureValues == null) 1811 { 1812 this.receivedSignatureValues = new SignatureConfirmations(); 1813 } 1814 this.receivedSignatureValues.AddConfirmation(signatureValue, isFromDecryptedSource); 1815 } 1816 } 1817 RecordEncryptionToken(SecurityToken token)1818 protected void RecordEncryptionToken(SecurityToken token) 1819 { 1820 this.encryptionTracker.RecordToken(token); 1821 } 1822 RecordSignatureToken(SecurityToken token)1823 protected void RecordSignatureToken(SecurityToken token) 1824 { 1825 this.signatureTracker.RecordToken(token); 1826 } 1827 SetRequiredProtectionOrder(MessageProtectionOrder protectionOrder)1828 public void SetRequiredProtectionOrder(MessageProtectionOrder protectionOrder) 1829 { 1830 ThrowIfProcessingStarted(); 1831 this.protectionOrder = protectionOrder; 1832 } 1833 ReadSignatureCore(XmlDictionaryReader signatureReader)1834 protected abstract SignedXml ReadSignatureCore(XmlDictionaryReader signatureReader); 1835 VerifySignature(SignedXml signedXml, bool isPrimarySignature, SecurityHeaderTokenResolver resolver, object signatureTarget, string id)1836 protected abstract SecurityToken VerifySignature(SignedXml signedXml, bool isPrimarySignature, 1837 SecurityHeaderTokenResolver resolver, object signatureTarget, string id); 1838 TryDeleteReferenceListEntry(string id)1839 protected abstract bool TryDeleteReferenceListEntry(string id); 1840 1841 struct OrderTracker 1842 { 1843 static readonly ReceiverProcessingOrder[] stateTransitionTableOnDecrypt = new ReceiverProcessingOrder[] 1844 { 1845 ReceiverProcessingOrder.Decrypt, ReceiverProcessingOrder.VerifyDecrypt, ReceiverProcessingOrder.Decrypt, 1846 ReceiverProcessingOrder.Mixed, ReceiverProcessingOrder.VerifyDecrypt, ReceiverProcessingOrder.Mixed 1847 }; 1848 static readonly ReceiverProcessingOrder[] stateTransitionTableOnVerify = new ReceiverProcessingOrder[] 1849 { 1850 ReceiverProcessingOrder.Verify, ReceiverProcessingOrder.Verify, ReceiverProcessingOrder.DecryptVerify, 1851 ReceiverProcessingOrder.DecryptVerify, ReceiverProcessingOrder.Mixed, ReceiverProcessingOrder.Mixed 1852 }; 1853 1854 const int MaxAllowedWrappedKeys = 1; 1855 1856 int referenceListCount; 1857 ReceiverProcessingOrder state; 1858 int signatureCount; 1859 int unencryptedSignatureCount; 1860 int numWrappedKeys; 1861 MessageProtectionOrder protectionOrder; 1862 bool enforce; 1863 1864 public bool AllSignaturesEncrypted 1865 { 1866 get { return this.unencryptedSignatureCount == 0; } 1867 } 1868 1869 public bool EncryptBeforeSignMode 1870 { 1871 get { return this.enforce && this.protectionOrder == MessageProtectionOrder.EncryptBeforeSign; } 1872 } 1873 1874 public bool EncryptBeforeSignOrderRequirementMet 1875 { 1876 get { return this.state != ReceiverProcessingOrder.DecryptVerify && this.state != ReceiverProcessingOrder.Mixed; } 1877 } 1878 1879 public bool PrimarySignatureDone 1880 { 1881 get { return this.signatureCount > 0; } 1882 } 1883 1884 public bool SignBeforeEncryptOrderRequirementMet 1885 { 1886 get { return this.state != ReceiverProcessingOrder.VerifyDecrypt && this.state != ReceiverProcessingOrder.Mixed; } 1887 } 1888 EnforceProtectionOrderSystem.ServiceModel.Security.ReceiveSecurityHeader.OrderTracker1889 void EnforceProtectionOrder() 1890 { 1891 switch (this.protectionOrder) 1892 { 1893 case MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature: 1894 if (!this.AllSignaturesEncrypted) 1895 { 1896 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException( 1897 SR.GetString(SR.PrimarySignatureIsRequiredToBeEncrypted))); 1898 } 1899 goto case MessageProtectionOrder.SignBeforeEncrypt; 1900 case MessageProtectionOrder.SignBeforeEncrypt: 1901 if (!this.SignBeforeEncryptOrderRequirementMet) 1902 { 1903 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException( 1904 SR.GetString(SR.MessageProtectionOrderMismatch, this.protectionOrder))); 1905 } 1906 break; 1907 case MessageProtectionOrder.EncryptBeforeSign: 1908 if (!this.EncryptBeforeSignOrderRequirementMet) 1909 { 1910 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException( 1911 SR.GetString(SR.MessageProtectionOrderMismatch, this.protectionOrder))); 1912 } 1913 break; 1914 default: 1915 Fx.Assert(""); 1916 break; 1917 } 1918 } 1919 OnProcessReferenceListSystem.ServiceModel.Security.ReceiveSecurityHeader.OrderTracker1920 public void OnProcessReferenceList() 1921 { 1922 Fx.Assert(this.enforce, "OrderTracker should have 'enforce' set to true."); 1923 if (this.referenceListCount > 0) 1924 { 1925 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException( 1926 SR.GetString(SR.AtMostOneReferenceListIsSupportedWithDefaultPolicyCheck))); 1927 } 1928 this.referenceListCount++; 1929 this.state = stateTransitionTableOnDecrypt[(int)this.state]; 1930 if (this.enforce) 1931 { 1932 EnforceProtectionOrder(); 1933 } 1934 } 1935 OnProcessSignatureSystem.ServiceModel.Security.ReceiveSecurityHeader.OrderTracker1936 public void OnProcessSignature(bool isEncrypted) 1937 { 1938 Fx.Assert(this.enforce, "OrderTracker should have 'enforce' set to true."); 1939 if (this.signatureCount > 0) 1940 { 1941 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.AtMostOneSignatureIsSupportedWithDefaultPolicyCheck))); 1942 } 1943 this.signatureCount++; 1944 if (!isEncrypted) 1945 { 1946 this.unencryptedSignatureCount++; 1947 } 1948 this.state = stateTransitionTableOnVerify[(int)this.state]; 1949 if (this.enforce) 1950 { 1951 EnforceProtectionOrder(); 1952 } 1953 } 1954 OnEncryptedKeySystem.ServiceModel.Security.ReceiveSecurityHeader.OrderTracker1955 public void OnEncryptedKey() 1956 { 1957 Fx.Assert(this.enforce, "OrderTracker should have 'enforce' set to true."); 1958 1959 if (this.numWrappedKeys == MaxAllowedWrappedKeys) 1960 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.WrappedKeyLimitExceeded, this.numWrappedKeys))); 1961 1962 this.numWrappedKeys++; 1963 } 1964 SetRequiredProtectionOrderSystem.ServiceModel.Security.ReceiveSecurityHeader.OrderTracker1965 public void SetRequiredProtectionOrder(MessageProtectionOrder protectionOrder) 1966 { 1967 this.protectionOrder = protectionOrder; 1968 this.enforce = true; 1969 } 1970 1971 enum ReceiverProcessingOrder : int 1972 { 1973 None = 0, 1974 Verify = 1, 1975 Decrypt = 2, 1976 DecryptVerify = 3, 1977 VerifyDecrypt = 4, 1978 Mixed = 5 1979 } 1980 } 1981 1982 struct OperationTracker 1983 { 1984 MessagePartSpecification parts; 1985 SecurityToken token; 1986 bool isDerivedToken; 1987 1988 public MessagePartSpecification Parts 1989 { 1990 get { return this.parts; } 1991 set { this.parts = value; } 1992 } 1993 1994 public SecurityToken Token 1995 { 1996 get { return this.token; } 1997 } 1998 1999 public bool IsDerivedToken 2000 { 2001 get { return this.isDerivedToken; } 2002 } 2003 RecordTokenSystem.ServiceModel.Security.ReceiveSecurityHeader.OperationTracker2004 public void RecordToken(SecurityToken token) 2005 { 2006 if (this.token == null) 2007 { 2008 this.token = token; 2009 } 2010 else if (!ReferenceEquals(this.token, token)) 2011 { 2012 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.MismatchInSecurityOperationToken))); 2013 } 2014 } 2015 SetDerivationSourceIfRequiredSystem.ServiceModel.Security.ReceiveSecurityHeader.OperationTracker2016 public void SetDerivationSourceIfRequired() 2017 { 2018 DerivedKeySecurityToken derivedKeyToken = this.token as DerivedKeySecurityToken; 2019 if (derivedKeyToken != null) 2020 { 2021 this.token = derivedKeyToken.TokenToDerive; 2022 this.isDerivedToken = true; 2023 } 2024 } 2025 } 2026 } 2027 2028 class TokenTracker 2029 { 2030 public SecurityToken token; 2031 public bool IsDerivedFrom; 2032 public bool IsSigned; 2033 public bool IsEncrypted; 2034 public bool IsEndorsing; 2035 public bool AlreadyReadEndorsingSignature; 2036 bool allowFirstTokenMismatch; 2037 public SupportingTokenAuthenticatorSpecification spec; 2038 TokenTracker(SupportingTokenAuthenticatorSpecification spec)2039 public TokenTracker(SupportingTokenAuthenticatorSpecification spec) 2040 : this(spec, null, false) 2041 { 2042 } 2043 TokenTracker(SupportingTokenAuthenticatorSpecification spec, SecurityToken token, bool allowFirstTokenMismatch)2044 public TokenTracker(SupportingTokenAuthenticatorSpecification spec, SecurityToken token, bool allowFirstTokenMismatch) 2045 { 2046 this.spec = spec; 2047 this.token = token; 2048 this.allowFirstTokenMismatch = allowFirstTokenMismatch; 2049 } 2050 RecordToken(SecurityToken token)2051 public void RecordToken(SecurityToken token) 2052 { 2053 if (this.token == null) 2054 { 2055 this.token = token; 2056 } 2057 else if (this.allowFirstTokenMismatch) 2058 { 2059 if (!AreTokensEqual(this.token, token)) 2060 { 2061 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.MismatchInSecurityOperationToken))); 2062 } 2063 this.token = token; 2064 this.allowFirstTokenMismatch = false; 2065 } 2066 else if (!object.ReferenceEquals(this.token, token)) 2067 { 2068 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.MismatchInSecurityOperationToken))); 2069 } 2070 } 2071 AreTokensEqual(SecurityToken outOfBandToken, SecurityToken replyToken)2072 static bool AreTokensEqual(SecurityToken outOfBandToken, SecurityToken replyToken) 2073 { 2074 // we support the serialized reply token legacy feature only for X509 certificates. 2075 // in this case the thumbprint of the reply certificate must match the outofband certificate's thumbprint 2076 if ((outOfBandToken is X509SecurityToken) && (replyToken is X509SecurityToken)) 2077 { 2078 byte[] outOfBandCertificateThumbprint = ((X509SecurityToken)outOfBandToken).Certificate.GetCertHash(); 2079 byte[] replyCertificateThumbprint = ((X509SecurityToken)replyToken).Certificate.GetCertHash(); 2080 return (CryptoHelper.IsEqual(outOfBandCertificateThumbprint, replyCertificateThumbprint)); 2081 } 2082 else 2083 { 2084 return false; 2085 } 2086 } 2087 } 2088 2089 class AggregateSecurityHeaderTokenResolver : System.IdentityModel.Tokens.AggregateTokenResolver 2090 { 2091 SecurityHeaderTokenResolver tokenResolver; 2092 AggregateSecurityHeaderTokenResolver(SecurityHeaderTokenResolver tokenResolver, ReadOnlyCollection<SecurityTokenResolver> outOfBandTokenResolvers)2093 public AggregateSecurityHeaderTokenResolver(SecurityHeaderTokenResolver tokenResolver, ReadOnlyCollection<SecurityTokenResolver> outOfBandTokenResolvers) : 2094 base(outOfBandTokenResolvers) 2095 { 2096 if (tokenResolver == null) 2097 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("tokenResolver"); 2098 2099 this.tokenResolver = tokenResolver; 2100 } 2101 TryResolveSecurityKeyCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityKey key)2102 protected override bool TryResolveSecurityKeyCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityKey key) 2103 { 2104 bool resolved = false; 2105 key = null; 2106 2107 resolved = this.tokenResolver.TryResolveSecurityKey(keyIdentifierClause, false, out key); 2108 2109 if (!resolved) 2110 { 2111 resolved = base.TryResolveSecurityKeyCore(keyIdentifierClause, out key); 2112 } 2113 2114 if (!resolved) 2115 { 2116 resolved = SecurityUtils.TryCreateKeyFromIntrinsicKeyClause(keyIdentifierClause, this, out key); 2117 } 2118 2119 return resolved; 2120 } 2121 TryResolveTokenCore(SecurityKeyIdentifier keyIdentifier, out SecurityToken token)2122 protected override bool TryResolveTokenCore(SecurityKeyIdentifier keyIdentifier, out SecurityToken token) 2123 { 2124 bool resolved = false; 2125 token = null; 2126 2127 resolved = this.tokenResolver.TryResolveToken(keyIdentifier, false, false, out token); 2128 2129 if (!resolved) 2130 { 2131 resolved = base.TryResolveTokenCore(keyIdentifier, out token); 2132 } 2133 2134 if (!resolved) 2135 { 2136 for (int i = 0; i < keyIdentifier.Count; ++i) 2137 { 2138 if (this.TryResolveTokenFromIntrinsicKeyClause(keyIdentifier[i], out token)) 2139 { 2140 resolved = true; 2141 break; 2142 } 2143 } 2144 } 2145 2146 return resolved; 2147 } 2148 TryResolveTokenFromIntrinsicKeyClause(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityToken token)2149 bool TryResolveTokenFromIntrinsicKeyClause(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityToken token) 2150 { 2151 token = null; 2152 if (keyIdentifierClause is RsaKeyIdentifierClause) 2153 { 2154 token = new RsaSecurityToken(((RsaKeyIdentifierClause)keyIdentifierClause).Rsa); 2155 return true; 2156 } 2157 else if (keyIdentifierClause is X509RawDataKeyIdentifierClause) 2158 { 2159 token = new X509SecurityToken(new X509Certificate2(((X509RawDataKeyIdentifierClause)keyIdentifierClause).GetX509RawData()), false); 2160 return true; 2161 } 2162 else if (keyIdentifierClause is EncryptedKeyIdentifierClause) 2163 { 2164 EncryptedKeyIdentifierClause keyClause = (EncryptedKeyIdentifierClause)keyIdentifierClause; 2165 SecurityKeyIdentifier wrappingTokenReference = keyClause.EncryptingKeyIdentifier; 2166 SecurityToken unwrappingToken; 2167 if (this.TryResolveToken(wrappingTokenReference, out unwrappingToken)) 2168 { 2169 token = SecurityUtils.CreateTokenFromEncryptedKeyClause(keyClause, unwrappingToken); 2170 return true; 2171 } 2172 } 2173 return false; 2174 } 2175 TryResolveTokenCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityToken token)2176 protected override bool TryResolveTokenCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityToken token) 2177 { 2178 bool resolved = false; 2179 token = null; 2180 2181 resolved = this.tokenResolver.TryResolveToken(keyIdentifierClause, false, false, out token); 2182 2183 if (!resolved) 2184 { 2185 resolved = base.TryResolveTokenCore(keyIdentifierClause, out token); 2186 } 2187 2188 if (!resolved) 2189 { 2190 resolved = TryResolveTokenFromIntrinsicKeyClause(keyIdentifierClause, out token); 2191 } 2192 2193 return resolved; 2194 } 2195 } 2196 } 2197