source: trunk/src/crypt32/oid.c@ 22020

Last change on this file since 22020 was 22020, checked in by dmik, 13 years ago

Disable debug fields of RTL_CRITICAL_SECTION_DEBUG.

Odin uses the DebugInfo ptr in CRITICAL_SECTION for its own purposes
which are incompatible with NT. For this reason any NT-style usage must
be disabled.

This in particular fixes debug assertions and crashes in CRYPT32.DLL (due to
misinterpretation of the structure fields) which happened e.g. during playback of
some Flash content.

File size: 56.5 KB
Line 
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 "config.h"
21#include "wine/port.h"
22
23#include <stdio.h>
24#include <stdarg.h>
25#include <string.h>
26#define NONAMELESSUNION
27#include "windef.h"
28#include "winbase.h"
29#include "wincrypt.h"
30#include "winreg.h"
31#include "winuser.h"
32#include "wine/debug.h"
33#include "wine/list.h"
34#include "crypt32_private.h"
35#include "cryptres.h"
36
37//WINE_DEFAULT_DEBUG_CHANNEL(crypt);
38
39static const WCHAR DllW[] = { 'D','l','l',0 };
40
41static void init_oid_info(void);
42static void free_function_sets(void);
43static void free_oid_info(void);
44
45void crypt_oid_init(void)
46{
47 init_oid_info();
48}
49
50void crypt_oid_free(void)
51{
52 dprintf(("oid: cp1"));
53 free_function_sets();
54 dprintf(("oid: cp2"));
55 free_oid_info();
56 dprintf(("oid: cp3"));
57}
58
59static RTL_CRITICAL_SECTION funcSetCS;
60static RTL_CRITICAL_SECTION_DEBUG funcSetCSDebug =
61{
62#ifndef __WIN32OS2__
63 0, 0, &funcSetCS,
64 { &funcSetCSDebug.ProcessLocksList, &funcSetCSDebug.ProcessLocksList },
65 0, 0, { (DWORD)(DWORD_PTR)(__FILE__ ": funcSetCS") }
66#endif
67};
68static RTL_CRITICAL_SECTION funcSetCS = { &funcSetCSDebug, -1, 0, 0, 0, 0 };
69static struct list funcSets = { &funcSets, &funcSets };
70
71struct OIDFunctionSet
72{
73 LPSTR name;
74 RTL_CRITICAL_SECTION cs; /* protects functions */
75 struct list functions;
76 struct list next;
77};
78
79struct OIDFunction
80{
81 DWORD encoding;
82 CRYPT_OID_FUNC_ENTRY entry;
83 struct list next;
84};
85
86static const WCHAR ROOT[] = {'R','O','O','T',0};
87static const WCHAR MY[] = {'M','Y',0};
88static const WCHAR CA[] = {'C','A',0};
89static const WCHAR ADDRESSBOOK[] = {'A','D','D','R','E','S','S','B','O','O','K',0};
90static const LPCWSTR LocalizedKeys[] = {ROOT,MY,CA,ADDRESSBOOK};
91static WCHAR LocalizedNames[4][256];
92
93static void free_function_sets(void)
94{
95 struct OIDFunctionSet *setCursor, *setNext;
96
97 LIST_FOR_EACH_ENTRY_SAFE(setCursor, setNext, &funcSets,
98 struct OIDFunctionSet, next)
99 {
100 struct OIDFunction *functionCursor, *funcNext;
101
102 list_remove(&setCursor->next);
103 CryptMemFree(setCursor->name);
104 LIST_FOR_EACH_ENTRY_SAFE(functionCursor, funcNext,
105 &setCursor->functions, struct OIDFunction, next)
106 {
107 list_remove(&functionCursor->next);
108 CryptMemFree(functionCursor);
109 }
110#ifndef __WIN32OS2__
111 setCursor->cs.DebugInfo->Spare[0] = 0;
112#endif
113 DeleteCriticalSection((CRITICAL_SECTION*)&setCursor->cs);
114 CryptMemFree(setCursor);
115 }
116}
117
118/* There is no free function associated with this; therefore, the sets are
119 * freed when crypt32.dll is unloaded.
120 */
121HCRYPTOIDFUNCSET WINAPI CryptInitOIDFunctionSet(LPCSTR pszFuncName,
122 DWORD dwFlags)
123{
124 struct OIDFunctionSet *cursor, *ret = NULL;
125
126 TRACE("(%s, %x)\n", debugstr_a(pszFuncName), dwFlags);
127
128 EnterCriticalSection((CRITICAL_SECTION*)&funcSetCS);
129 LIST_FOR_EACH_ENTRY(cursor, &funcSets, struct OIDFunctionSet, next)
130 {
131 if (!strcasecmp(pszFuncName, cursor->name))
132 {
133 ret = (HCRYPTOIDFUNCSET)cursor;
134 break;
135 }
136 }
137 if (!ret)
138 {
139 ret = CryptMemAlloc(sizeof(struct OIDFunctionSet));
140 if (ret)
141 {
142 memset(ret, 0, sizeof(*ret));
143 ret->name = CryptMemAlloc(strlen(pszFuncName) + 1);
144 if (ret->name)
145 {
146 InitializeCriticalSection((CRITICAL_SECTION*)&ret->cs);
147#ifndef __WIN32OS2__
148 ret->cs.DebugInfo->Spare[0] = (DWORD)(DWORD_PTR)(__FILE__ ": OIDFunctionSet.cs");
149#endif
150 list_init(&ret->functions);
151 strcpy(ret->name, pszFuncName);
152 list_add_tail(&funcSets, &ret->next);
153 }
154 else
155 {
156 CryptMemFree(ret);
157 ret = NULL;
158 }
159 }
160 }
161 LeaveCriticalSection((CRITICAL_SECTION*)&funcSetCS);
162
163 return (HCRYPTOIDFUNCSET)ret;
164}
165
166static char *CRYPT_GetKeyName(DWORD dwEncodingType, LPCSTR pszFuncName,
167 LPCSTR pszOID)
168{
169 static const char szEncodingTypeFmt[] =
170 "Software\\Microsoft\\Cryptography\\OID\\EncodingType %d\\%s\\%s";
171 UINT len;
172 char numericOID[7]; /* enough for "#65535" */
173 const char *oid;
174 LPSTR szKey;
175
176 /* MSDN says the encoding type is a mask, but it isn't treated that way.
177 * (E.g., if dwEncodingType were 3, the key names "EncodingType 1" and
178 * "EncodingType 2" would be expected if it were a mask. Instead native
179 * stores values in "EncodingType 3".
180 */
181 if (!HIWORD(pszOID))
182 {
183 crypt32_snprintf(numericOID, sizeof(numericOID), "#%d", LOWORD(pszOID));
184 oid = numericOID;
185 }
186 else
187 oid = pszOID;
188
189 /* This is enough: the lengths of the two string parameters are explicitly
190 * counted, and we need up to five additional characters for the encoding
191 * type. These are covered by the "%d", "%s", and "%s" characters in the
192 * format specifier that are removed by sprintf.
193 */
194 len = sizeof(szEncodingTypeFmt) + lstrlenA(pszFuncName) + lstrlenA(oid);
195 szKey = CryptMemAlloc(len);
196 if (szKey)
197 sprintf(szKey, szEncodingTypeFmt,
198 GET_CERT_ENCODING_TYPE(dwEncodingType), pszFuncName, oid);
199 return szKey;
200}
201
202BOOL WINAPI CryptGetDefaultOIDDllList(HCRYPTOIDFUNCSET hFuncSet,
203 DWORD dwEncodingType, LPWSTR pwszDllList, DWORD *pcchDllList)
204{
205 BOOL ret = TRUE;
206 struct OIDFunctionSet *set = (struct OIDFunctionSet *)hFuncSet;
207 char *keyName;
208 HKEY key;
209 long rc;
210
211 TRACE("(%p, %d, %p, %p)\n", hFuncSet, dwEncodingType, pwszDllList,
212 pcchDllList);
213
214 keyName = CRYPT_GetKeyName(dwEncodingType, set->name, "DEFAULT");
215 rc = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, NULL, 0,
216 KEY_READ, NULL, &key, NULL);
217 if (!rc)
218 {
219 DWORD size = *pcchDllList * sizeof(WCHAR);
220
221 rc = RegQueryValueExW(key, DllW, NULL, NULL, (LPBYTE)pwszDllList,
222 &size);
223 if (!rc)
224 *pcchDllList = size / sizeof(WCHAR);
225 else
226 {
227 /* No value, return an empty list */
228 if (pwszDllList && *pcchDllList)
229 *pwszDllList = '\0';
230 *pcchDllList = 1;
231 }
232 RegCloseKey(key);
233 }
234 else
235 {
236 /* No value, return an empty list */
237 if (pwszDllList && *pcchDllList)
238 *pwszDllList = '\0';
239 *pcchDllList = 1;
240 }
241 CryptMemFree(keyName);
242
243 return ret;
244}
245
246BOOL WINAPI CryptInstallOIDFunctionAddress(HMODULE hModule,
247 DWORD dwEncodingType, LPCSTR pszFuncName, DWORD cFuncEntry,
248 const CRYPT_OID_FUNC_ENTRY rgFuncEntry[], DWORD dwFlags)
249{
250 BOOL ret = TRUE;
251 struct OIDFunctionSet *set;
252
253 TRACE("(%p, %d, %s, %d, %p, %08x)\n", hModule, dwEncodingType,
254 debugstr_a(pszFuncName), cFuncEntry, rgFuncEntry, dwFlags);
255
256 set = (struct OIDFunctionSet *)CryptInitOIDFunctionSet(pszFuncName, 0);
257 if (set)
258 {
259 DWORD i;
260
261 EnterCriticalSection((CRITICAL_SECTION*)&set->cs);
262 for (i = 0; ret && i < cFuncEntry; i++)
263 {
264 struct OIDFunction *func;
265
266 if (HIWORD(rgFuncEntry[i].pszOID))
267 func = CryptMemAlloc(sizeof(struct OIDFunction)
268 + strlen(rgFuncEntry[i].pszOID) + 1);
269 else
270 func = CryptMemAlloc(sizeof(struct OIDFunction));
271 if (func)
272 {
273 func->encoding = GET_CERT_ENCODING_TYPE(dwEncodingType);
274 if (HIWORD(rgFuncEntry[i].pszOID))
275 {
276 LPSTR oid;
277
278 oid = (LPSTR)((LPBYTE)func + sizeof(*func));
279 strcpy(oid, rgFuncEntry[i].pszOID);
280 func->entry.pszOID = oid;
281 }
282 else
283 func->entry.pszOID = rgFuncEntry[i].pszOID;
284 func->entry.pvFuncAddr = rgFuncEntry[i].pvFuncAddr;
285 list_add_tail(&set->functions, &func->next);
286 }
287 else
288 ret = FALSE;
289 }
290 LeaveCriticalSection((CRITICAL_SECTION*)&set->cs);
291 }
292 else
293 ret = FALSE;
294 return ret;
295}
296
297struct FuncAddr
298{
299 HMODULE lib;
300 LPWSTR dllList;
301 LPWSTR currentDll;
302};
303
304static BOOL CRYPT_GetFuncFromReg(DWORD dwEncodingType, LPCSTR pszOID,
305 LPCSTR szFuncName, LPVOID *ppvFuncAddr, HCRYPTOIDFUNCADDR *phFuncAddr)
306{
307 BOOL ret = FALSE;
308 char *keyName;
309 const char *funcName;
310 HKEY key;
311 long rc;
312
313 keyName = CRYPT_GetKeyName(dwEncodingType, szFuncName, pszOID);
314 rc = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, KEY_READ, &key);
315 if (!rc)
316 {
317 DWORD type, size = 0;
318
319 rc = RegQueryValueExA(key, "FuncName", NULL, &type, NULL, &size);
320 if ((!rc || rc == ERROR_MORE_DATA) && type == REG_SZ)
321 {
322 funcName = CryptMemAlloc(size);
323 rc = RegQueryValueExA(key, "FuncName", NULL, &type,
324 (LPBYTE)funcName, &size);
325 }
326 else
327 funcName = szFuncName;
328 rc = RegQueryValueExW(key, DllW, NULL, &type, NULL, &size);
329 if ((!rc || rc == ERROR_MORE_DATA) && type == REG_SZ)
330 {
331 LPWSTR dllName = CryptMemAlloc(size);
332
333 if (dllName)
334 {
335 rc = RegQueryValueExW(key, DllW, NULL, NULL,
336 (LPBYTE)dllName, &size);
337 if (!rc)
338 {
339 HMODULE lib;
340
341 /* This is a bit of a hack; MSDN describes a more
342 * complicated unload routine than this will allow.
343 * Still, this seems to suffice for now.
344 */
345 lib = LoadLibraryW(dllName);
346 if (lib)
347 {
348 *ppvFuncAddr = (LPVOID)GetProcAddress(lib, funcName);
349 if (*ppvFuncAddr)
350 {
351 struct FuncAddr *addr =
352 CryptMemAlloc(sizeof(struct FuncAddr));
353
354 if (addr)
355 {
356 addr->lib = lib;
357 addr->dllList = addr->currentDll = NULL;
358 *phFuncAddr = addr;
359 ret = TRUE;
360 }
361 else
362 {
363 *phFuncAddr = NULL;
364 FreeLibrary(lib);
365 }
366 }
367 else
368 {
369 /* Unload the library, the caller doesn't want
370 * to unload it when the return value is NULL.
371 */
372 FreeLibrary(lib);
373 }
374 }
375 }
376 else
377 SetLastError(rc);
378 CryptMemFree(dllName);
379 }
380 }
381 else
382 SetLastError(rc);
383 if (funcName != szFuncName)
384 CryptMemFree((char *)funcName);
385 RegCloseKey(key);
386 }
387 else
388 SetLastError(rc);
389 CryptMemFree(keyName);
390 return ret;
391}
392
393BOOL WINAPI CryptGetOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet,
394 DWORD dwEncodingType, LPCSTR pszOID, DWORD dwFlags, void **ppvFuncAddr,
395 HCRYPTOIDFUNCADDR *phFuncAddr)
396{
397 BOOL ret = FALSE;
398 struct OIDFunctionSet *set = (struct OIDFunctionSet *)hFuncSet;
399
400 TRACE("(%p, %d, %s, %08x, %p, %p)\n", hFuncSet, dwEncodingType,
401 debugstr_a(pszOID), dwFlags, ppvFuncAddr, phFuncAddr);
402
403 *ppvFuncAddr = NULL;
404 if (!(dwFlags & CRYPT_GET_INSTALLED_OID_FUNC_FLAG))
405 {
406 struct OIDFunction *function;
407
408 EnterCriticalSection((CRITICAL_SECTION*)&set->cs);
409 LIST_FOR_EACH_ENTRY(function, &set->functions, struct OIDFunction, next)
410 {
411 if (function->encoding == GET_CERT_ENCODING_TYPE(dwEncodingType))
412 {
413 if (HIWORD(pszOID))
414 {
415 if (HIWORD(function->entry.pszOID) &&
416 !strcasecmp(function->entry.pszOID, pszOID))
417 {
418 *ppvFuncAddr = function->entry.pvFuncAddr;
419 *phFuncAddr = NULL; /* FIXME: what should it be? */
420 ret = TRUE;
421 break;
422 }
423 }
424 else if (function->entry.pszOID == pszOID)
425 {
426 *ppvFuncAddr = function->entry.pvFuncAddr;
427 *phFuncAddr = NULL; /* FIXME: what should it be? */
428 ret = TRUE;
429 break;
430 }
431 }
432 }
433 LeaveCriticalSection((CRITICAL_SECTION*)&set->cs);
434 }
435 if (!*ppvFuncAddr)
436 ret = CRYPT_GetFuncFromReg(dwEncodingType, pszOID, set->name,
437 ppvFuncAddr, phFuncAddr);
438 TRACE("returning %d\n", ret);
439 return ret;
440}
441
442BOOL WINAPI CryptFreeOIDFunctionAddress(HCRYPTOIDFUNCADDR hFuncAddr,
443 DWORD dwFlags)
444{
445 TRACE("(%p, %08x)\n", hFuncAddr, dwFlags);
446
447 /* FIXME: as MSDN states, need to check for DllCanUnloadNow in the DLL,
448 * and only unload it if it can be unloaded. Also need to implement ref
449 * counting on the functions.
450 */
451 if (hFuncAddr)
452 {
453 struct FuncAddr *addr = (struct FuncAddr *)hFuncAddr;
454
455 CryptMemFree(addr->dllList);
456 FreeLibrary(addr->lib);
457 CryptMemFree(addr);
458 }
459 return TRUE;
460}
461
462static BOOL CRYPT_GetFuncFromDll(LPCWSTR dll, LPCSTR func, HMODULE *lib,
463 void **ppvFuncAddr)
464{
465 BOOL ret = FALSE;
466
467 *lib = LoadLibraryW(dll);
468 if (*lib)
469 {
470 *ppvFuncAddr = (LPVOID)GetProcAddress(*lib, func);
471 if (*ppvFuncAddr)
472 ret = TRUE;
473 else
474 {
475 FreeLibrary(*lib);
476 *lib = NULL;
477 }
478 }
479 return ret;
480}
481
482BOOL WINAPI CryptGetDefaultOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet,
483 DWORD dwEncodingType, LPCWSTR pwszDll, DWORD dwFlags, void **ppvFuncAddr,
484 HCRYPTOIDFUNCADDR *phFuncAddr)
485{
486 struct OIDFunctionSet *set = (struct OIDFunctionSet *)hFuncSet;
487 BOOL ret = FALSE;
488
489 TRACE("(%p, %d, %s, %08x, %p, %p)\n", hFuncSet, dwEncodingType,
490 debugstr_w(pwszDll), dwFlags, ppvFuncAddr, phFuncAddr);
491
492 if (pwszDll)
493 {
494 HMODULE lib;
495
496 *phFuncAddr = NULL;
497 ret = CRYPT_GetFuncFromDll(pwszDll, set->name, &lib, ppvFuncAddr);
498 if (ret)
499 {
500 struct FuncAddr *addr = CryptMemAlloc(sizeof(struct FuncAddr));
501
502 if (addr)
503 {
504 addr->lib = lib;
505 addr->dllList = addr->currentDll = NULL;
506 *phFuncAddr = addr;
507 }
508 else
509 {
510 FreeLibrary(lib);
511 *ppvFuncAddr = NULL;
512 SetLastError(ERROR_OUTOFMEMORY);
513 ret = FALSE;
514 }
515 }
516 else
517 SetLastError(ERROR_FILE_NOT_FOUND);
518 }
519 else
520 {
521 struct FuncAddr *addr = (struct FuncAddr *)*phFuncAddr;
522
523 if (!addr)
524 {
525 DWORD size;
526
527 ret = CryptGetDefaultOIDDllList(hFuncSet, dwEncodingType, NULL,
528 &size);
529 if (ret)
530 {
531 LPWSTR dllList = CryptMemAlloc(size * sizeof(WCHAR));
532
533 if (dllList)
534 {
535 ret = CryptGetDefaultOIDDllList(hFuncSet, dwEncodingType,
536 dllList, &size);
537 if (ret)
538 {
539 addr = CryptMemAlloc(sizeof(struct FuncAddr));
540 if (addr)
541 {
542 addr->dllList = dllList;
543 addr->currentDll = dllList;
544 addr->lib = NULL;
545 *phFuncAddr = addr;
546 }
547 else
548 {
549 CryptMemFree(dllList);
550 SetLastError(ERROR_OUTOFMEMORY);
551 ret = FALSE;
552 }
553 }
554 }
555 else
556 {
557 SetLastError(ERROR_OUTOFMEMORY);
558 ret = FALSE;
559 }
560 }
561 }
562 if (addr)
563 {
564 if (!*addr->currentDll)
565 {
566 CryptFreeOIDFunctionAddress(*phFuncAddr, 0);
567 SetLastError(ERROR_FILE_NOT_FOUND);
568 *phFuncAddr = NULL;
569 ret = FALSE;
570 }
571 else
572 {
573 /* FIXME: as elsewhere, can't free until DllCanUnloadNow says
574 * it's possible, and should defer unloading for some time to
575 * avoid repeated LoadLibrary/FreeLibrary on the same dll.
576 */
577 FreeLibrary(addr->lib);
578 ret = CRYPT_GetFuncFromDll(addr->currentDll, set->name,
579 &addr->lib, ppvFuncAddr);
580 if (ret)
581 {
582 /* Move past the current DLL */
583 addr->currentDll += lstrlenW(addr->currentDll) + 1;
584 *phFuncAddr = addr;
585 }
586 else
587 {
588 CryptFreeOIDFunctionAddress(*phFuncAddr, 0);
589 SetLastError(ERROR_FILE_NOT_FOUND);
590 *phFuncAddr = NULL;
591 }
592 }
593 }
594 }
595 return ret;
596}
597
598/***********************************************************************
599 * CryptRegisterOIDFunction (CRYPT32.@)
600 *
601 * Register the DLL and the functions it uses to cover the combination
602 * of encoding type, functionname and OID.
603 *
604 * PARAMS
605 * dwEncodingType [I] Encoding type to be used.
606 * pszFuncName [I] Name of the function to be registered.
607 * pszOID [I] OID of the function (numeric or string).
608 * pwszDll [I] The DLL that is to be registered.
609 * pszOverrideFuncName [I] Name of the function in the DLL.
610 *
611 * RETURNS
612 * Success: TRUE.
613 * Failure: FALSE. (Look at GetLastError()).
614 *
615 * NOTES
616 * Registry errors are always reported via SetLastError().
617 */
618BOOL WINAPI CryptRegisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName,
619 LPCSTR pszOID, LPCWSTR pwszDll, LPCSTR pszOverrideFuncName)
620{
621 LONG r;
622 HKEY hKey;
623 LPSTR szKey;
624
625 TRACE("(%x, %s, %s, %s, %s)\n", dwEncodingType, pszFuncName,
626 debugstr_a(pszOID), debugstr_w(pwszDll), pszOverrideFuncName);
627
628 /* Native does nothing pwszDll is NULL */
629 if (!pwszDll)
630 return TRUE;
631
632 /* I'm not matching MS bug for bug here, because I doubt any app depends on
633 * it: native "succeeds" if pszFuncName is NULL, but the nonsensical entry
634 * it creates would never be used.
635 */
636 if (!pszFuncName || !pszOID)
637 {
638 SetLastError(E_INVALIDARG);
639 return FALSE;
640 }
641
642 szKey = CRYPT_GetKeyName(dwEncodingType, pszFuncName, pszOID);
643 TRACE("Key name is %s\n", debugstr_a(szKey));
644
645 if (!szKey)
646 return FALSE;
647
648 r = RegCreateKeyA(HKEY_LOCAL_MACHINE, szKey, &hKey);
649 CryptMemFree(szKey);
650
651 if (r != ERROR_SUCCESS) goto error_close_key;
652
653 /* write the values */
654 if (pszOverrideFuncName)
655 {
656 r = RegSetValueExA(hKey, "FuncName", 0, REG_SZ,
657 (LPBYTE)pszOverrideFuncName, lstrlenA(pszOverrideFuncName) + 1);
658 if (r != ERROR_SUCCESS) goto error_close_key;
659 }
660 r = RegSetValueExW(hKey, DllW, 0, REG_SZ, (LPBYTE) pwszDll,
661 (lstrlenW(pwszDll) + 1) * sizeof (WCHAR));
662
663error_close_key:
664
665 RegCloseKey(hKey);
666
667 if (r != ERROR_SUCCESS)
668 {
669 SetLastError(r);
670 return FALSE;
671 }
672
673 return TRUE;
674}
675
676/***********************************************************************
677 * CryptUnregisterOIDFunction (CRYPT32.@)
678 */
679BOOL WINAPI CryptUnregisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName,
680 LPCSTR pszOID)
681{
682 LPSTR szKey;
683 LONG rc;
684
685 TRACE("%x %s %s\n", dwEncodingType, debugstr_a(pszFuncName),
686 debugstr_a(pszOID));
687
688 if (!pszFuncName || !pszOID)
689 {
690 SetLastError(ERROR_INVALID_PARAMETER);
691 return FALSE;
692 }
693
694 szKey = CRYPT_GetKeyName(dwEncodingType, pszFuncName, pszOID);
695 rc = RegDeleteKeyA(HKEY_LOCAL_MACHINE, szKey);
696 CryptMemFree(szKey);
697 if (rc)
698 SetLastError(rc);
699 return rc ? FALSE : TRUE;
700}
701
702BOOL WINAPI CryptGetOIDFunctionValue(DWORD dwEncodingType, LPCSTR pszFuncName,
703 LPCSTR pszOID, LPCWSTR pwszValueName, DWORD *pdwValueType, BYTE *pbValueData,
704 DWORD *pcbValueData)
705{
706 LPSTR szKey;
707 LONG rc;
708 HKEY hKey;
709
710 TRACE("%x %s %s %s %p %p %p\n", dwEncodingType, debugstr_a(pszFuncName),
711 debugstr_a(pszOID), debugstr_w(pwszValueName), pdwValueType, pbValueData,
712 pcbValueData);
713
714 if (!GET_CERT_ENCODING_TYPE(dwEncodingType))
715 return TRUE;
716
717 if (!pszFuncName || !pszOID || !pwszValueName)
718 {
719 SetLastError(ERROR_INVALID_PARAMETER);
720 return FALSE;
721 }
722
723 szKey = CRYPT_GetKeyName(dwEncodingType, pszFuncName, pszOID);
724 rc = RegOpenKeyA(HKEY_LOCAL_MACHINE, szKey, &hKey);
725 CryptMemFree(szKey);
726 if (rc)
727 SetLastError(rc);
728 else
729 {
730 rc = RegQueryValueExW(hKey, pwszValueName, NULL, pdwValueType,
731 pbValueData, pcbValueData);
732 if (rc)
733 SetLastError(rc);
734 RegCloseKey(hKey);
735 }
736 return rc ? FALSE : TRUE;
737}
738
739BOOL WINAPI CryptSetOIDFunctionValue(DWORD dwEncodingType, LPCSTR pszFuncName,
740 LPCSTR pszOID, LPCWSTR pwszValueName, DWORD dwValueType,
741 const BYTE *pbValueData, DWORD cbValueData)
742{
743 LPSTR szKey;
744 LONG rc;
745 HKEY hKey;
746
747 TRACE("%x %s %s %s %d %p %d\n", dwEncodingType, debugstr_a(pszFuncName),
748 debugstr_a(pszOID), debugstr_w(pwszValueName), dwValueType, pbValueData,
749 cbValueData);
750
751 if (!GET_CERT_ENCODING_TYPE(dwEncodingType))
752 return TRUE;
753
754 if (!pszFuncName || !pszOID || !pwszValueName)
755 {
756 SetLastError(ERROR_INVALID_PARAMETER);
757 return FALSE;
758 }
759
760 szKey = CRYPT_GetKeyName(dwEncodingType, pszFuncName, pszOID);
761 rc = RegOpenKeyA(HKEY_LOCAL_MACHINE, szKey, &hKey);
762 CryptMemFree(szKey);
763 if (rc)
764 SetLastError(rc);
765 else
766 {
767 rc = RegSetValueExW(hKey, pwszValueName, 0, dwValueType, (LPBYTE)pbValueData,
768 cbValueData);
769 if (rc)
770 SetLastError(rc);
771 RegCloseKey(hKey);
772 }
773 return rc ? FALSE : TRUE;
774}
775
776static LPCWSTR CRYPT_FindStringInMultiString(LPCWSTR multi, LPCWSTR toFind)
777{
778 LPCWSTR ret = NULL, ptr;
779
780 for (ptr = multi; ptr && *ptr && !ret; ptr += lstrlenW(ptr) + 1)
781 {
782 if (!lstrcmpiW(ptr, toFind))
783 ret = ptr;
784 }
785 return ret;
786}
787
788static DWORD CRYPT_GetMultiStringCharacterLen(LPCWSTR multi)
789{
790 DWORD ret;
791
792 if (multi)
793 {
794 LPCWSTR ptr;
795
796 /* Count terminating empty string */
797 ret = 1;
798 for (ptr = multi; *ptr; ptr += lstrlenW(ptr) + 1)
799 ret += lstrlenW(ptr) + 1;
800 }
801 else
802 ret = 0;
803 return ret;
804}
805
806static LPWSTR CRYPT_AddStringToMultiString(LPWSTR multi, LPCWSTR toAdd,
807 DWORD index)
808{
809 LPWSTR ret;
810
811 if (!multi)
812 {
813 /* FIXME: ignoring index, is that okay? */
814 ret = CryptMemAlloc((lstrlenW(toAdd) + 2) * sizeof(WCHAR));
815 if (ret)
816 {
817 /* copy string, including NULL terminator */
818 memcpy(ret, toAdd, (lstrlenW(toAdd) + 1) * sizeof(WCHAR));
819 /* add terminating empty string */
820 *(ret + lstrlenW(toAdd) + 1) = 0;
821 }
822 }
823 else
824 {
825 DWORD len = CRYPT_GetMultiStringCharacterLen(multi);
826
827 ret = CryptMemRealloc(multi, (len + lstrlenW(toAdd) + 1) *
828 sizeof(WCHAR));
829 if (ret)
830 {
831 LPWSTR spotToAdd;
832
833 if (index == CRYPT_REGISTER_LAST_INDEX)
834 spotToAdd = ret + len - 1;
835 else
836 {
837 DWORD i;
838
839 /* FIXME: if index is too large for the string, toAdd is
840 * added to the end. Is that okay?
841 */
842 for (i = 0, spotToAdd = ret; i < index && *spotToAdd;
843 spotToAdd += lstrlenW(spotToAdd) + 1)
844 ;
845 }
846 if (spotToAdd)
847 {
848 /* Copy existing string "right" */
849 memmove(spotToAdd + lstrlenW(toAdd) + 1, spotToAdd,
850 (len - (spotToAdd - ret)) * sizeof(WCHAR));
851 /* Copy new string */
852 memcpy(spotToAdd, toAdd, (lstrlenW(toAdd) + 1) * sizeof(WCHAR));
853 }
854 else
855 {
856 CryptMemFree(ret);
857 ret = NULL;
858 }
859 }
860 }
861 return ret;
862}
863
864static BOOL CRYPT_RemoveStringFromMultiString(LPWSTR multi, LPCWSTR toRemove)
865{
866 LPWSTR spotToRemove = (LPWSTR)CRYPT_FindStringInMultiString(multi,
867 toRemove);
868 BOOL ret;
869
870 if (spotToRemove)
871 {
872 DWORD len = CRYPT_GetMultiStringCharacterLen(multi);
873
874 /* Copy remainder of string "left" */
875 memmove(spotToRemove, spotToRemove + lstrlenW(toRemove) + 1,
876 (len - (spotToRemove - multi)) * sizeof(WCHAR));
877 ret = TRUE;
878 }
879 else
880 {
881 SetLastError(ERROR_FILE_NOT_FOUND);
882 ret = FALSE;
883 }
884 return ret;
885}
886
887static BOOL CRYPT_GetDefaultOIDKey(DWORD dwEncodingType, LPCSTR pszFuncName,
888 PHKEY key)
889{
890 LPSTR keyName;
891 LONG r;
892
893 keyName = CRYPT_GetKeyName(dwEncodingType, pszFuncName, "DEFAULT");
894 TRACE("Key name is %s\n", debugstr_a(keyName));
895
896 if (!keyName)
897 return FALSE;
898
899 r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, NULL, 0, KEY_ALL_ACCESS,
900 NULL, key, NULL);
901 CryptMemFree(keyName);
902 if (r != ERROR_SUCCESS)
903 {
904 SetLastError(r);
905 return FALSE;
906 }
907 return TRUE;
908}
909
910static LPWSTR CRYPT_GetDefaultOIDDlls(HKEY key)
911{
912 LONG r;
913 DWORD type, size;
914 LPWSTR dlls;
915
916 r = RegQueryValueExW(key, DllW, NULL, &type, NULL, &size);
917 if (r == ERROR_SUCCESS && type == REG_MULTI_SZ)
918 {
919 dlls = CryptMemAlloc(size);
920 r = RegQueryValueExW(key, DllW, NULL, &type, (LPBYTE)dlls, &size);
921 if (r != ERROR_SUCCESS)
922 {
923 CryptMemFree(dlls);
924 dlls = NULL;
925 }
926 }
927 else
928 dlls = NULL;
929 return dlls;
930}
931
932static inline BOOL CRYPT_SetDefaultOIDDlls(HKEY key, LPCWSTR dlls)
933{
934 DWORD len = CRYPT_GetMultiStringCharacterLen(dlls);
935 LONG r;
936
937 if ((r = RegSetValueExW(key, DllW, 0, REG_MULTI_SZ, (LPBYTE)dlls,
938 len * sizeof (WCHAR))) != 0)
939 SetLastError(r);
940 return r == ERROR_SUCCESS;
941}
942
943/***********************************************************************
944 * CryptRegisterDefaultOIDFunction (CRYPT32.@)
945 */
946BOOL WINAPI CryptRegisterDefaultOIDFunction(DWORD dwEncodingType,
947 LPCSTR pszFuncName, DWORD dwIndex, LPCWSTR pwszDll)
948{
949 HKEY key;
950 LPWSTR dlls;
951 BOOL ret = FALSE;
952
953 TRACE("(%x, %s, %d, %s)\n", dwEncodingType, debugstr_a(pszFuncName),
954 dwIndex, debugstr_w(pwszDll));
955
956 if (!pwszDll)
957 {
958 SetLastError(E_INVALIDARG);
959 return FALSE;
960 }
961
962 if (!CRYPT_GetDefaultOIDKey(dwEncodingType, pszFuncName, &key))
963 return FALSE;
964
965 dlls = CRYPT_GetDefaultOIDDlls(key);
966 if (CRYPT_FindStringInMultiString(dlls, pwszDll))
967 SetLastError(ERROR_FILE_EXISTS);
968 else
969 {
970 dlls = CRYPT_AddStringToMultiString(dlls, pwszDll, dwIndex);
971 if (dlls)
972 ret = CRYPT_SetDefaultOIDDlls(key, dlls);
973 }
974 CryptMemFree(dlls);
975 RegCloseKey(key);
976 return ret;
977}
978
979BOOL WINAPI CryptUnregisterDefaultOIDFunction(DWORD dwEncodingType,
980 LPCSTR pszFuncName, LPCWSTR pwszDll)
981{
982 HKEY key;
983 LPWSTR dlls;
984 BOOL ret;
985
986 TRACE("(%x, %s, %s)\n", dwEncodingType, debugstr_a(pszFuncName),
987 debugstr_w(pwszDll));
988
989 if (!pwszDll)
990 {
991 SetLastError(E_INVALIDARG);
992 return FALSE;
993 }
994
995 if (!CRYPT_GetDefaultOIDKey(dwEncodingType, pszFuncName, &key))
996 return FALSE;
997
998 dlls = CRYPT_GetDefaultOIDDlls(key);
999 if ((ret = CRYPT_RemoveStringFromMultiString(dlls, pwszDll)) != FALSE)
1000 ret = CRYPT_SetDefaultOIDDlls(key, dlls);
1001 CryptMemFree(dlls);
1002 RegCloseKey(key);
1003 return ret;
1004}
1005
1006static void oid_init_localizednames(void)
1007{
1008 unsigned int i;
1009
1010 for(i = 0; i < sizeof(LocalizedKeys)/sizeof(LPCWSTR); i++)
1011 {
1012 LoadStringW(hInstance, IDS_LOCALIZEDNAME_ROOT+i, LocalizedNames[i], 256);
1013 }
1014}
1015
1016/********************************************************************
1017 * CryptFindLocalizedName (CRYPT32.@)
1018 */
1019LPCWSTR WINAPI CryptFindLocalizedName(LPCWSTR pwszCryptName)
1020{
1021 unsigned int i;
1022
1023 for(i = 0; i < sizeof(LocalizedKeys)/sizeof(LPCWSTR); i++)
1024 {
1025 if(!lstrcmpiW(LocalizedKeys[i], pwszCryptName))
1026 {
1027 return LocalizedNames[i];
1028 }
1029 }
1030
1031 FIXME("No name for: %s - stub\n",debugstr_w(pwszCryptName));
1032 return NULL;
1033}
1034
1035static RTL_CRITICAL_SECTION oidInfoCS;
1036static RTL_CRITICAL_SECTION_DEBUG oidInfoCSDebug =
1037{
1038#ifndef __WIN32OS2__
1039 0, 0, &oidInfoCS,
1040 { &oidInfoCSDebug.ProcessLocksList, &oidInfoCSDebug.ProcessLocksList },
1041 0, 0, { (DWORD)(DWORD_PTR)(__FILE__ ": oidInfoCS") }
1042#endif
1043};
1044static RTL_CRITICAL_SECTION oidInfoCS = { &oidInfoCSDebug, -1, 0, 0, 0, 0 };
1045static struct list oidInfo = { &oidInfo, &oidInfo };
1046
1047static const WCHAR tripledes[] = { '3','d','e','s',0 };
1048static const WCHAR cms3deswrap[] = { 'C','M','S','3','D','E','S','w','r','a',
1049 'p',0 };
1050static const WCHAR cmsrc2wrap[] = { 'C','M','S','R','C','2','w','r','a','p',0 };
1051static const WCHAR des[] = { 'd','e','s',0 };
1052static const WCHAR md2[] = { 'm','d','2',0 };
1053static const WCHAR md4[] = { 'm','d','4',0 };
1054static const WCHAR md5[] = { 'm','d','5',0 };
1055static const WCHAR rc2[] = { 'r','c','2',0 };
1056static const WCHAR rc4[] = { 'r','c','4',0 };
1057static const WCHAR sha[] = { 's','h','a',0 };
1058static const WCHAR sha1[] = { 's','h','a','1',0 };
1059static const WCHAR RSA[] = { 'R','S','A',0 };
1060static const WCHAR RSA_KEYX[] = { 'R','S','A','_','K','E','Y','X',0 };
1061static const WCHAR RSA_SIGN[] = { 'R','S','A','_','S','I','G','N',0 };
1062static const WCHAR DSA[] = { 'D','S','A',0 };
1063static const WCHAR DSA_SIGN[] = { 'D','S','A','_','S','I','G','N',0 };
1064static const WCHAR DH[] = { 'D','H',0 };
1065static const WCHAR DSS[] = { 'D','S','S',0 };
1066static const WCHAR mosaicKMandUpdSig[] =
1067 { 'm','o','s','a','i','c','K','M','a','n','d','U','p','d','S','i','g',0 };
1068static const WCHAR ESDH[] = { 'E','S','D','H',0 };
1069static const WCHAR NO_SIGN[] = { 'N','O','S','I','G','N',0 };
1070static const WCHAR dsaSHA1[] = { 'd','s','a','S','H','A','1',0 };
1071static const WCHAR md2RSA[] = { 'm','d','2','R','S','A',0 };
1072static const WCHAR md4RSA[] = { 'm','d','4','R','S','A',0 };
1073static const WCHAR md5RSA[] = { 'm','d','5','R','S','A',0 };
1074static const WCHAR shaDSA[] = { 's','h','a','D','S','A',0 };
1075static const WCHAR sha1DSA[] = { 's','h','a','1','D','S','A',0 };
1076static const WCHAR shaRSA[] = { 's','h','a','R','S','A',0 };
1077static const WCHAR sha1RSA[] = { 's','h','a','1','R','S','A',0 };
1078static const WCHAR mosaicUpdatedSig[] =
1079 { 'm','o','s','a','i','c','U','p','d','a','t','e','d','S','i','g',0 };
1080static const WCHAR CN[] = { 'C','N',0 };
1081static const WCHAR L[] = { 'L',0 };
1082static const WCHAR O[] = { 'O',0 };
1083static const WCHAR OU[] = { 'O','U',0 };
1084static const WCHAR E[] = { 'E',0 };
1085static const WCHAR C[] = { 'C',0 };
1086static const WCHAR S[] = { 'S',0 };
1087static const WCHAR ST[] = { 'S','T',0 };
1088static const WCHAR STREET[] = { 'S','T','R','E','E','T',0 };
1089static const WCHAR T[] = { 'T',0 };
1090static const WCHAR Title[] = { 'T','i','t','l','e',0 };
1091static const WCHAR G[] = { 'G',0 };
1092static const WCHAR GivenName[] = { 'G','i','v','e','n','N','a','m','e',0 };
1093static const WCHAR I[] = { 'I',0 };
1094static const WCHAR Initials[] = { 'I','n','i','t','i','a','l','s',0 };
1095static const WCHAR SN[] = { 'S','N',0 };
1096static const WCHAR DC[] = { 'D','C',0 };
1097static const WCHAR Description[] =
1098 { 'D','e','s','c','r','i','p','t','i','o','n',0 };
1099static const WCHAR PostalCode[] = { 'P','o','s','t','a','l','C','o','d','e',0 };
1100static const WCHAR POBox[] = { 'P','O','B','o','x',0 };
1101static const WCHAR Phone[] = { 'P','h','o','n','e',0 };
1102static const WCHAR X21Address[] = { 'X','2','1','A','d','d','r','e','s','s',0 };
1103static const WCHAR dnQualifier[] =
1104 { 'd','n','Q','u','a','l','i','f','i','e','r',0 };
1105static const WCHAR Email[] = { 'E','m','a','i','l',0 };
1106static const WCHAR GN[] = { 'G','N',0 };
1107
1108static const DWORD noNullFlag = CRYPT_OID_NO_NULL_ALGORITHM_PARA_FLAG;
1109static const DWORD mosaicFlags = CRYPT_OID_INHIBIT_SIGNATURE_FORMAT_FLAG |
1110 CRYPT_OID_NO_NULL_ALGORITHM_PARA_FLAG;
1111static const CRYPT_DATA_BLOB noNullBlob = { sizeof(noNullFlag),
1112 (LPBYTE)&noNullFlag };
1113static const CRYPT_DATA_BLOB mosaicFlagsBlob = { sizeof(mosaicFlags),
1114 (LPBYTE)&mosaicFlags };
1115
1116static const DWORD rsaSign = CALG_RSA_SIGN;
1117static const DWORD dssSign[2] = { CALG_DSS_SIGN,
1118 CRYPT_OID_NO_NULL_ALGORITHM_PARA_FLAG };
1119static const DWORD mosaicSign[2] = { CALG_DSS_SIGN,
1120 CRYPT_OID_INHIBIT_SIGNATURE_FORMAT_FLAG |
1121 CRYPT_OID_NO_NULL_ALGORITHM_PARA_FLAG };
1122static const CRYPT_DATA_BLOB rsaSignBlob = { sizeof(rsaSign),
1123 (LPBYTE)&rsaSign };
1124static const CRYPT_DATA_BLOB dssSignBlob = { sizeof(dssSign),
1125 (LPBYTE)dssSign };
1126static const CRYPT_DATA_BLOB mosaicSignBlob = { sizeof(mosaicSign),
1127 (LPBYTE)mosaicSign };
1128
1129static const DWORD ia5String[] = { CERT_RDN_IA5_STRING, 0 };
1130static const DWORD numericString[] = { CERT_RDN_NUMERIC_STRING, 0 };
1131static const DWORD printableString[] = { CERT_RDN_PRINTABLE_STRING, 0 };
1132static const DWORD domainCompTypes[] = { CERT_RDN_IA5_STRING,
1133 CERT_RDN_UTF8_STRING, 0 };
1134static const CRYPT_DATA_BLOB ia5StringBlob = { sizeof(ia5String),
1135 (LPBYTE)ia5String };
1136static const CRYPT_DATA_BLOB numericStringBlob = { sizeof(numericString),
1137 (LPBYTE)numericString };
1138static const CRYPT_DATA_BLOB printableStringBlob = { sizeof(printableString),
1139 (LPBYTE)printableString };
1140static const CRYPT_DATA_BLOB domainCompTypesBlob = { sizeof(domainCompTypes),
1141 (LPBYTE)domainCompTypes };
1142
1143static const struct OIDInfoConstructor {
1144 DWORD dwGroupId;
1145 LPCSTR pszOID;
1146 UINT Algid;
1147 LPCWSTR pwszName;
1148 const CRYPT_DATA_BLOB *blob;
1149} oidInfoConstructors[] = {
1150 { 1, szOID_OIWSEC_sha1, CALG_SHA1, sha1, NULL },
1151 { 1, szOID_OIWSEC_sha1, CALG_SHA1, sha, NULL },
1152 { 1, szOID_OIWSEC_sha, CALG_SHA, sha, NULL },
1153 { 1, szOID_RSA_MD5, CALG_MD5, md5, NULL },
1154 { 1, szOID_RSA_MD4, CALG_MD4, md4, NULL },
1155 { 1, szOID_RSA_MD2, CALG_MD2, md2, NULL },
1156
1157 { 2, szOID_OIWSEC_desCBC, CALG_DES, des, NULL },
1158 { 2, szOID_RSA_DES_EDE3_CBC, CALG_3DES, tripledes, NULL },
1159 { 2, szOID_RSA_RC2CBC, CALG_RC2, rc2, NULL },
1160 { 2, szOID_RSA_RC4, CALG_RC4, rc4, NULL },
1161 { 2, szOID_RSA_SMIMEalgCMS3DESwrap, CALG_3DES, cms3deswrap, NULL },
1162 { 2, szOID_RSA_SMIMEalgCMSRC2wrap, CALG_RC2, cmsrc2wrap, NULL },
1163
1164 { 3, szOID_RSA_RSA, CALG_RSA_KEYX, RSA, NULL },
1165 { 3, szOID_X957_DSA, CALG_DSS_SIGN, DSA, &noNullBlob },
1166 { 3, szOID_ANSI_X942_DH, CALG_DH_SF, DH, &noNullBlob },
1167 { 3, szOID_RSA_RSA, CALG_RSA_KEYX, RSA_KEYX, NULL },
1168 { 3, szOID_RSA_RSA, CALG_RSA_SIGN, RSA, NULL },
1169 { 3, szOID_RSA_RSA, CALG_RSA_SIGN, RSA_SIGN, NULL },
1170 { 3, szOID_OIWSEC_dsa, CALG_DSS_SIGN, DSA, &noNullBlob },
1171 { 3, szOID_OIWSEC_dsa, CALG_DSS_SIGN, DSS, &noNullBlob },
1172 { 3, szOID_OIWSEC_dsa, CALG_DSS_SIGN, DSA_SIGN, &noNullBlob },
1173 { 3, szOID_RSA_DH, CALG_DH_SF, DH, &noNullBlob },
1174 { 3, szOID_OIWSEC_rsaXchg, CALG_RSA_KEYX, RSA_KEYX, NULL },
1175 { 3, szOID_INFOSEC_mosaicKMandUpdSig, CALG_DSS_SIGN, mosaicKMandUpdSig,
1176 &mosaicFlagsBlob },
1177 { 3, szOID_RSA_SMIMEalgESDH, CALG_DH_EPHEM, ESDH, &noNullBlob },
1178 { 3, szOID_PKIX_NO_SIGNATURE, CALG_NO_SIGN, NO_SIGN, NULL },
1179
1180 { 4, szOID_RSA_SHA1RSA, CALG_SHA1, sha1RSA, &rsaSignBlob },
1181 { 4, szOID_RSA_MD5RSA, CALG_MD5, md5RSA, &rsaSignBlob },
1182 { 4, szOID_X957_SHA1DSA, CALG_SHA1, sha1DSA, &dssSignBlob },
1183 { 4, szOID_OIWSEC_sha1RSASign, CALG_SHA1, sha1RSA, &rsaSignBlob },
1184 { 4, szOID_OIWSEC_sha1RSASign, CALG_SHA1, shaRSA, &rsaSignBlob },
1185 { 4, szOID_OIWSEC_shaRSA, CALG_SHA1, shaRSA, &rsaSignBlob },
1186 { 4, szOID_OIWSEC_md5RSA, CALG_MD5, md5RSA, &rsaSignBlob },
1187 { 4, szOID_RSA_MD2RSA, CALG_MD2, md2RSA, &rsaSignBlob },
1188 { 4, szOID_RSA_MD4RSA, CALG_MD4, md4RSA, &rsaSignBlob },
1189 { 4, szOID_OIWSEC_md4RSA, CALG_MD4, md4RSA, &rsaSignBlob },
1190 { 4, szOID_OIWSEC_md4RSA2, CALG_MD4, md4RSA, &rsaSignBlob },
1191 { 4, szOID_OIWDIR_md2RSA, CALG_MD2, md2RSA, &rsaSignBlob },
1192 { 4, szOID_OIWSEC_shaDSA, CALG_SHA1, sha1DSA, &dssSignBlob },
1193 { 4, szOID_OIWSEC_shaDSA, CALG_SHA1, shaDSA, &dssSignBlob },
1194 { 4, szOID_OIWSEC_dsaSHA1, CALG_SHA1, dsaSHA1, &dssSignBlob },
1195 { 4, szOID_INFOSEC_mosaicUpdatedSig, CALG_SHA1, mosaicUpdatedSig,
1196 &mosaicSignBlob },
1197
1198 { 5, szOID_COMMON_NAME, 0, CN, NULL },
1199 { 5, szOID_LOCALITY_NAME, 0, L, NULL },
1200 { 5, szOID_ORGANIZATION_NAME, 0, O, NULL },
1201 { 5, szOID_ORGANIZATIONAL_UNIT_NAME, 0, OU, NULL },
1202 { 5, szOID_RSA_emailAddr, 0, E, &ia5StringBlob },
1203 { 5, szOID_RSA_emailAddr, 0, Email, &ia5StringBlob },
1204 { 5, szOID_COUNTRY_NAME, 0, C, &printableStringBlob },
1205 { 5, szOID_STATE_OR_PROVINCE_NAME, 0, S, NULL },
1206 { 5, szOID_STATE_OR_PROVINCE_NAME, 0, ST, NULL },
1207 { 5, szOID_STREET_ADDRESS, 0, STREET, NULL },
1208 { 5, szOID_TITLE, 0, T, NULL },
1209 { 5, szOID_TITLE, 0, Title, NULL },
1210 { 5, szOID_GIVEN_NAME, 0, G, NULL },
1211 { 5, szOID_GIVEN_NAME, 0, GN, NULL },
1212 { 5, szOID_GIVEN_NAME, 0, GivenName, NULL },
1213 { 5, szOID_INITIALS, 0, I, NULL },
1214 { 5, szOID_INITIALS, 0, Initials, NULL },
1215 { 5, szOID_SUR_NAME, 0, SN, NULL },
1216 { 5, szOID_DOMAIN_COMPONENT, 0, DC, &domainCompTypesBlob },
1217 { 5, szOID_DESCRIPTION, 0, Description, NULL },
1218 { 5, szOID_POSTAL_CODE, 0, PostalCode, NULL },
1219 { 5, szOID_POST_OFFICE_BOX, 0, POBox, NULL },
1220 { 5, szOID_TELEPHONE_NUMBER, 0, Phone, &printableStringBlob },
1221 { 5, szOID_X21_ADDRESS, 0, X21Address, &numericStringBlob },
1222 { 5, szOID_DN_QUALIFIER, 0, dnQualifier, 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, (LPCWSTR)IDS_SPC_SP_AGENCY_INFO, NULL },
1271 { 6, "1.3.6.1.4.1.311.2.1.27", 0, (LPCWSTR)IDS_SPC_FINANCIAL_CRITERIA, NULL },
1272 { 6, "1.3.6.1.4.1.311.2.1.26", 0, (LPCWSTR)IDS_SPC_MINIMAL_CRITERIA, 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
1377struct OIDInfo {
1378 CRYPT_OID_INFO info;
1379 struct list entry;
1380};
1381
1382static 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 (HIWORD(oidInfoConstructors[i].pwszName))
1391 {
1392 struct OIDInfo *info = NULL;
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#if 1
1399 memset(info, 0, sizeof(*info));
1400 info->info.cbSize = sizeof(CRYPT_OID_INFO);
1401 info->info.pszOID = oidInfoConstructors[i].pszOID;
1402 info->info.pwszName = oidInfoConstructors[i].pwszName;
1403 info->info.dwGroupId = oidInfoConstructors[i].dwGroupId;
1404 info->info.u.Algid = oidInfoConstructors[i].Algid;
1405 if (oidInfoConstructors[i].blob)
1406 {
1407 info->info.ExtraInfo.cbData =
1408 oidInfoConstructors[i].blob->cbData;
1409 info->info.ExtraInfo.pbData =
1410 oidInfoConstructors[i].blob->pbData;
1411 }
1412#endif
1413 list_add_tail(&oidInfo, &info->entry);
1414 }
1415 }
1416 else
1417 {
1418 LPCWSTR stringresource = NULL;
1419 int len = LoadStringW(hInstance,
1420 (UINT)(UINT_PTR)oidInfoConstructors[i].pwszName,
1421 (LPWSTR)&stringresource, 0);
1422
1423 if (len)
1424 {
1425 struct OIDInfo *info = CryptMemAlloc(sizeof(struct OIDInfo) +
1426 (len + 1) * sizeof(WCHAR));
1427
1428 if (info)
1429 {
1430#if 1
1431 memset(info, 0, sizeof(*info));
1432 info->info.cbSize = sizeof(CRYPT_OID_INFO);
1433 info->info.pszOID = oidInfoConstructors[i].pszOID;
1434 info->info.pwszName = (LPWSTR)(info + 1);
1435 info->info.dwGroupId = oidInfoConstructors[i].dwGroupId;
1436 info->info.u.Algid = oidInfoConstructors[i].Algid;
1437 if (stringresource && (char*)stringresource != (char*)0xAAAAAAAA)
1438 memcpy(info + 1, stringresource, len*sizeof(WCHAR));
1439 ((LPWSTR)(info + 1))[len] = 0;
1440 if (oidInfoConstructors[i].blob)
1441 {
1442 info->info.ExtraInfo.cbData =
1443 oidInfoConstructors[i].blob->cbData;
1444 info->info.ExtraInfo.pbData =
1445 oidInfoConstructors[i].blob->pbData;
1446 }
1447#endif
1448 list_add_tail(&oidInfo, &info->entry);
1449 }
1450 }
1451 }
1452 }
1453}
1454
1455static void free_oid_info(void)
1456{
1457 struct OIDInfo *info, *next;
1458
1459 LIST_FOR_EACH_ENTRY_SAFE(info, next, &oidInfo, struct OIDInfo, entry)
1460 {
1461 if (info > (struct OIDInfo*)0x10000)
1462 {
1463 if (&info->entry > (struct list*)0x10000)
1464 list_remove(&info->entry);
1465 CryptMemFree(info);
1466 }
1467 }
1468}
1469
1470/***********************************************************************
1471 * CryptEnumOIDInfo (CRYPT32.@)
1472 */
1473BOOL WINAPI CryptEnumOIDInfo(DWORD dwGroupId, DWORD dwFlags, void *pvArg,
1474 PFN_CRYPT_ENUM_OID_INFO pfnEnumOIDInfo)
1475{
1476 BOOL ret = TRUE;
1477 struct OIDInfo *info;
1478
1479 TRACE("(%d, %08x, %p, %p)\n", dwGroupId, dwFlags, pvArg,
1480 pfnEnumOIDInfo);
1481
1482 EnterCriticalSection((CRITICAL_SECTION*)&oidInfoCS);
1483 LIST_FOR_EACH_ENTRY(info, &oidInfo, struct OIDInfo, entry)
1484 {
1485 if (!dwGroupId || dwGroupId == info->info.dwGroupId)
1486 {
1487 ret = pfnEnumOIDInfo(&info->info, pvArg);
1488 if (!ret)
1489 break;
1490 }
1491 }
1492 LeaveCriticalSection((CRITICAL_SECTION*)&oidInfoCS);
1493 return ret;
1494}
1495
1496PCCRYPT_OID_INFO WINAPI CryptFindOIDInfo(DWORD dwKeyType, void *pvKey,
1497 DWORD dwGroupId)
1498{
1499 PCCRYPT_OID_INFO ret = NULL;
1500
1501 TRACE("(%d, %p, %d)\n", dwKeyType, pvKey, dwGroupId);
1502
1503 switch(dwKeyType)
1504 {
1505 case CRYPT_OID_INFO_ALGID_KEY:
1506 {
1507 struct OIDInfo *info;
1508
1509 TRACE("CRYPT_OID_INFO_ALGID_KEY: %d\n", *(DWORD *)pvKey);
1510 EnterCriticalSection((CRITICAL_SECTION*)&oidInfoCS);
1511 LIST_FOR_EACH_ENTRY(info, &oidInfo, struct OIDInfo, entry)
1512 {
1513 if (info->info.u.Algid == *(DWORD *)pvKey &&
1514 (!dwGroupId || info->info.dwGroupId == dwGroupId))
1515 {
1516 ret = &info->info;
1517 break;
1518 }
1519 }
1520 LeaveCriticalSection((CRITICAL_SECTION*)&oidInfoCS);
1521 break;
1522 }
1523 case CRYPT_OID_INFO_NAME_KEY:
1524 {
1525 struct OIDInfo *info;
1526
1527 TRACE("CRYPT_OID_INFO_NAME_KEY: %s\n", debugstr_w((LPWSTR)pvKey));
1528 EnterCriticalSection((CRITICAL_SECTION*)&oidInfoCS);
1529 LIST_FOR_EACH_ENTRY(info, &oidInfo, struct OIDInfo, entry)
1530 {
1531 if (!lstrcmpW(info->info.pwszName, (LPWSTR)pvKey) &&
1532 (!dwGroupId || info->info.dwGroupId == dwGroupId))
1533 {
1534 ret = &info->info;
1535 break;
1536 }
1537 }
1538 LeaveCriticalSection((CRITICAL_SECTION*)&oidInfoCS);
1539 break;
1540 }
1541 case CRYPT_OID_INFO_OID_KEY:
1542 {
1543 struct OIDInfo *info;
1544 LPSTR oid = (LPSTR)pvKey;
1545
1546 TRACE("CRYPT_OID_INFO_OID_KEY: %s\n", debugstr_a(oid));
1547 EnterCriticalSection((CRITICAL_SECTION*)&oidInfoCS);
1548 LIST_FOR_EACH_ENTRY(info, &oidInfo, struct OIDInfo, entry)
1549 {
1550 if (!lstrcmpA(info->info.pszOID, oid) &&
1551 (!dwGroupId || info->info.dwGroupId == dwGroupId))
1552 {
1553 ret = &info->info;
1554 break;
1555 }
1556 }
1557 LeaveCriticalSection((CRITICAL_SECTION*)&oidInfoCS);
1558 break;
1559 }
1560 case CRYPT_OID_INFO_SIGN_KEY:
1561 {
1562 struct OIDInfo *info;
1563
1564 TRACE("CRYPT_OID_INFO_SIGN_KEY: %d\n", *(DWORD *)pvKey);
1565 EnterCriticalSection((CRITICAL_SECTION*)&oidInfoCS);
1566 LIST_FOR_EACH_ENTRY(info, &oidInfo, struct OIDInfo, entry)
1567 {
1568 if (info->info.u.Algid == *(DWORD *)pvKey &&
1569 info->info.ExtraInfo.cbData >= sizeof(DWORD) &&
1570 *(DWORD *)info->info.ExtraInfo.pbData ==
1571 *(DWORD *)((LPBYTE)pvKey + sizeof(DWORD)) &&
1572 (!dwGroupId || info->info.dwGroupId == dwGroupId))
1573 {
1574 ret = &info->info;
1575 break;
1576 }
1577 }
1578 LeaveCriticalSection((CRITICAL_SECTION*)&oidInfoCS);
1579 break;
1580 }
1581 }
1582 return ret;
1583}
1584
1585LPCSTR WINAPI CertAlgIdToOID(DWORD dwAlgId)
1586{
1587 LPCSTR ret;
1588 PCCRYPT_OID_INFO info = CryptFindOIDInfo(CRYPT_OID_INFO_ALGID_KEY,
1589 &dwAlgId, 0);
1590
1591 if (info)
1592 ret = info->pszOID;
1593 else
1594 ret = NULL;
1595 return ret;
1596}
1597
1598DWORD WINAPI CertOIDToAlgId(LPCSTR pszObjId)
1599{
1600 DWORD ret;
1601 PCCRYPT_OID_INFO info = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
1602 (void *)pszObjId, 0);
1603
1604 if (info)
1605 ret = info->u.Algid;
1606 else
1607 ret = 0;
1608 return ret;
1609}
Note: See TracBrowser for help on using the repository browser.