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