in src/System.ServiceModel.Primitives/src/System/ServiceModel/Security/ReceiveSecurityHeader.cs [320:518]
public void Process(TimeSpan timeout, ChannelBinding channelBinding, ExtendedProtectionPolicy extendedProtectionPolicy)
{
Fx.Assert(ReaderQuotas != null, "Reader quotas must be set before processing");
MessageProtectionOrder actualProtectionOrder = _protectionOrder;
bool wasProtectionOrderDowngraded = false;
if (_protectionOrder == MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature)
{
throw ExceptionHelper.PlatformNotSupported(); // No support for message encryption
}
_channelBinding = channelBinding;
_extendedProtectionPolicy = extendedProtectionPolicy;
_orderTracker.SetRequiredProtectionOrder(actualProtectionOrder);
SetProcessingStarted();
_timeoutHelper = new TimeoutHelper(timeout);
Message = SecurityVerifiedMessage = new SecurityVerifiedMessage(Message, this);
XmlDictionaryReader reader = CreateSecurityHeaderReader();
reader.MoveToStartElement();
if (reader.IsEmptyElement)
{
throw TraceUtility.ThrowHelperError(new MessageSecurityException(SRP.SecurityHeaderIsEmpty), Message);
}
if (RequireMessageProtection)
{
_securityElementAttributes = XmlAttributeHolder.ReadAttributes(reader);
}
else
{
_securityElementAttributes = XmlAttributeHolder.emptyArray;
}
reader.ReadStartElement();
if (_primaryTokenParameters != null)
{
_primaryTokenTracker = new TokenTracker(null, _outOfBandPrimaryToken, _allowFirstTokenMismatch);
}
// universalTokenResolver is used for resolving tokens
_universalTokenResolver = new SecurityHeaderTokenResolver(this);
// primary token resolver is used for resolving primary signature and decryption
_primaryTokenResolver = new SecurityHeaderTokenResolver(this);
if (_outOfBandPrimaryToken != null)
{
_universalTokenResolver.Add(_outOfBandPrimaryToken, SecurityTokenReferenceStyle.External, _primaryTokenParameters);
_primaryTokenResolver.Add(_outOfBandPrimaryToken, SecurityTokenReferenceStyle.External, _primaryTokenParameters);
}
else if (_outOfBandPrimaryTokenCollection != null)
{
for (int i = 0; i < _outOfBandPrimaryTokenCollection.Count; ++i)
{
_universalTokenResolver.Add(_outOfBandPrimaryTokenCollection[i], SecurityTokenReferenceStyle.External, _primaryTokenParameters);
_primaryTokenResolver.Add(_outOfBandPrimaryTokenCollection[i], SecurityTokenReferenceStyle.External, _primaryTokenParameters);
}
}
if (_wrappingToken != null)
{
_universalTokenResolver.ExpectedWrapper = _wrappingToken;
_universalTokenResolver.ExpectedWrapperTokenParameters = _wrappingTokenParameters;
_primaryTokenResolver.ExpectedWrapper = _wrappingToken;
_primaryTokenResolver.ExpectedWrapperTokenParameters = _wrappingTokenParameters;
}
if (_outOfBandTokenResolver == null)
{
CombinedUniversalTokenResolver = _universalTokenResolver;
_combinedPrimaryTokenResolver = _primaryTokenResolver;
}
else
{
CombinedUniversalTokenResolver = new AggregateSecurityHeaderTokenResolver(_universalTokenResolver, _outOfBandTokenResolver);
_combinedPrimaryTokenResolver = new AggregateSecurityHeaderTokenResolver(_primaryTokenResolver, _outOfBandTokenResolver);
}
_allowedAuthenticators = new List<SecurityTokenAuthenticator>();
if (_primaryTokenAuthenticator != null)
{
_allowedAuthenticators.Add(_primaryTokenAuthenticator);
}
if (DerivedTokenAuthenticator != null)
{
_allowedAuthenticators.Add(DerivedTokenAuthenticator);
}
_pendingSupportingTokenAuthenticator = null;
int numSupportingTokensRequiringDerivation = 0;
if (_supportingTokenAuthenticators != null && _supportingTokenAuthenticators.Count > 0)
{
_supportingTokenTrackers = new List<TokenTracker>(_supportingTokenAuthenticators.Count);
for (int i = 0; i < _supportingTokenAuthenticators.Count; ++i)
{
SupportingTokenAuthenticatorSpecification spec = _supportingTokenAuthenticators[i];
switch (spec.SecurityTokenAttachmentMode)
{
case SecurityTokenAttachmentMode.Endorsing:
_hasEndorsingOrSignedEndorsingSupportingTokens = true;
break;
case SecurityTokenAttachmentMode.Signed:
break;
case SecurityTokenAttachmentMode.SignedEndorsing:
_hasEndorsingOrSignedEndorsingSupportingTokens = true;
break;
case SecurityTokenAttachmentMode.SignedEncrypted:
break;
}
if ((_primaryTokenAuthenticator != null) && (_primaryTokenAuthenticator.GetType().Equals(spec.TokenAuthenticator.GetType())))
{
_pendingSupportingTokenAuthenticator = spec.TokenAuthenticator;
}
else
{
_allowedAuthenticators.Add(spec.TokenAuthenticator);
}
if (spec.TokenParameters.RequireDerivedKeys && !spec.TokenParameters.HasAsymmetricKey &&
(spec.SecurityTokenAttachmentMode == SecurityTokenAttachmentMode.Endorsing || spec.SecurityTokenAttachmentMode == SecurityTokenAttachmentMode.SignedEndorsing))
{
++numSupportingTokensRequiringDerivation;
}
_supportingTokenTrackers.Add(new TokenTracker(spec));
}
}
if (DerivedTokenAuthenticator != null)
{
// we expect key derivation. Compute quotas for derived keys
int maxKeyDerivationLengthInBits = AlgorithmSuite.DefaultEncryptionKeyDerivationLength >= AlgorithmSuite.DefaultSignatureKeyDerivationLength ?
AlgorithmSuite.DefaultEncryptionKeyDerivationLength : AlgorithmSuite.DefaultSignatureKeyDerivationLength;
MaxDerivedKeyLength = maxKeyDerivationLengthInBits / 8;
// the upper bound of derived keys is (1 for primary signature + 1 for encryption + supporting token signatures requiring derivation)*2
// the multiplication by 2 is to take care of interop scenarios that may arise that require more derived keys than the lower bound.
_maxDerivedKeys = (1 + 1 + numSupportingTokensRequiringDerivation) * 2;
}
SecurityHeaderElementInferenceEngine engine = SecurityHeaderElementInferenceEngine.GetInferenceEngine(Layout);
engine.ExecuteProcessingPasses(this, reader);
if (RequireMessageProtection)
{
throw ExceptionHelper.PlatformNotSupported();
}
EnsureDecryptionComplete();
_signatureTracker.SetDerivationSourceIfRequired();
_encryptionTracker.SetDerivationSourceIfRequired();
if (EncryptionToken != null)
{
throw ExceptionHelper.PlatformNotSupported();
}
// ensure that the primary signature was signed with derived keys if required
if (EnforceDerivedKeyRequirement)
{
if (SignatureToken != null)
{
if (_primaryTokenParameters != null)
{
if (_primaryTokenParameters.RequireDerivedKeys && !_primaryTokenParameters.HasAsymmetricKey && !_primaryTokenTracker.IsDerivedFrom)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SRP.Format(SRP.PrimarySignatureWasNotSignedByDerivedKey, _primaryTokenParameters)));
}
}
else if (_wrappingTokenParameters != null && _wrappingTokenParameters.RequireDerivedKeys)
{
if (!_signatureTracker.IsDerivedToken)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SRP.Format(SRP.PrimarySignatureWasNotSignedByDerivedWrappedKey, _wrappingTokenParameters)));
}
}
}
// verify that the encryption is using key derivation
if (EncryptionToken != null)
{
throw ExceptionHelper.PlatformNotSupported();
}
}
if (wasProtectionOrderDowngraded && (BasicSupportingTokens != null) && (BasicSupportingTokens.Count > 0))
{
throw ExceptionHelper.PlatformNotSupported();
}
// verify all supporting token parameters have their requirements met
if (_supportingTokenTrackers != null && _supportingTokenTrackers.Count > 0)
{
throw ExceptionHelper.PlatformNotSupported();
}
if (_replayDetectionEnabled)
{
throw ExceptionHelper.PlatformNotSupported();
}
if (ExpectSignatureConfirmation)
{
throw ExceptionHelper.PlatformNotSupported();
}
MarkHeaderAsUnderstood();
}