protected override void ExecuteMessageProtectionPass(bool hasAtLeastOneSupportingTokenExpectedToBeSigned)
        {
            bool flag8;
            bool flag9;
            SignatureTargetIdManager idManager             = base.StandardsManager.IdManager;
            MessagePartSpecification specification         = base.RequiredEncryptionParts ?? MessagePartSpecification.NoParts;
            MessagePartSpecification signatureParts        = base.RequiredSignatureParts ?? MessagePartSpecification.NoParts;
            bool                   checkForTokensAtHeaders = hasAtLeastOneSupportingTokenExpectedToBeSigned;
            bool                   doSoapAttributeChecks   = !signatureParts.IsBodyIncluded;
            bool                   encryptBeforeSignMode   = base.EncryptBeforeSignMode;
            SignedInfo             signedInfo = (this.pendingSignature != null) ? this.pendingSignature.Signature.SignedInfo : null;
            SignatureConfirmations sentSignatureConfirmations = base.GetSentSignatureConfirmations();

            if (((sentSignatureConfirmations != null) && (sentSignatureConfirmations.Count > 0)) && sentSignatureConfirmations.IsMarkedForEncryption)
            {
                base.VerifySignatureEncryption();
            }
            MessageHeaders      headers             = base.SecurityVerifiedMessage.Headers;
            XmlDictionaryReader readerAtFirstHeader = base.SecurityVerifiedMessage.GetReaderAtFirstHeader();
            bool atLeastOneHeaderOrBodyEncrypted    = false;

            for (int i = 0; i < headers.Count; i++)
            {
                if (readerAtFirstHeader.NodeType != XmlNodeType.Element)
                {
                    readerAtFirstHeader.MoveToContent();
                }
                if (i == base.HeaderIndex)
                {
                    readerAtFirstHeader.Skip();
                }
                else
                {
                    bool   flag6;
                    bool   flag5 = false;
                    string str   = idManager.ExtractId(readerAtFirstHeader);
                    if (str != null)
                    {
                        flag5 = this.TryDeleteReferenceListEntry(str);
                    }
                    if (!flag5 && readerAtFirstHeader.IsStartElement("EncryptedHeader", "http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd"))
                    {
                        XmlDictionaryReader readerAtHeader = headers.GetReaderAtHeader(i);
                        readerAtHeader.ReadStartElement("EncryptedHeader", "http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd");
                        if (readerAtHeader.IsStartElement(EncryptedData.ElementName, System.ServiceModel.XD.XmlEncryptionDictionary.Namespace))
                        {
                            string attribute = readerAtHeader.GetAttribute(System.ServiceModel.XD.XmlEncryptionDictionary.Id, null);
                            if ((attribute != null) && this.TryDeleteReferenceListEntry(attribute))
                            {
                                flag5 = true;
                            }
                        }
                    }
                    base.ElementManager.VerifyUniquenessAndSetHeaderId(str, i);
                    MessageHeaderInfo info = headers[i];
                    if (!flag5 && specification.IsHeaderIncluded(info.Name, info.Namespace))
                    {
                        base.SecurityVerifiedMessage.OnUnencryptedPart(info.Name, info.Namespace);
                    }
                    if ((!flag5 || encryptBeforeSignMode) && (str != null))
                    {
                        flag6 = this.EnsureDigestValidityIfIdMatches(signedInfo, str, readerAtFirstHeader, doSoapAttributeChecks, signatureParts, info, checkForTokensAtHeaders);
                    }
                    else
                    {
                        flag6 = false;
                    }
                    if (flag5)
                    {
                        XmlDictionaryReader reader = flag6 ? headers.GetReaderAtHeader(i) : readerAtFirstHeader;
                        DecryptedHeader     header = this.DecryptHeader(reader, this.pendingDecryptionToken);
                        info = header;
                        str  = header.Id;
                        base.ElementManager.VerifyUniquenessAndSetDecryptedHeaderId(str, i);
                        headers.ReplaceAt(i, header);
                        if (!object.ReferenceEquals(reader, readerAtFirstHeader))
                        {
                            reader.Close();
                        }
                        if (!encryptBeforeSignMode && (str != null))
                        {
                            XmlDictionaryReader headerReader = header.GetHeaderReader();
                            flag6 = this.EnsureDigestValidityIfIdMatches(signedInfo, str, headerReader, doSoapAttributeChecks, signatureParts, info, checkForTokensAtHeaders);
                            headerReader.Close();
                        }
                    }
                    if (!flag6 && signatureParts.IsHeaderIncluded(info.Name, info.Namespace))
                    {
                        base.SecurityVerifiedMessage.OnUnsignedPart(info.Name, info.Namespace);
                    }
                    if (flag6 && flag5)
                    {
                        base.VerifySignatureEncryption();
                    }
                    if (flag5 && !flag6)
                    {
                        throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(System.ServiceModel.SR.GetString("EncryptedHeaderNotSigned", new object[] { info.Name, info.Namespace })));
                    }
                    if (!flag6 && !flag5)
                    {
                        readerAtFirstHeader.Skip();
                    }
                    atLeastOneHeaderOrBodyEncrypted |= flag5;
                }
            }
            readerAtFirstHeader.ReadEndElement();
            if (readerAtFirstHeader.NodeType != XmlNodeType.Element)
            {
                readerAtFirstHeader.MoveToContent();
            }
            string id = idManager.ExtractId(readerAtFirstHeader);

            base.ElementManager.VerifyUniquenessAndSetBodyId(id);
            base.SecurityVerifiedMessage.SetBodyPrefixAndAttributes(readerAtFirstHeader);
            bool flag7 = specification.IsBodyIncluded || this.HasPendingDecryptionItem();

            if ((!flag7 || encryptBeforeSignMode) && (id != null))
            {
                flag8 = this.EnsureDigestValidityIfIdMatches(signedInfo, id, readerAtFirstHeader, false, null, null, false);
            }
            else
            {
                flag8 = false;
            }
            if (flag7)
            {
                XmlDictionaryReader reader5 = flag8 ? base.SecurityVerifiedMessage.CreateFullBodyReader() : readerAtFirstHeader;
                reader5.ReadStartElement();
                string str4 = idManager.ExtractId(reader5);
                base.ElementManager.VerifyUniquenessAndSetBodyContentId(str4);
                flag9 = (str4 != null) && this.TryDeleteReferenceListEntry(str4);
                if (flag9)
                {
                    this.DecryptBody(reader5, this.pendingDecryptionToken);
                }
                if (!object.ReferenceEquals(reader5, readerAtFirstHeader))
                {
                    reader5.Close();
                }
                if ((!encryptBeforeSignMode && (signedInfo != null)) && signedInfo.HasUnverifiedReference(id))
                {
                    reader5 = base.SecurityVerifiedMessage.CreateFullBodyReader();
                    flag8   = this.EnsureDigestValidityIfIdMatches(signedInfo, id, reader5, false, null, null, false);
                    reader5.Close();
                }
            }
            else
            {
                flag9 = false;
            }
            if (flag8 && flag9)
            {
                base.VerifySignatureEncryption();
            }
            readerAtFirstHeader.Close();
            if (this.pendingSignature != null)
            {
                this.pendingSignature.CompleteSignatureVerification();
                this.pendingSignature = null;
            }
            this.pendingDecryptionToken      = null;
            atLeastOneHeaderOrBodyEncrypted |= flag9;
            if (!flag8 && signatureParts.IsBodyIncluded)
            {
                base.SecurityVerifiedMessage.OnUnsignedPart(System.ServiceModel.XD.MessageDictionary.Body.Value, base.Version.Envelope.Namespace);
            }
            if (!flag9 && specification.IsBodyIncluded)
            {
                base.SecurityVerifiedMessage.OnUnencryptedPart(System.ServiceModel.XD.MessageDictionary.Body.Value, base.Version.Envelope.Namespace);
            }
            base.SecurityVerifiedMessage.OnMessageProtectionPassComplete(atLeastOneHeaderOrBodyEncrypted);
        }
Esempio n. 2
0
        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();
                }

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

                bool isHeaderEncrypted = false;

                string id = idManager.ExtractId(reader);

                if (id != null)
                {
                    isHeaderEncrypted = TryDeleteReferenceListEntry(id);
                }

                if (!isHeaderEncrypted && reader.IsStartElement(SecurityXXX2005Strings.EncryptedHeader, SecurityXXX2005Strings.Namespace))
                {
                    XmlDictionaryReader localreader = headers.GetReaderAtHeader(i);
                    localreader.ReadStartElement(SecurityXXX2005Strings.EncryptedHeader, SecurityXXX2005Strings.Namespace);

                    if (localreader.IsStartElement(EncryptedData.ElementName, XD.XmlEncryptionDictionary.Namespace))
                    {
                        string encryptedDataId = localreader.GetAttribute(XD.XmlEncryptionDictionary.Id, null);

                        if (encryptedDataId != null && TryDeleteReferenceListEntry(encryptedDataId))
                        {
                            isHeaderEncrypted = true;
                        }
                    }
                }

                this.ElementManager.VerifyUniquenessAndSetHeaderId(id, i);

                MessageHeaderInfo info = headers[i];

                if (!isHeaderEncrypted && encryptionParts.IsHeaderIncluded(info.Name, info.Namespace))
                {
                    this.SecurityVerifiedMessage.OnUnencryptedPart(info.Name, info.Namespace);
                }

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

                if (isHeaderEncrypted)
                {
                    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 && isHeaderEncrypted)
                {
                    // We have a header that is signed and encrypted. So the accompanying primary signature
                    // should be encrypted as well.
                    this.VerifySignatureEncryption();
                }

                if (isHeaderEncrypted && !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 && !isHeaderEncrypted)
                {
                    reader.Skip();
                }

                atLeastOneHeaderOrBodyEncrypted |= isHeaderEncrypted;
            }

            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);
        }