示例#1
0
        /// <devdoc>
        ///    <para>
        ///       Performs encryption of an array of buffers,
        ///         proceeds buffer by buffer, if the individual
        ///         buffer size exceeds a SSL limit of 64K,
        ///         the buffers are then split into smaller ones.
        ///       Returns a new array of encrypted buffers.
        ///    </para>
        /// </devdoc>
        private BufferOffsetSize [] EncryptBuffers(BufferOffsetSize[] buffers)
        {
            // do we need lock this write as well?
            ArrayList encryptedBufferList = new ArrayList(buffers.Length);

            for (int i = 0; i < buffers.Length; i++)
            {
                SecureChannel chkSecureChannel = SecureChannel;
                if (chkSecureChannel == null)
                {
                    InnerException = new IOException(SR.GetString(SR.net_io_writefailure));
                    throw InnerException;
                }

                int offset    = buffers[i].Offset;
                int totalLeft = buffers[i].Size;
                do
                {
                    byte [] tempOutput = null;
                    int     size       = Math.Min(totalLeft, chkSecureChannel.MaxDataSize);

                    totalLeft -= size;

                    int errorCode = chkSecureChannel.Encrypt(buffers[i].Buffer, offset, size, ref tempOutput);

                    if (errorCode != (int)SecurityStatus.OK)
                    {
                        ProtocolToken message = new ProtocolToken(null, errorCode);
                        InnerException = message.GetException();
                        throw InnerException;
                    }

                    encryptedBufferList.Add(new BufferOffsetSize(tempOutput, false));

                    offset += size;
                } while (totalLeft > 0);
            }
            return((BufferOffsetSize [])encryptedBufferList.ToArray(typeof(BufferOffsetSize)));
        }
示例#2
0
        private IAsyncResult InnerWrite(bool async, byte[] buffer, int offset, int size, AsyncCallback asyncCallback, object asyncState)
        {
            // after shutdown/Close throw an exception
            if (m_ShutDown > 0)
            {
                throw new ObjectDisposedException(this.GetType().FullName);
            }
            // on earlier error throw an exception
            if (InnerException != null)
            {
                throw InnerException;
            }
            //
            // parameter validation
            //
            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }
            if (offset < 0 || offset > buffer.Length)
            {
                throw new ArgumentOutOfRangeException("offset");
            }
            if (size < 0 || size > buffer.Length - offset)
            {
                throw new ArgumentOutOfRangeException("size");
            }


            //
            // Lock the Write: this is inefficent, but we need to prevent
            //  writing data while the Stream is doing a handshake with the server.
            //  writing other data during the handshake would cause the server to
            //  fail and close the connection.
            //

            lock (this) {
                //
                // encrypt the data
                //

                byte[] ciphertext = null;

                GlobalLog.Print("Encrypt[" + Encoding.ASCII.GetString(buffer, 0, Math.Min(buffer.Length, 512)) + "]");

                SecureChannel chkSecureChannel = SecureChannel;
                if (chkSecureChannel == null)
                {
                    InnerException = new IOException(SR.GetString(SR.net_io_writefailure));
                    throw InnerException;
                }

                if (size > chkSecureChannel.MaxDataSize)
                {
                    BufferOffsetSize [] buffers = new BufferOffsetSize[1];
                    buffers[0] = new BufferOffsetSize(buffer, offset, size, false);
                    if (async)
                    {
                        return(BeginMultipleWrite(buffers, asyncCallback, asyncState));
                    }
                    else
                    {
                        MultipleWrite(buffers);
                        return(null);
                    }
                }

                int errorCode = chkSecureChannel.Encrypt(buffer, offset, size, ref ciphertext);

                if (errorCode != (int)SecurityStatus.OK)
                {
                    ProtocolToken message = new ProtocolToken(null, errorCode);
                    InnerException = message.GetException();
                    throw InnerException;
                }

                try {
                    if (async)
                    {
                        IAsyncResult asyncResult =
                            base.BeginWrite(
                                ciphertext,
                                0,
                                ciphertext.Length,
                                asyncCallback,
                                asyncState);

                        return(asyncResult);
                    }
                    else
                    {
                        base.Write(ciphertext, 0, ciphertext.Length);
                        return(null);
                    }
                }
                catch (Exception exception) {
                    //
                    // some sort of error occured Writing to the Trasport,
                    // set the Exception as InnerException and throw
                    //
                    InnerException = new IOException(SR.GetString(SR.net_io_writefailure), exception);
                    throw InnerException;
                }
            }
        }