ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

oid.c
Go to the documentation of this file.
00001 /*
00002  * Copyright 2002 Mike McCormack for CodeWeavers
00003  * Copyright 2005-2006 Juan Lang
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Lesser General Public
00007  * License as published by the Free Software Foundation; either
00008  * version 2.1 of the License, or (at your option) any later version.
00009  *
00010  * This library is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Lesser General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Lesser General Public
00016  * License along with this library; if not, write to the Free Software
00017  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00018  */
00019 
00020 #include "config.h"
00021 #include "wine/port.h"
00022 
00023 #include <stdio.h>
00024 #include <stdarg.h>
00025 #define NONAMELESSUNION
00026 #include "windef.h"
00027 #include "winbase.h"
00028 #include "wincrypt.h"
00029 #include "winreg.h"
00030 #include "winuser.h"
00031 #include "wine/debug.h"
00032 #include "wine/list.h"
00033 #include "crypt32_private.h"
00034 #include "cryptres.h"
00035 
00036 WINE_DEFAULT_DEBUG_CHANNEL(crypt);
00037 
00038 static const WCHAR DllW[] = { 'D','l','l',0 };
00039 
00040 static CRITICAL_SECTION funcSetCS;
00041 static CRITICAL_SECTION_DEBUG funcSetCSDebug =
00042 {
00043     0, 0, &funcSetCS,
00044     { &funcSetCSDebug.ProcessLocksList, &funcSetCSDebug.ProcessLocksList },
00045     0, 0, { (DWORD_PTR)(__FILE__ ": funcSetCS") }
00046 };
00047 static CRITICAL_SECTION funcSetCS = { &funcSetCSDebug, -1, 0, 0, 0, 0 };
00048 static struct list funcSets = { &funcSets, &funcSets };
00049 
00050 struct OIDFunctionSet
00051 {
00052     LPSTR name;
00053     CRITICAL_SECTION cs; /* protects functions */
00054     struct list functions;
00055     struct list next;
00056 };
00057 
00058 struct OIDFunction
00059 {
00060     DWORD encoding;
00061     CRYPT_OID_FUNC_ENTRY entry;
00062     struct list next;
00063 };
00064 
00065 static const WCHAR ROOT[] = {'R','O','O','T',0};
00066 static const WCHAR MY[] = {'M','Y',0};
00067 static const WCHAR CA[] = {'C','A',0};
00068 static const WCHAR ADDRESSBOOK[] = {'A','D','D','R','E','S','S','B','O','O','K',0};
00069 static const WCHAR TRUSTEDPUBLISHER[] = {'T','r','u','s','t','e','d','P','u','b','l','i','s','h','e','r',0};
00070 static const WCHAR DISALLOWED[] = {'D','i','s','a','l','l','o','w','e','d',0};
00071 static const LPCWSTR LocalizedKeys[] = {ROOT,MY,CA,ADDRESSBOOK,TRUSTEDPUBLISHER,DISALLOWED};
00072 static WCHAR LocalizedNames[sizeof(LocalizedKeys)/sizeof(LocalizedKeys[0])][256];
00073 
00074 static void free_function_sets(void)
00075 {
00076     struct OIDFunctionSet *setCursor, *setNext;
00077 
00078     LIST_FOR_EACH_ENTRY_SAFE(setCursor, setNext, &funcSets,
00079      struct OIDFunctionSet, next)
00080     {
00081         struct OIDFunction *functionCursor, *funcNext;
00082 
00083         list_remove(&setCursor->next);
00084         CryptMemFree(setCursor->name);
00085         LIST_FOR_EACH_ENTRY_SAFE(functionCursor, funcNext,
00086          &setCursor->functions, struct OIDFunction, next)
00087         {
00088             list_remove(&functionCursor->next);
00089             CryptMemFree(functionCursor);
00090         }
00091         setCursor->cs.DebugInfo->Spare[0] = 0;
00092         DeleteCriticalSection(&setCursor->cs);
00093         CryptMemFree(setCursor);
00094     }
00095     DeleteCriticalSection(&funcSetCS);
00096 }
00097 
00098 /* There is no free function associated with this; therefore, the sets are
00099  * freed when crypt32.dll is unloaded.
00100  */
00101 HCRYPTOIDFUNCSET WINAPI CryptInitOIDFunctionSet(LPCSTR pszFuncName,
00102  DWORD dwFlags)
00103 {
00104     struct OIDFunctionSet *cursor, *ret = NULL;
00105 
00106     TRACE("(%s, %x)\n", debugstr_a(pszFuncName), dwFlags);
00107 
00108     EnterCriticalSection(&funcSetCS);
00109     LIST_FOR_EACH_ENTRY(cursor, &funcSets, struct OIDFunctionSet, next)
00110     {
00111         if (!strcasecmp(pszFuncName, cursor->name))
00112         {
00113             ret = cursor;
00114             break;
00115         }
00116     }
00117     if (!ret)
00118     {
00119         ret = CryptMemAlloc(sizeof(struct OIDFunctionSet));
00120         if (ret)
00121         {
00122             memset(ret, 0, sizeof(*ret));
00123             ret->name = CryptMemAlloc(strlen(pszFuncName) + 1);
00124             if (ret->name)
00125             {
00126                 InitializeCriticalSection(&ret->cs);
00127                 ret->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": OIDFunctionSet.cs");
00128                 list_init(&ret->functions);
00129                 strcpy(ret->name, pszFuncName);
00130                 list_add_tail(&funcSets, &ret->next);
00131             }
00132             else
00133             {
00134                 CryptMemFree(ret);
00135                 ret = NULL;
00136             }
00137         }
00138     }
00139     LeaveCriticalSection(&funcSetCS);
00140 
00141     return ret;
00142 }
00143 
00144 static char *CRYPT_GetKeyName(DWORD dwEncodingType, LPCSTR pszFuncName,
00145  LPCSTR pszOID)
00146 {
00147     static const char szEncodingTypeFmt[] =
00148      "Software\\Microsoft\\Cryptography\\OID\\EncodingType %d\\%s\\%s";
00149     UINT len;
00150     char numericOID[7]; /* enough for "#65535" */
00151     const char *oid;
00152     LPSTR szKey;
00153 
00154     /* MSDN says the encoding type is a mask, but it isn't treated that way.
00155      * (E.g., if dwEncodingType were 3, the key names "EncodingType 1" and
00156      * "EncodingType 2" would be expected if it were a mask.  Instead native
00157      * stores values in "EncodingType 3".
00158      */
00159     if (IS_INTOID(pszOID))
00160     {
00161         snprintf(numericOID, sizeof(numericOID), "#%d", LOWORD(pszOID));
00162         oid = numericOID;
00163     }
00164     else
00165         oid = pszOID;
00166 
00167     /* This is enough: the lengths of the two string parameters are explicitly
00168      * counted, and we need up to five additional characters for the encoding
00169      * type.  These are covered by the "%d", "%s", and "%s" characters in the
00170      * format specifier that are removed by sprintf.
00171      */
00172     len = sizeof(szEncodingTypeFmt) + lstrlenA(pszFuncName) + lstrlenA(oid);
00173     szKey = CryptMemAlloc(len);
00174     if (szKey)
00175         sprintf(szKey, szEncodingTypeFmt,
00176          GET_CERT_ENCODING_TYPE(dwEncodingType), pszFuncName, oid);
00177     return szKey;
00178 }
00179 
00180 BOOL WINAPI CryptGetDefaultOIDDllList(HCRYPTOIDFUNCSET hFuncSet,
00181  DWORD dwEncodingType, LPWSTR pwszDllList, DWORD *pcchDllList)
00182 {
00183     BOOL ret = TRUE;
00184     struct OIDFunctionSet *set = hFuncSet;
00185     char *keyName;
00186     HKEY key;
00187     LSTATUS rc;
00188 
00189     TRACE("(%p, %d, %p, %p)\n", hFuncSet, dwEncodingType, pwszDllList,
00190      pcchDllList);
00191 
00192     keyName = CRYPT_GetKeyName(dwEncodingType, set->name, "DEFAULT");
00193     rc = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, NULL, 0,
00194      KEY_READ, NULL, &key, NULL);
00195     if (!rc)
00196     {
00197         DWORD size = *pcchDllList * sizeof(WCHAR);
00198 
00199         rc = RegQueryValueExW(key, DllW, NULL, NULL, (LPBYTE)pwszDllList,
00200          &size);
00201         if (!rc)
00202             *pcchDllList = size / sizeof(WCHAR);
00203         else
00204         {
00205             /* No value, return an empty list */
00206             if (pwszDllList && *pcchDllList)
00207                 *pwszDllList = '\0';
00208             *pcchDllList = 1;
00209         }
00210         RegCloseKey(key);
00211     }
00212     else
00213     {
00214         /* No value, return an empty list */
00215         if (pwszDllList && *pcchDllList)
00216             *pwszDllList = '\0';
00217         *pcchDllList = 1;
00218     }
00219     CryptMemFree(keyName);
00220 
00221     return ret;
00222 }
00223 
00224 BOOL WINAPI CryptInstallOIDFunctionAddress(HMODULE hModule,
00225  DWORD dwEncodingType, LPCSTR pszFuncName, DWORD cFuncEntry,
00226  const CRYPT_OID_FUNC_ENTRY rgFuncEntry[], DWORD dwFlags)
00227 {
00228     BOOL ret = TRUE;
00229     struct OIDFunctionSet *set;
00230 
00231     TRACE("(%p, %d, %s, %d, %p, %08x)\n", hModule, dwEncodingType,
00232      debugstr_a(pszFuncName), cFuncEntry, rgFuncEntry, dwFlags);
00233 
00234     set = CryptInitOIDFunctionSet(pszFuncName, 0);
00235     if (set)
00236     {
00237         DWORD i;
00238 
00239         EnterCriticalSection(&set->cs);
00240         for (i = 0; ret && i < cFuncEntry; i++)
00241         {
00242             struct OIDFunction *func;
00243 
00244             if (!IS_INTOID(rgFuncEntry[i].pszOID))
00245                 func = CryptMemAlloc(sizeof(struct OIDFunction)
00246                  + strlen(rgFuncEntry[i].pszOID) + 1);
00247             else
00248                 func = CryptMemAlloc(sizeof(struct OIDFunction));
00249             if (func)
00250             {
00251                 func->encoding = GET_CERT_ENCODING_TYPE(dwEncodingType);
00252                 if (!IS_INTOID(rgFuncEntry[i].pszOID))
00253                 {
00254                     LPSTR oid;
00255 
00256                     oid = (LPSTR)((LPBYTE)func + sizeof(*func));
00257                     strcpy(oid, rgFuncEntry[i].pszOID);
00258                     func->entry.pszOID = oid;
00259                 }
00260                 else
00261                     func->entry.pszOID = rgFuncEntry[i].pszOID;
00262                 func->entry.pvFuncAddr = rgFuncEntry[i].pvFuncAddr;
00263                 list_add_tail(&set->functions, &func->next);
00264             }
00265             else
00266                 ret = FALSE;
00267         }
00268         LeaveCriticalSection(&set->cs);
00269     }
00270     else
00271         ret = FALSE;
00272     return ret;
00273 }
00274 
00275 struct FuncAddr
00276 {
00277     HMODULE lib;
00278     LPWSTR  dllList;
00279     LPWSTR  currentDll;
00280 };
00281 
00282 static BOOL CRYPT_GetFuncFromReg(DWORD dwEncodingType, LPCSTR pszOID,
00283  LPCSTR szFuncName, LPVOID *ppvFuncAddr, HCRYPTOIDFUNCADDR *phFuncAddr)
00284 {
00285     BOOL ret = FALSE;
00286     char *keyName;
00287     const char *funcName;
00288     HKEY key;
00289     LSTATUS rc;
00290 
00291     keyName = CRYPT_GetKeyName(dwEncodingType, szFuncName, pszOID);
00292     rc = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, KEY_READ, &key);
00293     if (!rc)
00294     {
00295         DWORD type, size = 0;
00296 
00297         rc = RegQueryValueExA(key, "FuncName", NULL, &type, NULL, &size);
00298         if ((!rc || rc == ERROR_MORE_DATA) && type == REG_SZ)
00299         {
00300             funcName = CryptMemAlloc(size);
00301             rc = RegQueryValueExA(key, "FuncName", NULL, &type,
00302              (LPBYTE)funcName, &size);
00303         }
00304         else
00305             funcName = szFuncName;
00306         rc = RegQueryValueExW(key, DllW, NULL, &type, NULL, &size);
00307         if ((!rc || rc == ERROR_MORE_DATA) && type == REG_SZ)
00308         {
00309             LPWSTR dllName = CryptMemAlloc(size);
00310 
00311             if (dllName)
00312             {
00313                 rc = RegQueryValueExW(key, DllW, NULL, NULL,
00314                  (LPBYTE)dllName, &size);
00315                 if (!rc)
00316                 {
00317                     HMODULE lib;
00318 
00319                     /* This is a bit of a hack; MSDN describes a more
00320                      * complicated unload routine than this will allow.
00321                      * Still, this seems to suffice for now.
00322                      */
00323                     lib = LoadLibraryW(dllName);
00324                     if (lib)
00325                     {
00326                         *ppvFuncAddr = GetProcAddress(lib, funcName);
00327                         if (*ppvFuncAddr)
00328                         {
00329                             struct FuncAddr *addr =
00330                              CryptMemAlloc(sizeof(struct FuncAddr));
00331 
00332                             if (addr)
00333                             {
00334                                 addr->lib = lib;
00335                                 addr->dllList = addr->currentDll = NULL;
00336                                 *phFuncAddr = addr;
00337                                 ret = TRUE;
00338                             }
00339                             else
00340                             {
00341                                 *phFuncAddr = NULL;
00342                                 FreeLibrary(lib);
00343                             }
00344                         }
00345                         else
00346                         {
00347                             /* Unload the library, the caller doesn't want
00348                              * to unload it when the return value is NULL.
00349                              */
00350                             FreeLibrary(lib);
00351                         }
00352                     }
00353                 }
00354                 else
00355                     SetLastError(rc);
00356                 CryptMemFree(dllName);
00357             }
00358         }
00359         else
00360             SetLastError(rc);
00361         if (funcName != szFuncName)
00362             CryptMemFree((char *)funcName);
00363         RegCloseKey(key);
00364     }
00365     else
00366         SetLastError(rc);
00367     CryptMemFree(keyName);
00368     return ret;
00369 }
00370 
00371 BOOL WINAPI CryptGetOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet,
00372  DWORD dwEncodingType, LPCSTR pszOID, DWORD dwFlags, void **ppvFuncAddr,
00373  HCRYPTOIDFUNCADDR *phFuncAddr)
00374 {
00375     BOOL ret = FALSE;
00376     struct OIDFunctionSet *set = hFuncSet;
00377 
00378     TRACE("(%p, %d, %s, %08x, %p, %p)\n", hFuncSet, dwEncodingType,
00379      debugstr_a(pszOID), dwFlags, ppvFuncAddr, phFuncAddr);
00380 
00381     *ppvFuncAddr = NULL;
00382     if (!(dwFlags & CRYPT_GET_INSTALLED_OID_FUNC_FLAG))
00383     {
00384         struct OIDFunction *function;
00385 
00386         EnterCriticalSection(&set->cs);
00387         LIST_FOR_EACH_ENTRY(function, &set->functions, struct OIDFunction, next)
00388         {
00389             if (function->encoding == GET_CERT_ENCODING_TYPE(dwEncodingType))
00390             {
00391                 if (!IS_INTOID(pszOID))
00392                 {
00393                     if (!IS_INTOID(function->entry.pszOID) &&
00394                      !strcasecmp(function->entry.pszOID, pszOID))
00395                     {
00396                         *ppvFuncAddr = function->entry.pvFuncAddr;
00397                         *phFuncAddr = NULL; /* FIXME: what should it be? */
00398                         ret = TRUE;
00399                         break;
00400                     }
00401                 }
00402                 else if (function->entry.pszOID == pszOID)
00403                 {
00404                     *ppvFuncAddr = function->entry.pvFuncAddr;
00405                     *phFuncAddr = NULL; /* FIXME: what should it be? */
00406                     ret = TRUE;
00407                     break;
00408                 }
00409             }
00410         }
00411         LeaveCriticalSection(&set->cs);
00412     }
00413     if (!*ppvFuncAddr)
00414         ret = CRYPT_GetFuncFromReg(dwEncodingType, pszOID, set->name,
00415          ppvFuncAddr, phFuncAddr);
00416     TRACE("returning %d\n", ret);
00417     return ret;
00418 }
00419 
00420 BOOL WINAPI CryptFreeOIDFunctionAddress(HCRYPTOIDFUNCADDR hFuncAddr,
00421  DWORD dwFlags)
00422 {
00423     TRACE("(%p, %08x)\n", hFuncAddr, dwFlags);
00424 
00425     /* FIXME: as MSDN states, need to check for DllCanUnloadNow in the DLL,
00426      * and only unload it if it can be unloaded.  Also need to implement ref
00427      * counting on the functions.
00428      */
00429     if (hFuncAddr)
00430     {
00431         struct FuncAddr *addr = hFuncAddr;
00432 
00433         CryptMemFree(addr->dllList);
00434         FreeLibrary(addr->lib);
00435         CryptMemFree(addr);
00436     }
00437     return TRUE;
00438 }
00439 
00440 static BOOL CRYPT_GetFuncFromDll(LPCWSTR dll, LPCSTR func, HMODULE *lib,
00441  void **ppvFuncAddr)
00442 {
00443     BOOL ret = FALSE;
00444 
00445     *lib = LoadLibraryW(dll);
00446     if (*lib)
00447     {
00448         *ppvFuncAddr = GetProcAddress(*lib, func);
00449         if (*ppvFuncAddr)
00450             ret = TRUE;
00451         else
00452         {
00453             FreeLibrary(*lib);
00454             *lib = NULL;
00455         }
00456     }
00457     return ret;
00458 }
00459 
00460 BOOL WINAPI CryptGetDefaultOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet,
00461  DWORD dwEncodingType, LPCWSTR pwszDll, DWORD dwFlags, void **ppvFuncAddr,
00462  HCRYPTOIDFUNCADDR *phFuncAddr)
00463 {
00464     struct OIDFunctionSet *set = hFuncSet;
00465     BOOL ret = FALSE;
00466 
00467     TRACE("(%p, %d, %s, %08x, %p, %p)\n", hFuncSet, dwEncodingType,
00468      debugstr_w(pwszDll), dwFlags, ppvFuncAddr, phFuncAddr);
00469 
00470     if (pwszDll)
00471     {
00472         HMODULE lib;
00473 
00474         *phFuncAddr = NULL;
00475         ret = CRYPT_GetFuncFromDll(pwszDll, set->name, &lib, ppvFuncAddr);
00476         if (ret)
00477         {
00478             struct FuncAddr *addr = CryptMemAlloc(sizeof(struct FuncAddr));
00479 
00480             if (addr)
00481             {
00482                 addr->lib = lib;
00483                 addr->dllList = addr->currentDll = NULL;
00484                 *phFuncAddr = addr;
00485             }
00486             else
00487             {
00488                 FreeLibrary(lib);
00489                 *ppvFuncAddr = NULL;
00490                 SetLastError(ERROR_OUTOFMEMORY);
00491                 ret = FALSE;
00492             }
00493         }
00494         else
00495             SetLastError(ERROR_FILE_NOT_FOUND);
00496     }
00497     else
00498     {
00499         struct FuncAddr *addr = *phFuncAddr;
00500 
00501         if (!addr)
00502         {
00503             DWORD size;
00504 
00505             ret = CryptGetDefaultOIDDllList(hFuncSet, dwEncodingType, NULL,
00506              &size);
00507             if (ret)
00508             {
00509                 LPWSTR dllList = CryptMemAlloc(size * sizeof(WCHAR));
00510 
00511                 if (dllList)
00512                 {
00513                     ret = CryptGetDefaultOIDDllList(hFuncSet, dwEncodingType,
00514                      dllList, &size);
00515                     if (ret)
00516                     {
00517                         addr = CryptMemAlloc(sizeof(struct FuncAddr));
00518                         if (addr)
00519                         {
00520                             addr->dllList = dllList;
00521                             addr->currentDll = dllList;
00522                             addr->lib = NULL;
00523                             *phFuncAddr = addr;
00524                         }
00525                         else
00526                         {
00527                             CryptMemFree(dllList);
00528                             SetLastError(ERROR_OUTOFMEMORY);
00529                             ret = FALSE;
00530                         }
00531                     }
00532                 }
00533                 else
00534                 {
00535                     SetLastError(ERROR_OUTOFMEMORY);
00536                     ret = FALSE;
00537                 }
00538             }
00539         }
00540         if (addr)
00541         {
00542             if (!*addr->currentDll)
00543             {
00544                 CryptFreeOIDFunctionAddress(*phFuncAddr, 0);
00545                 SetLastError(ERROR_FILE_NOT_FOUND);
00546                 *phFuncAddr = NULL;
00547                 ret = FALSE;
00548             }
00549             else
00550             {
00551                 /* FIXME: as elsewhere, can't free until DllCanUnloadNow says
00552                  * it's possible, and should defer unloading for some time to
00553                  * avoid repeated LoadLibrary/FreeLibrary on the same dll.
00554                  */
00555                 FreeLibrary(addr->lib);
00556                 ret = CRYPT_GetFuncFromDll(addr->currentDll, set->name,
00557                  &addr->lib, ppvFuncAddr);
00558                 if (ret)
00559                 {
00560                     /* Move past the current DLL */
00561                     addr->currentDll += lstrlenW(addr->currentDll) + 1;
00562                     *phFuncAddr = addr;
00563                 }
00564                 else
00565                 {
00566                     CryptFreeOIDFunctionAddress(*phFuncAddr, 0);
00567                     SetLastError(ERROR_FILE_NOT_FOUND);
00568                     *phFuncAddr = NULL;
00569                 }
00570             }
00571         }
00572     }
00573     return ret;
00574 }
00575 
00576 /***********************************************************************
00577  *             CryptRegisterOIDFunction (CRYPT32.@)
00578  *
00579  * Register the DLL and the functions it uses to cover the combination
00580  * of encoding type, function name and OID.
00581  *
00582  * PARAMS
00583  *  dwEncodingType       [I] Encoding type to be used.
00584  *  pszFuncName          [I] Name of the function to be registered.
00585  *  pszOID               [I] OID of the function (numeric or string).
00586  *  pwszDll              [I] The DLL that is to be registered.
00587  *  pszOverrideFuncName  [I] Name of the function in the DLL.
00588  *
00589  * RETURNS
00590  *  Success: TRUE.
00591  *  Failure: FALSE. (Look at GetLastError()).
00592  *
00593  * NOTES
00594  *  Registry errors are always reported via SetLastError().
00595  */
00596 BOOL WINAPI CryptRegisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName,
00597                   LPCSTR pszOID, LPCWSTR pwszDll, LPCSTR pszOverrideFuncName)
00598 {
00599     LONG r;
00600     HKEY hKey;
00601     LPSTR szKey;
00602 
00603     TRACE("(%x, %s, %s, %s, %s)\n", dwEncodingType, debugstr_a(pszFuncName),
00604           debugstr_a(pszOID), debugstr_w(pwszDll), debugstr_a(pszOverrideFuncName));
00605 
00606     /* Native does nothing pwszDll is NULL */
00607     if (!pwszDll)
00608         return TRUE;
00609 
00610     /* I'm not matching MS bug for bug here, because I doubt any app depends on
00611      * it:  native "succeeds" if pszFuncName is NULL, but the nonsensical entry
00612      * it creates would never be used.
00613      */
00614     if (!pszFuncName || !pszOID)
00615     {
00616         SetLastError(E_INVALIDARG);
00617         return FALSE;
00618     }
00619 
00620     szKey = CRYPT_GetKeyName(dwEncodingType, pszFuncName, pszOID);
00621     TRACE("Key name is %s\n", debugstr_a(szKey));
00622 
00623     if (!szKey)
00624         return FALSE;
00625 
00626     r = RegCreateKeyA(HKEY_LOCAL_MACHINE, szKey, &hKey);
00627     CryptMemFree(szKey);
00628 
00629     if (r != ERROR_SUCCESS) goto error_close_key;
00630 
00631     /* write the values */
00632     if (pszOverrideFuncName)
00633     {
00634         r = RegSetValueExA(hKey, "FuncName", 0, REG_SZ,
00635              (const BYTE*)pszOverrideFuncName, lstrlenA(pszOverrideFuncName) + 1);
00636         if (r != ERROR_SUCCESS) goto error_close_key;
00637     }
00638     r = RegSetValueExW(hKey, DllW, 0, REG_SZ, (const BYTE*) pwszDll,
00639          (lstrlenW(pwszDll) + 1) * sizeof (WCHAR));
00640 
00641 error_close_key:
00642 
00643     RegCloseKey(hKey);
00644 
00645     if (r != ERROR_SUCCESS) 
00646     {
00647         SetLastError(r);
00648         return FALSE;
00649     }
00650 
00651     return TRUE;
00652 }
00653 
00654 /***********************************************************************
00655  *             CryptRegisterOIDInfo (CRYPT32.@)
00656  */
00657 BOOL WINAPI CryptRegisterOIDInfo(PCCRYPT_OID_INFO pInfo, DWORD dwFlags)
00658 {
00659     FIXME("(%p, %x): stub\n", pInfo, dwFlags );
00660     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00661     return FALSE;
00662 }
00663 
00664 /***********************************************************************
00665  *             CryptUnregisterOIDFunction (CRYPT32.@)
00666  */
00667 BOOL WINAPI CryptUnregisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName,
00668  LPCSTR pszOID)
00669 {
00670     LPSTR szKey;
00671     LONG rc;
00672 
00673     TRACE("%x %s %s\n", dwEncodingType, debugstr_a(pszFuncName),
00674      debugstr_a(pszOID));
00675 
00676     if (!pszFuncName || !pszOID)
00677     {
00678         SetLastError(ERROR_INVALID_PARAMETER);
00679         return FALSE;
00680     }
00681 
00682     szKey = CRYPT_GetKeyName(dwEncodingType, pszFuncName, pszOID);
00683     rc = RegDeleteKeyA(HKEY_LOCAL_MACHINE, szKey);
00684     CryptMemFree(szKey);
00685     if (rc)
00686         SetLastError(rc);
00687     return rc ? FALSE : TRUE;
00688 }
00689 
00690 BOOL WINAPI CryptGetOIDFunctionValue(DWORD dwEncodingType, LPCSTR pszFuncName,
00691  LPCSTR pszOID, LPCWSTR pwszValueName, DWORD *pdwValueType, BYTE *pbValueData,
00692  DWORD *pcbValueData)
00693 {
00694     LPSTR szKey;
00695     LONG rc;
00696     HKEY hKey;
00697 
00698     TRACE("%x %s %s %s %p %p %p\n", dwEncodingType, debugstr_a(pszFuncName),
00699      debugstr_a(pszOID), debugstr_w(pwszValueName), pdwValueType, pbValueData,
00700      pcbValueData);
00701 
00702     if (!GET_CERT_ENCODING_TYPE(dwEncodingType))
00703         return TRUE;
00704 
00705     if (!pszFuncName || !pszOID || !pwszValueName)
00706     {
00707         SetLastError(ERROR_INVALID_PARAMETER);
00708         return FALSE;
00709     }
00710 
00711     szKey = CRYPT_GetKeyName(dwEncodingType, pszFuncName, pszOID);
00712     rc = RegOpenKeyA(HKEY_LOCAL_MACHINE, szKey, &hKey);
00713     CryptMemFree(szKey);
00714     if (rc)
00715         SetLastError(rc);
00716     else
00717     {
00718         rc = RegQueryValueExW(hKey, pwszValueName, NULL, pdwValueType,
00719          pbValueData, pcbValueData);
00720         if (rc)
00721             SetLastError(rc);
00722         RegCloseKey(hKey);
00723     }
00724     return rc ? FALSE : TRUE;
00725 }
00726 
00727 BOOL WINAPI CryptSetOIDFunctionValue(DWORD dwEncodingType, LPCSTR pszFuncName,
00728  LPCSTR pszOID, LPCWSTR pwszValueName, DWORD dwValueType,
00729  const BYTE *pbValueData, DWORD cbValueData)
00730 {
00731     LPSTR szKey;
00732     LONG rc;
00733     HKEY hKey;
00734 
00735     TRACE("%x %s %s %s %d %p %d\n", dwEncodingType, debugstr_a(pszFuncName),
00736      debugstr_a(pszOID), debugstr_w(pwszValueName), dwValueType, pbValueData,
00737      cbValueData);
00738 
00739     if (!GET_CERT_ENCODING_TYPE(dwEncodingType))
00740         return TRUE;
00741 
00742     if (!pszFuncName || !pszOID || !pwszValueName)
00743     {
00744         SetLastError(ERROR_INVALID_PARAMETER);
00745         return FALSE;
00746     }
00747 
00748     szKey = CRYPT_GetKeyName(dwEncodingType, pszFuncName, pszOID);
00749     rc = RegOpenKeyA(HKEY_LOCAL_MACHINE, szKey, &hKey);
00750     CryptMemFree(szKey);
00751     if (rc)
00752         SetLastError(rc);
00753     else
00754     {
00755         rc = RegSetValueExW(hKey, pwszValueName, 0, dwValueType, pbValueData,
00756          cbValueData);
00757         if (rc)
00758             SetLastError(rc);
00759         RegCloseKey(hKey);
00760     }
00761     return rc ? FALSE : TRUE;
00762 }
00763 
00764 static LPCWSTR CRYPT_FindStringInMultiString(LPCWSTR multi, LPCWSTR toFind)
00765 {
00766     LPCWSTR ret = NULL, ptr;
00767 
00768     for (ptr = multi; ptr && *ptr && !ret; ptr += lstrlenW(ptr) + 1)
00769     {
00770         if (!lstrcmpiW(ptr, toFind))
00771             ret = ptr;
00772     }
00773     return ret;
00774 }
00775 
00776 static DWORD CRYPT_GetMultiStringCharacterLen(LPCWSTR multi)
00777 {
00778     DWORD ret;
00779 
00780     if (multi)
00781     {
00782         LPCWSTR ptr;
00783 
00784         /* Count terminating empty string */
00785         ret = 1;
00786         for (ptr = multi; *ptr; ptr += lstrlenW(ptr) + 1)
00787             ret += lstrlenW(ptr) + 1;
00788     }
00789     else
00790         ret = 0;
00791     return ret;
00792 }
00793 
00794 static LPWSTR CRYPT_AddStringToMultiString(LPWSTR multi, LPCWSTR toAdd,
00795  DWORD index)
00796 {
00797     LPWSTR ret;
00798 
00799     if (!multi)
00800     {
00801         /* FIXME: ignoring index, is that okay? */
00802         ret = CryptMemAlloc((lstrlenW(toAdd) + 2) * sizeof(WCHAR));
00803         if (ret)
00804         {
00805             /* copy string, including NULL terminator */
00806             memcpy(ret, toAdd, (lstrlenW(toAdd) + 1) * sizeof(WCHAR));
00807             /* add terminating empty string */
00808             *(ret + lstrlenW(toAdd) + 1) = 0;
00809         }
00810     }
00811     else
00812     {
00813         DWORD len = CRYPT_GetMultiStringCharacterLen(multi);
00814 
00815         ret = CryptMemRealloc(multi, (len + lstrlenW(toAdd) + 1) *
00816          sizeof(WCHAR));
00817         if (ret)
00818         {
00819             LPWSTR spotToAdd;
00820 
00821             if (index == CRYPT_REGISTER_LAST_INDEX)
00822                 spotToAdd = ret + len - 1;
00823             else
00824             {
00825                 DWORD i;
00826 
00827                 /* FIXME: if index is too large for the string, toAdd is
00828                  * added to the end.  Is that okay?
00829                  */
00830                 for (i = 0, spotToAdd = ret; i < index && *spotToAdd;
00831                  spotToAdd += lstrlenW(spotToAdd) + 1)
00832                     ;
00833             }
00834             if (spotToAdd)
00835             {
00836                 /* Copy existing string "right" */
00837                 memmove(spotToAdd + lstrlenW(toAdd) + 1, spotToAdd,
00838                  (len - (spotToAdd - ret)) * sizeof(WCHAR));
00839                 /* Copy new string */
00840                 memcpy(spotToAdd, toAdd, (lstrlenW(toAdd) + 1) * sizeof(WCHAR));
00841             }
00842             else
00843             {
00844                 CryptMemFree(ret);
00845                 ret = NULL;
00846             }
00847         }
00848     }
00849     return ret;
00850 }
00851 
00852 static BOOL CRYPT_RemoveStringFromMultiString(LPWSTR multi, LPCWSTR toRemove)
00853 {
00854     LPWSTR spotToRemove = (LPWSTR)CRYPT_FindStringInMultiString(multi,
00855      toRemove);
00856     BOOL ret;
00857 
00858     if (spotToRemove)
00859     {
00860         DWORD len = CRYPT_GetMultiStringCharacterLen(multi);
00861 
00862         if (spotToRemove + lstrlenW(toRemove) + 2 >= multi + len)
00863         {
00864             /* Removing last string in list, terminate multi string directly */
00865             *spotToRemove = 0;
00866             *(spotToRemove + 1) = 0;
00867         }
00868         else
00869         {
00870             LPCWSTR nextStr = spotToRemove + lstrlenW(toRemove) + 1;
00871 
00872             /* Copy remainder of string "left" */
00873             memmove(spotToRemove, nextStr,
00874              (len - (nextStr - multi)) * sizeof(WCHAR));
00875         }
00876         ret = TRUE;
00877     }
00878     else
00879     {
00880         SetLastError(ERROR_FILE_NOT_FOUND);
00881         ret = FALSE;
00882     }
00883     return ret;
00884 }
00885 
00886 static BOOL CRYPT_GetDefaultOIDKey(DWORD dwEncodingType, LPCSTR pszFuncName,
00887  PHKEY key)
00888 {
00889     LPSTR keyName;
00890     LONG r;
00891 
00892     keyName = CRYPT_GetKeyName(dwEncodingType, pszFuncName, "DEFAULT");
00893     TRACE("Key name is %s\n", debugstr_a(keyName));
00894 
00895     if (!keyName)
00896         return FALSE;
00897 
00898     r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, NULL, 0, KEY_ALL_ACCESS,
00899      NULL, key, NULL);
00900     CryptMemFree(keyName);
00901     if (r != ERROR_SUCCESS)
00902     {
00903         SetLastError(r);
00904         return FALSE;
00905     }
00906     return TRUE;
00907 }
00908 
00909 static LPWSTR CRYPT_GetDefaultOIDDlls(HKEY key)
00910 {
00911     LONG r;
00912     DWORD type, size;
00913     LPWSTR dlls;
00914 
00915     r = RegQueryValueExW(key, DllW, NULL, &type, NULL, &size);
00916     if (r == ERROR_SUCCESS && type == REG_MULTI_SZ)
00917     {
00918         dlls = CryptMemAlloc(size);
00919         r = RegQueryValueExW(key, DllW, NULL, &type, (LPBYTE)dlls, &size);
00920         if (r != ERROR_SUCCESS)
00921         {
00922             CryptMemFree(dlls);
00923             dlls = NULL;
00924         }
00925     }
00926     else
00927         dlls = NULL;
00928     return dlls;
00929 }
00930 
00931 static inline BOOL CRYPT_SetDefaultOIDDlls(HKEY key, LPCWSTR dlls)
00932 {
00933     DWORD len = CRYPT_GetMultiStringCharacterLen(dlls);
00934     LONG r;
00935 
00936     if ((r = RegSetValueExW(key, DllW, 0, REG_MULTI_SZ, (const BYTE *)dlls,
00937      len * sizeof (WCHAR))))
00938         SetLastError(r);
00939     return r == ERROR_SUCCESS;
00940 }
00941 
00942 /***********************************************************************
00943  *             CryptRegisterDefaultOIDFunction (CRYPT32.@)
00944  */
00945 BOOL WINAPI CryptRegisterDefaultOIDFunction(DWORD dwEncodingType,
00946  LPCSTR pszFuncName, DWORD dwIndex, LPCWSTR pwszDll)
00947 {
00948     HKEY key;
00949     LPWSTR dlls;
00950     BOOL ret = FALSE;
00951 
00952     TRACE("(%x, %s, %d, %s)\n", dwEncodingType, debugstr_a(pszFuncName),
00953      dwIndex, debugstr_w(pwszDll));
00954 
00955     if (!pwszDll)
00956     {
00957         SetLastError(E_INVALIDARG);
00958         return FALSE;
00959     }
00960 
00961     if (!CRYPT_GetDefaultOIDKey(dwEncodingType, pszFuncName, &key))
00962         return FALSE;
00963 
00964     dlls = CRYPT_GetDefaultOIDDlls(key);
00965     if (CRYPT_FindStringInMultiString(dlls, pwszDll))
00966         SetLastError(ERROR_FILE_EXISTS);
00967     else
00968     {
00969         dlls = CRYPT_AddStringToMultiString(dlls, pwszDll, dwIndex);
00970         if (dlls)
00971             ret = CRYPT_SetDefaultOIDDlls(key, dlls);
00972     }
00973     CryptMemFree(dlls);
00974     RegCloseKey(key);
00975     return ret;
00976 }
00977 
00978 BOOL WINAPI CryptUnregisterDefaultOIDFunction(DWORD dwEncodingType,
00979  LPCSTR pszFuncName, LPCWSTR pwszDll)
00980 {
00981     HKEY key;
00982     LPWSTR dlls;
00983     BOOL ret;
00984 
00985     TRACE("(%x, %s, %s)\n", dwEncodingType, debugstr_a(pszFuncName),
00986      debugstr_w(pwszDll));
00987 
00988     if (!pwszDll)
00989     {
00990         SetLastError(E_INVALIDARG);
00991         return FALSE;
00992     }
00993 
00994     if (!CRYPT_GetDefaultOIDKey(dwEncodingType, pszFuncName, &key))
00995         return FALSE;
00996 
00997     dlls = CRYPT_GetDefaultOIDDlls(key);
00998     if ((ret = CRYPT_RemoveStringFromMultiString(dlls, pwszDll)))
00999         ret = CRYPT_SetDefaultOIDDlls(key, dlls);
01000     CryptMemFree(dlls);
01001     RegCloseKey(key);
01002     return ret;
01003 }
01004 
01005 static void oid_init_localizednames(void)
01006 {
01007     unsigned int i;
01008 
01009     for(i = 0; i < sizeof(LocalizedKeys)/sizeof(LPCWSTR); i++)
01010     {
01011         LoadStringW(hInstance, IDS_LOCALIZEDNAME_ROOT+i, LocalizedNames[i], 256);
01012     }
01013 }
01014 
01015 /********************************************************************
01016  *              CryptFindLocalizedName (CRYPT32.@)
01017  */
01018 LPCWSTR WINAPI CryptFindLocalizedName(LPCWSTR pwszCryptName)
01019 {
01020     unsigned int i;
01021 
01022     for(i = 0; i < sizeof(LocalizedKeys)/sizeof(LPCWSTR); i++)
01023     {
01024         if(!lstrcmpiW(LocalizedKeys[i], pwszCryptName))
01025         {
01026             return LocalizedNames[i];
01027         }
01028     }
01029 
01030     FIXME("No name for: %s - stub\n",debugstr_w(pwszCryptName));
01031     return NULL;
01032 }
01033 
01034 static CRITICAL_SECTION oidInfoCS;
01035 static CRITICAL_SECTION_DEBUG oidInfoCSDebug =
01036 {
01037     0, 0, &oidInfoCS,
01038     { &oidInfoCSDebug.ProcessLocksList, &oidInfoCSDebug.ProcessLocksList },
01039     0, 0, { (DWORD_PTR)(__FILE__ ": oidInfoCS") }
01040 };
01041 static CRITICAL_SECTION oidInfoCS = { &oidInfoCSDebug, -1, 0, 0, 0, 0 };
01042 static struct list oidInfo = { &oidInfo, &oidInfo };
01043 
01044 static const WCHAR tripledes[] = { '3','d','e','s',0 };
01045 static const WCHAR cms3deswrap[] = { 'C','M','S','3','D','E','S','w','r','a',
01046  'p',0 };
01047 static const WCHAR cmsrc2wrap[] = { 'C','M','S','R','C','2','w','r','a','p',0 };
01048 static const WCHAR des[] = { 'd','e','s',0 };
01049 static const WCHAR md2[] = { 'm','d','2',0 };
01050 static const WCHAR md4[] = { 'm','d','4',0 };
01051 static const WCHAR md5[] = { 'm','d','5',0 };
01052 static const WCHAR rc2[] = { 'r','c','2',0 };
01053 static const WCHAR rc4[] = { 'r','c','4',0 };
01054 static const WCHAR sha[] = { 's','h','a',0 };
01055 static const WCHAR sha1[] = { 's','h','a','1',0 };
01056 static const WCHAR sha256[] = { 's','h','a','2','5','6',0 };
01057 static const WCHAR sha384[] = { 's','h','a','3','8','4',0 };
01058 static const WCHAR sha512[] = { 's','h','a','5','1','2',0 };
01059 static const WCHAR RSA[] = { 'R','S','A',0 };
01060 static const WCHAR RSA_KEYX[] = { 'R','S','A','_','K','E','Y','X',0 };
01061 static const WCHAR RSA_SIGN[] = { 'R','S','A','_','S','I','G','N',0 };
01062 static const WCHAR DSA[] = { 'D','S','A',0 };
01063 static const WCHAR DSA_SIGN[] = { 'D','S','A','_','S','I','G','N',0 };
01064 static const WCHAR DH[] = { 'D','H',0 };
01065 static const WCHAR DSS[] = { 'D','S','S',0 };
01066 static const WCHAR mosaicKMandUpdSig[] =
01067  { 'm','o','s','a','i','c','K','M','a','n','d','U','p','d','S','i','g',0 };
01068 static const WCHAR ESDH[] = { 'E','S','D','H',0 };
01069 static const WCHAR NO_SIGN[] = { 'N','O','S','I','G','N',0 };
01070 static const WCHAR dsaSHA1[] = { 'd','s','a','S','H','A','1',0 };
01071 static const WCHAR md2RSA[] = { 'm','d','2','R','S','A',0 };
01072 static const WCHAR md4RSA[] = { 'm','d','4','R','S','A',0 };
01073 static const WCHAR md5RSA[] = { 'm','d','5','R','S','A',0 };
01074 static const WCHAR shaDSA[] = { 's','h','a','D','S','A',0 };
01075 static const WCHAR sha1DSA[] = { 's','h','a','1','D','S','A',0 };
01076 static const WCHAR shaRSA[] = { 's','h','a','R','S','A',0 };
01077 static const WCHAR sha1RSA[] = { 's','h','a','1','R','S','A',0 };
01078 static const WCHAR sha256RSA[] = { 's','h','a','2','5','6','R','S','A',0 };
01079 static const WCHAR sha384RSA[] = { 's','h','a','3','8','4','R','S','A',0 };
01080 static const WCHAR sha512RSA[] = { 's','h','a','5','1','2','R','S','A',0 };
01081 static const WCHAR mosaicUpdatedSig[] =
01082  { 'm','o','s','a','i','c','U','p','d','a','t','e','d','S','i','g',0 };
01083 static const WCHAR CN[] = { 'C','N',0 };
01084 static const WCHAR L[] = { 'L',0 };
01085 static const WCHAR O[] = { 'O',0 };
01086 static const WCHAR OU[] = { 'O','U',0 };
01087 static const WCHAR E[] = { 'E',0 };
01088 static const WCHAR C[] = { 'C',0 };
01089 static const WCHAR S[] = { 'S',0 };
01090 static const WCHAR ST[] = { 'S','T',0 };
01091 static const WCHAR STREET[] = { 'S','T','R','E','E','T',0 };
01092 static const WCHAR T[] = { 'T',0 };
01093 static const WCHAR Title[] = { 'T','i','t','l','e',0 };
01094 static const WCHAR G[] = { 'G',0 };
01095 static const WCHAR GivenName[] = { 'G','i','v','e','n','N','a','m','e',0 };
01096 static const WCHAR I[] = { 'I',0 };
01097 static const WCHAR Initials[] = { 'I','n','i','t','i','a','l','s',0 };
01098 static const WCHAR SN[] = { 'S','N',0 };
01099 static const WCHAR DC[] = { 'D','C',0 };
01100 static const WCHAR Description[] =
01101  { 'D','e','s','c','r','i','p','t','i','o','n',0 };
01102 static const WCHAR PostalCode[] = { 'P','o','s','t','a','l','C','o','d','e',0 };
01103 static const WCHAR POBox[] = { 'P','O','B','o','x',0 };
01104 static const WCHAR Phone[] = { 'P','h','o','n','e',0 };
01105 static const WCHAR X21Address[] = { 'X','2','1','A','d','d','r','e','s','s',0 };
01106 static const WCHAR dnQualifier[] =
01107  { 'd','n','Q','u','a','l','i','f','i','e','r',0 };
01108 static const WCHAR Email[] = { 'E','m','a','i','l',0 };
01109 static const WCHAR GN[] = { 'G','N',0 };
01110 
01111 static const DWORD noNullFlag = CRYPT_OID_NO_NULL_ALGORITHM_PARA_FLAG;
01112 static const DWORD mosaicFlags = CRYPT_OID_INHIBIT_SIGNATURE_FORMAT_FLAG |
01113  CRYPT_OID_NO_NULL_ALGORITHM_PARA_FLAG;
01114 static const CRYPT_DATA_BLOB noNullBlob = { sizeof(noNullFlag),
01115  (LPBYTE)&noNullFlag };
01116 static const CRYPT_DATA_BLOB mosaicFlagsBlob = { sizeof(mosaicFlags),
01117  (LPBYTE)&mosaicFlags };
01118 
01119 static const DWORD rsaSign = CALG_RSA_SIGN;
01120 static const DWORD dssSign[2] = { CALG_DSS_SIGN,
01121  CRYPT_OID_NO_NULL_ALGORITHM_PARA_FLAG };
01122 static const DWORD mosaicSign[2] = { CALG_DSS_SIGN,
01123  CRYPT_OID_INHIBIT_SIGNATURE_FORMAT_FLAG |
01124  CRYPT_OID_NO_NULL_ALGORITHM_PARA_FLAG };
01125 static const CRYPT_DATA_BLOB rsaSignBlob = { sizeof(rsaSign),
01126  (LPBYTE)&rsaSign };
01127 static const CRYPT_DATA_BLOB dssSignBlob = { sizeof(dssSign),
01128  (LPBYTE)dssSign };
01129 static const CRYPT_DATA_BLOB mosaicSignBlob = { sizeof(mosaicSign),
01130  (LPBYTE)mosaicSign };
01131 
01132 static const DWORD ia5String[] = { CERT_RDN_IA5_STRING, 0 };
01133 static const DWORD numericString[] = { CERT_RDN_NUMERIC_STRING, 0 };
01134 static const DWORD printableString[] = { CERT_RDN_PRINTABLE_STRING, 0 };
01135 static const DWORD domainCompTypes[] = { CERT_RDN_IA5_STRING,
01136  CERT_RDN_UTF8_STRING, 0 };
01137 static const CRYPT_DATA_BLOB ia5StringBlob = { sizeof(ia5String),
01138  (LPBYTE)ia5String };
01139 static const CRYPT_DATA_BLOB numericStringBlob = { sizeof(numericString),
01140  (LPBYTE)numericString };
01141 static const CRYPT_DATA_BLOB printableStringBlob = { sizeof(printableString),
01142  (LPBYTE)printableString };
01143 static const CRYPT_DATA_BLOB domainCompTypesBlob = { sizeof(domainCompTypes),
01144  (LPBYTE)domainCompTypes };
01145 
01146 static const struct OIDInfoConstructor {
01147     DWORD   dwGroupId;
01148     LPCSTR  pszOID;
01149     UINT    Algid;
01150     LPCWSTR pwszName;
01151     const CRYPT_DATA_BLOB *blob;
01152 } oidInfoConstructors[] = {
01153  { 1, szOID_OIWSEC_sha1,               CALG_SHA1,     sha1, NULL },
01154  { 1, szOID_OIWSEC_sha1,               CALG_SHA1,     sha, NULL },
01155  { 1, szOID_OIWSEC_sha,                CALG_SHA,      sha, NULL },
01156  { 1, szOID_RSA_MD5,                   CALG_MD5,      md5, NULL },
01157  { 1, szOID_RSA_MD4,                   CALG_MD4,      md4, NULL },
01158  { 1, szOID_RSA_MD2,                   CALG_MD2,      md2, NULL },
01159 
01160  { 2, szOID_OIWSEC_desCBC,             CALG_DES,      des, NULL },
01161  { 2, szOID_RSA_DES_EDE3_CBC,          CALG_3DES,     tripledes, NULL },
01162  { 2, szOID_RSA_RC2CBC,                CALG_RC2,      rc2, NULL },
01163  { 2, szOID_RSA_RC4,                   CALG_RC4,      rc4, NULL },
01164  { 2, szOID_RSA_SMIMEalgCMS3DESwrap,   CALG_3DES,     cms3deswrap, NULL },
01165  { 2, szOID_RSA_SMIMEalgCMSRC2wrap,    CALG_RC2,      cmsrc2wrap, NULL },
01166 
01167  { 3, szOID_RSA_RSA,                   CALG_RSA_KEYX, RSA, NULL },
01168  { 3, szOID_X957_DSA,                  CALG_DSS_SIGN, DSA, &noNullBlob },
01169  { 3, szOID_ANSI_X942_DH,              CALG_DH_SF,    DH, &noNullBlob },
01170  { 3, szOID_RSA_RSA,                   CALG_RSA_KEYX, RSA_KEYX, NULL },
01171  { 3, szOID_RSA_RSA,                   CALG_RSA_SIGN, RSA, NULL },
01172  { 3, szOID_RSA_RSA,                   CALG_RSA_SIGN, RSA_SIGN, NULL },
01173  { 3, szOID_OIWSEC_dsa,                CALG_DSS_SIGN, DSA, &noNullBlob },
01174  { 3, szOID_OIWSEC_dsa,                CALG_DSS_SIGN, DSS, &noNullBlob },
01175  { 3, szOID_OIWSEC_dsa,                CALG_DSS_SIGN, DSA_SIGN, &noNullBlob },
01176  { 3, szOID_RSA_DH,                    CALG_DH_SF,    DH, &noNullBlob },
01177  { 3, szOID_OIWSEC_rsaXchg,            CALG_RSA_KEYX, RSA_KEYX, NULL },
01178  { 3, szOID_INFOSEC_mosaicKMandUpdSig, CALG_DSS_SIGN, mosaicKMandUpdSig,
01179    &mosaicFlagsBlob },
01180  { 3, szOID_RSA_SMIMEalgESDH,          CALG_DH_EPHEM, ESDH, &noNullBlob },
01181  { 3, szOID_PKIX_NO_SIGNATURE,         CALG_NO_SIGN,  NO_SIGN, NULL },
01182 
01183  { 4, szOID_RSA_SHA1RSA,               CALG_SHA1,     sha1RSA, &rsaSignBlob },
01184  { 4, szOID_RSA_SHA256RSA,             CALG_SHA_256,  sha256RSA, &rsaSignBlob },
01185  { 4, szOID_RSA_SHA384RSA,             CALG_SHA_384,  sha384RSA, &rsaSignBlob },
01186  { 4, szOID_RSA_SHA512RSA,             CALG_SHA_512,  sha512RSA, &rsaSignBlob },
01187  { 4, szOID_RSA_MD5RSA,                CALG_MD5,      md5RSA, &rsaSignBlob },
01188  { 4, szOID_X957_SHA1DSA,              CALG_SHA1,     sha1DSA, &dssSignBlob },
01189  { 4, szOID_OIWSEC_sha1RSASign,        CALG_SHA1,     sha1RSA, &rsaSignBlob },
01190  { 4, szOID_OIWSEC_sha1RSASign,        CALG_SHA1,     shaRSA, &rsaSignBlob },
01191  { 4, szOID_OIWSEC_shaRSA,             CALG_SHA1,     shaRSA, &rsaSignBlob },
01192  { 4, szOID_OIWSEC_md5RSA,             CALG_MD5,      md5RSA, &rsaSignBlob },
01193  { 4, szOID_RSA_MD2RSA,                CALG_MD2,      md2RSA, &rsaSignBlob },
01194  { 4, szOID_RSA_MD4RSA,                CALG_MD4,      md4RSA, &rsaSignBlob },
01195  { 4, szOID_OIWSEC_md4RSA,             CALG_MD4,      md4RSA, &rsaSignBlob },
01196  { 4, szOID_OIWSEC_md4RSA2,            CALG_MD4,      md4RSA, &rsaSignBlob },
01197  { 4, szOID_OIWDIR_md2RSA,             CALG_MD2,      md2RSA, &rsaSignBlob },
01198  { 4, szOID_OIWSEC_shaDSA,             CALG_SHA1,     sha1DSA, &dssSignBlob },
01199  { 4, szOID_OIWSEC_shaDSA,             CALG_SHA1,     shaDSA, &dssSignBlob },
01200  { 4, szOID_OIWSEC_dsaSHA1,            CALG_SHA1,     dsaSHA1, &dssSignBlob },
01201  { 4, szOID_INFOSEC_mosaicUpdatedSig,  CALG_SHA1,     mosaicUpdatedSig,
01202    &mosaicSignBlob },
01203 
01204  { 5, szOID_COMMON_NAME,              0, CN, NULL },
01205  { 5, szOID_LOCALITY_NAME,            0, L, NULL },
01206  { 5, szOID_ORGANIZATION_NAME,        0, O, NULL },
01207  { 5, szOID_ORGANIZATIONAL_UNIT_NAME, 0, OU, NULL },
01208  { 5, szOID_RSA_emailAddr,            0, E, &ia5StringBlob },
01209  { 5, szOID_RSA_emailAddr,            0, Email, &ia5StringBlob },
01210  { 5, szOID_COUNTRY_NAME,             0, C, &printableStringBlob },
01211  { 5, szOID_STATE_OR_PROVINCE_NAME,   0, S, NULL },
01212  { 5, szOID_STATE_OR_PROVINCE_NAME,   0, ST, NULL },
01213  { 5, szOID_STREET_ADDRESS,           0, STREET, NULL },
01214  { 5, szOID_TITLE,                    0, T, NULL },
01215  { 5, szOID_TITLE,                    0, Title, NULL },
01216  { 5, szOID_GIVEN_NAME,               0, G, NULL },
01217  { 5, szOID_GIVEN_NAME,               0, GN, NULL },
01218  { 5, szOID_GIVEN_NAME,               0, GivenName, NULL },
01219  { 5, szOID_INITIALS,                 0, I, NULL },
01220  { 5, szOID_INITIALS,                 0, Initials, NULL },
01221  { 5, szOID_SUR_NAME,                 0, SN, NULL },
01222  { 5, szOID_DOMAIN_COMPONENT,         0, DC, &domainCompTypesBlob },
01223  { 5, szOID_DESCRIPTION,              0, Description, NULL },
01224  { 5, szOID_POSTAL_CODE,              0, PostalCode, NULL },
01225  { 5, szOID_POST_OFFICE_BOX,          0, POBox, NULL },
01226  { 5, szOID_TELEPHONE_NUMBER,         0, Phone, &printableStringBlob },
01227  { 5, szOID_X21_ADDRESS,              0, X21Address, &numericStringBlob },
01228  { 5, szOID_DN_QUALIFIER,             0, dnQualifier, NULL },
01229 
01230  { 6, szOID_AUTHORITY_KEY_IDENTIFIER2, 0, (LPCWSTR)IDS_AUTHORITY_KEY_ID, NULL },
01231  { 6, szOID_AUTHORITY_KEY_IDENTIFIER, 0, (LPCWSTR)IDS_AUTHORITY_KEY_ID, NULL },
01232  { 6, szOID_KEY_ATTRIBUTES, 0, (LPCWSTR)IDS_KEY_ATTRIBUTES, NULL },
01233  { 6, szOID_KEY_USAGE_RESTRICTION, 0, (LPCWSTR)IDS_KEY_USAGE_RESTRICTION, NULL },
01234  { 6, szOID_SUBJECT_ALT_NAME2, 0, (LPCWSTR)IDS_SUBJECT_ALT_NAME, NULL },
01235  { 6, szOID_SUBJECT_ALT_NAME, 0, (LPCWSTR)IDS_SUBJECT_ALT_NAME, NULL },
01236  { 6, szOID_ISSUER_ALT_NAME2, 0, (LPCWSTR)IDS_ISSUER_ALT_NAME, NULL },
01237  { 6, szOID_ISSUER_ALT_NAME2, 0, (LPCWSTR)IDS_ISSUER_ALT_NAME, NULL },
01238  { 6, szOID_BASIC_CONSTRAINTS2, 0, (LPCWSTR)IDS_BASIC_CONSTRAINTS, NULL },
01239  { 6, szOID_BASIC_CONSTRAINTS, 0, (LPCWSTR)IDS_BASIC_CONSTRAINTS, NULL },
01240  { 6, szOID_KEY_USAGE, 0, (LPCWSTR)IDS_KEY_USAGE, NULL },
01241  { 6, szOID_CERT_POLICIES, 0, (LPCWSTR)IDS_CERT_POLICIES, NULL },
01242  { 6, szOID_SUBJECT_KEY_IDENTIFIER, 0, (LPCWSTR)IDS_SUBJECT_KEY_IDENTIFIER, NULL },
01243  { 6, szOID_CRL_REASON_CODE, 0, (LPCWSTR)IDS_CRL_REASON_CODE, NULL },
01244  { 6, szOID_CRL_DIST_POINTS, 0, (LPCWSTR)IDS_CRL_DIST_POINTS, NULL },
01245  { 6, szOID_ENHANCED_KEY_USAGE, 0, (LPCWSTR)IDS_ENHANCED_KEY_USAGE, NULL },
01246  { 6, szOID_AUTHORITY_INFO_ACCESS, 0, (LPCWSTR)IDS_AUTHORITY_INFO_ACCESS, NULL },
01247  { 6, szOID_CERT_EXTENSIONS, 0, (LPCWSTR)IDS_CERT_EXTENSIONS, NULL },
01248  { 6, szOID_RSA_certExtensions, 0, (LPCWSTR)IDS_CERT_EXTENSIONS, NULL },
01249  { 6, szOID_NEXT_UPDATE_LOCATION, 0, (LPCWSTR)IDS_NEXT_UPDATE_LOCATION, NULL },
01250  { 6, szOID_YESNO_TRUST_ATTR, 0, (LPCWSTR)IDS_YES_OR_NO_TRUST, NULL },
01251  { 6, szOID_RSA_emailAddr, 0, (LPCWSTR)IDS_EMAIL_ADDRESS, NULL },
01252  { 6, szOID_RSA_unstructName, 0, (LPCWSTR)IDS_UNSTRUCTURED_NAME, NULL },
01253  { 6, szOID_RSA_contentType, 0, (LPCWSTR)IDS_CONTENT_TYPE, NULL },
01254  { 6, szOID_RSA_messageDigest, 0, (LPCWSTR)IDS_MESSAGE_DIGEST, NULL },
01255  { 6, szOID_RSA_signingTime, 0, (LPCWSTR)IDS_SIGNING_TIME, NULL },
01256  { 6, szOID_RSA_counterSign, 0, (LPCWSTR)IDS_COUNTER_SIGN, NULL },
01257  { 6, szOID_RSA_challengePwd, 0, (LPCWSTR)IDS_CHALLENGE_PASSWORD, NULL },
01258  { 6, szOID_RSA_unstructAddr, 0, (LPCWSTR)IDS_UNSTRUCTURED_ADDRESS, NULL },
01259  { 6, szOID_RSA_SMIMECapabilities, 0, (LPCWSTR)IDS_SMIME_CAPABILITIES, NULL },
01260  { 6, szOID_RSA_preferSignedData, 0, (LPCWSTR)IDS_PREFER_SIGNED_DATA, NULL },
01261  { 6, szOID_PKIX_POLICY_QUALIFIER_CPS, 0, (LPCWSTR)IDS_CPS, NULL },
01262  { 6, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE, 0, (LPCWSTR)IDS_USER_NOTICE, NULL },
01263  { 6, szOID_PKIX_OCSP, 0, (LPCWSTR)IDS_OCSP, NULL },
01264  { 6, szOID_PKIX_CA_ISSUERS, 0, (LPCWSTR)IDS_CA_ISSUER, NULL },
01265  { 6, szOID_ENROLL_CERTTYPE_EXTENSION, 0, (LPCWSTR)IDS_CERT_TEMPLATE_NAME, NULL },
01266  { 6, szOID_ENROLL_CERTTYPE_EXTENSION, 0, (LPCWSTR)IDS_CERT_TYPE, NULL },
01267  { 6, szOID_CERT_MANIFOLD, 0, (LPCWSTR)IDS_CERT_MANIFOLD, NULL },
01268  { 6, szOID_NETSCAPE_CERT_TYPE, 0, (LPCWSTR)IDS_NETSCAPE_CERT_TYPE, NULL },
01269  { 6, szOID_NETSCAPE_BASE_URL, 0, (LPCWSTR)IDS_NETSCAPE_BASE_URL, NULL },
01270  { 6, szOID_NETSCAPE_REVOCATION_URL, 0, (LPCWSTR)IDS_NETSCAPE_REVOCATION_URL, NULL },
01271  { 6, szOID_NETSCAPE_CA_REVOCATION_URL, 0, (LPCWSTR)IDS_NETSCAPE_CA_REVOCATION_URL, NULL },
01272  { 6, szOID_NETSCAPE_CERT_RENEWAL_URL, 0, (LPCWSTR)IDS_NETSCAPE_CERT_RENEWAL_URL, NULL },
01273  { 6, szOID_NETSCAPE_CA_POLICY_URL, 0, (LPCWSTR)IDS_NETSCAPE_CA_POLICY_URL, NULL },
01274  { 6, szOID_NETSCAPE_SSL_SERVER_NAME, 0, (LPCWSTR)IDS_NETSCAPE_SSL_SERVER_NAME, NULL },
01275  { 6, szOID_NETSCAPE_COMMENT, 0, (LPCWSTR)IDS_NETSCAPE_COMMENT, NULL },
01276  { 6, "1.3.6.1.4.1.311.2.1.10", 0, (LPCWSTR)IDS_SPC_SP_AGENCY_INFO, NULL },
01277  { 6, "1.3.6.1.4.1.311.2.1.27", 0, (LPCWSTR)IDS_SPC_FINANCIAL_CRITERIA, NULL },
01278  { 6, "1.3.6.1.4.1.311.2.1.26", 0, (LPCWSTR)IDS_SPC_MINIMAL_CRITERIA, NULL },
01279  { 6, szOID_COUNTRY_NAME, 0, (LPCWSTR)IDS_COUNTRY, NULL },
01280  { 6, szOID_ORGANIZATION_NAME, 0, (LPCWSTR)IDS_ORGANIZATION, NULL },
01281  { 6, szOID_ORGANIZATIONAL_UNIT_NAME, 0, (LPCWSTR)IDS_ORGANIZATIONAL_UNIT, NULL },
01282  { 6, szOID_COMMON_NAME, 0, (LPCWSTR)IDS_COMMON_NAME, NULL },
01283  { 6, szOID_LOCALITY_NAME, 0, (LPCWSTR)IDS_LOCALITY, NULL },
01284  { 6, szOID_STATE_OR_PROVINCE_NAME, 0, (LPCWSTR)IDS_STATE_OR_PROVINCE, NULL },
01285  { 6, szOID_TITLE, 0, (LPCWSTR)IDS_TITLE, NULL },
01286  { 6, szOID_GIVEN_NAME, 0, (LPCWSTR)IDS_GIVEN_NAME, NULL },
01287  { 6, szOID_INITIALS, 0, (LPCWSTR)IDS_INITIALS, NULL },
01288  { 6, szOID_SUR_NAME, 0, (LPCWSTR)IDS_SUR_NAME, NULL },
01289  { 6, szOID_DOMAIN_COMPONENT, 0, (LPCWSTR)IDS_DOMAIN_COMPONENT, NULL },
01290  { 6, szOID_STREET_ADDRESS, 0, (LPCWSTR)IDS_STREET_ADDRESS, NULL },
01291  { 6, szOID_DEVICE_SERIAL_NUMBER, 0, (LPCWSTR)IDS_SERIAL_NUMBER, NULL },
01292  { 6, szOID_CERTSRV_CA_VERSION, 0, (LPCWSTR)IDS_CA_VERSION, NULL },
01293  { 6, szOID_CERTSRV_CROSSCA_VERSION, 0, (LPCWSTR)IDS_CROSS_CA_VERSION, NULL },
01294  { 6, szOID_SERIALIZED, 0, (LPCWSTR)IDS_SERIALIZED_SIG_SERIAL_NUMBER, NULL },
01295  { 6, szOID_NT_PRINCIPAL_NAME, 0, (LPCWSTR)IDS_PRINCIPAL_NAME, NULL },
01296  { 6, szOID_PRODUCT_UPDATE, 0, (LPCWSTR)IDS_WINDOWS_PRODUCT_UPDATE, NULL },
01297  { 6, szOID_ENROLLMENT_NAME_VALUE_PAIR, 0, (LPCWSTR)IDS_ENROLLMENT_NAME_VALUE_PAIR, NULL },
01298  { 6, szOID_OS_VERSION, 0, (LPCWSTR)IDS_OS_VERSION, NULL },
01299  { 6, szOID_ENROLLMENT_CSP_PROVIDER, 0, (LPCWSTR)IDS_ENROLLMENT_CSP, NULL },
01300  { 6, szOID_CRL_NUMBER, 0, (LPCWSTR)IDS_CRL_NUMBER, NULL },
01301  { 6, szOID_DELTA_CRL_INDICATOR, 0, (LPCWSTR)IDS_DELTA_CRL_INDICATOR, NULL },
01302  { 6, szOID_ISSUING_DIST_POINT, 0, (LPCWSTR)IDS_ISSUING_DIST_POINT, NULL },
01303  { 6, szOID_FRESHEST_CRL, 0, (LPCWSTR)IDS_FRESHEST_CRL, NULL },
01304  { 6, szOID_NAME_CONSTRAINTS, 0, (LPCWSTR)IDS_NAME_CONSTRAINTS, NULL },
01305  { 6, szOID_POLICY_MAPPINGS, 0, (LPCWSTR)IDS_POLICY_MAPPINGS, NULL },
01306  { 6, szOID_LEGACY_POLICY_MAPPINGS, 0, (LPCWSTR)IDS_POLICY_MAPPINGS, NULL },
01307  { 6, szOID_POLICY_CONSTRAINTS, 0, (LPCWSTR)IDS_POLICY_CONSTRAINTS, NULL },
01308  { 6, szOID_CROSS_CERT_DIST_POINTS, 0, (LPCWSTR)IDS_CROSS_CERT_DIST_POINTS, NULL },
01309  { 6, szOID_APPLICATION_CERT_POLICIES, 0, (LPCWSTR)IDS_APPLICATION_POLICIES, NULL },
01310  { 6, szOID_APPLICATION_POLICY_MAPPINGS, 0, (LPCWSTR)IDS_APPLICATION_POLICY_MAPPINGS, NULL },
01311  { 6, szOID_APPLICATION_POLICY_CONSTRAINTS, 0, (LPCWSTR)IDS_APPLICATION_POLICY_CONSTRAINTS, NULL },
01312  { 6, szOID_CT_PKI_DATA, 0, (LPCWSTR)IDS_CMC_DATA, NULL },
01313  { 6, szOID_CT_PKI_RESPONSE, 0, (LPCWSTR)IDS_CMC_RESPONSE, NULL },
01314  { 6, szOID_CMC, 0, (LPCWSTR)IDS_UNSIGNED_CMC_REQUEST, NULL },
01315  { 6, szOID_CMC_STATUS_INFO, 0, (LPCWSTR)IDS_CMC_STATUS_INFO, NULL },
01316  { 6, szOID_CMC_ADD_EXTENSIONS, 0, (LPCWSTR)IDS_CMC_EXTENSIONS, NULL },
01317  { 6, szOID_CTL, 0, (LPCWSTR)IDS_CMC_ATTRIBUTES, NULL },
01318  { 6, szOID_RSA_data, 0, (LPCWSTR)IDS_PKCS_7_DATA, NULL },
01319  { 6, szOID_RSA_signedData, 0, (LPCWSTR)IDS_PKCS_7_SIGNED, NULL },
01320  { 6, szOID_RSA_envelopedData, 0, (LPCWSTR)IDS_PKCS_7_ENVELOPED, NULL },
01321  { 6, szOID_RSA_signEnvData, 0, (LPCWSTR)IDS_PKCS_7_SIGNED_ENVELOPED, NULL },
01322  { 6, szOID_RSA_digestedData, 0, (LPCWSTR)IDS_PKCS_7_DIGESTED, NULL },
01323  { 6, szOID_RSA_encryptedData, 0, (LPCWSTR)IDS_PKCS_7_ENCRYPTED, NULL },
01324  { 6, szOID_CERTSRV_PREVIOUS_CERT_HASH, 0, (LPCWSTR)IDS_PREVIOUS_CA_CERT_HASH, NULL },
01325  { 6, szOID_CRL_VIRTUAL_BASE, 0, (LPCWSTR)IDS_CRL_VIRTUAL_BASE, NULL },
01326  { 6, szOID_CRL_NEXT_PUBLISH, 0, (LPCWSTR)IDS_CRL_NEXT_PUBLISH, NULL },
01327  { 6, szOID_KP_CA_EXCHANGE, 0, (LPCWSTR)IDS_CA_EXCHANGE, NULL },
01328  { 6, szOID_KP_KEY_RECOVERY_AGENT, 0, (LPCWSTR)IDS_KEY_RECOVERY_AGENT, NULL },
01329  { 6, szOID_CERTIFICATE_TEMPLATE, 0, (LPCWSTR)IDS_CERTIFICATE_TEMPLATE, NULL },
01330  { 6, szOID_ENTERPRISE_OID_ROOT, 0, (LPCWSTR)IDS_ENTERPRISE_ROOT_OID, NULL },
01331  { 6, szOID_RDN_DUMMY_SIGNER, 0, (LPCWSTR)IDS_RDN_DUMMY_SIGNER, NULL },
01332  { 6, szOID_ARCHIVED_KEY_ATTR, 0, (LPCWSTR)IDS_ARCHIVED_KEY_ATTR, NULL },
01333  { 6, szOID_CRL_SELF_CDP, 0, (LPCWSTR)IDS_CRL_SELF_CDP, NULL },
01334  { 6, szOID_REQUIRE_CERT_CHAIN_POLICY, 0, (LPCWSTR)IDS_REQUIRE_CERT_CHAIN_POLICY, NULL },
01335  { 6, szOID_CMC_TRANSACTION_ID, 0, (LPCWSTR)IDS_TRANSACTION_ID, NULL },
01336  { 6, szOID_CMC_SENDER_NONCE, 0, (LPCWSTR)IDS_SENDER_NONCE, NULL },
01337  { 6, szOID_CMC_RECIPIENT_NONCE, 0, (LPCWSTR)IDS_RECIPIENT_NONCE, NULL },
01338  { 6, szOID_CMC_REG_INFO, 0, (LPCWSTR)IDS_REG_INFO, NULL },
01339  { 6, szOID_CMC_GET_CERT, 0, (LPCWSTR)IDS_GET_CERTIFICATE, NULL },
01340  { 6, szOID_CMC_GET_CRL, 0, (LPCWSTR)IDS_GET_CRL, NULL },
01341  { 6, szOID_CMC_REVOKE_REQUEST, 0, (LPCWSTR)IDS_REVOKE_REQUEST, NULL },
01342  { 6, szOID_CMC_QUERY_PENDING, 0, (LPCWSTR)IDS_QUERY_PENDING, NULL },
01343  { 6, szOID_SORTED_CTL, 0, (LPCWSTR)IDS_SORTED_CTL, NULL },
01344  { 6, szOID_ARCHIVED_KEY_CERT_HASH, 0, (LPCWSTR)IDS_ARCHIVED_KEY_CERT_HASH, NULL },
01345  { 6, szOID_PRIVATEKEY_USAGE_PERIOD, 0, (LPCWSTR)IDS_PRIVATE_KEY_USAGE_PERIOD, NULL },
01346  { 6, szOID_REQUEST_CLIENT_INFO, 0, (LPCWSTR)IDS_CLIENT_INFORMATION, NULL },
01347 
01348  { 7, szOID_PKIX_KP_SERVER_AUTH, 0, (LPCWSTR)IDS_SERVER_AUTHENTICATION, NULL },
01349  { 7, szOID_PKIX_KP_CLIENT_AUTH, 0, (LPCWSTR)IDS_CLIENT_AUTHENTICATION, NULL },
01350  { 7, szOID_PKIX_KP_CODE_SIGNING, 0, (LPCWSTR)IDS_CODE_SIGNING, NULL },
01351  { 7, szOID_PKIX_KP_EMAIL_PROTECTION, 0, (LPCWSTR)IDS_SECURE_EMAIL, NULL },
01352  { 7, szOID_PKIX_KP_TIMESTAMP_SIGNING, 0, (LPCWSTR)IDS_TIME_STAMPING, NULL },
01353  { 7, szOID_KP_CTL_USAGE_SIGNING, 0, (LPCWSTR)IDS_MICROSOFT_TRUST_LIST_SIGNING, NULL },
01354  { 7, szOID_KP_TIME_STAMP_SIGNING, 0, (LPCWSTR)IDS_MICROSOFT_TIME_STAMPING, NULL },
01355  { 7, szOID_PKIX_KP_IPSEC_END_SYSTEM, 0, (LPCWSTR)IDS_IPSEC_END_SYSTEM, NULL },
01356  { 7, szOID_PKIX_KP_IPSEC_TUNNEL, 0, (LPCWSTR)IDS_IPSEC_TUNNEL, NULL },
01357  { 7, szOID_PKIX_KP_IPSEC_USER, 0, (LPCWSTR)IDS_IPSEC_USER, NULL },
01358  { 7, szOID_KP_EFS, 0, (LPCWSTR)IDS_EFS, NULL },
01359  { 7, szOID_WHQL_CRYPTO, 0, (LPCWSTR)IDS_WHQL_CRYPTO, NULL },
01360  { 7, szOID_NT5_CRYPTO, 0, (LPCWSTR)IDS_NT5_CRYPTO, NULL },
01361  { 7, szOID_OEM_WHQL_CRYPTO, 0, (LPCWSTR)IDS_OEM_WHQL_CRYPTO, NULL },
01362  { 7, szOID_EMBEDDED_NT_CRYPTO, 0, (LPCWSTR)IDS_EMBEDDED_NT_CRYPTO, NULL },
01363  { 7, szOID_LICENSES, 0, (LPCWSTR)IDS_KEY_PACK_LICENSES, NULL },
01364  { 7, szOID_LICENSE_SERVER, 0, (LPCWSTR)IDS_LICENSE_SERVER, NULL },
01365  { 7, szOID_KP_SMARTCARD_LOGON, 0, (LPCWSTR)IDS_SMART_CARD_LOGON, NULL },
01366  { 7, szOID_DRM, 0, (LPCWSTR)IDS_DIGITAL_RIGHTS, NULL },
01367  { 7, szOID_KP_QUALIFIED_SUBORDINATION, 0, (LPCWSTR)IDS_QUALIFIED_SUBORDINATION, NULL },
01368  { 7, szOID_KP_KEY_RECOVERY, 0, (LPCWSTR)IDS_KEY_RECOVERY, NULL },
01369  { 7, szOID_KP_DOCUMENT_SIGNING, 0, (LPCWSTR)IDS_DOCUMENT_SIGNING, NULL },
01370  { 7, szOID_IPSEC_KP_IKE_INTERMEDIATE, 0, (LPCWSTR)IDS_IPSEC_IKE_INTERMEDIATE, NULL },
01371  { 7, szOID_EFS_RECOVERY, 0, (LPCWSTR)IDS_FILE_RECOVERY, NULL },
01372  { 7, szOID_ROOT_LIST_SIGNER, 0, (LPCWSTR)IDS_ROOT_LIST_SIGNER, NULL },
01373  { 7, szOID_ANY_APPLICATION_POLICY, 0, (LPCWSTR)IDS_ANY_APPLICATION_POLICIES, NULL },
01374  { 7, szOID_DS_EMAIL_REPLICATION, 0, (LPCWSTR)IDS_DS_EMAIL_REPLICATION, NULL },
01375  { 7, szOID_ENROLLMENT_AGENT, 0, (LPCWSTR)IDS_ENROLLMENT_AGENT, NULL },
01376  { 7, szOID_KP_KEY_RECOVERY_AGENT, 0, (LPCWSTR)IDS_KEY_RECOVERY_AGENT, NULL },
01377  { 7, szOID_KP_CA_EXCHANGE, 0, (LPCWSTR)IDS_CA_EXCHANGE, NULL },
01378  { 7, szOID_KP_LIFETIME_SIGNING, 0, (LPCWSTR)IDS_LIFETIME_SIGNING, NULL },
01379 
01380  { 8, szOID_ANY_CERT_POLICY, 0, (LPCWSTR)IDS_ANY_CERT_POLICY, NULL },
01381 };
01382 
01383 struct OIDInfo {
01384     CRYPT_OID_INFO info;
01385     struct list entry;
01386 };
01387 
01388 static void init_oid_info(void)
01389 {
01390     DWORD i;
01391 
01392     oid_init_localizednames();
01393     for (i = 0; i < sizeof(oidInfoConstructors) /
01394      sizeof(oidInfoConstructors[0]); i++)
01395     {
01396         if (!IS_INTRESOURCE(oidInfoConstructors[i].pwszName))
01397         {
01398             struct OIDInfo *info;
01399 
01400             /* The name is a static string, so just use the same pointer */
01401             info = CryptMemAlloc(sizeof(struct OIDInfo));
01402             if (info)
01403             {
01404                 memset(info, 0, sizeof(*info));
01405                 info->info.cbSize = sizeof(CRYPT_OID_INFO);
01406                 info->info.pszOID = oidInfoConstructors[i].pszOID;
01407                 info->info.pwszName = oidInfoConstructors[i].pwszName;
01408                 info->info.dwGroupId = oidInfoConstructors[i].dwGroupId;
01409                 info->info.u.Algid = oidInfoConstructors[i].Algid;
01410                 if (oidInfoConstructors[i].blob)
01411                 {
01412                     info->info.ExtraInfo.cbData =
01413                      oidInfoConstructors[i].blob->cbData;
01414                     info->info.ExtraInfo.pbData =
01415                      oidInfoConstructors[i].blob->pbData;
01416                 }
01417                 list_add_tail(&oidInfo, &info->entry);
01418             }
01419         }
01420         else
01421         {
01422             LPCWSTR stringresource;
01423             int len = LoadStringW(hInstance,
01424              (UINT_PTR)oidInfoConstructors[i].pwszName,
01425              (LPWSTR)&stringresource, 0);
01426 
01427             if (len)
01428             {
01429                 struct OIDInfo *info = CryptMemAlloc(sizeof(struct OIDInfo) +
01430                  (len + 1) * sizeof(WCHAR));
01431 
01432                 if (info)
01433                 {
01434                     memset(info, 0, sizeof(*info));
01435                     info->info.cbSize = sizeof(CRYPT_OID_INFO);
01436                     info->info.pszOID = oidInfoConstructors[i].pszOID;
01437                     info->info.pwszName = (LPWSTR)(info + 1);
01438                     info->info.dwGroupId = oidInfoConstructors[i].dwGroupId;
01439                     info->info.u.Algid = oidInfoConstructors[i].Algid;
01440                     memcpy(info + 1, stringresource, len*sizeof(WCHAR));
01441                     ((LPWSTR)(info + 1))[len] = 0;
01442                     if (oidInfoConstructors[i].blob)
01443                     {
01444                         info->info.ExtraInfo.cbData =
01445                          oidInfoConstructors[i].blob->cbData;
01446                         info->info.ExtraInfo.pbData =
01447                          oidInfoConstructors[i].blob->pbData;
01448                     }
01449                     list_add_tail(&oidInfo, &info->entry);
01450                 }
01451             }
01452         }
01453     }
01454 }
01455 
01456 static void free_oid_info(void)
01457 {
01458     struct OIDInfo *info, *next;
01459 
01460     LIST_FOR_EACH_ENTRY_SAFE(info, next, &oidInfo, struct OIDInfo, entry)
01461     {
01462         list_remove(&info->entry);
01463         CryptMemFree(info);
01464     }
01465     DeleteCriticalSection(&oidInfoCS);
01466 }
01467 
01468 /***********************************************************************
01469  *             CryptEnumOIDInfo (CRYPT32.@)
01470  */
01471 BOOL WINAPI CryptEnumOIDInfo(DWORD dwGroupId, DWORD dwFlags, void *pvArg,
01472  PFN_CRYPT_ENUM_OID_INFO pfnEnumOIDInfo)
01473 {
01474     BOOL ret = TRUE;
01475     struct OIDInfo *info;
01476 
01477     TRACE("(%d, %08x, %p, %p)\n", dwGroupId, dwFlags, pvArg,
01478      pfnEnumOIDInfo);
01479 
01480     EnterCriticalSection(&oidInfoCS);
01481     LIST_FOR_EACH_ENTRY(info, &oidInfo, struct OIDInfo, entry)
01482     {
01483         if (!dwGroupId || dwGroupId == info->info.dwGroupId)
01484         {
01485             ret = pfnEnumOIDInfo(&info->info, pvArg);
01486             if (!ret)
01487                 break;
01488         }
01489     }
01490     LeaveCriticalSection(&oidInfoCS);
01491     return ret;
01492 }
01493 
01494 PCCRYPT_OID_INFO WINAPI CryptFindOIDInfo(DWORD dwKeyType, void *pvKey,
01495  DWORD dwGroupId)
01496 {
01497     PCCRYPT_OID_INFO ret = NULL;
01498 
01499     TRACE("(%d, %p, %d)\n", dwKeyType, pvKey, dwGroupId);
01500 
01501     switch(dwKeyType)
01502     {
01503     case CRYPT_OID_INFO_ALGID_KEY:
01504     {
01505         struct OIDInfo *info;
01506 
01507         TRACE("CRYPT_OID_INFO_ALGID_KEY: %d\n", *(DWORD *)pvKey);
01508         EnterCriticalSection(&oidInfoCS);
01509         LIST_FOR_EACH_ENTRY(info, &oidInfo, struct OIDInfo, entry)
01510         {
01511             if (info->info.u.Algid == *(DWORD *)pvKey &&
01512              (!dwGroupId || info->info.dwGroupId == dwGroupId))
01513             {
01514                 ret = &info->info;
01515                 break;
01516             }
01517         }
01518         LeaveCriticalSection(&oidInfoCS);
01519         break;
01520     }
01521     case CRYPT_OID_INFO_NAME_KEY:
01522     {
01523         struct OIDInfo *info;
01524 
01525         TRACE("CRYPT_OID_INFO_NAME_KEY: %s\n", debugstr_w(pvKey));
01526         EnterCriticalSection(&oidInfoCS);
01527         LIST_FOR_EACH_ENTRY(info, &oidInfo, struct OIDInfo, entry)
01528         {
01529             if (!lstrcmpW(info->info.pwszName, pvKey) &&
01530              (!dwGroupId || info->info.dwGroupId == dwGroupId))
01531             {
01532                 ret = &info->info;
01533                 break;
01534             }
01535         }
01536         LeaveCriticalSection(&oidInfoCS);
01537         break;
01538     }
01539     case CRYPT_OID_INFO_OID_KEY:
01540     {
01541         struct OIDInfo *info;
01542         LPSTR oid = pvKey;
01543 
01544         TRACE("CRYPT_OID_INFO_OID_KEY: %s\n", debugstr_a(oid));
01545         EnterCriticalSection(&oidInfoCS);
01546         LIST_FOR_EACH_ENTRY(info, &oidInfo, struct OIDInfo, entry)
01547         {
01548             if (!lstrcmpA(info->info.pszOID, oid) &&
01549              (!dwGroupId || info->info.dwGroupId == dwGroupId))
01550             {
01551                 ret = &info->info;
01552                 break;
01553             }
01554         }
01555         LeaveCriticalSection(&oidInfoCS);
01556         break;
01557     }
01558     case CRYPT_OID_INFO_SIGN_KEY:
01559     {
01560         struct OIDInfo *info;
01561 
01562         TRACE("CRYPT_OID_INFO_SIGN_KEY: %d\n", *(DWORD *)pvKey);
01563         EnterCriticalSection(&oidInfoCS);
01564         LIST_FOR_EACH_ENTRY(info, &oidInfo, struct OIDInfo, entry)
01565         {
01566             if (info->info.u.Algid == *(DWORD *)pvKey &&
01567              info->info.ExtraInfo.cbData >= sizeof(DWORD) &&
01568              *(DWORD *)info->info.ExtraInfo.pbData ==
01569              *(DWORD *)((LPBYTE)pvKey + sizeof(DWORD)) &&
01570              (!dwGroupId || info->info.dwGroupId == dwGroupId))
01571             {
01572                 ret = &info->info;
01573                 break;
01574             }
01575         }
01576         LeaveCriticalSection(&oidInfoCS);
01577         break;
01578     }
01579     }
01580     return ret;
01581 }
01582 
01583 LPCSTR WINAPI CertAlgIdToOID(DWORD dwAlgId)
01584 {
01585     LPCSTR ret;
01586     PCCRYPT_OID_INFO info = CryptFindOIDInfo(CRYPT_OID_INFO_ALGID_KEY,
01587      &dwAlgId, 0);
01588 
01589     if (info)
01590         ret = info->pszOID;
01591     else
01592         ret = NULL;
01593     return ret;
01594 }
01595 
01596 DWORD WINAPI CertOIDToAlgId(LPCSTR pszObjId)
01597 {
01598     DWORD ret;
01599     PCCRYPT_OID_INFO info = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
01600      (void *)pszObjId, 0);
01601 
01602     if (info)
01603         ret = info->u.Algid;
01604     else
01605         ret = 0;
01606     return ret;
01607 }
01608 
01609 void crypt_oid_init(void)
01610 {
01611     init_oid_info();
01612 }
01613 
01614 void crypt_oid_free(void)
01615 {
01616     free_function_sets();
01617     free_oid_info();
01618 }

Generated on Mon May 28 2012 04:22:56 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.