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, 2007 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 {
44 protected HashAlgorithm hash;
47 public virtual void SetUp ()
49 hash = HashAlgorithm.Create ();
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
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;
63 public virtual void Create ()
65 // try the default hash algorithm (created in SetUp)
66 Assert.AreEqual (defaultHash, hash.ToString (), "HashAlgorithm.Create()");
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')");
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')");
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')");
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')");
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')");
104 // try to build invalid implementation
105 hash = HashAlgorithm.Create ("InvalidHash");
106 Assert.IsNull (hash, "HashAlgorithm.Create('InvalidHash')");
110 [ExpectedException (typeof (ArgumentNullException))]
111 public virtual void CreateNull ()
113 // try to build null implementation
114 hash = HashAlgorithm.Create (null);
118 [ExpectedException (typeof (ObjectDisposedException))]
121 byte[] inputABC = Encoding.Default.GetBytes ("abc");
122 hash.ComputeHash (inputABC);
124 // cannot use a disposed object
125 hash.ComputeHash (inputABC);
129 [ExpectedException (typeof (ObjectDisposedException))]
130 public void Clear2 ()
132 byte[] inputABC = Encoding.Default.GetBytes ("abc");
133 MemoryStream ms = new MemoryStream (inputABC);
134 hash.ComputeHash (ms);
136 // cannot use a disposed object
137 hash.ComputeHash (ms);
141 [ExpectedException (typeof (ArgumentNullException))]
142 public void NullStream ()
145 hash.ComputeHash (s);
149 public void Disposable ()
151 using (HashAlgorithm hash = HashAlgorithm.Create ()) {
152 hash.ComputeHash (new byte [0]);
157 [ExpectedException (typeof (ObjectDisposedException))]
158 public void InitializeDisposed ()
160 hash.ComputeHash (new byte [0]);
161 hash.Clear (); // disposed
163 hash.ComputeHash (new byte [0]);
167 [ExpectedException (typeof (ArgumentNullException))]
168 public void ComputeHash_ArrayNull ()
171 hash.ComputeHash (array);
175 [ExpectedException (typeof (ArgumentNullException))]
176 public void ComputeHash_ArrayNullIntInt ()
179 hash.ComputeHash (array, 0, 0);
183 [ExpectedException (typeof (ArgumentOutOfRangeException))]
184 public void ComputeHash_OffsetNegative ()
186 byte[] array = new byte [0];
187 hash.ComputeHash (array, -1, 0);
191 [ExpectedException (typeof (ArgumentException))]
192 public void ComputeHash_OffsetOverflow ()
194 byte[] array = new byte [1];
195 hash.ComputeHash (array, Int32.MaxValue, 1);
199 [ExpectedException (typeof (ArgumentException))]
200 public void ComputeHash_CountNegative ()
202 byte[] array = new byte [0];
203 hash.ComputeHash (array, 0, -1);
207 [ExpectedException (typeof (ArgumentException))]
208 public void ComputeHash_CountOverflow ()
210 byte[] array = new byte [1];
211 hash.ComputeHash (array, 1, Int32.MaxValue);
215 // not checked in Fx 1.1
216 // [ExpectedException (typeof (ObjectDisposedException))]
217 public void TransformBlock_Disposed ()
219 hash.ComputeHash (new byte [0]);
221 byte[] input = new byte [8];
222 byte[] output = new byte [8];
223 hash.TransformBlock (input, 0, input.Length, output, 0);
227 [ExpectedException (typeof (ArgumentNullException))]
228 public void TransformBlock_InputBuffer_Null ()
230 byte[] output = new byte [8];
231 hash.TransformBlock (null, 0, output.Length, output, 0);
235 [ExpectedException (typeof (ArgumentOutOfRangeException))]
236 public void TransformBlock_InputOffset_Negative ()
238 byte[] input = new byte [8];
239 byte[] output = new byte [8];
240 hash.TransformBlock (input, -1, input.Length, output, 0);
244 [ExpectedException (typeof (ArgumentException))]
245 public void TransformBlock_InputOffset_Overflow ()
247 byte[] input = new byte [8];
248 byte[] output = new byte [8];
249 hash.TransformBlock (input, Int32.MaxValue, input.Length, output, 0);
253 [ExpectedException (typeof (ArgumentException))]
254 public void TransformBlock_InputCount_Negative ()
256 byte[] input = new byte [8];
257 byte[] output = new byte [8];
258 hash.TransformBlock (input, 0, -1, output, 0);
262 [ExpectedException (typeof (ArgumentException))]
263 public void TransformBlock_InputCount_Overflow ()
265 byte[] input = new byte [8];
266 byte[] output = new byte [8];
267 hash.TransformBlock (input, 0, Int32.MaxValue, output, 0);
272 [Category ("NotDotNet")] // System.ExecutionEngineException on MS runtime (1.1)
274 public void TransformBlock_OutputBuffer_Null ()
276 byte[] input = new byte [8];
277 hash.TransformBlock (input, 0, input.Length, null, 0);
282 [ExpectedException (typeof (ArgumentOutOfRangeException))]
284 [ExpectedException (typeof (IndexOutOfRangeException))]
286 public void TransformBlock_OutputOffset_Negative ()
288 byte[] input = new byte [8];
289 byte[] output = new byte [8];
290 hash.TransformBlock (input, 0, input.Length, output, -1);
295 [ExpectedException (typeof (ArgumentException))]
297 [ExpectedException (typeof (IndexOutOfRangeException))]
299 public void TransformBlock_OutputOffset_Overflow ()
301 byte[] input = new byte [8];
302 byte[] output = new byte [8];
303 hash.TransformBlock (input, 0, input.Length, output, Int32.MaxValue);
307 // not checked in Fx 1.1
308 // [ExpectedException (typeof (ObjectDisposedException))]
309 public void TransformFinalBlock_Disposed ()
311 hash.ComputeHash (new byte [0]);
313 byte[] input = new byte [8];
314 hash.TransformFinalBlock (input, 0, input.Length);
318 [ExpectedException (typeof (ArgumentNullException))]
319 public void TransformFinalBlock_InputBuffer_Null ()
321 hash.TransformFinalBlock (null, 0, 8);
325 [ExpectedException (typeof (ArgumentOutOfRangeException))]
326 public void TransformFinalBlock_InputOffset_Negative ()
328 byte[] input = new byte [8];
329 hash.TransformFinalBlock (input, -1, input.Length);
333 [ExpectedException (typeof (ArgumentException))]
334 public void TransformFinalBlock_InputOffset_Overflow ()
336 byte[] input = new byte [8];
337 hash.TransformFinalBlock (input, Int32.MaxValue, input.Length);
341 [ExpectedException (typeof (ArgumentException))]
342 public void TransformFinalBlock_InputCount_Negative ()
344 byte[] input = new byte [8];
345 hash.TransformFinalBlock (input, 0, -1);
349 [ExpectedException (typeof (ArgumentException))]
350 public void TransformFinalBlock_InputCount_Overflow ()
352 byte[] input = new byte [8];
353 hash.TransformFinalBlock (input, 0, Int32.MaxValue);
356 public virtual bool ManagedHashImplementation {
357 get { return false; }
361 [Category ("NotWorking")] // Mono nevers throws an exception (and we're all managed ;-)
362 public void TransformFinalBlock_Twice ()
364 bool exception = false;
365 byte[] input = new byte [8];
366 hash.TransformFinalBlock (input, 0, input.Length);
368 hash.TransformFinalBlock (input, 0, input.Length);
370 catch (CryptographicException) {
372 if (ManagedHashImplementation)
373 Assert.Fail ("*Managed don't throw CryptographicException");
375 if (!ManagedHashImplementation && !exception)
376 Assert.Fail ("Expected CryptographicException from non *Managed classes");
380 [Category ("NotWorking")] // Mono nevers throws an exception (and we're all managed ;-)
381 public void TransformFinalBlock_TransformBlock ()
383 bool exception = false;
384 byte[] input = new byte[8];
385 hash.TransformFinalBlock (input, 0, input.Length);
387 hash.TransformBlock (input, 0, input.Length, input, 0);
389 catch (CryptographicException) {
391 if (ManagedHashImplementation)
392 Assert.Fail ("*Managed don't throw CryptographicException");
394 if (!ManagedHashImplementation && !exception)
395 Assert.Fail ("Expected CryptographicException from non *Managed classes");
399 public void TransformFinalBlock_Twice_Initialize ()
401 byte[] input = new byte[8];
402 hash.TransformFinalBlock (input, 0, input.Length);
404 hash.TransformFinalBlock (input, 0, input.Length);
408 public void TransformFinalBlock_ReturnedBuffer ()
410 byte[] input = new byte[8];
411 byte[] output = hash.TransformFinalBlock (input, 0, input.Length);
412 Assert.AreEqual (input, output, "buffer");
414 Assert.AreEqual (0, input[0], "0"); // output is a copy (not a reference)
417 private byte[] HashBuffer (bool intersect)
419 byte[] buffer = new byte [256];
420 for (int i = 0; i < buffer.Length; i++)
421 buffer [i] = (byte) i;
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);
429 hash.TransformFinalBlock (buffer, 192, 64);
434 public void InputOutputIntersection ()
436 Assert.AreEqual (HashBuffer (false), HashBuffer (true), "Intersect");
440 [ExpectedException (typeof (NullReferenceException))]
441 [Category ("NotWorking")] // initialization problem ? fx2.0 only ?
442 public void Hash_AfterInitialize_FirstTime ()
445 // getting the property throws
446 Assert.IsNull (hash.Hash);
450 [ExpectedException (typeof (CryptographicUnexpectedOperationException))]
451 public void Hash_AfterInitialize_SecondTime ()
453 byte[] input = new byte[8];
455 hash.TransformBlock (input, 0, input.Length, input, 0);
457 // getting the property throws
458 Assert.IsNull (hash.Hash);
462 [ExpectedException (typeof (CryptographicUnexpectedOperationException))]
463 public void Hash_AfterTransformBlock ()
465 byte[] input = new byte[8];
467 hash.TransformBlock (input, 0, input.Length, input, 0);
468 // getting the property throws
469 Assert.IsNull (hash.Hash);
473 public void Hash_AfterTransformFinalBlock ()
475 byte[] input = new byte[8];
477 hash.TransformFinalBlock (input, 0, input.Length);
478 Assert.IsNotNull (hash.Hash);