Usage and flow

I am calling a method in the Soap extension that decrypts and validates the Soap chant. I have classes:

I have a class that decodes and validates a signed Soap message that feeds a stream back to the Soap extension class:

The DecryptAndVerifySingXml and GetGuid method use the stream from the soap extension class.

public class CryptUtility
{
    public virtual Stream DecryptAndVerifySingXml(Stream inputStream)
    {
        XmlDocument doc = new XmlDocument();

        using (XmlTextReader reader = new XmlTextReader(inputStream))
        {
            doc.Load(reader);
        }


        using (MemoryStream retStream = new MemoryStream())
        {
            retStream.Position = 0;
            doc.Save(retStream);
        }

        //.....crypt and verify sing

        if (signedXml.CheckSignature(Key) == false)
        {
            throw new SecurityException("error");
        }

        else
        {
            using (MemoryStream retStream = new MemoryStream())
            {
                doc.Save(retStream);
                return retStream;
            }
        }
    }

    //get value from Soap header
    public string GetGuid(MemoryStream inputStream)
    {
        inputStream.Position = 0;

        string soapBodyString = Encoding.UTF8.GetString(inputStream.ToArray());

        XmlDocument doc = new XmlDocument();
        doc.LoadXml(soapBodyString);

        if (doc.GetElementsByTagName("Ticket").Item(0).InnerText == "")
        {
            throw new SecurityException("Neplatny uzivatel");
        }
        else
        {
            return doc.GetElementsByTagName("Ticket").Item(0).InnerText;
        }

    }
}

      

I am using the CryptUtility class in the Soap extension class:

public class SoapMsg : SoapExtension
    {

        private CryptUtility cryptUtil = null;
        string GUID;

        //...
        public override void Initialize(object initializer)
        {
            SoapMsgAttribute attribute =
              initializer as SoapMsgAttribute;
            soapElement = attribute.SoapElementArray;

            //create instance
            cryptUtil = new CryptUtility();
        }

        //copy stream method
        private void CopyStream(Stream from, Stream to)
        {
            TextReader reader = new StreamReader(from);
            TextWriter writer = new StreamWriter(to);
            writer.Write(reader.ReadToEnd());
            writer.Flush(); 
        }

        private void DecryptMessage()
        {
            using (MemoryStream copyOldStream = new MemoryStream())
            {
                CopyStream(oldStream, copyOldStream);

                copyOldStream.Position = 0;
                using (Stream retStream = cryptUtil.DecryptAndVerifySingXml(copyOldStream)
                {
                    retStream.Position = 0; //  < == in this place is bug   !!! line 183.
                    newStream.Position = 0;
                    CopyStream(retStream, newStream);
                    newStream.Position = 0;
                }
            }
        }


         public override void ProcessMessage(SoapMessage message)
        {
            switch (message.Stage)
            {
                case SoapMessageStage.BeforeSerialize:
                    break;
                case SoapMessageStage.AfterSerialize:
                    {
                    }
                    break;
                case SoapMessageStage.BeforeDeserialize:
                    {
                        using (MemoryStream tempStream = new MemoryStream())
                        {
                            CopyStream(oldStream, tempStream);

                            tempStream.Position = 0;

                            GUID = cryptUtil.GetGuid(tempStream);

                            oldStream.Position = 0;

                            // call method, in which is bug
                            DecryptMessage();
                    }
                    break;
                case SoapMessageStage.AfterDeserialize:
                    break;
                default:
                    throw new ArgumentException("error");
            }
        }


    }
 }

      

In ProcessMessage, in BeforeDeserialize, I call the DecryptMessage () method which has an error. On the client side soap extension with this error:

System.Web.Services.Protocols.SoapException: The server was unable to process the request. ---> System.ObjectDisposedException: Unable to access a closed stream. at System.IO .__ Error.StreamIsClosed ()

Error in line: retStream.Position = 0; // <== there is an error in this place !!! line 183. in the DecryptMessage () method.

I used Google at first, but I couldn't find a solution for this error. Can anyone help me?

+2


source to share


2 answers


The problem is that you are deleting the stream, which you then return, so the caller will not be able to use it.

Get rid of operators using

for returned streams. You also don't use a stream in the first block, and you can get rid of the "else". Here's the complete method DecryptVerifySignXml

with these changes:

public virtual Stream DecryptAndVerifySignXml(Stream inputStream)
{
    XmlDocument doc = new XmlDocument();

    using (XmlTextReader reader = new XmlTextReader(inputStream))
    {
        doc.Load(reader);
    }

    //.....crypt and verify sing

    if (!signedXml.CheckSignature(Key))
    {
        throw new SecurityException("error");
    }

    MemoryStream retStream = new MemoryStream();
    doc.Save(retStream);
    retStream.Position = 0; // Rewind so it ready to use
    return retStream;
}

      



(I'm not sure if the name of the method is particularly correct, I must say that this method does no decryption, and it doesn't sign anything - it just loads some XML and validates the existing signature. What's by by ...)

However, your method is CopyStream

broken, it assumes that the content is UTF-8 encoded text. This may be true in some cases, but not all. Instead, you should use something like this:

static void CopyStream(Stream input, Stream output)
{
    byte[] buffer = new byte[8192];
    int bytesRead;
    while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0)
    {
        output.Write(buffer, 0, bytesRead);
    }
}

      

+4


source


Remove using

from your ad retStream

; so change this

using (MemoryStream retStream = new MemoryStream())

      



with this

MemoryStream retStream = new MemoryStream();

      

+2


source







All Articles