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