CryptoStream.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. //
  2. // System.Security.Cryptography CryptoStream.cs
  3. //
  4. // Authors:
  5. // Thomas Neidhart ([email protected])
  6. // Sebastien Pouliot ([email protected])
  7. //
  8. // Portions (C) 2002 Motus Technologies Inc. (http://www.motus.com)
  9. //
  10. using System;
  11. using System.IO;
  12. namespace System.Security.Cryptography {
  13. public class CryptoStream : Stream {
  14. private Stream _stream;
  15. private ICryptoTransform _transform;
  16. private CryptoStreamMode _mode;
  17. private byte[] work;
  18. private int workPos;
  19. private bool disposed;
  20. public CryptoStream (Stream stream, ICryptoTransform transform, CryptoStreamMode mode)
  21. {
  22. _stream = stream;
  23. _transform = transform;
  24. _mode = mode;
  25. disposed = false;
  26. if (mode == CryptoStreamMode.Read)
  27. work = new byte [transform.InputBlockSize];
  28. else if (mode == CryptoStreamMode.Write)
  29. work = new byte [transform.OutputBlockSize];
  30. workPos = 0;
  31. }
  32. ~CryptoStream ()
  33. {
  34. Dispose (false);
  35. }
  36. public override bool CanRead {
  37. get { return (_mode == CryptoStreamMode.Read); }
  38. }
  39. public override bool CanSeek {
  40. get { return false; }
  41. }
  42. public override bool CanWrite {
  43. get { return (_mode == CryptoStreamMode.Write); }
  44. }
  45. public override long Length {
  46. get {
  47. throw new NotSupportedException ("Length property not supported by CryptoStream");
  48. }
  49. }
  50. public override long Position {
  51. get {
  52. throw new NotSupportedException ("Position property not supported by CryptoStream");
  53. }
  54. set {
  55. throw new NotSupportedException ("Position property not supported by CryptoStream");
  56. }
  57. }
  58. public void Clear ()
  59. {
  60. Dispose (true);
  61. }
  62. public override void Close ()
  63. {
  64. if (_mode != CryptoStreamMode.Write)
  65. throw new NotSupportedException ();
  66. byte[] finalBuffer = _transform.TransformFinalBlock (work, 0, workPos);
  67. if (_stream != null) {
  68. _stream.Write (finalBuffer, 0, finalBuffer.Length);
  69. _stream.Close ();
  70. }
  71. }
  72. public override int Read (byte[] buffer, int offset, int count)
  73. {
  74. if (_mode != CryptoStreamMode.Read)
  75. throw new NotSupportedException ();
  76. if ((offset < 0) || (count < 0))
  77. throw new ArgumentOutOfRangeException ();
  78. if (offset + count > buffer.Length)
  79. throw new ArgumentException ();
  80. // reached end of stream ?
  81. if (_stream.Position == _stream.Length)
  82. return 0;
  83. int result = 0;
  84. int bufferPos = offset;
  85. while (count > 0) {
  86. int len = Math.Min (work.Length - workPos, count);
  87. _stream.Read (work, workPos, len);
  88. workPos += len;
  89. count -= len;
  90. if (_stream.Position == _stream.Length) {
  91. byte[] input = _transform.TransformFinalBlock (work, 0, work.Length);
  92. Array.Copy (input, 0, buffer, bufferPos, input.Length);
  93. result += input.Length;
  94. break;
  95. } else if (workPos == work.Length) {
  96. workPos = 0;
  97. result += _transform.TransformBlock (work, 0, work.Length, buffer, bufferPos);
  98. }
  99. bufferPos += len;
  100. }
  101. return result;
  102. }
  103. public override void Write (byte[] buffer, int offset, int count)
  104. {
  105. if (_mode != CryptoStreamMode.Write)
  106. throw new NotSupportedException ();
  107. if ((offset < 0) || (count < 0))
  108. throw new ArgumentOutOfRangeException ();
  109. if (offset + count > buffer.Length)
  110. throw new ArgumentException ();
  111. int bufferPos = offset;
  112. while (count > 0) {
  113. int len = Math.Min (work.Length - workPos, count);
  114. Array.Copy (buffer, bufferPos, work, workPos, len);
  115. bufferPos += len;
  116. workPos += len;
  117. count -= len;
  118. if (workPos == work.Length) {
  119. workPos = 0;
  120. byte[] output = new byte[_transform.OutputBlockSize];
  121. _transform.TransformBlock (work, 0, work.Length, output, 0);
  122. _stream.Write (output, 0, output.Length);
  123. }
  124. }
  125. }
  126. public override void Flush ()
  127. {
  128. if (_mode != CryptoStreamMode.Write)
  129. throw new NotSupportedException ("cannot flush a non-writeable CryptoStream");
  130. if (_stream != null)
  131. _stream.Flush ();
  132. }
  133. public void FlushFinalBlock ()
  134. {
  135. if (_mode != CryptoStreamMode.Write)
  136. throw new NotSupportedException ("cannot flush a non-writeable CryptoStream");
  137. if (_stream != null) {
  138. _stream.Flush ();
  139. Close ();
  140. }
  141. }
  142. public override long Seek (long offset, SeekOrigin origin)
  143. {
  144. throw new NotSupportedException ("cannot Seek a CryptoStream");
  145. }
  146. // LAMESPEC: Exception NotSupportedException not documented
  147. public override void SetLength (long value)
  148. {
  149. throw new NotSupportedException ("cannot SetLength a CryptoStream");
  150. }
  151. protected virtual void Dispose (bool disposing)
  152. {
  153. if (!disposed) {
  154. if (_stream != null)
  155. _stream.Close ();
  156. }
  157. }
  158. } // CryptoStream
  159. } // System.Security.Cryptography