Merge pull request #642 from Ventero/CleanCopyLocal
[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 #if NET_4_0
111                 [Test]
112                 public void Encrypt_RoundTrip_HMACSHA256 ()
113                 {
114                         MachineKeySection section = new MachineKeySection ();
115                         section.Validation = MachineKeyValidation.HMACSHA256;
116                         EncryptSign_RoundTrip (section);
117                 }
118
119                 [Test]
120                 public void Encrypt_RoundTrip_HMACSHA384 ()
121                 {
122                         MachineKeySection section = new MachineKeySection ();
123                         section.Validation = MachineKeyValidation.HMACSHA384;
124                         EncryptSign_RoundTrip (section);
125                 }
126
127                 [Test]
128                 public void Encrypt_RoundTrip_HMACSHA512 ()
129                 {
130                         MachineKeySection section = new MachineKeySection ();
131                         section.Validation = MachineKeyValidation.HMACSHA512;
132                         EncryptSign_RoundTrip (section);
133                 }
134
135                 [Test]
136                 public void Encrypt_RoundTrip_Custom_RIPEMD160 ()
137                 {
138                         MachineKeySection section = new MachineKeySection ();
139                         section.ValidationAlgorithm = "alg:HMACRIPEMD160";
140                         EncryptSign_RoundTrip (section);
141                 }
142 #endif
143                 public void EncryptSign_RoundTrip (MachineKeySection section)
144                 {
145                         byte [] data = new byte [14];
146                         byte [] block = MachineKeySectionUtils.EncryptSign (section, data);
147                         byte [] decdata = MachineKeySectionUtils.VerifyDecrypt (section, block);
148                         Assert.AreEqual (data, decdata, "roundtrip");
149
150                         // changing a byte of the data
151                         byte b0 = block [0];
152                         block [0] = ChangeByte (b0);
153                         Assert.IsNull (MachineKeySectionUtils.VerifyDecrypt (section, block), "bad data");
154                         block [0] = b0;
155
156                         // changing a byte of the signature
157                         byte be = block [block.Length - 1];
158                         block [block.Length - 1] = ChangeByte (be);
159                         Assert.IsNull (MachineKeySectionUtils.VerifyDecrypt (section, block), "bad signature");
160                 }
161
162                 [Test]
163                 public void EncryptSign_RoundTrip_Default ()
164                 {
165                         EncryptSign_RoundTrip (new MachineKeySection ());
166                 }
167
168                 [Test]
169                 public void EncryptSign_RoundTrip_AES ()
170                 {
171                         MachineKeySection section = new MachineKeySection ();
172                         section.Validation = MachineKeyValidation.AES;
173                         EncryptSign_RoundTrip (section);
174                 }
175
176                 [Test]
177                 public void EncryptSign_RoundTrip_TripleDES ()
178                 {
179                         MachineKeySection section = new MachineKeySection ();
180                         section.Validation = MachineKeyValidation.TripleDES;
181                         EncryptSign_RoundTrip (section);
182                 }
183
184                 [Test]
185                 public void EncryptSign_RoundTrip_MD5 ()
186                 {
187                         MachineKeySection section = new MachineKeySection ();
188                         section.Validation = MachineKeyValidation.MD5;
189                         EncryptSign_RoundTrip (section);
190                 }
191
192                 [Test]
193                 public void EncryptSign_RoundTrip_SHA1 ()
194                 {
195                         MachineKeySection section = new MachineKeySection ();
196                         section.Validation = MachineKeyValidation.SHA1;
197                         EncryptSign_RoundTrip (section);
198                 }
199 #if NET_4_0
200                 [Test]
201                 public void EncryptSign_RoundTrip_HMACSHA256 ()
202                 {
203                         MachineKeySection section = new MachineKeySection ();
204                         section.Validation = MachineKeyValidation.HMACSHA256;
205                         EncryptSign_RoundTrip (section);
206                 }
207
208                 [Test]
209                 public void EncryptSign_RoundTrip_HMACSHA384 ()
210                 {
211                         MachineKeySection section = new MachineKeySection ();
212                         section.Validation = MachineKeyValidation.HMACSHA384;
213                         EncryptSign_RoundTrip (section);
214                 }
215
216                 [Test]
217                 public void EncryptSign_RoundTrip_HMACSHA512 ()
218                 {
219                         MachineKeySection section = new MachineKeySection ();
220                         section.Validation = MachineKeyValidation.HMACSHA512;
221                         EncryptSign_RoundTrip (section);
222                 }
223
224                 [Test]
225                 public void EncryptSign_RoundTrip_Custom_RIPEMD160 ()
226                 {
227                         MachineKeySection section = new MachineKeySection ();
228                         section.ValidationAlgorithm = "alg:HMACRIPEMD160";
229                         EncryptSign_RoundTrip (section);
230                 }
231 #endif
232                 public void Validation_RoundTrip (MachineKeySection section)
233                 {
234                         byte [] data = new byte [] { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 };
235                         byte [] block = MachineKeySectionUtils.Sign (section, data);
236                         Assert.AreEqual (data, MachineKeySectionUtils.Verify (section, block), "OK");
237
238                         // changing last byte
239                         for (int i = 0; i < data.Length; i++) {
240                                 byte b = block [i];
241                                 block [i] = ChangeByte (b);
242                                 Assert.IsNull (MachineKeySectionUtils.Verify (section, block), "bad-" + i.ToString ());
243                                 block [i] = b;
244                         }
245                 }
246
247                 [Test]
248                 public void Validation_RoundTrip_Default ()
249                 {
250                         Validation_RoundTrip (new MachineKeySection ());
251                 }
252
253                 [Test]
254                 public void Validation_RoundTrip_AES ()
255                 {
256                         MachineKeySection section = new MachineKeySection ();
257                         section.Validation = MachineKeyValidation.AES;
258                         Validation_RoundTrip (section);
259                 }
260
261                 [Test]
262                 public void Validation_RoundTrip_TripleDES ()
263                 {
264                         MachineKeySection section = new MachineKeySection ();
265                         section.Validation = MachineKeyValidation.TripleDES;
266                         Validation_RoundTrip (section);
267                 }
268
269                 [Test]
270                 public void Validation_RoundTrip_MD5 ()
271                 {
272                         MachineKeySection section = new MachineKeySection ();
273                         section.Validation = MachineKeyValidation.MD5;
274                         Validation_RoundTrip (section);
275                 }
276
277                 [Test]
278                 public void Validation_RoundTrip_SHA1 ()
279                 {
280                         MachineKeySection section = new MachineKeySection ();
281                         section.Validation = MachineKeyValidation.SHA1;
282                         Validation_RoundTrip (section);
283                 }
284
285 #if NET_4_0
286                 [Test]
287                 public void Validation_RoundTrip_HMACSHA256 ()
288                 {
289                         MachineKeySection section = new MachineKeySection ();
290                         section.Validation = MachineKeyValidation.HMACSHA256;
291                         Validation_RoundTrip (section);
292                 }
293
294                 [Test]
295                 public void Validation_RoundTrip_HMACSHA384 ()
296                 {
297                         MachineKeySection section = new MachineKeySection ();
298                         section.Validation = MachineKeyValidation.HMACSHA384;
299                         Validation_RoundTrip (section);
300                 }
301
302                 [Test]
303                 public void Validation_RoundTrip_HMACSHA512 ()
304                 {
305                         MachineKeySection section = new MachineKeySection ();
306                         section.Validation = MachineKeyValidation.HMACSHA512;
307                         Validation_RoundTrip (section);
308                 }
309
310                 [Test]
311                 public void Validation_RoundTrip_Custom_RIPEMD160 ()
312                 {
313                         MachineKeySection section = new MachineKeySection ();
314                         section.ValidationAlgorithm = "alg:HMACRIPEMD160";
315                         Validation_RoundTrip (section);
316                 }
317 #endif
318                 [Test]
319                 public void GetHexString ()
320                 {
321                         Assert.AreEqual ("DEADC0DE", MachineKeySectionUtils.GetHexString (new byte [] { 0xde, 0xad, 0xc0, 0xde }), "deadcode");
322                 }
323         }
324 }
325