123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
- #pragma warning disable
- using System;
- using System.Diagnostics;
- using System.IO;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
- namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.IO
- {
- public class CipherStream
- : Stream
- {
- internal Stream stream;
- internal IBufferedCipher inCipher, outCipher;
- private byte[] mInBuf;
- private int mInPos;
- private bool inStreamEnded;
- public CipherStream(
- Stream stream,
- IBufferedCipher readCipher,
- IBufferedCipher writeCipher)
- {
- this.stream = stream;
- if (readCipher != null)
- {
- this.inCipher = readCipher;
- mInBuf = null;
- }
- if (writeCipher != null)
- {
- this.outCipher = writeCipher;
- }
- }
- public IBufferedCipher ReadCipher
- {
- get { return inCipher; }
- }
- public IBufferedCipher WriteCipher
- {
- get { return outCipher; }
- }
- public override int ReadByte()
- {
- if (inCipher == null)
- return stream.ReadByte();
- if (mInBuf == null || mInPos >= mInBuf.Length)
- {
- if (!FillInBuf())
- return -1;
- }
- return mInBuf[mInPos++];
- }
- public override int Read(
- byte[] buffer,
- int offset,
- int count)
- {
- if (inCipher == null)
- return stream.Read(buffer, offset, count);
- int num = 0;
- while (num < count)
- {
- if (mInBuf == null || mInPos >= mInBuf.Length)
- {
- if (!FillInBuf())
- break;
- }
- int numToCopy = System.Math.Min(count - num, mInBuf.Length - mInPos);
- Array.Copy(mInBuf, mInPos, buffer, offset + num, numToCopy);
- mInPos += numToCopy;
- num += numToCopy;
- }
- return num;
- }
- private bool FillInBuf()
- {
- if (inStreamEnded)
- return false;
- mInPos = 0;
- do
- {
- mInBuf = ReadAndProcessBlock();
- }
- while (!inStreamEnded && mInBuf == null);
- return mInBuf != null;
- }
- private byte[] ReadAndProcessBlock()
- {
- int blockSize = inCipher.GetBlockSize();
- int readSize = (blockSize == 0) ? 256 : blockSize;
- byte[] block = new byte[readSize];
- int numRead = 0;
- do
- {
- int count = stream.Read(block, numRead, block.Length - numRead);
- if (count < 1)
- {
- inStreamEnded = true;
- break;
- }
- numRead += count;
- }
- while (numRead < block.Length);
- Debug.Assert(inStreamEnded || numRead == block.Length);
- byte[] bytes = inStreamEnded
- ? inCipher.DoFinal(block, 0, numRead)
- : inCipher.ProcessBytes(block);
- if (bytes != null && bytes.Length == 0)
- {
- bytes = null;
- }
- return bytes;
- }
- public override void Write(
- byte[] buffer,
- int offset,
- int count)
- {
- Debug.Assert(buffer != null);
- Debug.Assert(0 <= offset && offset <= buffer.Length);
- Debug.Assert(count >= 0);
- int end = offset + count;
- Debug.Assert(0 <= end && end <= buffer.Length);
- if (outCipher == null)
- {
- stream.Write(buffer, offset, count);
- return;
- }
- byte[] data = outCipher.ProcessBytes(buffer, offset, count);
- if (data != null)
- {
- stream.Write(data, 0, data.Length);
- }
- }
- public override void WriteByte(
- byte b)
- {
- if (outCipher == null)
- {
- stream.WriteByte(b);
- return;
- }
- byte[] data = outCipher.ProcessByte(b);
- if (data != null)
- {
- stream.Write(data, 0, data.Length);
- }
- }
- public override bool CanRead
- {
- get { return stream.CanRead && (inCipher != null); }
- }
- public override bool CanWrite
- {
- get { return stream.CanWrite && (outCipher != null); }
- }
- public override bool CanSeek
- {
- get { return false; }
- }
- public sealed override long Length
- {
- get { throw new NotSupportedException(); }
- }
- public sealed override long Position
- {
- get { throw new NotSupportedException(); }
- set { throw new NotSupportedException(); }
- }
- #if PORTABLE || NETFX_CORE
- protected override void Dispose(bool disposing)
- {
- if (disposing)
- {
- if (outCipher != null)
- {
- byte[] data = outCipher.DoFinal();
- stream.Write(data, 0, data.Length);
- stream.Flush();
- }
- BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.Dispose(stream);
- }
- base.Dispose(disposing);
- }
- #else
- public override void Close()
- {
- if (outCipher != null)
- {
- byte[] data = outCipher.DoFinal();
- stream.Write(data, 0, data.Length);
- stream.Flush();
- }
- BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.Dispose(stream);
- base.Close();
- }
- #endif
- public override void Flush()
- {
- // Note: outCipher.DoFinal is only called during Close()
- stream.Flush();
- }
- public sealed override long Seek(
- long offset,
- SeekOrigin origin)
- {
- throw new NotSupportedException();
- }
- public sealed override void SetLength(
- long length)
- {
- throw new NotSupportedException();
- }
- }
- }
- #pragma warning restore
- #endif
|