1 //
2 // RSAPKCS1SignatureFormatterTest.cs - NUnit tests for PKCS#1 v.1.5 signature.
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-2005, 2011 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.Security.Cryptography;
33 
34 namespace MonoTests.System.Security.Cryptography {
35 
36 	[TestFixture]
37 	public class RSAPKCS1SignatureFormatterTest {
38 
39 		private static byte[] signatureRSASHA256 = { 0xAD, 0x6E, 0x29, 0xC8, 0x7D, 0xFE, 0x5F, 0xB3, 0x92, 0x07, 0x4C, 0x51, 0x08, 0xC5, 0x91, 0xA2, 0xCF, 0x7E, 0xA6, 0x05, 0x66, 0x85, 0xA3, 0x8E, 0x7C, 0xB0, 0xCA, 0x93, 0x4F, 0x4E, 0xF5, 0x45, 0x0F, 0xED, 0x46, 0xFB, 0x34, 0xBC, 0x8A, 0x6A, 0x48, 0xD9, 0x76, 0x28, 0xE1, 0x68, 0xA0, 0x1F, 0x7F, 0x3E, 0xCC, 0x0A, 0x5F, 0x06, 0x8E, 0xEB, 0xB7, 0xA7, 0x48, 0x6B, 0x92, 0x1A, 0x7A, 0x66, 0x42, 0x4F, 0x0B, 0xC1, 0x19, 0x96, 0xAC, 0x67, 0xA0, 0x6C, 0x3E, 0x39, 0xD2, 0xEB, 0xCA, 0xD7, 0x12, 0x29, 0x46, 0x0A, 0x60, 0x70, 0xA9, 0x2B, 0x80, 0x9F, 0xCD, 0x08, 0x02, 0xEB, 0xA5, 0x62, 0xEC, 0xAB, 0xBB, 0x64, 0x8B, 0x2D, 0xB9, 0x55, 0x0A, 0xE3, 0x5A, 0x2C, 0xDA, 0x54, 0xD4, 0x79, 0x0A, 0x8D, 0xB6, 0x57, 0x05, 0xF7, 0x6C, 0x6D, 0xB7, 0xD8, 0xB4, 0x07, 0xC4, 0xCD, 0x79, 0xD4 };
40 		private static byte[] signatureRSASHA384 = { 0x53, 0x80, 0xFD, 0x26, 0x8F, 0xCF, 0xE5, 0x44, 0x55, 0x4A, 0xC5, 0xB2, 0x46, 0x78, 0x89, 0x42, 0xF8, 0x51, 0xB8, 0x4D, 0x3B, 0xCA, 0x48, 0x5A, 0x36, 0x9F, 0x62, 0x01, 0x72, 0x1E, 0xD8, 0x2D, 0xC2, 0x2D, 0x3E, 0x67, 0x1C, 0x5D, 0x89, 0xAB, 0x39, 0x8D, 0x07, 0xC8, 0xD4, 0x47, 0x97, 0xA4, 0x68, 0x7A, 0x87, 0xA4, 0xCF, 0x7B, 0x32, 0x4F, 0xD3, 0xD1, 0x90, 0xDC, 0x76, 0x23, 0x51, 0xA7, 0xEE, 0xFC, 0x7F, 0xDF, 0x3C, 0xB0, 0x05, 0xF3, 0xE3, 0xAA, 0x96, 0x30, 0xE0, 0xE4, 0x8B, 0x09, 0xB1, 0x78, 0xAC, 0x99, 0xDB, 0xC5, 0x0E, 0xFA, 0xAB, 0x4F, 0xA1, 0x02, 0xCA, 0x77, 0x93, 0x74, 0x5A, 0xB8, 0x71, 0x9C, 0x3E, 0x2E, 0xAE, 0x62, 0xC7, 0xE5, 0xBF, 0xDA, 0xFE, 0x31, 0xA7, 0x91, 0xC0, 0x04, 0xE3, 0x95, 0xCB, 0x3F, 0x54, 0xA8, 0x09, 0x25, 0xF7, 0x09, 0x78, 0xE6, 0x09, 0x84 };
41 		private static byte[] signatureRSASHA512 = { 0xA8, 0xD0, 0x24, 0xCB, 0xA2, 0x4B, 0x5E, 0x0D, 0xBC, 0x3F, 0x6F, 0x0F, 0x8D, 0xE4, 0x31, 0x9E, 0x37, 0x84, 0xE0, 0x31, 0x5B, 0x63, 0x24, 0xC5, 0xA9, 0x05, 0x41, 0xAA, 0x69, 0x02, 0x8F, 0xC1, 0x57, 0x06, 0x1F, 0xBF, 0x3B, 0x8B, 0xC8, 0x86, 0xB3, 0x02, 0xEA, 0xF1, 0x75, 0xE4, 0x70, 0x21, 0x1E, 0x16, 0x4C, 0x37, 0xB2, 0x31, 0x78, 0xD0, 0xA0, 0x88, 0xA5, 0x1D, 0x5D, 0x8F, 0xBC, 0xC3, 0x87, 0x94, 0x4B, 0x8F, 0x4E, 0x92, 0xBC, 0x80, 0xF8, 0xA5, 0x90, 0xF7, 0xA0, 0x6D, 0x96, 0x61, 0x65, 0x0D, 0xD5, 0x3F, 0xD7, 0x4F, 0x07, 0x58, 0x40, 0xB8, 0xA4, 0x14, 0x14, 0x55, 0x39, 0x4F, 0xF0, 0xB5, 0x56, 0x99, 0xC8, 0x52, 0x0C, 0xDD, 0xBA, 0x8D, 0xFB, 0x06, 0x83, 0x6E, 0x79, 0x25, 0x75, 0xEF, 0x0D, 0x26, 0x14, 0x3A, 0xBB, 0x62, 0x29, 0x21, 0xF6, 0x4B, 0x9E, 0x87, 0x28, 0x57 };
42 
43 		private static RSA rsa;
44 		private static DSA dsa;
45 
46 		private RSAPKCS1SignatureFormatter fmt;
47 
48 		[SetUp]
SetUp()49 		public void SetUp ()
50 		{
51 			if (rsa == null) {
52 				rsa = RSA.Create ();
53 				rsa.ImportParameters (AllTests.GetRsaKey (true));
54 			}
55 			if (dsa == null)
56 				dsa = DSA.Create ();
57 		}
58 
AssertEquals(string msg, byte[] array1, byte[] array2)59 		public void AssertEquals (string msg, byte[] array1, byte[] array2)
60 		{
61 			Assert.AreEqual (array1, array2, msg);
62 		}
63 
64 		[Test]
ConstructorEmpty()65 		public void ConstructorEmpty ()
66 		{
67 			fmt = new RSAPKCS1SignatureFormatter ();
68 			Assert.IsNotNull (fmt);
69 		}
70 
71 		[Test]
72 		[ExpectedException (typeof (ArgumentNullException))]
ConstructorNull()73 		public void ConstructorNull ()
74 		{
75 			new RSAPKCS1SignatureFormatter (null);
76 		}
77 
78 		[Test]
ConstructorRSA()79 		public void ConstructorRSA ()
80 		{
81 			fmt = new RSAPKCS1SignatureFormatter (rsa);
82 			Assert.IsNotNull (fmt);
83 		}
84 
85 		[Test]
86 		[ExpectedException (typeof (InvalidCastException))]
ConstructorDSA()87 		public void ConstructorDSA ()
88 		{
89 			fmt = new RSAPKCS1SignatureFormatter (dsa);
90 		}
91 
92 		[Test]
SetKeyRSA()93 		public void SetKeyRSA ()
94 		{
95 			fmt = new RSAPKCS1SignatureFormatter ();
96 			fmt.SetKey (rsa);
97 		}
98 
99 		[Test]
100 		[ExpectedException (typeof (InvalidCastException))]
SetKeyDSA()101 		public void SetKeyDSA ()
102 		{
103 			fmt = new RSAPKCS1SignatureFormatter ();
104 			fmt.SetKey (dsa);
105 		}
106 
107 		[Test]
108 		[ExpectedException (typeof (ArgumentNullException))]
SetKeyNull()109 		public void SetKeyNull ()
110 		{
111 			fmt = new RSAPKCS1SignatureFormatter ();
112 			fmt.SetKey (null);
113 		}
114 
115 		[Test]
SetHashAlgorithmSHA1()116 		public void SetHashAlgorithmSHA1 ()
117 		{
118 			fmt = new RSAPKCS1SignatureFormatter ();
119 			fmt.SetHashAlgorithm ("SHA1");
120 		}
121 
122 		[Test]
SetHashAlgorithmMD5()123 		public void SetHashAlgorithmMD5 ()
124 		{
125 			fmt = new RSAPKCS1SignatureFormatter ();
126 			fmt.SetHashAlgorithm ("MD5");
127 		}
128 
129 		[Test]
SetHashAlgorithmSHA256()130 		public void SetHashAlgorithmSHA256 ()
131 		{
132 			fmt = new RSAPKCS1SignatureFormatter ();
133 			fmt.SetHashAlgorithm ("SHA256");
134 		}
135 
136 		[Test]
SetHashAlgorithmSHA384()137 		public void SetHashAlgorithmSHA384 ()
138 		{
139 			fmt = new RSAPKCS1SignatureFormatter ();
140 			fmt.SetHashAlgorithm ("SHA384");
141 		}
142 
143 		[Test]
SetHashAlgorithmSHA512()144 		public void SetHashAlgorithmSHA512 ()
145 		{
146 			fmt = new RSAPKCS1SignatureFormatter ();
147 			fmt.SetHashAlgorithm ("SHA512");
148 		}
149 
150 		[Test]
151 		[ExpectedException (typeof (ArgumentNullException))]
SetHashAlgorithmNull()152 		public void SetHashAlgorithmNull ()
153 		{
154 			fmt = new RSAPKCS1SignatureFormatter ();
155 			fmt.SetHashAlgorithm (null);
156 		}
157 
158 		// see: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpcongeneratingsignatures.asp
159 
160 		[Test]
161 		[ExpectedException (typeof (CryptographicUnexpectedOperationException))]
CreateSignatureNullHash()162 		public void CreateSignatureNullHash ()
163 		{
164 			fmt = new RSAPKCS1SignatureFormatter ();
165 			fmt.SetKey (rsa);
166 			byte[] hash = null;
167 			byte[] signature = fmt.CreateSignature (hash);
168 		}
169 
170 		[Test]
171 		[ExpectedException (typeof (CryptographicUnexpectedOperationException))]
CreateSignatureNoHashAlgorithm()172 		public void CreateSignatureNoHashAlgorithm ()
173 		{
174 			fmt = new RSAPKCS1SignatureFormatter ();
175 			// no hash algorithm
176 			byte[] hash = new byte [1];
177 			byte[] signature = fmt.CreateSignature (hash);
178 		}
179 
180 		[Test]
181 		[ExpectedException (typeof (CryptographicUnexpectedOperationException))]
CreateSignatureNoKey()182 		public void CreateSignatureNoKey ()
183 		{
184 			fmt = new RSAPKCS1SignatureFormatter ();
185 			// no key
186 			fmt.SetHashAlgorithm ("SHA1");
187 			byte[] hash = new byte [20];
188 			byte[] signature = fmt.CreateSignature (hash);
189 		}
190 
191 		[Test]
CreateSignatureRSASHA1()192 		public void CreateSignatureRSASHA1 ()
193 		{
194 			fmt = new RSAPKCS1SignatureFormatter ();
195 			// we need the private key
196 			fmt.SetKey (rsa);
197 			// good SHA1
198 			fmt.SetHashAlgorithm ("SHA1");
199 			byte[] hash = new byte [20];
200 			byte[] signature = fmt.CreateSignature (hash);
201 			Assert.IsNotNull (fmt);
202 		}
203 
204 		[Test]
205 		[ExpectedException (typeof (CryptographicException))]
CreateSignatureRSASHA1BadLength()206 		public void CreateSignatureRSASHA1BadLength ()
207 		{
208 			fmt = new RSAPKCS1SignatureFormatter ();
209 			// we need the private key
210 			fmt.SetKey (rsa);
211 			// wrong length SHA1
212 			fmt.SetHashAlgorithm ("SHA1");
213 			byte[] hash = new byte [19];
214 			byte[] signature = fmt.CreateSignature (hash);
215 		}
216 
217 		[Test]
CreateSignatureRSAMD5()218 		public void CreateSignatureRSAMD5 ()
219 		{
220 			fmt = new RSAPKCS1SignatureFormatter ();
221 			// we need the private key
222 			fmt.SetKey (rsa);
223 			// good MD5
224 			fmt.SetHashAlgorithm ("MD5");
225 			byte[] hash = new byte [16];
226 			byte[] signature = fmt.CreateSignature (hash);
227 			Assert.IsNotNull (fmt);
228 		}
229 
CreateSignature(string hashName, int hashSize)230 		private byte[] CreateSignature (string hashName, int hashSize)
231 		{
232 			fmt = new RSAPKCS1SignatureFormatter ();
233 
234 			// we need the private key
235 			RSA rsa = RSA.Create ("Mono.Security.Cryptography.RSAManaged");	// only available with Mono::
236 			if (rsa == null) {
237 				rsa = RSA.Create ();
238 			}
239 			rsa.ImportParameters (AllTests.GetRsaKey (true));
240 			fmt.SetKey (rsa);
241 
242 			HashAlgorithm ha = HashAlgorithm.Create (hashName);
243 			byte[] data = new byte [ha.HashSize >> 3];
244 			// this way we get the same results as CreateSignatureHash
245 			data = ha.ComputeHash (data);
246 
247 			fmt.SetHashAlgorithm (hashName);
248 			return fmt.CreateSignature (data);
249 		}
250 
251 		// historical note: this was not supported using MS framework 1.0 and 1.1 (CryptographicException)
252 		// but was supported by Mono:: - it's also supported on 2.0+ (at least on Win XP+)
253 		[Test]
CreateSignatureRSASHA256()254 		public void CreateSignatureRSASHA256 ()
255 		{
256 			byte[] signature = CreateSignature ("SHA256", 32);
257 			AssertEquals ("CreateSignature(SHA256)", signatureRSASHA256, signature);
258 		}
259 
260 		// historical note: this was not supported using MS framework 1.0 and 1.1 (CryptographicException)
261 		// but was supported by Mono:: - it's also supported on 2.0+ (at least on Win XP+)
262 		[Test]
CreateSignatureRSASHA384()263 		public void CreateSignatureRSASHA384 ()
264 		{
265 			byte[] signature = CreateSignature ("SHA384", 48);
266 			AssertEquals ("CreateSignature(SHA384)", signatureRSASHA384, signature);
267 		}
268 
269 		// historical note: this was not supported using MS framework 1.0 and 1.1 (CryptographicException)
270 		// but was supported by Mono:: - it's also supported on 2.0+ (at least on Win XP+)
271 		[Test]
CreateSignatureRSASHA512()272 		public void CreateSignatureRSASHA512 ()
273 		{
274 			byte[] signature = CreateSignature ("SHA512", 64);
275 			AssertEquals ("CreateSignature(SHA512)", signatureRSASHA512, signature);
276 		}
277 
278 		[Test]
279 		[ExpectedException (typeof (CryptographicUnexpectedOperationException))]
CreateSignatureRSABadHash()280 		public void CreateSignatureRSABadHash ()
281 		{
282 			fmt = new RSAPKCS1SignatureFormatter ();
283 			// we need the private key
284 			fmt.SetKey (rsa);
285 			// null (bad ;-)
286 			byte[] hash = null;
287 			byte[] signature  = fmt.CreateSignature (hash);
288 		}
289 
290 		[Test]
291 		[ExpectedException (typeof (ArgumentNullException))]
CreateSignatureHashBadHash()292 		public void CreateSignatureHashBadHash ()
293 		{
294 			fmt = new RSAPKCS1SignatureFormatter ();
295 			HashAlgorithm hash = null;
296 			byte[] data = new byte [20];
297 			// no hash algorithm
298 			byte[] signature = fmt.CreateSignature (hash);
299 		}
300 
301 		[Test]
302 		[ExpectedException (typeof (CryptographicUnexpectedOperationException))]
CreateSignatureHashNoKey()303 		public void CreateSignatureHashNoKey ()
304 		{
305 			fmt = new RSAPKCS1SignatureFormatter ();
306 			byte[] data = new byte [20];
307 			// no key
308 			HashAlgorithm hash = SHA1.Create ();
309 			hash.ComputeHash (data);
310 			byte[] signature = fmt.CreateSignature (hash);
311 		}
312 
313 		[Test]
CreateSignatureHashSHA1()314 		public void CreateSignatureHashSHA1 ()
315 		{
316 			fmt = new RSAPKCS1SignatureFormatter ();
317 			byte[] data = new byte [20];
318 			// we need the private key
319 			fmt.SetKey (rsa);
320 			// good SHA1
321 			HashAlgorithm hash = SHA1.Create ();
322 			hash.ComputeHash (data);
323 			byte[] signature = fmt.CreateSignature (hash);
324 			Assert.IsNotNull (signature);
325 		}
326 
327 		[Test]
CreateSignatureHashMD5()328 		public void CreateSignatureHashMD5 ()
329 		{
330 			fmt = new RSAPKCS1SignatureFormatter ();
331 			byte[] data = new byte [16];
332 			// we need the private key
333 			fmt.SetKey (rsa);
334 			// good MD5
335 			HashAlgorithm hash = MD5.Create ();
336 			hash.ComputeHash (data);
337 			byte[] signature = fmt.CreateSignature (hash);
338 			Assert.IsNotNull (signature);
339 		}
340 
CreateSignatureHash(string hashName)341 		private byte[] CreateSignatureHash (string hashName)
342 		{
343 			fmt = new RSAPKCS1SignatureFormatter ();
344 
345 			// we need the private key
346 			RSA rsa = RSA.Create ("Mono.Security.Cryptography.RSAManaged");	// only available with Mono::
347 			if (rsa == null) {
348 				rsa = RSA.Create ();
349 			}
350 			rsa.ImportParameters (AllTests.GetRsaKey (true));
351 			fmt.SetKey (rsa);
352 
353 			HashAlgorithm hash = HashAlgorithm.Create (hashName);
354 			byte[] data = new byte [(hash.HashSize >> 3)];
355 			hash.ComputeHash (data);
356 			return fmt.CreateSignature (hash);
357 		}
358 
359 		// historical note: this was not supported using MS framework 1.0 and 1.1 (CryptographicException)
360 		// but was supported by Mono:: - it's also supported on 2.0+ (at least on Win XP+)
361 		[Test]
CreateSignatureHashSHA256()362 		public void CreateSignatureHashSHA256 ()
363 		{
364 			byte[] signature = CreateSignatureHash ("SHA256");
365 			AssertEquals ("CreateSignatureHash(SHA256)", signatureRSASHA256, signature);
366 		}
367 
368 		// historical note: this was not supported using MS framework 1.0 and 1.1 (CryptographicException)
369 		// but was supported by Mono:: - it's also supported on 2.0+ (at least on Win XP+)
370 		[Test]
CreateSignatureHashSHA384()371 		public void CreateSignatureHashSHA384 ()
372 		{
373 			byte[] signature = CreateSignatureHash ("SHA384");
374 			AssertEquals ("CreateSignatureHash(SHA384)", signatureRSASHA384, signature);
375 		}
376 
377 		// historical note: this was not supported using MS framework 1.0 and 1.1 (CryptographicException)
378 		// but was supported by Mono:: - it's also supported on 2.0+ (at least on Win XP+)
379 		[Test]
CreateSignatureHashSHA512()380 		public void CreateSignatureHashSHA512 ()
381 		{
382 			byte[] signature = CreateSignatureHash ("SHA512");
383 			AssertEquals ("CreateSignatureHash(SHA512)", signatureRSASHA512, signature);
384 		}
385 	}
386 }
387