1 /* 2 * Miscellaneous crypt32 tests 3 * 4 * Copyright 2005 Juan Lang 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #include "precomp.h" 22 23 static HMODULE hCrypt; 24 25 static void test_findAttribute(void) 26 { 27 PCRYPT_ATTRIBUTE ret; 28 BYTE blobbin[] = {0x02,0x01,0x01}; 29 static CHAR oid[] = "1.2.3"; 30 CRYPT_ATTR_BLOB blobs[] = { { sizeof blobbin, blobbin }, }; 31 CRYPT_ATTRIBUTE attr = { oid, sizeof(blobs) / sizeof(blobs[0]), blobs }; 32 33 /* returns NULL, last error not set */ 34 SetLastError(0xdeadbeef); 35 ret = CertFindAttribute(NULL, 0, NULL); 36 ok(ret == NULL, "Expected failure\n"); 37 ok(GetLastError() == 0xdeadbeef, "Last error was set to %08x\n", 38 GetLastError()); 39 if (0) 40 { 41 /* crashes */ 42 CertFindAttribute(NULL, 1, NULL); 43 /* returns NULL, last error is ERROR_INVALID_PARAMETER 44 * crashes on Vista 45 */ 46 SetLastError(0xdeadbeef); 47 ret = CertFindAttribute(NULL, 1, &attr); 48 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 49 "Expected ERROR_INVALID_PARAMETER, got %d (%08x)\n", GetLastError(), 50 GetLastError()); 51 } 52 /* returns NULL, last error not set */ 53 SetLastError(0xdeadbeef); 54 ret = CertFindAttribute("bogus", 1, &attr); 55 ok(ret == NULL, "Expected failure\n"); 56 ok(GetLastError() == 0xdeadbeef, "Last error was set to %08x\n", 57 GetLastError()); 58 /* returns NULL, last error not set */ 59 SetLastError(0xdeadbeef); 60 ret = CertFindAttribute("1.2.4", 1, &attr); 61 ok(ret == NULL, "Expected failure\n"); 62 ok(GetLastError() == 0xdeadbeef, "Last error was set to %08x\n", 63 GetLastError()); 64 /* succeeds, last error not set */ 65 SetLastError(0xdeadbeef); 66 ret = CertFindAttribute("1.2.3", 1, &attr); 67 ok(ret != NULL, "CertFindAttribute failed: %08x\n", GetLastError()); 68 } 69 70 static void test_findExtension(void) 71 { 72 PCERT_EXTENSION ret; 73 static CHAR oid[] = "1.2.3"; 74 BYTE blobbin[] = {0x02,0x01,0x01}; 75 CERT_EXTENSION ext = { oid, TRUE, { sizeof blobbin, blobbin } }; 76 77 /* returns NULL, last error not set */ 78 SetLastError(0xdeadbeef); 79 ret = CertFindExtension(NULL, 0, NULL); 80 ok(ret == NULL, "Expected failure\n"); 81 ok(GetLastError() == 0xdeadbeef, "Last error was set to %08x\n", 82 GetLastError()); 83 if (0) 84 { 85 /* crashes */ 86 SetLastError(0xdeadbeef); 87 CertFindExtension(NULL, 1, NULL); 88 /* returns NULL, last error is ERROR_INVALID_PARAMETER 89 * crashes on Vista 90 */ 91 SetLastError(0xdeadbeef); 92 ret = CertFindExtension(NULL, 1, &ext); 93 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 94 "Expected ERROR_INVALID_PARAMETER, got %d (%08x)\n", GetLastError(), 95 GetLastError()); 96 } 97 /* returns NULL, last error not set */ 98 SetLastError(0xdeadbeef); 99 ret = CertFindExtension("bogus", 1, &ext); 100 ok(ret == NULL, "Expected failure\n"); 101 ok(GetLastError() == 0xdeadbeef, "Last error was set to %08x\n", 102 GetLastError()); 103 /* returns NULL, last error not set */ 104 SetLastError(0xdeadbeef); 105 ret = CertFindExtension("1.2.4", 1, &ext); 106 ok(ret == NULL, "Expected failure\n"); 107 ok(GetLastError() == 0xdeadbeef, "Last error was set to %08x\n", 108 GetLastError()); 109 /* succeeds, last error not set */ 110 SetLastError(0xdeadbeef); 111 ret = CertFindExtension("1.2.3", 1, &ext); 112 ok(ret != NULL, "CertFindExtension failed: %08x\n", GetLastError()); 113 } 114 115 static void test_findRDNAttr(void) 116 { 117 PCERT_RDN_ATTR ret; 118 static CHAR oid[] = "1.2.3"; 119 BYTE bin[] = { 0x16,0x09,'J','u','a','n',' ','L','a','n','g' }; 120 CERT_RDN_ATTR attrs[] = { 121 { oid, CERT_RDN_IA5_STRING, { sizeof bin, bin } }, 122 }; 123 CERT_RDN rdns[] = { 124 { sizeof(attrs) / sizeof(attrs[0]), attrs }, 125 }; 126 CERT_NAME_INFO nameInfo = { sizeof(rdns) / sizeof(rdns[0]), rdns }; 127 128 if (0) 129 { 130 /* crashes */ 131 SetLastError(0xdeadbeef); 132 CertFindRDNAttr(NULL, NULL); 133 /* returns NULL, last error is ERROR_INVALID_PARAMETER 134 * crashes on Vista 135 */ 136 SetLastError(0xdeadbeef); 137 ret = CertFindRDNAttr(NULL, &nameInfo); 138 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 139 "Expected ERROR_INVALID_PARAMETER, got %d (%08x)\n", GetLastError(), 140 GetLastError()); 141 } 142 /* returns NULL, last error not set */ 143 SetLastError(0xdeadbeef); 144 ret = CertFindRDNAttr("bogus", &nameInfo); 145 ok(ret == NULL, "Expected failure\n"); 146 ok(GetLastError() == 0xdeadbeef, "Last error was set to %08x\n", 147 GetLastError()); 148 /* returns NULL, last error not set */ 149 SetLastError(0xdeadbeef); 150 ret = CertFindRDNAttr("1.2.4", &nameInfo); 151 ok(ret == NULL, "Expected failure\n"); 152 ok(GetLastError() == 0xdeadbeef, "Last error was set to %08x\n", 153 GetLastError()); 154 /* succeeds, last error not set */ 155 SetLastError(0xdeadbeef); 156 ret = CertFindRDNAttr("1.2.3", &nameInfo); 157 ok(ret != NULL, "CertFindRDNAttr failed: %08x\n", GetLastError()); 158 } 159 160 static void test_verifyTimeValidity(void) 161 { 162 SYSTEMTIME sysTime; 163 FILETIME fileTime; 164 CERT_INFO info = { 0 }; 165 LONG ret; 166 167 GetSystemTime(&sysTime); 168 SystemTimeToFileTime(&sysTime, &fileTime); 169 /* crashes 170 ret = CertVerifyTimeValidity(NULL, NULL); 171 ret = CertVerifyTimeValidity(&fileTime, NULL); 172 */ 173 /* Check with 0 NotBefore and NotAfter */ 174 ret = CertVerifyTimeValidity(&fileTime, &info); 175 ok(ret == 1, "Expected 1, got %d\n", ret); 176 info.NotAfter = fileTime; 177 /* Check with NotAfter equal to comparison time */ 178 ret = CertVerifyTimeValidity(&fileTime, &info); 179 ok(ret == 0, "Expected 0, got %d\n", ret); 180 /* Check with NotBefore after comparison time */ 181 info.NotBefore = fileTime; 182 info.NotBefore.dwLowDateTime += 5000; 183 ret = CertVerifyTimeValidity(&fileTime, &info); 184 ok(ret == -1, "Expected -1, got %d\n", ret); 185 } 186 187 static void test_cryptAllocate(void) 188 { 189 LPVOID buf; 190 191 buf = CryptMemAlloc(0); 192 ok(buf != NULL, "CryptMemAlloc failed: %08x\n", GetLastError()); 193 CryptMemFree(buf); 194 /* CryptMemRealloc(NULL, 0) fails pre-Vista */ 195 buf = CryptMemAlloc(0); 196 buf = CryptMemRealloc(buf, 1); 197 ok(buf != NULL, "CryptMemRealloc failed: %08x\n", GetLastError()); 198 CryptMemFree(buf); 199 } 200 201 202 static void test_cryptTls(void) 203 { 204 DWORD (WINAPI *pI_CryptAllocTls)(void); 205 LPVOID (WINAPI *pI_CryptDetachTls)(DWORD dwTlsIndex); 206 LPVOID (WINAPI *pI_CryptGetTls)(DWORD dwTlsIndex); 207 BOOL (WINAPI *pI_CryptSetTls)(DWORD dwTlsIndex, LPVOID lpTlsValue); 208 BOOL (WINAPI *pI_CryptFreeTls)(DWORD dwTlsIndex, DWORD unknown); 209 DWORD index; 210 BOOL ret; 211 212 pI_CryptAllocTls = (void *)GetProcAddress(hCrypt, "I_CryptAllocTls"); 213 pI_CryptDetachTls = (void *)GetProcAddress(hCrypt, "I_CryptDetachTls"); 214 pI_CryptGetTls = (void *)GetProcAddress(hCrypt, "I_CryptGetTls"); 215 pI_CryptSetTls = (void *)GetProcAddress(hCrypt, "I_CryptSetTls"); 216 pI_CryptFreeTls = (void *)GetProcAddress(hCrypt, "I_CryptFreeTls"); 217 218 /* One normal pass */ 219 index = pI_CryptAllocTls(); 220 ok(index, "I_CryptAllocTls failed: %08x\n", GetLastError()); 221 if (index) 222 { 223 LPVOID ptr; 224 225 ptr = pI_CryptGetTls(index); 226 ok(!ptr, "Expected NULL\n"); 227 ret = pI_CryptSetTls(index, (LPVOID)0xdeadbeef); 228 ok(ret, "I_CryptSetTls failed: %08x\n", GetLastError()); 229 ptr = pI_CryptGetTls(index); 230 ok(ptr == (LPVOID)0xdeadbeef, "Expected 0xdeadbeef, got %p\n", ptr); 231 /* This crashes 232 ret = pI_CryptFreeTls(index, 1); 233 */ 234 ret = pI_CryptFreeTls(index, 0); 235 ok(ret, "I_CryptFreeTls failed: %08x\n", GetLastError()); 236 ret = pI_CryptFreeTls(index, 0); 237 ok(!ret, "I_CryptFreeTls succeeded\n"); 238 ok(GetLastError() == E_INVALIDARG, 239 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 240 } 241 /* Similar pass, check I_CryptDetachTls */ 242 index = pI_CryptAllocTls(); 243 ok(index, "I_CryptAllocTls failed: %08x\n", GetLastError()); 244 if (index) 245 { 246 LPVOID ptr; 247 248 ptr = pI_CryptGetTls(index); 249 ok(!ptr, "Expected NULL\n"); 250 ret = pI_CryptSetTls(index, (LPVOID)0xdeadbeef); 251 ok(ret, "I_CryptSetTls failed: %08x\n", GetLastError()); 252 ptr = pI_CryptGetTls(index); 253 ok(ptr == (LPVOID)0xdeadbeef, "Expected 0xdeadbeef, got %p\n", ptr); 254 ptr = pI_CryptDetachTls(index); 255 ok(ptr == (LPVOID)0xdeadbeef, "Expected 0xdeadbeef, got %p\n", ptr); 256 ptr = pI_CryptGetTls(index); 257 ok(!ptr, "Expected NULL\n"); 258 } 259 } 260 261 static void test_readTrustedPublisherDWORD(void) 262 { 263 264 BOOL (WINAPI *pReadDWORD)(LPCWSTR, DWORD *); 265 266 pReadDWORD = (void *)GetProcAddress(hCrypt, "I_CryptReadTrustedPublisherDWORDValueFromRegistry"); 267 if (pReadDWORD) 268 { 269 static const WCHAR safer[] = { 270 'S','o','f','t','w','a','r','e','\\', 271 'P','o','l','i','c','i','e','s','\\', 272 'M','i','c','r','o','s','o','f','t','\\','S','y','s','t','e','m', 273 'C','e','r','t','i','f','i','c','a','t','e','s','\\', 274 'T','r','u','s','t','e','d','P','u','b','l','i','s','h','e','r', 275 '\\','S','a','f','e','r',0 }; 276 static const WCHAR authenticodeFlags[] = { 'A','u','t','h','e','n', 277 't','i','c','o','d','e','F','l','a','g','s',0 }; 278 BOOL ret, exists = FALSE; 279 DWORD size, readFlags = 0, returnedFlags; 280 HKEY key; 281 LONG rc; 282 283 rc = RegOpenKeyW(HKEY_LOCAL_MACHINE, safer, &key); 284 if (rc == ERROR_SUCCESS) 285 { 286 size = sizeof(readFlags); 287 rc = RegQueryValueExW(key, authenticodeFlags, NULL, NULL, 288 (LPBYTE)&readFlags, &size); 289 if (rc == ERROR_SUCCESS) 290 exists = TRUE; 291 } 292 returnedFlags = 0xdeadbeef; 293 ret = pReadDWORD(authenticodeFlags, &returnedFlags); 294 ok(ret == exists, "Unexpected return value\n"); 295 ok(readFlags == returnedFlags, 296 "Expected flags %08x, got %08x\n", readFlags, returnedFlags); 297 } 298 } 299 300 static void test_getDefaultCryptProv(void) 301 { 302 HCRYPTPROV (WINAPI *pI_CryptGetDefaultCryptProv)(DWORD w); 303 HCRYPTPROV prov; 304 305 pI_CryptGetDefaultCryptProv = (void *)GetProcAddress(hCrypt, "I_CryptGetDefaultCryptProv"); 306 if (!pI_CryptGetDefaultCryptProv) return; 307 308 prov = pI_CryptGetDefaultCryptProv(0xdeadbeef); 309 ok(prov == 0 && GetLastError() == E_INVALIDARG, 310 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 311 prov = pI_CryptGetDefaultCryptProv(PROV_RSA_FULL); 312 ok(prov == 0 && GetLastError() == E_INVALIDARG, 313 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 314 prov = pI_CryptGetDefaultCryptProv(1); 315 ok(prov == 0 && GetLastError() == E_INVALIDARG, 316 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 317 prov = pI_CryptGetDefaultCryptProv(0); 318 ok(prov != 0, "I_CryptGetDefaultCryptProv failed: %08x\n", GetLastError()); 319 CryptReleaseContext(prov, 0); 320 } 321 322 static void test_CryptInstallOssGlobal(void) 323 { 324 int (WINAPI *pI_CryptInstallOssGlobal)(DWORD,DWORD,DWORD); 325 int ret,i; 326 327 pI_CryptInstallOssGlobal = (void *)GetProcAddress(hCrypt,"I_CryptInstallOssGlobal"); 328 /* passing in some random values to I_CryptInstallOssGlobal, it always returns 9 the first time, then 10, 11 etc.*/ 329 for(i=0;i<30;i++) 330 { 331 ret = pI_CryptInstallOssGlobal(rand(),rand(),rand()); 332 ok((9+i) == ret || 333 ret == 0, /* Vista */ 334 "Expected %d or 0, got %d\n",(9+i),ret); 335 } 336 } 337 338 static const BYTE encodedInt[] = { 0x02,0x01,0x01 }; 339 static const WCHAR encodedIntStr[] = { '0','2',' ','0','1',' ','0','1',0 }; 340 static const BYTE encodedBigInt[] = { 0x02,0x1f,0x01,0x02,0x03,0x04,0x05,0x06, 341 0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15, 342 0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f }; 343 static const WCHAR encodedBigIntStr[] = { '0','2',' ','1','f',' ','0','1',' ', 344 '0','2',' ','0','3',' ','0','4',' ','0','5',' ','0','6',' ','0','7',' ','0', 345 '8',' ','0','9',' ','0','a',' ','0','b',' ','0','c',' ','0','d',' ','0','e', 346 ' ','0','f',' ','1','0',' ','1','1',' ','1','2',' ','1','3',' ','1','4',' ', 347 '1','5',' ','1','6',' ','1','7',' ','1','8',' ','1','9',' ','1','a',' ','1', 348 'b',' ','1','c',' ','1','d',' ','1','e',' ','1','f',0 }; 349 350 static void test_format_object(void) 351 { 352 BOOL (WINAPI *pCryptFormatObject)(DWORD dwEncoding, DWORD dwFormatType, 353 DWORD dwFormatStrType, void *pFormatStruct, LPCSTR lpszStructType, 354 const BYTE *pbEncoded, DWORD dwEncoded, void *pbFormat, 355 DWORD *pcbFormat); 356 BOOL ret; 357 DWORD size; 358 LPWSTR str; 359 360 pCryptFormatObject = (void *)GetProcAddress(hCrypt, "CryptFormatObject"); 361 if (!pCryptFormatObject) 362 { 363 skip("No CryptFormatObject\n"); 364 return; 365 } 366 /* Crash */ 367 if (0) 368 { 369 pCryptFormatObject(0, 0, 0, NULL, NULL, NULL, 0, NULL, NULL); 370 } 371 /* When called with any but the default encoding, it fails to find a 372 * formatting function. 373 */ 374 SetLastError(0xdeadbeef); 375 ret = pCryptFormatObject(0, 0, 0, NULL, NULL, NULL, 0, NULL, &size); 376 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, 377 "expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError()); 378 /* When called with the default encoding type for any undefined struct type 379 * (including none), it succeeds: the default encoding is a hex string 380 * encoding. 381 */ 382 SetLastError(0xdeadbeef); 383 ret = pCryptFormatObject(X509_ASN_ENCODING, 0, 0, NULL, NULL, NULL, 0, 384 NULL, &size); 385 ok(ret, "CryptFormatObject failed: %d\n", GetLastError()); 386 if (ret) 387 { 388 if (size == 0 && GetLastError() == ERROR_FILE_NOT_FOUND) 389 { 390 win_skip("CryptFormatObject has no default implementation\n"); 391 return; 392 } 393 ok(size == sizeof(WCHAR), "unexpected size %d\n", size); 394 str = HeapAlloc(GetProcessHeap(), 0, size); 395 SetLastError(0xdeadbeef); 396 size = 0; 397 ret = pCryptFormatObject(X509_ASN_ENCODING, 0, 0, NULL, NULL, NULL, 0, 398 str, &size); 399 ok(!ret && GetLastError() == ERROR_MORE_DATA, 400 "expected ERROR_MORE_DATA, got %d\n", GetLastError()); 401 size = sizeof(WCHAR); 402 ret = pCryptFormatObject(X509_ASN_ENCODING, 0, 0, NULL, NULL, NULL, 0, 403 str, &size); 404 ok(ret, "CryptFormatObject failed: %d\n", GetLastError()); 405 ok(!str[0], "expected empty string\n"); 406 HeapFree(GetProcessHeap(), 0, str); 407 } 408 ret = pCryptFormatObject(X509_ASN_ENCODING, 0, 0, NULL, NULL, encodedInt, 409 sizeof(encodedInt), NULL, &size); 410 ok(ret, "CryptFormatObject failed: %d\n", GetLastError()); 411 if (ret) 412 { 413 str = HeapAlloc(GetProcessHeap(), 0, size); 414 ret = pCryptFormatObject(X509_ASN_ENCODING, 0, 0, NULL, NULL, 415 encodedInt, sizeof(encodedInt), str, &size); 416 ok(ret, "CryptFormatObject failed: %d\n", GetLastError()); 417 ok(!lstrcmpW(str, encodedIntStr), "unexpected format string\n"); 418 HeapFree(GetProcessHeap(), 0, str); 419 } 420 ret = pCryptFormatObject(X509_ASN_ENCODING, 0, 0, NULL, NULL, 421 encodedBigInt, sizeof(encodedBigInt), NULL, &size); 422 ok(ret, "CryptFormatObject failed: %d\n", GetLastError()); 423 if (ret) 424 { 425 str = HeapAlloc(GetProcessHeap(), 0, size); 426 ret = pCryptFormatObject(X509_ASN_ENCODING, 0, 0, NULL, NULL, 427 encodedBigInt, sizeof(encodedBigInt), str, &size); 428 ok(ret, "CryptFormatObject failed: %d\n", GetLastError()); 429 ok(!lstrcmpiW(str, encodedBigIntStr), "unexpected format string\n"); 430 HeapFree(GetProcessHeap(), 0, str); 431 } 432 /* When called with the default encoding type for any undefined struct 433 * type but CRYPT_FORMAT_STR_NO_HEX specified, it fails to find a 434 * formatting function. 435 */ 436 SetLastError(0xdeadbeef); 437 ret = pCryptFormatObject(X509_ASN_ENCODING, 0, CRYPT_FORMAT_STR_NO_HEX, 438 NULL, NULL, NULL, 0, NULL, &size); 439 ok(!ret, "CryptFormatObject succeeded\n"); 440 ok(GetLastError() == ERROR_FILE_NOT_FOUND || 441 GetLastError() == 0xdeadbeef, /* Vista, W2K8 */ 442 "expected ERROR_FILE_NOT_FOUND or no change, got %d\n", GetLastError()); 443 /* When called to format an AUTHORITY_KEY_ID2_INFO, it fails when no 444 * data are given. 445 */ 446 SetLastError(0xdeadbeef); 447 ret = pCryptFormatObject(X509_ASN_ENCODING, 0, 0, NULL, 448 szOID_AUTHORITY_KEY_IDENTIFIER2, NULL, 0, NULL, &size); 449 ok(!ret && GetLastError() == E_INVALIDARG, 450 "expected E_INVALIDARG, got %d\n", GetLastError()); 451 } 452 453 START_TEST(main) 454 { 455 hCrypt = GetModuleHandleA("crypt32.dll"); 456 457 test_findAttribute(); 458 test_findExtension(); 459 test_findRDNAttr(); 460 test_verifyTimeValidity(); 461 test_cryptAllocate(); 462 test_cryptTls(); 463 test_readTrustedPublisherDWORD(); 464 test_getDefaultCryptProv(); 465 test_CryptInstallOssGlobal(); 466 test_format_object(); 467 } 468