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