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;
148 SymmetricAlgorithm aes;
153 if (readStream == null) {
154 readStream = new MemoryStream (new byte [0], false);
155 writeStream = new MemoryStream (new byte [0], true);
156 aes = SymmetricAlgorithm.Create ();
157 encryptor = aes.CreateEncryptor ();
161 public void AssertEquals (string msg, byte[] array1, byte[] array2)
163 Assert.AreEqual (array1, array2, msg);
167 [ExpectedException (typeof (NullReferenceException))]
168 public void StreamNull ()
170 cs = new CryptoStream (null, encryptor, CryptoStreamMode.Read);
174 [ExpectedException (typeof (NullReferenceException))]
175 public void TransformNull ()
177 MemoryStream write = new MemoryStream (8);
178 byte[] data = {0, 1, 2, 3, 4, 5, 6, 7};
179 cs = new CryptoStream (write, null, CryptoStreamMode.Write);
180 cs.Write (data, 0, 8);
184 public void StreamReadModeRead ()
186 cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
187 Assert.IsTrue (cs.CanRead, "Read.CanRead");
188 Assert.IsFalse (cs.CanWrite, "Read.CanWrite");
189 Assert.IsFalse (cs.CanSeek, "Read.CanSeek");
193 [ExpectedException (typeof (ArgumentException))]
194 public void StreamReadModeWrite ()
196 cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Write);
200 [ExpectedException (typeof (ArgumentException))]
201 public void StreamWriteModeRead ()
203 // This needs a stream which can't be read from; memory stream won't do that.
204 string f = Path.GetTempFileName ();
205 FileStream fs = new FileStream (f, FileMode.OpenOrCreate, FileAccess.Write);
207 cs = new CryptoStream (fs, encryptor, CryptoStreamMode.Read);
215 public void StreamWriteModeWrite ()
217 cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
218 Assert.IsFalse (cs.CanRead, "Read.CanRead");
219 Assert.IsTrue (cs.CanWrite, "Read.CanWrite");
220 Assert.IsFalse (cs.CanSeek, "Read.CanSeek");
224 [ExpectedException (typeof (NotSupportedException))]
225 public void GetLength ()
227 DebugStream debug = new DebugStream ();
228 cs = new CryptoStream (debug, encryptor, CryptoStreamMode.Read);
233 [ExpectedException (typeof (NotSupportedException))]
234 public void GetPosition ()
236 DebugStream debug = new DebugStream ();
237 cs = new CryptoStream (debug, encryptor, CryptoStreamMode.Read);
238 long x = cs.Position;
242 [ExpectedException (typeof (NotSupportedException))]
243 public void SetPosition ()
245 DebugStream debug = new DebugStream ();
246 cs = new CryptoStream (debug, encryptor, CryptoStreamMode.Read);
251 [ExpectedException (typeof (NotSupportedException))]
254 DebugStream debug = new DebugStream ();
255 cs = new CryptoStream (debug, encryptor, CryptoStreamMode.Read);
256 cs.Seek (0, SeekOrigin.Begin);
260 [ExpectedException (typeof (NotSupportedException))]
261 public void SetLength ()
263 DebugStream debug = new DebugStream ();
264 cs = new CryptoStream (debug, encryptor, CryptoStreamMode.Read);
269 // LAMESPEC : [ExpectedException (typeof (NotSupportedException))]
270 public void FlushReadStream ()
272 cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
278 [ExpectedException (typeof (NotSupportedException))]
280 public void FlushFinalBlockReadStream ()
282 cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
283 cs.FlushFinalBlock ();
287 [ExpectedException (typeof (NotSupportedException))]
288 public void FlushFinalBlock_Dual ()
290 // do no corrupt writeStream in further tests
291 using (Stream s = new MemoryStream ()) {
292 byte[] data = {0, 1, 2, 3, 4, 5, 6, 7};
293 cs = new CryptoStream (s, encryptor, CryptoStreamMode.Write);
294 cs.Write (data, 0, data.Length);
295 cs.FlushFinalBlock ();
296 cs.FlushFinalBlock ();
301 // LAMESPEC or MS BUG [ExpectedException (typeof (ObjectDisposedException))]
302 [ExpectedException (typeof (NotSupportedException))]
303 public void FlushFinalBlock_Disposed ()
305 // do no corrupt writeStream in further tests
306 using (Stream s = new MemoryStream ()) {
307 cs = new CryptoStream (s, encryptor, CryptoStreamMode.Write);
309 cs.FlushFinalBlock ();
314 // LAMESPEC or MS BUG [ExpectedException (typeof (ObjectDisposedException))]
316 [ExpectedException (typeof (ArgumentNullException))]
318 public void Read_Disposed ()
320 // do no corrupt readStream in further tests
321 using (Stream s = new MemoryStream ()) {
322 byte[] buffer = new byte [8];
323 cs = new CryptoStream (s, encryptor, CryptoStreamMode.Read);
325 Assert.AreEqual (0, cs.Read (buffer, 0, 8), "Read from disposed");
331 // MS BUG [ExpectedException (typeof (ObjectDisposedException))]
332 [Category ("NotWorking")]
333 [ExpectedException (typeof (IndexOutOfRangeException))]
334 public void Read_Disposed_Break ()
336 // do no corrupt readStream in further tests
337 using (Stream s = new MemoryStream ()) {
338 byte[] buffer = new byte [8];
339 cs = new CryptoStream (s, encryptor, CryptoStreamMode.Read);
340 int len = cs.Read (buffer, 0, 4);
341 Assert.AreEqual (4, len, "Read 4");
343 len = cs.Read (buffer, 3, 4);
349 [ExpectedException (typeof (NotSupportedException))]
350 public void Read_WriteStream ()
352 cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
353 byte[] buffer = new byte [8];
354 cs.Read (buffer, 0, 8);
358 [ExpectedException (typeof (NullReferenceException))]
359 public void Read_NullBuffer ()
361 cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
362 cs.Read (null, 0, 8);
366 public void Read_EmptyBuffer_ZeroCount ()
368 byte[] buffer = new byte [0];
369 cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
370 int len = cs.Read (buffer, 0, 0);
371 Assert.AreEqual (0, len, "Read 0");
375 [ExpectedException (typeof (ArgumentOutOfRangeException))]
376 public void Read_NegativeOffset ()
378 byte[] buffer = new byte [8];
379 cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
380 cs.Read (buffer, -1, 8);
384 public void Read_ZeroCount ()
386 byte[] buffer = new byte [8];
387 cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
388 int len = cs.Read (buffer, 0, 0);
389 Assert.AreEqual (0, len, "Read 0");
393 [ExpectedException (typeof (ArgumentOutOfRangeException))]
394 public void Read_NegativeCount ()
396 byte[] buffer = new byte [8];
397 cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
398 cs.Read (buffer, 0, -1);
402 [ExpectedException (typeof (ArgumentException))]
403 public void Read_OverflowCount ()
405 byte[] buffer = new byte [8];
406 cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
407 cs.Read (buffer, 0, Int32.MaxValue);
411 [ExpectedException (typeof (ArgumentException))]
412 public void Read_InvalidOffset ()
414 byte[] buffer = new byte [8];
415 cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
416 cs.Read (buffer, 5, 4);
420 [ExpectedException (typeof (ArgumentException))]
421 public void Read_OverflowOffset ()
423 byte[] buffer = new byte [8];
424 cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
425 cs.Read (buffer, Int32.MaxValue, 4);
430 // MS BUG [ExpectedException (typeof (ObjectDisposedException))]
431 [Category ("NotWorking")]
432 [ExpectedException (typeof (IndexOutOfRangeException))]
433 public void Write_Disposed ()
435 // do no corrupt writeStream in further tests
436 using (Stream s = new MemoryStream ()) {
437 byte[] buffer = new byte [8];
438 cs = new CryptoStream (s, encryptor, CryptoStreamMode.Write);
440 cs.Write (buffer, 0, 8);
446 [ExpectedException (typeof (NotSupportedException))]
447 public void Write_ReadStream ()
449 cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
450 byte[] buffer = new byte [8];
451 cs.Write (buffer, 0, 8);
455 [ExpectedException (typeof (NullReferenceException))]
456 public void Write_NullBuffer ()
458 cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
459 cs.Write (null, 0, 8);
463 public void Write_EmptyBuffer_ZeroCount ()
465 byte[] buffer = new byte [0];
466 cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
467 cs.Write (buffer, 0, 0);
471 [ExpectedException (typeof (ArgumentOutOfRangeException))]
472 public void Write_NegativeOffset ()
474 byte[] buffer = new byte [8];
475 cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
476 cs.Write (buffer, -1, 8);
480 [ExpectedException (typeof (ArgumentException))]
481 public void Write_OverflowOffset ()
483 byte[] buffer = new byte [8];
484 cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
485 cs.Write (buffer, Int32.MaxValue, 8);
489 public void Write_ZeroCount ()
491 byte[] buffer = new byte [8];
492 cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
493 cs.Write (buffer, 0, 0);
497 [ExpectedException (typeof (ArgumentOutOfRangeException))]
498 public void Write_NegativeCount ()
500 byte[] buffer = new byte [8];
501 cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
502 cs.Write (buffer, 0, -1);
506 [ExpectedException (typeof (ArgumentException))]
507 public void Write_InvalidOffset ()
509 DebugStream debug = new DebugStream ();
510 byte[] buffer = new byte [8];
511 cs = new CryptoStream (debug, encryptor, CryptoStreamMode.Write);
512 cs.Write (buffer, 5, 4);
516 [ExpectedException (typeof (ArgumentException))]
517 public void Write_OverflowCount ()
519 DebugStream debug = new DebugStream ();
520 byte[] buffer = new byte [8];
521 cs = new CryptoStream (debug, encryptor, CryptoStreamMode.Write);
522 cs.Write (buffer, 0, Int32.MaxValue);
526 public void FullRoundtripRead ()
529 using (DebugStream mem1 = new DebugStream ()) {
530 byte[] toEncrypt = Encoding.Unicode.GetBytes ("Please encode me!");
531 using (CryptoStream crypt = new CryptoStream (mem1, aes.CreateEncryptor (), CryptoStreamMode.Write)) {
532 crypt.Write (toEncrypt, 0, toEncrypt.Length);
533 crypt.FlushFinalBlock ();
535 encrypted = mem1.ToArray ();
538 using (DebugStream mem2 = new DebugStream (encrypted)) {
539 byte[] buffer = new byte [1024];
540 CryptoStream cr = new CryptoStream (mem2, aes.CreateDecryptor (), CryptoStreamMode.Read);
541 int len = cr.Read (buffer, 0, buffer.Length);
543 Assert.AreEqual (34, len, "Full Length Read");
544 Assert.AreEqual ("Please encode me!", Encoding.Unicode.GetString (buffer, 0, len), "Full Block Read");
548 // bugzilla 46143 (adapted from test case by Joerg Rosenkranz)
550 public void PartialRoundtripRead ()
553 using (DebugStream mem1 = new DebugStream ()) {
554 byte[] toEncrypt = Encoding.Unicode.GetBytes ("Please encode me!");
555 using (CryptoStream crypt = new CryptoStream (mem1, aes.CreateEncryptor (), CryptoStreamMode.Write)) {
556 crypt.Write (toEncrypt, 0, toEncrypt.Length);
557 crypt.FlushFinalBlock ();
559 encrypted = mem1.ToArray ();
562 using (DebugStream mem2 = new DebugStream (encrypted)) {
563 byte[] buffer = new byte [1024];
564 CryptoStream cr = new CryptoStream (mem2, aes.CreateDecryptor (), CryptoStreamMode.Read);
565 int len = cr.Read (buffer, 0, 20);
568 Assert.AreEqual (20, len, "Partial Length Read");
569 Assert.AreEqual ("Please enc", Encoding.Unicode.GetString (buffer, 0, len), "Partial Block Read");
573 // bugzilla: 40689 (adapted from test case by Henning Westerholt)
575 public void WriteOnBlockWithFinal ()
577 byte[] desKey = {0, 1, 2, 3, 4, 5, 6, 7};
578 byte[] desIV = {0, 1, 2, 3, 4, 5, 6, 7};
579 DES des = DES.Create ();
581 MemoryStream msin = new MemoryStream ();
582 CryptoStream enc = new CryptoStream (msin, des.CreateEncryptor (desKey, desIV), CryptoStreamMode.Write);
583 byte[] data = new byte [2200];
584 enc.Write (data, 0, 2200);
585 enc.FlushFinalBlock ();
587 Assert.AreEqual (2208, msin.Length, "Encryped Write Length"); // 2200 + padding
589 MemoryStream msout = new MemoryStream ();
592 byte[] tmp = new byte [1024];
594 long totallen = msin.Length;
596 CryptoStream dec = new CryptoStream (msout, des.CreateDecryptor (desKey, desIV), CryptoStreamMode.Write);
597 int len = msin.Read (tmp, 0, 1024);
599 dec.Write (tmp, 0, len);
601 len = msin.Read (tmp, 0, 1024);
603 Assert.AreEqual (2200, msout.Length, "Decryped Write Length");
610 Assert.AreEqual (2208, readlen, "Read Length"); // 2200 + padding
614 public void PreGeneratedStreams ()
616 byte[] desKey = {0, 1, 2, 3, 4, 5, 6, 7};
617 byte[] desIV = {0, 1, 2, 3, 4, 5, 6, 7};
618 DES des = DES.Create ();
620 for (int i=0; i < 9; i++) {
621 MemoryStream msin = new MemoryStream ();
622 CryptoStream enc = new CryptoStream (msin, des.CreateEncryptor (desKey, desIV), CryptoStreamMode.Write);
623 byte[] data = new byte [i];
624 enc.Write (data, 0, i);
625 enc.FlushFinalBlock ();
627 string msg = "PreGeneratedStream #" + i;
628 string result = BitConverter.ToString (msin.ToArray ());
631 Assert.AreEqual ("92-C9-DB-45-30-0B-93-2F", result, msg);
634 Assert.AreEqual ("08-CF-A1-37-BD-56-D0-65", result, msg);
637 Assert.AreEqual ("58-87-D4-9B-2C-27-97-0C", result, msg);
640 Assert.AreEqual ("07-35-90-94-68-7D-51-FB", result, msg);
643 Assert.AreEqual ("BF-00-98-C5-20-71-D0-DB", result, msg);
646 Assert.AreEqual ("1A-55-C8-6E-C1-9B-31-82", result, msg);
649 Assert.AreEqual ("2D-2B-76-41-61-0E-00-0C", result, msg);
652 Assert.AreEqual ("DC-FF-73-D2-7F-D7-48-5D", result, msg);
655 Assert.AreEqual ("E1-B2-46-E5-A7-C7-4C-BC-0E-40-4A-FC-08-92-B1-EB", result, msg);
661 private byte[] EmptyStream (PaddingMode mode)
663 SymmetricAlgorithm algo = Rijndael.Create ();
664 algo.Key = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };
665 algo.IV = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };
667 MemoryStream ms = new MemoryStream ();
668 CryptoStream cs = new CryptoStream (ms, algo.CreateEncryptor(), CryptoStreamMode.Write);
669 cs.Write (ms.GetBuffer (), 0, (int) ms.Length);
670 cs.FlushFinalBlock ();
672 return ms.ToArray ();
676 public void EmptyStreamWithPaddingNone ()
678 byte[] result = EmptyStream (PaddingMode.None);
679 Assert.AreEqual (0, result.Length, "Result Length");
683 public void EmptyStreamWithPaddingPKCS7 ()
685 byte[] expected = { 0x07, 0xFE, 0xEF, 0x74, 0xE1, 0xD5, 0x03, 0x6E, 0x90, 0x0E, 0xEE, 0x11, 0x8E, 0x94, 0x92, 0x93 };
686 byte[] result = EmptyStream (PaddingMode.PKCS7);
687 Assert.AreEqual (16, result.Length, "Result Length");
688 Assert.AreEqual (expected, result, "Result");
692 public void EmptyStreamWithPaddingZeros ()
694 byte[] result = EmptyStream (PaddingMode.Zeros);
695 Assert.AreEqual (0, result.Length, "Result Length");
698 // bugzilla: 49323 (adapted from test case by Carlos Guzmán Álvarez)
700 public void MultiblocksWithPartial ()
702 SymmetricAlgorithm tdes = new TripleDESCryptoServiceProvider ();
703 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};
704 tdes.IV = new byte[] {193, 227, 54, 132, 68, 172, 55, 91};
706 byte[] fragment = new byte[] {20, 0, 0, 12, 181, 134, 8, 230, 185, 75, 19, 129, 101, 142, 118, 190};
707 byte[] mac = new byte[] {42, 148, 229, 58, 185, 249, 154, 131, 157, 79, 176, 168, 143, 71, 0, 118, 5, 10, 95, 8};
709 // Encryption ( fragment + mac [+ padding + padding_length] )
710 MemoryStream ms = new MemoryStream ();
711 CryptoStream cs = new CryptoStream (ms, tdes.CreateEncryptor (), CryptoStreamMode.Write);
712 cs.Write (fragment, 0, fragment.Length);
713 cs.Write (mac, 0, mac.Length);
714 // Calculate padding_length
715 int fragmentLength = fragment.Length + mac.Length + 1;
716 int padding = (((fragmentLength / 8) * 8) + 8) - fragmentLength;
717 // Write padding length byte
718 cs.WriteByte ((byte)padding);
720 byte[] encrypted = ms.ToArray ();
721 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 };
722 Assert.AreEqual (expected, encrypted, "MultiblocksWithPartial");
725 // Adapted from Subba Rao Thirumoorthy email on mono-devel-list (december 2003)
726 private byte[] NonMultipleOfBlockSize_Encrypt (ICryptoTransform ct, byte[] data)
728 DebugStream stream = new DebugStream ();
729 CryptoStream CryptStream = new CryptoStream (stream, ct, CryptoStreamMode.Write);
733 byte[] Buffer = new byte [1024];
735 DebugStream fout = new DebugStream (data);
736 while (myLength < data.Length) {
737 len = fout.Read (Buffer, 0, 1023);
740 CryptStream.Write (Buffer, 0, len);
741 CryptStream.Flush ();
742 myLength = myLength + len;
744 CryptStream.FlushFinalBlock ();
745 // we must ensure that the result is correct
746 Assert.AreEqual (64, len, "Length(final)");
747 byte[] result = stream.ToArray ();
748 string end = BitConverter.ToString (result, 65520, 16);
749 Assert.AreEqual ("04-70-19-1D-28-C5-BD-9A-23-C6-60-E2-28-96-38-65", end, "End part");
756 private byte[] NonMultipleOfBlockSize_Decrypt (ICryptoTransform ct, byte[] data)
758 DebugStream stream = new DebugStream (data);
759 CryptoStream CryptStream = new CryptoStream (stream, ct, CryptoStreamMode.Read);
763 byte[] Buffer = new Byte [1024];
765 DebugStream fout = new DebugStream ();
766 // each returned block must be 1023 bytes long
767 // even if this isn't a multiple of the block size
768 while ((len = CryptStream.Read (Buffer, 0, 1023)) != 0) {
769 fout.Write (Buffer, 0, len);
771 myLength = myLength + len;
774 byte[] result = fout.ToArray ();
775 CryptStream.Close ();
781 public void NonMultipleOfBlockSize ()
783 byte[] key = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
784 byte[] iv = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
785 byte[] data = new byte [65536];
787 RijndaelManaged aes = new RijndaelManaged ();
788 ICryptoTransform encryptor = aes.CreateEncryptor (key, iv);
789 byte[] encdata = NonMultipleOfBlockSize_Encrypt (encryptor, data);
790 Assert.AreEqual ((data.Length + (aes.BlockSize >> 3)), encdata.Length, "Encrypted Data Length");
792 ICryptoTransform decryptor = aes.CreateDecryptor (key, iv);
793 byte[] decdata = NonMultipleOfBlockSize_Decrypt (decryptor, encdata);
794 Assert.AreEqual (data.Length, decdata.Length, "Decrypted Data Length");
798 while (b && (i < data.Length)) {
799 b = (data [i] == decdata [i]);
802 Assert.IsTrue (b, "NonMultipleOfBlockSize");
805 // bugzilla: 51322 - indirectly related but it explains why my first (unapplied) patch didn't work
807 public void DecryptPartial_TransformFinalBlock_required ()
809 byte[] key = {0, 1, 2, 3, 4, 5, 6, 7};
810 byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7};
811 DES des = DES.Create ();
813 byte[] data = Encoding.Unicode.GetBytes ("ximian"); // 12 bytes, 1.5 DES block size
814 DebugStream encrypted = new DebugStream ();
815 cs = new CryptoStream (encrypted, des.CreateEncryptor (key, iv), CryptoStreamMode.Write);
816 cs.Write (data, 0, data.Length);
819 data = encrypted.ToArray ();
820 DebugStream decrypted = new DebugStream (data);
821 cs = new CryptoStream (decrypted, des.CreateDecryptor (key, iv), CryptoStreamMode.Read);
822 int len = cs.Read (data, 0, data.Length);
824 Assert.AreEqual (12, len, "Length");
825 Assert.AreEqual ("ximian", Encoding.Unicode.GetString (data, 0, len), "Unicode DES Roundtrip");
828 [Category ("NotWorking")]
830 public void DecryptPartial_TransformFinalBlock_2Pass ()
832 byte[] key = {0, 1, 2, 3, 4, 5, 6, 7};
833 byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7};
834 DES des = DES.Create ();
836 byte[] data = Encoding.Unicode.GetBytes ("ximian"); // 12 bytes, 1.5 DES block size
837 DebugStream encrypted = new DebugStream ();
838 cs = new CryptoStream (encrypted, des.CreateEncryptor (key, iv), CryptoStreamMode.Write);
839 cs.Write (data, 0, data.Length);
842 data = encrypted.ToArray ();
843 DebugStream decrypted = new DebugStream (data);
844 cs = new CryptoStream (decrypted, des.CreateDecryptor (key, iv), CryptoStreamMode.Read);
845 int len = cs.Read (data, 0, 6);
846 Assert.AreEqual (6, len, "Length (1st pass)");
847 Assert.AreEqual ("xim", Encoding.Unicode.GetString (data, 0, len), "Partial DES Roundtrip");
848 len += cs.Read (data, 6, 8);
849 Assert.AreEqual (12, len, "Length (1st+2nd)");
850 Assert.AreEqual ("ximian", Encoding.Unicode.GetString (data, 0, len), "Full DES Roundtrip");
854 // based on http://www.c-sharpcorner.com/Code/2002/May/FileEncryption.asp
855 [Category ("NotWorking")]
857 public void WriteByteReadByte ()
859 DebugStream original = new DebugStream (Encoding.Unicode.GetBytes ("ximian"));
861 DebugStream encrypted = new DebugStream ();
862 byte[] key = {0, 1, 2, 3, 4, 5, 6, 7};
863 byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7};
864 DES des = DES.Create ();
865 cs = new CryptoStream (encrypted, des.CreateEncryptor (key, iv), CryptoStreamMode.Write);
868 while ((data = original.ReadByte ()) != -1)
869 cs.WriteByte((byte) data);
872 byte[] result = encrypted.ToArray ();
873 Assert.AreEqual ("18-EA-93-3F-20-86-D2-AA-78-02-D7-6F-E4-47-17-9C", BitConverter.ToString (result), "Encrypted");
875 encrypted = new DebugStream (result);
876 DebugStream decrypted = new DebugStream ();
877 cs = new CryptoStream (encrypted, des.CreateDecryptor (key, iv), CryptoStreamMode.Read);
879 while ((data = cs.ReadByte ()) != -1)
880 decrypted.WriteByte((byte) data);
884 Assert.AreEqual ("ximian", Encoding.Unicode.GetString (decrypted.ToArray ()), "W/R Byte Roundtrip");
887 // based http://www.4guysfromrolla.com/webtech/090501-1.shtml
889 public string EncryptData (ICryptoTransform des, string strData)
891 strData = String.Format("{0,5:00000}" + strData, strData.Length);
892 byte[] data = Encoding.ASCII.GetBytes (strData);
894 MemoryStream mStream = new MemoryStream (data);
895 CryptoStream cs = new CryptoStream (mStream, des, CryptoStreamMode.Read);
896 MemoryStream mOut = new MemoryStream ();
899 byte[] output = new byte [1024];
901 bytesRead = cs.Read (output, 0, 1024);
903 mOut.Write (output, 0, bytesRead);
905 while (bytesRead > 0);
907 return Convert.ToBase64String (mOut.ToArray ());
910 public string DecryptData (ICryptoTransform des, string strData)
912 MemoryStream mOut = new MemoryStream ();
913 byte[] data = Convert.FromBase64String (strData);
914 CryptoStream cs = new CryptoStream (mOut, des, CryptoStreamMode.Write);
915 cs.Write (data, 0, (int)data.Length);
916 cs.FlushFinalBlock ();
917 return Encoding.ASCII.GetString (mOut.ToArray ()).Substring (5);
921 public void EncryptOnRead ()
923 SHA1 sha = SHA1.Create ();
924 byte[] vector = sha.ComputeHash (Encoding.ASCII.GetBytes ("s3kr3t"));
925 byte[] key = new byte [8];
926 Buffer.BlockCopy (vector, 0, key, 0, key.Length);
927 byte[] iv = new byte [8];
928 Buffer.BlockCopy (vector, 8, iv, 0, iv.Length);
930 DES des = DES.Create ();
932 StringBuilder sb = new StringBuilder ();
934 string data = sb.ToString ();
935 string encdata = EncryptData (des.CreateEncryptor (key, iv), data);
936 string decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
937 Assert.AreEqual ("9YVfvrh5yj0=", encdata, "Encrypt-" + data);
938 Assert.AreEqual (data, decdata, "Decrypt-" + data);
941 data = sb.ToString ();
942 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
943 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
944 Assert.AreEqual ("qNe4d0UlkU8=", encdata, "Encrypt-" + data);
945 Assert.AreEqual (data, decdata, "Decrypt-" + data);
948 data = sb.ToString ();
949 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
950 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
951 Assert.AreEqual ("OcernYAQ1NAME/Gny+ZuaA==", encdata, "Encrypt-" + data);
952 Assert.AreEqual (data, decdata, "Decrypt-" + data);
955 data = sb.ToString ();
956 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
957 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
958 Assert.AreEqual ("H5UveR2lds1T+IWN4pks2Q==", encdata, "Encrypt-" + data);
959 Assert.AreEqual (data, decdata, "Decrypt-" + data);
962 data = sb.ToString ();
963 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
964 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
965 Assert.AreEqual ("dDQ3HAVtTbiRwwUqWANaeA==", encdata, "Encrypt-" + data);
966 Assert.AreEqual (data, decdata, "Decrypt-" + data);
969 data = sb.ToString ();
970 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
971 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
972 Assert.AreEqual ("At1r7dVDjJlQidf4QzCNkw==", encdata, "Encrypt-" + data);
973 Assert.AreEqual (data, decdata, "Decrypt-" + data);
976 data = sb.ToString ();
977 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
978 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
979 Assert.AreEqual ("DFDJWJGaNrFVBDXovsq1ew==", encdata, "Encrypt-" + data);
980 Assert.AreEqual (data, decdata, "Decrypt-" + data);
983 data = sb.ToString ();
984 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
985 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
986 Assert.AreEqual ("gM040QGMPOBj3u1lEK4XHQ==", encdata, "Encrypt-" + data);
987 Assert.AreEqual (data, decdata, "Decrypt-" + data);
990 data = sb.ToString ();
991 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
992 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
993 Assert.AreEqual ("P5hRUhrxOWFX0ER/IjJL/Q==", encdata, "Encrypt-" + data);
994 Assert.AreEqual (data, decdata, "Decrypt-" + data);
997 data = sb.ToString ();
998 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
999 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1000 Assert.AreEqual ("uDIaQ1uXtWUIboGFLt306Q==", encdata, "Encrypt-" + data);
1001 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1004 data = sb.ToString ();
1005 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1006 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1007 Assert.AreEqual ("giJKTXfad5Z8hebhXtYZ4hmKX/EC8w6x", encdata, "Encrypt-" + data);
1008 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1011 data = sb.ToString ();
1012 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1013 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1014 Assert.AreEqual ("lBehBplIrjjrlIrMjYcNz1DOoXLHjZdn", encdata, "Encrypt-" + data);
1015 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1018 data = sb.ToString ();
1019 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1020 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1021 Assert.AreEqual ("2elWrUnjmsAOpo2s4voJyZXEJ/rtKB7P", encdata, "Encrypt-" + data);
1022 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1025 data = sb.ToString ();
1026 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1027 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1028 Assert.AreEqual ("GB3BaIZGf9K+T82j7T8Fri2rQ2/YUdSe", encdata, "Encrypt-" + data);
1029 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1032 data = sb.ToString ();
1033 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1034 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1035 Assert.AreEqual ("Gc+wkJL+CVjdJchgcIoi8dkH2BVpHJgB", encdata, "Encrypt-" + data);
1036 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1039 data = sb.ToString ();
1040 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1041 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1042 Assert.AreEqual ("loeuyII/PvWb91M4pFVkyaPxQoQVYpNb", encdata, "Encrypt-" + data);
1043 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1046 data = sb.ToString ();
1047 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1048 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1049 Assert.AreEqual ("PHXmi/sxNIgApXAfdm+Bf54/nCM//N8o", encdata, "Encrypt-" + data);
1050 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1053 data = sb.ToString ();
1054 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1055 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1056 Assert.AreEqual ("xpb+wj/8LmH2ScTg3OU4JOsE5Owj6flF", encdata, "Encrypt-" + data);
1057 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1060 data = sb.ToString ();
1061 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1062 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1063 Assert.AreEqual ("WJz4VfsZ2emzhYWoSf+PNBDpHooxEregqMWnzm4gcqU=", encdata, "Encrypt-" + data);
1064 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1067 data = sb.ToString ();
1068 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1069 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1070 Assert.AreEqual ("PaouZu1iOKbCMRJSu04y/kB+TcOk4yp8K2BOGDs1PPE=", encdata, "Encrypt-" + data);
1071 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1074 data = sb.ToString ();
1075 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1076 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1077 Assert.AreEqual ("qbTDs4dFy7eERdn5vV7JRPk2/m9smtwvZjA6+TmGlkI=", encdata, "Encrypt-" + data);
1078 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1081 data = sb.ToString ();
1082 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1083 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1084 Assert.AreEqual ("f2FsphcpM7Fu90S5V17ptly44lL4GvFCCaFdnnU4twk=", encdata, "Encrypt-" + data);
1085 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1088 data = sb.ToString ();
1089 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1090 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1091 Assert.AreEqual ("imD+ntHsUmp9ALJedzC1JmAJY0r2O4KkP8271+XuG4g=", encdata, "Encrypt-" + data);
1092 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1095 data = sb.ToString ();
1096 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1097 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1098 Assert.AreEqual ("80QLLUmHwx1fcEYGeFz1WXlS13kUy994sQLI6GhcjuM=", encdata, "Encrypt-" + data);
1099 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1102 data = sb.ToString ();
1103 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1104 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1105 Assert.AreEqual ("DtIIlj8BCOppmIgQ9AEdUj7pBB49S/9Q38kbWLjwiVs=", encdata, "Encrypt-" + data);
1106 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1109 data = sb.ToString ();
1110 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1111 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1112 Assert.AreEqual ("LNkprYaaUFtyan204OzX+a2pzOb/Pg5WXzXJ6WWB1rQ=", encdata, "Encrypt-" + data);
1113 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1116 data = sb.ToString ();
1117 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1118 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1119 Assert.AreEqual ("FRgx9m2lT2PxtYSIdRwc+SznJetNiRk1MEIZDl3D13pvo2yOtJ1MSQ==", encdata, "Encrypt-" + data);
1120 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1123 data = sb.ToString ();
1124 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1125 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1126 Assert.AreEqual ("V7JlnpJscrdIpX4z5S+/Q5WDjKzK4aB5TiqI3JZOYJ+KE1CWQNNeow==", encdata, "Encrypt-" + data);
1127 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1130 data = sb.ToString ();
1131 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1132 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1133 Assert.AreEqual ("wVwPv1c2KQynbwiOBCAhmQlReOQT52qFR34AX4dtjEeQ1oCQ1N1tHg==", encdata, "Encrypt-" + data);
1134 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1137 data = sb.ToString ();
1138 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1139 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1140 Assert.AreEqual ("Zi+G0yfmuFjSjP455pjVeKBDDWB4qvTb0K0h20UtflrYG6wcWqUzDw==", encdata, "Encrypt-" + data);
1141 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1144 data = sb.ToString ();
1145 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1146 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1147 Assert.AreEqual ("0hGoonZ8jrLhMNDKBuWrlvFnq15ZLvnyq+Ilq8r4aYUEDxttQMwi5w==", encdata, "Encrypt-" + data);
1148 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1151 // based on System.Security assembly XmlDsigBase64TransformTest
1154 public void FromBase64_Write ()
1156 string expected = "http://www.go-mono.com/";
1157 byte[] data = Encoding.UTF8.GetBytes (expected);
1158 string temp = Convert.ToBase64String (data, 0, data.Length);
1159 data = Encoding.UTF8.GetBytes (temp);
1161 DebugStream debug = new DebugStream ();
1162 ICryptoTransform base64 = new FromBase64Transform ();
1163 cs = new CryptoStream (debug, base64, CryptoStreamMode.Write);
1164 cs.Write (data, 0, data.Length);
1165 cs.FlushFinalBlock ();
1166 byte[] encoded = debug.ToArray ();
1168 string result = Encoding.UTF8.GetString (encoded);
1169 Assert.AreEqual (expected, result, "FromBase64_Write");
1173 public void FromBase64_Read ()
1175 byte[] original = Encoding.UTF8.GetBytes ("aHR0cDovL3d3dy5nby1tb25vLmNvbS8=");
1176 DebugStream debug = new DebugStream (original);
1178 ICryptoTransform base64 = new FromBase64Transform ();
1179 cs = new CryptoStream (debug, base64, CryptoStreamMode.Read);
1181 byte[] data = new byte [1024];
1182 int length = cs.Read (data, 0, data.Length);
1185 string result = Encoding.UTF8.GetString (data, 0, length);
1186 Assert.AreEqual ("http://www.go-mono.com/", result, "ToBase64_Read");
1190 public void ToBase64_Write ()
1192 byte[] data = Encoding.UTF8.GetBytes ("http://www.go-mono.com/");
1194 DebugStream debug = new DebugStream ();
1195 ICryptoTransform base64 = new ToBase64Transform ();
1196 cs = new CryptoStream (debug, base64, CryptoStreamMode.Write);
1197 cs.Write (data, 0, data.Length);
1198 cs.FlushFinalBlock ();
1199 byte[] encoded = debug.ToArray ();
1201 string result = Encoding.UTF8.GetString (encoded);
1202 Assert.AreEqual ("aHR0cDovL3d3dy5nby1tb25vLmNvbS8=", result, "ToBase64_Write");
1206 public void ToBase64_Read ()
1208 byte[] original = Encoding.UTF8.GetBytes ("http://www.go-mono.com/");
1209 DebugStream debug = new DebugStream (original);
1211 ICryptoTransform base64 = new ToBase64Transform ();
1212 cs = new CryptoStream (debug, base64, CryptoStreamMode.Read);
1214 byte[] data = new byte [1024];
1215 int length = cs.Read (data, 0, data.Length);
1218 string result = Encoding.UTF8.GetString (data, 0, length);
1219 Assert.AreEqual ("aHR0cDovL3d3dy5nby1tb25vLmNvbS8=", result, "ToBase64_Read");
1222 // Cascaded CryptoStream - like sample in book .NET Framework Security, chapter 30
1225 public void CascadedCryptoStream_Write ()
1227 DebugStream debug = new DebugStream ();
1229 // calculate both the hash (before encryption) and encrypt in one Write operation
1230 byte[] key = {0, 1, 2, 3, 4, 5, 6, 7};
1231 byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7};
1232 DES des = DES.Create ();
1233 CryptoStream cse = new CryptoStream (debug, des.CreateEncryptor (key, iv), CryptoStreamMode.Write);
1235 MD5 hash = MD5.Create ();
1236 CryptoStream csh = new CryptoStream (cse, hash, CryptoStreamMode.Write);
1238 byte[] data = Encoding.UTF8.GetBytes ("http://www.go-mono.com/");
1239 csh.Write (data, 0, data.Length);
1240 csh.FlushFinalBlock ();
1242 byte[] result = debug.ToArray ();
1243 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");
1244 byte[] digest = hash.Hash;
1245 Assert.AreEqual ("71-04-12-D1-95-01-CF-F9-8D-8F-F8-0D-F9-AA-11-7D", BitConverter.ToString (digest), "Hash");
1247 [Category ("NotWorking")]
1249 public void CascadedCryptoStream_Read ()
1251 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 };
1252 DebugStream debug = new DebugStream (encdata);
1254 // decrypt data and validate its hash in one Read operation
1255 byte[] key = {0, 1, 2, 3, 4, 5, 6, 7};
1256 byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7};
1257 DES des = DES.Create ();
1258 CryptoStream csd = new CryptoStream (debug, des.CreateDecryptor (key, iv), CryptoStreamMode.Read);
1260 MD5 hash = MD5.Create ();
1261 CryptoStream csh = new CryptoStream (csd, hash, CryptoStreamMode.Read);
1263 byte[] data = new byte [1024];
1264 int length = csh.Read (data, 0, data.Length);
1267 string result = Encoding.UTF8.GetString (data, 0, length);
1268 Assert.AreEqual ("http://www.go-mono.com/", result, "Decrypted");
1269 byte[] digest = hash.Hash;
1270 Assert.AreEqual ("71-04-12-D1-95-01-CF-F9-8D-8F-F8-0D-F9-AA-11-7D", BitConverter.ToString (digest), "Hash Validation");
1273 // bugzilla: 60573 - the number of block is not reduced for encryptors
1276 public void EncryptorWriteBlocks ()
1278 DebugStream debug = new DebugStream ();
1280 byte[] key = {0, 1, 2, 3, 4, 5, 6, 7};
1281 byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7};
1282 DES des = DES.Create ();
1283 CryptoStream cse = new CryptoStream (debug, des.CreateEncryptor (key, iv), CryptoStreamMode.Write);
1285 byte[] data = new byte [64];
1286 cse.Write (data, 0, 64);
1287 Assert.AreEqual (64, debug.Length, "Length");
1292 public void DecryptorWriteBlocks ()
1294 DebugStream debug = new DebugStream ();
1296 byte[] key = {0, 1, 2, 3, 4, 5, 6, 7};
1297 byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7};
1298 DES des = DES.Create ();
1299 CryptoStream csd = new CryptoStream (debug, des.CreateDecryptor (key, iv), CryptoStreamMode.Write);
1301 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 };
1302 csd.Write (data, 0, 64);
1303 Assert.AreEqual (56, debug.Length, "Length");
1304 // last block is kept for later processing
1308 public void PaddingModeNone ()
1310 byte[] Key = new byte [16];
1311 byte[] IV = new byte [16];
1312 byte[] Buffer = new byte [64];
1314 Rijndael alg = Rijndael.Create ();
1315 alg.Mode = CipherMode.CBC;
1316 alg.Padding = PaddingMode.None;
1318 MemoryStream cms = new MemoryStream ();
1319 ICryptoTransform ct = alg.CreateDecryptor (Key, IV);
1320 CryptoStream cs = new CryptoStream (cms, ct, CryptoStreamMode.Write);
1321 cs.Write (Buffer, 0, 64);
1324 Assert.AreEqual (64, cms.ToArray ().Length, "Length");
1327 private void WriteByte (PaddingMode mode, bool padded)
1329 byte[] Key = new byte[16];
1330 byte[] IV = new byte[16];
1331 byte[] Buffer = new byte[64];
1333 Rijndael alg = Rijndael.Create ();
1334 alg.Mode = CipherMode.CBC;
1337 MemoryStream cms = new MemoryStream ();
1338 ICryptoTransform ct = alg.CreateEncryptor (Key, IV);
1339 CryptoStream cs = new CryptoStream (cms, ct, CryptoStreamMode.Write);
1340 for (int i = 0; i < Buffer.Length; i++)
1341 cs.WriteByte (Buffer[i]);
1344 byte[] result = cms.ToArray ();
1345 // if padded then add one block, if not then it's the original length
1346 int len = padded ? 80: 64;
1347 Assert.AreEqual (len, result.Length, mode.ToString () + ".Encrypted.Length");
1349 cms = new MemoryStream ();
1350 ct = alg.CreateDecryptor (Key, IV);
1351 cs = new CryptoStream (cms, ct, CryptoStreamMode.Write);
1352 for (int i = 0; i < result.Length; i++)
1353 cs.WriteByte (result[i]);
1356 byte[] plaintext = cms.ToArray ();
1357 Assert.AreEqual (64, plaintext.Length, mode.ToString () + ".Decrypted.Length");
1359 Assert.AreEqual (Buffer, plaintext, mode.ToString () + ".Date");
1363 public void WriteByte ()
1365 WriteByte (PaddingMode.None, false);
1366 WriteByte (PaddingMode.Zeros, false);
1367 WriteByte (PaddingMode.PKCS7, true); // related to bug #81597
1368 WriteByte (PaddingMode.ANSIX923, true);
1369 WriteByte (PaddingMode.ISO10126, true);
1373 public void ReadModeDispose_FinalBlock ()
1375 using (SHA1 sha1 = SHA1.Create()) {
1376 using (MemoryStream mem = new MemoryStream(new byte[] { 1, 2, 3 }, false))
1377 using (CryptoStream cs = new CryptoStream(mem, sha1, CryptoStreamMode.Read))
1380 byte b = sha1.Hash [0]; // This will throw if TransformFinalBlock not called in sha1
1381 GC.KeepAlive (b); // just the warning...
1386 public void CustomDisposeCalled ()
1388 using (MemoryStream mem = new MemoryStream(new byte[] { 1, 2, 3 }, false)) {
1390 using (cs = new MyCryptoStream (mem, SHA1.Create()))
1393 Assert.IsTrue (cs.DisposeCalled, "#1");
1398 public void ExplicitFlush ()
1400 // Tests that explicitly calling Flush does not call Flush in the underlying stream
1401 MyStream ms = new MyStream ();
1402 using (CryptoStream cs = new CryptoStream (ms, SHA1.Create (), CryptoStreamMode.Read)) {
1403 ms.FlushCounterEnabled = true;
1405 ms.FlushCounterEnabled = false;
1407 Assert.IsTrue (ms.FlushCounter == 0);
1411 public void ImplicitFlush ()
1413 // Tests that Dispose() calls Flush on the underlying stream
1414 MyStream ms = new MyStream ();
1415 ms.FlushCounterEnabled = true;
1416 using (CryptoStream cs = new CryptoStream (ms, SHA1.Create (), CryptoStreamMode.Read)) {
1418 Assert.IsTrue (ms.FlushCounter == 1);
1422 public void ImplicitFlushCascade ()
1424 // Tests that Dispose() calls FlushFinalBlock() on the underlying stream
1425 MyStream ms = new MyStream ();
1426 ms.FlushCounterEnabled = true;
1427 CryptoStream cs1 = new CryptoStream (ms, SHA1.Create (), CryptoStreamMode.Read);
1428 using (CryptoStream cs = new CryptoStream (cs1, SHA1.Create (), CryptoStreamMode.Read)) {
1430 Assert.IsTrue (ms.FlushCounter == 1);
1434 [ExpectedException (typeof (ArgumentException))]
1435 public void Ctor_InvalidEnumValue ()
1437 CryptoStream cs = new CryptoStream (Stream.Null, SHA1.Create (), (CryptoStreamMode) 0xff);
1441 public void OutputBlock_Smaller ()
1443 // The OutputBlockSize is smaller than the InputBlockSize
1444 using (CryptoStream cs = new CryptoStream(Stream.Null, new MyCryptAlgorithm(), CryptoStreamMode.Write)) {
1445 byte[] buffer = new byte[512 * 1024];
1446 cs.Write(buffer, 0, buffer.Length);
1450 class MyCryptoStream : CryptoStream {
1451 public bool DisposeCalled { get; private set;}
1453 public MyCryptoStream(Stream stream, ICryptoTransform transform)
1454 : base(stream, transform, CryptoStreamMode.Read)
1458 protected override void Dispose(bool disposing)
1460 base.Dispose(disposing);
1461 DisposeCalled = true;
1465 class ExpandTransform : ICryptoTransform {
1467 public bool CanReuseTransform {
1468 get { return true; }
1471 public bool CanTransformMultipleBlocks {
1475 public int InputBlockSize {
1479 public int OutputBlockSize {
1483 public ExpandTransform (bool canTranformMultipleBlocks, int outputBlockSize)
1485 this.CanTransformMultipleBlocks = canTranformMultipleBlocks;
1486 this.OutputBlockSize = outputBlockSize;
1489 public void Dispose ()
1493 public int TransformBlock (byte [] inputBuffer, int inputOffset, int inputCount, byte [] outputBuffer, int outputOffset)
1496 for (var i = 0; i < inputCount; i++, inputOffset++) {
1497 for (var j = 0; j < OutputBlockSize; j++, outputOffset++, ret++) {
1498 outputBuffer [outputOffset] = inputBuffer [inputOffset];
1504 public byte [] TransformFinalBlock (byte [] inputBuffer, int inputOffset, int inputCount)
1506 var outputBuffer = new byte [inputCount * OutputBlockSize];
1507 TransformBlock (inputBuffer, inputOffset, inputCount, outputBuffer, 0);
1508 return outputBuffer;
1512 static string[] expand_values = {
1513 "00-01-02-03-04-05-06-07",
1514 "00-00-01-01-02-02-03-03-04-04-05-05-06-06-07-07",
1515 "00-00-00-01-01-01-02-02-02-03-03-03-04-04-04-05-05-05-06-06-06-07-07-07",
1516 "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",
1517 "00-01-02-03-04-05-06-07",
1518 "00-00-01-01-02-02-03-03-04-04-05-05-06-06-07-07",
1519 "00-00-00-01-01-01-02-02-02-03-03-03-04-04-04-05-05-05-06-06-06-07-07-07",
1520 "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"
1524 public void Expand ()
1527 foreach (var transformMultiple in new [] { false, true }) {
1528 foreach (var outputBlockSize in new [] { 1, 2, 3, 4 }) {
1529 var expantedStream = new MemoryStream ();
1530 var inputData = new byte [] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };
1532 using (var stream = new CryptoStream (expantedStream, new ExpandTransform (transformMultiple, outputBlockSize), CryptoStreamMode.Write)) {
1533 stream.Write (inputData, 0, inputData.Length);
1535 expantedStream.Close ();
1537 string value = BitConverter.ToString (expantedStream.ToArray ());
1538 Assert.AreEqual (expand_values [n++], value);
1543 class CompressTransform : ICryptoTransform {
1544 public bool CanReuseTransform {
1545 get { return true; }
1548 public bool CanTransformMultipleBlocks {
1549 get { return true; }
1552 public int InputBlockSize {
1556 public int OutputBlockSize {
1560 public CompressTransform (int inputBlockSize)
1562 this.InputBlockSize = inputBlockSize;
1565 public void Dispose ()
1569 private int bufferedCount = 0;
1571 public int TransformBlock (byte [] inputBuffer, int inputOffset, int inputCount, byte [] outputBuffer, int outputOffset)
1574 for (var i = 0; i < inputCount; i++, inputOffset++) {
1575 if (++bufferedCount == InputBlockSize) {
1576 outputBuffer [outputOffset++] = inputBuffer [inputOffset];
1584 public byte [] TransformFinalBlock (byte [] inputBuffer, int inputOffset, int inputCount)
1586 var outputBuffer = new byte [inputCount * OutputBlockSize];
1587 var ret = TransformBlock (inputBuffer, inputOffset, inputCount, outputBuffer, 0);
1588 byte[] result = new byte [ret];
1589 Array.Copy (outputBuffer, result, ret);
1594 static string[] compress_values = {
1595 "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",
1596 "01-03-05-07-09-0B-0D-0F-11-13-15-17-19-1B-1D-1F",
1597 "02-05-08-0B-0E-11-14-17-1A-1D",
1598 "03-07-0B-0F-13-17-1B-1F",
1602 public void Compress ()
1605 foreach (var inputBlockSize in new [] { 1, 2, 3, 4 }) {
1606 var inputData = new byte [] {
1607 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1608 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
1609 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1610 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
1613 using (var stream = new CryptoStream (new MemoryStream (inputData), new CompressTransform (inputBlockSize), CryptoStreamMode.Read)) {
1614 var buffer = new byte [inputData.Length];
1615 var ret = stream.Read (buffer, 0, buffer.Length);
1616 string value = BitConverter.ToString (buffer, 0, ret);
1617 Assert.AreEqual (compress_values [n++], value);
1622 class MyCryptAlgorithm : ICryptoTransform {
1623 public bool CanReuseTransform { get { return true; } }
1624 public bool CanTransformMultipleBlocks { get { return false; } }
1625 public int InputBlockSize { get { return 128 * 1024; } }
1626 public int OutputBlockSize { get { return 64 * 1024; } }
1628 public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
1630 return this.OutputBlockSize;
1633 public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount)
1635 return new byte[this.OutputBlockSize];
1638 public void Dispose() {}
1641 class MyStream : Stream {
1642 public bool FlushCounterEnabled;
1643 public int FlushCounter;
1645 public override bool CanRead
1652 public override bool CanSeek
1659 public override bool CanWrite
1666 public override long Length
1673 public override long Position
1682 public override void Flush ()
1684 if (FlushCounterEnabled)
1688 public override int Read (byte[] buffer, int offset, int count)
1693 public override int ReadByte ()
1698 public override long Seek (long offset, SeekOrigin origin)
1703 public override void SetLength (long value)
1707 public override void Write (byte[] buffer, int offset, int count)
1711 public override void WriteByte (byte value)