If the window manager does not support _NET_ACTIVE_WINDOW, fall back to XGetInputFocus
[mono.git] / mcs / class / corlib / Test / System.Security.Cryptography / HMACSHA1Test.cs
1 //
2 // HMACSHA1Test.cs - NUnit Test Cases for HMACSHA1
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 #if NET_2_0
39         public class HS160 : HMACSHA1 {
40
41                 public int BlockSize {
42                         get { return base.BlockSizeValue; }
43                         set { base.BlockSizeValue = value; }
44                 }
45         }
46 #endif
47
48 // References:
49 // a.   The Keyed-Hash Message Authentication Code (HMAC)
50 //      http://csrc.nist.gov/publications/fips/fips198/fips-198a.pdf
51 // b.   IETF RFC2202: Test Cases for HMAC-MD5 and HMAC-SHA-1
52 //      http://www.ietf.org/rfc/rfc2202.txt
53
54 public class HMACSHA1Test : KeyedHashAlgorithmTest {
55
56         protected HMACSHA1 algo;
57
58         [SetUp]
59         protected override void SetUp () 
60         {
61                 hash = HMACSHA1.Create ();
62                 (hash as KeyedHashAlgorithm).Key = new byte [8];
63         }
64
65         [Test]
66         public void Constructors () 
67         {
68                 algo = new HMACSHA1 ();
69                 Assert.IsNotNull (hash, "HMACSHA1 ()");
70
71                 byte[] key = new byte [8];
72                 algo = new HMACSHA1 (key);
73                 Assert.IsNotNull (hash, "HMACSHA1 (key)");
74         }
75
76         [Test]
77         [ExpectedException (typeof (NullReferenceException))]
78         public void Constructor_Null () 
79         {
80                 algo = new HMACSHA1 (null);
81         }
82
83         [Test]
84         public void Invariants () 
85         {
86                 algo = new HMACSHA1 ();
87                 Assert.IsTrue (algo.CanReuseTransform, "HMACSHA1.CanReuseTransform");
88                 Assert.IsTrue (algo.CanTransformMultipleBlocks, "HMACSHA1.CanTransformMultipleBlocks");
89                 Assert.AreEqual ("SHA1", algo.HashName, "HMACSHA1.HashName");
90                 Assert.AreEqual (160, algo.HashSize, "HMACSHA1.HashSize");
91                 Assert.AreEqual (1, algo.InputBlockSize, "HMACSHA1.InputBlockSize");
92                 Assert.AreEqual (1, algo.OutputBlockSize, "HMACSHA1.OutputBlockSize");
93                 Assert.AreEqual ("System.Security.Cryptography.HMACSHA1", algo.ToString (), "HMACSHA1.ToString()"); 
94         }
95
96 #if NET_2_0
97         [Test]
98         public void BlockSize ()
99         {
100                 HS160 hmac = new HS160 ();
101                 Assert.AreEqual (64, hmac.BlockSize, "BlockSizeValue");
102         }
103 #else
104         // this is legal in .NET 2.0 because HMACSHA1 derives from HMAC
105         [Test]
106         [ExpectedException (typeof (InvalidCastException))]
107         public void InvalidHashName () 
108         {
109                 algo = new HMACSHA1 ();
110                 algo.HashName = "MD5";
111                 byte[] data = Encoding.Default.GetBytes ("MD5");
112                 byte[] hmac = algo.ComputeHash (data);
113         }
114 #endif
115
116         public void Check (string testName, byte[] key, byte[] data, byte[] result) 
117         {
118                 string classTestName = "HMACSHA1-" + testName;
119                 CheckA (testName, key, data, result);
120                 CheckB (testName, key, data, result);
121                 CheckC (testName, key, data, result);
122                 CheckD (testName, key, data, result);
123                 CheckE (testName, key, data, result);
124                 CheckF (testName, key, data, result);
125         }
126
127         public void CheckA (string testName, byte[] key, byte[] data, byte[] result) 
128         {
129 #if NET_2_0
130                 algo = new HMACSHA1 (key, true);
131 #else
132                 algo = new HMACSHA1 (key);
133 #endif
134                 byte[] hmac = algo.ComputeHash (data);
135                 Assert.AreEqual (result, hmac, testName + "a1");
136                 Assert.AreEqual (result, algo.Hash, testName + "a2");
137         }
138
139         public void CheckB (string testName, byte[] key, byte[] data, byte[] result) 
140         {
141 #if NET_2_0
142                 algo = new HMACSHA1 (key, false);
143 #else
144                 algo = new HMACSHA1 (key);
145 #endif
146                 byte[] hmac = algo.ComputeHash (data, 0, data.Length);
147                 Assert.AreEqual (result, hmac, testName + "b1");
148                 Assert.AreEqual (result, algo.Hash, testName + "b2");
149         }
150         
151         public void CheckC (string testName, byte[] key, byte[] data, byte[] result) 
152         {
153                 algo = new HMACSHA1 (key);
154                 MemoryStream ms = new MemoryStream (data);
155                 byte[] hmac = algo.ComputeHash (ms);
156                 Assert.AreEqual (result, hmac, testName + "c1");
157                 Assert.AreEqual (result, algo.Hash, testName + "c2");
158         }
159
160         public void CheckD (string testName, byte[] key, byte[] data, byte[] result) 
161         {
162                 algo = new HMACSHA1 (key);
163                 // LAMESPEC or FIXME: TransformFinalBlock doesn't return HashValue !
164                 algo.TransformFinalBlock (data, 0, data.Length);
165                 Assert.AreEqual (result, algo.Hash, testName + "d");
166         }
167
168         public void CheckE (string testName, byte[] key, byte[] data, byte[] result) 
169         {
170                 algo = new HMACSHA1 (key);
171                 byte[] copy = new byte [data.Length];
172                 // LAMESPEC or FIXME: TransformFinalBlock doesn't return HashValue !
173                 for (int i=0; i < data.Length - 1; i++)
174                         algo.TransformBlock (data, i, 1, copy, i);
175                 algo.TransformFinalBlock (data, data.Length - 1, 1);
176                 Assert.AreEqual (result, algo.Hash, testName + "e");
177         }
178
179         public void CheckF (string testName, byte[] key, byte[] data, byte[] result)
180         {
181                 algo = new HMACSHA1 (key);
182                 byte[] temp = new byte[data.Length + 2];
183                 for (int i = 0; i < data.Length; i ++)
184                         temp[i + 1] = data[i];
185                 byte[] hmac = algo.ComputeHash (temp, 1, data.Length);
186                 Assert.AreEqual (result, hmac, testName + "f");
187         }
188
189         [Test]
190         public void FIPS198_A1 () 
191         {
192                 // exact 64 bytes key (no hashing - no padding)
193                 byte[] key =  { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
194                                 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
195                                 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
196                                 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
197                                 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
198                                 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
199                                 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
200                                 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f };
201
202                 byte[] fips = { 0x4f, 0x4c, 0xa3, 0xd5, 0xd6, 0x8b, 0xa7, 0xcc, 0x0a, 0x12,
203                                 0x08, 0xc9, 0xc6, 0x1e, 0x9c, 0x5d, 0xa0, 0x40, 0x3c, 0x0a };
204
205                 byte[] data = Encoding.Default.GetBytes ("Sample #1");
206                 Check ("FIPS198-A1", key, data, fips);
207         }
208
209         [Test]
210         public void FIPS198_A2 () 
211         {
212                 // key < 64 bytes -> requires padding
213                 byte[] key =  { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
214                                 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43 };
215
216                 byte[] fips = { 0x09, 0x22, 0xd3, 0x40, 0x5f, 0xaa, 0x3d, 0x19, 0x4f, 0x82,
217                                 0xa4, 0x58, 0x30, 0x73, 0x7d, 0x5c, 0xc6, 0xc7, 0x5d, 0x24 };
218
219                 byte[] data = Encoding.Default.GetBytes ("Sample #2");
220                 Check ("FIPS198-A2", key, data, fips);
221         }
222
223         [Test]
224         public void FIPS198_A3 () 
225         {
226                 // key > 64 bytes -> requires hashing
227                 byte[] key =  { 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
228                                 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
229                                 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
230                                 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
231                                 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
232                                 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
233                                 0xb0, 0xb1, 0xb2, 0xb3 };
234
235                 byte[] fips = { 0xbc, 0xf4, 0x1e, 0xab, 0x8b, 0xb2, 0xd8, 0x02, 0xf3, 0xd0,
236                                 0x5c, 0xaf, 0x7c, 0xb0, 0x92, 0xec, 0xf8, 0xd1, 0xa3, 0xaa };
237
238                 byte[] data = Encoding.Default.GetBytes ("Sample #3");
239                 Check ("FIPS198-A3", key, data, fips);
240         }
241
242         [Test]
243         public void FIPS198_A4 () 
244         {
245                 byte[] key =  { 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
246                                 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
247                                 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d,
248                                 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
249                                 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0 };
250
251                 byte[] fips = { 0x9e, 0xa8, 0x86, 0xef, 0xe2, 0x68, 0xdb, 0xec, 0xce, 0x42,
252                                 0x0c, 0x75, 0x24, 0xdf, 0x32, 0xe0, 0x75, 0x1a, 0x2a, 0x26 };
253
254                 byte[] data = Encoding.Default.GetBytes ("Sample #4");
255                 Check ("FIPS198-A4", key, data, fips);
256         }
257
258         [Test]
259         public void RFC2202_TC1 () 
260         {
261                 byte[] key =  { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b };
262                 byte[] data = Encoding.Default.GetBytes ("Hi There");
263                 byte[] digest = { 0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, 0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e, 0xf1, 0x46, 0xbe, 0x00 };
264                 Check ("RFC2202-TC1", key, data, digest);
265         }
266
267         [Test]
268         public void RFC2202_TC2 () 
269         {
270                 byte[] key = Encoding.Default.GetBytes ("Jefe");
271                 byte[] data = Encoding.Default.GetBytes ("what do ya want for nothing?");
272                 byte[] digest = { 0xef, 0xfc, 0xdf, 0x6a, 0xe5, 0xeb, 0x2f, 0xa2, 0xd2, 0x74, 0x16, 0xd5, 0xf1, 0x84, 0xdf, 0x9c, 0x25, 0x9a, 0x7c, 0x79 };
273                 Check ("RFC2202-TC2", key, data, digest);
274         }
275
276         [Test]
277         public void RFC2202_TC3 () 
278         {
279                 byte[] key = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };
280                 byte[] data = new byte [50];
281                 for (int i = 0; i < data.Length; i++)
282                         data[i] = 0xdd;
283                 byte[] digest = { 0x12, 0x5d, 0x73, 0x42, 0xb9, 0xac, 0x11, 0xcd, 0x91, 0xa3, 0x9a, 0xf4, 0x8a, 0xa1, 0x7b, 0x4f, 0x63, 0xf1, 0x75, 0xd3 };
284                 Check ("RFC2202-TC3", key, data, digest);
285         }
286
287         [Test]
288         public void RFC2202_TC4 () 
289         {
290                 byte[] key = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19 };
291                 byte[] data = new byte [50];
292                 for (int i = 0; i < data.Length; i++)
293                         data[i] = 0xcd;
294                 byte[] digest = { 0x4c, 0x90, 0x07, 0xf4, 0x02, 0x62, 0x50, 0xc6, 0xbc, 0x84, 0x14, 0xf9, 0xbf, 0x50, 0xc8, 0x6c, 0x2d, 0x72, 0x35, 0xda };
295                 Check ("RFC2202-TC4", key, data, digest);
296         }
297
298         [Test]
299         public void RFC2202_TC5 () 
300         {
301                 byte[] key = { 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c };
302                 byte[] data = Encoding.Default.GetBytes ("Test With Truncation");
303                 byte[] digest = { 0x4c, 0x1a, 0x03, 0x42, 0x4b, 0x55, 0xe0, 0x7f, 0xe7, 0xf2, 0x7b, 0xe1, 0xd5, 0x8b, 0xb9, 0x32, 0x4a, 0x9a, 0x5a, 0x04 };
304                 Check ("RFC2202-TC5", key, data, digest);
305         }
306
307         [Test]
308         public void RFC2202_TC6 () 
309         {
310                 byte[] key = new byte [80];
311                 for (int i = 0; i < key.Length; i++)
312                         key[i] = 0xaa;
313                 byte[] data = Encoding.Default.GetBytes ("Test Using Larger Than Block-Size Key - Hash Key First");
314                 byte[] digest = { 0xaa, 0x4a, 0xe5, 0xe1, 0x52, 0x72, 0xd0, 0x0e, 0x95, 0x70, 0x56, 0x37, 0xce, 0x8a, 0x3b, 0x55, 0xed, 0x40, 0x21, 0x12 };
315                 Check ("RFC2202-TC6", key, data, digest);
316         }
317
318         [Test]
319         public void RFC2202_TC7 () 
320         {
321                 byte[] key = new byte [80];
322                 for (int i = 0; i < key.Length; i++)
323                         key[i] = 0xaa;
324                 byte[] data = Encoding.Default.GetBytes ("Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data");
325                 byte[] digest = { 0xe8, 0xe9, 0x9d, 0x0f, 0x45, 0x23, 0x7d, 0x78, 0x6d, 0x6b, 0xba, 0xa7, 0x96, 0x5c, 0x78, 0x08, 0xbb, 0xff, 0x1a, 0x91 };
326                 Check ("RFC2202-TC7", key, data, digest);
327         }
328 }
329
330 }