| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000 |
- //----------------------------------------------------------
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //------------------------------------------------------------
- namespace System.ServiceModel.Security
- {
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.IdentityModel.Policy;
- using System.IdentityModel.Selectors;
- using System.IdentityModel.Tokens;
- using System.Runtime;
- using System.ServiceModel;
- using System.ServiceModel.Channels;
- using System.ServiceModel.Diagnostics;
- using System.ServiceModel.Description;
- using System.ServiceModel.Security.Tokens;
- abstract class MessageSecurityProtocol : SecurityProtocol
- {
- readonly MessageSecurityProtocolFactory factory;
- SecurityToken identityVerifiedToken; // verified for the readonly target
- protected MessageSecurityProtocol(MessageSecurityProtocolFactory factory, EndpointAddress target, Uri via)
- : base(factory, target, via)
- {
- this.factory = factory;
- }
- // Protocols that have more than one active, identity checked
- // token at any time should override this property and return
- // false
- protected virtual bool CacheIdentityCheckResultForToken
- {
- get { return true; }
- }
- protected virtual bool DoAutomaticEncryptionMatch
- {
- get { return true; }
- }
- protected virtual bool PerformIncomingAndOutgoingMessageExpectationChecks
- {
- get { return true; }
- }
- protected bool RequiresIncomingSecurityProcessing(Message message)
- {
- // if we are receiveing a response that has no security that we should accept this AND no security header exists
- // then it is OK to skip the header.
- if (this.factory.ActAsInitiator
- && this.factory.SecurityBindingElement.EnableUnsecuredResponse
- && !this.factory.StandardsManager.SecurityVersion.DoesMessageContainSecurityHeader(message))
- return false;
- bool requiresAppSecurity = this.factory.RequireIntegrity || this.factory.RequireConfidentiality || this.factory.DetectReplays;
- return requiresAppSecurity || factory.ExpectSupportingTokens;
- }
- protected bool RequiresOutgoingSecurityProcessing
- {
- get
- {
- // If were are the listener, don't apply security if the flag is set
- if (!this.factory.ActAsInitiator && this.factory.SecurityBindingElement.EnableUnsecuredResponse)
- return false;
- bool requiresAppSecurity = this.factory.ApplyIntegrity || this.factory.ApplyConfidentiality || this.factory.AddTimestamp;
- return requiresAppSecurity || factory.ExpectSupportingTokens;
- }
- }
- protected MessageSecurityProtocolFactory MessageSecurityProtocolFactory
- {
- get { return this.factory; }
- }
- public override IAsyncResult BeginSecureOutgoingMessage(Message message, TimeSpan timeout, AsyncCallback callback, object state)
- {
- try
- {
- this.CommunicationObject.ThrowIfClosedOrNotOpen();
- ValidateOutgoingState(message);
- if (!this.RequiresOutgoingSecurityProcessing && message.Properties.Security == null)
- {
- return new CompletedAsyncResult<Message>(message, callback, state);
- }
- return BeginSecureOutgoingMessageCore(message, timeout, null, callback, state);
- }
- catch (Exception exception)
- {
- // Always immediately rethrow fatal exceptions.
- if (Fx.IsFatal(exception)) throw;
- base.OnSecureOutgoingMessageFailure(message);
- throw;
- }
- }
- public override IAsyncResult BeginSecureOutgoingMessage(Message message, TimeSpan timeout, SecurityProtocolCorrelationState correlationState, AsyncCallback callback, object state)
- {
- try
- {
- this.CommunicationObject.ThrowIfClosedOrNotOpen();
- ValidateOutgoingState(message);
- if (!this.RequiresOutgoingSecurityProcessing && message.Properties.Security == null)
- {
- return new CompletedAsyncResult<Message>(message, callback, state);
- }
- return BeginSecureOutgoingMessageCore(message, timeout, correlationState, callback, state);
- }
- catch (Exception exception)
- {
- // Always immediately rethrow fatal exceptions.
- if (Fx.IsFatal(exception)) throw;
- base.OnSecureOutgoingMessageFailure(message);
- throw;
- }
- }
- protected abstract IAsyncResult BeginSecureOutgoingMessageCore(Message message, TimeSpan timeout, SecurityProtocolCorrelationState correlationState, AsyncCallback callback, object state);
- public override void EndSecureOutgoingMessage(IAsyncResult result, out Message message)
- {
- if (result == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("result");
- }
- try
- {
- SecurityProtocolCorrelationState newCorrelationState;
- EndSecureOutgoingMessageCore(result, out message, out newCorrelationState);
- base.OnOutgoingMessageSecured(message);
- }
- catch (Exception exception)
- {
- // Always immediately rethrow fatal exceptions.
- if (Fx.IsFatal(exception)) throw;
- base.OnSecureOutgoingMessageFailure(null);
- throw;
- }
- }
- public override void EndSecureOutgoingMessage(IAsyncResult result, out Message message, out SecurityProtocolCorrelationState newCorrelationState)
- {
- if (result == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("result");
- }
- try
- {
- EndSecureOutgoingMessageCore(result, out message, out newCorrelationState);
- base.OnOutgoingMessageSecured(message);
- }
- catch (Exception exception)
- {
- // Always immediately rethrow fatal exceptions.
- if (Fx.IsFatal(exception)) throw;
- base.OnSecureOutgoingMessageFailure(null);
- throw;
- }
- }
- protected abstract void EndSecureOutgoingMessageCore(IAsyncResult result, out Message message, out SecurityProtocolCorrelationState newCorrelationState);
- // helper method for attaching the client claims in a symmetric security protocol
- protected void AttachRecipientSecurityProperty(Message message, SecurityToken protectionToken, bool isWrappedToken, IList<SecurityToken> basicTokens, IList<SecurityToken> endorsingTokens,
- IList<SecurityToken> signedEndorsingTokens, IList<SecurityToken> signedTokens, Dictionary<SecurityToken, ReadOnlyCollection<IAuthorizationPolicy>> tokenPoliciesMapping)
- {
- ReadOnlyCollection<IAuthorizationPolicy> protectionTokenPolicies;
- if (isWrappedToken)
- {
- protectionTokenPolicies = EmptyReadOnlyCollection<IAuthorizationPolicy>.Instance;
- }
- else
- {
- protectionTokenPolicies = tokenPoliciesMapping[protectionToken];
- }
- SecurityMessageProperty security = SecurityMessageProperty.GetOrCreate(message);
- security.ProtectionToken = new SecurityTokenSpecification(protectionToken, protectionTokenPolicies);
- AddSupportingTokenSpecification(security, basicTokens, endorsingTokens, signedEndorsingTokens, signedTokens, tokenPoliciesMapping);
- security.ServiceSecurityContext = new ServiceSecurityContext(security.GetInitiatorTokenAuthorizationPolicies());
- }
- // helper method for attaching the server claims in a symmetric security protocol
- protected void DoIdentityCheckAndAttachInitiatorSecurityProperty(Message message, SecurityToken protectionToken, ReadOnlyCollection<IAuthorizationPolicy> protectionTokenPolicies)
- {
- AuthorizationContext protectionAuthContext = EnsureIncomingIdentity(message, protectionToken, protectionTokenPolicies);
- SecurityMessageProperty security = SecurityMessageProperty.GetOrCreate(message);
- security.ProtectionToken = new SecurityTokenSpecification(protectionToken, protectionTokenPolicies);
- security.ServiceSecurityContext = new ServiceSecurityContext(protectionAuthContext, protectionTokenPolicies ?? EmptyReadOnlyCollection<IAuthorizationPolicy>.Instance);
- }
- protected AuthorizationContext EnsureIncomingIdentity(Message message, SecurityToken token, ReadOnlyCollection<IAuthorizationPolicy> authorizationPolicies)
- {
- if (token == null)
- {
- throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.NoSigningTokenAvailableToDoIncomingIdentityCheck)), message);
- }
- AuthorizationContext authContext = (authorizationPolicies != null) ? AuthorizationContext.CreateDefaultAuthorizationContext(authorizationPolicies) : null;
- if (this.factory.IdentityVerifier != null)
- {
- if (this.Target == null)
- {
- throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.NoOutgoingEndpointAddressAvailableForDoingIdentityCheckOnReply)), message);
- }
- this.factory.IdentityVerifier.EnsureIncomingIdentity(this.Target, authContext);
- }
- return authContext;
- }
- protected void EnsureOutgoingIdentity(SecurityToken token, SecurityTokenAuthenticator authenticator)
- {
- if (object.ReferenceEquals(token, this.identityVerifiedToken))
- {
- return;
- }
- if (this.factory.IdentityVerifier == null)
- {
- return;
- }
- if (this.Target == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.NoOutgoingEndpointAddressAvailableForDoingIdentityCheck)));
- }
- ReadOnlyCollection<IAuthorizationPolicy> authzPolicies = authenticator.ValidateToken(token);
- this.factory.IdentityVerifier.EnsureOutgoingIdentity(this.Target, authzPolicies);
- if (this.CacheIdentityCheckResultForToken)
- {
- this.identityVerifiedToken = token;
- }
- }
- protected SecurityProtocolCorrelationState GetCorrelationState(SecurityToken correlationToken)
- {
- return new SecurityProtocolCorrelationState(correlationToken);
- }
- protected SecurityProtocolCorrelationState GetCorrelationState(SecurityToken correlationToken, ReceiveSecurityHeader securityHeader)
- {
- SecurityProtocolCorrelationState result = new SecurityProtocolCorrelationState(correlationToken);
- if (securityHeader.MaintainSignatureConfirmationState && !this.factory.ActAsInitiator)
- {
- result.SignatureConfirmations = securityHeader.GetSentSignatureValues();
- }
- return result;
- }
- protected SecurityToken GetCorrelationToken(SecurityProtocolCorrelationState[] correlationStates)
- {
- SecurityToken token = null;
- if (correlationStates != null)
- {
- for (int i = 0; i < correlationStates.Length; ++i)
- {
- if (correlationStates[i].Token == null)
- continue;
- if (token == null)
- {
- token = correlationStates[i].Token;
- }
- else if (!object.ReferenceEquals(token, correlationStates[i].Token))
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.MultipleCorrelationTokensFound)));
- }
- }
- }
- if (token == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.NoCorrelationTokenFound)));
- }
- return token;
- }
- protected SecurityToken GetCorrelationToken(SecurityProtocolCorrelationState correlationState)
- {
- if (correlationState == null || correlationState.Token == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.CannotFindCorrelationStateForApplyingSecurity)));
- }
- return correlationState.Token;
- }
- protected static void EnsureNonWrappedToken(SecurityToken token, Message message)
- {
- if (token is WrappedKeySecurityToken)
- {
- throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.TokenNotExpectedInSecurityHeader, token)), message);
- }
- }
- protected SecurityToken GetTokenAndEnsureOutgoingIdentity(SecurityTokenProvider provider, bool isEncryptionOn, TimeSpan timeout, SecurityTokenAuthenticator authenticator)
- {
- SecurityToken token = GetToken(provider, this.Target, timeout);
- if (isEncryptionOn)
- {
- EnsureOutgoingIdentity(token, authenticator);
- }
- return token;
- }
- protected SendSecurityHeader ConfigureSendSecurityHeader(Message message, string actor, IList<SupportingTokenSpecification> supportingTokens, SecurityProtocolCorrelationState correlationState)
- {
- MessageSecurityProtocolFactory factory = this.MessageSecurityProtocolFactory;
- SendSecurityHeader securityHeader = CreateSendSecurityHeader(message, actor, factory);
- securityHeader.SignThenEncrypt = factory.MessageProtectionOrder != MessageProtectionOrder.EncryptBeforeSign;
- // If ProtectTokens is enabled then we make sure that both the client side and the service side sign the primary token
- // ( if it is an issued token, the check exists in sendsecurityheader)in the primary signature while sending a message.
- securityHeader.ShouldProtectTokens = factory.SecurityBindingElement.ProtectTokens;
- securityHeader.EncryptPrimarySignature = factory.MessageProtectionOrder == MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature;
- if (factory.DoRequestSignatureConfirmation && correlationState != null)
- {
- if (factory.ActAsInitiator)
- {
- securityHeader.MaintainSignatureConfirmationState = true;
- securityHeader.CorrelationState = correlationState;
- }
- else if (correlationState.SignatureConfirmations != null)
- {
- securityHeader.AddSignatureConfirmations(correlationState.SignatureConfirmations);
- }
- }
- string action = message.Headers.Action;
- if (this.factory.ApplyIntegrity)
- {
- securityHeader.SignatureParts = this.factory.GetOutgoingSignatureParts(action);
- }
- if (factory.ApplyConfidentiality)
- {
- securityHeader.EncryptionParts = this.factory.GetOutgoingEncryptionParts(action);
- }
- AddSupportingTokens(securityHeader, supportingTokens);
- return securityHeader;
- }
- protected ReceiveSecurityHeader CreateSecurityHeader(Message message, string actor, MessageDirection transferDirection, SecurityStandardsManager standardsManager)
- {
- standardsManager = standardsManager ?? this.factory.StandardsManager;
- ReceiveSecurityHeader securityHeader = standardsManager.CreateReceiveSecurityHeader(message, actor,
- this.factory.IncomingAlgorithmSuite, transferDirection);
- securityHeader.Layout = this.factory.SecurityHeaderLayout;
- securityHeader.MaxReceivedMessageSize = factory.SecurityBindingElement.MaxReceivedMessageSize;
- securityHeader.ReaderQuotas = factory.SecurityBindingElement.ReaderQuotas;
- if (this.factory.ExpectKeyDerivation)
- {
- securityHeader.DerivedTokenAuthenticator = this.factory.DerivedKeyTokenAuthenticator;
- }
- return securityHeader;
- }
- bool HasCorrelationState(SecurityProtocolCorrelationState[] correlationState)
- {
- if (correlationState == null || correlationState.Length == 0)
- {
- return false;
- }
- else if (correlationState.Length == 1 && correlationState[0] == null)
- {
- return false;
- }
- else
- {
- return true;
- }
- }
- protected ReceiveSecurityHeader ConfigureReceiveSecurityHeader(Message message, string actor, SecurityProtocolCorrelationState[] correlationStates, out IList<SupportingTokenAuthenticatorSpecification> supportingAuthenticators)
- {
- return ConfigureReceiveSecurityHeader(message, actor, correlationStates, null, out supportingAuthenticators);
- }
- protected ReceiveSecurityHeader ConfigureReceiveSecurityHeader(Message message, string actor, SecurityProtocolCorrelationState[] correlationStates, SecurityStandardsManager standardsManager, out IList<SupportingTokenAuthenticatorSpecification> supportingAuthenticators)
- {
- MessageSecurityProtocolFactory factory = this.MessageSecurityProtocolFactory;
- MessageDirection direction = factory.ActAsInitiator ? MessageDirection.Output : MessageDirection.Input;
- ReceiveSecurityHeader securityHeader = CreateSecurityHeader(message, actor, direction, standardsManager);
- string action = message.Headers.Action;
- supportingAuthenticators = GetSupportingTokenAuthenticatorsAndSetExpectationFlags(this.factory, message, securityHeader);
- if (factory.RequireIntegrity || securityHeader.ExpectSignedTokens)
- {
- securityHeader.RequiredSignatureParts = factory.GetIncomingSignatureParts(action);
- }
- if (factory.RequireConfidentiality || securityHeader.ExpectBasicTokens)
- {
- securityHeader.RequiredEncryptionParts = factory.GetIncomingEncryptionParts(action);
- }
- securityHeader.ExpectEncryption = factory.RequireConfidentiality || securityHeader.ExpectBasicTokens;
- securityHeader.ExpectSignature = factory.RequireIntegrity || securityHeader.ExpectSignedTokens;
- securityHeader.SetRequiredProtectionOrder(factory.MessageProtectionOrder);
- // On the receiving side if protectTokens is enabled
- // 1. If we are service, we make sure that the client always signs the primary token( can be any token type)else we throw.
- // But currently the service can sign the primary token in reply only if the primary token is an issued token
- // 2. If we are client, we do not care if the service signs the primary token or not. Otherwise it will be impossible to have a wcf client /service talk to each other unless we
- // either use a symmetric binding with issued tokens or asymmetric bindings with both the intiator and recipient parameters being issued tokens( later one is rare).
- securityHeader.RequireSignedPrimaryToken = !factory.ActAsInitiator && factory.SecurityBindingElement.ProtectTokens;
- if (factory.ActAsInitiator && factory.DoRequestSignatureConfirmation && HasCorrelationState(correlationStates))
- {
- securityHeader.MaintainSignatureConfirmationState = true;
- securityHeader.ExpectSignatureConfirmation = true;
- }
- else if (!factory.ActAsInitiator && factory.DoRequestSignatureConfirmation)
- {
- securityHeader.MaintainSignatureConfirmationState = true;
- }
- else
- {
- securityHeader.MaintainSignatureConfirmationState = false;
- }
- return securityHeader;
- }
- protected void ProcessSecurityHeader(ReceiveSecurityHeader securityHeader, ref Message message,
- SecurityToken requiredSigningToken, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationStates)
- {
- TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
- securityHeader.ReplayDetectionEnabled = this.factory.DetectReplays;
- securityHeader.SetTimeParameters(this.factory.NonceCache, this.factory.ReplayWindow, this.factory.MaxClockSkew);
- securityHeader.Process(timeoutHelper.RemainingTime(), SecurityUtils.GetChannelBindingFromMessage(message), this.factory.ExtendedProtectionPolicy);
- if (this.factory.AddTimestamp && securityHeader.Timestamp == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.RequiredTimestampMissingInSecurityHeader)));
- }
- if (requiredSigningToken != null && requiredSigningToken != securityHeader.SignatureToken)
- {
- throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.ReplyWasNotSignedWithRequiredSigningToken)), message);
- }
- if (this.DoAutomaticEncryptionMatch)
- {
- SecurityUtils.EnsureExpectedSymmetricMatch(securityHeader.SignatureToken, securityHeader.EncryptionToken, message);
- }
- if (securityHeader.MaintainSignatureConfirmationState && this.factory.ActAsInitiator)
- {
- CheckSignatureConfirmation(securityHeader, correlationStates);
- }
- message = securityHeader.ProcessedMessage;
- }
- protected void CheckSignatureConfirmation(ReceiveSecurityHeader securityHeader, SecurityProtocolCorrelationState[] correlationStates)
- {
- SignatureConfirmations receivedConfirmations = securityHeader.GetSentSignatureConfirmations();
- SignatureConfirmations sentSignatures = null;
- if (correlationStates != null)
- {
- for (int i = 0; i < correlationStates.Length; ++i)
- {
- if (correlationStates[i].SignatureConfirmations != null)
- {
- sentSignatures = correlationStates[i].SignatureConfirmations;
- break;
- }
- }
- }
- if (sentSignatures == null)
- {
- if (receivedConfirmations != null && receivedConfirmations.Count > 0)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.FoundUnexpectedSignatureConfirmations)));
- }
- return;
- }
- bool allSignaturesConfirmed = false;
- if (receivedConfirmations != null && sentSignatures.Count == receivedConfirmations.Count)
- {
- bool[] matchingSigIndexes = new bool[sentSignatures.Count];
- for (int i = 0; i < sentSignatures.Count; ++i)
- {
- byte[] sentSignature;
- bool wasSentSigEncrypted;
- sentSignatures.GetConfirmation(i, out sentSignature, out wasSentSigEncrypted);
- for (int j = 0; j < receivedConfirmations.Count; ++j)
- {
- byte[] receivedSignature;
- bool wasReceivedSigEncrypted;
- if (matchingSigIndexes[j])
- {
- continue;
- }
- receivedConfirmations.GetConfirmation(j, out receivedSignature, out wasReceivedSigEncrypted);
- if ((wasReceivedSigEncrypted == wasSentSigEncrypted) && CryptoHelper.IsEqual(receivedSignature, sentSignature))
- {
- matchingSigIndexes[j] = true;
- break;
- }
- }
- }
- int k;
- for (k = 0; k < matchingSigIndexes.Length; ++k)
- {
- if (!matchingSigIndexes[k])
- {
- break;
- }
- }
- if (k == matchingSigIndexes.Length)
- {
- allSignaturesConfirmed = true;
- }
- }
- if (!allSignaturesConfirmed)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.NotAllSignaturesConfirmed)));
- }
- }
- public override void SecureOutgoingMessage(ref Message message, TimeSpan timeout)
- {
- try
- {
- this.CommunicationObject.ThrowIfClosedOrNotOpen();
- ValidateOutgoingState(message);
- if (!this.RequiresOutgoingSecurityProcessing && message.Properties.Security == null)
- {
- return;
- }
- SecureOutgoingMessageCore(ref message, timeout, null);
- base.OnOutgoingMessageSecured(message);
- }
- catch (Exception exception)
- {
- // Always immediately rethrow fatal exceptions.
- if (Fx.IsFatal(exception)) throw;
- base.OnSecureOutgoingMessageFailure(message);
- throw;
- }
- }
- public override SecurityProtocolCorrelationState SecureOutgoingMessage(ref Message message, TimeSpan timeout, SecurityProtocolCorrelationState correlationState)
- {
- try
- {
- this.CommunicationObject.ThrowIfClosedOrNotOpen();
- ValidateOutgoingState(message);
- if (!this.RequiresOutgoingSecurityProcessing && message.Properties.Security == null)
- {
- return null;
- }
- SecurityProtocolCorrelationState newCorrelationState = SecureOutgoingMessageCore(ref message, timeout, correlationState);
- base.OnOutgoingMessageSecured(message);
- return newCorrelationState;
- }
- catch (Exception exception)
- {
- // Always immediately rethrow fatal exceptions.
- if (Fx.IsFatal(exception)) throw;
- base.OnSecureOutgoingMessageFailure(message);
- throw;
- }
- }
- protected abstract SecurityProtocolCorrelationState SecureOutgoingMessageCore(ref Message message, TimeSpan timeout, SecurityProtocolCorrelationState correlationState);
- void ValidateOutgoingState(Message message)
- {
- if (this.PerformIncomingAndOutgoingMessageExpectationChecks && !this.factory.ExpectOutgoingMessages)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SecurityBindingNotSetUpToProcessOutgoingMessages)));
- }
- if (message == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message");
- }
- }
- public override void VerifyIncomingMessage(ref Message message, TimeSpan timeout)
- {
- try
- {
- this.CommunicationObject.ThrowIfClosedOrNotOpen();
- if (this.PerformIncomingAndOutgoingMessageExpectationChecks && !factory.ExpectIncomingMessages)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SecurityBindingNotSetUpToProcessIncomingMessages)));
- }
- if (message == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message");
- }
- if (!this.RequiresIncomingSecurityProcessing(message))
- {
- return;
- }
- string actor = string.Empty; // message.Version.Envelope.UltimateDestinationActor;
- VerifyIncomingMessageCore(ref message, actor, timeout, null);
- base.OnIncomingMessageVerified(message);
- }
- catch (MessageSecurityException e)
- {
- base.OnVerifyIncomingMessageFailure(message, e);
- throw;
- }
- catch (Exception e)
- {
- // Always immediately rethrow fatal exceptions.
- if (Fx.IsFatal(e)) throw;
- base.OnVerifyIncomingMessageFailure(message, e);
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.MessageSecurityVerificationFailed), e));
- }
- }
- public override SecurityProtocolCorrelationState VerifyIncomingMessage(ref Message message, TimeSpan timeout, params SecurityProtocolCorrelationState[] correlationStates)
- {
- try
- {
- this.CommunicationObject.ThrowIfClosedOrNotOpen();
- if (this.PerformIncomingAndOutgoingMessageExpectationChecks && !factory.ExpectIncomingMessages)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SecurityBindingNotSetUpToProcessIncomingMessages)));
- }
- if (message == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message");
- }
- if (!this.RequiresIncomingSecurityProcessing(message))
- {
- return null;
- }
- string actor = string.Empty; // message.Version.Envelope.UltimateDestinationActor;
- SecurityProtocolCorrelationState newCorrelationState = VerifyIncomingMessageCore(ref message, actor, timeout, correlationStates);
- base.OnIncomingMessageVerified(message);
- return newCorrelationState;
- }
- catch (MessageSecurityException e)
- {
- base.OnVerifyIncomingMessageFailure(message, e);
- throw;
- }
- catch (Exception e)
- {
- // Always immediately rethrow fatal exceptions.
- if (Fx.IsFatal(e)) throw;
- base.OnVerifyIncomingMessageFailure(message, e);
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.MessageSecurityVerificationFailed), e));
- }
- }
- protected abstract SecurityProtocolCorrelationState VerifyIncomingMessageCore(ref Message message, string actor, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationStates);
- internal SecurityProtocolCorrelationState GetSignatureConfirmationCorrelationState(SecurityProtocolCorrelationState oldCorrelationState, SecurityProtocolCorrelationState newCorrelationState)
- {
- if (this.factory.ActAsInitiator)
- {
- return newCorrelationState;
- }
- else
- {
- return oldCorrelationState;
- }
- }
- protected abstract class GetOneTokenAndSetUpSecurityAsyncResult : GetSupportingTokensAsyncResult
- {
- readonly MessageSecurityProtocol binding;
- readonly SecurityTokenProvider provider;
- Message message;
- readonly bool doIdentityChecks;
- SecurityTokenAuthenticator identityCheckAuthenticator;
- static AsyncCallback getTokenCompleteCallback = Fx.ThunkCallback(new AsyncCallback(GetTokenCompleteCallback));
- SecurityProtocolCorrelationState newCorrelationState;
- SecurityProtocolCorrelationState oldCorrelationState;
- TimeoutHelper timeoutHelper;
- public GetOneTokenAndSetUpSecurityAsyncResult(Message m, MessageSecurityProtocol binding, SecurityTokenProvider provider,
- bool doIdentityChecks, SecurityTokenAuthenticator identityCheckAuthenticator, SecurityProtocolCorrelationState oldCorrelationState, TimeSpan timeout, AsyncCallback callback, object state)
- : base(m, binding, timeout, callback, state)
- {
- this.message = m;
- this.binding = binding;
- this.provider = provider;
- this.doIdentityChecks = doIdentityChecks;
- this.oldCorrelationState = oldCorrelationState;
- this.identityCheckAuthenticator = identityCheckAuthenticator;
- }
- protected MessageSecurityProtocol Binding
- {
- get { return this.binding; }
- }
- protected SecurityProtocolCorrelationState NewCorrelationState
- {
- get { return this.newCorrelationState; }
- }
- protected SecurityProtocolCorrelationState OldCorrelationState
- {
- get { return this.oldCorrelationState; }
- }
- internal static Message End(IAsyncResult result, out SecurityProtocolCorrelationState newCorrelationState)
- {
- GetOneTokenAndSetUpSecurityAsyncResult self = AsyncResult.End<GetOneTokenAndSetUpSecurityAsyncResult>(result);
- newCorrelationState = self.newCorrelationState;
- return self.message;
- }
- bool OnGetTokenComplete(SecurityToken token)
- {
- if (token == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.TokenProviderCannotGetTokensForTarget, this.binding.Target)));
- }
- if (this.doIdentityChecks)
- {
- this.binding.EnsureOutgoingIdentity(token, this.identityCheckAuthenticator);
- }
- OnGetTokenDone(ref this.message, token, timeoutHelper.RemainingTime());
- return true;
- }
- protected abstract void OnGetTokenDone(ref Message message, SecurityToken token, TimeSpan timeout);
- static void GetTokenCompleteCallback(IAsyncResult result)
- {
- if (result == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("result");
- }
- if (result.CompletedSynchronously)
- {
- return;
- }
- GetOneTokenAndSetUpSecurityAsyncResult self = result.AsyncState as GetOneTokenAndSetUpSecurityAsyncResult;
- if (self == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("result", SR.GetString(SR.InvalidAsyncResult));
- }
- Exception completionException = null;
- bool completeSelf = false;
- try
- {
- SecurityToken token = self.provider.EndGetToken(result);
- completeSelf = self.OnGetTokenComplete(token);
- }
- #pragma warning suppress 56500 // covered by FxCOP
- catch (Exception e)
- {
- // Always immediately rethrow fatal exceptions.
- if (Fx.IsFatal(e)) throw;
- completeSelf = true;
- completionException = e;
- }
- if (completeSelf)
- {
- self.Complete(false, completionException);
- }
- }
- protected void SetCorrelationToken(SecurityToken token)
- {
- newCorrelationState = new SecurityProtocolCorrelationState(token);
- }
- protected override bool OnGetSupportingTokensDone(TimeSpan timeout)
- {
- this.timeoutHelper = new TimeoutHelper(timeout);
- IAsyncResult result = this.provider.BeginGetToken(timeoutHelper.RemainingTime(), getTokenCompleteCallback, this);
- if (!result.CompletedSynchronously)
- {
- return false;
- }
- SecurityToken token = this.provider.EndGetToken(result);
- return this.OnGetTokenComplete(token);
- }
- }
- // note: identity check done only on token obtained from first
- // token provider; either or both token providers may be null;
- // get token calls are skipped for null providers.
- protected abstract class GetTwoTokensAndSetUpSecurityAsyncResult : GetSupportingTokensAsyncResult
- {
- readonly MessageSecurityProtocol binding;
- readonly SecurityTokenProvider primaryProvider;
- readonly SecurityTokenProvider secondaryProvider;
- Message message;
- readonly bool doIdentityChecks;
- SecurityTokenAuthenticator identityCheckAuthenticator;
- SecurityToken primaryToken;
- static readonly AsyncCallback getPrimaryTokenCompleteCallback = Fx.ThunkCallback(new AsyncCallback(GetPrimaryTokenCompleteCallback));
- static readonly AsyncCallback getSecondaryTokenCompleteCallback = Fx.ThunkCallback(new AsyncCallback(GetSecondaryTokenCompleteCallback));
- SecurityProtocolCorrelationState newCorrelationState;
- SecurityProtocolCorrelationState oldCorrelationState;
- TimeoutHelper timeoutHelper;
- public GetTwoTokensAndSetUpSecurityAsyncResult(Message m, MessageSecurityProtocol binding,
- SecurityTokenProvider primaryProvider, SecurityTokenProvider secondaryProvider, bool doIdentityChecks, SecurityTokenAuthenticator identityCheckAuthenticator,
- SecurityProtocolCorrelationState oldCorrelationState,
- TimeSpan timeout,
- AsyncCallback callback, object state)
- : base(m, binding, timeout, callback, state)
- {
- this.message = m;
- this.binding = binding;
- this.primaryProvider = primaryProvider;
- this.secondaryProvider = secondaryProvider;
- this.doIdentityChecks = doIdentityChecks;
- this.identityCheckAuthenticator = identityCheckAuthenticator;
- this.oldCorrelationState = oldCorrelationState;
- }
- protected MessageSecurityProtocol Binding
- {
- get { return this.binding; }
- }
- protected SecurityProtocolCorrelationState NewCorrelationState
- {
- get { return this.newCorrelationState; }
- }
- protected SecurityProtocolCorrelationState OldCorrelationState
- {
- get { return this.oldCorrelationState; }
- }
- internal static Message End(IAsyncResult result, out SecurityProtocolCorrelationState newCorrelationState)
- {
- GetTwoTokensAndSetUpSecurityAsyncResult self = AsyncResult.End<GetTwoTokensAndSetUpSecurityAsyncResult>(result);
- newCorrelationState = self.newCorrelationState;
- return self.message;
- }
- bool OnGetPrimaryTokenComplete(SecurityToken token)
- {
- return OnGetPrimaryTokenComplete(token, false);
- }
- bool OnGetPrimaryTokenComplete(SecurityToken token, bool primaryCallSkipped)
- {
- if (!primaryCallSkipped)
- {
- if (token == null)
- {
- throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.TokenProviderCannotGetTokensForTarget, this.binding.Target)), this.message);
- }
- if (this.doIdentityChecks)
- {
- this.binding.EnsureOutgoingIdentity(token, this.identityCheckAuthenticator);
- }
- }
- this.primaryToken = token;
- if (this.secondaryProvider == null)
- {
- return this.OnGetSecondaryTokenComplete(null, true);
- }
- else
- {
- IAsyncResult result = this.secondaryProvider.BeginGetToken(this.timeoutHelper.RemainingTime(), getSecondaryTokenCompleteCallback, this);
- if (!result.CompletedSynchronously)
- {
- return false;
- }
- SecurityToken token2 = this.secondaryProvider.EndGetToken(result);
- return this.OnGetSecondaryTokenComplete(token2);
- }
- }
- bool OnGetSecondaryTokenComplete(SecurityToken token)
- {
- return OnGetSecondaryTokenComplete(token, false);
- }
- bool OnGetSecondaryTokenComplete(SecurityToken token, bool secondaryCallSkipped)
- {
- if (!secondaryCallSkipped && token == null)
- {
- throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.TokenProviderCannotGetTokensForTarget, this.binding.Target)), this.message);
- }
- OnBothGetTokenCallsDone(ref this.message, this.primaryToken, token, timeoutHelper.RemainingTime());
- return true;
- }
- protected abstract void OnBothGetTokenCallsDone(ref Message message, SecurityToken primaryToken, SecurityToken secondaryToken, TimeSpan timeout);
- static void GetPrimaryTokenCompleteCallback(IAsyncResult result)
- {
- if (result == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("result");
- }
- if (result.CompletedSynchronously)
- {
- return;
- }
- GetTwoTokensAndSetUpSecurityAsyncResult self = result.AsyncState as GetTwoTokensAndSetUpSecurityAsyncResult;
- if (self == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("result", SR.GetString(SR.InvalidAsyncResult));
- }
- bool completeSelf = false;
- Exception completionException = null;
- try
- {
- SecurityToken token = self.primaryProvider.EndGetToken(result);
- completeSelf = self.OnGetPrimaryTokenComplete(token);
- }
- #pragma warning suppress 56500 // covered by FxCOP
- catch (Exception e)
- {
- // Always immediately rethrow fatal exceptions.
- if (Fx.IsFatal(e)) throw;
- completeSelf = true;
- completionException = e;
- }
- if (completeSelf)
- {
- self.Complete(false, completionException);
- }
- }
- static void GetSecondaryTokenCompleteCallback(IAsyncResult result)
- {
- if (result == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("result");
- }
- if (result.CompletedSynchronously)
- {
- return;
- }
- GetTwoTokensAndSetUpSecurityAsyncResult self = result.AsyncState as GetTwoTokensAndSetUpSecurityAsyncResult;
- if (self == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("result", SR.GetString(SR.InvalidAsyncResult));
- }
- bool completeSelf = false;
- Exception completionException = null;
- try
- {
- SecurityToken token = self.secondaryProvider.EndGetToken(result);
- completeSelf = self.OnGetSecondaryTokenComplete(token);
- }
- #pragma warning suppress 56500 // covered by FxCOP
- catch (Exception e)
- {
- // Always immediately rethrow fatal exceptions.
- if (Fx.IsFatal(e)) throw;
- completeSelf = true;
- completionException = e;
- }
- if (completeSelf)
- {
- self.Complete(false, completionException);
- }
- }
- protected void SetCorrelationToken(SecurityToken token)
- {
- newCorrelationState = new SecurityProtocolCorrelationState(token);
- }
- protected override bool OnGetSupportingTokensDone(TimeSpan timeout)
- {
- this.timeoutHelper = new TimeoutHelper(timeout);
- bool completeSelf = false;
- if (this.primaryProvider == null)
- {
- completeSelf = this.OnGetPrimaryTokenComplete(null);
- }
- else
- {
- IAsyncResult result = this.primaryProvider.BeginGetToken(this.timeoutHelper.RemainingTime(), getPrimaryTokenCompleteCallback, this);
- if (result.CompletedSynchronously)
- {
- SecurityToken token = this.primaryProvider.EndGetToken(result);
- completeSelf = this.OnGetPrimaryTokenComplete(token);
- }
- }
- return completeSelf;
- }
- }
- }
- }
|