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 (NullReferenceException
))]
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);
271 public void TransformBlock_OutputBuffer_Null ()
273 byte[] input
= new byte [8];
274 hash
.TransformBlock (input
, 0, input
.Length
, null, 0);
278 [ExpectedException (typeof (ArgumentOutOfRangeException
))]
279 public void TransformBlock_OutputOffset_Negative ()
281 byte[] input
= new byte [8];
282 byte[] output
= new byte [8];
283 hash
.TransformBlock (input
, 0, input
.Length
, output
, -1);
287 [ExpectedException (typeof (ArgumentException
))]
288 public void TransformBlock_OutputOffset_Overflow ()
290 byte[] input
= new byte [8];
291 byte[] output
= new byte [8];
292 hash
.TransformBlock (input
, 0, input
.Length
, output
, Int32
.MaxValue
);
296 // not checked in Fx 1.1
297 // [ExpectedException (typeof (ObjectDisposedException))]
298 public void TransformFinalBlock_Disposed ()
300 hash
.ComputeHash (new byte [0]);
302 byte[] input
= new byte [8];
303 hash
.TransformFinalBlock (input
, 0, input
.Length
);
307 [ExpectedException (typeof (ArgumentNullException
))]
308 public void TransformFinalBlock_InputBuffer_Null ()
310 hash
.TransformFinalBlock (null, 0, 8);
314 [ExpectedException (typeof (ArgumentOutOfRangeException
))]
315 public void TransformFinalBlock_InputOffset_Negative ()
317 byte[] input
= new byte [8];
318 hash
.TransformFinalBlock (input
, -1, input
.Length
);
322 [ExpectedException (typeof (ArgumentException
))]
323 public void TransformFinalBlock_InputOffset_Overflow ()
325 byte[] input
= new byte [8];
326 hash
.TransformFinalBlock (input
, Int32
.MaxValue
, input
.Length
);
330 [ExpectedException (typeof (ArgumentException
))]
331 public void TransformFinalBlock_InputCount_Negative ()
333 byte[] input
= new byte [8];
334 hash
.TransformFinalBlock (input
, 0, -1);
338 [ExpectedException (typeof (ArgumentException
))]
339 public void TransformFinalBlock_InputCount_Overflow ()
341 byte[] input
= new byte [8];
342 hash
.TransformFinalBlock (input
, 0, Int32
.MaxValue
);
345 public virtual bool ManagedHashImplementation
{
346 get { return false; }
350 [Category ("NotWorking")] // Mono nevers throws an exception (and we're all managed ;-)
351 public void TransformFinalBlock_Twice ()
353 bool exception
= false;
354 byte[] input
= new byte [8];
355 hash
.TransformFinalBlock (input
, 0, input
.Length
);
357 hash
.TransformFinalBlock (input
, 0, input
.Length
);
359 catch (CryptographicException
) {
361 if (ManagedHashImplementation
)
362 Assert
.Fail ("*Managed don't throw CryptographicException");
364 if (!ManagedHashImplementation
&& !exception
)
365 Assert
.Fail ("Expected CryptographicException from non *Managed classes");
369 [Category ("NotWorking")] // Mono nevers throws an exception (and we're all managed ;-)
370 public void TransformFinalBlock_TransformBlock ()
372 bool exception
= false;
373 byte[] input
= new byte[8];
374 hash
.TransformFinalBlock (input
, 0, input
.Length
);
376 hash
.TransformBlock (input
, 0, input
.Length
, input
, 0);
378 catch (CryptographicException
) {
380 if (ManagedHashImplementation
)
381 Assert
.Fail ("*Managed don't throw CryptographicException");
383 if (!ManagedHashImplementation
&& !exception
)
384 Assert
.Fail ("Expected CryptographicException from non *Managed classes");
388 public void TransformFinalBlock_Twice_Initialize ()
390 byte[] input
= new byte[8];
391 hash
.TransformFinalBlock (input
, 0, input
.Length
);
393 hash
.TransformFinalBlock (input
, 0, input
.Length
);
397 public void TransformFinalBlock_ReturnedBuffer ()
399 byte[] input
= new byte[8];
400 byte[] output
= hash
.TransformFinalBlock (input
, 0, input
.Length
);
401 Assert
.AreEqual (input
, output
, "buffer");
403 Assert
.AreEqual (0, input
[0], "0"); // output is a copy (not a reference)
406 private byte[] HashBuffer (bool intersect
)
408 byte[] buffer
= new byte [256];
409 for (int i
= 0; i
< buffer
.Length
; i
++)
410 buffer
[i
] = (byte) i
;
414 hash
.TransformBlock (buffer
, 0, 64, buffer
, 0);
415 // bad - we rewrite the beginning of the buffer
416 hash
.TransformBlock (buffer
, 64, 128, buffer
, intersect
? 0 : 64);
418 hash
.TransformFinalBlock (buffer
, 192, 64);
423 public void InputOutputIntersection ()
425 Assert
.AreEqual (HashBuffer (false), HashBuffer (true), "Intersect");
429 [ExpectedException (typeof (NullReferenceException
))]
430 [Category ("NotWorking")] // initialization problem ? fx2.0 only ?
431 public void Hash_AfterInitialize_FirstTime ()
434 // getting the property throws
435 Assert
.IsNull (hash
.Hash
);
439 [ExpectedException (typeof (CryptographicUnexpectedOperationException
))]
440 public void Hash_AfterInitialize_SecondTime ()
442 byte[] input
= new byte[8];
444 hash
.TransformBlock (input
, 0, input
.Length
, input
, 0);
446 // getting the property throws
447 Assert
.IsNull (hash
.Hash
);
451 [ExpectedException (typeof (CryptographicUnexpectedOperationException
))]
452 public void Hash_AfterTransformBlock ()
454 byte[] input
= new byte[8];
456 hash
.TransformBlock (input
, 0, input
.Length
, input
, 0);
457 // getting the property throws
458 Assert
.IsNull (hash
.Hash
);
462 public void Hash_AfterTransformFinalBlock ()
464 byte[] input
= new byte[8];
466 hash
.TransformFinalBlock (input
, 0, input
.Length
);
467 Assert
.IsNotNull (hash
.Hash
);