WSSecurityOneDotZeroReceiveSecurityHeader.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Security / WSSecurityOneDotZeroReceiveSecurityHeader.cs / 1 / WSSecurityOneDotZeroReceiveSecurityHeader.cs

                            //---------------------------------------------------------- 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------

namespace System.ServiceModel.Security 
{
    using System.Collections.Generic; 
    using System.ServiceModel.Channels; 
    using System.ServiceModel;
    using System.ServiceModel.Description; 
    using System.Collections.ObjectModel;
    using System.Diagnostics;
    using System.IO;
    using System.IdentityModel.Claims; 
    using System.IdentityModel.Policy;
    using System.IdentityModel.Selectors; 
    using System.IdentityModel.Tokens; 
    using System.Security.Cryptography;
    using System.ServiceModel.Security.Tokens; 
    using System.Text;
    using System.Xml;
    using System.Xml.Serialization;
    using System.ServiceModel.Diagnostics; 

    using Reference = System.IdentityModel.Reference; 
    using SignedXml = System.IdentityModel.SignedXml; 
    using SignedInfo = System.IdentityModel.SignedInfo;
    using StandardSignedInfo = System.IdentityModel.StandardSignedInfo; 
    using Signature = System.IdentityModel.Signature;

    class WSSecurityOneDotZeroReceiveSecurityHeader : ReceiveSecurityHeader
    { 
        WrappedKeySecurityToken pendingDecryptionToken;
        ReferenceList pendingReferenceList; 
        SignedXml pendingSignature; 
        List earlyDecryptedDataReferences;
 
        public WSSecurityOneDotZeroReceiveSecurityHeader(Message message, string actor, bool mustUnderstand, bool relay,
            SecurityStandardsManager standardsManager,
            SecurityAlgorithmSuite algorithmSuite,
            int headerIndex, 
            MessageDirection transferDirection)
            : base(message, actor, mustUnderstand, relay, standardsManager, algorithmSuite, headerIndex, transferDirection) 
        { 
        }
 
        protected static SymmetricAlgorithm CreateDecryptionAlgorithm(SecurityToken token, string encryptionMethod, SecurityAlgorithmSuite suite)
        {
            if (encryptionMethod == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(
                    SR.GetString(SR.EncryptionMethodMissingInEncryptedData))); 
            } 
            suite.EnsureAcceptableEncryptionAlgorithm(encryptionMethod);
            SymmetricSecurityKey symmetricSecurityKey = SecurityUtils.GetSecurityKey(token); 
            if (symmetricSecurityKey == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(
                    SR.GetString(SR.TokenCannotCreateSymmetricCrypto, token))); 
            }
            suite.EnsureAcceptableDecryptionSymmetricKeySize(symmetricSecurityKey, token); 
            SymmetricAlgorithm algorithm = symmetricSecurityKey.GetSymmetricAlgorithm(encryptionMethod); 
            if (algorithm == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(
                    SR.GetString(SR.UnableToCreateSymmetricAlgorithmFromToken, encryptionMethod)));
            }
 
            return algorithm;
        } 
 
        void DecryptBody(XmlDictionaryReader bodyContentReader, SecurityToken token)
        { 
            EncryptedData bodyXml = new EncryptedData();
            bodyXml.SecurityTokenSerializer = this.StandardsManager.SecurityTokenSerializer;
            bodyXml.ReadFrom(bodyContentReader, MaxReceivedMessageSize);
            if (!bodyContentReader.EOF && bodyContentReader.NodeType != XmlNodeType.EndElement) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.GetString(SR.BadEncryptedBody))); 
            } 
            if (token == null)
            { 
                token = ResolveKeyIdentifier(bodyXml.KeyIdentifier, this.PrimaryTokenResolver, false);
            }
            RecordEncryptionToken(token);
            using (SymmetricAlgorithm algorithm = CreateDecryptionAlgorithm(token, bodyXml.EncryptionMethod, this.AlgorithmSuite)) 
            {
                bodyXml.SetUpDecryption(algorithm); 
                this.SecurityVerifiedMessage.SetDecryptedBody(bodyXml.GetDecryptedBuffer()); 
            }
        } 

        protected virtual DecryptedHeader DecryptHeader(XmlDictionaryReader reader, WrappedKeySecurityToken wrappedKeyToken)
        {
            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 
                new MessageSecurityException(SR.GetString(SR.HeaderDecryptionNotSupportedInWsSecurityJan2004)));
        } 
 
        protected override byte[] DecryptSecurityHeaderElement(
            EncryptedData encryptedData, WrappedKeySecurityToken wrappedKeyToken, out SecurityToken encryptionToken) 
        {
            if ((encryptedData.KeyIdentifier != null) || (wrappedKeyToken == null))
            {
                // The EncryptedData might have a KeyInfo inside it. Try resolving the SecurityKeyIdentifier. 
                encryptionToken = ResolveKeyIdentifier(encryptedData.KeyIdentifier, this.CombinedPrimaryTokenResolver, false);
                if (wrappedKeyToken != null && wrappedKeyToken.ReferenceList != null && encryptedData.HasId && wrappedKeyToken.ReferenceList.ContainsReferredId(encryptedData.Id) && (wrappedKeyToken != encryptionToken)) 
                { 
                    // We have a EncryptedKey with a ReferenceList inside it. This would mean that
                    // all the EncryptedData pointed by the ReferenceList should be encrypted only 
                    // by this key. The individual EncryptedData elements if containing a KeyInfo
                    // clause should point back to the same EncryptedKey token.
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.EncryptedKeyWasNotEncryptedWithTheRequiredEncryptingToken, wrappedKeyToken)));
                } 
            }
            else 
            { 
                encryptionToken = wrappedKeyToken;
            } 
            using (SymmetricAlgorithm algorithm = CreateDecryptionAlgorithm(encryptionToken, encryptedData.EncryptionMethod, this.AlgorithmSuite))
            {
                encryptedData.SetUpDecryption(algorithm);
                return encryptedData.GetDecryptedBuffer(); 
            }
        } 
 
        protected override WrappedKeySecurityToken DecryptWrappedKey(XmlDictionaryReader reader)
        { 
            WrappedKeySecurityToken token = (WrappedKeySecurityToken) this.StandardsManager.SecurityTokenSerializer.ReadToken(
                reader, this.PrimaryTokenResolver);
            this.AlgorithmSuite.EnsureAcceptableKeyWrapAlgorithm(token.WrappingAlgorithm, token.WrappingSecurityKey is AsymmetricSecurityKey);
            return token; 
        }
 
        bool EnsureDigestValidityIfIdMatches( 
            SignedInfo signedInfo,
            string id, XmlDictionaryReader reader, bool doSoapAttributeChecks, 
            MessagePartSpecification signatureParts, MessageHeaderInfo info, bool checkForTokensAtHeaders)
        {
            if (signedInfo == null)
            { 
                return false;
            } 
            if (doSoapAttributeChecks) 
            {
                VerifySoapAttributeMatchForHeader(info, signatureParts, reader); 
            }

            bool signed = false;
            bool isRecognizedSecurityToken = checkForTokensAtHeaders && this.StandardsManager.SecurityTokenSerializer.CanReadToken(reader); 

            try 
            { 
                signed = signedInfo.EnsureDigestValidityIfIdMatches(id, reader);
            } 
            catch (CryptographicException exception)
            {
                //
                // Wrap the crypto exception here so that the perf couter can be updated correctly 
                //
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.FailedSignatureVerification), exception)); 
            } 

            if (signed && isRecognizedSecurityToken) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.SecurityTokenFoundOutsideSecurityHeader, info.Namespace, info.Name)));
            }
 
            return signed;
        } 
 
        protected override void ExecuteMessageProtectionPass(bool hasAtLeastOneSupportingTokenExpectedToBeSigned)
        { 
            SignatureTargetIdManager idManager = this.StandardsManager.IdManager;
            MessagePartSpecification encryptionParts = this.RequiredEncryptionParts ?? MessagePartSpecification.NoParts;
            MessagePartSpecification signatureParts = this.RequiredSignatureParts ?? MessagePartSpecification.NoParts;
 
            bool checkForTokensAtHeaders = hasAtLeastOneSupportingTokenExpectedToBeSigned;
            bool doSoapAttributeChecks = !signatureParts.IsBodyIncluded; 
            bool encryptBeforeSign = this.EncryptBeforeSignMode; 
            SignedInfo signedInfo = this.pendingSignature != null ? this.pendingSignature.Signature.SignedInfo : null;
 
            SignatureConfirmations signatureConfirmations = this.GetSentSignatureConfirmations();
            if (signatureConfirmations != null && signatureConfirmations.Count > 0 && signatureConfirmations.IsMarkedForEncryption)
            {
                // If Signature Confirmations are encrypted then the signature should 
                // be encrypted as well.
                this.VerifySignatureEncryption(); 
            } 

            MessageHeaders headers = this.SecurityVerifiedMessage.Headers; 
            XmlDictionaryReader reader = this.SecurityVerifiedMessage.GetReaderAtFirstHeader();

            bool atLeastOneHeaderOrBodyEncrypted = false;
 
            for (int i = 0; i < headers.Count; i++)
            { 
                if (reader.NodeType != XmlNodeType.Element) 
                {
                    reader.MoveToContent(); 
                }

                string id = idManager.ExtractId(reader);
                this.ElementManager.VerifyUniquenessAndSetHeaderId(id, i); 

                if (i == this.HeaderIndex) 
                { 
                    reader.Skip();
                    continue; 
                }

                MessageHeaderInfo info = headers[i];
 
                bool headerEncrypted = id != null && TryDeleteReferenceListEntry(id);
                if (!headerEncrypted && encryptionParts.IsHeaderIncluded(info.Name, info.Namespace)) 
                { 
                    this.SecurityVerifiedMessage.OnUnencryptedPart(info.Name, info.Namespace);
                } 

                bool headerSigned;
                if ((!headerEncrypted || encryptBeforeSign) && id != null)
                { 
                    headerSigned = EnsureDigestValidityIfIdMatches(signedInfo, id, reader, doSoapAttributeChecks, signatureParts, info, checkForTokensAtHeaders);
                } 
                else 
                {
                    headerSigned = false; 
                }

                if (headerEncrypted)
                { 
                    XmlDictionaryReader decryptionReader = headerSigned ? headers.GetReaderAtHeader(i) : reader;
                    DecryptedHeader decryptedHeader = DecryptHeader(decryptionReader, this.pendingDecryptionToken); 
                    info = decryptedHeader; 
                    id = decryptedHeader.Id;
                    this.ElementManager.VerifyUniquenessAndSetDecryptedHeaderId(id, i); 
                    headers.ReplaceAt(i, decryptedHeader);
                    if (!ReferenceEquals(decryptionReader, reader))
                    {
                        decryptionReader.Close(); 
                    }
 
                    if (!encryptBeforeSign && id != null) 
                    {
                        XmlDictionaryReader decryptedHeaderReader = decryptedHeader.GetHeaderReader(); 
                        headerSigned = EnsureDigestValidityIfIdMatches(signedInfo, id, decryptedHeaderReader, doSoapAttributeChecks, signatureParts, info, checkForTokensAtHeaders);
                        decryptedHeaderReader.Close();
                    }
                } 

                if (!headerSigned && signatureParts.IsHeaderIncluded(info.Name, info.Namespace)) 
                { 
                    this.SecurityVerifiedMessage.OnUnsignedPart(info.Name, info.Namespace);
                } 

                if (headerSigned && headerEncrypted)
                {
                    // We have a header that is signed and encrypted. So the accompanying primary signature 
                    // should be encrypted as well.
                    this.VerifySignatureEncryption(); 
                } 

                if (headerEncrypted && !headerSigned) 
                {
                    // We require all encrypted headers (outside the security header) to be signed.
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.EncryptedHeaderNotSigned, info.Name, info.Namespace)));
                } 

                if (!headerSigned && !headerEncrypted) 
                { 
                    reader.Skip();
                } 

                atLeastOneHeaderOrBodyEncrypted |= headerEncrypted;
            }
 
            reader.ReadEndElement();
 
            if (reader.NodeType != XmlNodeType.Element) 
            {
                reader.MoveToContent(); 
            }

            string bodyId = idManager.ExtractId(reader);
            this.ElementManager.VerifyUniquenessAndSetBodyId(bodyId); 
            this.SecurityVerifiedMessage.SetBodyPrefixAndAttributes(reader);
 
            bool expectBodyEncryption = encryptionParts.IsBodyIncluded || HasPendingDecryptionItem(); 

            bool bodySigned; 
            if ((!expectBodyEncryption || encryptBeforeSign) && bodyId != null)
            {
                bodySigned = EnsureDigestValidityIfIdMatches(signedInfo, bodyId, reader, false, null, null, false);
            } 
            else
            { 
                bodySigned = false; 
            }
 
            bool bodyEncrypted;
            if (expectBodyEncryption)
            {
                XmlDictionaryReader bodyReader = bodySigned ? this.SecurityVerifiedMessage.CreateFullBodyReader() : reader; 
                bodyReader.ReadStartElement();
                string bodyContentId = idManager.ExtractId(bodyReader); 
                this.ElementManager.VerifyUniquenessAndSetBodyContentId(bodyContentId); 
                bodyEncrypted = bodyContentId != null && TryDeleteReferenceListEntry(bodyContentId);
                if (bodyEncrypted) 
                {
                    DecryptBody(bodyReader, this.pendingDecryptionToken);
                }
                if (!ReferenceEquals(bodyReader, reader)) 
                {
                    bodyReader.Close(); 
                } 
                if (!encryptBeforeSign && signedInfo != null && signedInfo.HasUnverifiedReference(bodyId))
                { 
                    bodyReader = this.SecurityVerifiedMessage.CreateFullBodyReader();
                    bodySigned = EnsureDigestValidityIfIdMatches(signedInfo, bodyId, bodyReader, false, null, null, false);
                    bodyReader.Close();
                } 
            }
            else 
            { 
                bodyEncrypted = false;
            } 

            if (bodySigned && bodyEncrypted)
            {
                this.VerifySignatureEncryption(); 
            }
 
            reader.Close(); 

            if (this.pendingSignature != null) 
            {
                this.pendingSignature.CompleteSignatureVerification();
                this.pendingSignature = null;
            } 
            this.pendingDecryptionToken = null;
            atLeastOneHeaderOrBodyEncrypted |= bodyEncrypted; 
 
            if (!bodySigned && signatureParts.IsBodyIncluded)
            { 
                this.SecurityVerifiedMessage.OnUnsignedPart(XD.MessageDictionary.Body.Value, this.Version.Envelope.Namespace);
            }

            if (!bodyEncrypted && encryptionParts.IsBodyIncluded) 
            {
                this.SecurityVerifiedMessage.OnUnencryptedPart(XD.MessageDictionary.Body.Value, this.Version.Envelope.Namespace); 
            } 

            this.SecurityVerifiedMessage.OnMessageProtectionPassComplete(atLeastOneHeaderOrBodyEncrypted); 
        }

        protected override bool IsReaderAtEncryptedData(XmlDictionaryReader reader)
        { 
            bool encrypted = reader.IsStartElement(EncryptedData.ElementName, XD.XmlEncryptionDictionary.Namespace);
 
            if (encrypted == true) 
                this.HasAtLeastOneItemInsideSecurityHeaderEncrypted = true;
 
            return encrypted;
        }

        protected override bool IsReaderAtEncryptedKey(XmlDictionaryReader reader) 
        {
            return reader.IsStartElement(EncryptedKey.ElementName, XD.XmlEncryptionDictionary.Namespace); 
        } 

        protected override bool IsReaderAtReferenceList(XmlDictionaryReader reader) 
        {
            return reader.IsStartElement(ReferenceList.ElementName, ReferenceList.NamespaceUri);
        }
 
        protected override bool IsReaderAtSignature(XmlDictionaryReader reader)
        { 
            return reader.IsStartElement(XD.XmlSignatureDictionary.Signature, XD.XmlSignatureDictionary.Namespace); 
        }
 
        protected override void ProcessReferenceListCore(ReferenceList referenceList, WrappedKeySecurityToken wrappedKeyToken)
        {
            this.pendingReferenceList = referenceList;
            this.pendingDecryptionToken = wrappedKeyToken; 
        }
 
        protected override ReferenceList ReadReferenceListCore(XmlDictionaryReader reader) 
        {
            ReferenceList referenceList = new ReferenceList(); 
            referenceList.ReadFrom(reader);
            return referenceList;
        }
 
        protected override EncryptedData ReadSecurityHeaderEncryptedItem(XmlDictionaryReader reader)
        { 
            EncryptedData encryptedData = new EncryptedData(); 
            encryptedData.SecurityTokenSerializer = this.StandardsManager.SecurityTokenSerializer;
            encryptedData.ReadFrom(reader); 
            return encryptedData;
        }

        protected override SignedXml ReadSignatureCore(XmlDictionaryReader signatureReader) 
        {
            SignedXml signedXml = new SignedXml(ServiceModelDictionaryManager.Instance, this.StandardsManager.SecurityTokenSerializer); 
            signedXml.Signature.SignedInfo.ResourcePool = this.ResourcePool; 
            signedXml.ReadFrom(signatureReader);
            return signedXml; 
        }

        protected static bool TryResolveKeyIdentifier(
            SecurityKeyIdentifier keyIdentifier, SecurityTokenResolver resolver, bool isFromSignature, out SecurityToken token) 
        {
            if (keyIdentifier == null) 
            { 
                if (isFromSignature)
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.NoKeyInfoInSignatureToFindVerificationToken)));
                }
                else
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.NoKeyInfoInEncryptedItemToFindDecryptingToken)));
                } 
            } 

            return resolver.TryResolveToken(keyIdentifier, out token); 
        }

        protected static SecurityToken ResolveKeyIdentifier(SecurityKeyIdentifier keyIdentifier, SecurityTokenResolver resolver, bool isFromSignature)
        { 
            SecurityToken token;
            if (!TryResolveKeyIdentifier(keyIdentifier, resolver, isFromSignature, out token)) 
            { 
                if (isFromSignature)
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(
                        SR.GetString(SR.UnableToResolveKeyInfoForVerifyingSignature, keyIdentifier, resolver)));
                }
                else 
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException( 
                        SR.GetString(SR.UnableToResolveKeyInfoForDecryption, keyIdentifier, resolver))); 
                }
            } 

            return token;
        }
 
        SecurityToken ResolveSignatureToken(SecurityKeyIdentifier keyIdentifier, SecurityTokenResolver resolver, bool isPrimarySignature)
        { 
            SecurityToken token; 
            TryResolveKeyIdentifier(keyIdentifier, resolver, true, out token);
            if (token == null && !isPrimarySignature) 
            {
                // check if there is a rsa key token authenticator
                if (keyIdentifier.Count == 1)
                { 
                    RsaKeyIdentifierClause rsaClause;
                    if (keyIdentifier.TryFind(out rsaClause)) 
                    { 
                        RsaSecurityTokenAuthenticator rsaAuthenticator = FindAllowedAuthenticator(false);
                        if (rsaAuthenticator != null) 
                        {
                            token = new RsaSecurityToken(rsaClause.Rsa);
                            ReadOnlyCollection authorizationPolicies = rsaAuthenticator.ValidateToken(token);
                            SupportingTokenAuthenticatorSpecification spec; 
                            TokenTracker rsaTracker = GetSupportingTokenTracker(rsaAuthenticator, out spec);
                            if (rsaTracker == null) 
                            { 
                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new MessageSecurityException(SR.GetString(SR.UnknownTokenAuthenticatorUsedInTokenProcessing, rsaAuthenticator)));
                            } 
                            rsaTracker.RecordToken(token);
                            SecurityTokenAuthorizationPoliciesMapping.Add(token, authorizationPolicies);
                        }
                    } 
                }
            } 
            if (token == null) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException( 
                        SR.GetString(SR.UnableToResolveKeyInfoForVerifyingSignature, keyIdentifier, resolver)));
            }
            return token;
        } 

        bool HasPendingDecryptionItem() 
        { 
            return this.pendingReferenceList != null && this.pendingReferenceList.DataReferenceCount > 0;
        } 

        protected override bool TryDeleteReferenceListEntry(string id)
        {
            return this.pendingReferenceList != null && this.pendingReferenceList.TryRemoveReferredId(id); 
        }
 
        protected override void EnsureDecryptionComplete() 
        {
            if (this.earlyDecryptedDataReferences != null) 
            {
                 for (int i = 0; i < this.earlyDecryptedDataReferences.Count; i++)
                 {
                     if (!TryDeleteReferenceListEntry(this.earlyDecryptedDataReferences[i])) 
                     {
                         throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.UnexpectedEncryptedElementInSecurityHeader)), this.Message); 
                     } 
                 }
            } 
            if (HasPendingDecryptionItem())
            {
                throw TraceUtility.ThrowHelperError(
                    new MessageSecurityException(SR.GetString(SR.UnableToResolveDataReference, this.pendingReferenceList.GetReferredId(0))), this.Message); 
            }
        } 
 
        protected override void OnDecryptionOfSecurityHeaderItemRequiringReferenceListEntry(string id)
        { 
            if (!TryDeleteReferenceListEntry(id))
            {
                if (this.earlyDecryptedDataReferences == null)
                { 
                    this.earlyDecryptedDataReferences = new List(4);
                } 
                this.earlyDecryptedDataReferences.Add(id); 
            }
        } 

        protected override SecurityToken VerifySignature(SignedXml signedXml, bool isPrimarySignature,
            SecurityHeaderTokenResolver resolver, object signatureTarget, string id)
        { 
            SecurityToken token = ResolveSignatureToken(signedXml.Signature.KeyIdentifier, resolver, isPrimarySignature);
            if (isPrimarySignature) 
            { 
                RecordSignatureToken(token);
            } 
            ReadOnlyCollection keys = token.SecurityKeys;
            SecurityKey securityKey = (keys != null && keys.Count > 0) ? keys[0] : null;
            if (securityKey == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(
                    SR.GetString(SR.UnableToCreateICryptoFromTokenForSignatureVerification, token))); 
            } 
            this.AlgorithmSuite.EnsureAcceptableSignatureKeySize(securityKey, token);
            this.AlgorithmSuite.EnsureAcceptableSignatureAlgorithm(securityKey, signedXml.Signature.SignedInfo.SignatureMethod); 
            signedXml.StartSignatureVerification(securityKey);
            StandardSignedInfo signedInfo = (StandardSignedInfo)signedXml.Signature.SignedInfo;
            bool encryptedFormRequired = this.EncryptBeforeSignMode;
            ValidateDigestsOfTargetsInSecurityHeader(signedInfo, this.Timestamp, encryptedFormRequired, isPrimarySignature, signatureTarget, id); 
            if (!isPrimarySignature)
            { 
                if ((!this.RequireMessageProtection) && (securityKey is AsymmetricSecurityKey) && (this.Version.Addressing != AddressingVersion.None)) 
                {
                    // For Transport Security using Asymmetric Keys verify that 
                    // the 'To' header is signed.
                    int headerIndex = this.Message.Headers.FindHeader(XD.AddressingDictionary.To.Value, this.Message.Version.Addressing.Namespace);
                    if (headerIndex == -1)
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.TransportSecuredMessageMissingToHeader))); 
                    XmlDictionaryReader toHeaderReader = this.Message.Headers.GetReaderAtHeader(headerIndex);
                    id = toHeaderReader.GetAttribute(XD.UtilityDictionary.IdAttribute, XD.UtilityDictionary.Namespace); 
                    if (id == null) 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.UnsignedToHeaderInTransportSecuredMessage)));
                    signedXml.EnsureDigestValidity(id, toHeaderReader); 
                }
                signedXml.CompleteSignatureVerification();
                return token;
            } 
            this.pendingSignature = signedXml;
 
            return token; 
        }
 
        void ValidateDigestsOfTargetsInSecurityHeader(StandardSignedInfo signedInfo, SecurityTimestamp timestamp, bool encryptedFormReaderRequired, bool isPrimarySignature, object signatureTarget, string id)
        {
            DiagnosticUtility.DebugAssert(!isPrimarySignature || (isPrimarySignature && (signatureTarget == null)), "For primary signature we try to validate all the references.");
 
            for (int i = 0; i < signedInfo.ReferenceCount; i++)
            { 
                Reference reference = signedInfo[i]; 
                this.AlgorithmSuite.EnsureAcceptableDigestAlgorithm(reference.DigestMethod);
                string referredId = reference.ExtractReferredId(); 
                if (isPrimarySignature || (id == referredId))
                {
                    if (timestamp != null && timestamp.Id == referredId && !reference.TransformChain.NeedsInclusiveContext &&
                        timestamp.DigestAlgorithm == reference.DigestMethod && timestamp.GetDigest() != null) 
                    {
                        reference.EnsureDigestValidity(referredId, timestamp.GetDigest()); 
                        this.ElementManager.SetTimestampSigned(referredId); 
                    }
                    else 
                    {
                        if (signatureTarget != null)
                            reference.EnsureDigestValidity(id, signatureTarget);
                        else 
                        {
                            XmlDictionaryReader reader = this.ElementManager.GetSignatureVerificationReader(referredId, encryptedFormReaderRequired); 
                            if (reader != null) 
                            {
                                reference.EnsureDigestValidity(referredId, reader); 
                                reader.Close();
                            }
                        }
                    } 

                    if (!isPrimarySignature) 
                    { 
                        // We were given an id to verify and we have verified it. So just break out
                        // of the loop. 
                        break;
                    }
                }
            } 
        }
 
 
        void VerifySoapAttributeMatchForHeader(MessageHeaderInfo info, MessagePartSpecification signatureParts, XmlDictionaryReader reader)
        { 
            if (!signatureParts.IsHeaderIncluded(info.Name, info.Namespace))
            {
                return;
            } 

            EnvelopeVersion currentVersion = this.Version.Envelope; 
            EnvelopeVersion otherVersion = currentVersion == EnvelopeVersion.Soap11 ? EnvelopeVersion.Soap12 : EnvelopeVersion.Soap11; 

            bool presentInCurrentVersion; 
            bool presentInOtherVersion;

            presentInCurrentVersion = null != reader.GetAttribute(XD.MessageDictionary.MustUnderstand, currentVersion.DictionaryNamespace);
            presentInOtherVersion = null != reader.GetAttribute(XD.MessageDictionary.MustUnderstand, otherVersion.DictionaryNamespace); 
            if (presentInOtherVersion && !presentInCurrentVersion)
            { 
                throw TraceUtility.ThrowHelperError( 
                    new MessageSecurityException(SR.GetString(
                        SR.InvalidAttributeInSignedHeader, info.Name, info.Namespace, 
                        XD.MessageDictionary.MustUnderstand, otherVersion.DictionaryNamespace,
                        XD.MessageDictionary.MustUnderstand, currentVersion.DictionaryNamespace)), this.SecurityVerifiedMessage);
            }
 
            presentInCurrentVersion = null != reader.GetAttribute(currentVersion.DictionaryActor, currentVersion.DictionaryNamespace);
            presentInOtherVersion = null != reader.GetAttribute(otherVersion.DictionaryActor, otherVersion.DictionaryNamespace); 
            if (presentInOtherVersion && !presentInCurrentVersion) 
            {
                throw TraceUtility.ThrowHelperError( 
                    new MessageSecurityException(SR.GetString(
                        SR.InvalidAttributeInSignedHeader, info.Name, info.Namespace,
                        otherVersion.DictionaryActor, otherVersion.DictionaryNamespace,
                        currentVersion.DictionaryActor, currentVersion.DictionaryNamespace)), this.SecurityVerifiedMessage); 
            }
        } 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK