2 // HashAlgorithmTest.cs - NUnit Test Cases for HashAlgorithm
5 // Sebastien Pouliot <sebastien@ximian.com>
7 // (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
8 // Copyright (C) 2004, 2006 Novell, Inc (http://www.novell.com)
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using NUnit.Framework;
33 using System.Security.Cryptography;
36 namespace MonoTests.System.Security.Cryptography {
38 // HashAlgorithm is a abstract class - so most of it's functionality wont
39 // be tested here (but will be in its descendants).
42 public class HashAlgorithmTest : Assertion {
43 protected HashAlgorithm hash;
46 protected virtual void SetUp ()
48 hash = HashAlgorithm.Create ();
51 public void AssertEquals (string msg, byte[] array1, byte[] array2)
53 AllTests.AssertEquals (msg, array1, array2);
56 // Note: These tests will only be valid without a "machine.config" file
57 // or a "machine.config" file that do not modify the default algorithm
59 private const string defaultSHA1 = "System.Security.Cryptography.SHA1CryptoServiceProvider";
60 private const string defaultMD5 = "System.Security.Cryptography.MD5CryptoServiceProvider";
61 private const string defaultSHA256 = "System.Security.Cryptography.SHA256Managed";
62 private const string defaultSHA384 = "System.Security.Cryptography.SHA384Managed";
63 private const string defaultSHA512 = "System.Security.Cryptography.SHA512Managed";
64 private const string defaultHash = defaultSHA1;
67 public virtual void Create ()
69 // try the default hash algorithm (created in SetUp)
70 AssertEquals( "HashAlgorithm.Create()", defaultHash, hash.ToString());
72 // try to build all hash algorithms
73 hash = HashAlgorithm.Create ("SHA");
74 AssertEquals ("HashAlgorithm.Create('SHA')", defaultSHA1, hash.ToString ());
75 hash = HashAlgorithm.Create ("SHA1");
76 AssertEquals ("HashAlgorithm.Create('SHA1')", defaultSHA1, hash.ToString ());
77 hash = HashAlgorithm.Create ("System.Security.Cryptography.SHA1");
78 AssertEquals ("HashAlgorithm.Create('System.Security.Cryptography.SHA1')", defaultSHA1, hash.ToString ());
79 hash = HashAlgorithm.Create ("System.Security.Cryptography.HashAlgorithm" );
80 AssertEquals ("HashAlgorithm.Create('System.Security.Cryptography.HashAlgorithm')", defaultHash, hash.ToString ());
82 hash = HashAlgorithm.Create ("MD5");
83 AssertEquals ("HashAlgorithm.Create('MD5')", defaultMD5, hash.ToString ());
84 hash = HashAlgorithm.Create ("System.Security.Cryptography.MD5");
85 AssertEquals ("HashAlgorithm.Create('System.Security.Cryptography.MD5')", defaultMD5, hash.ToString ());
87 hash = HashAlgorithm.Create ("SHA256");
88 AssertEquals ("HashAlgorithm.Create('SHA256')", defaultSHA256, hash.ToString ());
89 hash = HashAlgorithm.Create ("SHA-256");
90 AssertEquals ("HashAlgorithm.Create('SHA-256')", defaultSHA256, hash.ToString ());
91 hash = HashAlgorithm.Create ("System.Security.Cryptography.SHA256");
92 AssertEquals ("HashAlgorithm.Create('System.Security.Cryptography.SHA256')", defaultSHA256, hash.ToString ());
94 hash = HashAlgorithm.Create ("SHA384");
95 AssertEquals ("HashAlgorithm.Create('SHA384')", defaultSHA384, hash.ToString ());
96 hash = HashAlgorithm.Create ("SHA-384");
97 AssertEquals ("HashAlgorithm.Create('SHA-384')", defaultSHA384, hash.ToString ());
98 hash = HashAlgorithm.Create ("System.Security.Cryptography.SHA384");
99 AssertEquals ("HashAlgorithm.Create('System.Security.Cryptography.SHA384')", defaultSHA384, hash.ToString ());
101 hash = HashAlgorithm.Create ("SHA512");
102 AssertEquals ("HashAlgorithm.Create('SHA512')", defaultSHA512, hash.ToString ());
103 hash = HashAlgorithm.Create ("SHA-512");
104 AssertEquals ("HashAlgorithm.Create('SHA-512')", defaultSHA512, hash.ToString ());
105 hash = HashAlgorithm.Create ("System.Security.Cryptography.SHA512");
106 AssertEquals ("HashAlgorithm.Create('System.Security.Cryptography.SHA512')", defaultSHA512, hash.ToString ());
108 // try to build invalid implementation
109 hash = HashAlgorithm.Create ("InvalidHash");
110 AssertNull ("HashAlgorithm.Create('InvalidHash')", hash);
114 [ExpectedException (typeof (ArgumentNullException))]
115 public virtual void CreateNull ()
117 // try to build null implementation
118 hash = HashAlgorithm.Create (null);
122 [ExpectedException (typeof (ObjectDisposedException))]
125 byte[] inputABC = Encoding.Default.GetBytes ("abc");
126 hash.ComputeHash (inputABC);
128 // cannot use a disposed object
129 hash.ComputeHash (inputABC);
133 [ExpectedException (typeof (ObjectDisposedException))]
134 public void Clear2 ()
136 byte[] inputABC = Encoding.Default.GetBytes ("abc");
137 MemoryStream ms = new MemoryStream (inputABC);
138 hash.ComputeHash (ms);
140 // cannot use a disposed object
141 hash.ComputeHash (ms);
145 [ExpectedException (typeof (NullReferenceException))]
146 public void NullStream ()
149 byte[] result = hash.ComputeHash (s);
153 public void Disposable ()
155 using (HashAlgorithm hash = HashAlgorithm.Create ()) {
156 byte[] data = hash.ComputeHash (new byte [0]);
161 [ExpectedException (typeof (ObjectDisposedException))]
162 public void InitializeDisposed ()
164 hash.ComputeHash (new byte [0]);
165 hash.Clear (); // disposed
167 hash.ComputeHash (new byte [0]);
171 [ExpectedException (typeof (ArgumentNullException))]
172 public void ComputeHash_ArrayNull ()
175 hash.ComputeHash (array);
179 [ExpectedException (typeof (ArgumentNullException))]
180 public void ComputeHash_ArrayNullIntInt ()
183 hash.ComputeHash (array, 0, 0);
187 [ExpectedException (typeof (ArgumentOutOfRangeException))]
188 public void ComputeHash_OffsetNegative ()
190 byte[] array = new byte [0];
191 hash.ComputeHash (array, -1, 0);
195 [ExpectedException (typeof (ArgumentException))]
196 public void ComputeHash_OffsetOverflow ()
198 byte[] array = new byte [1];
199 hash.ComputeHash (array, Int32.MaxValue, 1);
203 [ExpectedException (typeof (ArgumentException))]
204 public void ComputeHash_CountNegative ()
206 byte[] array = new byte [0];
207 hash.ComputeHash (array, 0, -1);
211 [ExpectedException (typeof (ArgumentException))]
212 public void ComputeHash_CountOverflow ()
214 byte[] array = new byte [1];
215 hash.ComputeHash (array, 1, Int32.MaxValue);
219 // not checked in Fx 1.1
220 // [ExpectedException (typeof (ObjectDisposedException))]
221 public void TransformBlock_Disposed ()
223 hash.ComputeHash (new byte [0]);
225 byte[] input = new byte [8];
226 byte[] output = new byte [8];
227 hash.TransformBlock (input, 0, input.Length, output, 0);
231 [ExpectedException (typeof (ArgumentNullException))]
232 public void TransformBlock_InputBuffer_Null ()
234 byte[] output = new byte [8];
235 hash.TransformBlock (null, 0, output.Length, output, 0);
239 [ExpectedException (typeof (ArgumentOutOfRangeException))]
240 public void TransformBlock_InputOffset_Negative ()
242 byte[] input = new byte [8];
243 byte[] output = new byte [8];
244 hash.TransformBlock (input, -1, input.Length, output, 0);
248 [ExpectedException (typeof (ArgumentException))]
249 public void TransformBlock_InputOffset_Overflow ()
251 byte[] input = new byte [8];
252 byte[] output = new byte [8];
253 hash.TransformBlock (input, Int32.MaxValue, input.Length, output, 0);
257 [ExpectedException (typeof (ArgumentException))]
258 public void TransformBlock_InputCount_Negative ()
260 byte[] input = new byte [8];
261 byte[] output = new byte [8];
262 hash.TransformBlock (input, 0, -1, output, 0);
266 [ExpectedException (typeof (ArgumentException))]
267 public void TransformBlock_InputCount_Overflow ()
269 byte[] input = new byte [8];
270 byte[] output = new byte [8];
271 hash.TransformBlock (input, 0, Int32.MaxValue, output, 0);
276 [Category ("NotDotNet")] // System.ExecutionEngineException on MS runtime (1.1)
278 public void TransformBlock_OutputBuffer_Null ()
280 byte[] input = new byte [8];
281 hash.TransformBlock (input, 0, input.Length, null, 0);
286 [ExpectedException (typeof (ArgumentOutOfRangeException))]
288 [ExpectedException (typeof (IndexOutOfRangeException))]
290 public void TransformBlock_OutputOffset_Negative ()
292 byte[] input = new byte [8];
293 byte[] output = new byte [8];
294 hash.TransformBlock (input, 0, input.Length, output, -1);
299 [ExpectedException (typeof (ArgumentException))]
301 [ExpectedException (typeof (IndexOutOfRangeException))]
303 public void TransformBlock_OutputOffset_Overflow ()
305 byte[] input = new byte [8];
306 byte[] output = new byte [8];
307 hash.TransformBlock (input, 0, input.Length, output, Int32.MaxValue);
311 // not checked in Fx 1.1
312 // [ExpectedException (typeof (ObjectDisposedException))]
313 public void TransformFinalBlock_Disposed ()
315 hash.ComputeHash (new byte [0]);
317 byte[] input = new byte [8];
318 hash.TransformFinalBlock (input, 0, input.Length);
322 [ExpectedException (typeof (ArgumentNullException))]
323 public void TransformFinalBlock_InputBuffer_Null ()
325 hash.TransformFinalBlock (null, 0, 8);
329 [ExpectedException (typeof (ArgumentOutOfRangeException))]
330 public void TransformFinalBlock_InputOffset_Negative ()
332 byte[] input = new byte [8];
333 hash.TransformFinalBlock (input, -1, input.Length);
337 [ExpectedException (typeof (ArgumentException))]
338 public void TransformFinalBlock_InputOffset_Overflow ()
340 byte[] input = new byte [8];
341 hash.TransformFinalBlock (input, Int32.MaxValue, input.Length);
345 [ExpectedException (typeof (ArgumentException))]
346 public void TransformFinalBlock_InputCount_Negative ()
348 byte[] input = new byte [8];
349 hash.TransformFinalBlock (input, 0, -1);
353 [ExpectedException (typeof (ArgumentException))]
354 public void TransformFinalBlock_InputCount_Overflow ()
356 byte[] input = new byte [8];
357 hash.TransformFinalBlock (input, 0, Int32.MaxValue);
361 [Category ("NotWorking")] // Mono nevers throws an exception (and we're all managed ;-)
362 public void TransformFinalBlock_Twice ()
364 bool managed = (hash.GetType ().ToString ().IndexOf ("Managed") > 0);
365 bool exception = false;
366 byte[] input = new byte [8];
367 hash.TransformFinalBlock (input, 0, input.Length);
369 hash.TransformFinalBlock (input, 0, input.Length);
371 catch (CryptographicException) {
374 Fail ("*Managed don't throw CryptographicException");
376 if (!managed && !exception)
377 Fail ("Expected CryptographicException from non *Managed classes");
381 [Category ("NotWorking")] // Mono nevers throws an exception (and we're all managed ;-)
382 public void TransformFinalBlock_TransformBlock ()
384 bool managed = (hash.GetType ().ToString ().IndexOf ("Managed") > 0);
385 bool exception = false;
386 byte[] input = new byte[8];
387 hash.TransformFinalBlock (input, 0, input.Length);
389 hash.TransformBlock (input, 0, input.Length, input, 0);
391 catch (CryptographicException) {
394 Fail ("*Managed don't throw CryptographicException");
396 if (!managed && !exception)
397 Fail ("Expected CryptographicException from non *Managed classes");
401 public void TransformFinalBlock_Twice_Initialize ()
403 byte[] input = new byte[8];
404 hash.TransformFinalBlock (input, 0, input.Length);
406 hash.TransformFinalBlock (input, 0, input.Length);
410 public void TransformFinalBlock_ReturnedBuffer ()
412 byte[] input = new byte[8];
413 byte[] output = hash.TransformFinalBlock (input, 0, input.Length);
414 AssertEquals ("buffer", input, output);
416 AssertEquals ("0", 0, input[0]); // output is a copy (not a reference)
419 private byte[] HashBuffer (bool intersect)
421 byte[] buffer = new byte [256];
422 for (int i = 0; i < buffer.Length; i++)
423 buffer [i] = (byte) i;
427 hash.TransformBlock (buffer, 0, 64, buffer, 0);
428 // bad - we rewrite the beginning of the buffer
429 hash.TransformBlock (buffer, 64, 128, buffer, intersect ? 0 : 64);
431 hash.TransformFinalBlock (buffer, 192, 64);
436 public void InputOutputIntersection ()
438 AssertEquals ("Intersect", HashBuffer (false), HashBuffer (true));
442 [ExpectedException (typeof (NullReferenceException))]
443 [Category ("NotWorking")] // initialization problem ? fx2.0 only ?
444 public void Hash_AfterInitialize_FirstTime ()
447 // getting the property throws
448 AssertNull (hash.Hash);
452 [ExpectedException (typeof (CryptographicUnexpectedOperationException))]
453 public void Hash_AfterInitialize_SecondTime ()
455 byte[] input = new byte[8];
457 hash.TransformBlock (input, 0, input.Length, input, 0);
459 // getting the property throws
460 AssertNull (hash.Hash);
464 [ExpectedException (typeof (CryptographicUnexpectedOperationException))]
465 public void Hash_AfterTransformBlock ()
467 byte[] input = new byte[8];
469 hash.TransformBlock (input, 0, input.Length, input, 0);
470 // getting the property throws
471 AssertNull (hash.Hash);
475 public void Hash_AfterTransformFinalBlock ()
477 byte[] input = new byte[8];
479 hash.TransformFinalBlock (input, 0, input.Length);
480 AssertNotNull (hash.Hash);