This commit was manufactured by cvs2svn to create branch 'mono-1-0'.
[mono.git] / mcs / class / corlib / Test / System.Security.Cryptography / CryptoStreamTest.cs
1 //
2 // CryptoStreamTest.cs - NUnit Test Cases for CryptoStream
3 //
4 // Author:
5 //      Sebastien Pouliot <sebastien@ximian.com>
6 //
7 // (C) 2003 Motus Technologies Inc. (http://www.motus.com)
8 // (C) 2004 Novell (http://www.novell.com)
9 //
10
11 /* WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING *
12  * 
13  * DO NOT USE ANY OF THE TEST CASE AS SAMPLES FOR YOUR OWN CODE. MANY
14  * CASES CONTAINS ERRORS AND AREN'T SECURE IN THEIR USE.
15  * 
16  * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING */
17
18 using NUnit.Framework;
19 using System;
20 using System.IO;
21 using System.Reflection;
22 using System.Runtime.InteropServices;
23 using System.Security.Cryptography;
24 using System.Text;
25
26 namespace MonoTests.System.Security.Cryptography {
27
28         // much useful for debugging
29         public class DebugStream : MemoryStream {
30
31                 // constructor
32
33                 public DebugStream () : base () {}
34                 public DebugStream (byte[] buffer) : base (buffer) {}
35                 public DebugStream (int capacity) : base (capacity) {}
36
37                 public override bool CanRead {
38                         get { return base.CanRead; }
39                 }
40
41                 public override bool CanSeek {
42                         get { return base.CanSeek; }
43                 }
44
45                 public override bool CanWrite {
46                         get { return base.CanWrite; }
47                 }
48
49                 public override int Capacity {
50                         get { return base.Capacity; }
51                         set { base.Capacity = value; }
52                 }
53
54                 public override long Length {
55                         get { return base.Length; }
56                 }
57                 
58                 public override long Position {
59                         get { return base.Position; }
60                         set { base.Position = value; }
61                 }
62
63                 // methods
64                 
65                 public override void Close () 
66                 {
67                         base.Close ();
68                 }
69                 
70                 public override void Flush () 
71                 {
72                         base.Flush ();
73                 }
74
75                 public override byte[] GetBuffer () 
76                 {
77                         return base.GetBuffer ();
78                 }
79
80                 public override int Read ([In,Out] byte[] buffer, int offset, int count)
81                 {
82                         int len = base.Read (buffer, offset, count);
83                         return len;
84                 }
85
86                 public override int ReadByte () 
87                 {
88                         return base.ReadByte ();
89                 }
90
91                 public override long Seek (long offset, SeekOrigin loc)
92                 {
93                         return base.Seek (offset, loc);
94                 }
95                 
96                 public override void SetLength (long value)
97                 {
98                         base.SetLength (value);
99                 }
100                 
101                 public override byte[] ToArray () 
102                 {
103                         return base.ToArray ();
104                 }
105
106                 public override void Write (byte[] buffer, int offset, int count) 
107                 {
108                         base.Write (buffer, offset, count);
109                 }
110
111                 public override void WriteByte (byte value) 
112                 {
113                         base.WriteByte (value);
114                 }
115
116                 public override void WriteTo (Stream stream) 
117                 {
118                         base.WriteTo (stream);
119                 }
120         }
121
122         [TestFixture]
123         public class CryptoStreamTest : Assertion {
124
125                 Stream readStream;
126                 Stream writeStream;
127                 ICryptoTransform encryptor;
128                 ICryptoTransform decryptor;
129                 CryptoStream cs;
130                 SymmetricAlgorithm aes;
131
132                 [SetUp]
133                 public void SetUp () 
134                 {
135                         if (readStream == null) {
136                                 readStream = new FileStream ("read", FileMode.OpenOrCreate, FileAccess.Read);
137                                 writeStream = new FileStream ("write", FileMode.OpenOrCreate, FileAccess.Write);
138                                 aes = SymmetricAlgorithm.Create ();
139                                 encryptor = aes.CreateEncryptor ();
140                                 decryptor = aes.CreateEncryptor ();
141                         }
142                 }
143
144                 [TearDown]
145                 public void TearDown () 
146                 {
147                         try {
148                                 if (File.Exists ("read"))
149                                         File.Delete ("read");
150                                 if (File.Exists ("write"))
151                                         File.Delete ("write");
152                         }
153                         catch {}
154                 }
155
156                 public void AssertEquals (string msg, byte[] array1, byte[] array2)
157                 {
158                         AllTests.AssertEquals (msg, array1, array2);
159                 }
160
161                 [Test]
162                 [ExpectedException (typeof (NullReferenceException))]
163                 public void StreamNull ()
164                 {
165                         cs = new CryptoStream (null, encryptor, CryptoStreamMode.Read);
166                 }
167
168                 [Test]
169                 [ExpectedException (typeof (NullReferenceException))]
170                 public void TransformNull ()
171                 {
172                         MemoryStream write = new MemoryStream (8);
173                         byte[] data = {0, 1, 2, 3, 4, 5, 6, 7};
174                         cs = new CryptoStream (write, null, CryptoStreamMode.Write);
175                         cs.Write (data, 0, 8);
176                 }
177
178                 [Test]
179                 public void StreamReadModeRead () 
180                 {
181                         cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
182                         Assert ("Read.CanRead", cs.CanRead);
183                         Assert ("Read.CanWrite", !cs.CanWrite);
184                         Assert ("Read.CanSeek", !cs.CanSeek);
185                 }
186
187                 [Test]
188                 [ExpectedException (typeof (ArgumentException))]
189                 public void StreamReadModeWrite () 
190                 {
191                         cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Write);
192                 }
193
194                 [Test]
195                 [ExpectedException (typeof (ArgumentException))]
196                 public void StreamWriteModeRead () 
197                 {
198                         cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Read);
199                 }
200
201                 [Test]
202                 public void StreamWriteModeWrite () 
203                 {
204                         cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
205                         Assert ("Read.CanRead", !cs.CanRead);
206                         Assert ("Read.CanWrite", cs.CanWrite);
207                         Assert ("Read.CanSeek", !cs.CanSeek);
208                 }
209
210                 [Test]
211                 [ExpectedException (typeof (NotSupportedException))]
212                 public void GetLength () 
213                 {
214                         cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
215                         long x = cs.Length;
216                 }
217
218                 [Test]
219                 [ExpectedException (typeof (NotSupportedException))]
220                 public void GetPosition () 
221                 {
222                         cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
223                         long x = cs.Position;
224                 }
225
226                 [Test]
227                 [ExpectedException (typeof (NotSupportedException))]
228                 public void SetPosition () 
229                 {
230                         cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
231                         cs.Position = 1;
232                 }
233
234                 [Test]
235                 [ExpectedException (typeof (NotSupportedException))]
236                 public void Seek () 
237                 {
238                         cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
239                         cs.Seek (0, SeekOrigin.Begin);
240                 }
241
242                 [Test]
243                 [ExpectedException (typeof (NotSupportedException))]
244                 public void SetLength () 
245                 {
246                         cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
247                         cs.SetLength (0);
248                 }
249
250                 [Test]
251                 // LAMESPEC : [ExpectedException (typeof (NotSupportedException))]
252                 public void FlushReadStream () 
253                 {
254                         cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
255                         cs.Flush ();
256                 }
257
258                 [Test]
259                 [ExpectedException (typeof (NotSupportedException))]
260                 public void FlushFinalBlockReadStream () 
261                 {
262                         cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
263                         cs.FlushFinalBlock ();
264                 }
265
266                 [Test]
267                 [ExpectedException (typeof (NotSupportedException))]
268                 public void FlushFinalBlock_Dual () 
269                 {
270                         byte[] data = {0, 1, 2, 3, 4, 5, 6, 7};
271                         cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
272                         cs.Write (data, 0, data.Length);
273                         cs.FlushFinalBlock ();
274                         cs.FlushFinalBlock ();
275                 }
276
277                 [Test]
278                 // LAMESPEC or MS BUG [ExpectedException (typeof (ObjectDisposedException))]
279                 [ExpectedException (typeof (ArgumentNullException))]
280                 public void FlushFinalBlock_Disposed () 
281                 {
282                         cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
283                         cs.Clear ();
284                         cs.FlushFinalBlock ();
285                 }
286
287                 [Test]
288                 // LAMESPEC or MS BUG [ExpectedException (typeof (ObjectDisposedException))]
289                 [ExpectedException (typeof (ArgumentNullException))]
290                 public void Read_Disposed () 
291                 {
292                         byte[] buffer = new byte [8];
293                         cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
294                         cs.Clear ();
295                         cs.Read (buffer, 0, 8);
296                 }
297
298                 [Test]
299                 // MS BUG [ExpectedException (typeof (ObjectDisposedException))]
300                 [Ignore ("Test cause System.ExecutionEngineException on MS runtime")]
301                 public void Read_Disposed_Break () 
302                 {
303                         byte[] buffer = new byte [8];
304                         cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
305                         int len = cs.Read (buffer, 0, 4);
306                         AssertEquals ("Read 4", 4, len);
307                         cs.Clear ();
308                         len = cs.Read (buffer, 3, 4);
309                 }
310
311                 [Test]
312                 [ExpectedException (typeof (NotSupportedException))]
313                 public void Read_WriteStream () 
314                 {
315                         cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
316                         byte[] buffer = new byte [8];
317                         cs.Read (buffer, 0, 8);
318                 }
319
320                 [Test]
321                 // [ExpectedException (typeof (ArgumentNullException))]
322                 [ExpectedException (typeof (NullReferenceException))]
323                 public void Read_NullBuffer () 
324                 {
325                         cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
326                         cs.Read (null, 0, 8);
327                 }
328
329                 [Test]
330                 public void Read_EmptyBuffer_ZeroCount () 
331                 {
332                         byte[] buffer = new byte [0];
333                         cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
334                         int len = cs.Read (buffer, 0, 0);
335                         AssertEquals ("Read 0", 0, len);
336                 }
337
338                 [Test]
339                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
340                 public void Read_NegativeOffset () 
341                 {
342                         byte[] buffer = new byte [8];
343                         cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
344                         cs.Read (buffer, -1, 8);
345                 }
346
347                 [Test]
348                 public void Read_ZeroCount () 
349                 {
350                         byte[] buffer = new byte [8];
351                         cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
352                         int len = cs.Read (buffer, 0, 0);
353                         AssertEquals ("Read 0", 0, len);
354                 }
355
356                 [Test]
357                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
358                 public void Read_NegativeCount () 
359                 {
360                         byte[] buffer = new byte [8];
361                         cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
362                         cs.Read (buffer, 0, -1);
363                 }
364
365                 [Test]
366                 [ExpectedException (typeof (ArgumentException))]
367                 public void Read_OverflowCount () 
368                 {
369                         byte[] buffer = new byte [8];
370                         cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
371                         cs.Read (buffer, 0, Int32.MaxValue);
372                 }
373
374                 [Test]
375                 [ExpectedException (typeof (ArgumentException))]
376                 public void Read_InvalidOffset () 
377                 {
378                         byte[] buffer = new byte [8];
379                         cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
380                         cs.Read (buffer, 5, 4);
381                 }
382
383                 [Test]
384                 [ExpectedException (typeof (ArgumentException))]
385                 public void Read_OverflowOffset () 
386                 {
387                         byte[] buffer = new byte [8];
388                         cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
389                         cs.Read (buffer, Int32.MaxValue, 4);
390                 }
391
392                 [Test]
393                 // MS BUG [ExpectedException (typeof (ObjectDisposedException))]
394                 [Ignore ("Test cause System.ExecutionEngineException on MS runtime")]
395                 public void Write_Disposed () 
396                 {
397                         byte[] buffer = new byte [8];
398                         cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
399                         cs.Clear ();
400                         cs.Write (buffer, 0, 8);
401                 }
402
403                 [Test]
404                 [ExpectedException (typeof (NotSupportedException))]
405                 public void Write_ReadStream () 
406                 {
407                         cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
408                         byte[] buffer = new byte [8];
409                         cs.Write (buffer, 0, 8);
410                 }
411
412                 [Test]
413                 // [ExpectedException (typeof (ArgumentNullException))]
414                 [ExpectedException (typeof (NullReferenceException))]
415                 public void Write_NullBuffer () 
416                 {
417                         cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
418                         cs.Write (null, 0, 8);
419                 }
420
421                 [Test]
422                 public void Write_EmptyBuffer_ZeroCount () 
423                 {
424                         byte[] buffer = new byte [0];
425                         cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
426                         cs.Write (buffer, 0, 0);
427                 }
428
429                 [Test]
430                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
431                 public void Write_NegativeOffset () 
432                 {
433                         byte[] buffer = new byte [8];
434                         cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
435                         cs.Write (buffer, -1, 8);
436                 }
437
438                 [Test]
439                 [ExpectedException (typeof (ArgumentException))]
440                 public void Write_OverflowOffset () 
441                 {
442                         byte[] buffer = new byte [8];
443                         cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
444                         cs.Write (buffer, Int32.MaxValue, 8);
445                 }
446
447                 [Test]
448                 public void Write_ZeroCount () 
449                 {
450                         byte[] buffer = new byte [8];
451                         cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
452                         cs.Write (buffer, 0, 0);
453                 }
454
455                 [Test]
456                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
457                 public void Write_NegativeCount () 
458                 {
459                         byte[] buffer = new byte [8];
460                         cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
461                         cs.Write (buffer, 0, -1);
462                 }
463
464                 [Test]
465                 [ExpectedException (typeof (ArgumentException))]
466                 public void Write_InvalidOffset () 
467                 {
468                         byte[] buffer = new byte [8];
469                         cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
470                         cs.Write (buffer, 5, 4);
471                 }
472
473                 [Test]
474                 [ExpectedException (typeof (ArgumentException))]
475                 public void Write_OverflowCount () 
476                 {
477                         byte[] buffer = new byte [8];
478                         cs = new CryptoStream (writeStream, encryptor, CryptoStreamMode.Write);
479                         cs.Write (buffer, 0, Int32.MaxValue);
480                 }
481
482                 [Test]
483                 public void FullRoundtripRead () 
484                 {
485                         byte[] encrypted;
486                         using (DebugStream mem1 = new DebugStream ()) {
487                                 byte[] toEncrypt = Encoding.Unicode.GetBytes ("Please encode me!");
488                                 using (CryptoStream crypt = new CryptoStream (mem1, aes.CreateEncryptor (), CryptoStreamMode.Write)) {
489                                         crypt.Write (toEncrypt, 0, toEncrypt.Length);
490                                         crypt.FlushFinalBlock ();
491                                 }
492                                 encrypted = mem1.ToArray ();
493                         }
494                                         
495                         using (DebugStream mem2 = new DebugStream (encrypted)) {
496                                 byte[] buffer = new byte [1024];
497                                 CryptoStream cr = new CryptoStream (mem2, aes.CreateDecryptor (), CryptoStreamMode.Read);
498                                 int len = cr.Read (buffer, 0, buffer.Length);
499                                 cr.Close ();
500                                 AssertEquals ("Full Length Read", 34, len);
501                                 AssertEquals ("Full Block Read", "Please encode me!", Encoding.Unicode.GetString (buffer, 0, len));
502                         }
503                 }
504
505                 // bugzilla 46143 (adapted from test case by Joerg Rosenkranz)
506                 [Test]
507                 public void PartialRoundtripRead () 
508                 {
509                         byte[] encrypted;
510                         using (DebugStream mem1 = new DebugStream ()) {
511                                 byte[] toEncrypt = Encoding.Unicode.GetBytes ("Please encode me!");
512                                 using (CryptoStream crypt = new CryptoStream (mem1, aes.CreateEncryptor (), CryptoStreamMode.Write)) {
513                                         crypt.Write (toEncrypt, 0, toEncrypt.Length);
514                                         crypt.FlushFinalBlock ();
515                                 }
516                                 encrypted = mem1.ToArray ();
517                         }
518                                         
519                         using (DebugStream mem2 = new DebugStream (encrypted)) {
520                                 byte[] buffer = new byte [1024];
521                                 CryptoStream cr = new CryptoStream (mem2, aes.CreateDecryptor (), CryptoStreamMode.Read);
522                                 int len = cr.Read (buffer, 0, 20);
523                                 cr.Clear ();
524                                 cr.Close ();
525                                 AssertEquals ("Partial Length Read", 20, len);
526                                 AssertEquals ("Partial Block Read", "Please enc", Encoding.Unicode.GetString (buffer, 0, len));
527                         }
528                 }
529
530                 // bugzilla: 40689 (adapted from test case by Henning Westerholt)
531                 [Test]
532                 public void WriteOnBlockWithFinal () 
533                 {
534                         byte[] desKey = {0, 1, 2, 3, 4, 5, 6, 7};
535                         byte[] desIV = {0, 1, 2, 3, 4, 5, 6, 7};
536                         DES des = DES.Create ();
537
538                         MemoryStream msin = new MemoryStream ();
539                         CryptoStream enc = new CryptoStream (msin, des.CreateEncryptor (desKey, desIV), CryptoStreamMode.Write);
540                         byte[] data = new byte [2200];
541                         enc.Write (data, 0, 2200);
542                         enc.FlushFinalBlock ();
543                         msin.Position = 0;
544                         AssertEquals ("Encryped Write Length", 2208, msin.Length); // 2200 + padding
545
546                         MemoryStream msout = new MemoryStream ();
547                         msout.SetLength (0);
548
549                         byte[] tmp = new byte [1024];
550                         long readlen = 0;
551                         long totallen = msin.Length;
552
553                         CryptoStream dec = new CryptoStream (msout, des.CreateDecryptor (desKey, desIV), CryptoStreamMode.Write);
554                         int len = msin.Read (tmp, 0, 1024);
555                         while (len > 0) {
556                                 dec.Write (tmp, 0, len);
557                                 readlen += len;
558                                 len = msin.Read (tmp, 0, 1024);
559                         }
560                         AssertEquals ("Decryped Write Length", 2200, msout.Length);
561
562                         dec.Close ();
563                         dec.Clear ();
564                         msout.Close ();
565                         msin.Close ();
566
567                         AssertEquals ("Read Length", 2208, readlen); // 2200 + padding
568                 }
569
570                 [Test]
571                 public void PreGeneratedStreams ()
572                 {
573                         byte[] desKey = {0, 1, 2, 3, 4, 5, 6, 7};
574                         byte[] desIV = {0, 1, 2, 3, 4, 5, 6, 7};
575                         DES des = DES.Create ();
576         
577                         for (int i=0; i < 9; i++) {
578                                 MemoryStream msin = new MemoryStream ();
579                                 CryptoStream enc = new CryptoStream (msin, des.CreateEncryptor (desKey, desIV), CryptoStreamMode.Write);
580                                 byte[] data = new byte [i];
581                                 enc.Write (data, 0, i);
582                                 enc.FlushFinalBlock ();
583
584                                 string msg = "PreGeneratedStream #" + i;
585                                 string result = BitConverter.ToString (msin.ToArray ());
586                                 switch (i) {
587                                         case 0:
588                                                 AssertEquals (msg, "92-C9-DB-45-30-0B-93-2F", result); 
589                                                 break;
590                                         case 1:
591                                                 AssertEquals (msg, "08-CF-A1-37-BD-56-D0-65", result); 
592                                                 break;
593                                         case 2:
594                                                 AssertEquals (msg, "58-87-D4-9B-2C-27-97-0C", result); 
595                                                 break;
596                                         case 3:
597                                                 AssertEquals (msg, "07-35-90-94-68-7D-51-FB", result); 
598                                                 break;
599                                         case 4:
600                                                 AssertEquals (msg, "BF-00-98-C5-20-71-D0-DB", result); 
601                                                 break;
602                                         case 5:
603                                                 AssertEquals (msg, "1A-55-C8-6E-C1-9B-31-82", result); 
604                                                 break;
605                                         case 6:
606                                                 AssertEquals (msg, "2D-2B-76-41-61-0E-00-0C", result); 
607                                                 break;
608                                         case 7:
609                                                 AssertEquals (msg, "DC-FF-73-D2-7F-D7-48-5D", result); 
610                                                 break;
611                                         case 8:
612                                                 AssertEquals (msg, "E1-B2-46-E5-A7-C7-4C-BC-0E-40-4A-FC-08-92-B1-EB", result); 
613                                                 break;
614                                 }
615                         }
616                 }
617
618                 private byte[] EmptyStream (PaddingMode mode) 
619                 {
620                         SymmetricAlgorithm algo = Rijndael.Create ();
621                         algo.Key = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };
622                         algo.IV = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };
623                         algo.Padding = mode;
624                         MemoryStream ms = new MemoryStream ();
625                         CryptoStream cs = new CryptoStream (ms, algo.CreateEncryptor(), CryptoStreamMode.Write);
626                         cs.Write (ms.GetBuffer (), 0, (int) ms.Length);
627                         cs.FlushFinalBlock ();
628                         cs.Flush ();
629                         return ms.ToArray ();
630                 }
631
632                 [Test]
633                 public void EmptyStreamWithPaddingNone () 
634                 {
635                         byte[] result = EmptyStream (PaddingMode.None);
636                         AssertEquals ("Result Length", 0, result.Length);
637                 }
638
639                 [Test]
640                 public void EmptyStreamWithPaddingPKCS7 () 
641                 {
642                         byte[] expected = { 0x07, 0xFE, 0xEF, 0x74, 0xE1, 0xD5, 0x03, 0x6E, 0x90, 0x0E, 0xEE, 0x11, 0x8E, 0x94, 0x92, 0x93 };
643                         byte[] result = EmptyStream (PaddingMode.PKCS7);
644                         AssertEquals ("Result Length", 16, result.Length);
645                         AssertEquals ("Result", expected, result);
646                 }
647
648                 [Test]
649                 public void EmptyStreamWithPaddingZeros () 
650                 {
651                         byte[] result = EmptyStream (PaddingMode.Zeros);
652                         AssertEquals ("Result Length", 0, result.Length);
653                 }
654
655                 // bugzilla: 49323 (adapted from test case by Carlos Guzmán Álvarez)
656                 [Test]
657                 public void MultiblocksWithPartial () 
658                 {
659                         SymmetricAlgorithm tdes = new TripleDESCryptoServiceProvider ();
660                         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};
661                         tdes.IV = new byte[] {193, 227, 54, 132, 68, 172, 55, 91};
662
663                         byte[] fragment = new byte[] {20, 0, 0, 12, 181, 134, 8, 230, 185, 75, 19, 129, 101, 142, 118, 190};
664                         byte[] mac = new byte[] {42, 148, 229, 58, 185, 249, 154, 131, 157, 79, 176, 168, 143, 71, 0, 118, 5, 10, 95, 8};
665                                                                                                                                                                                                   
666                         // Encryption ( fragment + mac [+ padding + padding_length] )
667                         MemoryStream ms = new MemoryStream ();
668                         CryptoStream cs = new CryptoStream (ms, tdes.CreateEncryptor (), CryptoStreamMode.Write);
669                         cs.Write (fragment, 0, fragment.Length);
670                         cs.Write (mac, 0, mac.Length);
671                         // Calculate padding_length
672                         int fragmentLength = fragment.Length + mac.Length + 1;
673                         int padding = (((fragmentLength / 8) * 8) + 8) - fragmentLength;
674                         // Write padding length byte
675                         cs.WriteByte ((byte)padding);
676                         cs.Close ();
677                         byte[] encrypted = ms.ToArray ();
678                         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 };
679                         AssertEquals ("MultiblocksWithPartial", expected, encrypted);
680                 }
681
682                 // Adapted from Subba Rao Thirumoorthy email on mono-devel-list (december 2003)
683                 private byte[] NonMultipleOfBlockSize_Encrypt (ICryptoTransform ct, byte[] data)
684                 {
685                         DebugStream stream = new DebugStream ();
686                         CryptoStream CryptStream = new CryptoStream (stream, ct, CryptoStreamMode.Write);
687
688                         int len = 0;
689                         long myLength = 0;
690                         byte[] Buffer = new byte [1024];
691                         
692                         DebugStream fout = new DebugStream (data);
693                         while (myLength < data.Length) {
694                                 len = fout.Read (Buffer, 0, 1023);
695                                 if (len == 0)
696                                         break;
697                                 CryptStream.Write (Buffer, 0, len);
698                                 CryptStream.Flush ();
699                                 myLength = myLength + len;
700                         }
701                         CryptStream.FlushFinalBlock ();
702                         // we must ensure that the result is correct
703                         AssertEquals ("Length(final)", 64, len);
704                         byte[] result = stream.ToArray ();
705                         string end = BitConverter.ToString (result, 65520, 16);
706                         AssertEquals ("End part", "04-70-19-1D-28-C5-BD-9A-23-C6-60-E2-28-96-38-65", end);
707
708                         CryptStream.Close();
709                         stream.Close();
710                         return result;
711                 }
712
713                 private byte[] NonMultipleOfBlockSize_Decrypt (ICryptoTransform ct, byte[] data) 
714                 {
715                         DebugStream stream = new DebugStream (data);
716                         CryptoStream CryptStream = new CryptoStream (stream, ct, CryptoStreamMode.Read);
717
718                         int len = 0;
719                         long myLength = 0;
720                         byte[] Buffer = new Byte [1024];
721
722                         DebugStream fout = new DebugStream ();
723                         // each returned block must be 1023 bytes long 
724                         // even if this isn't a multiple of the block size
725                         while ((len = CryptStream.Read (Buffer, 0, 1023)) != 0) {
726                                 fout.Write (Buffer, 0, len);
727                                 fout.Flush ();
728                                 myLength = myLength + len;
729                         }
730
731                         byte[] result = fout.ToArray ();
732                         CryptStream.Close ();
733                         stream.Close ();
734                         return result;
735                 }
736
737                 [Test]
738                 public void NonMultipleOfBlockSize ()
739                 {
740                         byte[] key = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
741                         byte[] iv  = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
742                         byte[] data = new byte [65536];
743
744                         RijndaelManaged aes = new RijndaelManaged ();
745                         ICryptoTransform encryptor = aes.CreateEncryptor (key, iv);
746                         byte[] encdata = NonMultipleOfBlockSize_Encrypt (encryptor, data);
747                         AssertEquals ("Encrypted Data Length", (data.Length + (aes.BlockSize >> 3)), encdata.Length);
748                         
749                         ICryptoTransform decryptor = aes.CreateDecryptor (key, iv);
750                         byte[] decdata = NonMultipleOfBlockSize_Decrypt (decryptor, encdata);
751                         AssertEquals ("Decrypted Data Length", data.Length, decdata.Length);
752
753                         int i = 0;
754                         bool b = true;
755                         while (b && (i < data.Length)) {
756                                 b = (data [i] == decdata [i]);
757                                 i++;
758                         }
759                         Assert ("NonMultipleOfBlockSize", b);
760                 }
761
762                 // bugzilla: 51322 - indirectly related but it explains why my first (unapplied) patch didn't work
763                 [Test]
764                 public void DecryptPartial_TransformFinalBlock_required () 
765                 {
766                         byte[] key = {0, 1, 2, 3, 4, 5, 6, 7};
767                         byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7};
768                         DES des = DES.Create ();
769
770                         byte[] data = Encoding.Unicode.GetBytes ("ximian");     // 12 bytes, 1.5 DES block size
771                         DebugStream encrypted = new DebugStream ();
772                         cs = new CryptoStream (encrypted, des.CreateEncryptor (key, iv), CryptoStreamMode.Write);
773                         cs.Write (data, 0, data.Length);
774                         cs.Close ();
775
776                         data = encrypted.ToArray ();
777                         DebugStream decrypted = new DebugStream (data);
778                         cs = new CryptoStream (decrypted, des.CreateDecryptor (key, iv), CryptoStreamMode.Read);
779                         int len = cs.Read (data, 0, data.Length);
780                         cs.Close ();
781                         AssertEquals ("Length", 12, len);
782                         AssertEquals ("Unicode DES Roundtrip", "ximian", Encoding.Unicode.GetString (data, 0, len));
783                 }
784
785                 [Test]
786                 public void DecryptPartial_TransformFinalBlock_2Pass () 
787                 {
788                         byte[] key = {0, 1, 2, 3, 4, 5, 6, 7};
789                         byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7};
790                         DES des = DES.Create ();
791
792                         byte[] data = Encoding.Unicode.GetBytes ("ximian");     // 12 bytes, 1.5 DES block size
793                         DebugStream encrypted = new DebugStream ();
794                         cs = new CryptoStream (encrypted, des.CreateEncryptor (key, iv), CryptoStreamMode.Write);
795                         cs.Write (data, 0, data.Length);
796                         cs.Close ();
797
798                         data = encrypted.ToArray ();
799                         DebugStream decrypted = new DebugStream (data);
800                         cs = new CryptoStream (decrypted, des.CreateDecryptor (key, iv), CryptoStreamMode.Read);
801                         int len = cs.Read (data, 0, 6);
802                         AssertEquals ("Length (1st pass)", 6, len);
803                         AssertEquals ("Partial DES Roundtrip", "xim", Encoding.Unicode.GetString (data, 0, len));
804                         len += cs.Read (data, 6, 8);
805                         AssertEquals ("Length (1st+2nd)", 12, len);
806                         AssertEquals ("Full DES Roundtrip", "ximian", Encoding.Unicode.GetString (data, 0, len));
807                         cs.Close ();
808                 }
809
810                 // based on http://www.c-sharpcorner.com/Code/2002/May/FileEncryption.asp
811                 [Test]
812                 public void WriteByteReadByte () 
813                 {
814                         DebugStream original = new DebugStream (Encoding.Unicode.GetBytes ("ximian"));
815
816                         DebugStream encrypted = new DebugStream ();
817                         byte[] key = {0, 1, 2, 3, 4, 5, 6, 7};
818                         byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7};
819                         DES des = DES.Create ();
820                         cs = new CryptoStream (encrypted, des.CreateEncryptor (key, iv), CryptoStreamMode.Write);
821
822                         int data;
823                         while ((data = original.ReadByte ()) != -1)
824                                 cs.WriteByte((byte) data);
825                         cs.Close ();
826
827                         byte[] result = encrypted.ToArray ();
828                         AssertEquals ("Encrypted", "18-EA-93-3F-20-86-D2-AA-78-02-D7-6F-E4-47-17-9C", BitConverter.ToString (result));
829
830                         encrypted = new DebugStream (result);
831                         DebugStream decrypted = new DebugStream ();
832                         cs = new CryptoStream (encrypted, des.CreateDecryptor (key, iv), CryptoStreamMode.Read);
833
834                         while ((data = cs.ReadByte ()) != -1)
835                                 decrypted.WriteByte((byte) data);
836                         cs.Close ();
837                         decrypted.Close ();
838
839                         AssertEquals ("W/R Byte Roundtrip", "ximian", Encoding.Unicode.GetString (decrypted.ToArray ()));
840                 }
841
842                 // based http://www.4guysfromrolla.com/webtech/090501-1.shtml
843
844                 public string EncryptData (ICryptoTransform des, string strData) 
845                 {
846                         strData = String.Format("{0,5:00000}" + strData, strData.Length);
847                         byte[] data = Encoding.ASCII.GetBytes (strData);
848
849                         MemoryStream mStream = new MemoryStream (data); 
850                         CryptoStream cs = new CryptoStream (mStream, des, CryptoStreamMode.Read);        
851                         MemoryStream mOut = new MemoryStream ();
852         
853                         int bytesRead; 
854                         byte[] output = new byte [1024]; 
855                         do { 
856                                 bytesRead = cs.Read (output, 0, 1024);
857                                 if (bytesRead != 0) 
858                                         mOut.Write (output, 0, bytesRead); 
859                         } 
860                         while (bytesRead > 0); 
861         
862                         return Convert.ToBase64String (mOut.ToArray ());
863                 }
864
865                 public string DecryptData (ICryptoTransform des, string strData) 
866                 {
867                         MemoryStream mOut = new MemoryStream ();
868                         byte[] data = Convert.FromBase64String (strData);
869                         CryptoStream cs = new CryptoStream (mOut, des, CryptoStreamMode.Write);        
870                         cs.Write (data, 0, (int)data.Length);
871                         cs.FlushFinalBlock ();
872                         return Encoding.ASCII.GetString (mOut.ToArray ()).Substring (5);
873                 }
874
875                 [Test]
876                 public void EncryptOnRead () 
877                 {
878                         SHA1 sha = SHA1.Create ();
879                         byte[] vector = sha.ComputeHash (Encoding.ASCII.GetBytes ("s3kr3t"));
880                         byte[] key = new byte [8];
881                         Buffer.BlockCopy (vector, 0, key, 0, key.Length);
882                         byte[] iv = new byte [8];
883                         Buffer.BlockCopy (vector, 8, iv, 0, iv.Length);
884
885                         DES des = DES.Create ();
886
887                         StringBuilder sb = new StringBuilder ();
888                         sb.Append ("a");
889                         string data = sb.ToString ();
890                         string encdata = EncryptData (des.CreateEncryptor (key, iv), data);
891                         string decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
892                         AssertEquals ("Encrypt-" + data, "9YVfvrh5yj0=", encdata);
893                         AssertEquals ("Decrypt-" + data, data, decdata);
894
895                         sb.Append ("a");
896                         data = sb.ToString ();
897                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
898                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
899                         AssertEquals ("Encrypt-" + data, "qNe4d0UlkU8=", encdata);
900                         AssertEquals ("Decrypt-" + data, data, decdata);
901
902                         sb.Append ("a");
903                         data = sb.ToString ();
904                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
905                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
906                         AssertEquals ("Encrypt-" + data, "OcernYAQ1NAME/Gny+ZuaA==", encdata);
907                         AssertEquals ("Decrypt-" + data, data, decdata);
908
909                         sb.Append ("a");
910                         data = sb.ToString ();
911                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
912                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
913                         AssertEquals ("Encrypt-" + data, "H5UveR2lds1T+IWN4pks2Q==", encdata);
914                         AssertEquals ("Decrypt-" + data, data, decdata);
915
916                         sb.Append ("a");
917                         data = sb.ToString ();
918                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
919                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
920                         AssertEquals ("Encrypt-" + data, "dDQ3HAVtTbiRwwUqWANaeA==", encdata);
921                         AssertEquals ("Decrypt-" + data, data, decdata);
922
923                         sb.Append ("a");
924                         data = sb.ToString ();
925                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
926                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
927                         AssertEquals ("Encrypt-" + data, "At1r7dVDjJlQidf4QzCNkw==", encdata);
928                         AssertEquals ("Decrypt-" + data, data, decdata);
929
930                         sb.Append ("a");
931                         data = sb.ToString ();
932                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
933                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
934                         AssertEquals ("Encrypt-" + data, "DFDJWJGaNrFVBDXovsq1ew==", encdata);
935                         AssertEquals ("Decrypt-" + data, data, decdata);
936
937                         sb.Append ("a");
938                         data = sb.ToString ();
939                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
940                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
941                         AssertEquals ("Encrypt-" + data, "gM040QGMPOBj3u1lEK4XHQ==", encdata);
942                         AssertEquals ("Decrypt-" + data, data, decdata);
943
944                         sb.Append ("a");
945                         data = sb.ToString ();
946                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
947                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
948                         AssertEquals ("Encrypt-" + data, "P5hRUhrxOWFX0ER/IjJL/Q==", encdata);
949                         AssertEquals ("Decrypt-" + data, data, decdata);
950
951                         sb.Append ("a");
952                         data = sb.ToString ();
953                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
954                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
955                         AssertEquals ("Encrypt-" + data, "uDIaQ1uXtWUIboGFLt306Q==", encdata);
956                         AssertEquals ("Decrypt-" + data, data, decdata);
957
958                         sb.Append ("a");
959                         data = sb.ToString ();
960                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
961                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
962                         AssertEquals ("Encrypt-" + data, "giJKTXfad5Z8hebhXtYZ4hmKX/EC8w6x", encdata);
963                         AssertEquals ("Decrypt-" + data, data, decdata);
964
965                         sb.Append ("a");
966                         data = sb.ToString ();
967                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
968                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
969                         AssertEquals ("Encrypt-" + data, "lBehBplIrjjrlIrMjYcNz1DOoXLHjZdn", encdata);
970                         AssertEquals ("Decrypt-" + data, data, decdata);
971
972                         sb.Append ("a");
973                         data = sb.ToString ();
974                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
975                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
976                         AssertEquals ("Encrypt-" + data, "2elWrUnjmsAOpo2s4voJyZXEJ/rtKB7P", encdata);
977                         AssertEquals ("Decrypt-" + data, data, decdata);
978
979                         sb.Append ("a");
980                         data = sb.ToString ();
981                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
982                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
983                         AssertEquals ("Encrypt-" + data, "GB3BaIZGf9K+T82j7T8Fri2rQ2/YUdSe", encdata);
984                         AssertEquals ("Decrypt-" + data, data, decdata);
985
986                         sb.Append ("a");
987                         data = sb.ToString ();
988                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
989                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
990                         AssertEquals ("Encrypt-" + data, "Gc+wkJL+CVjdJchgcIoi8dkH2BVpHJgB", encdata);
991                         AssertEquals ("Decrypt-" + data, data, decdata);
992
993                         sb.Append ("a");
994                         data = sb.ToString ();
995                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
996                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
997                         AssertEquals ("Encrypt-" + data, "loeuyII/PvWb91M4pFVkyaPxQoQVYpNb", encdata);
998                         AssertEquals ("Decrypt-" + data, data, decdata);
999
1000                         sb.Append ("a");
1001                         data = sb.ToString ();
1002                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1003                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1004                         AssertEquals ("Encrypt-" + data, "PHXmi/sxNIgApXAfdm+Bf54/nCM//N8o", encdata);
1005                         AssertEquals ("Decrypt-" + data, data, decdata);
1006
1007                         sb.Append ("a");
1008                         data = sb.ToString ();
1009                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1010                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1011                         AssertEquals ("Encrypt-" + data, "xpb+wj/8LmH2ScTg3OU4JOsE5Owj6flF", encdata);
1012                         AssertEquals ("Decrypt-" + data, data, decdata);
1013
1014                         sb.Append ("a");
1015                         data = sb.ToString ();
1016                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1017                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1018                         AssertEquals ("Encrypt-" + data, "WJz4VfsZ2emzhYWoSf+PNBDpHooxEregqMWnzm4gcqU=", encdata);
1019                         AssertEquals ("Decrypt-" + data, data, decdata);
1020
1021                         sb.Append ("a");
1022                         data = sb.ToString ();
1023                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1024                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1025                         AssertEquals ("Encrypt-" + data, "PaouZu1iOKbCMRJSu04y/kB+TcOk4yp8K2BOGDs1PPE=", encdata);
1026                         AssertEquals ("Decrypt-" + data, data, decdata);
1027
1028                         sb.Append ("a");
1029                         data = sb.ToString ();
1030                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1031                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1032                         AssertEquals ("Encrypt-" + data, "qbTDs4dFy7eERdn5vV7JRPk2/m9smtwvZjA6+TmGlkI=", encdata);
1033                         AssertEquals ("Decrypt-" + data, data, decdata);
1034
1035                         sb.Append ("a");
1036                         data = sb.ToString ();
1037                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1038                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1039                         AssertEquals ("Encrypt-" + data, "f2FsphcpM7Fu90S5V17ptly44lL4GvFCCaFdnnU4twk=", encdata);
1040                         AssertEquals ("Decrypt-" + data, data, decdata);
1041
1042                         sb.Append ("a");
1043                         data = sb.ToString ();
1044                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1045                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1046                         AssertEquals ("Encrypt-" + data, "imD+ntHsUmp9ALJedzC1JmAJY0r2O4KkP8271+XuG4g=", encdata);
1047                         AssertEquals ("Decrypt-" + data, data, decdata);
1048
1049                         sb.Append ("a");
1050                         data = sb.ToString ();
1051                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1052                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1053                         AssertEquals ("Encrypt-" + data, "80QLLUmHwx1fcEYGeFz1WXlS13kUy994sQLI6GhcjuM=", encdata);
1054                         AssertEquals ("Decrypt-" + data, data, decdata);
1055
1056                         sb.Append ("a");
1057                         data = sb.ToString ();
1058                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1059                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1060                         AssertEquals ("Encrypt-" + data, "DtIIlj8BCOppmIgQ9AEdUj7pBB49S/9Q38kbWLjwiVs=", encdata);
1061                         AssertEquals ("Decrypt-" + data, data, decdata);
1062
1063                         sb.Append ("a");
1064                         data = sb.ToString ();
1065                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1066                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1067                         AssertEquals ("Encrypt-" + data, "LNkprYaaUFtyan204OzX+a2pzOb/Pg5WXzXJ6WWB1rQ=", encdata);
1068                         AssertEquals ("Decrypt-" + data, data, decdata);
1069
1070                         sb.Append ("a");
1071                         data = sb.ToString ();
1072                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1073                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1074                         AssertEquals ("Encrypt-" + data, "FRgx9m2lT2PxtYSIdRwc+SznJetNiRk1MEIZDl3D13pvo2yOtJ1MSQ==", encdata);
1075                         AssertEquals ("Decrypt-" + data, data, decdata);
1076
1077                         sb.Append ("a");
1078                         data = sb.ToString ();
1079                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1080                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1081                         AssertEquals ("Encrypt-" + data, "V7JlnpJscrdIpX4z5S+/Q5WDjKzK4aB5TiqI3JZOYJ+KE1CWQNNeow==", encdata);
1082                         AssertEquals ("Decrypt-" + data, data, decdata);
1083
1084                         sb.Append ("a");
1085                         data = sb.ToString ();
1086                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1087                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1088                         AssertEquals ("Encrypt-" + data, "wVwPv1c2KQynbwiOBCAhmQlReOQT52qFR34AX4dtjEeQ1oCQ1N1tHg==", encdata);
1089                         AssertEquals ("Decrypt-" + data, data, decdata);
1090
1091                         sb.Append ("a");
1092                         data = sb.ToString ();
1093                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1094                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1095                         AssertEquals ("Encrypt-" + data, "Zi+G0yfmuFjSjP455pjVeKBDDWB4qvTb0K0h20UtflrYG6wcWqUzDw==", encdata);
1096                         AssertEquals ("Decrypt-" + data, data, decdata);
1097
1098                         sb.Append ("a");
1099                         data = sb.ToString ();
1100                         encdata = EncryptData (des.CreateEncryptor (key, iv), data);
1101                         decdata = DecryptData (des.CreateDecryptor (key, iv), encdata);
1102                         AssertEquals ("Encrypt-" + data, "0hGoonZ8jrLhMNDKBuWrlvFnq15ZLvnyq+Ilq8r4aYUEDxttQMwi5w==", encdata);
1103                         AssertEquals ("Decrypt-" + data, data, decdata);
1104                 }
1105
1106                 // based on System.Security assembly XmlDsigBase64TransformTest
1107
1108                 [Test]
1109                 public void FromBase64_Write () 
1110                 {
1111                         string expected = "http://www.go-mono.com/";
1112                         byte[] data = Encoding.UTF8.GetBytes (expected);
1113                         string temp = Convert.ToBase64String (data, 0, data.Length);
1114                         data = Encoding.UTF8.GetBytes (temp);
1115
1116                         DebugStream debug = new DebugStream ();
1117                         ICryptoTransform base64 = new FromBase64Transform ();
1118                         cs = new CryptoStream (debug, base64, CryptoStreamMode.Write);
1119                         cs.Write (data, 0, data.Length);
1120                         cs.FlushFinalBlock ();
1121                         byte[] encoded = debug.ToArray ();
1122
1123                         string result = Encoding.UTF8.GetString (encoded);
1124                         AssertEquals ("FromBase64_Write", expected, result);
1125                 }
1126
1127                 [Test]
1128                 public void FromBase64_Read () 
1129                 {
1130                         byte[] original = Encoding.UTF8.GetBytes ("aHR0cDovL3d3dy5nby1tb25vLmNvbS8=");
1131                         DebugStream debug = new DebugStream (original);
1132
1133                         ICryptoTransform base64 = new FromBase64Transform ();
1134                         cs = new CryptoStream (debug, base64, CryptoStreamMode.Read);
1135                         
1136                         byte[] data = new byte [1024];
1137                         int length = cs.Read (data, 0, data.Length);
1138                         cs.Close ();
1139
1140                         string result = Encoding.UTF8.GetString (data, 0, length);
1141                         AssertEquals ("ToBase64_Read", "http://www.go-mono.com/", result);
1142                 }
1143
1144                 [Test]
1145                 public void ToBase64_Write () 
1146                 {
1147                         byte[] data = Encoding.UTF8.GetBytes ("http://www.go-mono.com/");
1148
1149                         DebugStream debug = new DebugStream ();
1150                         ICryptoTransform base64 = new ToBase64Transform ();
1151                         cs = new CryptoStream (debug, base64, CryptoStreamMode.Write);
1152                         cs.Write (data, 0, data.Length);
1153                         cs.FlushFinalBlock ();
1154                         byte[] encoded = debug.ToArray ();
1155
1156                         string result = Encoding.UTF8.GetString (encoded);
1157                         AssertEquals ("ToBase64_Write", "aHR0cDovL3d3dy5nby1tb25vLmNvbS8=", result);
1158                 }
1159
1160                 [Test]
1161                 public void ToBase64_Read () 
1162                 {
1163                         byte[] original = Encoding.UTF8.GetBytes ("http://www.go-mono.com/");
1164                         DebugStream debug = new DebugStream (original);
1165
1166                         ICryptoTransform base64 = new ToBase64Transform ();
1167                         cs = new CryptoStream (debug, base64, CryptoStreamMode.Read);
1168                         
1169                         byte[] data = new byte [1024];
1170                         int length = cs.Read (data, 0, data.Length);
1171                         cs.Close ();
1172
1173                         string result = Encoding.UTF8.GetString (data, 0, length);
1174                         AssertEquals ("ToBase64_Read", "aHR0cDovL3d3dy5nby1tb25vLmNvbS8=", result);
1175                 }
1176
1177                 // Cascaded CryptoStream - like sample in book .NET Framework Security, chapter 30
1178
1179                 [Test]
1180                 public void CascadedCryptoStream_Write () 
1181                 {
1182                         DebugStream debug = new DebugStream ();
1183
1184                         // calculate both the hash (before encryption) and encrypt in one Write operation
1185                         byte[] key = {0, 1, 2, 3, 4, 5, 6, 7};
1186                         byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7};
1187                         DES des = DES.Create ();
1188                         CryptoStream cse = new CryptoStream (debug, des.CreateEncryptor (key, iv), CryptoStreamMode.Write);
1189
1190                         MD5 hash = MD5.Create ();
1191                         CryptoStream csh = new CryptoStream (cse, hash, CryptoStreamMode.Write);
1192
1193                         byte[] data = Encoding.UTF8.GetBytes ("http://www.go-mono.com/");
1194                         csh.Write (data, 0, data.Length);
1195                         csh.FlushFinalBlock ();
1196
1197                         byte[] result = debug.ToArray ();
1198                         AssertEquals ("Encrypted", "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));
1199                         byte[] digest = hash.Hash;
1200                         AssertEquals ("Hash", "71-04-12-D1-95-01-CF-F9-8D-8F-F8-0D-F9-AA-11-7D", BitConverter.ToString (digest));
1201                 }
1202
1203                 [Test]
1204                 public void CascadedCryptoStream_Read () 
1205                 {
1206                         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 };
1207                         DebugStream debug = new DebugStream (encdata);
1208
1209                         // decrypt data and validate its hash in one Read operation
1210                         byte[] key = {0, 1, 2, 3, 4, 5, 6, 7};
1211                         byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7};
1212                         DES des = DES.Create ();
1213                         CryptoStream csd = new CryptoStream (debug, des.CreateDecryptor (key, iv), CryptoStreamMode.Read);
1214
1215                         MD5 hash = MD5.Create ();
1216                         CryptoStream csh = new CryptoStream (csd, hash, CryptoStreamMode.Read);
1217
1218                         byte[] data = new byte [1024];
1219                         int length = csh.Read (data, 0, data.Length);
1220                         csh.Close ();
1221                         
1222                         string result = Encoding.UTF8.GetString (data, 0, length);
1223                         AssertEquals ("Decrypted", "http://www.go-mono.com/", result);
1224                         byte[] digest = hash.Hash;
1225                         AssertEquals ("Hash Validation", "71-04-12-D1-95-01-CF-F9-8D-8F-F8-0D-F9-AA-11-7D", BitConverter.ToString (digest));
1226                 }
1227
1228                 // bugzilla: 60573 - the number of block is not reduced for encryptors
1229
1230                 [Test]
1231                 public void EncryptorWriteBlocks () 
1232                 {
1233                         DebugStream debug = new DebugStream ();
1234
1235                         byte[] key = {0, 1, 2, 3, 4, 5, 6, 7};
1236                         byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7};
1237                         DES des = DES.Create ();
1238                         CryptoStream cse = new CryptoStream (debug, des.CreateEncryptor (key, iv), CryptoStreamMode.Write);
1239
1240                         byte[] data = new byte [64];
1241                         cse.Write (data, 0, 64);
1242                         AssertEquals ("Length", 64, debug.Length);
1243                         cse.Close ();
1244                 }
1245
1246                 [Test]
1247                 public void DecryptorWriteBlocks () 
1248                 {
1249                         DebugStream debug = new DebugStream ();
1250
1251                         byte[] key = {0, 1, 2, 3, 4, 5, 6, 7};
1252                         byte[] iv = {0, 1, 2, 3, 4, 5, 6, 7};
1253                         DES des = DES.Create ();
1254                         CryptoStream csd = new CryptoStream (debug, des.CreateDecryptor (key, iv), CryptoStreamMode.Write);
1255
1256                         byte[] data = new byte [64];
1257                         csd.Write (data, 0, 64);
1258                         AssertEquals ("Length", 56, debug.Length);
1259                         // last block is kept for later processing
1260                         csd.Close ();
1261                 }
1262         }
1263 }