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