SecurityAppliedMessage.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 / SecurityAppliedMessage.cs / 1 / SecurityAppliedMessage.cs

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

namespace System.ServiceModel.Security 
{
    using System.Diagnostics; 
    using System.IO; 
    using System.Text;
    using System.Xml; 
    using System.Security.Cryptography;
    using System.ServiceModel.Channels;

    using ISecurityElement = System.IdentityModel.ISecurityElement; 
    using XmlAttributeHolder = System.IdentityModel.XmlAttributeHolder;
    using IPrefixGenerator = System.IdentityModel.IPrefixGenerator; 
 
    sealed class SecurityAppliedMessage : DelegatingMessage
    { 
        string bodyId;
        bool bodyIdInserted;
        string bodyPrefix = MessageStrings.Prefix;
        XmlBuffer fullBodyBuffer; 
        ISecurityElement encryptedBodyContent;
        XmlAttributeHolder[] bodyAttributes; 
        bool delayedApplicationHandled; 
        readonly MessagePartProtectionMode bodyProtectionMode;
        BodyState state = BodyState.Created; 
        readonly SendSecurityHeader securityHeader;
        MemoryStream startBodyFragment;
        MemoryStream endBodyFragment;
        byte[] fullBodyFragment; 
        int fullBodyFragmentLength;
 
        public SecurityAppliedMessage(Message messageToProcess, SendSecurityHeader securityHeader, bool signBody, bool encryptBody) 
            : base(messageToProcess)
        { 
            DiagnosticUtility.DebugAssert(!(messageToProcess is SecurityAppliedMessage), "SecurityAppliedMessage should not be wrapped");
            this.securityHeader = securityHeader;
            this.bodyProtectionMode = MessagePartProtectionModeHelper.GetProtectionMode(signBody, encryptBody, securityHeader.SignThenEncrypt);
        } 

        public string BodyId 
        { 
            get { return this.bodyId; }
        } 

        public MessagePartProtectionMode BodyProtectionMode
        {
            get { return this.bodyProtectionMode; } 
        }
 
        internal byte[] PrimarySignatureValue 
        {
            get { return this.securityHeader.PrimarySignatureValue; } 
        }

        Exception CreateBadStateException(string operation)
        { 
            return new InvalidOperationException(SR.GetString(SR.MessageBodyOperationNotValidInBodyState,
                operation, this.state)); 
        } 

        void EnsureUniqueSecurityApplication() 
        {
            if (this.delayedApplicationHandled)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.DelayedSecurityApplicationAlreadyCompleted))); 
            }
            this.delayedApplicationHandled = true; 
        } 

        protected override void OnBodyToString(XmlDictionaryWriter writer) 
        {
            if (this.state == BodyState.Created || this.fullBodyFragment != null)
            {
                base.OnBodyToString(writer); 
            }
            else 
            { 
                OnWriteBodyContents(writer);
            } 
        }

        protected override void OnClose()
        { 
            try
            { 
                this.InnerMessage.Close(); 
            }
            finally 
            {
                this.fullBodyBuffer = null;
                this.bodyAttributes = null;
                this.encryptedBodyContent = null; 
                this.state = BodyState.Disposed;
            } 
        } 

        protected override void OnWriteStartBody(XmlDictionaryWriter writer) 
        {
            if (this.startBodyFragment != null || this.fullBodyFragment != null)
            {
                WriteStartInnerMessageWithId(writer); 
                return;
            } 
 
            switch (this.state)
            { 
                case BodyState.Created:
                case BodyState.Encrypted:
                    this.InnerMessage.WriteStartBody(writer);
                    return; 
                case BodyState.Signed:
                case BodyState.EncryptedThenSigned: 
                    XmlDictionaryReader reader = fullBodyBuffer.GetReader(0); 
                    writer.WriteStartElement(reader.Prefix, reader.LocalName, reader.NamespaceURI);
                    writer.WriteAttributes(reader, false); 
                    reader.Close();
                    return;
                case BodyState.SignedThenEncrypted:
                    writer.WriteStartElement(this.bodyPrefix, XD.MessageDictionary.Body, this.Version.Envelope.DictionaryNamespace); 
                    if (this.bodyAttributes != null)
                    { 
                        XmlAttributeHolder.WriteAttributes(this.bodyAttributes, writer); 
                    }
                    return; 
                default:
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateBadStateException("OnWriteStartBody"));
            }
        } 

        protected override void OnWriteBodyContents(XmlDictionaryWriter writer) 
        { 
            switch (this.state)
            { 
                case BodyState.Created:
                    this.InnerMessage.WriteBodyContents(writer);
                    return;
                case BodyState.Signed: 
                case BodyState.EncryptedThenSigned:
                    XmlDictionaryReader reader = fullBodyBuffer.GetReader(0); 
                    reader.ReadStartElement(); 
                    while (reader.NodeType != XmlNodeType.EndElement)
                        writer.WriteNode(reader, false); 
                    reader.ReadEndElement();
                    reader.Close();
                    return;
                case BodyState.Encrypted: 
                case BodyState.SignedThenEncrypted:
                    this.encryptedBodyContent.WriteTo(writer, ServiceModelDictionaryManager.Instance); 
                    break; 
                default:
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateBadStateException("OnWriteBodyContents")); 
            }
        }

        protected override void OnWriteMessage(XmlDictionaryWriter writer) 
        {
            EnsureUniqueSecurityApplication(); 
 
            MessagePrefixGenerator prefixGenerator = new MessagePrefixGenerator(writer);
            this.securityHeader.StartSecurityApplication(); 

            this.Headers.Add(this.securityHeader);

            this.InnerMessage.WriteStartEnvelope(writer); 

            this.Headers.RemoveAt(this.Headers.Count - 1); 
 
            this.securityHeader.ApplyBodySecurity(writer, prefixGenerator);
 
            this.InnerMessage.WriteStartHeaders(writer);
            this.securityHeader.ApplySecurityAndWriteHeaders(this.Headers, writer, prefixGenerator);

            this.securityHeader.RemoveSignatureEncryptionIfAppropriate(); 

            this.securityHeader.CompleteSecurityApplication(); 
            this.securityHeader.WriteHeader(writer, this.Version); 
            writer.WriteEndElement();
 
            if (this.fullBodyFragment != null)
            {
                ((IFragmentCapableXmlDictionaryWriter) writer).WriteFragment(this.fullBodyFragment, 0, this.fullBodyFragmentLength);
            } 
            else
            { 
                if (this.startBodyFragment != null) 
                {
                    ((IFragmentCapableXmlDictionaryWriter) writer).WriteFragment(this.startBodyFragment.GetBuffer(), 0, (int) this.startBodyFragment.Length); 
                }
                else
                {
                    OnWriteStartBody(writer); 
                }
 
                OnWriteBodyContents(writer); 

                if (this.endBodyFragment != null) 
                {
                    ((IFragmentCapableXmlDictionaryWriter) writer).WriteFragment(this.endBodyFragment.GetBuffer(), 0, (int) this.endBodyFragment.Length);
                }
                else 
                {
                    writer.WriteEndElement(); 
                } 
            }
 
            writer.WriteEndElement();
        }

        void SetBodyId() 
        {
            this.bodyId = this.InnerMessage.GetBodyAttribute( 
                UtilityStrings.IdAttribute, 
                this.securityHeader.StandardsManager.IdManager.DefaultIdNamespaceUri);
            if (this.bodyId == null) 
            {
                this.bodyId = this.securityHeader.GenerateId();
                this.bodyIdInserted = true;
            } 
        }
 
        public void WriteBodyToEncrypt(EncryptedData encryptedData, SymmetricAlgorithm algorithm) 
        {
            encryptedData.Id = this.securityHeader.GenerateId(); 

            BodyContentHelper helper = new BodyContentHelper();
            XmlDictionaryWriter encryptingWriter = helper.CreateWriter();
            this.InnerMessage.WriteBodyContents(encryptingWriter); 
            encryptedData.SetUpEncryption(algorithm, helper.ExtractResult());
            this.encryptedBodyContent = encryptedData; 
 
            this.state = BodyState.Encrypted;
        } 

        public void WriteBodyToEncryptThenSign(Stream canonicalStream, EncryptedData encryptedData, SymmetricAlgorithm algorithm)
        {
            encryptedData.Id = this.securityHeader.GenerateId(); 
            SetBodyId();
 
            XmlDictionaryWriter encryptingWriter = XmlDictionaryWriter.CreateTextWriter(Stream.Null); 
            // The XmlSerializer body formatter would add a
            // document declaration to the body fragment when a fresh writer 
            // is provided. Hence, insert a dummy element here and capture
            // the body contents as a fragment.
            encryptingWriter.WriteStartElement("a");
            MemoryStream ms = new MemoryStream(); 
            ((IFragmentCapableXmlDictionaryWriter)encryptingWriter).StartFragment(ms, true);
 
            this.InnerMessage.WriteBodyContents(encryptingWriter); 
            ((IFragmentCapableXmlDictionaryWriter)encryptingWriter).EndFragment();
            encryptingWriter.WriteEndElement(); 
            ms.Flush();
            encryptedData.SetUpEncryption(algorithm, new ArraySegment(ms.GetBuffer(), 0, (int) ms.Length));

            this.fullBodyBuffer = new XmlBuffer(int.MaxValue); 
            XmlDictionaryWriter canonicalWriter = this.fullBodyBuffer.OpenSection(XmlDictionaryReaderQuotas.Max);
 
            canonicalWriter.StartCanonicalization(canonicalStream, false, null); 
            WriteStartInnerMessageWithId(canonicalWriter);
            encryptedData.WriteTo(canonicalWriter, ServiceModelDictionaryManager.Instance); 
            canonicalWriter.WriteEndElement();
            canonicalWriter.EndCanonicalization();
            canonicalWriter.Flush();
 
            this.fullBodyBuffer.CloseSection();
            this.fullBodyBuffer.Close(); 
 
            this.state = BodyState.EncryptedThenSigned;
        } 

        public void WriteBodyToSign(Stream canonicalStream)
        {
            SetBodyId(); 

            this.fullBodyBuffer = new XmlBuffer(int.MaxValue); 
            XmlDictionaryWriter canonicalWriter = this.fullBodyBuffer.OpenSection(XmlDictionaryReaderQuotas.Max); 
            canonicalWriter.StartCanonicalization(canonicalStream, false, null);
            WriteInnerMessageWithId(canonicalWriter); 
            canonicalWriter.EndCanonicalization();
            canonicalWriter.Flush();
            this.fullBodyBuffer.CloseSection();
            this.fullBodyBuffer.Close(); 

            this.state = BodyState.Signed; 
        } 

        public void WriteBodyToSignThenEncrypt(Stream canonicalStream, EncryptedData encryptedData, SymmetricAlgorithm algorithm) 
        {
            XmlBuffer buffer = new XmlBuffer(int.MaxValue);
            XmlDictionaryWriter fragmentingWriter = buffer.OpenSection(XmlDictionaryReaderQuotas.Max);
            WriteBodyToSignThenEncryptWithFragments(canonicalStream, false, null, encryptedData, algorithm, fragmentingWriter); 
            ((IFragmentCapableXmlDictionaryWriter)fragmentingWriter).WriteFragment(this.startBodyFragment.GetBuffer(), 0, (int)this.startBodyFragment.Length);
            ((IFragmentCapableXmlDictionaryWriter)fragmentingWriter).WriteFragment(this.endBodyFragment.GetBuffer(), 0, (int)this.endBodyFragment.Length); 
            buffer.CloseSection(); 
            buffer.Close();
 
            this.startBodyFragment = null;
            this.endBodyFragment = null;

            XmlDictionaryReader reader = buffer.GetReader(0); 
            reader.MoveToContent();
            this.bodyPrefix = reader.Prefix; 
            if (reader.HasAttributes) 
            {
                this.bodyAttributes = XmlAttributeHolder.ReadAttributes(reader); 
            }
            reader.Close();
        }
 
        public void WriteBodyToSignThenEncryptWithFragments(
            Stream stream, bool includeComments, string[] inclusivePrefixes, 
            EncryptedData encryptedData, SymmetricAlgorithm algorithm, XmlDictionaryWriter writer) 
        {
            IFragmentCapableXmlDictionaryWriter fragmentingWriter = (IFragmentCapableXmlDictionaryWriter) writer; 

            SetBodyId();
            encryptedData.Id = this.securityHeader.GenerateId();
 
            this.startBodyFragment = new MemoryStream();
            BufferedOutputStream bodyContentFragment = new BufferedOutputStream(SR.XmlBufferQuotaExceeded, 1024, int.MaxValue, BufferManager.CreateBufferManager(0, int.MaxValue)); 
            this.endBodyFragment = new MemoryStream(); 

            writer.StartCanonicalization(stream, includeComments, inclusivePrefixes); 

            fragmentingWriter.StartFragment(this.startBodyFragment, false);
            WriteStartInnerMessageWithId(writer);
            fragmentingWriter.EndFragment(); 

            fragmentingWriter.StartFragment(bodyContentFragment, true); 
            this.InnerMessage.WriteBodyContents(writer); 
            fragmentingWriter.EndFragment();
 
            fragmentingWriter.StartFragment(this.endBodyFragment, false);
            writer.WriteEndElement();
            fragmentingWriter.EndFragment();
 
            writer.EndCanonicalization();
 
            int bodyLength; 
            byte[] bodyBuffer = bodyContentFragment.ToArray(out bodyLength);
 
            encryptedData.SetUpEncryption(algorithm, new ArraySegment(bodyBuffer, 0, bodyLength));
            this.encryptedBodyContent = encryptedData;

            this.state = BodyState.SignedThenEncrypted; 
        }
 
        public void WriteBodyToSignWithFragments(Stream stream, bool includeComments, string[] inclusivePrefixes, XmlDictionaryWriter writer) 
        {
            IFragmentCapableXmlDictionaryWriter fragmentingWriter = (IFragmentCapableXmlDictionaryWriter) writer; 

            SetBodyId();
            BufferedOutputStream fullBodyFragment = new BufferedOutputStream(SR.XmlBufferQuotaExceeded, 1024, int.MaxValue, BufferManager.CreateBufferManager(0, int.MaxValue));
 
            writer.StartCanonicalization(stream, includeComments, inclusivePrefixes);
            fragmentingWriter.StartFragment(fullBodyFragment, false); 
            WriteStartInnerMessageWithId(writer); 
            this.InnerMessage.WriteBodyContents(writer);
            writer.WriteEndElement(); 
            fragmentingWriter.EndFragment();
            writer.EndCanonicalization();

            this.fullBodyFragment = fullBodyFragment.ToArray(out this.fullBodyFragmentLength); 

            this.state = BodyState.Signed; 
        } 

        void WriteInnerMessageWithId(XmlDictionaryWriter writer) 
        {
            WriteStartInnerMessageWithId(writer);
            this.InnerMessage.WriteBodyContents(writer);
            writer.WriteEndElement(); 
        }
 
        void WriteStartInnerMessageWithId(XmlDictionaryWriter writer) 
        {
            this.InnerMessage.WriteStartBody(writer); 
            if (this.bodyIdInserted)
            {
                this.securityHeader.StandardsManager.IdManager.WriteIdAttribute(writer, this.bodyId);
            } 
        }
 
        enum BodyState 
        {
            Created, 
            Signed,
            SignedThenEncrypted,
            EncryptedThenSigned,
            Encrypted, 
            Disposed,
        } 
 
        struct BodyContentHelper
        { 
            MemoryStream stream;
            XmlDictionaryWriter writer;

            public XmlDictionaryWriter CreateWriter() 
            {
                this.stream = new MemoryStream(); 
                this.writer = XmlDictionaryWriter.CreateTextWriter(stream); 
                return this.writer;
            } 

            public ArraySegment ExtractResult()
            {
                this.writer.Flush(); 
                return new ArraySegment(this.stream.GetBuffer(), 0, (int) this.stream.Length);
            } 
        } 

        sealed class MessagePrefixGenerator : IPrefixGenerator 
        {
            XmlWriter writer;

            public MessagePrefixGenerator(XmlWriter writer) 
            {
                this.writer = writer; 
            } 

            public string GetPrefix(string namespaceUri, int depth, bool isForAttribute) 
            {
                return this.writer.LookupPrefix(namespaceUri);
            }
        } 
    }
} 

// 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