2 // CryptoStreamTest.cs - NUnit Test Cases for CryptoStream
5 // Sebastien Pouliot <sebastien@ximian.com>
7 // (C) 2003 Motus Technologies Inc. (http://www.motus.com)
8 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 /* WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING *
32 * DO NOT USE ANY OF THE TEST CASE AS SAMPLES FOR YOUR OWN CODE. MANY
33 * CASES CONTAINS ERRORS AND AREN'T SECURE IN THEIR USE.
35 * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING */
37 using NUnit.Framework;
40 using System.Reflection;
41 using System.Runtime.InteropServices;
42 using System.Security.Cryptography;
45 namespace MonoTests.System.Security.Cryptography {
47 // much useful for debugging
48 public class DebugStream : MemoryStream {
52 public DebugStream () : base () {}
53 public DebugStream (byte[] buffer) : base (buffer) {}
54 public DebugStream (int capacity) : base (capacity) {}
56 public override bool CanRead {
57 get { return base.CanRead; }
60 public override bool CanSeek {
61 get { return base.CanSeek; }
64 public override bool CanWrite {
65 get { return base.CanWrite; }
68 public override int Capacity {
69 get { return base.Capacity; }
70 set { base.Capacity = value; }
73 public override long Length {
74 get { return base.Length; }
77 public override long Position {
78 get { return base.Position; }
79 set { base.Position = value; }
84 public override void Close ()
89 public override void Flush ()
94 public override byte[] GetBuffer ()
96 return base.GetBuffer ();
99 public override int Read ([In,Out] byte[] buffer, int offset, int count)
101 int len = base.Read (buffer, offset, count);
105 public override int ReadByte ()
107 return base.ReadByte ();
110 public override long Seek (long offset, SeekOrigin loc)
112 return base.Seek (offset, loc);
115 public override void SetLength (long value)
117 base.SetLength (value);
120 public override byte[] ToArray ()
122 return base.ToArray ();
125 public override void Write (byte[] buffer, int offset, int count)
127 base.Write (buffer, offset, count);
130 public override void WriteByte (byte value)
132 base.WriteByte (value);
135 public override void WriteTo (Stream stream)
137 base.WriteTo (stream);
142 public class CryptoStreamTest {
146 ICryptoTransform encryptor;
147 ICryptoTransform decryptor;
149 SymmetricAlgorithm aes;
154 if (readStream == null) {
155 readStream = new MemoryStream (new byte [0], false);
156 writeStream = new MemoryStream (new byte [0], true);
157 aes = SymmetricAlgorithm.Create ();
158 encryptor = aes.CreateEncryptor ();
159 decryptor = aes.CreateEncryptor ();
163 public void AssertEquals (string msg, byte[] array1, byte[] array2)
165 Assert.AreEqual (array1, array2, msg);
169 [ExpectedException (typeof (NullReferenceException))]
170 public void StreamNull ()
172 cs = new CryptoStream (null, encryptor, CryptoStreamMode.Read);
176 [ExpectedException (typeof (NullReferenceException))]
177 public void TransformNull ()
179 MemoryStream write = new MemoryStream (8);
180 byte[] data = {0, 1, 2, 3, 4, 5, 6, 7};
181 cs = new CryptoStream (write, null, CryptoStreamMode.Write);
182 cs.Write (data, 0, 8);
186 public void StreamReadModeRead ()
188 cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
189 Assert.IsTrue (cs.CanRead, "Read.CanRead");
190 Assert.IsFalse (cs.CanWrite, "Read.CanWrite");
191 Assert.IsFalse (cs.CanSeek, "Read.CanSeek");
195 [ExpectedException (typeof (ArgumentException))]
196 public void StreamReadModeWrite ()
198 cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Write);
202 [ExpectedException (typeof (ArgumentException))]
203 public void StreamWriteModeRead ()
205 // This needs a stream which can't be read from; memory stream won't do that.
206 string f = Path.GetTempFileName ();
207 FileStream fs = new FileStream (f, FileMode.OpenOrCreate, FileAccess.Write);
209 cs = new CryptoStream (fs, encryptor, CryptoStreamMode.Read);
217 public void StreamWriteModeWrite ()
219 cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
220 Assert.IsFalse (cs.CanRead, "Read.CanRead");
221 Assert.IsTrue (cs.CanWrite, "Read.CanWrite");
222 Assert.IsFalse (cs.CanSeek, "Read.CanSeek");
226 [ExpectedException (typeof (NotSupportedException))]
227 public void GetLength ()
229 DebugStream debug = new DebugStream ();
230 cs = new CryptoStream (debug, encryptor, CryptoStreamMode.Read);
235 [ExpectedException (typeof (NotSupportedException))]
236 public void GetPosition ()
238 DebugStream debug = new DebugStream ();
239 cs = new CryptoStream (debug, encryptor, CryptoStreamMode.Read);
240 long x = cs.Position;
244 [ExpectedException (typeof (NotSupportedException))]
245 public void SetPosition ()
247 DebugStream debug = new DebugStream ();
248 cs = new CryptoStream (debug, encryptor, CryptoStreamMode.Read);
253 [ExpectedException (typeof (NotSupportedException))]
256 DebugStream debug = new DebugStream ();
257 cs = new CryptoStream (debug, encryptor, CryptoStreamMode.Read);
258 cs.Seek (0, SeekOrigin.Begin);
262 [ExpectedException (typeof (NotSupportedException))]
263 public void SetLength ()
265 DebugStream debug = new DebugStream ();
266 cs = new CryptoStream (debug, encryptor, CryptoStreamMode.Read);
271 // LAMESPEC : [ExpectedException (typeof (NotSupportedException))]
272 public void FlushReadStream ()
274 cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
280 [ExpectedException (typeof (NotSupportedException))]
282 public void FlushFinalBlockReadStream ()
284 cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
285 cs.FlushFinalBlock ();
289 [ExpectedException (typeof (NotSupportedException))]
290 public void FlushFinalBlock_Dual ()
292 // do no corrupt writeStream in further tests
293 using (Stream s = new MemoryStream ()) {
294 byte[] data = {0, 1, 2, 3, 4, 5, 6, 7};
295 cs = new CryptoStream (s, encryptor, CryptoStreamMode.Write);
296 cs.Write (data, 0, data.Length);
297 cs.FlushFinalBlock ();
298 cs.FlushFinalBlock ();
303 // LAMESPEC or MS BUG [ExpectedException (typeof (ObjectDisposedException))]
305 [ExpectedException (typeof (NotSupportedException))]
307 [ExpectedException (typeof (ArgumentNullException))]
309 public void FlushFinalBlock_Disposed ()
311 // do no corrupt writeStream in further tests
312 using (Stream s = new MemoryStream ()) {
313 cs = new CryptoStream (s, encryptor, CryptoStreamMode.Write);
315 cs.FlushFinalBlock ();
320 // LAMESPEC or MS BUG [ExpectedException (typeof (ObjectDisposedException))]
322 [ExpectedException (typeof (ArgumentNullException))]
324 public void Read_Disposed ()
326 // do no corrupt readStream in further tests
327 using (Stream s = new MemoryStream ()) {
328 byte[] buffer = new byte [8];
329 cs = new CryptoStream (s, encryptor, CryptoStreamMode.Read);
331 Assert.AreEqual (0, cs.Read (buffer, 0, 8), "Read from disposed");
336 // MS BUG [ExpectedException (typeof (ObjectDisposedException))]
338 [Category ("NotWorking")]
339 [ExpectedException (typeof (IndexOutOfRangeException))]
341 [Category ("NotDotNet")] // Test cause System.ExecutionEngineException on MS runtime
342 [ExpectedException (typeof (ArgumentNullException))] // should fail like previous test case
344 public void Read_Disposed_Break ()
346 // do no corrupt readStream in further tests
347 using (Stream s = new MemoryStream ()) {
348 byte[] buffer = new byte [8];
349 cs = new CryptoStream (s, encryptor, CryptoStreamMode.Read);
350 int len = cs.Read (buffer, 0, 4);
351 Assert.AreEqual (4, len, "Read 4");
353 len = cs.Read (buffer, 3, 4);
358 [ExpectedException (typeof (NotSupportedException))]
359 public void Read_WriteStream ()
361 cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
362 byte[] buffer = new byte [8];
363 cs.Read (buffer, 0, 8);
367 [ExpectedException (typeof (NullReferenceException))]
368 public void Read_NullBuffer ()
370 cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
371 cs.Read (null, 0, 8);
375 public void Read_EmptyBuffer_ZeroCount ()
377 byte[] buffer = new byte [0];
378 cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
379 int len = cs.Read (buffer, 0, 0);
380 Assert.AreEqual (0, len, "Read 0");
384 [ExpectedException (typeof (ArgumentOutOfRangeException))]
385 public void Read_NegativeOffset ()
387 byte[] buffer = new byte [8];
388 cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
389 cs.Read (buffer, -1, 8);
393 public void Read_ZeroCount ()
395 byte[] buffer = new byte [8];
396 cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
397 int len = cs.Read (buffer, 0, 0);
398 Assert.AreEqual (0, len, "Read 0");
402 [ExpectedException (typeof (ArgumentOutOfRangeException))]
403 public void Read_NegativeCount ()
405 byte[] buffer = new byte [8];
406 cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
407 cs.Read (buffer, 0, -1);
411 [ExpectedException (typeof (ArgumentException))]
412 public void Read_OverflowCount ()
414 byte[] buffer = new byte [8];
415 cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
416 cs.Read (buffer, 0, Int32.MaxValue);
420 [ExpectedException (typeof (ArgumentException))]
421 public void Read_InvalidOffset ()
423 byte[] buffer = new byte [8];
424 cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
425 cs.Read (buffer, 5, 4);
429 [ExpectedException (typeof (ArgumentException))]
430 public void Read_OverflowOffset ()
432 byte[] buffer = new byte [8];
433 cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
434 cs.Read (buffer, Int32.MaxValue, 4);
438 // MS BUG [ExpectedException (typeof (ObjectDisposedException))]
440 [Category ("NotWorking")]
441 [ExpectedException (typeof (IndexOutOfRangeException))]
443 [Category ("NotDotNet")] // Test cause System.ExecutionEngineException on MS runtime
444 [ExpectedException (typeof (ArgumentNullException))] // to match exception throw by Read in a similar case
446 public void Write_Disposed ()
448 // do no corrupt writeStream in further tests
449 using (Stream s = new MemoryStream ()) {
450 byte[] buffer = new byte [8];
451 cs = new CryptoStream (s, encryptor, CryptoStreamMode.Write);
453 cs.Write (buffer, 0, 8);
458 [ExpectedException (typeof (NotSupportedException))]
459 public void Write_ReadStream ()
461 cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
462 byte[] buffer = new byte [8];
463 cs.Write (buffer, 0, 8);
467 [ExpectedException (typeof (NullReferenceException))]
468 public void Write_NullBuffer ()
470 cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
471 cs.Write (null, 0, 8);
475 public void Write_EmptyBuffer_ZeroCount ()
477 byte[] buffer = new byte [0];
478 cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
479 cs.Write (buffer, 0, 0);
483 [ExpectedException (typeof (ArgumentOutOfRangeException))]
484 public void Write_NegativeOffset ()
486 byte[] buffer = new byte [8];
487 cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
488 cs.Write (buffer, -1, 8);
492 [ExpectedException (typeof (ArgumentException))]
493 public void Write_OverflowOffset ()
495 byte[] buffer = new byte [8];
496 cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
497 cs.Write (buffer, Int32.MaxValue, 8);
501 public void Write_ZeroCount ()
503 byte[] buffer = new byte [8];
504 cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
505 cs.Write (buffer, 0, 0);
509 [ExpectedException (typeof (ArgumentOutOfRangeException))]
510 public void Write_NegativeCount ()
512 byte[] buffer = new byte [8];
513 cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
514 cs.Write (buffer, 0, -1);
518 [ExpectedException (typeof (ArgumentException))]
519 public void Write_InvalidOffset ()
521 DebugStream debug = new DebugStream ();
522 byte[] buffer = new byte [8];
523 cs = new CryptoStream (debug, encryptor, CryptoStreamMode.Write);
524 cs.Write (buffer, 5, 4);
528 [ExpectedException (typeof (ArgumentException))]
529 public void Write_OverflowCount ()
531 DebugStream debug = new DebugStream ();
532 byte[] buffer = new byte [8];
533 cs = new CryptoStream (debug, encryptor, CryptoStreamMode.Write);
534 cs.Write (buffer, 0, Int32.MaxValue);
538 public void FullRoundtripRead ()
541 using (DebugStream mem1 = new DebugStream ()) {
542 byte[] toEncrypt = Encoding.Unicode.GetBytes ("Please encode me!");
543 using (CryptoStream crypt = new CryptoStream (mem1, aes.CreateEncryptor (), CryptoStreamMode.Write)) {
544 crypt.Write (toEncrypt, 0, toEncrypt.Length);
545 crypt.FlushFinalBlock ();
547 encrypted = mem1.ToArray ();
550 using (DebugStream mem2 = new DebugStream (encrypted)) {
551 byte[] buffer = new byte [1024];
552 CryptoStream cr = new CryptoStream (mem2, aes.CreateDecryptor (), CryptoStreamMode.Read);
553 int len = cr.Read (buffer, 0, buffer.Length);
555 Assert.AreEqual (34, len, "Full Length Read");
556 Assert.AreEqual ("Please encode me!", Encoding.Unicode.GetString (buffer, 0, len), "Full Block Read");
560 // bugzilla 46143 (adapted from test case by Joerg Rosenkranz)
562 public void PartialRoundtripRead ()
565 using (DebugStream mem1 = new DebugStream ()) {
566 byte[] toEncrypt = Encoding.Unicode.GetBytes ("Please encode me!");
567 using (CryptoStream crypt = new CryptoStream (mem1, aes.CreateEncryptor (), CryptoStreamMode.Write)) {
568 crypt.Write (toEncrypt, 0, toEncrypt.Length);
569 crypt.FlushFinalBlock ();
571 encrypted = mem1.ToArray ();
574 using (DebugStream mem2 = new DebugStream (encrypted)) {
575 byte[] buffer = new byte [1024];
576 CryptoStream cr = new CryptoStream (mem2, aes.CreateDecryptor (), CryptoStreamMode.Read);
577 int len = cr.Read (buffer, 0, 20);
580 Assert.AreEqual (20, len, "Partial Length Read");
581 Assert.AreEqual ("Please enc", Encoding.Unicode.GetString (buffer, 0, len), "Partial Block Read");
585 // bugzilla: 40689 (adapted from test case by Henning Westerholt)
587 public void WriteOnBlockWithFinal ()
589 byte[] desKey = {0, 1, 2, 3, 4, 5, 6, 7};
590 byte[] desIV = {0, 1, 2, 3, 4, 5, 6, 7};
591 DES des = DES.Create ();
593 MemoryStream msin = new MemoryStream ();
594 CryptoStream enc = new CryptoStream (msin, des.CreateEncryptor (desKey, desIV), CryptoStreamMode.Write);
595 byte[] data = new byte [2200];
596 enc.Write (data, 0, 2200);
597 enc.FlushFinalBlock ();
599 Assert.AreEqual (2208, msin.Length, "Encryped Write Length"); // 2200 + padding
601 MemoryStream msout = new MemoryStream ();
604 byte[] tmp = new byte [1024];
606 long totallen = msin.Length;
608 CryptoStream dec = new CryptoStream (msout, des.CreateDecryptor (desKey, desIV), CryptoStreamMode.Write);
609 int len = msin.Read (tmp, 0, 1024);
611 dec.Write (tmp, 0, len);
613 len = msin.Read (tmp, 0, 1024);
615 Assert.AreEqual (2200, msout.Length, "Decryped Write Length");
622 Assert.AreEqual (2208, readlen, "Read Length"); // 2200 + padding
626 public void PreGeneratedStreams ()
628 byte[] desKey = {0, 1, 2, 3, 4, 5, 6, 7};
629 byte[] desIV = {0, 1, 2, 3, 4, 5, 6, 7};
630 DES des = DES.Create ();
632 for (int i=0; i < 9; i++) {
633 MemoryStream msin = new MemoryStream ();
634 CryptoStream enc = new CryptoStream (msin, des.CreateEncryptor (desKey, desIV), CryptoStreamMode.Write);
635 byte[] data = new byte [i];
636 enc.Write (data, 0, i);
637 enc.FlushFinalBlock ();
639 string msg = "PreGeneratedStream #" + i;
640 string result = BitConverter.ToString (msin.ToArray ());
643 Assert.AreEqual ("92-C9-DB-45-30-0B-93-2F", result, msg);
646 Assert.AreEqual ("08-CF-A1-37-BD-56-D0-65", result, msg);
649 Assert.AreEqual ("58-87-D4-9B-2C-27-97-0C", result, msg);
652 Assert.AreEqual ("07-35-90-94-68-7D-51-FB", result, msg);
655 Assert.AreEqual ("BF-00-98-C5-20-71-D0-DB", result, msg);
658 Assert.AreEqual ("1A-55-C8-6E-C1-9B-31-82", result, msg);
661 Assert.AreEqual ("2D-2B-76-41-61-0E-00-0C", result, msg);
664 Assert.AreEqual ("DC-FF-73-D2-7F-D7-48-5D", result, msg);
667 Assert.AreEqual ("E1-B2-46-E5-A7-C7-4C-BC-0E-40-4A-FC-08-92-B1-EB", result, msg);
673 private byte[] EmptyStream (PaddingMode mode)
675 SymmetricAlgorithm algo = Rijndael.Create ();
676 algo.Key = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };
677 algo.IV = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };
679 MemoryStream ms = new MemoryStream ();
680 CryptoStream cs = new CryptoStream (ms, algo.CreateEncryptor(), CryptoStreamMode.Write);
681 cs.Write (ms.GetBuffer (), 0, (int) ms.Length);
682 cs.FlushFinalBlock ();
684 return ms.ToArray ();
688 public void EmptyStreamWithPaddingNone ()
690 byte[] result = EmptyStream (PaddingMode.None);
691 Assert.AreEqual (0, result.Length, "Result Length");
695 public void EmptyStreamWithPaddingPKCS7 ()
697 byte[] expected = { 0x07, 0xFE, 0xEF, 0x74, 0xE1, 0xD5, 0x03, 0x6E, 0x90, 0x0E, 0xEE, 0x11, 0x8E, 0x94, 0x92, 0x93 };
698 byte[] result = EmptyStream (PaddingMode.PKCS7);
699 Assert.AreEqual (16, result.Length, "Result Length");
700 Assert.AreEqual (expected, result, "Result");
704 public void EmptyStreamWithPaddingZeros ()
706 byte[] result = EmptyStream (PaddingMode.Zeros);
707 Assert.AreEqual (0, result.Length, "Result Length");
710 // bugzilla: 49323 (adapted from test case by Carlos Guzmán Álvarez)
712 public void MultiblocksWithPartial ()
714 SymmetricAlgorithm tdes = new TripleDESCryptoServiceProvider ();
715 tdes.Key = new byte[] {161, 54, 179, 213, 89, 75, 130, 4, 186, 99, 158, 127, 19, 195, 175, 143, 79, 109, 25, 202, 237, 235, 62, 170};
716 tdes.IV = new byte[] {193, 227, 54, 132, 68, 172, 55, 91};
718 byte[] fragment = new byte[] {20, 0, 0, 12, 181, 134, 8, 230, 185, 75, 19, 129, 101, 142, 118, 190};
719 byte[] mac = new byte[] {42, 148, 229, 58, 185, 249, 154, 131, 157, 79, 176, 168, 143, 71, 0, 118, 5, 10, 95, 8};
721 // Encryption ( fragment + mac [+ padding + padding_length] )
722 MemoryStream ms = new MemoryStream ();
723 CryptoStream cs = new CryptoStream (ms, tdes.CreateEncryptor (), CryptoStreamMode.Write);
724 cs.Write (fragment, 0, fragment.Length);
725 cs.Write (mac, 0, mac.Length);
726 // Calculate padding_length
727 int fragmentLength = fragment.Length + mac.Length + 1;
728 int padding = (((fragmentLength / 8) * 8) + 8) - fragmentLength;
729 // Write padding length byte
730 cs.WriteByte ((byte)padding);
732 byte[] encrypted = ms.ToArray ();
733 byte[] expected = new byte[] { 0x9c, 0x99, 0x56, 0x8e, 0x75, 0x3e, 0x02, 0x95, 0x5b, 0x5c, 0x46, 0x8b, 0xcf, 0xf8, 0x27, 0x21, 0x53, 0x5f, 0x3d, 0xd8, 0x16, 0x95, 0x82, 0x3d, 0x88, 0x9b, 0x9a, 0x47, 0xda, 0x97, 0x90, 0x86, 0x50, 0x0e, 0x48, 0xee, 0xe7, 0x9b, 0x25, 0x41 };
734 Assert.AreEqual (expected, encrypted, "MultiblocksWithPartial");
737 // Adapted from Subba Rao Thirumoorthy email on mono-devel-list (december 2003)
738 private byte[] NonMultipleOfBlockSize_Encrypt (ICryptoTransform ct, byte[] data)
740 DebugStream stream = new DebugStream ();
741 CryptoStream CryptStream = new CryptoStream (stream, ct, CryptoStreamMode.Write);
745 byte[] Buffer = new byte [1024];
747 DebugStream fout = new DebugStream (data);
748 while (myLength < data.Length) {
749 len = fout.Read (Buffer, 0, 1023);
752 CryptStream.Write (Buffer, 0, len);
753 CryptStream.Flush ();
754 myLength = myLength + len;
756 CryptStream.FlushFinalBlock ();
757 // we must ensure that the result is correct
758 Assert.AreEqual (64, len, "Length(final)");
759 byte[] result = stream.ToArray ();
760 string end = BitConverter.ToString (result, 65520, 16);
761 Assert.AreEqual ("04-70-19-1D-28-C5-BD-9A-23-C6-60-E2-28-96-38-65", end, "End part");
768 private byte[] NonMultipleOfBlockSize_Decrypt (ICryptoTransform ct, byte[] data)
770 DebugStream stream = new DebugStream (data);
771 CryptoStream CryptStream = new CryptoStream (stream, ct, CryptoStreamMode.Read);
775 byte[] Buffer = new Byte [1024];
777 DebugStream fout = new DebugStream ();
778 // each returned block must be 1023 bytes long
779 // even if this isn't a multiple of the block size
780 while ((len = CryptStream.Read (Buffer, 0, 1023)) != 0) {
781 fout.Write (Buffer, 0, len);
783 myLength = myLength + len;
786 byte[] result = fout.ToArray ();
787 CryptStream.Close ();
793 public void NonMultipleOfBlockSize ()
795 byte[] key = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
796 byte[] iv = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
797 byte[] data = new byte [65536];
799 RijndaelManaged aes = new RijndaelManaged ();
800 ICryptoTransform encryptor = aes.CreateEncryptor (key, iv);
801 byte[] encdata = NonMultipleOfBlockSize_Encrypt (encryptor, data);
802 Assert.AreEqual ((data.Length + (aes.BlockSize >> 3)), encdata.Length, "Encrypted Data Length");
804 ICryptoTransform decryptor = aes.CreateDecryptor (key, iv);
805 byte[] decdata = NonMultipleOfBlockSize_Decrypt (decryptor, encdata);
806 Assert.AreEqual (data.Length, decdata.Length, "Decrypted Data Length");
810 while (b && (i < data.Length)) {
811 b = (data [i] == decdata [i]);
814 Assert.IsTrue (b, "NonMultipleOfBlockSize");
817 // bugzilla: 51322 - indirectly related but it explains why my first (unapplied) patch didn't work
819 public void DecryptPartial_TransformFinalBlock_required ()
821 byte[] key = {0, 1, 2, 3, 4, 5, 6, 7};
822 byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7};
823 DES des = DES.Create ();
825 byte[] data = Encoding.Unicode.GetBytes ("ximian"); // 12 bytes, 1.5 DES block size
826 DebugStream encrypted = new DebugStream ();
827 cs = new CryptoStream (encrypted, des.CreateEncryptor (key, iv), CryptoStreamMode.Write);
828 cs.Write (data, 0, data.Length);
831 data = encrypted.ToArray ();
832 DebugStream decrypted = new DebugStream (data);
833 cs = new CryptoStream (decrypted, des.CreateDecryptor (key, iv), CryptoStreamMode.Read);
834 int len = cs.Read (data, 0, data.Length);
836 Assert.AreEqual (12, len, "Length");
837 Assert.AreEqual ("ximian", Encoding.Unicode.GetString (data, 0, len), "Unicode DES Roundtrip");
841 [Category ("NotWorking")]
844 public void DecryptPartial_TransformFinalBlock_2Pass ()
846 byte[] key = {0, 1, 2, 3, 4, 5, 6, 7};
847 byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7};
848 DES des = DES.Create ();
850 byte[] data = Encoding.Unicode.GetBytes ("ximian"); // 12 bytes, 1.5 DES block size
851 DebugStream encrypted = new DebugStream ();
852 cs = new CryptoStream (encrypted, des.CreateEncryptor (key, iv), CryptoStreamMode.Write);
853 cs.Write (data, 0, data.Length);
856 data = encrypted.ToArray ();
857 DebugStream decrypted = new DebugStream (data);
858 cs = new CryptoStream (decrypted, des.CreateDecryptor (key, iv), CryptoStreamMode.Read);
859 int len = cs.Read (data, 0, 6);
860 Assert.AreEqual (6, len, "Length (1st pass)");
861 Assert.AreEqual ("xim", Encoding.Unicode.GetString (data, 0, len), "Partial DES Roundtrip");
862 len += cs.Read (data, 6, 8);
863 Assert.AreEqual (12, len, "Length (1st+2nd)");
864 Assert.AreEqual ("ximian", Encoding.Unicode.GetString (data, 0, len), "Full DES Roundtrip");
868 // based on http://www.c-sharpcorner.com/Code/2002/May/FileEncryption.asp
870 [Category ("NotWorking")]
873 public void WriteByteReadByte ()
875 DebugStream original = new DebugStream (Encoding.Unicode.GetBytes ("ximian"));
877 DebugStream encrypted = new DebugStream ();
878 byte[] key = {0, 1, 2, 3, 4, 5, 6, 7};
879 byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7};
880 DES des = DES.Create ();
881 cs = new CryptoStream (encrypted, des.CreateEncryptor (key, iv), CryptoStreamMode.Write);
884 while ((data = original.ReadByte ()) != -1)
885 cs.WriteByte((byte) data);
888 byte[] result = encrypted.ToArray ();
889 Assert.AreEqual ("18-EA-93-3F-20-86-D2-AA-78-02-D7-6F-E4-47-17-9C", BitConverter.ToString (result), "Encrypted");
891 encrypted = new DebugStream (result);
892 DebugStream decrypted = new DebugStream ();
893 cs = new CryptoStream (encrypted, des.CreateDecryptor (key, iv), CryptoStreamMode.Read);
895 while ((data = cs.ReadByte ()) != -1)
896 decrypted.WriteByte((byte) data);
900 Assert.AreEqual ("ximian", Encoding.Unicode.GetString (decrypted.ToArray ()), "W/R Byte Roundtrip");
903 // based http://www.4guysfromrolla.com/webtech/090501-1.shtml
905 public string EncryptData (ICryptoTransform des, string strData)
907 strData = String.Format("{0,5:00000}" + strData, strData.Length);
908 byte[] data = Encoding.ASCII.GetBytes (strData);
910 MemoryStream mStream = new MemoryStream (data);
911 CryptoStream cs = new CryptoStream (mStream, des, CryptoStreamMode.Read);
912 MemoryStream mOut = new MemoryStream ();
915 byte[] output = new byte [1024];
917 bytesRead = cs.Read (output, 0, 1024);
919 mOut.Write (output, 0, bytesRead);
921 while (bytesRead > 0);
923 return Convert.ToBase64String (mOut.ToArray ());
926 public string DecryptData (ICryptoTransform des, string strData)
928 MemoryStream mOut = new MemoryStream ();
929 byte[] data = Convert.FromBase64String (strData);
930 CryptoStream cs = new CryptoStream (mOut, des, CryptoStreamMode.Write);
931 cs.Write (data, 0, (int)data.Length);
932 cs.FlushFinalBlock ();
933 return Encoding.ASCII.GetString (mOut.ToArray ()).Substring (5);
937 public void EncryptOnRead ()
939 SHA1 sha = SHA1.Create ();
940 byte[] vector = sha.ComputeHash (Encoding.ASCII.GetBytes ("s3kr3t"));
941 byte[] key = new byte [8];
942 Buffer.BlockCopy (vector, 0, key, 0, key.Length);
943 byte[] iv = new byte [8];
944 Buffer.BlockCopy (vector, 8, iv, 0, iv.Length);
946 DES des = DES.Create ();
948 StringBuilder sb = new StringBuilder ();
950 string data = sb.ToString ();
951 string encdata = EncryptData (des.CreateEncryptor (key, iv), data);
952 string decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
953 Assert.AreEqual ("9YVfvrh5yj0=", encdata, "Encrypt-" + data);
954 Assert.AreEqual (data, decdata, "Decrypt-" + data);
957 data = sb.ToString ();
958 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
959 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
960 Assert.AreEqual ("qNe4d0UlkU8=", encdata, "Encrypt-" + data);
961 Assert.AreEqual (data, decdata, "Decrypt-" + data);
964 data = sb.ToString ();
965 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
966 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
967 Assert.AreEqual ("OcernYAQ1NAME/Gny+ZuaA==", encdata, "Encrypt-" + data);
968 Assert.AreEqual (data, decdata, "Decrypt-" + data);
971 data = sb.ToString ();
972 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
973 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
974 Assert.AreEqual ("H5UveR2lds1T+IWN4pks2Q==", encdata, "Encrypt-" + data);
975 Assert.AreEqual (data, decdata, "Decrypt-" + data);
978 data = sb.ToString ();
979 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
980 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
981 Assert.AreEqual ("dDQ3HAVtTbiRwwUqWANaeA==", encdata, "Encrypt-" + data);
982 Assert.AreEqual (data, decdata, "Decrypt-" + data);
985 data = sb.ToString ();
986 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
987 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
988 Assert.AreEqual ("At1r7dVDjJlQidf4QzCNkw==", encdata, "Encrypt-" + data);
989 Assert.AreEqual (data, decdata, "Decrypt-" + data);
992 data = sb.ToString ();
993 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
994 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
995 Assert.AreEqual ("DFDJWJGaNrFVBDXovsq1ew==", encdata, "Encrypt-" + data);
996 Assert.AreEqual (data, decdata, "Decrypt-" + data);
999 data = sb.ToString ();
1000 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1001 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1002 Assert.AreEqual ("gM040QGMPOBj3u1lEK4XHQ==", encdata, "Encrypt-" + data);
1003 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1006 data = sb.ToString ();
1007 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1008 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1009 Assert.AreEqual ("P5hRUhrxOWFX0ER/IjJL/Q==", encdata, "Encrypt-" + data);
1010 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1013 data = sb.ToString ();
1014 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1015 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1016 Assert.AreEqual ("uDIaQ1uXtWUIboGFLt306Q==", encdata, "Encrypt-" + data);
1017 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1020 data = sb.ToString ();
1021 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1022 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1023 Assert.AreEqual ("giJKTXfad5Z8hebhXtYZ4hmKX/EC8w6x", encdata, "Encrypt-" + data);
1024 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1027 data = sb.ToString ();
1028 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1029 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1030 Assert.AreEqual ("lBehBplIrjjrlIrMjYcNz1DOoXLHjZdn", encdata, "Encrypt-" + data);
1031 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1034 data = sb.ToString ();
1035 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1036 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1037 Assert.AreEqual ("2elWrUnjmsAOpo2s4voJyZXEJ/rtKB7P", encdata, "Encrypt-" + data);
1038 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1041 data = sb.ToString ();
1042 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1043 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1044 Assert.AreEqual ("GB3BaIZGf9K+T82j7T8Fri2rQ2/YUdSe", encdata, "Encrypt-" + data);
1045 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1048 data = sb.ToString ();
1049 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1050 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1051 Assert.AreEqual ("Gc+wkJL+CVjdJchgcIoi8dkH2BVpHJgB", encdata, "Encrypt-" + data);
1052 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1055 data = sb.ToString ();
1056 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1057 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1058 Assert.AreEqual ("loeuyII/PvWb91M4pFVkyaPxQoQVYpNb", encdata, "Encrypt-" + data);
1059 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1062 data = sb.ToString ();
1063 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1064 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1065 Assert.AreEqual ("PHXmi/sxNIgApXAfdm+Bf54/nCM//N8o", encdata, "Encrypt-" + data);
1066 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1069 data = sb.ToString ();
1070 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1071 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1072 Assert.AreEqual ("xpb+wj/8LmH2ScTg3OU4JOsE5Owj6flF", encdata, "Encrypt-" + data);
1073 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1076 data = sb.ToString ();
1077 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1078 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1079 Assert.AreEqual ("WJz4VfsZ2emzhYWoSf+PNBDpHooxEregqMWnzm4gcqU=", encdata, "Encrypt-" + data);
1080 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1083 data = sb.ToString ();
1084 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1085 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1086 Assert.AreEqual ("PaouZu1iOKbCMRJSu04y/kB+TcOk4yp8K2BOGDs1PPE=", encdata, "Encrypt-" + data);
1087 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1090 data = sb.ToString ();
1091 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1092 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1093 Assert.AreEqual ("qbTDs4dFy7eERdn5vV7JRPk2/m9smtwvZjA6+TmGlkI=", encdata, "Encrypt-" + data);
1094 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1097 data = sb.ToString ();
1098 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1099 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1100 Assert.AreEqual ("f2FsphcpM7Fu90S5V17ptly44lL4GvFCCaFdnnU4twk=", encdata, "Encrypt-" + data);
1101 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1104 data = sb.ToString ();
1105 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1106 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1107 Assert.AreEqual ("imD+ntHsUmp9ALJedzC1JmAJY0r2O4KkP8271+XuG4g=", encdata, "Encrypt-" + data);
1108 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1111 data = sb.ToString ();
1112 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1113 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1114 Assert.AreEqual ("80QLLUmHwx1fcEYGeFz1WXlS13kUy994sQLI6GhcjuM=", encdata, "Encrypt-" + data);
1115 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1118 data = sb.ToString ();
1119 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1120 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1121 Assert.AreEqual ("DtIIlj8BCOppmIgQ9AEdUj7pBB49S/9Q38kbWLjwiVs=", encdata, "Encrypt-" + data);
1122 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1125 data = sb.ToString ();
1126 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1127 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1128 Assert.AreEqual ("LNkprYaaUFtyan204OzX+a2pzOb/Pg5WXzXJ6WWB1rQ=", encdata, "Encrypt-" + data);
1129 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1132 data = sb.ToString ();
1133 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1134 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1135 Assert.AreEqual ("FRgx9m2lT2PxtYSIdRwc+SznJetNiRk1MEIZDl3D13pvo2yOtJ1MSQ==", encdata, "Encrypt-" + data);
1136 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1139 data = sb.ToString ();
1140 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1141 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1142 Assert.AreEqual ("V7JlnpJscrdIpX4z5S+/Q5WDjKzK4aB5TiqI3JZOYJ+KE1CWQNNeow==", encdata, "Encrypt-" + data);
1143 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1146 data = sb.ToString ();
1147 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1148 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1149 Assert.AreEqual ("wVwPv1c2KQynbwiOBCAhmQlReOQT52qFR34AX4dtjEeQ1oCQ1N1tHg==", encdata, "Encrypt-" + data);
1150 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1153 data = sb.ToString ();
1154 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1155 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1156 Assert.AreEqual ("Zi+G0yfmuFjSjP455pjVeKBDDWB4qvTb0K0h20UtflrYG6wcWqUzDw==", encdata, "Encrypt-" + data);
1157 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1160 data = sb.ToString ();
1161 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1162 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1163 Assert.AreEqual ("0hGoonZ8jrLhMNDKBuWrlvFnq15ZLvnyq+Ilq8r4aYUEDxttQMwi5w==", encdata, "Encrypt-" + data);
1164 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1167 // based on System.Security assembly XmlDsigBase64TransformTest
1170 public void FromBase64_Write ()
1172 string expected = "http://www.go-mono.com/";
1173 byte[] data = Encoding.UTF8.GetBytes (expected);
1174 string temp = Convert.ToBase64String (data, 0, data.Length);
1175 data = Encoding.UTF8.GetBytes (temp);
1177 DebugStream debug = new DebugStream ();
1178 ICryptoTransform base64 = new FromBase64Transform ();
1179 cs = new CryptoStream (debug, base64, CryptoStreamMode.Write);
1180 cs.Write (data, 0, data.Length);
1181 cs.FlushFinalBlock ();
1182 byte[] encoded = debug.ToArray ();
1184 string result = Encoding.UTF8.GetString (encoded);
1185 Assert.AreEqual (expected, result, "FromBase64_Write");
1189 public void FromBase64_Read ()
1191 byte[] original = Encoding.UTF8.GetBytes ("aHR0cDovL3d3dy5nby1tb25vLmNvbS8=");
1192 DebugStream debug = new DebugStream (original);
1194 ICryptoTransform base64 = new FromBase64Transform ();
1195 cs = new CryptoStream (debug, base64, CryptoStreamMode.Read);
1197 byte[] data = new byte [1024];
1198 int length = cs.Read (data, 0, data.Length);
1201 string result = Encoding.UTF8.GetString (data, 0, length);
1202 Assert.AreEqual ("http://www.go-mono.com/", result, "ToBase64_Read");
1206 public void ToBase64_Write ()
1208 byte[] data = Encoding.UTF8.GetBytes ("http://www.go-mono.com/");
1210 DebugStream debug = new DebugStream ();
1211 ICryptoTransform base64 = new ToBase64Transform ();
1212 cs = new CryptoStream (debug, base64, CryptoStreamMode.Write);
1213 cs.Write (data, 0, data.Length);
1214 cs.FlushFinalBlock ();
1215 byte[] encoded = debug.ToArray ();
1217 string result = Encoding.UTF8.GetString (encoded);
1218 Assert.AreEqual ("aHR0cDovL3d3dy5nby1tb25vLmNvbS8=", result, "ToBase64_Write");
1222 public void ToBase64_Read ()
1224 byte[] original = Encoding.UTF8.GetBytes ("http://www.go-mono.com/");
1225 DebugStream debug = new DebugStream (original);
1227 ICryptoTransform base64 = new ToBase64Transform ();
1228 cs = new CryptoStream (debug, base64, CryptoStreamMode.Read);
1230 byte[] data = new byte [1024];
1231 int length = cs.Read (data, 0, data.Length);
1234 string result = Encoding.UTF8.GetString (data, 0, length);
1235 Assert.AreEqual ("aHR0cDovL3d3dy5nby1tb25vLmNvbS8=", result, "ToBase64_Read");
1238 // Cascaded CryptoStream - like sample in book .NET Framework Security, chapter 30
1241 public void CascadedCryptoStream_Write ()
1243 DebugStream debug = new DebugStream ();
1245 // calculate both the hash (before encryption) and encrypt in one Write operation
1246 byte[] key = {0, 1, 2, 3, 4, 5, 6, 7};
1247 byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7};
1248 DES des = DES.Create ();
1249 CryptoStream cse = new CryptoStream (debug, des.CreateEncryptor (key, iv), CryptoStreamMode.Write);
1251 MD5 hash = MD5.Create ();
1252 CryptoStream csh = new CryptoStream (cse, hash, CryptoStreamMode.Write);
1254 byte[] data = Encoding.UTF8.GetBytes ("http://www.go-mono.com/");
1255 csh.Write (data, 0, data.Length);
1256 csh.FlushFinalBlock ();
1258 byte[] result = debug.ToArray ();
1259 Assert.AreEqual ("8C-24-76-74-09-79-2B-D3-47-C3-32-F5-F3-1A-5E-57-04-33-2E-B8-50-77-B2-A1", BitConverter.ToString (result), "Encrypted");
1260 byte[] digest = hash.Hash;
1261 Assert.AreEqual ("71-04-12-D1-95-01-CF-F9-8D-8F-F8-0D-F9-AA-11-7D", BitConverter.ToString (digest), "Hash");
1264 [Category ("NotWorking")]
1267 public void CascadedCryptoStream_Read ()
1269 byte[] encdata = new byte[] { 0x8C, 0x24, 0x76, 0x74, 0x09, 0x79, 0x2B, 0xD3, 0x47, 0xC3, 0x32, 0xF5, 0xF3, 0x1A, 0x5E, 0x57, 0x04, 0x33, 0x2E, 0xB8, 0x50, 0x77, 0xB2, 0xA1 };
1270 DebugStream debug = new DebugStream (encdata);
1272 // decrypt data and validate its hash in one Read operation
1273 byte[] key = {0, 1, 2, 3, 4, 5, 6, 7};
1274 byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7};
1275 DES des = DES.Create ();
1276 CryptoStream csd = new CryptoStream (debug, des.CreateDecryptor (key, iv), CryptoStreamMode.Read);
1278 MD5 hash = MD5.Create ();
1279 CryptoStream csh = new CryptoStream (csd, hash, CryptoStreamMode.Read);
1281 byte[] data = new byte [1024];
1282 int length = csh.Read (data, 0, data.Length);
1285 string result = Encoding.UTF8.GetString (data, 0, length);
1286 Assert.AreEqual ("http://www.go-mono.com/", result, "Decrypted");
1287 byte[] digest = hash.Hash;
1288 Assert.AreEqual ("71-04-12-D1-95-01-CF-F9-8D-8F-F8-0D-F9-AA-11-7D", BitConverter.ToString (digest), "Hash Validation");
1291 // bugzilla: 60573 - the number of block is not reduced for encryptors
1294 public void EncryptorWriteBlocks ()
1296 DebugStream debug = new DebugStream ();
1298 byte[] key = {0, 1, 2, 3, 4, 5, 6, 7};
1299 byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7};
1300 DES des = DES.Create ();
1301 CryptoStream cse = new CryptoStream (debug, des.CreateEncryptor (key, iv), CryptoStreamMode.Write);
1303 byte[] data = new byte [64];
1304 cse.Write (data, 0, 64);
1305 Assert.AreEqual (64, debug.Length, "Length");
1310 public void DecryptorWriteBlocks ()
1312 DebugStream debug = new DebugStream ();
1314 byte[] key = {0, 1, 2, 3, 4, 5, 6, 7};
1315 byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7};
1316 DES des = DES.Create ();
1317 CryptoStream csd = new CryptoStream (debug, des.CreateDecryptor (key, iv), CryptoStreamMode.Write);
1319 byte[] data = new byte [64] { 0xE1, 0xB2, 0x46, 0xE5, 0xA7, 0xC7, 0x4C, 0xBC, 0xD5, 0xF0, 0x8E, 0x25, 0x3B, 0xFA, 0x23, 0x80, 0x03, 0x16, 0x18, 0x17, 0xA3, 0x59, 0xBA, 0xAC, 0xFC, 0x47, 0x57, 0x2A, 0xF9, 0x44, 0x07, 0x84, 0x20, 0x74, 0x06, 0x38, 0xC2, 0xF3, 0xA1, 0xCE, 0x8C, 0x73, 0xB1, 0xE3, 0x75, 0x03, 0x66, 0x89, 0xF0, 0x4E, 0x98, 0x68, 0xB1, 0xBD, 0x85, 0x25, 0xFF, 0x4B, 0x11, 0x74, 0xEF, 0x14, 0xC8, 0xE9 };
1320 csd.Write (data, 0, 64);
1321 Assert.AreEqual (56, debug.Length, "Length");
1322 // last block is kept for later processing
1326 public void PaddingModeNone ()
1328 byte[] Key = new byte [16];
1329 byte[] IV = new byte [16];
1330 byte[] Buffer = new byte [64];
1332 Rijndael alg = Rijndael.Create ();
1333 alg.Mode = CipherMode.CBC;
1334 alg.Padding = PaddingMode.None;
1336 MemoryStream cms = new MemoryStream ();
1337 ICryptoTransform ct = alg.CreateDecryptor (Key, IV);
1338 CryptoStream cs = new CryptoStream (cms, ct, CryptoStreamMode.Write);
1339 cs.Write (Buffer, 0, 64);
1342 Assert.AreEqual (64, cms.ToArray ().Length, "Length");
1345 private void WriteByte (PaddingMode mode, bool padded)
1347 byte[] Key = new byte[16];
1348 byte[] IV = new byte[16];
1349 byte[] Buffer = new byte[64];
1351 Rijndael alg = Rijndael.Create ();
1352 alg.Mode = CipherMode.CBC;
1355 MemoryStream cms = new MemoryStream ();
1356 ICryptoTransform ct = alg.CreateEncryptor (Key, IV);
1357 CryptoStream cs = new CryptoStream (cms, ct, CryptoStreamMode.Write);
1358 for (int i = 0; i < Buffer.Length; i++)
1359 cs.WriteByte (Buffer[i]);
1362 byte[] result = cms.ToArray ();
1363 // if padded then add one block, if not then it's the original length
1364 int len = padded ? 80: 64;
1365 Assert.AreEqual (len, result.Length, mode.ToString () + ".Encrypted.Length");
1367 cms = new MemoryStream ();
1368 ct = alg.CreateDecryptor (Key, IV);
1369 cs = new CryptoStream (cms, ct, CryptoStreamMode.Write);
1370 for (int i = 0; i < result.Length; i++)
1371 cs.WriteByte (result[i]);
1374 byte[] plaintext = cms.ToArray ();
1375 Assert.AreEqual (64, plaintext.Length, mode.ToString () + ".Decrypted.Length");
1377 Assert.AreEqual (Buffer, plaintext, mode.ToString () + ".Date");
1381 public void WriteByte ()
1383 WriteByte (PaddingMode.None, false);
1384 WriteByte (PaddingMode.Zeros, false);
1385 WriteByte (PaddingMode.PKCS7, true); // related to bug #81597
1387 WriteByte (PaddingMode.ANSIX923, true);
1388 WriteByte (PaddingMode.ISO10126, true);
1393 public void ReadModeDispose_FinalBlock ()
1395 using (SHA1 sha1 = SHA1.Create()) {
1396 using (MemoryStream mem = new MemoryStream(new byte[] { 1, 2, 3 }, false))
1397 using (CryptoStream cs = new CryptoStream(mem, sha1, CryptoStreamMode.Read))
1400 byte b = sha1.Hash [0]; // This will throw if TransformFinalBlock not called in sha1
1401 GC.KeepAlive (b); // just the warning...
1406 public void CustomDisposeCalled ()
1408 using (MemoryStream mem = new MemoryStream(new byte[] { 1, 2, 3 }, false)) {
1410 using (cs = new MyCryptoStream (mem, SHA1.Create()))
1413 Assert.IsTrue (cs.DisposeCalled, "#1");
1418 public void ExplicitFlush ()
1420 // Tests that explicitly calling Flush does not call Flush in the underlying stream
1421 MyStream ms = new MyStream ();
1422 using (CryptoStream cs = new CryptoStream (ms, SHA1.Create (), CryptoStreamMode.Read)) {
1423 ms.FlushCounterEnabled = true;
1425 ms.FlushCounterEnabled = false;
1427 Assert.IsTrue (ms.FlushCounter == 0);
1431 public void ImplicitFlush ()
1433 // Tests that Dispose() calls Flush on the underlying stream
1434 MyStream ms = new MyStream ();
1435 ms.FlushCounterEnabled = true;
1436 using (CryptoStream cs = new CryptoStream (ms, SHA1.Create (), CryptoStreamMode.Read)) {
1438 Assert.IsTrue (ms.FlushCounter == 1);
1442 public void ImplicitFlushCascade ()
1444 // Tests that Dispose() calls FlushFinalBlock() on the underlying stream
1445 MyStream ms = new MyStream ();
1446 ms.FlushCounterEnabled = true;
1447 CryptoStream cs1 = new CryptoStream (ms, SHA1.Create (), CryptoStreamMode.Read);
1448 using (CryptoStream cs = new CryptoStream (cs1, SHA1.Create (), CryptoStreamMode.Read)) {
1450 Assert.IsTrue (ms.FlushCounter == 1);
1454 [ExpectedException (typeof (ArgumentException))]
1455 public void Ctor_InvalidEnumValue ()
1457 CryptoStream cs = new CryptoStream (Stream.Null, SHA1.Create (), (CryptoStreamMode) 0xff);
1461 public void OutputBlock_Smaller ()
1463 // The OutputBlockSize is smaller than the InputBlockSize
1464 using (CryptoStream cs = new CryptoStream(Stream.Null, new MyCryptAlgorithm(), CryptoStreamMode.Write)) {
1465 byte[] buffer = new byte[512 * 1024];
1466 cs.Write(buffer, 0, buffer.Length);
1470 class MyCryptoStream : CryptoStream {
1471 public bool DisposeCalled { get; private set;}
1473 public MyCryptoStream(Stream stream, ICryptoTransform transform)
1474 : base(stream, transform, CryptoStreamMode.Read)
1478 protected override void Dispose(bool disposing)
1480 base.Dispose(disposing);
1481 DisposeCalled = true;
1485 class ExpandTransform : ICryptoTransform {
1487 public bool CanReuseTransform {
1488 get { return true; }
1491 public bool CanTransformMultipleBlocks {
1495 public int InputBlockSize {
1499 public int OutputBlockSize {
1503 public ExpandTransform (bool canTranformMultipleBlocks, int outputBlockSize)
1505 this.CanTransformMultipleBlocks = canTranformMultipleBlocks;
1506 this.OutputBlockSize = outputBlockSize;
1509 public void Dispose ()
1513 public int TransformBlock (byte [] inputBuffer, int inputOffset, int inputCount, byte [] outputBuffer, int outputOffset)
1516 for (var i = 0; i < inputCount; i++, inputOffset++) {
1517 for (var j = 0; j < OutputBlockSize; j++, outputOffset++, ret++) {
1518 outputBuffer [outputOffset] = inputBuffer [inputOffset];
1524 public byte [] TransformFinalBlock (byte [] inputBuffer, int inputOffset, int inputCount)
1526 var outputBuffer = new byte [inputCount * OutputBlockSize];
1527 TransformBlock (inputBuffer, inputOffset, inputCount, outputBuffer, 0);
1528 return outputBuffer;
1532 static string[] expand_values = {
1533 "00-01-02-03-04-05-06-07",
1534 "00-00-01-01-02-02-03-03-04-04-05-05-06-06-07-07",
1535 "00-00-00-01-01-01-02-02-02-03-03-03-04-04-04-05-05-05-06-06-06-07-07-07",
1536 "00-00-00-00-01-01-01-01-02-02-02-02-03-03-03-03-04-04-04-04-05-05-05-05-06-06-06-06-07-07-07-07",
1537 "00-01-02-03-04-05-06-07",
1538 "00-00-01-01-02-02-03-03-04-04-05-05-06-06-07-07",
1539 "00-00-00-01-01-01-02-02-02-03-03-03-04-04-04-05-05-05-06-06-06-07-07-07",
1540 "00-00-00-00-01-01-01-01-02-02-02-02-03-03-03-03-04-04-04-04-05-05-05-05-06-06-06-06-07-07-07-07"
1544 public void Expand ()
1547 foreach (var transformMultiple in new [] { false, true }) {
1548 foreach (var outputBlockSize in new [] { 1, 2, 3, 4 }) {
1549 var expantedStream = new MemoryStream ();
1550 var inputData = new byte [] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };
1552 using (var stream = new CryptoStream (expantedStream, new ExpandTransform (transformMultiple, outputBlockSize), CryptoStreamMode.Write)) {
1553 stream.Write (inputData, 0, inputData.Length);
1555 expantedStream.Close ();
1557 string value = BitConverter.ToString (expantedStream.ToArray ());
1558 Assert.AreEqual (expand_values [n++], value);
1563 class CompressTransform : ICryptoTransform {
1564 public bool CanReuseTransform {
1565 get { return true; }
1568 public bool CanTransformMultipleBlocks {
1569 get { return true; }
1572 public int InputBlockSize {
1576 public int OutputBlockSize {
1580 public CompressTransform (int inputBlockSize)
1582 this.InputBlockSize = inputBlockSize;
1585 public void Dispose ()
1589 private int bufferedCount = 0;
1591 public int TransformBlock (byte [] inputBuffer, int inputOffset, int inputCount, byte [] outputBuffer, int outputOffset)
1594 for (var i = 0; i < inputCount; i++, inputOffset++) {
1595 if (++bufferedCount == InputBlockSize) {
1596 outputBuffer [outputOffset++] = inputBuffer [inputOffset];
1604 public byte [] TransformFinalBlock (byte [] inputBuffer, int inputOffset, int inputCount)
1606 var outputBuffer = new byte [inputCount * OutputBlockSize];
1607 var ret = TransformBlock (inputBuffer, inputOffset, inputCount, outputBuffer, 0);
1608 byte[] result = new byte [ret];
1609 Array.Copy (outputBuffer, result, ret);
1614 static string[] compress_values = {
1615 "00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F-10-11-12-13-14-15-16-17-18-19-1A-1B-1C-1D-1E-1F",
1616 "01-03-05-07-09-0B-0D-0F-11-13-15-17-19-1B-1D-1F",
1617 "02-05-08-0B-0E-11-14-17-1A-1D",
1618 "03-07-0B-0F-13-17-1B-1F",
1622 public void Compress ()
1625 foreach (var inputBlockSize in new [] { 1, 2, 3, 4 }) {
1626 var inputData = new byte [] {
1627 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1628 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
1629 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1630 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
1633 using (var stream = new CryptoStream (new MemoryStream (inputData), new CompressTransform (inputBlockSize), CryptoStreamMode.Read)) {
1634 var buffer = new byte [inputData.Length];
1635 var ret = stream.Read (buffer, 0, buffer.Length);
1636 string value = BitConverter.ToString (buffer, 0, ret);
1637 Assert.AreEqual (compress_values [n++], value);
1642 class MyCryptAlgorithm : ICryptoTransform {
1643 public bool CanReuseTransform { get { return true; } }
1644 public bool CanTransformMultipleBlocks { get { return false; } }
1645 public int InputBlockSize { get { return 128 * 1024; } }
1646 public int OutputBlockSize { get { return 64 * 1024; } }
1648 public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
1650 return this.OutputBlockSize;
1653 public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount)
1655 return new byte[this.OutputBlockSize];
1658 public void Dispose() {}
1661 class MyStream : Stream {
1662 public bool FlushCounterEnabled;
1663 public int FlushCounter;
1665 public override bool CanRead
1672 public override bool CanSeek
1679 public override bool CanWrite
1686 public override long Length
1693 public override long Position
1702 public override void Flush ()
1704 if (FlushCounterEnabled)
1708 public override int Read (byte[] buffer, int offset, int count)
1713 public override int ReadByte ()
1718 public override long Seek (long offset, SeekOrigin origin)
1723 public override void SetLength (long value)
1727 public override void Write (byte[] buffer, int offset, int count)
1731 public override void WriteByte (byte value)