public override void ApplyBodySecurity(XmlDictionaryWriter writer, IPrefixGenerator prefixGenerator)
        {
            SecurityAppliedMessage message = this.SecurityAppliedMessage;
            EncryptedData          encryptedData;
            HashStream             hashStream;

            switch (message.BodyProtectionMode)
            {
            case MessagePartProtectionMode.None:
                return;

            case MessagePartProtectionMode.Sign:
                hashStream = TakeHashStream();
                if (CanCanonicalizeAndFragment(writer))
                {
                    message.WriteBodyToSignWithFragments(hashStream, false, null, writer);
                }
                else
                {
                    message.WriteBodyToSign(hashStream);
                }
                this.signedInfo.AddReference(message.BodyId, hashStream.FlushHashAndGetValue());
                return;

            case MessagePartProtectionMode.SignThenEncrypt:
                hashStream    = TakeHashStream();
                encryptedData = CreateEncryptedDataForBody();
                if (CanCanonicalizeAndFragment(writer))
                {
                    message.WriteBodyToSignThenEncryptWithFragments(hashStream, false, null, encryptedData, this.encryptingSymmetricAlgorithm, writer);
                }
                else
                {
                    message.WriteBodyToSignThenEncrypt(hashStream, encryptedData, this.encryptingSymmetricAlgorithm);
                }
                this.signedInfo.AddReference(message.BodyId, hashStream.FlushHashAndGetValue());
                this.referenceList.AddReferredId(encryptedData.Id);
                this.hasSignedEncryptedMessagePart = true;
                return;

            case MessagePartProtectionMode.Encrypt:
                encryptedData = CreateEncryptedDataForBody();
                message.WriteBodyToEncrypt(encryptedData, this.encryptingSymmetricAlgorithm);
                this.referenceList.AddReferredId(encryptedData.Id);
                return;

            case MessagePartProtectionMode.EncryptThenSign:
                hashStream    = TakeHashStream();
                encryptedData = CreateEncryptedDataForBody();
                message.WriteBodyToEncryptThenSign(hashStream, encryptedData, this.encryptingSymmetricAlgorithm);
                this.signedInfo.AddReference(message.BodyId, hashStream.FlushHashAndGetValue());
                this.referenceList.AddReferredId(encryptedData.Id);
                return;

            default:
                Fx.Assert("Invalid MessagePartProtectionMode");
                return;
            }
        }
 void AddEncryptionReference(MessageHeader header, string headerId, IPrefixGenerator prefixGenerator, bool sign,
     out MemoryStream plainTextStream, out string encryptedDataId)
 {
     plainTextStream = new MemoryStream();
     XmlDictionaryWriter encryptingWriter = XmlDictionaryWriter.CreateTextWriter(plainTextStream);
     if (sign)
     {
         AddSignatureReference(header, headerId, prefixGenerator, encryptingWriter);
     }
     else
     {
         header.WriteHeader(encryptingWriter, this.Version);
         encryptingWriter.Flush();
     }
     encryptedDataId = this.GenerateId();
     referenceList.AddReferredId(encryptedDataId);
 }
        void AddEncryptionReference(MessageHeader header, string headerId, IPrefixGenerator prefixGenerator, bool sign,
                                    out MemoryStream plainTextStream, out string encryptedDataId)
        {
            plainTextStream = new MemoryStream();
            XmlDictionaryWriter encryptingWriter = XmlDictionaryWriter.CreateTextWriter(plainTextStream);

            if (sign)
            {
                AddSignatureReference(header, headerId, prefixGenerator, encryptingWriter);
            }
            else
            {
                header.WriteHeader(encryptingWriter, this.Version);
                encryptingWriter.Flush();
            }
            encryptedDataId = this.GenerateId();
            referenceList.AddReferredId(encryptedDataId);
        }
        string GetSignatureHash(MessageHeader header, string headerId, IPrefixGenerator prefixGenerator, XmlDictionaryWriter writer, out byte[] hash)
        {
            HashStream          hashStream = TakeHashStream();
            XmlDictionaryWriter effectiveWriter;
            XmlBuffer           canonicalBuffer = null;

            if (writer.CanCanonicalize)
            {
                effectiveWriter = writer;
            }
            else
            {
                canonicalBuffer = new XmlBuffer(int.MaxValue);
                effectiveWriter = canonicalBuffer.OpenSection(XmlDictionaryReaderQuotas.Max);
            }

            effectiveWriter.StartCanonicalization(hashStream, false, null);

            header.WriteStartHeader(effectiveWriter, this.Version);
            if (headerId == null)
            {
                headerId = GenerateId();
                this.StandardsManager.IdManager.WriteIdAttribute(effectiveWriter, headerId);
            }
            header.WriteHeaderContents(effectiveWriter, this.Version);
            effectiveWriter.WriteEndElement();
            effectiveWriter.EndCanonicalization();
            effectiveWriter.Flush();

            if (!ReferenceEquals(effectiveWriter, writer))
            {
                Fx.Assert(canonicalBuffer != null, "Canonical buffer cannot be null.");
                canonicalBuffer.CloseSection();
                canonicalBuffer.Close();
                XmlDictionaryReader dicReader = canonicalBuffer.GetReader(0);
                writer.WriteNode(dicReader, false);
                dicReader.Close();
            }

            hash = hashStream.FlushHashAndGetValue();

            return(headerId);
        }
 public override void ApplyBodySecurity(XmlDictionaryWriter writer, IPrefixGenerator prefixGenerator)
 {
     SecurityAppliedMessage message = this.SecurityAppliedMessage;
     EncryptedData encryptedData;
     HashStream hashStream;
     switch (message.BodyProtectionMode)
     {
         case MessagePartProtectionMode.None:
             return;
         case MessagePartProtectionMode.Sign:
             hashStream = TakeHashStream();
             if (CanCanonicalizeAndFragment(writer))
             {
                 message.WriteBodyToSignWithFragments(hashStream, false, null, writer);
             }
             else
             {
                 message.WriteBodyToSign(hashStream);
             }
             this.signedInfo.AddReference(message.BodyId, hashStream.FlushHashAndGetValue());
             return;
         case MessagePartProtectionMode.SignThenEncrypt:
             hashStream = TakeHashStream();
             encryptedData = CreateEncryptedDataForBody();
             if (CanCanonicalizeAndFragment(writer))
             {
                 message.WriteBodyToSignThenEncryptWithFragments(hashStream, false, null, encryptedData, this.encryptingSymmetricAlgorithm, writer);
             }
             else
             {
                 message.WriteBodyToSignThenEncrypt(hashStream, encryptedData, this.encryptingSymmetricAlgorithm);
             }
             this.signedInfo.AddReference(message.BodyId, hashStream.FlushHashAndGetValue());
             this.referenceList.AddReferredId(encryptedData.Id);
             this.hasSignedEncryptedMessagePart = true;
             return;
         case MessagePartProtectionMode.Encrypt:
             encryptedData = CreateEncryptedDataForBody();
             message.WriteBodyToEncrypt(encryptedData, this.encryptingSymmetricAlgorithm);
             this.referenceList.AddReferredId(encryptedData.Id);
             return;
         case MessagePartProtectionMode.EncryptThenSign:
             hashStream = TakeHashStream();
             encryptedData = CreateEncryptedDataForBody();
             message.WriteBodyToEncryptThenSign(hashStream, encryptedData, this.encryptingSymmetricAlgorithm);
             this.signedInfo.AddReference(message.BodyId, hashStream.FlushHashAndGetValue());
             this.referenceList.AddReferredId(encryptedData.Id);
             return;
         default:
             Fx.Assert("Invalid MessagePartProtectionMode");
             return;
     }
 }
        public override void ApplySecurityAndWriteHeaders(MessageHeaders headers, XmlDictionaryWriter writer, IPrefixGenerator prefixGenerator)
        {
            string[] headerIds;
            if (this.RequireMessageProtection || this.ShouldSignToHeader)
            {
                headerIds = headers.GetHeaderAttributes(UtilityStrings.IdAttribute,
                    this.StandardsManager.IdManager.DefaultIdNamespaceUri);
            }
            else
            {
                headerIds = null;
            }
            for (int i = 0; i < headers.Count; i++)
            {
                MessageHeader header = headers.GetMessageHeader(i);
                if (this.Version.Addressing == AddressingVersion.None && header.Namespace == AddressingVersion.None.Namespace)
                {
                    continue;
                }

                if (header != this)
                {
                    ApplySecurityAndWriteHeader(header, headerIds == null ? null : headerIds[i], writer, prefixGenerator);
                }
            }
        }
        void ApplySecurityAndWriteHeader(MessageHeader header, string headerId, XmlDictionaryWriter writer, IPrefixGenerator prefixGenerator)
        {
            if (!this.RequireMessageProtection && this.ShouldSignToHeader)
            {
                if ((header.Name == XD.AddressingDictionary.To.Value) &&
                    (header.Namespace == this.Message.Version.Addressing.Namespace))
                {
                    if (this.toHeaderHash == null)
                    {
                        byte[] headerHash;
                        headerId = GetSignatureHash(header, headerId, prefixGenerator, writer, out headerHash);
                        this.toHeaderHash = headerHash;
                        this.toHeaderId = headerId;
                    }
                    else
                        // More than one 'To' header is specified in the message.
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.TransportSecuredMessageHasMoreThanOneToHeader)));

                    return;
                }
            }

            MessagePartProtectionMode protectionMode = GetProtectionMode(header);
            MemoryStream plainTextStream;
            string encryptedDataId;
            switch (protectionMode)
            {
                case MessagePartProtectionMode.None:
                    header.WriteHeader(writer, this.Version);
                    return;
                case MessagePartProtectionMode.Sign:
                    AddSignatureReference(header, headerId, prefixGenerator, writer);
                    return;
                case MessagePartProtectionMode.SignThenEncrypt:
                    AddEncryptionReference(header, headerId, prefixGenerator, true, out plainTextStream, out encryptedDataId);
                    EncryptAndWriteHeader(header, encryptedDataId, plainTextStream, writer);
                    this.hasSignedEncryptedMessagePart = true;
                    return;
                case MessagePartProtectionMode.Encrypt:
                    AddEncryptionReference(header, headerId, prefixGenerator, false, out plainTextStream, out encryptedDataId);
                    EncryptAndWriteHeader(header, encryptedDataId, plainTextStream, writer);
                    return;
                case MessagePartProtectionMode.EncryptThenSign:
                    AddEncryptionReference(header, headerId, prefixGenerator, false, out plainTextStream, out encryptedDataId);
                    EncryptedHeader encryptedHeader = EncryptHeader(
                        header, this.encryptingSymmetricAlgorithm, this.encryptionKeyIdentifier, this.Version, encryptedDataId, plainTextStream);
                    AddSignatureReference(encryptedHeader, encryptedDataId, prefixGenerator, writer);
                    return;
                default:
                    Fx.Assert("Invalid MessagePartProtectionMode");
                    return;
            }
        }
 void AddSignatureReference(MessageHeader header, string headerId, IPrefixGenerator prefixGenerator, XmlDictionaryWriter writer)
 {
     byte[] hashValue;
     headerId = GetSignatureHash(header, headerId, prefixGenerator, writer, out hashValue);
     this.signedInfo.AddReference(headerId, hashValue);
 }
        string GetSignatureHash(MessageHeader header, string headerId, IPrefixGenerator prefixGenerator, XmlDictionaryWriter writer, out byte[] hash)
        {
            HashStream hashStream = TakeHashStream();
            XmlDictionaryWriter effectiveWriter;
            XmlBuffer canonicalBuffer = null;

            if (writer.CanCanonicalize)
            {
                effectiveWriter = writer;
            }
            else
            {
                canonicalBuffer = new XmlBuffer(int.MaxValue);
                effectiveWriter = canonicalBuffer.OpenSection(XmlDictionaryReaderQuotas.Max);
            }

            effectiveWriter.StartCanonicalization(hashStream, false, null);

            header.WriteStartHeader(effectiveWriter, this.Version);
            if (headerId == null)
            {
                headerId = GenerateId();
                this.StandardsManager.IdManager.WriteIdAttribute(effectiveWriter, headerId);
            }
            header.WriteHeaderContents(effectiveWriter, this.Version);
            effectiveWriter.WriteEndElement();
            effectiveWriter.EndCanonicalization();
            effectiveWriter.Flush();

            if (!ReferenceEquals(effectiveWriter, writer))
            {
                Fx.Assert(canonicalBuffer != null, "Canonical buffer cannot be null.");
                canonicalBuffer.CloseSection();
                canonicalBuffer.Close();
                XmlDictionaryReader dicReader = canonicalBuffer.GetReader(0);
                writer.WriteNode(dicReader, false);
                dicReader.Close();
            }

            hash = hashStream.FlushHashAndGetValue();

            return headerId;
        }
        public override void ApplySecurityAndWriteHeaders(MessageHeaders headers, XmlDictionaryWriter writer, IPrefixGenerator prefixGenerator)
        {
            string[] headerIds;
            if (this.RequireMessageProtection || this.ShouldSignToHeader)
            {
                headerIds = headers.GetHeaderAttributes(UtilityStrings.IdAttribute,
                                                        this.StandardsManager.IdManager.DefaultIdNamespaceUri);
            }
            else
            {
                headerIds = null;
            }
            for (int i = 0; i < headers.Count; i++)
            {
                MessageHeader header = headers.GetMessageHeader(i);
                if (this.Version.Addressing == AddressingVersion.None && header.Namespace == AddressingVersion.None.Namespace)
                {
                    continue;
                }

                if (header != this)
                {
                    ApplySecurityAndWriteHeader(header, headerIds == null ? null : headerIds[i], writer, prefixGenerator);
                }
            }
        }
        void ApplySecurityAndWriteHeader(MessageHeader header, string headerId, XmlDictionaryWriter writer, IPrefixGenerator prefixGenerator)
        {
            if (!this.RequireMessageProtection && this.ShouldSignToHeader)
            {
                if ((header.Name == XD.AddressingDictionary.To.Value) &&
                    (header.Namespace == this.Message.Version.Addressing.Namespace))
                {
                    if (this.toHeaderHash == null)
                    {
                        byte[] headerHash;
                        headerId          = GetSignatureHash(header, headerId, prefixGenerator, writer, out headerHash);
                        this.toHeaderHash = headerHash;
                        this.toHeaderId   = headerId;
                    }
                    else
                    {
                        // More than one 'To' header is specified in the message.
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.TransportSecuredMessageHasMoreThanOneToHeader)));
                    }

                    return;
                }
            }

            MessagePartProtectionMode protectionMode = GetProtectionMode(header);
            MemoryStream plainTextStream;
            string       encryptedDataId;

            switch (protectionMode)
            {
            case MessagePartProtectionMode.None:
                header.WriteHeader(writer, this.Version);
                return;

            case MessagePartProtectionMode.Sign:
                AddSignatureReference(header, headerId, prefixGenerator, writer);
                return;

            case MessagePartProtectionMode.SignThenEncrypt:
                AddEncryptionReference(header, headerId, prefixGenerator, true, out plainTextStream, out encryptedDataId);
                EncryptAndWriteHeader(header, encryptedDataId, plainTextStream, writer);
                this.hasSignedEncryptedMessagePart = true;
                return;

            case MessagePartProtectionMode.Encrypt:
                AddEncryptionReference(header, headerId, prefixGenerator, false, out plainTextStream, out encryptedDataId);
                EncryptAndWriteHeader(header, encryptedDataId, plainTextStream, writer);
                return;

            case MessagePartProtectionMode.EncryptThenSign:
                AddEncryptionReference(header, headerId, prefixGenerator, false, out plainTextStream, out encryptedDataId);
                EncryptedHeader encryptedHeader = EncryptHeader(
                    header, this.encryptingSymmetricAlgorithm, this.encryptionKeyIdentifier, this.Version, encryptedDataId, plainTextStream);
                AddSignatureReference(encryptedHeader, encryptedDataId, prefixGenerator, writer);
                return;

            default:
                Fx.Assert("Invalid MessagePartProtectionMode");
                return;
            }
        }
 void AddSignatureReference(MessageHeader header, string headerId, IPrefixGenerator prefixGenerator, XmlDictionaryWriter writer)
 {
     byte[] hashValue;
     headerId = GetSignatureHash(header, headerId, prefixGenerator, writer, out hashValue);
     this.signedInfo.AddReference(headerId, hashValue);
 }
 public abstract void ApplySecurityAndWriteHeaders(MessageHeaders headers, XmlDictionaryWriter writer, IPrefixGenerator prefixGenerator);
 public abstract void ApplyBodySecurity(XmlDictionaryWriter writer, IPrefixGenerator prefixGenerator);