TimeZoneInfo.CreateLocal now handles environment variable TZ.
[mono.git] / mcs / class / corlib / Test / System.Security.Cryptography / HashAlgorithmTest.cs
1 //
2 // HashAlgorithmTest.cs - NUnit Test Cases for HashAlgorithm
3 //
4 // Author:
5 //      Sebastien Pouliot  <sebastien@ximian.com>
6 //
7 // (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
8 // Copyright (C) 2004, 2006, 2007 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 using NUnit.Framework;
31 using System;
32 using System.IO;
33 using System.Security.Cryptography;
34 using System.Text;
35
36 namespace MonoTests.System.Security.Cryptography {
37
38 // HashAlgorithm is a abstract class - so most of it's functionality wont
39 // be tested here (but will be in its descendants).
40
41 [TestFixture]
42 public class HashAlgorithmTest {
43
44         protected HashAlgorithm hash;
45
46         [SetUp]
47         public virtual void SetUp () 
48         {
49                 hash = HashAlgorithm.Create ();
50         }
51
52         // Note: These tests will only be valid without a "machine.config" file
53         // or a "machine.config" file that do not modify the default algorithm
54         // configuration.
55         private const string defaultSHA1 = "System.Security.Cryptography.SHA1CryptoServiceProvider";
56         private const string defaultMD5 = "System.Security.Cryptography.MD5CryptoServiceProvider";
57         private const string defaultSHA256 = "System.Security.Cryptography.SHA256Managed";
58         private const string defaultSHA384 = "System.Security.Cryptography.SHA384Managed";
59         private const string defaultSHA512 = "System.Security.Cryptography.SHA512Managed";
60         private const string defaultHash = defaultSHA1;
61
62         [Test]
63         public virtual void Create () 
64         {
65                 // try the default hash algorithm (created in SetUp)
66                 Assert.AreEqual (defaultHash, hash.ToString (), "HashAlgorithm.Create()");
67
68                 // try to build all hash algorithms
69                 hash = HashAlgorithm.Create ("SHA");
70                 Assert.AreEqual (defaultSHA1, hash.ToString (), "HashAlgorithm.Create('SHA')");
71                 hash = HashAlgorithm.Create ("SHA1");
72                 Assert.AreEqual (defaultSHA1, hash.ToString (), "HashAlgorithm.Create('SHA1')");
73                 hash = HashAlgorithm.Create ("System.Security.Cryptography.SHA1");
74                 Assert.AreEqual (defaultSHA1, hash.ToString (), "HashAlgorithm.Create('System.Security.Cryptography.SHA1')");
75                 hash = HashAlgorithm.Create ("System.Security.Cryptography.HashAlgorithm" );
76                 Assert.AreEqual (defaultHash, hash.ToString (), "HashAlgorithm.Create('System.Security.Cryptography.HashAlgorithm')");
77
78                 hash = HashAlgorithm.Create ("MD5");
79                 Assert.AreEqual (defaultMD5, hash.ToString (), "HashAlgorithm.Create('MD5')");
80                 hash = HashAlgorithm.Create ("System.Security.Cryptography.MD5");
81                 Assert.AreEqual (defaultMD5, hash.ToString (), "HashAlgorithm.Create('System.Security.Cryptography.MD5')");
82
83                 hash = HashAlgorithm.Create ("SHA256");
84                 Assert.AreEqual (defaultSHA256, hash.ToString (), "HashAlgorithm.Create('SHA256')");
85                 hash = HashAlgorithm.Create ("SHA-256");
86                 Assert.AreEqual (defaultSHA256, hash.ToString (), "HashAlgorithm.Create('SHA-256')");
87                 hash = HashAlgorithm.Create ("System.Security.Cryptography.SHA256");
88                 Assert.AreEqual (defaultSHA256, hash.ToString (), "HashAlgorithm.Create('System.Security.Cryptography.SHA256')");
89         
90                 hash = HashAlgorithm.Create ("SHA384");
91                 Assert.AreEqual (defaultSHA384, hash.ToString (), "HashAlgorithm.Create('SHA384')");
92                 hash = HashAlgorithm.Create ("SHA-384");
93                 Assert.AreEqual (defaultSHA384, hash.ToString (), "HashAlgorithm.Create('SHA-384')");
94                 hash = HashAlgorithm.Create ("System.Security.Cryptography.SHA384");
95                 Assert.AreEqual (defaultSHA384, hash.ToString (), "HashAlgorithm.Create('System.Security.Cryptography.SHA384')");
96         
97                 hash = HashAlgorithm.Create ("SHA512");
98                 Assert.AreEqual (defaultSHA512, hash.ToString (), "HashAlgorithm.Create('SHA512')");
99                 hash = HashAlgorithm.Create ("SHA-512");
100                 Assert.AreEqual (defaultSHA512, hash.ToString (), "HashAlgorithm.Create('SHA-512')");
101                 hash = HashAlgorithm.Create ("System.Security.Cryptography.SHA512");
102                 Assert.AreEqual (defaultSHA512, hash.ToString (), "HashAlgorithm.Create('System.Security.Cryptography.SHA512')");
103         
104                 // try to build invalid implementation
105                 hash = HashAlgorithm.Create ("InvalidHash");
106                 Assert.IsNull (hash, "HashAlgorithm.Create('InvalidHash')");
107         }
108
109         [Test]
110         [ExpectedException (typeof (ArgumentNullException))]
111         public virtual void CreateNull () 
112         {
113                 // try to build null implementation
114                 hash = HashAlgorithm.Create (null);
115         }
116
117         [Test]
118         [ExpectedException (typeof (ObjectDisposedException))]
119         public void Clear () 
120         {
121                 byte[] inputABC = Encoding.Default.GetBytes ("abc");
122                 hash.ComputeHash (inputABC);
123                 hash.Clear ();
124                 // cannot use a disposed object
125                 hash.ComputeHash (inputABC);
126         }
127
128         [Test]
129         [ExpectedException (typeof (ObjectDisposedException))]
130         public void Clear2 () 
131         {
132                 byte[] inputABC = Encoding.Default.GetBytes ("abc");
133                 MemoryStream ms = new MemoryStream (inputABC);
134                 hash.ComputeHash (ms);
135                 hash.Clear ();
136                 // cannot use a disposed object
137                 hash.ComputeHash (ms);
138         }
139
140         [Test]
141         [ExpectedException (typeof (ArgumentNullException))]
142         public void NullStream () 
143         {
144                 Stream s = null;
145                 hash.ComputeHash (s);
146         }
147
148         [Test]
149         public void Disposable () 
150         {
151                 using (HashAlgorithm hash = HashAlgorithm.Create ()) {
152                         hash.ComputeHash (new byte [0]);
153                 }
154         }
155
156         [Test]
157         [ExpectedException (typeof (ObjectDisposedException))]
158         public void InitializeDisposed () 
159         {
160                 hash.ComputeHash (new byte [0]);
161                 hash.Clear (); // disposed
162                 hash.Initialize ();
163                 hash.ComputeHash (new byte [0]);
164         }
165
166         [Test]
167         [ExpectedException (typeof (ArgumentNullException))]
168         public void ComputeHash_ArrayNull ()
169         {
170                 byte[] array = null;
171                 hash.ComputeHash (array);
172         }
173
174         [Test]
175         [ExpectedException (typeof (ArgumentNullException))]
176         public void ComputeHash_ArrayNullIntInt ()
177         {
178                 byte[] array = null;
179                 hash.ComputeHash (array, 0, 0);
180         }
181
182         [Test]
183         [ExpectedException (typeof (ArgumentOutOfRangeException))]
184         public void ComputeHash_OffsetNegative ()
185         {
186                 byte[] array = new byte [0];
187                 hash.ComputeHash (array, -1, 0);
188         }
189
190         [Test]
191         [ExpectedException (typeof (ArgumentException))]
192         public void ComputeHash_OffsetOverflow ()
193         {
194                 byte[] array = new byte [1];
195                 hash.ComputeHash (array, Int32.MaxValue, 1);
196         }
197
198         [Test]
199         [ExpectedException (typeof (ArgumentException))]
200         public void ComputeHash_CountNegative ()
201         {
202                 byte[] array = new byte [0];
203                 hash.ComputeHash (array, 0, -1);
204         }
205
206         [Test]
207         [ExpectedException (typeof (ArgumentException))]
208         public void ComputeHash_CountOverflow ()
209         {
210                 byte[] array = new byte [1];
211                 hash.ComputeHash (array, 1, Int32.MaxValue);
212         }
213
214         [Test]
215 // not checked in Fx 1.1
216 //      [ExpectedException (typeof (ObjectDisposedException))]
217         public void TransformBlock_Disposed () 
218         {
219                 hash.ComputeHash (new byte [0]);
220                 hash.Initialize ();
221                 byte[] input = new byte [8];
222                 byte[] output = new byte [8];
223                 hash.TransformBlock (input, 0, input.Length, output, 0);
224         }
225
226         [Test]
227         [ExpectedException (typeof (ArgumentNullException))]
228         public void TransformBlock_InputBuffer_Null ()
229         {
230                 byte[] output = new byte [8];
231                 hash.TransformBlock (null, 0, output.Length, output, 0);
232         }
233
234         [Test]
235         [ExpectedException (typeof (ArgumentOutOfRangeException))]
236         public void TransformBlock_InputOffset_Negative ()
237         {
238                 byte[] input = new byte [8];
239                 byte[] output = new byte [8];
240                 hash.TransformBlock (input, -1, input.Length, output, 0);
241         }
242
243         [Test]
244         [ExpectedException (typeof (ArgumentException))]
245         public void TransformBlock_InputOffset_Overflow ()
246         {
247                 byte[] input = new byte [8];
248                 byte[] output = new byte [8];
249                 hash.TransformBlock (input, Int32.MaxValue, input.Length, output, 0);
250         }
251
252         [Test]
253         [ExpectedException (typeof (ArgumentException))]
254         public void TransformBlock_InputCount_Negative ()
255         {
256                 byte[] input = new byte [8];
257                 byte[] output = new byte [8];
258                 hash.TransformBlock (input, 0, -1, output, 0);
259         }
260
261         [Test]
262         [ExpectedException (typeof (ArgumentException))]
263         public void TransformBlock_InputCount_Overflow ()
264         {
265                 byte[] input = new byte [8];
266                 byte[] output = new byte [8];
267                 hash.TransformBlock (input, 0, Int32.MaxValue, output, 0);
268         }
269
270         [Test]
271 #if ONLY_1_1
272         [Category ("NotDotNet")] // System.ExecutionEngineException on MS runtime (1.1)
273 #endif
274         public void TransformBlock_OutputBuffer_Null ()
275         {
276                 byte[] input = new byte [8];
277                 hash.TransformBlock (input, 0, input.Length, null, 0);
278         }
279
280         [Test]
281 #if NET_2_0
282         [ExpectedException (typeof (ArgumentOutOfRangeException))]
283 #else
284         [ExpectedException (typeof (IndexOutOfRangeException))]
285 #endif
286         public void TransformBlock_OutputOffset_Negative ()
287         {
288                 byte[] input = new byte [8];
289                 byte[] output = new byte [8];
290                 hash.TransformBlock (input, 0, input.Length, output, -1);
291         }
292
293         [Test]
294 #if NET_2_0
295         [ExpectedException (typeof (ArgumentException))]
296 #else
297         [ExpectedException (typeof (IndexOutOfRangeException))]
298 #endif
299         public void TransformBlock_OutputOffset_Overflow ()
300         {
301                 byte[] input = new byte [8];
302                 byte[] output = new byte [8];
303                 hash.TransformBlock (input, 0, input.Length, output, Int32.MaxValue);
304         }
305
306         [Test]
307 // not checked in Fx 1.1
308 //      [ExpectedException (typeof (ObjectDisposedException))]
309         public void TransformFinalBlock_Disposed () 
310         {
311                 hash.ComputeHash (new byte [0]);
312                 hash.Initialize ();
313                 byte[] input = new byte [8];
314                 hash.TransformFinalBlock (input, 0, input.Length);
315         }
316
317         [Test]
318         [ExpectedException (typeof (ArgumentNullException))]
319         public void TransformFinalBlock_InputBuffer_Null ()
320         {
321                 hash.TransformFinalBlock (null, 0, 8);
322         }
323
324         [Test]
325         [ExpectedException (typeof (ArgumentOutOfRangeException))]
326         public void TransformFinalBlock_InputOffset_Negative ()
327         {
328                 byte[] input = new byte [8];
329                 hash.TransformFinalBlock (input, -1, input.Length);
330         }
331
332         [Test]
333         [ExpectedException (typeof (ArgumentException))]
334         public void TransformFinalBlock_InputOffset_Overflow ()
335         {
336                 byte[] input = new byte [8];
337                 hash.TransformFinalBlock (input, Int32.MaxValue, input.Length);
338         }
339
340         [Test]
341         [ExpectedException (typeof (ArgumentException))]
342         public void TransformFinalBlock_InputCount_Negative ()
343         {
344                 byte[] input = new byte [8];
345                 hash.TransformFinalBlock (input, 0, -1);
346         }
347
348         [Test]
349         [ExpectedException (typeof (ArgumentException))]
350         public void TransformFinalBlock_InputCount_Overflow ()
351         {
352                 byte[] input = new byte [8];
353                 hash.TransformFinalBlock (input, 0, Int32.MaxValue);
354         }
355
356         public virtual bool ManagedHashImplementation {
357                 get { return false; }
358         }
359 #if !NET_2_1
360         [Test]
361         [Category ("NotWorking")] // Mono nevers throws an exception (and we're all managed ;-)
362         public void TransformFinalBlock_Twice ()
363         {
364                 bool exception = false;
365                 byte[] input = new byte [8];
366                 hash.TransformFinalBlock (input, 0, input.Length);
367                 try {
368                         hash.TransformFinalBlock (input, 0, input.Length);
369                 }
370                 catch (CryptographicException) {
371                         exception = true;
372                         if (ManagedHashImplementation)
373                                 Assert.Fail ("*Managed don't throw CryptographicException");
374                 }
375                 if (!ManagedHashImplementation && !exception)
376                         Assert.Fail ("Expected CryptographicException from non *Managed classes");
377         }
378
379         [Test]
380         [Category ("NotWorking")] // Mono nevers throws an exception (and we're all managed ;-)
381         public void TransformFinalBlock_TransformBlock ()
382         {
383                 bool exception = false;
384                 byte[] input = new byte[8];
385                 hash.TransformFinalBlock (input, 0, input.Length);
386                 try {
387                         hash.TransformBlock (input, 0, input.Length, input, 0);
388                 }
389                 catch (CryptographicException) {
390                         exception = true;
391                         if (ManagedHashImplementation)
392                                 Assert.Fail ("*Managed don't throw CryptographicException");
393                 }
394                 if (!ManagedHashImplementation && !exception)
395                         Assert.Fail ("Expected CryptographicException from non *Managed classes");
396         }
397 #endif
398         [Test]
399         public void TransformFinalBlock_Twice_Initialize ()
400         {
401                 byte[] input = new byte[8];
402                 hash.TransformFinalBlock (input, 0, input.Length);
403                 hash.Initialize ();
404                 hash.TransformFinalBlock (input, 0, input.Length);
405         }
406
407         [Test]
408         public void TransformFinalBlock_ReturnedBuffer ()
409         {
410                 byte[] input = new byte[8];
411                 byte[] output = hash.TransformFinalBlock (input, 0, input.Length);
412                 Assert.AreEqual (input, output, "buffer");
413                 output[0] = 1;
414                 Assert.AreEqual (0, input[0], "0"); // output is a copy (not a reference)
415         }
416
417         private byte[] HashBuffer (bool intersect)
418         {
419                 byte[] buffer = new byte [256];
420                 for (int i = 0; i < buffer.Length; i++)
421                         buffer [i] = (byte) i;
422
423                 hash.Initialize ();
424                 // ok
425                 hash.TransformBlock (buffer, 0, 64, buffer, 0);
426                 // bad - we rewrite the beginning of the buffer
427                 hash.TransformBlock (buffer, 64, 128, buffer, intersect ? 0 : 64);
428                 // ok
429                 hash.TransformFinalBlock (buffer, 192, 64);
430                 return hash.Hash;
431         }
432
433         [Test]
434         public void InputOutputIntersection ()
435         {
436                 Assert.AreEqual (HashBuffer (false), HashBuffer (true), "Intersect");
437         }
438 #if !NET_2_1
439         [Test]
440         [ExpectedException (typeof (NullReferenceException))]
441         [Category ("NotWorking")] // initialization problem ? fx2.0 only ?
442         public void Hash_AfterInitialize_FirstTime ()
443         {
444                 hash.Initialize ();
445                 // getting the property throws
446                 Assert.IsNull (hash.Hash);
447         }
448 #endif
449         [Test]
450         [ExpectedException (typeof (CryptographicUnexpectedOperationException))]
451         public void Hash_AfterInitialize_SecondTime ()
452         {
453                 byte[] input = new byte[8];
454                 hash.Initialize ();
455                 hash.TransformBlock (input, 0, input.Length, input, 0);
456                 hash.Initialize ();
457                 // getting the property throws
458                 Assert.IsNull (hash.Hash);
459         }
460
461         [Test]
462         [ExpectedException (typeof (CryptographicUnexpectedOperationException))]
463         public void Hash_AfterTransformBlock ()
464         {
465                 byte[] input = new byte[8];
466                 hash.Initialize ();
467                 hash.TransformBlock (input, 0, input.Length, input, 0);
468                 // getting the property throws
469                 Assert.IsNull (hash.Hash);
470         }
471
472         [Test]
473         public void Hash_AfterTransformFinalBlock ()
474         {
475                 byte[] input = new byte[8];
476                 hash.Initialize ();
477                 hash.TransformFinalBlock (input, 0, input.Length);
478                 Assert.IsNotNull (hash.Hash);
479         }
480 }
481
482 }