1 /* 2 * Copyright 2002 Mike McCormack for CodeWeavers 3 * Copyright 2005-2006 Juan Lang 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2.1 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 18 */ 19 20 #include "crypt32_private.h" 21 22 WINE_DEFAULT_DEBUG_CHANNEL(crypt); 23 24 static const WCHAR DllW[] = { 'D','l','l',0 }; 25 26 static CRITICAL_SECTION funcSetCS; 27 static CRITICAL_SECTION_DEBUG funcSetCSDebug = 28 { 29 0, 0, &funcSetCS, 30 { &funcSetCSDebug.ProcessLocksList, &funcSetCSDebug.ProcessLocksList }, 31 0, 0, { (DWORD_PTR)(__FILE__ ": funcSetCS") } 32 }; 33 static CRITICAL_SECTION funcSetCS = { &funcSetCSDebug, -1, 0, 0, 0, 0 }; 34 static struct list funcSets = { &funcSets, &funcSets }; 35 36 struct OIDFunctionSet 37 { 38 LPSTR name; 39 CRITICAL_SECTION cs; /* protects functions */ 40 struct list functions; 41 struct list next; 42 }; 43 44 struct OIDFunction 45 { 46 DWORD encoding; 47 CRYPT_OID_FUNC_ENTRY entry; 48 struct list next; 49 }; 50 51 static const WCHAR ROOT[] = {'R','O','O','T',0}; 52 static const WCHAR MY[] = {'M','Y',0}; 53 static const WCHAR CA[] = {'C','A',0}; 54 static const WCHAR ADDRESSBOOK[] = {'A','D','D','R','E','S','S','B','O','O','K',0}; 55 static const WCHAR TRUSTEDPUBLISHER[] = {'T','r','u','s','t','e','d','P','u','b','l','i','s','h','e','r',0}; 56 static const WCHAR DISALLOWED[] = {'D','i','s','a','l','l','o','w','e','d',0}; 57 static const LPCWSTR LocalizedKeys[] = {ROOT,MY,CA,ADDRESSBOOK,TRUSTEDPUBLISHER,DISALLOWED}; 58 static WCHAR LocalizedNames[sizeof(LocalizedKeys)/sizeof(LocalizedKeys[0])][256]; 59 60 static void free_function_sets(void) 61 { 62 struct OIDFunctionSet *setCursor, *setNext; 63 64 LIST_FOR_EACH_ENTRY_SAFE(setCursor, setNext, &funcSets, 65 struct OIDFunctionSet, next) 66 { 67 struct OIDFunction *functionCursor, *funcNext; 68 69 list_remove(&setCursor->next); 70 CryptMemFree(setCursor->name); 71 LIST_FOR_EACH_ENTRY_SAFE(functionCursor, funcNext, 72 &setCursor->functions, struct OIDFunction, next) 73 { 74 list_remove(&functionCursor->next); 75 CryptMemFree(functionCursor); 76 } 77 setCursor->cs.DebugInfo->Spare[0] = 0; 78 DeleteCriticalSection(&setCursor->cs); 79 CryptMemFree(setCursor); 80 } 81 DeleteCriticalSection(&funcSetCS); 82 } 83 84 /* There is no free function associated with this; therefore, the sets are 85 * freed when crypt32.dll is unloaded. 86 */ 87 HCRYPTOIDFUNCSET WINAPI CryptInitOIDFunctionSet(LPCSTR pszFuncName, 88 DWORD dwFlags) 89 { 90 struct OIDFunctionSet *cursor, *ret = NULL; 91 92 TRACE("(%s, %x)\n", debugstr_a(pszFuncName), dwFlags); 93 94 EnterCriticalSection(&funcSetCS); 95 LIST_FOR_EACH_ENTRY(cursor, &funcSets, struct OIDFunctionSet, next) 96 { 97 if (!strcasecmp(pszFuncName, cursor->name)) 98 { 99 ret = cursor; 100 break; 101 } 102 } 103 if (!ret) 104 { 105 ret = CryptMemAlloc(sizeof(struct OIDFunctionSet)); 106 if (ret) 107 { 108 memset(ret, 0, sizeof(*ret)); 109 ret->name = CryptMemAlloc(strlen(pszFuncName) + 1); 110 if (ret->name) 111 { 112 InitializeCriticalSection(&ret->cs); 113 ret->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": OIDFunctionSet.cs"); 114 list_init(&ret->functions); 115 strcpy(ret->name, pszFuncName); 116 list_add_tail(&funcSets, &ret->next); 117 } 118 else 119 { 120 CryptMemFree(ret); 121 ret = NULL; 122 } 123 } 124 } 125 LeaveCriticalSection(&funcSetCS); 126 127 return ret; 128 } 129 130 static char *CRYPT_GetKeyName(DWORD dwEncodingType, LPCSTR pszFuncName, 131 LPCSTR pszOID) 132 { 133 static const char szEncodingTypeFmt[] = 134 "Software\\Microsoft\\Cryptography\\OID\\EncodingType %d\\%s\\%s"; 135 UINT len; 136 char numericOID[7]; /* enough for "#65535" */ 137 const char *oid; 138 LPSTR szKey; 139 140 /* MSDN says the encoding type is a mask, but it isn't treated that way. 141 * (E.g., if dwEncodingType were 3, the key names "EncodingType 1" and 142 * "EncodingType 2" would be expected if it were a mask. Instead native 143 * stores values in "EncodingType 3". 144 */ 145 if (IS_INTOID(pszOID)) 146 { 147 snprintf(numericOID, sizeof(numericOID), "#%d", LOWORD(pszOID)); 148 oid = numericOID; 149 } 150 else 151 oid = pszOID; 152 153 /* This is enough: the lengths of the two string parameters are explicitly 154 * counted, and we need up to five additional characters for the encoding 155 * type. These are covered by the "%d", "%s", and "%s" characters in the 156 * format specifier that are removed by sprintf. 157 */ 158 len = sizeof(szEncodingTypeFmt) + lstrlenA(pszFuncName) + lstrlenA(oid); 159 szKey = CryptMemAlloc(len); 160 if (szKey) 161 sprintf(szKey, szEncodingTypeFmt, 162 GET_CERT_ENCODING_TYPE(dwEncodingType), pszFuncName, oid); 163 return szKey; 164 } 165 166 BOOL WINAPI CryptGetDefaultOIDDllList(HCRYPTOIDFUNCSET hFuncSet, 167 DWORD dwEncodingType, LPWSTR pwszDllList, DWORD *pcchDllList) 168 { 169 BOOL ret = TRUE; 170 struct OIDFunctionSet *set = hFuncSet; 171 char *keyName; 172 HKEY key; 173 LSTATUS rc; 174 175 TRACE("(%p, %d, %p, %p)\n", hFuncSet, dwEncodingType, pwszDllList, 176 pcchDllList); 177 178 keyName = CRYPT_GetKeyName(dwEncodingType, set->name, "DEFAULT"); 179 rc = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, NULL, 0, 180 KEY_READ, NULL, &key, NULL); 181 if (!rc) 182 { 183 DWORD size = *pcchDllList * sizeof(WCHAR); 184 185 rc = RegQueryValueExW(key, DllW, NULL, NULL, (LPBYTE)pwszDllList, 186 &size); 187 if (!rc) 188 *pcchDllList = size / sizeof(WCHAR); 189 else 190 { 191 /* No value, return an empty list */ 192 if (pwszDllList && *pcchDllList) 193 *pwszDllList = '\0'; 194 *pcchDllList = 1; 195 } 196 RegCloseKey(key); 197 } 198 else 199 { 200 /* No value, return an empty list */ 201 if (pwszDllList && *pcchDllList) 202 *pwszDllList = '\0'; 203 *pcchDllList = 1; 204 } 205 CryptMemFree(keyName); 206 207 return ret; 208 } 209 210 BOOL WINAPI CryptInstallOIDFunctionAddress(HMODULE hModule, 211 DWORD dwEncodingType, LPCSTR pszFuncName, DWORD cFuncEntry, 212 const CRYPT_OID_FUNC_ENTRY rgFuncEntry[], DWORD dwFlags) 213 { 214 BOOL ret = TRUE; 215 struct OIDFunctionSet *set; 216 217 TRACE("(%p, %d, %s, %d, %p, %08x)\n", hModule, dwEncodingType, 218 debugstr_a(pszFuncName), cFuncEntry, rgFuncEntry, dwFlags); 219 220 set = CryptInitOIDFunctionSet(pszFuncName, 0); 221 if (set) 222 { 223 DWORD i; 224 225 EnterCriticalSection(&set->cs); 226 for (i = 0; ret && i < cFuncEntry; i++) 227 { 228 struct OIDFunction *func; 229 230 if (!IS_INTOID(rgFuncEntry[i].pszOID)) 231 func = CryptMemAlloc(sizeof(struct OIDFunction) 232 + strlen(rgFuncEntry[i].pszOID) + 1); 233 else 234 func = CryptMemAlloc(sizeof(struct OIDFunction)); 235 if (func) 236 { 237 func->encoding = GET_CERT_ENCODING_TYPE(dwEncodingType); 238 if (!IS_INTOID(rgFuncEntry[i].pszOID)) 239 { 240 LPSTR oid; 241 242 oid = (LPSTR)((LPBYTE)func + sizeof(*func)); 243 strcpy(oid, rgFuncEntry[i].pszOID); 244 func->entry.pszOID = oid; 245 } 246 else 247 func->entry.pszOID = rgFuncEntry[i].pszOID; 248 func->entry.pvFuncAddr = rgFuncEntry[i].pvFuncAddr; 249 list_add_tail(&set->functions, &func->next); 250 } 251 else 252 ret = FALSE; 253 } 254 LeaveCriticalSection(&set->cs); 255 } 256 else 257 ret = FALSE; 258 return ret; 259 } 260 261 struct FuncAddr 262 { 263 HMODULE lib; 264 LPWSTR dllList; 265 LPWSTR currentDll; 266 }; 267 268 static BOOL CRYPT_GetFuncFromReg(DWORD dwEncodingType, LPCSTR pszOID, 269 LPCSTR szFuncName, LPVOID *ppvFuncAddr, HCRYPTOIDFUNCADDR *phFuncAddr) 270 { 271 BOOL ret = FALSE; 272 char *keyName; 273 const char *funcName; 274 HKEY key; 275 LSTATUS rc; 276 277 keyName = CRYPT_GetKeyName(dwEncodingType, szFuncName, pszOID); 278 rc = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, KEY_READ, &key); 279 if (!rc) 280 { 281 DWORD type, size = 0; 282 283 rc = RegQueryValueExA(key, "FuncName", NULL, &type, NULL, &size); 284 if ((!rc || rc == ERROR_MORE_DATA) && type == REG_SZ) 285 { 286 funcName = CryptMemAlloc(size); 287 rc = RegQueryValueExA(key, "FuncName", NULL, &type, 288 (LPBYTE)funcName, &size); 289 } 290 else 291 funcName = szFuncName; 292 rc = RegQueryValueExW(key, DllW, NULL, &type, NULL, &size); 293 if ((!rc || rc == ERROR_MORE_DATA) && type == REG_SZ) 294 { 295 LPWSTR dllName = CryptMemAlloc(size); 296 297 if (dllName) 298 { 299 rc = RegQueryValueExW(key, DllW, NULL, NULL, 300 (LPBYTE)dllName, &size); 301 if (!rc) 302 { 303 HMODULE lib; 304 305 /* This is a bit of a hack; MSDN describes a more 306 * complicated unload routine than this will allow. 307 * Still, this seems to suffice for now. 308 */ 309 lib = LoadLibraryW(dllName); 310 if (lib) 311 { 312 *ppvFuncAddr = GetProcAddress(lib, funcName); 313 if (*ppvFuncAddr) 314 { 315 struct FuncAddr *addr = 316 CryptMemAlloc(sizeof(struct FuncAddr)); 317 318 if (addr) 319 { 320 addr->lib = lib; 321 addr->dllList = addr->currentDll = NULL; 322 *phFuncAddr = addr; 323 ret = TRUE; 324 } 325 else 326 { 327 *phFuncAddr = NULL; 328 FreeLibrary(lib); 329 } 330 } 331 else 332 { 333 /* Unload the library, the caller doesn't want 334 * to unload it when the return value is NULL. 335 */ 336 FreeLibrary(lib); 337 } 338 } 339 } 340 else 341 SetLastError(rc); 342 CryptMemFree(dllName); 343 } 344 } 345 else 346 SetLastError(rc); 347 if (funcName != szFuncName) 348 CryptMemFree((char *)funcName); 349 RegCloseKey(key); 350 } 351 else 352 SetLastError(rc); 353 CryptMemFree(keyName); 354 return ret; 355 } 356 357 BOOL WINAPI CryptGetOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet, 358 DWORD dwEncodingType, LPCSTR pszOID, DWORD dwFlags, void **ppvFuncAddr, 359 HCRYPTOIDFUNCADDR *phFuncAddr) 360 { 361 BOOL ret = FALSE; 362 struct OIDFunctionSet *set = hFuncSet; 363 364 TRACE("(%p, %d, %s, %08x, %p, %p)\n", hFuncSet, dwEncodingType, 365 debugstr_a(pszOID), dwFlags, ppvFuncAddr, phFuncAddr); 366 367 *ppvFuncAddr = NULL; 368 if (!(dwFlags & CRYPT_GET_INSTALLED_OID_FUNC_FLAG)) 369 { 370 struct OIDFunction *function; 371 372 EnterCriticalSection(&set->cs); 373 LIST_FOR_EACH_ENTRY(function, &set->functions, struct OIDFunction, next) 374 { 375 if (function->encoding == GET_CERT_ENCODING_TYPE(dwEncodingType)) 376 { 377 if (!IS_INTOID(pszOID)) 378 { 379 if (!IS_INTOID(function->entry.pszOID) && 380 !strcasecmp(function->entry.pszOID, pszOID)) 381 { 382 *ppvFuncAddr = function->entry.pvFuncAddr; 383 *phFuncAddr = NULL; /* FIXME: what should it be? */ 384 ret = TRUE; 385 break; 386 } 387 } 388 else if (function->entry.pszOID == pszOID) 389 { 390 *ppvFuncAddr = function->entry.pvFuncAddr; 391 *phFuncAddr = NULL; /* FIXME: what should it be? */ 392 ret = TRUE; 393 break; 394 } 395 } 396 } 397 LeaveCriticalSection(&set->cs); 398 } 399 if (!*ppvFuncAddr) 400 ret = CRYPT_GetFuncFromReg(dwEncodingType, pszOID, set->name, 401 ppvFuncAddr, phFuncAddr); 402 TRACE("returning %d\n", ret); 403 return ret; 404 } 405 406 BOOL WINAPI CryptFreeOIDFunctionAddress(HCRYPTOIDFUNCADDR hFuncAddr, 407 DWORD dwFlags) 408 { 409 TRACE("(%p, %08x)\n", hFuncAddr, dwFlags); 410 411 /* FIXME: as MSDN states, need to check for DllCanUnloadNow in the DLL, 412 * and only unload it if it can be unloaded. Also need to implement ref 413 * counting on the functions. 414 */ 415 if (hFuncAddr) 416 { 417 struct FuncAddr *addr = hFuncAddr; 418 419 CryptMemFree(addr->dllList); 420 FreeLibrary(addr->lib); 421 CryptMemFree(addr); 422 } 423 return TRUE; 424 } 425 426 static BOOL CRYPT_GetFuncFromDll(LPCWSTR dll, LPCSTR func, HMODULE *lib, 427 void **ppvFuncAddr) 428 { 429 BOOL ret = FALSE; 430 431 *lib = LoadLibraryW(dll); 432 if (*lib) 433 { 434 *ppvFuncAddr = GetProcAddress(*lib, func); 435 if (*ppvFuncAddr) 436 ret = TRUE; 437 else 438 { 439 FreeLibrary(*lib); 440 *lib = NULL; 441 } 442 } 443 return ret; 444 } 445 446 BOOL WINAPI CryptGetDefaultOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet, 447 DWORD dwEncodingType, LPCWSTR pwszDll, DWORD dwFlags, void **ppvFuncAddr, 448 HCRYPTOIDFUNCADDR *phFuncAddr) 449 { 450 struct OIDFunctionSet *set = hFuncSet; 451 BOOL ret = FALSE; 452 453 TRACE("(%p, %d, %s, %08x, %p, %p)\n", hFuncSet, dwEncodingType, 454 debugstr_w(pwszDll), dwFlags, ppvFuncAddr, phFuncAddr); 455 456 if (pwszDll) 457 { 458 HMODULE lib; 459 460 *phFuncAddr = NULL; 461 ret = CRYPT_GetFuncFromDll(pwszDll, set->name, &lib, ppvFuncAddr); 462 if (ret) 463 { 464 struct FuncAddr *addr = CryptMemAlloc(sizeof(struct FuncAddr)); 465 466 if (addr) 467 { 468 addr->lib = lib; 469 addr->dllList = addr->currentDll = NULL; 470 *phFuncAddr = addr; 471 } 472 else 473 { 474 FreeLibrary(lib); 475 *ppvFuncAddr = NULL; 476 SetLastError(ERROR_OUTOFMEMORY); 477 ret = FALSE; 478 } 479 } 480 else 481 SetLastError(ERROR_FILE_NOT_FOUND); 482 } 483 else 484 { 485 struct FuncAddr *addr = *phFuncAddr; 486 487 if (!addr) 488 { 489 DWORD size; 490 491 ret = CryptGetDefaultOIDDllList(hFuncSet, dwEncodingType, NULL, 492 &size); 493 if (ret) 494 { 495 LPWSTR dllList = CryptMemAlloc(size * sizeof(WCHAR)); 496 497 if (dllList) 498 { 499 ret = CryptGetDefaultOIDDllList(hFuncSet, dwEncodingType, 500 dllList, &size); 501 if (ret) 502 { 503 addr = CryptMemAlloc(sizeof(struct FuncAddr)); 504 if (addr) 505 { 506 addr->dllList = dllList; 507 addr->currentDll = dllList; 508 addr->lib = NULL; 509 *phFuncAddr = addr; 510 } 511 else 512 { 513 CryptMemFree(dllList); 514 SetLastError(ERROR_OUTOFMEMORY); 515 ret = FALSE; 516 } 517 } 518 } 519 else 520 { 521 SetLastError(ERROR_OUTOFMEMORY); 522 ret = FALSE; 523 } 524 } 525 } 526 if (addr) 527 { 528 if (!*addr->currentDll) 529 { 530 CryptFreeOIDFunctionAddress(*phFuncAddr, 0); 531 SetLastError(ERROR_FILE_NOT_FOUND); 532 *phFuncAddr = NULL; 533 ret = FALSE; 534 } 535 else 536 { 537 /* FIXME: as elsewhere, can't free until DllCanUnloadNow says 538 * it's possible, and should defer unloading for some time to 539 * avoid repeated LoadLibrary/FreeLibrary on the same dll. 540 */ 541 FreeLibrary(addr->lib); 542 ret = CRYPT_GetFuncFromDll(addr->currentDll, set->name, 543 &addr->lib, ppvFuncAddr); 544 if (ret) 545 { 546 /* Move past the current DLL */ 547 addr->currentDll += lstrlenW(addr->currentDll) + 1; 548 *phFuncAddr = addr; 549 } 550 else 551 { 552 CryptFreeOIDFunctionAddress(*phFuncAddr, 0); 553 SetLastError(ERROR_FILE_NOT_FOUND); 554 *phFuncAddr = NULL; 555 } 556 } 557 } 558 } 559 return ret; 560 } 561 562 /*********************************************************************** 563 * CryptRegisterOIDFunction (CRYPT32.@) 564 * 565 * Register the DLL and the functions it uses to cover the combination 566 * of encoding type, function name and OID. 567 * 568 * PARAMS 569 * dwEncodingType [I] Encoding type to be used. 570 * pszFuncName [I] Name of the function to be registered. 571 * pszOID [I] OID of the function (numeric or string). 572 * pwszDll [I] The DLL that is to be registered. 573 * pszOverrideFuncName [I] Name of the function in the DLL. 574 * 575 * RETURNS 576 * Success: TRUE. 577 * Failure: FALSE. (Look at GetLastError()). 578 * 579 * NOTES 580 * Registry errors are always reported via SetLastError(). 581 */ 582 BOOL WINAPI CryptRegisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName, 583 LPCSTR pszOID, LPCWSTR pwszDll, LPCSTR pszOverrideFuncName) 584 { 585 LONG r; 586 HKEY hKey; 587 LPSTR szKey; 588 589 TRACE("(%x, %s, %s, %s, %s)\n", dwEncodingType, debugstr_a(pszFuncName), 590 debugstr_a(pszOID), debugstr_w(pwszDll), debugstr_a(pszOverrideFuncName)); 591 592 /* Native does nothing pwszDll is NULL */ 593 if (!pwszDll) 594 return TRUE; 595 596 /* I'm not matching MS bug for bug here, because I doubt any app depends on 597 * it: native "succeeds" if pszFuncName is NULL, but the nonsensical entry 598 * it creates would never be used. 599 */ 600 if (!pszFuncName || !pszOID) 601 { 602 SetLastError(E_INVALIDARG); 603 return FALSE; 604 } 605 606 szKey = CRYPT_GetKeyName(dwEncodingType, pszFuncName, pszOID); 607 TRACE("Key name is %s\n", debugstr_a(szKey)); 608 609 if (!szKey) 610 return FALSE; 611 612 r = RegCreateKeyA(HKEY_LOCAL_MACHINE, szKey, &hKey); 613 CryptMemFree(szKey); 614 615 if (r != ERROR_SUCCESS) goto error_close_key; 616 617 /* write the values */ 618 if (pszOverrideFuncName) 619 { 620 r = RegSetValueExA(hKey, "FuncName", 0, REG_SZ, 621 (const BYTE*)pszOverrideFuncName, lstrlenA(pszOverrideFuncName) + 1); 622 if (r != ERROR_SUCCESS) goto error_close_key; 623 } 624 r = RegSetValueExW(hKey, DllW, 0, REG_SZ, (const BYTE*) pwszDll, 625 (lstrlenW(pwszDll) + 1) * sizeof (WCHAR)); 626 627 error_close_key: 628 629 RegCloseKey(hKey); 630 631 if (r != ERROR_SUCCESS) 632 { 633 SetLastError(r); 634 return FALSE; 635 } 636 637 return TRUE; 638 } 639 640 /*********************************************************************** 641 * CryptRegisterOIDInfo (CRYPT32.@) 642 */ 643 BOOL WINAPI CryptRegisterOIDInfo(PCCRYPT_OID_INFO pInfo, DWORD dwFlags) 644 { 645 FIXME("(%p, %x): stub\n", pInfo, dwFlags ); 646 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 647 return FALSE; 648 } 649 650 /*********************************************************************** 651 * CryptUnregisterOIDFunction (CRYPT32.@) 652 */ 653 BOOL WINAPI CryptUnregisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName, 654 LPCSTR pszOID) 655 { 656 LPSTR szKey; 657 LONG rc; 658 659 TRACE("%x %s %s\n", dwEncodingType, debugstr_a(pszFuncName), 660 debugstr_a(pszOID)); 661 662 if (!pszFuncName || !pszOID) 663 { 664 SetLastError(ERROR_INVALID_PARAMETER); 665 return FALSE; 666 } 667 668 szKey = CRYPT_GetKeyName(dwEncodingType, pszFuncName, pszOID); 669 rc = RegDeleteKeyA(HKEY_LOCAL_MACHINE, szKey); 670 CryptMemFree(szKey); 671 if (rc) 672 SetLastError(rc); 673 return !rc; 674 } 675 676 BOOL WINAPI CryptGetOIDFunctionValue(DWORD dwEncodingType, LPCSTR pszFuncName, 677 LPCSTR pszOID, LPCWSTR pwszValueName, DWORD *pdwValueType, BYTE *pbValueData, 678 DWORD *pcbValueData) 679 { 680 LPSTR szKey; 681 LONG rc; 682 HKEY hKey; 683 684 TRACE("%x %s %s %s %p %p %p\n", dwEncodingType, debugstr_a(pszFuncName), 685 debugstr_a(pszOID), debugstr_w(pwszValueName), pdwValueType, pbValueData, 686 pcbValueData); 687 688 if (!GET_CERT_ENCODING_TYPE(dwEncodingType)) 689 return TRUE; 690 691 if (!pszFuncName || !pszOID || !pwszValueName) 692 { 693 SetLastError(ERROR_INVALID_PARAMETER); 694 return FALSE; 695 } 696 697 szKey = CRYPT_GetKeyName(dwEncodingType, pszFuncName, pszOID); 698 rc = RegOpenKeyA(HKEY_LOCAL_MACHINE, szKey, &hKey); 699 CryptMemFree(szKey); 700 if (rc) 701 SetLastError(rc); 702 else 703 { 704 rc = RegQueryValueExW(hKey, pwszValueName, NULL, pdwValueType, 705 pbValueData, pcbValueData); 706 if (rc) 707 SetLastError(rc); 708 RegCloseKey(hKey); 709 } 710 return !rc; 711 } 712 713 BOOL WINAPI CryptSetOIDFunctionValue(DWORD dwEncodingType, LPCSTR pszFuncName, 714 LPCSTR pszOID, LPCWSTR pwszValueName, DWORD dwValueType, 715 const BYTE *pbValueData, DWORD cbValueData) 716 { 717 LPSTR szKey; 718 LONG rc; 719 HKEY hKey; 720 721 TRACE("%x %s %s %s %d %p %d\n", dwEncodingType, debugstr_a(pszFuncName), 722 debugstr_a(pszOID), debugstr_w(pwszValueName), dwValueType, pbValueData, 723 cbValueData); 724 725 if (!GET_CERT_ENCODING_TYPE(dwEncodingType)) 726 return TRUE; 727 728 if (!pszFuncName || !pszOID || !pwszValueName) 729 { 730 SetLastError(ERROR_INVALID_PARAMETER); 731 return FALSE; 732 } 733 734 szKey = CRYPT_GetKeyName(dwEncodingType, pszFuncName, pszOID); 735 rc = RegOpenKeyA(HKEY_LOCAL_MACHINE, szKey, &hKey); 736 CryptMemFree(szKey); 737 if (rc) 738 SetLastError(rc); 739 else 740 { 741 rc = RegSetValueExW(hKey, pwszValueName, 0, dwValueType, pbValueData, 742 cbValueData); 743 if (rc) 744 SetLastError(rc); 745 RegCloseKey(hKey); 746 } 747 return !rc; 748 } 749 750 static LPCWSTR CRYPT_FindStringInMultiString(LPCWSTR multi, LPCWSTR toFind) 751 { 752 LPCWSTR ret = NULL, ptr; 753 754 for (ptr = multi; ptr && *ptr && !ret; ptr += lstrlenW(ptr) + 1) 755 { 756 if (!lstrcmpiW(ptr, toFind)) 757 ret = ptr; 758 } 759 return ret; 760 } 761 762 static DWORD CRYPT_GetMultiStringCharacterLen(LPCWSTR multi) 763 { 764 DWORD ret; 765 766 if (multi) 767 { 768 LPCWSTR ptr; 769 770 /* Count terminating empty string */ 771 ret = 1; 772 for (ptr = multi; *ptr; ptr += lstrlenW(ptr) + 1) 773 ret += lstrlenW(ptr) + 1; 774 } 775 else 776 ret = 0; 777 return ret; 778 } 779 780 static LPWSTR CRYPT_AddStringToMultiString(LPWSTR multi, LPCWSTR toAdd, 781 DWORD index) 782 { 783 LPWSTR ret; 784 785 if (!multi) 786 { 787 /* FIXME: ignoring index, is that okay? */ 788 ret = CryptMemAlloc((lstrlenW(toAdd) + 2) * sizeof(WCHAR)); 789 if (ret) 790 { 791 /* copy string, including NULL terminator */ 792 memcpy(ret, toAdd, (lstrlenW(toAdd) + 1) * sizeof(WCHAR)); 793 /* add terminating empty string */ 794 *(ret + lstrlenW(toAdd) + 1) = 0; 795 } 796 } 797 else 798 { 799 DWORD len = CRYPT_GetMultiStringCharacterLen(multi); 800 801 ret = CryptMemRealloc(multi, (len + lstrlenW(toAdd) + 1) * 802 sizeof(WCHAR)); 803 if (ret) 804 { 805 LPWSTR spotToAdd; 806 807 if (index == CRYPT_REGISTER_LAST_INDEX) 808 spotToAdd = ret + len - 1; 809 else 810 { 811 DWORD i; 812 813 /* FIXME: if index is too large for the string, toAdd is 814 * added to the end. Is that okay? 815 */ 816 for (i = 0, spotToAdd = ret; i < index && *spotToAdd; 817 spotToAdd += lstrlenW(spotToAdd) + 1) 818 ; 819 } 820 if (spotToAdd) 821 { 822 /* Copy existing string "right" */ 823 memmove(spotToAdd + lstrlenW(toAdd) + 1, spotToAdd, 824 (len - (spotToAdd - ret)) * sizeof(WCHAR)); 825 /* Copy new string */ 826 memcpy(spotToAdd, toAdd, (lstrlenW(toAdd) + 1) * sizeof(WCHAR)); 827 } 828 else 829 { 830 CryptMemFree(ret); 831 ret = NULL; 832 } 833 } 834 } 835 return ret; 836 } 837 838 static BOOL CRYPT_RemoveStringFromMultiString(LPWSTR multi, LPCWSTR toRemove) 839 { 840 LPWSTR spotToRemove = (LPWSTR)CRYPT_FindStringInMultiString(multi, 841 toRemove); 842 BOOL ret; 843 844 if (spotToRemove) 845 { 846 DWORD len = CRYPT_GetMultiStringCharacterLen(multi); 847 848 if (spotToRemove + lstrlenW(toRemove) + 2 >= multi + len) 849 { 850 /* Removing last string in list, terminate multi string directly */ 851 *spotToRemove = 0; 852 *(spotToRemove + 1) = 0; 853 } 854 else 855 { 856 LPCWSTR nextStr = spotToRemove + lstrlenW(toRemove) + 1; 857 858 /* Copy remainder of string "left" */ 859 memmove(spotToRemove, nextStr, 860 (len - (nextStr - multi)) * sizeof(WCHAR)); 861 } 862 ret = TRUE; 863 } 864 else 865 { 866 SetLastError(ERROR_FILE_NOT_FOUND); 867 ret = FALSE; 868 } 869 return ret; 870 } 871 872 static BOOL CRYPT_GetDefaultOIDKey(DWORD dwEncodingType, LPCSTR pszFuncName, 873 PHKEY key) 874 { 875 LPSTR keyName; 876 LONG r; 877 878 keyName = CRYPT_GetKeyName(dwEncodingType, pszFuncName, "DEFAULT"); 879 TRACE("Key name is %s\n", debugstr_a(keyName)); 880 881 if (!keyName) 882 return FALSE; 883 884 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, NULL, 0, KEY_ALL_ACCESS, 885 NULL, key, NULL); 886 CryptMemFree(keyName); 887 if (r != ERROR_SUCCESS) 888 { 889 SetLastError(r); 890 return FALSE; 891 } 892 return TRUE; 893 } 894 895 static LPWSTR CRYPT_GetDefaultOIDDlls(HKEY key) 896 { 897 LONG r; 898 DWORD type, size; 899 LPWSTR dlls; 900 901 r = RegQueryValueExW(key, DllW, NULL, &type, NULL, &size); 902 if (r == ERROR_SUCCESS && type == REG_MULTI_SZ) 903 { 904 dlls = CryptMemAlloc(size); 905 r = RegQueryValueExW(key, DllW, NULL, &type, (LPBYTE)dlls, &size); 906 if (r != ERROR_SUCCESS) 907 { 908 CryptMemFree(dlls); 909 dlls = NULL; 910 } 911 } 912 else 913 dlls = NULL; 914 return dlls; 915 } 916 917 static inline BOOL CRYPT_SetDefaultOIDDlls(HKEY key, LPCWSTR dlls) 918 { 919 DWORD len = CRYPT_GetMultiStringCharacterLen(dlls); 920 LONG r; 921 922 if ((r = RegSetValueExW(key, DllW, 0, REG_MULTI_SZ, (const BYTE *)dlls, 923 len * sizeof (WCHAR)))) 924 SetLastError(r); 925 return r == ERROR_SUCCESS; 926 } 927 928 /*********************************************************************** 929 * CryptRegisterDefaultOIDFunction (CRYPT32.@) 930 */ 931 BOOL WINAPI CryptRegisterDefaultOIDFunction(DWORD dwEncodingType, 932 LPCSTR pszFuncName, DWORD dwIndex, LPCWSTR pwszDll) 933 { 934 HKEY key; 935 LPWSTR dlls; 936 BOOL ret = FALSE; 937 938 TRACE("(%x, %s, %d, %s)\n", dwEncodingType, debugstr_a(pszFuncName), 939 dwIndex, debugstr_w(pwszDll)); 940 941 if (!pwszDll) 942 { 943 SetLastError(E_INVALIDARG); 944 return FALSE; 945 } 946 947 if (!CRYPT_GetDefaultOIDKey(dwEncodingType, pszFuncName, &key)) 948 return FALSE; 949 950 dlls = CRYPT_GetDefaultOIDDlls(key); 951 if (CRYPT_FindStringInMultiString(dlls, pwszDll)) 952 SetLastError(ERROR_FILE_EXISTS); 953 else 954 { 955 dlls = CRYPT_AddStringToMultiString(dlls, pwszDll, dwIndex); 956 if (dlls) 957 ret = CRYPT_SetDefaultOIDDlls(key, dlls); 958 } 959 CryptMemFree(dlls); 960 RegCloseKey(key); 961 return ret; 962 } 963 964 BOOL WINAPI CryptUnregisterDefaultOIDFunction(DWORD dwEncodingType, 965 LPCSTR pszFuncName, LPCWSTR pwszDll) 966 { 967 HKEY key; 968 LPWSTR dlls; 969 BOOL ret; 970 971 TRACE("(%x, %s, %s)\n", dwEncodingType, debugstr_a(pszFuncName), 972 debugstr_w(pwszDll)); 973 974 if (!pwszDll) 975 { 976 SetLastError(E_INVALIDARG); 977 return FALSE; 978 } 979 980 if (!CRYPT_GetDefaultOIDKey(dwEncodingType, pszFuncName, &key)) 981 return FALSE; 982 983 dlls = CRYPT_GetDefaultOIDDlls(key); 984 if ((ret = CRYPT_RemoveStringFromMultiString(dlls, pwszDll))) 985 ret = CRYPT_SetDefaultOIDDlls(key, dlls); 986 CryptMemFree(dlls); 987 RegCloseKey(key); 988 return ret; 989 } 990 991 static void oid_init_localizednames(void) 992 { 993 unsigned int i; 994 995 for(i = 0; i < sizeof(LocalizedKeys)/sizeof(LPCWSTR); i++) 996 { 997 LoadStringW(hInstance, IDS_LOCALIZEDNAME_ROOT+i, LocalizedNames[i], 256); 998 } 999 } 1000 1001 /******************************************************************** 1002 * CryptFindLocalizedName (CRYPT32.@) 1003 */ 1004 LPCWSTR WINAPI CryptFindLocalizedName(LPCWSTR pwszCryptName) 1005 { 1006 unsigned int i; 1007 1008 for(i = 0; i < sizeof(LocalizedKeys)/sizeof(LPCWSTR); i++) 1009 { 1010 if(!lstrcmpiW(LocalizedKeys[i], pwszCryptName)) 1011 { 1012 return LocalizedNames[i]; 1013 } 1014 } 1015 1016 FIXME("No name for: %s - stub\n",debugstr_w(pwszCryptName)); 1017 return NULL; 1018 } 1019 1020 static CRITICAL_SECTION oidInfoCS; 1021 static CRITICAL_SECTION_DEBUG oidInfoCSDebug = 1022 { 1023 0, 0, &oidInfoCS, 1024 { &oidInfoCSDebug.ProcessLocksList, &oidInfoCSDebug.ProcessLocksList }, 1025 0, 0, { (DWORD_PTR)(__FILE__ ": oidInfoCS") } 1026 }; 1027 static CRITICAL_SECTION oidInfoCS = { &oidInfoCSDebug, -1, 0, 0, 0, 0 }; 1028 static struct list oidInfo = { &oidInfo, &oidInfo }; 1029 1030 static const WCHAR tripledes[] = { '3','d','e','s',0 }; 1031 static const WCHAR cms3deswrap[] = { 'C','M','S','3','D','E','S','w','r','a', 1032 'p',0 }; 1033 static const WCHAR cmsrc2wrap[] = { 'C','M','S','R','C','2','w','r','a','p',0 }; 1034 static const WCHAR des[] = { 'd','e','s',0 }; 1035 static const WCHAR md2[] = { 'm','d','2',0 }; 1036 static const WCHAR md4[] = { 'm','d','4',0 }; 1037 static const WCHAR md5[] = { 'm','d','5',0 }; 1038 static const WCHAR rc2[] = { 'r','c','2',0 }; 1039 static const WCHAR rc4[] = { 'r','c','4',0 }; 1040 static const WCHAR sha[] = { 's','h','a',0 }; 1041 static const WCHAR sha1[] = { 's','h','a','1',0 }; 1042 static const WCHAR sha256[] = { 's','h','a','2','5','6',0 }; 1043 static const WCHAR sha384[] = { 's','h','a','3','8','4',0 }; 1044 static const WCHAR sha512[] = { 's','h','a','5','1','2',0 }; 1045 static const WCHAR RSA[] = { 'R','S','A',0 }; 1046 static const WCHAR RSA_KEYX[] = { 'R','S','A','_','K','E','Y','X',0 }; 1047 static const WCHAR RSA_SIGN[] = { 'R','S','A','_','S','I','G','N',0 }; 1048 static const WCHAR DSA[] = { 'D','S','A',0 }; 1049 static const WCHAR DSA_SIGN[] = { 'D','S','A','_','S','I','G','N',0 }; 1050 static const WCHAR DH[] = { 'D','H',0 }; 1051 static const WCHAR DSS[] = { 'D','S','S',0 }; 1052 static const WCHAR mosaicKMandUpdSig[] = 1053 { 'm','o','s','a','i','c','K','M','a','n','d','U','p','d','S','i','g',0 }; 1054 static const WCHAR ESDH[] = { 'E','S','D','H',0 }; 1055 static const WCHAR NO_SIGN[] = { 'N','O','S','I','G','N',0 }; 1056 static const WCHAR dsaSHA1[] = { 'd','s','a','S','H','A','1',0 }; 1057 static const WCHAR md2RSA[] = { 'm','d','2','R','S','A',0 }; 1058 static const WCHAR md4RSA[] = { 'm','d','4','R','S','A',0 }; 1059 static const WCHAR md5RSA[] = { 'm','d','5','R','S','A',0 }; 1060 static const WCHAR shaDSA[] = { 's','h','a','D','S','A',0 }; 1061 static const WCHAR sha1DSA[] = { 's','h','a','1','D','S','A',0 }; 1062 static const WCHAR shaRSA[] = { 's','h','a','R','S','A',0 }; 1063 static const WCHAR sha1RSA[] = { 's','h','a','1','R','S','A',0 }; 1064 static const WCHAR sha256RSA[] = { 's','h','a','2','5','6','R','S','A',0 }; 1065 static const WCHAR sha384RSA[] = { 's','h','a','3','8','4','R','S','A',0 }; 1066 static const WCHAR sha512RSA[] = { 's','h','a','5','1','2','R','S','A',0 }; 1067 static const WCHAR mosaicUpdatedSig[] = 1068 { 'm','o','s','a','i','c','U','p','d','a','t','e','d','S','i','g',0 }; 1069 static const WCHAR CN[] = { 'C','N',0 }; 1070 static const WCHAR L[] = { 'L',0 }; 1071 static const WCHAR O[] = { 'O',0 }; 1072 static const WCHAR OU[] = { 'O','U',0 }; 1073 static const WCHAR E[] = { 'E',0 }; 1074 static const WCHAR C[] = { 'C',0 }; 1075 static const WCHAR S[] = { 'S',0 }; 1076 static const WCHAR ST[] = { 'S','T',0 }; 1077 static const WCHAR STREET[] = { 'S','T','R','E','E','T',0 }; 1078 static const WCHAR T[] = { 'T',0 }; 1079 static const WCHAR Title[] = { 'T','i','t','l','e',0 }; 1080 static const WCHAR G[] = { 'G',0 }; 1081 static const WCHAR GivenName[] = { 'G','i','v','e','n','N','a','m','e',0 }; 1082 static const WCHAR I[] = { 'I',0 }; 1083 static const WCHAR Initials[] = { 'I','n','i','t','i','a','l','s',0 }; 1084 static const WCHAR SN[] = { 'S','N',0 }; 1085 static const WCHAR DC[] = { 'D','C',0 }; 1086 static const WCHAR Description[] = 1087 { 'D','e','s','c','r','i','p','t','i','o','n',0 }; 1088 static const WCHAR PostalCode[] = { 'P','o','s','t','a','l','C','o','d','e',0 }; 1089 static const WCHAR POBox[] = { 'P','O','B','o','x',0 }; 1090 static const WCHAR Phone[] = { 'P','h','o','n','e',0 }; 1091 static const WCHAR X21Address[] = { 'X','2','1','A','d','d','r','e','s','s',0 }; 1092 static const WCHAR dnQualifier[] = 1093 { 'd','n','Q','u','a','l','i','f','i','e','r',0 }; 1094 static const WCHAR SpcSpAgencyInfo[] = { 'S','p','c','S','p','A','g','e','n','c','y','I','n','f','o',0 }; 1095 static const WCHAR SpcFinancialCriteria[] = { 'S','p','c','F','i','n','a','n','c','i','a','l','C','r','i','t','e','r','i','a',0 }; 1096 static const WCHAR SpcMinimalCriteria[] = { 'S','p','c','M','i','n','i','m','a','l','C','r','i','t','e','r','i','a',0 }; 1097 static const WCHAR Email[] = { 'E','m','a','i','l',0 }; 1098 static const WCHAR GN[] = { 'G','N',0 }; 1099 static const WCHAR SERIALNUMBER[] = { 'S','E','R','I','A','L','N','U','M','B','E','R',0 }; 1100 1101 static const DWORD noNullFlag = CRYPT_OID_NO_NULL_ALGORITHM_PARA_FLAG; 1102 static const DWORD mosaicFlags = CRYPT_OID_INHIBIT_SIGNATURE_FORMAT_FLAG | 1103 CRYPT_OID_NO_NULL_ALGORITHM_PARA_FLAG; 1104 static const CRYPT_DATA_BLOB noNullBlob = { sizeof(noNullFlag), 1105 (LPBYTE)&noNullFlag }; 1106 static const CRYPT_DATA_BLOB mosaicFlagsBlob = { sizeof(mosaicFlags), 1107 (LPBYTE)&mosaicFlags }; 1108 1109 static const DWORD rsaSign = CALG_RSA_SIGN; 1110 static const DWORD dssSign[2] = { CALG_DSS_SIGN, 1111 CRYPT_OID_NO_NULL_ALGORITHM_PARA_FLAG }; 1112 static const DWORD mosaicSign[2] = { CALG_DSS_SIGN, 1113 CRYPT_OID_INHIBIT_SIGNATURE_FORMAT_FLAG | 1114 CRYPT_OID_NO_NULL_ALGORITHM_PARA_FLAG }; 1115 static const CRYPT_DATA_BLOB rsaSignBlob = { sizeof(rsaSign), 1116 (LPBYTE)&rsaSign }; 1117 static const CRYPT_DATA_BLOB dssSignBlob = { sizeof(dssSign), 1118 (LPBYTE)dssSign }; 1119 static const CRYPT_DATA_BLOB mosaicSignBlob = { sizeof(mosaicSign), 1120 (LPBYTE)mosaicSign }; 1121 1122 static const DWORD ia5String[] = { CERT_RDN_IA5_STRING, 0 }; 1123 static const DWORD numericString[] = { CERT_RDN_NUMERIC_STRING, 0 }; 1124 static const DWORD printableString[] = { CERT_RDN_PRINTABLE_STRING, 0 }; 1125 static const DWORD domainCompTypes[] = { CERT_RDN_IA5_STRING, 1126 CERT_RDN_UTF8_STRING, 0 }; 1127 static const CRYPT_DATA_BLOB ia5StringBlob = { sizeof(ia5String), 1128 (LPBYTE)ia5String }; 1129 static const CRYPT_DATA_BLOB numericStringBlob = { sizeof(numericString), 1130 (LPBYTE)numericString }; 1131 static const CRYPT_DATA_BLOB printableStringBlob = { sizeof(printableString), 1132 (LPBYTE)printableString }; 1133 static const CRYPT_DATA_BLOB domainCompTypesBlob = { sizeof(domainCompTypes), 1134 (LPBYTE)domainCompTypes }; 1135 1136 static const struct OIDInfoConstructor { 1137 DWORD dwGroupId; 1138 LPCSTR pszOID; 1139 UINT Algid; 1140 LPCWSTR pwszName; 1141 const CRYPT_DATA_BLOB *blob; 1142 } oidInfoConstructors[] = { 1143 { 1, szOID_OIWSEC_sha1, CALG_SHA1, sha1, NULL }, 1144 { 1, szOID_OIWSEC_sha1, CALG_SHA1, sha, NULL }, 1145 { 1, szOID_OIWSEC_sha, CALG_SHA, sha, NULL }, 1146 { 1, szOID_RSA_MD5, CALG_MD5, md5, NULL }, 1147 { 1, szOID_RSA_MD4, CALG_MD4, md4, NULL }, 1148 { 1, szOID_RSA_MD2, CALG_MD2, md2, NULL }, 1149 { 1, szOID_NIST_sha256, CALG_SHA_256, sha256, NULL }, 1150 { 1, szOID_NIST_sha384, CALG_SHA_384, sha384, NULL }, 1151 { 1, szOID_NIST_sha512, CALG_SHA_512, sha512, NULL }, 1152 1153 { 2, szOID_OIWSEC_desCBC, CALG_DES, des, NULL }, 1154 { 2, szOID_RSA_DES_EDE3_CBC, CALG_3DES, tripledes, NULL }, 1155 { 2, szOID_RSA_RC2CBC, CALG_RC2, rc2, NULL }, 1156 { 2, szOID_RSA_RC4, CALG_RC4, rc4, NULL }, 1157 { 2, szOID_RSA_SMIMEalgCMS3DESwrap, CALG_3DES, cms3deswrap, NULL }, 1158 { 2, szOID_RSA_SMIMEalgCMSRC2wrap, CALG_RC2, cmsrc2wrap, NULL }, 1159 1160 { 3, szOID_RSA_RSA, CALG_RSA_KEYX, RSA, NULL }, 1161 { 3, szOID_X957_DSA, CALG_DSS_SIGN, DSA, &noNullBlob }, 1162 { 3, szOID_ANSI_X942_DH, CALG_DH_SF, DH, &noNullBlob }, 1163 { 3, szOID_RSA_RSA, CALG_RSA_KEYX, RSA_KEYX, NULL }, 1164 { 3, szOID_RSA_RSA, CALG_RSA_SIGN, RSA, NULL }, 1165 { 3, szOID_RSA_RSA, CALG_RSA_SIGN, RSA_SIGN, NULL }, 1166 { 3, szOID_OIWSEC_dsa, CALG_DSS_SIGN, DSA, &noNullBlob }, 1167 { 3, szOID_OIWSEC_dsa, CALG_DSS_SIGN, DSS, &noNullBlob }, 1168 { 3, szOID_OIWSEC_dsa, CALG_DSS_SIGN, DSA_SIGN, &noNullBlob }, 1169 { 3, szOID_RSA_DH, CALG_DH_SF, DH, &noNullBlob }, 1170 { 3, szOID_OIWSEC_rsaXchg, CALG_RSA_KEYX, RSA_KEYX, NULL }, 1171 { 3, szOID_INFOSEC_mosaicKMandUpdSig, CALG_DSS_SIGN, mosaicKMandUpdSig, 1172 &mosaicFlagsBlob }, 1173 { 3, szOID_RSA_SMIMEalgESDH, CALG_DH_EPHEM, ESDH, &noNullBlob }, 1174 { 3, szOID_PKIX_NO_SIGNATURE, CALG_NO_SIGN, NO_SIGN, NULL }, 1175 1176 { 4, szOID_RSA_SHA1RSA, CALG_SHA1, sha1RSA, &rsaSignBlob }, 1177 { 4, szOID_RSA_SHA256RSA, CALG_SHA_256, sha256RSA, &rsaSignBlob }, 1178 { 4, szOID_RSA_SHA384RSA, CALG_SHA_384, sha384RSA, &rsaSignBlob }, 1179 { 4, szOID_RSA_SHA512RSA, CALG_SHA_512, sha512RSA, &rsaSignBlob }, 1180 { 4, szOID_RSA_MD5RSA, CALG_MD5, md5RSA, &rsaSignBlob }, 1181 { 4, szOID_X957_SHA1DSA, CALG_SHA1, sha1DSA, &dssSignBlob }, 1182 { 4, szOID_OIWSEC_sha1RSASign, CALG_SHA1, sha1RSA, &rsaSignBlob }, 1183 { 4, szOID_OIWSEC_sha1RSASign, CALG_SHA1, shaRSA, &rsaSignBlob }, 1184 { 4, szOID_OIWSEC_shaRSA, CALG_SHA1, shaRSA, &rsaSignBlob }, 1185 { 4, szOID_OIWSEC_md5RSA, CALG_MD5, md5RSA, &rsaSignBlob }, 1186 { 4, szOID_RSA_MD2RSA, CALG_MD2, md2RSA, &rsaSignBlob }, 1187 { 4, szOID_RSA_MD4RSA, CALG_MD4, md4RSA, &rsaSignBlob }, 1188 { 4, szOID_OIWSEC_md4RSA, CALG_MD4, md4RSA, &rsaSignBlob }, 1189 { 4, szOID_OIWSEC_md4RSA2, CALG_MD4, md4RSA, &rsaSignBlob }, 1190 { 4, szOID_OIWDIR_md2RSA, CALG_MD2, md2RSA, &rsaSignBlob }, 1191 { 4, szOID_OIWSEC_shaDSA, CALG_SHA1, sha1DSA, &dssSignBlob }, 1192 { 4, szOID_OIWSEC_shaDSA, CALG_SHA1, shaDSA, &dssSignBlob }, 1193 { 4, szOID_OIWSEC_dsaSHA1, CALG_SHA1, dsaSHA1, &dssSignBlob }, 1194 { 4, szOID_INFOSEC_mosaicUpdatedSig, CALG_SHA1, mosaicUpdatedSig, 1195 &mosaicSignBlob }, 1196 1197 { 5, szOID_COMMON_NAME, 0, CN, NULL }, 1198 { 5, szOID_LOCALITY_NAME, 0, L, NULL }, 1199 { 5, szOID_ORGANIZATION_NAME, 0, O, NULL }, 1200 { 5, szOID_ORGANIZATIONAL_UNIT_NAME, 0, OU, NULL }, 1201 { 5, szOID_RSA_emailAddr, 0, E, &ia5StringBlob }, 1202 { 5, szOID_RSA_emailAddr, 0, Email, &ia5StringBlob }, 1203 { 5, szOID_COUNTRY_NAME, 0, C, &printableStringBlob }, 1204 { 5, szOID_STATE_OR_PROVINCE_NAME, 0, S, NULL }, 1205 { 5, szOID_STATE_OR_PROVINCE_NAME, 0, ST, NULL }, 1206 { 5, szOID_STREET_ADDRESS, 0, STREET, NULL }, 1207 { 5, szOID_TITLE, 0, T, NULL }, 1208 { 5, szOID_TITLE, 0, Title, NULL }, 1209 { 5, szOID_GIVEN_NAME, 0, G, NULL }, 1210 { 5, szOID_GIVEN_NAME, 0, GN, NULL }, 1211 { 5, szOID_GIVEN_NAME, 0, GivenName, NULL }, 1212 { 5, szOID_INITIALS, 0, I, NULL }, 1213 { 5, szOID_INITIALS, 0, Initials, NULL }, 1214 { 5, szOID_SUR_NAME, 0, SN, NULL }, 1215 { 5, szOID_DOMAIN_COMPONENT, 0, DC, &domainCompTypesBlob }, 1216 { 5, szOID_DESCRIPTION, 0, Description, NULL }, 1217 { 5, szOID_POSTAL_CODE, 0, PostalCode, NULL }, 1218 { 5, szOID_POST_OFFICE_BOX, 0, POBox, NULL }, 1219 { 5, szOID_TELEPHONE_NUMBER, 0, Phone, &printableStringBlob }, 1220 { 5, szOID_X21_ADDRESS, 0, X21Address, &numericStringBlob }, 1221 { 5, szOID_DN_QUALIFIER, 0, dnQualifier, NULL }, 1222 { 5, szOID_DEVICE_SERIAL_NUMBER, 0, SERIALNUMBER, NULL }, 1223 1224 { 6, szOID_AUTHORITY_KEY_IDENTIFIER2, 0, (LPCWSTR)IDS_AUTHORITY_KEY_ID, NULL }, 1225 { 6, szOID_AUTHORITY_KEY_IDENTIFIER, 0, (LPCWSTR)IDS_AUTHORITY_KEY_ID, NULL }, 1226 { 6, szOID_KEY_ATTRIBUTES, 0, (LPCWSTR)IDS_KEY_ATTRIBUTES, NULL }, 1227 { 6, szOID_KEY_USAGE_RESTRICTION, 0, (LPCWSTR)IDS_KEY_USAGE_RESTRICTION, NULL }, 1228 { 6, szOID_SUBJECT_ALT_NAME2, 0, (LPCWSTR)IDS_SUBJECT_ALT_NAME, NULL }, 1229 { 6, szOID_SUBJECT_ALT_NAME, 0, (LPCWSTR)IDS_SUBJECT_ALT_NAME, NULL }, 1230 { 6, szOID_ISSUER_ALT_NAME2, 0, (LPCWSTR)IDS_ISSUER_ALT_NAME, NULL }, 1231 { 6, szOID_ISSUER_ALT_NAME2, 0, (LPCWSTR)IDS_ISSUER_ALT_NAME, NULL }, 1232 { 6, szOID_BASIC_CONSTRAINTS2, 0, (LPCWSTR)IDS_BASIC_CONSTRAINTS, NULL }, 1233 { 6, szOID_BASIC_CONSTRAINTS, 0, (LPCWSTR)IDS_BASIC_CONSTRAINTS, NULL }, 1234 { 6, szOID_KEY_USAGE, 0, (LPCWSTR)IDS_KEY_USAGE, NULL }, 1235 { 6, szOID_CERT_POLICIES, 0, (LPCWSTR)IDS_CERT_POLICIES, NULL }, 1236 { 6, szOID_SUBJECT_KEY_IDENTIFIER, 0, (LPCWSTR)IDS_SUBJECT_KEY_IDENTIFIER, NULL }, 1237 { 6, szOID_CRL_REASON_CODE, 0, (LPCWSTR)IDS_CRL_REASON_CODE, NULL }, 1238 { 6, szOID_CRL_DIST_POINTS, 0, (LPCWSTR)IDS_CRL_DIST_POINTS, NULL }, 1239 { 6, szOID_ENHANCED_KEY_USAGE, 0, (LPCWSTR)IDS_ENHANCED_KEY_USAGE, NULL }, 1240 { 6, szOID_AUTHORITY_INFO_ACCESS, 0, (LPCWSTR)IDS_AUTHORITY_INFO_ACCESS, NULL }, 1241 { 6, szOID_CERT_EXTENSIONS, 0, (LPCWSTR)IDS_CERT_EXTENSIONS, NULL }, 1242 { 6, szOID_RSA_certExtensions, 0, (LPCWSTR)IDS_CERT_EXTENSIONS, NULL }, 1243 { 6, szOID_NEXT_UPDATE_LOCATION, 0, (LPCWSTR)IDS_NEXT_UPDATE_LOCATION, NULL }, 1244 { 6, szOID_YESNO_TRUST_ATTR, 0, (LPCWSTR)IDS_YES_OR_NO_TRUST, NULL }, 1245 { 6, szOID_RSA_emailAddr, 0, (LPCWSTR)IDS_EMAIL_ADDRESS, NULL }, 1246 { 6, szOID_RSA_unstructName, 0, (LPCWSTR)IDS_UNSTRUCTURED_NAME, NULL }, 1247 { 6, szOID_RSA_contentType, 0, (LPCWSTR)IDS_CONTENT_TYPE, NULL }, 1248 { 6, szOID_RSA_messageDigest, 0, (LPCWSTR)IDS_MESSAGE_DIGEST, NULL }, 1249 { 6, szOID_RSA_signingTime, 0, (LPCWSTR)IDS_SIGNING_TIME, NULL }, 1250 { 6, szOID_RSA_counterSign, 0, (LPCWSTR)IDS_COUNTER_SIGN, NULL }, 1251 { 6, szOID_RSA_challengePwd, 0, (LPCWSTR)IDS_CHALLENGE_PASSWORD, NULL }, 1252 { 6, szOID_RSA_unstructAddr, 0, (LPCWSTR)IDS_UNSTRUCTURED_ADDRESS, NULL }, 1253 { 6, szOID_RSA_SMIMECapabilities, 0, (LPCWSTR)IDS_SMIME_CAPABILITIES, NULL }, 1254 { 6, szOID_RSA_preferSignedData, 0, (LPCWSTR)IDS_PREFER_SIGNED_DATA, NULL }, 1255 { 6, szOID_PKIX_POLICY_QUALIFIER_CPS, 0, (LPCWSTR)IDS_CPS, NULL }, 1256 { 6, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE, 0, (LPCWSTR)IDS_USER_NOTICE, NULL }, 1257 { 6, szOID_PKIX_OCSP, 0, (LPCWSTR)IDS_OCSP, NULL }, 1258 { 6, szOID_PKIX_CA_ISSUERS, 0, (LPCWSTR)IDS_CA_ISSUER, NULL }, 1259 { 6, szOID_ENROLL_CERTTYPE_EXTENSION, 0, (LPCWSTR)IDS_CERT_TEMPLATE_NAME, NULL }, 1260 { 6, szOID_ENROLL_CERTTYPE_EXTENSION, 0, (LPCWSTR)IDS_CERT_TYPE, NULL }, 1261 { 6, szOID_CERT_MANIFOLD, 0, (LPCWSTR)IDS_CERT_MANIFOLD, NULL }, 1262 { 6, szOID_NETSCAPE_CERT_TYPE, 0, (LPCWSTR)IDS_NETSCAPE_CERT_TYPE, NULL }, 1263 { 6, szOID_NETSCAPE_BASE_URL, 0, (LPCWSTR)IDS_NETSCAPE_BASE_URL, NULL }, 1264 { 6, szOID_NETSCAPE_REVOCATION_URL, 0, (LPCWSTR)IDS_NETSCAPE_REVOCATION_URL, NULL }, 1265 { 6, szOID_NETSCAPE_CA_REVOCATION_URL, 0, (LPCWSTR)IDS_NETSCAPE_CA_REVOCATION_URL, NULL }, 1266 { 6, szOID_NETSCAPE_CERT_RENEWAL_URL, 0, (LPCWSTR)IDS_NETSCAPE_CERT_RENEWAL_URL, NULL }, 1267 { 6, szOID_NETSCAPE_CA_POLICY_URL, 0, (LPCWSTR)IDS_NETSCAPE_CA_POLICY_URL, NULL }, 1268 { 6, szOID_NETSCAPE_SSL_SERVER_NAME, 0, (LPCWSTR)IDS_NETSCAPE_SSL_SERVER_NAME, NULL }, 1269 { 6, szOID_NETSCAPE_COMMENT, 0, (LPCWSTR)IDS_NETSCAPE_COMMENT, NULL }, 1270 { 6, "1.3.6.1.4.1.311.2.1.10", 0, SpcSpAgencyInfo, NULL }, 1271 { 6, "1.3.6.1.4.1.311.2.1.27", 0, SpcFinancialCriteria, NULL }, 1272 { 6, "1.3.6.1.4.1.311.2.1.26", 0, SpcMinimalCriteria, NULL }, 1273 { 6, szOID_COUNTRY_NAME, 0, (LPCWSTR)IDS_COUNTRY, NULL }, 1274 { 6, szOID_ORGANIZATION_NAME, 0, (LPCWSTR)IDS_ORGANIZATION, NULL }, 1275 { 6, szOID_ORGANIZATIONAL_UNIT_NAME, 0, (LPCWSTR)IDS_ORGANIZATIONAL_UNIT, NULL }, 1276 { 6, szOID_COMMON_NAME, 0, (LPCWSTR)IDS_COMMON_NAME, NULL }, 1277 { 6, szOID_LOCALITY_NAME, 0, (LPCWSTR)IDS_LOCALITY, NULL }, 1278 { 6, szOID_STATE_OR_PROVINCE_NAME, 0, (LPCWSTR)IDS_STATE_OR_PROVINCE, NULL }, 1279 { 6, szOID_TITLE, 0, (LPCWSTR)IDS_TITLE, NULL }, 1280 { 6, szOID_GIVEN_NAME, 0, (LPCWSTR)IDS_GIVEN_NAME, NULL }, 1281 { 6, szOID_INITIALS, 0, (LPCWSTR)IDS_INITIALS, NULL }, 1282 { 6, szOID_SUR_NAME, 0, (LPCWSTR)IDS_SUR_NAME, NULL }, 1283 { 6, szOID_DOMAIN_COMPONENT, 0, (LPCWSTR)IDS_DOMAIN_COMPONENT, NULL }, 1284 { 6, szOID_STREET_ADDRESS, 0, (LPCWSTR)IDS_STREET_ADDRESS, NULL }, 1285 { 6, szOID_DEVICE_SERIAL_NUMBER, 0, (LPCWSTR)IDS_SERIAL_NUMBER, NULL }, 1286 { 6, szOID_CERTSRV_CA_VERSION, 0, (LPCWSTR)IDS_CA_VERSION, NULL }, 1287 { 6, szOID_CERTSRV_CROSSCA_VERSION, 0, (LPCWSTR)IDS_CROSS_CA_VERSION, NULL }, 1288 { 6, szOID_SERIALIZED, 0, (LPCWSTR)IDS_SERIALIZED_SIG_SERIAL_NUMBER, NULL }, 1289 { 6, szOID_NT_PRINCIPAL_NAME, 0, (LPCWSTR)IDS_PRINCIPAL_NAME, NULL }, 1290 { 6, szOID_PRODUCT_UPDATE, 0, (LPCWSTR)IDS_WINDOWS_PRODUCT_UPDATE, NULL }, 1291 { 6, szOID_ENROLLMENT_NAME_VALUE_PAIR, 0, (LPCWSTR)IDS_ENROLLMENT_NAME_VALUE_PAIR, NULL }, 1292 { 6, szOID_OS_VERSION, 0, (LPCWSTR)IDS_OS_VERSION, NULL }, 1293 { 6, szOID_ENROLLMENT_CSP_PROVIDER, 0, (LPCWSTR)IDS_ENROLLMENT_CSP, NULL }, 1294 { 6, szOID_CRL_NUMBER, 0, (LPCWSTR)IDS_CRL_NUMBER, NULL }, 1295 { 6, szOID_DELTA_CRL_INDICATOR, 0, (LPCWSTR)IDS_DELTA_CRL_INDICATOR, NULL }, 1296 { 6, szOID_ISSUING_DIST_POINT, 0, (LPCWSTR)IDS_ISSUING_DIST_POINT, NULL }, 1297 { 6, szOID_FRESHEST_CRL, 0, (LPCWSTR)IDS_FRESHEST_CRL, NULL }, 1298 { 6, szOID_NAME_CONSTRAINTS, 0, (LPCWSTR)IDS_NAME_CONSTRAINTS, NULL }, 1299 { 6, szOID_POLICY_MAPPINGS, 0, (LPCWSTR)IDS_POLICY_MAPPINGS, NULL }, 1300 { 6, szOID_LEGACY_POLICY_MAPPINGS, 0, (LPCWSTR)IDS_POLICY_MAPPINGS, NULL }, 1301 { 6, szOID_POLICY_CONSTRAINTS, 0, (LPCWSTR)IDS_POLICY_CONSTRAINTS, NULL }, 1302 { 6, szOID_CROSS_CERT_DIST_POINTS, 0, (LPCWSTR)IDS_CROSS_CERT_DIST_POINTS, NULL }, 1303 { 6, szOID_APPLICATION_CERT_POLICIES, 0, (LPCWSTR)IDS_APPLICATION_POLICIES, NULL }, 1304 { 6, szOID_APPLICATION_POLICY_MAPPINGS, 0, (LPCWSTR)IDS_APPLICATION_POLICY_MAPPINGS, NULL }, 1305 { 6, szOID_APPLICATION_POLICY_CONSTRAINTS, 0, (LPCWSTR)IDS_APPLICATION_POLICY_CONSTRAINTS, NULL }, 1306 { 6, szOID_CT_PKI_DATA, 0, (LPCWSTR)IDS_CMC_DATA, NULL }, 1307 { 6, szOID_CT_PKI_RESPONSE, 0, (LPCWSTR)IDS_CMC_RESPONSE, NULL }, 1308 { 6, szOID_CMC, 0, (LPCWSTR)IDS_UNSIGNED_CMC_REQUEST, NULL }, 1309 { 6, szOID_CMC_STATUS_INFO, 0, (LPCWSTR)IDS_CMC_STATUS_INFO, NULL }, 1310 { 6, szOID_CMC_ADD_EXTENSIONS, 0, (LPCWSTR)IDS_CMC_EXTENSIONS, NULL }, 1311 { 6, szOID_CTL, 0, (LPCWSTR)IDS_CMC_ATTRIBUTES, NULL }, 1312 { 6, szOID_RSA_data, 0, (LPCWSTR)IDS_PKCS_7_DATA, NULL }, 1313 { 6, szOID_RSA_signedData, 0, (LPCWSTR)IDS_PKCS_7_SIGNED, NULL }, 1314 { 6, szOID_RSA_envelopedData, 0, (LPCWSTR)IDS_PKCS_7_ENVELOPED, NULL }, 1315 { 6, szOID_RSA_signEnvData, 0, (LPCWSTR)IDS_PKCS_7_SIGNED_ENVELOPED, NULL }, 1316 { 6, szOID_RSA_digestedData, 0, (LPCWSTR)IDS_PKCS_7_DIGESTED, NULL }, 1317 { 6, szOID_RSA_encryptedData, 0, (LPCWSTR)IDS_PKCS_7_ENCRYPTED, NULL }, 1318 { 6, szOID_CERTSRV_PREVIOUS_CERT_HASH, 0, (LPCWSTR)IDS_PREVIOUS_CA_CERT_HASH, NULL }, 1319 { 6, szOID_CRL_VIRTUAL_BASE, 0, (LPCWSTR)IDS_CRL_VIRTUAL_BASE, NULL }, 1320 { 6, szOID_CRL_NEXT_PUBLISH, 0, (LPCWSTR)IDS_CRL_NEXT_PUBLISH, NULL }, 1321 { 6, szOID_KP_CA_EXCHANGE, 0, (LPCWSTR)IDS_CA_EXCHANGE, NULL }, 1322 { 6, szOID_KP_KEY_RECOVERY_AGENT, 0, (LPCWSTR)IDS_KEY_RECOVERY_AGENT, NULL }, 1323 { 6, szOID_CERTIFICATE_TEMPLATE, 0, (LPCWSTR)IDS_CERTIFICATE_TEMPLATE, NULL }, 1324 { 6, szOID_ENTERPRISE_OID_ROOT, 0, (LPCWSTR)IDS_ENTERPRISE_ROOT_OID, NULL }, 1325 { 6, szOID_RDN_DUMMY_SIGNER, 0, (LPCWSTR)IDS_RDN_DUMMY_SIGNER, NULL }, 1326 { 6, szOID_ARCHIVED_KEY_ATTR, 0, (LPCWSTR)IDS_ARCHIVED_KEY_ATTR, NULL }, 1327 { 6, szOID_CRL_SELF_CDP, 0, (LPCWSTR)IDS_CRL_SELF_CDP, NULL }, 1328 { 6, szOID_REQUIRE_CERT_CHAIN_POLICY, 0, (LPCWSTR)IDS_REQUIRE_CERT_CHAIN_POLICY, NULL }, 1329 { 6, szOID_CMC_TRANSACTION_ID, 0, (LPCWSTR)IDS_TRANSACTION_ID, NULL }, 1330 { 6, szOID_CMC_SENDER_NONCE, 0, (LPCWSTR)IDS_SENDER_NONCE, NULL }, 1331 { 6, szOID_CMC_RECIPIENT_NONCE, 0, (LPCWSTR)IDS_RECIPIENT_NONCE, NULL }, 1332 { 6, szOID_CMC_REG_INFO, 0, (LPCWSTR)IDS_REG_INFO, NULL }, 1333 { 6, szOID_CMC_GET_CERT, 0, (LPCWSTR)IDS_GET_CERTIFICATE, NULL }, 1334 { 6, szOID_CMC_GET_CRL, 0, (LPCWSTR)IDS_GET_CRL, NULL }, 1335 { 6, szOID_CMC_REVOKE_REQUEST, 0, (LPCWSTR)IDS_REVOKE_REQUEST, NULL }, 1336 { 6, szOID_CMC_QUERY_PENDING, 0, (LPCWSTR)IDS_QUERY_PENDING, NULL }, 1337 { 6, szOID_SORTED_CTL, 0, (LPCWSTR)IDS_SORTED_CTL, NULL }, 1338 { 6, szOID_ARCHIVED_KEY_CERT_HASH, 0, (LPCWSTR)IDS_ARCHIVED_KEY_CERT_HASH, NULL }, 1339 { 6, szOID_PRIVATEKEY_USAGE_PERIOD, 0, (LPCWSTR)IDS_PRIVATE_KEY_USAGE_PERIOD, NULL }, 1340 { 6, szOID_REQUEST_CLIENT_INFO, 0, (LPCWSTR)IDS_CLIENT_INFORMATION, NULL }, 1341 1342 { 7, szOID_PKIX_KP_SERVER_AUTH, 0, (LPCWSTR)IDS_SERVER_AUTHENTICATION, NULL }, 1343 { 7, szOID_PKIX_KP_CLIENT_AUTH, 0, (LPCWSTR)IDS_CLIENT_AUTHENTICATION, NULL }, 1344 { 7, szOID_PKIX_KP_CODE_SIGNING, 0, (LPCWSTR)IDS_CODE_SIGNING, NULL }, 1345 { 7, szOID_PKIX_KP_EMAIL_PROTECTION, 0, (LPCWSTR)IDS_SECURE_EMAIL, NULL }, 1346 { 7, szOID_PKIX_KP_TIMESTAMP_SIGNING, 0, (LPCWSTR)IDS_TIME_STAMPING, NULL }, 1347 { 7, szOID_KP_CTL_USAGE_SIGNING, 0, (LPCWSTR)IDS_MICROSOFT_TRUST_LIST_SIGNING, NULL }, 1348 { 7, szOID_KP_TIME_STAMP_SIGNING, 0, (LPCWSTR)IDS_MICROSOFT_TIME_STAMPING, NULL }, 1349 { 7, szOID_PKIX_KP_IPSEC_END_SYSTEM, 0, (LPCWSTR)IDS_IPSEC_END_SYSTEM, NULL }, 1350 { 7, szOID_PKIX_KP_IPSEC_TUNNEL, 0, (LPCWSTR)IDS_IPSEC_TUNNEL, NULL }, 1351 { 7, szOID_PKIX_KP_IPSEC_USER, 0, (LPCWSTR)IDS_IPSEC_USER, NULL }, 1352 { 7, szOID_KP_EFS, 0, (LPCWSTR)IDS_EFS, NULL }, 1353 { 7, szOID_WHQL_CRYPTO, 0, (LPCWSTR)IDS_WHQL_CRYPTO, NULL }, 1354 { 7, szOID_NT5_CRYPTO, 0, (LPCWSTR)IDS_NT5_CRYPTO, NULL }, 1355 { 7, szOID_OEM_WHQL_CRYPTO, 0, (LPCWSTR)IDS_OEM_WHQL_CRYPTO, NULL }, 1356 { 7, szOID_EMBEDDED_NT_CRYPTO, 0, (LPCWSTR)IDS_EMBEDDED_NT_CRYPTO, NULL }, 1357 { 7, szOID_LICENSES, 0, (LPCWSTR)IDS_KEY_PACK_LICENSES, NULL }, 1358 { 7, szOID_LICENSE_SERVER, 0, (LPCWSTR)IDS_LICENSE_SERVER, NULL }, 1359 { 7, szOID_KP_SMARTCARD_LOGON, 0, (LPCWSTR)IDS_SMART_CARD_LOGON, NULL }, 1360 { 7, szOID_DRM, 0, (LPCWSTR)IDS_DIGITAL_RIGHTS, NULL }, 1361 { 7, szOID_KP_QUALIFIED_SUBORDINATION, 0, (LPCWSTR)IDS_QUALIFIED_SUBORDINATION, NULL }, 1362 { 7, szOID_KP_KEY_RECOVERY, 0, (LPCWSTR)IDS_KEY_RECOVERY, NULL }, 1363 { 7, szOID_KP_DOCUMENT_SIGNING, 0, (LPCWSTR)IDS_DOCUMENT_SIGNING, NULL }, 1364 { 7, szOID_IPSEC_KP_IKE_INTERMEDIATE, 0, (LPCWSTR)IDS_IPSEC_IKE_INTERMEDIATE, NULL }, 1365 { 7, szOID_EFS_RECOVERY, 0, (LPCWSTR)IDS_FILE_RECOVERY, NULL }, 1366 { 7, szOID_ROOT_LIST_SIGNER, 0, (LPCWSTR)IDS_ROOT_LIST_SIGNER, NULL }, 1367 { 7, szOID_ANY_APPLICATION_POLICY, 0, (LPCWSTR)IDS_ANY_APPLICATION_POLICIES, NULL }, 1368 { 7, szOID_DS_EMAIL_REPLICATION, 0, (LPCWSTR)IDS_DS_EMAIL_REPLICATION, NULL }, 1369 { 7, szOID_ENROLLMENT_AGENT, 0, (LPCWSTR)IDS_ENROLLMENT_AGENT, NULL }, 1370 { 7, szOID_KP_KEY_RECOVERY_AGENT, 0, (LPCWSTR)IDS_KEY_RECOVERY_AGENT, NULL }, 1371 { 7, szOID_KP_CA_EXCHANGE, 0, (LPCWSTR)IDS_CA_EXCHANGE, NULL }, 1372 { 7, szOID_KP_LIFETIME_SIGNING, 0, (LPCWSTR)IDS_LIFETIME_SIGNING, NULL }, 1373 1374 { 8, szOID_ANY_CERT_POLICY, 0, (LPCWSTR)IDS_ANY_CERT_POLICY, NULL }, 1375 }; 1376 1377 struct OIDInfo { 1378 CRYPT_OID_INFO info; 1379 struct list entry; 1380 }; 1381 1382 static void init_oid_info(void) 1383 { 1384 DWORD i; 1385 1386 oid_init_localizednames(); 1387 for (i = 0; i < sizeof(oidInfoConstructors) / 1388 sizeof(oidInfoConstructors[0]); i++) 1389 { 1390 if (!IS_INTRESOURCE(oidInfoConstructors[i].pwszName)) 1391 { 1392 struct OIDInfo *info; 1393 1394 /* The name is a static string, so just use the same pointer */ 1395 info = CryptMemAlloc(sizeof(struct OIDInfo)); 1396 if (info) 1397 { 1398 memset(info, 0, sizeof(*info)); 1399 info->info.cbSize = sizeof(CRYPT_OID_INFO); 1400 info->info.pszOID = oidInfoConstructors[i].pszOID; 1401 info->info.pwszName = oidInfoConstructors[i].pwszName; 1402 info->info.dwGroupId = oidInfoConstructors[i].dwGroupId; 1403 info->info.u.Algid = oidInfoConstructors[i].Algid; 1404 if (oidInfoConstructors[i].blob) 1405 { 1406 info->info.ExtraInfo.cbData = 1407 oidInfoConstructors[i].blob->cbData; 1408 info->info.ExtraInfo.pbData = 1409 oidInfoConstructors[i].blob->pbData; 1410 } 1411 list_add_tail(&oidInfo, &info->entry); 1412 } 1413 } 1414 else 1415 { 1416 LPCWSTR stringresource; 1417 int len = LoadStringW(hInstance, 1418 (UINT_PTR)oidInfoConstructors[i].pwszName, 1419 (LPWSTR)&stringresource, 0); 1420 1421 if (len) 1422 { 1423 struct OIDInfo *info = CryptMemAlloc(sizeof(struct OIDInfo) + 1424 (len + 1) * sizeof(WCHAR)); 1425 1426 if (info) 1427 { 1428 memset(info, 0, sizeof(*info)); 1429 info->info.cbSize = sizeof(CRYPT_OID_INFO); 1430 info->info.pszOID = oidInfoConstructors[i].pszOID; 1431 info->info.pwszName = (LPWSTR)(info + 1); 1432 info->info.dwGroupId = oidInfoConstructors[i].dwGroupId; 1433 info->info.u.Algid = oidInfoConstructors[i].Algid; 1434 memcpy(info + 1, stringresource, len*sizeof(WCHAR)); 1435 ((LPWSTR)(info + 1))[len] = 0; 1436 if (oidInfoConstructors[i].blob) 1437 { 1438 info->info.ExtraInfo.cbData = 1439 oidInfoConstructors[i].blob->cbData; 1440 info->info.ExtraInfo.pbData = 1441 oidInfoConstructors[i].blob->pbData; 1442 } 1443 list_add_tail(&oidInfo, &info->entry); 1444 } 1445 } 1446 } 1447 } 1448 } 1449 1450 static void free_oid_info(void) 1451 { 1452 struct OIDInfo *info, *next; 1453 1454 LIST_FOR_EACH_ENTRY_SAFE(info, next, &oidInfo, struct OIDInfo, entry) 1455 { 1456 list_remove(&info->entry); 1457 CryptMemFree(info); 1458 } 1459 DeleteCriticalSection(&oidInfoCS); 1460 } 1461 1462 /*********************************************************************** 1463 * CryptEnumOIDInfo (CRYPT32.@) 1464 */ 1465 BOOL WINAPI CryptEnumOIDInfo(DWORD dwGroupId, DWORD dwFlags, void *pvArg, 1466 PFN_CRYPT_ENUM_OID_INFO pfnEnumOIDInfo) 1467 { 1468 BOOL ret = TRUE; 1469 struct OIDInfo *info; 1470 1471 TRACE("(%d, %08x, %p, %p)\n", dwGroupId, dwFlags, pvArg, 1472 pfnEnumOIDInfo); 1473 1474 EnterCriticalSection(&oidInfoCS); 1475 LIST_FOR_EACH_ENTRY(info, &oidInfo, struct OIDInfo, entry) 1476 { 1477 if (!dwGroupId || dwGroupId == info->info.dwGroupId) 1478 { 1479 ret = pfnEnumOIDInfo(&info->info, pvArg); 1480 if (!ret) 1481 break; 1482 } 1483 } 1484 LeaveCriticalSection(&oidInfoCS); 1485 return ret; 1486 } 1487 1488 PCCRYPT_OID_INFO WINAPI CryptFindOIDInfo(DWORD dwKeyType, void *pvKey, 1489 DWORD dwGroupId) 1490 { 1491 PCCRYPT_OID_INFO ret = NULL; 1492 1493 TRACE("(%d, %p, %d)\n", dwKeyType, pvKey, dwGroupId); 1494 1495 switch(dwKeyType) 1496 { 1497 case CRYPT_OID_INFO_ALGID_KEY: 1498 { 1499 struct OIDInfo *info; 1500 1501 TRACE("CRYPT_OID_INFO_ALGID_KEY: %d\n", *(DWORD *)pvKey); 1502 EnterCriticalSection(&oidInfoCS); 1503 LIST_FOR_EACH_ENTRY(info, &oidInfo, struct OIDInfo, entry) 1504 { 1505 if (info->info.u.Algid == *(DWORD *)pvKey && 1506 (!dwGroupId || info->info.dwGroupId == dwGroupId)) 1507 { 1508 ret = &info->info; 1509 break; 1510 } 1511 } 1512 LeaveCriticalSection(&oidInfoCS); 1513 break; 1514 } 1515 case CRYPT_OID_INFO_NAME_KEY: 1516 { 1517 struct OIDInfo *info; 1518 1519 TRACE("CRYPT_OID_INFO_NAME_KEY: %s\n", debugstr_w(pvKey)); 1520 EnterCriticalSection(&oidInfoCS); 1521 LIST_FOR_EACH_ENTRY(info, &oidInfo, struct OIDInfo, entry) 1522 { 1523 if (!lstrcmpW(info->info.pwszName, pvKey) && 1524 (!dwGroupId || info->info.dwGroupId == dwGroupId)) 1525 { 1526 ret = &info->info; 1527 break; 1528 } 1529 } 1530 LeaveCriticalSection(&oidInfoCS); 1531 break; 1532 } 1533 case CRYPT_OID_INFO_OID_KEY: 1534 { 1535 struct OIDInfo *info; 1536 LPSTR oid = pvKey; 1537 1538 TRACE("CRYPT_OID_INFO_OID_KEY: %s\n", debugstr_a(oid)); 1539 EnterCriticalSection(&oidInfoCS); 1540 LIST_FOR_EACH_ENTRY(info, &oidInfo, struct OIDInfo, entry) 1541 { 1542 if (!lstrcmpA(info->info.pszOID, oid) && 1543 (!dwGroupId || info->info.dwGroupId == dwGroupId)) 1544 { 1545 ret = &info->info; 1546 break; 1547 } 1548 } 1549 LeaveCriticalSection(&oidInfoCS); 1550 break; 1551 } 1552 case CRYPT_OID_INFO_SIGN_KEY: 1553 { 1554 struct OIDInfo *info; 1555 1556 TRACE("CRYPT_OID_INFO_SIGN_KEY: %d\n", *(DWORD *)pvKey); 1557 EnterCriticalSection(&oidInfoCS); 1558 LIST_FOR_EACH_ENTRY(info, &oidInfo, struct OIDInfo, entry) 1559 { 1560 if (info->info.u.Algid == *(DWORD *)pvKey && 1561 info->info.ExtraInfo.cbData >= sizeof(DWORD) && 1562 *(DWORD *)info->info.ExtraInfo.pbData == 1563 *(DWORD *)((LPBYTE)pvKey + sizeof(DWORD)) && 1564 (!dwGroupId || info->info.dwGroupId == dwGroupId)) 1565 { 1566 ret = &info->info; 1567 break; 1568 } 1569 } 1570 LeaveCriticalSection(&oidInfoCS); 1571 break; 1572 } 1573 } 1574 return ret; 1575 } 1576 1577 LPCSTR WINAPI CertAlgIdToOID(DWORD dwAlgId) 1578 { 1579 LPCSTR ret; 1580 PCCRYPT_OID_INFO info = CryptFindOIDInfo(CRYPT_OID_INFO_ALGID_KEY, 1581 &dwAlgId, 0); 1582 1583 if (info) 1584 ret = info->pszOID; 1585 else 1586 ret = NULL; 1587 return ret; 1588 } 1589 1590 DWORD WINAPI CertOIDToAlgId(LPCSTR pszObjId) 1591 { 1592 DWORD ret; 1593 PCCRYPT_OID_INFO info = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY, 1594 (void *)pszObjId, 0); 1595 1596 if (info) 1597 ret = info->u.Algid; 1598 else 1599 ret = 0; 1600 return ret; 1601 } 1602 1603 void crypt_oid_init(void) 1604 { 1605 init_oid_info(); 1606 } 1607 1608 void crypt_oid_free(void) 1609 { 1610 free_function_sets(); 1611 free_oid_info(); 1612 } 1613