< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.Security.AggregateSecurityHeaderTokenResolver
Assembly: CoreWCF.Primitives
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Security/ReceiveSecurityHeader.cs
Line coverage
8%
Covered lines: 3
Uncovered lines: 34
Coverable lines: 37
Total lines: 2005
Line coverage: 8.1%
Branch coverage
3%
Covered branches: 1
Total branches: 26
Branch coverage: 3.8%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor(...)50%22100%
TryResolveSecurityKeyCore(...)0%440%
TryResolveTokenCore(...)0%880%
TryResolveTokenFromIntrinsicKeyClause(...)0%880%
TryResolveTokenCore(...)0%440%

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Security/ReceiveSecurityHeader.cs

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