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");
337 // MS BUG [ExpectedException (typeof (ObjectDisposedException))]
339 [Category ("NotWorking")]
340 [ExpectedException (typeof (IndexOutOfRangeException))]
342 [Category ("NotDotNet")] // Test cause System.ExecutionEngineException on MS runtime
343 [ExpectedException (typeof (ArgumentNullException))] // should fail like previous test case
345 public void Read_Disposed_Break ()
347 // do no corrupt readStream in further tests
348 using (Stream s = new MemoryStream ()) {
349 byte[] buffer = new byte [8];
350 cs = new CryptoStream (s, encryptor, CryptoStreamMode.Read);
351 int len = cs.Read (buffer, 0, 4);
352 Assert.AreEqual (4, len, "Read 4");
354 len = cs.Read (buffer, 3, 4);
360 [ExpectedException (typeof (NotSupportedException))]
361 public void Read_WriteStream ()
363 cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
364 byte[] buffer = new byte [8];
365 cs.Read (buffer, 0, 8);
369 [ExpectedException (typeof (NullReferenceException))]
370 public void Read_NullBuffer ()
372 cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
373 cs.Read (null, 0, 8);
377 public void Read_EmptyBuffer_ZeroCount ()
379 byte[] buffer = new byte [0];
380 cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
381 int len = cs.Read (buffer, 0, 0);
382 Assert.AreEqual (0, len, "Read 0");
386 [ExpectedException (typeof (ArgumentOutOfRangeException))]
387 public void Read_NegativeOffset ()
389 byte[] buffer = new byte [8];
390 cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
391 cs.Read (buffer, -1, 8);
395 public void Read_ZeroCount ()
397 byte[] buffer = new byte [8];
398 cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
399 int len = cs.Read (buffer, 0, 0);
400 Assert.AreEqual (0, len, "Read 0");
404 [ExpectedException (typeof (ArgumentOutOfRangeException))]
405 public void Read_NegativeCount ()
407 byte[] buffer = new byte [8];
408 cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
409 cs.Read (buffer, 0, -1);
413 [ExpectedException (typeof (ArgumentException))]
414 public void Read_OverflowCount ()
416 byte[] buffer = new byte [8];
417 cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
418 cs.Read (buffer, 0, Int32.MaxValue);
422 [ExpectedException (typeof (ArgumentException))]
423 public void Read_InvalidOffset ()
425 byte[] buffer = new byte [8];
426 cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
427 cs.Read (buffer, 5, 4);
431 [ExpectedException (typeof (ArgumentException))]
432 public void Read_OverflowOffset ()
434 byte[] buffer = new byte [8];
435 cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
436 cs.Read (buffer, Int32.MaxValue, 4);
441 // MS BUG [ExpectedException (typeof (ObjectDisposedException))]
443 [Category ("NotWorking")]
444 [ExpectedException (typeof (IndexOutOfRangeException))]
446 [Category ("NotDotNet")] // Test cause System.ExecutionEngineException on MS runtime
447 [ExpectedException (typeof (ArgumentNullException))] // to match exception throw by Read in a similar case
449 public void Write_Disposed ()
451 // do no corrupt writeStream in further tests
452 using (Stream s = new MemoryStream ()) {
453 byte[] buffer = new byte [8];
454 cs = new CryptoStream (s, encryptor, CryptoStreamMode.Write);
456 cs.Write (buffer, 0, 8);
462 [ExpectedException (typeof (NotSupportedException))]
463 public void Write_ReadStream ()
465 cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
466 byte[] buffer = new byte [8];
467 cs.Write (buffer, 0, 8);
471 [ExpectedException (typeof (NullReferenceException))]
472 public void Write_NullBuffer ()
474 cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
475 cs.Write (null, 0, 8);
479 public void Write_EmptyBuffer_ZeroCount ()
481 byte[] buffer = new byte [0];
482 cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
483 cs.Write (buffer, 0, 0);
487 [ExpectedException (typeof (ArgumentOutOfRangeException))]
488 public void Write_NegativeOffset ()
490 byte[] buffer = new byte [8];
491 cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
492 cs.Write (buffer, -1, 8);
496 [ExpectedException (typeof (ArgumentException))]
497 public void Write_OverflowOffset ()
499 byte[] buffer = new byte [8];
500 cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
501 cs.Write (buffer, Int32.MaxValue, 8);
505 public void Write_ZeroCount ()
507 byte[] buffer = new byte [8];
508 cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
509 cs.Write (buffer, 0, 0);
513 [ExpectedException (typeof (ArgumentOutOfRangeException))]
514 public void Write_NegativeCount ()
516 byte[] buffer = new byte [8];
517 cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
518 cs.Write (buffer, 0, -1);
522 [ExpectedException (typeof (ArgumentException))]
523 public void Write_InvalidOffset ()
525 DebugStream debug = new DebugStream ();
526 byte[] buffer = new byte [8];
527 cs = new CryptoStream (debug, encryptor, CryptoStreamMode.Write);
528 cs.Write (buffer, 5, 4);
532 [ExpectedException (typeof (ArgumentException))]
533 public void Write_OverflowCount ()
535 DebugStream debug = new DebugStream ();
536 byte[] buffer = new byte [8];
537 cs = new CryptoStream (debug, encryptor, CryptoStreamMode.Write);
538 cs.Write (buffer, 0, Int32.MaxValue);
542 public void FullRoundtripRead ()
545 using (DebugStream mem1 = new DebugStream ()) {
546 byte[] toEncrypt = Encoding.Unicode.GetBytes ("Please encode me!");
547 using (CryptoStream crypt = new CryptoStream (mem1, aes.CreateEncryptor (), CryptoStreamMode.Write)) {
548 crypt.Write (toEncrypt, 0, toEncrypt.Length);
549 crypt.FlushFinalBlock ();
551 encrypted = mem1.ToArray ();
554 using (DebugStream mem2 = new DebugStream (encrypted)) {
555 byte[] buffer = new byte [1024];
556 CryptoStream cr = new CryptoStream (mem2, aes.CreateDecryptor (), CryptoStreamMode.Read);
557 int len = cr.Read (buffer, 0, buffer.Length);
559 Assert.AreEqual (34, len, "Full Length Read");
560 Assert.AreEqual ("Please encode me!", Encoding.Unicode.GetString (buffer, 0, len), "Full Block Read");
564 // bugzilla 46143 (adapted from test case by Joerg Rosenkranz)
566 public void PartialRoundtripRead ()
569 using (DebugStream mem1 = new DebugStream ()) {
570 byte[] toEncrypt = Encoding.Unicode.GetBytes ("Please encode me!");
571 using (CryptoStream crypt = new CryptoStream (mem1, aes.CreateEncryptor (), CryptoStreamMode.Write)) {
572 crypt.Write (toEncrypt, 0, toEncrypt.Length);
573 crypt.FlushFinalBlock ();
575 encrypted = mem1.ToArray ();
578 using (DebugStream mem2 = new DebugStream (encrypted)) {
579 byte[] buffer = new byte [1024];
580 CryptoStream cr = new CryptoStream (mem2, aes.CreateDecryptor (), CryptoStreamMode.Read);
581 int len = cr.Read (buffer, 0, 20);
584 Assert.AreEqual (20, len, "Partial Length Read");
585 Assert.AreEqual ("Please enc", Encoding.Unicode.GetString (buffer, 0, len), "Partial Block Read");
589 // bugzilla: 40689 (adapted from test case by Henning Westerholt)
591 public void WriteOnBlockWithFinal ()
593 byte[] desKey = {0, 1, 2, 3, 4, 5, 6, 7};
594 byte[] desIV = {0, 1, 2, 3, 4, 5, 6, 7};
595 DES des = DES.Create ();
597 MemoryStream msin = new MemoryStream ();
598 CryptoStream enc = new CryptoStream (msin, des.CreateEncryptor (desKey, desIV), CryptoStreamMode.Write);
599 byte[] data = new byte [2200];
600 enc.Write (data, 0, 2200);
601 enc.FlushFinalBlock ();
603 Assert.AreEqual (2208, msin.Length, "Encryped Write Length"); // 2200 + padding
605 MemoryStream msout = new MemoryStream ();
608 byte[] tmp = new byte [1024];
610 long totallen = msin.Length;
612 CryptoStream dec = new CryptoStream (msout, des.CreateDecryptor (desKey, desIV), CryptoStreamMode.Write);
613 int len = msin.Read (tmp, 0, 1024);
615 dec.Write (tmp, 0, len);
617 len = msin.Read (tmp, 0, 1024);
619 Assert.AreEqual (2200, msout.Length, "Decryped Write Length");
626 Assert.AreEqual (2208, readlen, "Read Length"); // 2200 + padding
630 public void PreGeneratedStreams ()
632 byte[] desKey = {0, 1, 2, 3, 4, 5, 6, 7};
633 byte[] desIV = {0, 1, 2, 3, 4, 5, 6, 7};
634 DES des = DES.Create ();
636 for (int i=0; i < 9; i++) {
637 MemoryStream msin = new MemoryStream ();
638 CryptoStream enc = new CryptoStream (msin, des.CreateEncryptor (desKey, desIV), CryptoStreamMode.Write);
639 byte[] data = new byte [i];
640 enc.Write (data, 0, i);
641 enc.FlushFinalBlock ();
643 string msg = "PreGeneratedStream #" + i;
644 string result = BitConverter.ToString (msin.ToArray ());
647 Assert.AreEqual ("92-C9-DB-45-30-0B-93-2F", result, msg);
650 Assert.AreEqual ("08-CF-A1-37-BD-56-D0-65", result, msg);
653 Assert.AreEqual ("58-87-D4-9B-2C-27-97-0C", result, msg);
656 Assert.AreEqual ("07-35-90-94-68-7D-51-FB", result, msg);
659 Assert.AreEqual ("BF-00-98-C5-20-71-D0-DB", result, msg);
662 Assert.AreEqual ("1A-55-C8-6E-C1-9B-31-82", result, msg);
665 Assert.AreEqual ("2D-2B-76-41-61-0E-00-0C", result, msg);
668 Assert.AreEqual ("DC-FF-73-D2-7F-D7-48-5D", result, msg);
671 Assert.AreEqual ("E1-B2-46-E5-A7-C7-4C-BC-0E-40-4A-FC-08-92-B1-EB", result, msg);
677 private byte[] EmptyStream (PaddingMode mode)
679 SymmetricAlgorithm algo = Rijndael.Create ();
680 algo.Key = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };
681 algo.IV = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };
683 MemoryStream ms = new MemoryStream ();
684 CryptoStream cs = new CryptoStream (ms, algo.CreateEncryptor(), CryptoStreamMode.Write);
685 cs.Write (ms.GetBuffer (), 0, (int) ms.Length);
686 cs.FlushFinalBlock ();
688 return ms.ToArray ();
692 public void EmptyStreamWithPaddingNone ()
694 byte[] result = EmptyStream (PaddingMode.None);
695 Assert.AreEqual (0, result.Length, "Result Length");
699 public void EmptyStreamWithPaddingPKCS7 ()
701 byte[] expected = { 0x07, 0xFE, 0xEF, 0x74, 0xE1, 0xD5, 0x03, 0x6E, 0x90, 0x0E, 0xEE, 0x11, 0x8E, 0x94, 0x92, 0x93 };
702 byte[] result = EmptyStream (PaddingMode.PKCS7);
703 Assert.AreEqual (16, result.Length, "Result Length");
704 Assert.AreEqual (expected, result, "Result");
708 public void EmptyStreamWithPaddingZeros ()
710 byte[] result = EmptyStream (PaddingMode.Zeros);
711 Assert.AreEqual (0, result.Length, "Result Length");
714 // bugzilla: 49323 (adapted from test case by Carlos Guzmán Álvarez)
716 public void MultiblocksWithPartial ()
718 SymmetricAlgorithm tdes = new TripleDESCryptoServiceProvider ();
719 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};
720 tdes.IV = new byte[] {193, 227, 54, 132, 68, 172, 55, 91};
722 byte[] fragment = new byte[] {20, 0, 0, 12, 181, 134, 8, 230, 185, 75, 19, 129, 101, 142, 118, 190};
723 byte[] mac = new byte[] {42, 148, 229, 58, 185, 249, 154, 131, 157, 79, 176, 168, 143, 71, 0, 118, 5, 10, 95, 8};
725 // Encryption ( fragment + mac [+ padding + padding_length] )
726 MemoryStream ms = new MemoryStream ();
727 CryptoStream cs = new CryptoStream (ms, tdes.CreateEncryptor (), CryptoStreamMode.Write);
728 cs.Write (fragment, 0, fragment.Length);
729 cs.Write (mac, 0, mac.Length);
730 // Calculate padding_length
731 int fragmentLength = fragment.Length + mac.Length + 1;
732 int padding = (((fragmentLength / 8) * 8) + 8) - fragmentLength;
733 // Write padding length byte
734 cs.WriteByte ((byte)padding);
736 byte[] encrypted = ms.ToArray ();
737 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 };
738 Assert.AreEqual (expected, encrypted, "MultiblocksWithPartial");
741 // Adapted from Subba Rao Thirumoorthy email on mono-devel-list (december 2003)
742 private byte[] NonMultipleOfBlockSize_Encrypt (ICryptoTransform ct, byte[] data)
744 DebugStream stream = new DebugStream ();
745 CryptoStream CryptStream = new CryptoStream (stream, ct, CryptoStreamMode.Write);
749 byte[] Buffer = new byte [1024];
751 DebugStream fout = new DebugStream (data);
752 while (myLength < data.Length) {
753 len = fout.Read (Buffer, 0, 1023);
756 CryptStream.Write (Buffer, 0, len);
757 CryptStream.Flush ();
758 myLength = myLength + len;
760 CryptStream.FlushFinalBlock ();
761 // we must ensure that the result is correct
762 Assert.AreEqual (64, len, "Length(final)");
763 byte[] result = stream.ToArray ();
764 string end = BitConverter.ToString (result, 65520, 16);
765 Assert.AreEqual ("04-70-19-1D-28-C5-BD-9A-23-C6-60-E2-28-96-38-65", end, "End part");
772 private byte[] NonMultipleOfBlockSize_Decrypt (ICryptoTransform ct, byte[] data)
774 DebugStream stream = new DebugStream (data);
775 CryptoStream CryptStream = new CryptoStream (stream, ct, CryptoStreamMode.Read);
779 byte[] Buffer = new Byte [1024];
781 DebugStream fout = new DebugStream ();
782 // each returned block must be 1023 bytes long
783 // even if this isn't a multiple of the block size
784 while ((len = CryptStream.Read (Buffer, 0, 1023)) != 0) {
785 fout.Write (Buffer, 0, len);
787 myLength = myLength + len;
790 byte[] result = fout.ToArray ();
791 CryptStream.Close ();
797 public void NonMultipleOfBlockSize ()
799 byte[] key = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
800 byte[] iv = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
801 byte[] data = new byte [65536];
803 RijndaelManaged aes = new RijndaelManaged ();
804 ICryptoTransform encryptor = aes.CreateEncryptor (key, iv);
805 byte[] encdata = NonMultipleOfBlockSize_Encrypt (encryptor, data);
806 Assert.AreEqual ((data.Length + (aes.BlockSize >> 3)), encdata.Length, "Encrypted Data Length");
808 ICryptoTransform decryptor = aes.CreateDecryptor (key, iv);
809 byte[] decdata = NonMultipleOfBlockSize_Decrypt (decryptor, encdata);
810 Assert.AreEqual (data.Length, decdata.Length, "Decrypted Data Length");
814 while (b && (i < data.Length)) {
815 b = (data [i] == decdata [i]);
818 Assert.IsTrue (b, "NonMultipleOfBlockSize");
821 // bugzilla: 51322 - indirectly related but it explains why my first (unapplied) patch didn't work
823 public void DecryptPartial_TransformFinalBlock_required ()
825 byte[] key = {0, 1, 2, 3, 4, 5, 6, 7};
826 byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7};
827 DES des = DES.Create ();
829 byte[] data = Encoding.Unicode.GetBytes ("ximian"); // 12 bytes, 1.5 DES block size
830 DebugStream encrypted = new DebugStream ();
831 cs = new CryptoStream (encrypted, des.CreateEncryptor (key, iv), CryptoStreamMode.Write);
832 cs.Write (data, 0, data.Length);
835 data = encrypted.ToArray ();
836 DebugStream decrypted = new DebugStream (data);
837 cs = new CryptoStream (decrypted, des.CreateDecryptor (key, iv), CryptoStreamMode.Read);
838 int len = cs.Read (data, 0, data.Length);
840 Assert.AreEqual (12, len, "Length");
841 Assert.AreEqual ("ximian", Encoding.Unicode.GetString (data, 0, len), "Unicode DES Roundtrip");
845 [Category ("NotWorking")]
848 public void DecryptPartial_TransformFinalBlock_2Pass ()
850 byte[] key = {0, 1, 2, 3, 4, 5, 6, 7};
851 byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7};
852 DES des = DES.Create ();
854 byte[] data = Encoding.Unicode.GetBytes ("ximian"); // 12 bytes, 1.5 DES block size
855 DebugStream encrypted = new DebugStream ();
856 cs = new CryptoStream (encrypted, des.CreateEncryptor (key, iv), CryptoStreamMode.Write);
857 cs.Write (data, 0, data.Length);
860 data = encrypted.ToArray ();
861 DebugStream decrypted = new DebugStream (data);
862 cs = new CryptoStream (decrypted, des.CreateDecryptor (key, iv), CryptoStreamMode.Read);
863 int len = cs.Read (data, 0, 6);
864 Assert.AreEqual (6, len, "Length (1st pass)");
865 Assert.AreEqual ("xim", Encoding.Unicode.GetString (data, 0, len), "Partial DES Roundtrip");
866 len += cs.Read (data, 6, 8);
867 Assert.AreEqual (12, len, "Length (1st+2nd)");
868 Assert.AreEqual ("ximian", Encoding.Unicode.GetString (data, 0, len), "Full DES Roundtrip");
872 // based on http://www.c-sharpcorner.com/Code/2002/May/FileEncryption.asp
874 [Category ("NotWorking")]
877 public void WriteByteReadByte ()
879 DebugStream original = new DebugStream (Encoding.Unicode.GetBytes ("ximian"));
881 DebugStream encrypted = new DebugStream ();
882 byte[] key = {0, 1, 2, 3, 4, 5, 6, 7};
883 byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7};
884 DES des = DES.Create ();
885 cs = new CryptoStream (encrypted, des.CreateEncryptor (key, iv), CryptoStreamMode.Write);
888 while ((data = original.ReadByte ()) != -1)
889 cs.WriteByte((byte) data);
892 byte[] result = encrypted.ToArray ();
893 Assert.AreEqual ("18-EA-93-3F-20-86-D2-AA-78-02-D7-6F-E4-47-17-9C", BitConverter.ToString (result), "Encrypted");
895 encrypted = new DebugStream (result);
896 DebugStream decrypted = new DebugStream ();
897 cs = new CryptoStream (encrypted, des.CreateDecryptor (key, iv), CryptoStreamMode.Read);
899 while ((data = cs.ReadByte ()) != -1)
900 decrypted.WriteByte((byte) data);
904 Assert.AreEqual ("ximian", Encoding.Unicode.GetString (decrypted.ToArray ()), "W/R Byte Roundtrip");
907 // based http://www.4guysfromrolla.com/webtech/090501-1.shtml
909 public string EncryptData (ICryptoTransform des, string strData)
911 strData = String.Format("{0,5:00000}" + strData, strData.Length);
912 byte[] data = Encoding.ASCII.GetBytes (strData);
914 MemoryStream mStream = new MemoryStream (data);
915 CryptoStream cs = new CryptoStream (mStream, des, CryptoStreamMode.Read);
916 MemoryStream mOut = new MemoryStream ();
919 byte[] output = new byte [1024];
921 bytesRead = cs.Read (output, 0, 1024);
923 mOut.Write (output, 0, bytesRead);
925 while (bytesRead > 0);
927 return Convert.ToBase64String (mOut.ToArray ());
930 public string DecryptData (ICryptoTransform des, string strData)
932 MemoryStream mOut = new MemoryStream ();
933 byte[] data = Convert.FromBase64String (strData);
934 CryptoStream cs = new CryptoStream (mOut, des, CryptoStreamMode.Write);
935 cs.Write (data, 0, (int)data.Length);
936 cs.FlushFinalBlock ();
937 return Encoding.ASCII.GetString (mOut.ToArray ()).Substring (5);
941 public void EncryptOnRead ()
943 SHA1 sha = SHA1.Create ();
944 byte[] vector = sha.ComputeHash (Encoding.ASCII.GetBytes ("s3kr3t"));
945 byte[] key = new byte [8];
946 Buffer.BlockCopy (vector, 0, key, 0, key.Length);
947 byte[] iv = new byte [8];
948 Buffer.BlockCopy (vector, 8, iv, 0, iv.Length);
950 DES des = DES.Create ();
952 StringBuilder sb = new StringBuilder ();
954 string data = sb.ToString ();
955 string encdata = EncryptData (des.CreateEncryptor (key, iv), data);
956 string decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
957 Assert.AreEqual ("9YVfvrh5yj0=", encdata, "Encrypt-" + data);
958 Assert.AreEqual (data, decdata, "Decrypt-" + data);
961 data = sb.ToString ();
962 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
963 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
964 Assert.AreEqual ("qNe4d0UlkU8=", encdata, "Encrypt-" + data);
965 Assert.AreEqual (data, decdata, "Decrypt-" + data);
968 data = sb.ToString ();
969 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
970 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
971 Assert.AreEqual ("OcernYAQ1NAME/Gny+ZuaA==", encdata, "Encrypt-" + data);
972 Assert.AreEqual (data, decdata, "Decrypt-" + data);
975 data = sb.ToString ();
976 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
977 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
978 Assert.AreEqual ("H5UveR2lds1T+IWN4pks2Q==", encdata, "Encrypt-" + data);
979 Assert.AreEqual (data, decdata, "Decrypt-" + data);
982 data = sb.ToString ();
983 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
984 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
985 Assert.AreEqual ("dDQ3HAVtTbiRwwUqWANaeA==", encdata, "Encrypt-" + data);
986 Assert.AreEqual (data, decdata, "Decrypt-" + data);
989 data = sb.ToString ();
990 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
991 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
992 Assert.AreEqual ("At1r7dVDjJlQidf4QzCNkw==", encdata, "Encrypt-" + data);
993 Assert.AreEqual (data, decdata, "Decrypt-" + data);
996 data = sb.ToString ();
997 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
998 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
999 Assert.AreEqual ("DFDJWJGaNrFVBDXovsq1ew==", encdata, "Encrypt-" + data);
1000 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1003 data = sb.ToString ();
1004 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1005 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1006 Assert.AreEqual ("gM040QGMPOBj3u1lEK4XHQ==", encdata, "Encrypt-" + data);
1007 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1010 data = sb.ToString ();
1011 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1012 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1013 Assert.AreEqual ("P5hRUhrxOWFX0ER/IjJL/Q==", encdata, "Encrypt-" + data);
1014 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1017 data = sb.ToString ();
1018 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1019 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1020 Assert.AreEqual ("uDIaQ1uXtWUIboGFLt306Q==", encdata, "Encrypt-" + data);
1021 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1024 data = sb.ToString ();
1025 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1026 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1027 Assert.AreEqual ("giJKTXfad5Z8hebhXtYZ4hmKX/EC8w6x", encdata, "Encrypt-" + data);
1028 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1031 data = sb.ToString ();
1032 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1033 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1034 Assert.AreEqual ("lBehBplIrjjrlIrMjYcNz1DOoXLHjZdn", encdata, "Encrypt-" + data);
1035 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1038 data = sb.ToString ();
1039 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1040 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1041 Assert.AreEqual ("2elWrUnjmsAOpo2s4voJyZXEJ/rtKB7P", encdata, "Encrypt-" + data);
1042 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1045 data = sb.ToString ();
1046 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1047 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1048 Assert.AreEqual ("GB3BaIZGf9K+T82j7T8Fri2rQ2/YUdSe", encdata, "Encrypt-" + data);
1049 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1052 data = sb.ToString ();
1053 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1054 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1055 Assert.AreEqual ("Gc+wkJL+CVjdJchgcIoi8dkH2BVpHJgB", encdata, "Encrypt-" + data);
1056 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1059 data = sb.ToString ();
1060 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1061 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1062 Assert.AreEqual ("loeuyII/PvWb91M4pFVkyaPxQoQVYpNb", encdata, "Encrypt-" + data);
1063 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1066 data = sb.ToString ();
1067 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1068 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1069 Assert.AreEqual ("PHXmi/sxNIgApXAfdm+Bf54/nCM//N8o", encdata, "Encrypt-" + data);
1070 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1073 data = sb.ToString ();
1074 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1075 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1076 Assert.AreEqual ("xpb+wj/8LmH2ScTg3OU4JOsE5Owj6flF", encdata, "Encrypt-" + data);
1077 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1080 data = sb.ToString ();
1081 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1082 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1083 Assert.AreEqual ("WJz4VfsZ2emzhYWoSf+PNBDpHooxEregqMWnzm4gcqU=", encdata, "Encrypt-" + data);
1084 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1087 data = sb.ToString ();
1088 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1089 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1090 Assert.AreEqual ("PaouZu1iOKbCMRJSu04y/kB+TcOk4yp8K2BOGDs1PPE=", encdata, "Encrypt-" + data);
1091 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1094 data = sb.ToString ();
1095 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1096 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1097 Assert.AreEqual ("qbTDs4dFy7eERdn5vV7JRPk2/m9smtwvZjA6+TmGlkI=", encdata, "Encrypt-" + data);
1098 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1101 data = sb.ToString ();
1102 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1103 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1104 Assert.AreEqual ("f2FsphcpM7Fu90S5V17ptly44lL4GvFCCaFdnnU4twk=", encdata, "Encrypt-" + data);
1105 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1108 data = sb.ToString ();
1109 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1110 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1111 Assert.AreEqual ("imD+ntHsUmp9ALJedzC1JmAJY0r2O4KkP8271+XuG4g=", encdata, "Encrypt-" + data);
1112 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1115 data = sb.ToString ();
1116 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1117 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1118 Assert.AreEqual ("80QLLUmHwx1fcEYGeFz1WXlS13kUy994sQLI6GhcjuM=", encdata, "Encrypt-" + data);
1119 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1122 data = sb.ToString ();
1123 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1124 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1125 Assert.AreEqual ("DtIIlj8BCOppmIgQ9AEdUj7pBB49S/9Q38kbWLjwiVs=", encdata, "Encrypt-" + data);
1126 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1129 data = sb.ToString ();
1130 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1131 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1132 Assert.AreEqual ("LNkprYaaUFtyan204OzX+a2pzOb/Pg5WXzXJ6WWB1rQ=", encdata, "Encrypt-" + data);
1133 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1136 data = sb.ToString ();
1137 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1138 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1139 Assert.AreEqual ("FRgx9m2lT2PxtYSIdRwc+SznJetNiRk1MEIZDl3D13pvo2yOtJ1MSQ==", encdata, "Encrypt-" + data);
1140 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1143 data = sb.ToString ();
1144 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1145 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1146 Assert.AreEqual ("V7JlnpJscrdIpX4z5S+/Q5WDjKzK4aB5TiqI3JZOYJ+KE1CWQNNeow==", encdata, "Encrypt-" + data);
1147 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1150 data = sb.ToString ();
1151 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1152 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1153 Assert.AreEqual ("wVwPv1c2KQynbwiOBCAhmQlReOQT52qFR34AX4dtjEeQ1oCQ1N1tHg==", encdata, "Encrypt-" + data);
1154 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1157 data = sb.ToString ();
1158 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1159 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1160 Assert.AreEqual ("Zi+G0yfmuFjSjP455pjVeKBDDWB4qvTb0K0h20UtflrYG6wcWqUzDw==", encdata, "Encrypt-" + data);
1161 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1164 data = sb.ToString ();
1165 encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1166 decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1167 Assert.AreEqual ("0hGoonZ8jrLhMNDKBuWrlvFnq15ZLvnyq+Ilq8r4aYUEDxttQMwi5w==", encdata, "Encrypt-" + data);
1168 Assert.AreEqual (data, decdata, "Decrypt-" + data);
1171 // based on System.Security assembly XmlDsigBase64TransformTest
1174 public void FromBase64_Write ()
1176 string expected = "http://www.go-mono.com/";
1177 byte[] data = Encoding.UTF8.GetBytes (expected);
1178 string temp = Convert.ToBase64String (data, 0, data.Length);
1179 data = Encoding.UTF8.GetBytes (temp);
1181 DebugStream debug = new DebugStream ();
1182 ICryptoTransform base64 = new FromBase64Transform ();
1183 cs = new CryptoStream (debug, base64, CryptoStreamMode.Write);
1184 cs.Write (data, 0, data.Length);
1185 cs.FlushFinalBlock ();
1186 byte[] encoded = debug.ToArray ();
1188 string result = Encoding.UTF8.GetString (encoded);
1189 Assert.AreEqual (expected, result, "FromBase64_Write");
1193 public void FromBase64_Read ()
1195 byte[] original = Encoding.UTF8.GetBytes ("aHR0cDovL3d3dy5nby1tb25vLmNvbS8=");
1196 DebugStream debug = new DebugStream (original);
1198 ICryptoTransform base64 = new FromBase64Transform ();
1199 cs = new CryptoStream (debug, base64, CryptoStreamMode.Read);
1201 byte[] data = new byte [1024];
1202 int length = cs.Read (data, 0, data.Length);
1205 string result = Encoding.UTF8.GetString (data, 0, length);
1206 Assert.AreEqual ("http://www.go-mono.com/", result, "ToBase64_Read");
1210 public void ToBase64_Write ()
1212 byte[] data = Encoding.UTF8.GetBytes ("http://www.go-mono.com/");
1214 DebugStream debug = new DebugStream ();
1215 ICryptoTransform base64 = new ToBase64Transform ();
1216 cs = new CryptoStream (debug, base64, CryptoStreamMode.Write);
1217 cs.Write (data, 0, data.Length);
1218 cs.FlushFinalBlock ();
1219 byte[] encoded = debug.ToArray ();
1221 string result = Encoding.UTF8.GetString (encoded);
1222 Assert.AreEqual ("aHR0cDovL3d3dy5nby1tb25vLmNvbS8=", result, "ToBase64_Write");
1226 public void ToBase64_Read ()
1228 byte[] original = Encoding.UTF8.GetBytes ("http://www.go-mono.com/");
1229 DebugStream debug = new DebugStream (original);
1231 ICryptoTransform base64 = new ToBase64Transform ();
1232 cs = new CryptoStream (debug, base64, CryptoStreamMode.Read);
1234 byte[] data = new byte [1024];
1235 int length = cs.Read (data, 0, data.Length);
1238 string result = Encoding.UTF8.GetString (data, 0, length);
1239 Assert.AreEqual ("aHR0cDovL3d3dy5nby1tb25vLmNvbS8=", result, "ToBase64_Read");
1242 // Cascaded CryptoStream - like sample in book .NET Framework Security, chapter 30
1245 public void CascadedCryptoStream_Write ()
1247 DebugStream debug = new DebugStream ();
1249 // calculate both the hash (before encryption) and encrypt in one Write operation
1250 byte[] key = {0, 1, 2, 3, 4, 5, 6, 7};
1251 byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7};
1252 DES des = DES.Create ();
1253 CryptoStream cse = new CryptoStream (debug, des.CreateEncryptor (key, iv), CryptoStreamMode.Write);
1255 MD5 hash = MD5.Create ();
1256 CryptoStream csh = new CryptoStream (cse, hash, CryptoStreamMode.Write);
1258 byte[] data = Encoding.UTF8.GetBytes ("http://www.go-mono.com/");
1259 csh.Write (data, 0, data.Length);
1260 csh.FlushFinalBlock ();
1262 byte[] result = debug.ToArray ();
1263 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");
1264 byte[] digest = hash.Hash;
1265 Assert.AreEqual ("71-04-12-D1-95-01-CF-F9-8D-8F-F8-0D-F9-AA-11-7D", BitConverter.ToString (digest), "Hash");
1268 [Category ("NotWorking")]
1271 public void CascadedCryptoStream_Read ()
1273 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 };
1274 DebugStream debug = new DebugStream (encdata);
1276 // decrypt data and validate its hash in one Read operation
1277 byte[] key = {0, 1, 2, 3, 4, 5, 6, 7};
1278 byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7};
1279 DES des = DES.Create ();
1280 CryptoStream csd = new CryptoStream (debug, des.CreateDecryptor (key, iv), CryptoStreamMode.Read);
1282 MD5 hash = MD5.Create ();
1283 CryptoStream csh = new CryptoStream (csd, hash, CryptoStreamMode.Read);
1285 byte[] data = new byte [1024];
1286 int length = csh.Read (data, 0, data.Length);
1289 string result = Encoding.UTF8.GetString (data, 0, length);
1290 Assert.AreEqual ("http://www.go-mono.com/", result, "Decrypted");
1291 byte[] digest = hash.Hash;
1292 Assert.AreEqual ("71-04-12-D1-95-01-CF-F9-8D-8F-F8-0D-F9-AA-11-7D", BitConverter.ToString (digest), "Hash Validation");
1295 // bugzilla: 60573 - the number of block is not reduced for encryptors
1298 public void EncryptorWriteBlocks ()
1300 DebugStream debug = new DebugStream ();
1302 byte[] key = {0, 1, 2, 3, 4, 5, 6, 7};
1303 byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7};
1304 DES des = DES.Create ();
1305 CryptoStream cse = new CryptoStream (debug, des.CreateEncryptor (key, iv), CryptoStreamMode.Write);
1307 byte[] data = new byte [64];
1308 cse.Write (data, 0, 64);
1309 Assert.AreEqual (64, debug.Length, "Length");
1314 public void DecryptorWriteBlocks ()
1316 DebugStream debug = new DebugStream ();
1318 byte[] key = {0, 1, 2, 3, 4, 5, 6, 7};
1319 byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7};
1320 DES des = DES.Create ();
1321 CryptoStream csd = new CryptoStream (debug, des.CreateDecryptor (key, iv), CryptoStreamMode.Write);
1323 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 };
1324 csd.Write (data, 0, 64);
1325 Assert.AreEqual (56, debug.Length, "Length");
1326 // last block is kept for later processing
1330 public void PaddingModeNone ()
1332 byte[] Key = new byte [16];
1333 byte[] IV = new byte [16];
1334 byte[] Buffer = new byte [64];
1336 Rijndael alg = Rijndael.Create ();
1337 alg.Mode = CipherMode.CBC;
1338 alg.Padding = PaddingMode.None;
1340 MemoryStream cms = new MemoryStream ();
1341 ICryptoTransform ct = alg.CreateDecryptor (Key, IV);
1342 CryptoStream cs = new CryptoStream (cms, ct, CryptoStreamMode.Write);
1343 cs.Write (Buffer, 0, 64);
1346 Assert.AreEqual (64, cms.ToArray ().Length, "Length");
1349 private void WriteByte (PaddingMode mode, bool padded)
1351 byte[] Key = new byte[16];
1352 byte[] IV = new byte[16];
1353 byte[] Buffer = new byte[64];
1355 Rijndael alg = Rijndael.Create ();
1356 alg.Mode = CipherMode.CBC;
1359 MemoryStream cms = new MemoryStream ();
1360 ICryptoTransform ct = alg.CreateEncryptor (Key, IV);
1361 CryptoStream cs = new CryptoStream (cms, ct, CryptoStreamMode.Write);
1362 for (int i = 0; i < Buffer.Length; i++)
1363 cs.WriteByte (Buffer[i]);
1366 byte[] result = cms.ToArray ();
1367 // if padded then add one block, if not then it's the original length
1368 int len = padded ? 80: 64;
1369 Assert.AreEqual (len, result.Length, mode.ToString () + ".Encrypted.Length");
1371 cms = new MemoryStream ();
1372 ct = alg.CreateDecryptor (Key, IV);
1373 cs = new CryptoStream (cms, ct, CryptoStreamMode.Write);
1374 for (int i = 0; i < result.Length; i++)
1375 cs.WriteByte (result[i]);
1378 byte[] plaintext = cms.ToArray ();
1379 Assert.AreEqual (64, plaintext.Length, mode.ToString () + ".Decrypted.Length");
1381 Assert.AreEqual (Buffer, plaintext, mode.ToString () + ".Date");
1385 public void WriteByte ()
1387 WriteByte (PaddingMode.None, false);
1388 WriteByte (PaddingMode.Zeros, false);
1389 WriteByte (PaddingMode.PKCS7, true); // related to bug #81597
1391 WriteByte (PaddingMode.ANSIX923, true);
1392 WriteByte (PaddingMode.ISO10126, true);
1397 public void ReadModeDispose_FinalBlock ()
1399 using (SHA1 sha1 = SHA1.Create()) {
1400 using (MemoryStream mem = new MemoryStream(new byte[] { 1, 2, 3 }, false))
1401 using (CryptoStream cs = new CryptoStream(mem, sha1, CryptoStreamMode.Read))
1404 byte b = sha1.Hash [0]; // This will throw if TransformFinalBlock not called in sha1
1405 GC.KeepAlive (b); // just the warning...
1410 public void CustomDisposeCalled ()
1412 using (MemoryStream mem = new MemoryStream(new byte[] { 1, 2, 3 }, false)) {
1414 using (cs = new MyCryptoStream (mem, SHA1.Create()))
1417 Assert.IsTrue (cs.DisposeCalled, "#1");
1422 public void ExplicitFlush ()
1424 // Tests that explicitly calling Flush does not call Flush in the underlying stream
1425 MyStream ms = new MyStream ();
1426 using (CryptoStream cs = new CryptoStream (ms, SHA1.Create (), CryptoStreamMode.Read)) {
1427 ms.FlushCounterEnabled = true;
1429 ms.FlushCounterEnabled = false;
1431 Assert.IsTrue (ms.FlushCounter == 0);
1435 public void ImplicitFlush ()
1437 // Tests that Dispose() calls Flush on the underlying stream
1438 MyStream ms = new MyStream ();
1439 ms.FlushCounterEnabled = true;
1440 using (CryptoStream cs = new CryptoStream (ms, SHA1.Create (), CryptoStreamMode.Read)) {
1442 Assert.IsTrue (ms.FlushCounter == 1);
1446 public void ImplicitFlushCascade ()
1448 // Tests that Dispose() calls FlushFinalBlock() on the underlying stream
1449 MyStream ms = new MyStream ();
1450 ms.FlushCounterEnabled = true;
1451 CryptoStream cs1 = new CryptoStream (ms, SHA1.Create (), CryptoStreamMode.Read);
1452 using (CryptoStream cs = new CryptoStream (cs1, SHA1.Create (), CryptoStreamMode.Read)) {
1454 Assert.IsTrue (ms.FlushCounter == 1);
1458 [ExpectedException (typeof (ArgumentException))]
1459 public void Ctor_InvalidEnumValue ()
1461 CryptoStream cs = new CryptoStream (Stream.Null, SHA1.Create (), (CryptoStreamMode) 0xff);
1465 public void OutputBlock_Smaller ()
1467 // The OutputBlockSize is smaller than the InputBlockSize
1468 using (CryptoStream cs = new CryptoStream(Stream.Null, new MyCryptAlgorithm(), CryptoStreamMode.Write)) {
1469 byte[] buffer = new byte[512 * 1024];
1470 cs.Write(buffer, 0, buffer.Length);
1474 class MyCryptoStream : CryptoStream {
1475 public bool DisposeCalled { get; private set;}
1477 public MyCryptoStream(Stream stream, ICryptoTransform transform)
1478 : base(stream, transform, CryptoStreamMode.Read)
1482 protected override void Dispose(bool disposing)
1484 base.Dispose(disposing);
1485 DisposeCalled = true;
1489 class ExpandTransform : ICryptoTransform {
1491 public bool CanReuseTransform {
1492 get { return true; }
1495 public bool CanTransformMultipleBlocks {
1499 public int InputBlockSize {
1503 public int OutputBlockSize {
1507 public ExpandTransform (bool canTranformMultipleBlocks, int outputBlockSize)
1509 this.CanTransformMultipleBlocks = canTranformMultipleBlocks;
1510 this.OutputBlockSize = outputBlockSize;
1513 public void Dispose ()
1517 public int TransformBlock (byte [] inputBuffer, int inputOffset, int inputCount, byte [] outputBuffer, int outputOffset)
1520 for (var i = 0; i < inputCount; i++, inputOffset++) {
1521 for (var j = 0; j < OutputBlockSize; j++, outputOffset++, ret++) {
1522 outputBuffer [outputOffset] = inputBuffer [inputOffset];
1528 public byte [] TransformFinalBlock (byte [] inputBuffer, int inputOffset, int inputCount)
1530 var outputBuffer = new byte [inputCount * OutputBlockSize];
1531 TransformBlock (inputBuffer, inputOffset, inputCount, outputBuffer, 0);
1532 return outputBuffer;
1536 static string[] expand_values = {
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",
1541 "00-01-02-03-04-05-06-07",
1542 "00-00-01-01-02-02-03-03-04-04-05-05-06-06-07-07",
1543 "00-00-00-01-01-01-02-02-02-03-03-03-04-04-04-05-05-05-06-06-06-07-07-07",
1544 "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"
1548 public void Expand ()
1551 foreach (var transformMultiple in new [] { false, true }) {
1552 foreach (var outputBlockSize in new [] { 1, 2, 3, 4 }) {
1553 var expantedStream = new MemoryStream ();
1554 var inputData = new byte [] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };
1556 using (var stream = new CryptoStream (expantedStream, new ExpandTransform (transformMultiple, outputBlockSize), CryptoStreamMode.Write)) {
1557 stream.Write (inputData, 0, inputData.Length);
1559 expantedStream.Close ();
1561 string value = BitConverter.ToString (expantedStream.ToArray ());
1562 Assert.AreEqual (expand_values [n++], value);
1567 class CompressTransform : ICryptoTransform {
1568 public bool CanReuseTransform {
1569 get { return true; }
1572 public bool CanTransformMultipleBlocks {
1573 get { return true; }
1576 public int InputBlockSize {
1580 public int OutputBlockSize {
1584 public CompressTransform (int inputBlockSize)
1586 this.InputBlockSize = inputBlockSize;
1589 public void Dispose ()
1593 private int bufferedCount = 0;
1595 public int TransformBlock (byte [] inputBuffer, int inputOffset, int inputCount, byte [] outputBuffer, int outputOffset)
1598 for (var i = 0; i < inputCount; i++, inputOffset++) {
1599 if (++bufferedCount == InputBlockSize) {
1600 outputBuffer [outputOffset++] = inputBuffer [inputOffset];
1608 public byte [] TransformFinalBlock (byte [] inputBuffer, int inputOffset, int inputCount)
1610 var outputBuffer = new byte [inputCount * OutputBlockSize];
1611 var ret = TransformBlock (inputBuffer, inputOffset, inputCount, outputBuffer, 0);
1612 byte[] result = new byte [ret];
1613 Array.Copy (outputBuffer, result, ret);
1618 static string[] compress_values = {
1619 "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",
1620 "01-03-05-07-09-0B-0D-0F-11-13-15-17-19-1B-1D-1F",
1621 "02-05-08-0B-0E-11-14-17-1A-1D",
1622 "03-07-0B-0F-13-17-1B-1F",
1626 public void Compress ()
1629 foreach (var inputBlockSize in new [] { 1, 2, 3, 4 }) {
1630 var inputData = new byte [] {
1631 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1632 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
1633 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1634 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
1637 using (var stream = new CryptoStream (new MemoryStream (inputData), new CompressTransform (inputBlockSize), CryptoStreamMode.Read)) {
1638 var buffer = new byte [inputData.Length];
1639 var ret = stream.Read (buffer, 0, buffer.Length);
1640 string value = BitConverter.ToString (buffer, 0, ret);
1641 Assert.AreEqual (compress_values [n++], value);
1646 class MyCryptAlgorithm : ICryptoTransform {
1647 public bool CanReuseTransform { get { return true; } }
1648 public bool CanTransformMultipleBlocks { get { return false; } }
1649 public int InputBlockSize { get { return 128 * 1024; } }
1650 public int OutputBlockSize { get { return 64 * 1024; } }
1652 public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
1654 return this.OutputBlockSize;
1657 public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount)
1659 return new byte[this.OutputBlockSize];
1662 public void Dispose() {}
1665 class MyStream : Stream {
1666 public bool FlushCounterEnabled;
1667 public int FlushCounter;
1669 public override bool CanRead
1676 public override bool CanSeek
1683 public override bool CanWrite
1690 public override long Length
1697 public override long Position
1706 public override void Flush ()
1708 if (FlushCounterEnabled)
1712 public override int Read (byte[] buffer, int offset, int count)
1717 public override int ReadByte ()
1722 public override long Seek (long offset, SeekOrigin origin)
1727 public override void SetLength (long value)
1731 public override void Write (byte[] buffer, int offset, int count)
1735 public override void WriteByte (byte value)