Merge pull request #1840 from ludovic-henry/iolayer-thread-interrupt
[mono.git] / mcs / class / System.Web / Test / System.Web.Util / MachineKeySectionUtilsTest.cs
1 //
2 // Unit tests for MachineKeySectionUtils (internals)
3 //
4 // Author:
5 //      Sebastien Pouliot  <sebastien@ximian.com>
6 //
7 // Copyright (C) 2010 Novell, Inc (http://www.novell.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 using System;
30 using System.IO;
31 using System.Web.Configuration;
32 using System.Web.Util;
33 using NUnit.Framework;
34
35 namespace MonoTests.System.Web.Util {
36
37         [TestFixture]
38         public class MachineKeySectionUtilsTest {
39
40                 static byte ChangeByte (byte b)
41                 {
42                         return (b == Byte.MaxValue) ? Byte.MinValue : (byte) (b + 1);
43                 }
44
45                 public void Encrypt_RoundTrip (MachineKeySection section)
46                 {
47                         byte [] data = new byte [14];
48                         byte [] encdata = MachineKeySectionUtils.Encrypt (section, data);
49                         byte [] decdata = MachineKeySectionUtils.Decrypt (section, encdata);
50                         Assert.AreEqual (data, decdata, "roundtrip");
51
52                         // changing length (missing first byte)
53                         byte [] cut = new byte [encdata.Length - 1];
54                         Array.Copy (encdata, 1, cut, 0, cut.Length);
55                         Assert.IsNull (MachineKeySectionUtils.Decrypt (section, cut), "bad length");
56
57                         // changing last byte (padding)
58                         byte be = encdata [encdata.Length - 1];
59                         encdata [encdata.Length - 1] = ChangeByte (be);
60                         byte[] result = MachineKeySectionUtils.Decrypt (section, encdata);
61                         // this will return null if a bad padding is detected - OTOH since we're using a random key and we
62                         // encrypt a random IV it's possible the decrypted stuff will randomly have a "valid" padding (there's
63                         // only so much possible values and the bots runs those tests pretty often and give false positive)
64                         // To avoid this we fallback to ensure the data is invalid (if should be empty)
65                         int total = 0;
66                         if (result != null) {
67                                 for (int i=0; i < result.Length; i++)
68                                         total += result [i];
69                         }
70                         Assert.IsTrue (result == null || total != 0, "bad padding");
71                 }
72
73                 [Test]
74                 public void Encrypt_RoundTrip_Default ()
75                 {
76                         Encrypt_RoundTrip (new MachineKeySection ());
77                 }
78
79                 [Test]
80                 public void Encrypt_RoundTrip_AES ()
81                 {
82                         MachineKeySection section = new MachineKeySection ();
83                         section.Validation = MachineKeyValidation.AES;
84                         Encrypt_RoundTrip (section);
85                 }
86
87                 [Test]
88                 public void Encrypt_RoundTrip_TripleDES ()
89                 {
90                         MachineKeySection section = new MachineKeySection ();
91                         section.Validation = MachineKeyValidation.TripleDES;
92                         Encrypt_RoundTrip (section);
93                 }
94
95                 [Test]
96                 public void Encrypt_RoundTrip_MD5 ()
97                 {
98                         MachineKeySection section = new MachineKeySection ();
99                         section.Validation = MachineKeyValidation.MD5;
100                         Encrypt_RoundTrip (section);
101                 }
102
103                 [Test]
104                 public void Encrypt_RoundTrip_SHA1 ()
105                 {
106                         MachineKeySection section = new MachineKeySection ();
107                         section.Validation = MachineKeyValidation.SHA1;
108                         Encrypt_RoundTrip (section);
109                 }
110                 [Test]
111                 public void Encrypt_RoundTrip_HMACSHA256 ()
112                 {
113                         MachineKeySection section = new MachineKeySection ();
114                         section.Validation = MachineKeyValidation.HMACSHA256;
115                         EncryptSign_RoundTrip (section);
116                 }
117
118                 [Test]
119                 public void Encrypt_RoundTrip_HMACSHA384 ()
120                 {
121                         MachineKeySection section = new MachineKeySection ();
122                         section.Validation = MachineKeyValidation.HMACSHA384;
123                         EncryptSign_RoundTrip (section);
124                 }
125
126                 [Test]
127                 public void Encrypt_RoundTrip_HMACSHA512 ()
128                 {
129                         MachineKeySection section = new MachineKeySection ();
130                         section.Validation = MachineKeyValidation.HMACSHA512;
131                         EncryptSign_RoundTrip (section);
132                 }
133
134                 [Test]
135                 public void Encrypt_RoundTrip_Custom_RIPEMD160 ()
136                 {
137                         MachineKeySection section = new MachineKeySection ();
138                         section.ValidationAlgorithm = "alg:HMACRIPEMD160";
139                         EncryptSign_RoundTrip (section);
140                 }
141                 public void EncryptSign_RoundTrip (MachineKeySection section)
142                 {
143                         byte [] data = new byte [14];
144                         byte [] block = MachineKeySectionUtils.EncryptSign (section, data);
145                         byte [] decdata = MachineKeySectionUtils.VerifyDecrypt (section, block);
146                         Assert.AreEqual (data, decdata, "roundtrip");
147
148                         // changing a byte of the data
149                         byte b0 = block [0];
150                         block [0] = ChangeByte (b0);
151                         Assert.IsNull (MachineKeySectionUtils.VerifyDecrypt (section, block), "bad data");
152                         block [0] = b0;
153
154                         // changing a byte of the signature
155                         byte be = block [block.Length - 1];
156                         block [block.Length - 1] = ChangeByte (be);
157                         Assert.IsNull (MachineKeySectionUtils.VerifyDecrypt (section, block), "bad signature");
158                 }
159
160                 [Test]
161                 public void EncryptSign_RoundTrip_Default ()
162                 {
163                         EncryptSign_RoundTrip (new MachineKeySection ());
164                 }
165
166                 [Test]
167                 public void EncryptSign_RoundTrip_AES ()
168                 {
169                         MachineKeySection section = new MachineKeySection ();
170                         section.Validation = MachineKeyValidation.AES;
171                         EncryptSign_RoundTrip (section);
172                 }
173
174                 [Test]
175                 public void EncryptSign_RoundTrip_TripleDES ()
176                 {
177                         MachineKeySection section = new MachineKeySection ();
178                         section.Validation = MachineKeyValidation.TripleDES;
179                         EncryptSign_RoundTrip (section);
180                 }
181
182                 [Test]
183                 public void EncryptSign_RoundTrip_MD5 ()
184                 {
185                         MachineKeySection section = new MachineKeySection ();
186                         section.Validation = MachineKeyValidation.MD5;
187                         EncryptSign_RoundTrip (section);
188                 }
189
190                 [Test]
191                 public void EncryptSign_RoundTrip_SHA1 ()
192                 {
193                         MachineKeySection section = new MachineKeySection ();
194                         section.Validation = MachineKeyValidation.SHA1;
195                         EncryptSign_RoundTrip (section);
196                 }
197                 [Test]
198                 public void EncryptSign_RoundTrip_HMACSHA256 ()
199                 {
200                         MachineKeySection section = new MachineKeySection ();
201                         section.Validation = MachineKeyValidation.HMACSHA256;
202                         EncryptSign_RoundTrip (section);
203                 }
204
205                 [Test]
206                 public void EncryptSign_RoundTrip_HMACSHA384 ()
207                 {
208                         MachineKeySection section = new MachineKeySection ();
209                         section.Validation = MachineKeyValidation.HMACSHA384;
210                         EncryptSign_RoundTrip (section);
211                 }
212
213                 [Test]
214                 public void EncryptSign_RoundTrip_HMACSHA512 ()
215                 {
216                         MachineKeySection section = new MachineKeySection ();
217                         section.Validation = MachineKeyValidation.HMACSHA512;
218                         EncryptSign_RoundTrip (section);
219                 }
220
221                 [Test]
222                 public void EncryptSign_RoundTrip_Custom_RIPEMD160 ()
223                 {
224                         MachineKeySection section = new MachineKeySection ();
225                         section.ValidationAlgorithm = "alg:HMACRIPEMD160";
226                         EncryptSign_RoundTrip (section);
227                 }
228                 public void Validation_RoundTrip (MachineKeySection section)
229                 {
230                         byte [] data = new byte [] { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 };
231                         byte [] block = MachineKeySectionUtils.Sign (section, data);
232                         Assert.AreEqual (data, MachineKeySectionUtils.Verify (section, block), "OK");
233
234                         // changing last byte
235                         for (int i = 0; i < data.Length; i++) {
236                                 byte b = block [i];
237                                 block [i] = ChangeByte (b);
238                                 Assert.IsNull (MachineKeySectionUtils.Verify (section, block), "bad-" + i.ToString ());
239                                 block [i] = b;
240                         }
241                 }
242
243                 [Test]
244                 public void Validation_RoundTrip_Default ()
245                 {
246                         Validation_RoundTrip (new MachineKeySection ());
247                 }
248
249                 [Test]
250                 public void Validation_RoundTrip_AES ()
251                 {
252                         MachineKeySection section = new MachineKeySection ();
253                         section.Validation = MachineKeyValidation.AES;
254                         Validation_RoundTrip (section);
255                 }
256
257                 [Test]
258                 public void Validation_RoundTrip_TripleDES ()
259                 {
260                         MachineKeySection section = new MachineKeySection ();
261                         section.Validation = MachineKeyValidation.TripleDES;
262                         Validation_RoundTrip (section);
263                 }
264
265                 [Test]
266                 public void Validation_RoundTrip_MD5 ()
267                 {
268                         MachineKeySection section = new MachineKeySection ();
269                         section.Validation = MachineKeyValidation.MD5;
270                         Validation_RoundTrip (section);
271                 }
272
273                 [Test]
274                 public void Validation_RoundTrip_SHA1 ()
275                 {
276                         MachineKeySection section = new MachineKeySection ();
277                         section.Validation = MachineKeyValidation.SHA1;
278                         Validation_RoundTrip (section);
279                 }
280
281                 [Test]
282                 public void Validation_RoundTrip_HMACSHA256 ()
283                 {
284                         MachineKeySection section = new MachineKeySection ();
285                         section.Validation = MachineKeyValidation.HMACSHA256;
286                         Validation_RoundTrip (section);
287                 }
288
289                 [Test]
290                 public void Validation_RoundTrip_HMACSHA384 ()
291                 {
292                         MachineKeySection section = new MachineKeySection ();
293                         section.Validation = MachineKeyValidation.HMACSHA384;
294                         Validation_RoundTrip (section);
295                 }
296
297                 [Test]
298                 public void Validation_RoundTrip_HMACSHA512 ()
299                 {
300                         MachineKeySection section = new MachineKeySection ();
301                         section.Validation = MachineKeyValidation.HMACSHA512;
302                         Validation_RoundTrip (section);
303                 }
304
305                 [Test]
306                 public void Validation_RoundTrip_Custom_RIPEMD160 ()
307                 {
308                         MachineKeySection section = new MachineKeySection ();
309                         section.ValidationAlgorithm = "alg:HMACRIPEMD160";
310                         Validation_RoundTrip (section);
311                 }
312                 [Test]
313                 public void GetHexString ()
314                 {
315                         Assert.AreEqual ("DEADC0DE", MachineKeySectionUtils.GetHexString (new byte [] { 0xde, 0xad, 0xc0, 0xde }), "deadcode");
316                 }
317         }
318 }
319