diff --git a/reactos/lib/crypt32/cert.c b/reactos/lib/crypt32/cert.c index 23e4a3c178f..9eaaa19c513 100644 --- a/reactos/lib/crypt32/cert.c +++ b/reactos/lib/crypt32/cert.c @@ -3285,15 +3285,12 @@ BOOL WINAPI CryptVerifyCertificateSignatureEx(HCRYPTPROV hCryptProv, return ret; } -HCRYPTOIDFUNCSET WINAPI CryptInitOIDFunctionSet(LPCSTR pszFuncName, DWORD dwFlags) +BOOL WINAPI CryptVerifyMessageSignature(/*PCRYPT_VERIFY_MESSAGE_PARA*/ void* pVerifyPara, + DWORD dwSignerIndex, const BYTE* pbSignedBlob, DWORD cbSignedBlob, + BYTE* pbDecoded, DWORD* pcbDecoded, PCCERT_CONTEXT* ppSignerCert) { - FIXME("stub: %s %lx\n", debugstr_a(pszFuncName), dwFlags); - return NULL; -} - -BOOL WINAPI CryptUnregisterDefaultOIDFunction(DWORD dwEncodingType, - LPCSTR pszFuncName, LPCWSTR pwszDll) -{ - FIXME("stub: %lx %s %s\n", dwEncodingType, debugstr_a(pszFuncName), debugstr_w(pwszDll)); + FIXME("stub: %p, %ld, %p, %ld, %p, %p, %p\n", + pVerifyPara, dwSignerIndex, pbSignedBlob, cbSignedBlob, + pbDecoded, pcbDecoded, ppSignerCert); return FALSE; } diff --git a/reactos/lib/crypt32/crypt32.spec b/reactos/lib/crypt32/crypt32.spec index 5d43e33f0d0..897853c79ce 100644 --- a/reactos/lib/crypt32/crypt32.spec +++ b/reactos/lib/crypt32/crypt32.spec @@ -105,13 +105,13 @@ @ stdcall CryptExportPublicKeyInfoEx(long long long str long ptr ptr ptr) @ stub CryptFindOIDInfo @ stub CryptFormatObject -@ stub CryptFreeOIDFunctionAddress +@ stdcall CryptFreeOIDFunctionAddress(long long) @ stub CryptGetAsyncParam -@ stub CryptGetDefaultOIDDllList -@ stub CryptGetDefaultOIDFunctionAddress +@ stdcall CryptGetDefaultOIDDllList(long long ptr ptr) +@ stdcall CryptGetDefaultOIDFunctionAddress(long long wstr long ptr ptr) @ stub CryptGetMessageCertificates @ stub CryptGetMessageSignerCount -@ stub CryptGetOIDFunctionAddress +@ stdcall CryptGetOIDFunctionAddress(long long str long ptr ptr) @ stdcall CryptGetOIDFunctionValue(long str str wstr ptr ptr ptr) @ stdcall CryptHashCertificate(long long long ptr long ptr ptr) @ stub CryptHashMessage @@ -121,7 +121,7 @@ @ stdcall CryptImportPublicKeyInfo(long long ptr ptr) @ stdcall CryptImportPublicKeyInfoEx(long long ptr long long ptr ptr) @ stdcall CryptInitOIDFunctionSet(str long) -@ stub CryptInstallOIDFunctionAddress +@ stdcall CryptInstallOIDFunctionAddress(ptr long str long ptr long) @ stub CryptLoadSip @ stdcall CryptMemAlloc(long) @ stdcall CryptMemFree(ptr) @@ -165,16 +165,16 @@ @ stub CryptVerifyDetachedMessageHash @ stub CryptVerifyDetachedMessageSignature @ stub CryptVerifyMessageHash -@ stub CryptVerifyMessageSignature +@ stdcall CryptVerifyMessageSignature(ptr long ptr long ptr ptr ptr) @ stub CryptVerifyMessageSignatureWithKey @ stub CryptVerifySignatureU @ stdcall I_CryptAllocTls() -@ stdcall I_CryptCreateLruCache(long long) +@ stdcall I_CryptCreateLruCache(ptr ptr) @ stub I_CryptCreateLruEntry @ stdcall I_CryptDetachTls(long) -@ stdcall I_CryptFindLruEntryData(long) -@ stdcall I_CryptFlushLruCache(long) -@ stdcall I_CryptFreeLruCache(long) +@ stdcall I_CryptFindLruEntryData(long long long) +@ stdcall I_CryptFlushLruCache(ptr long long) +@ stdcall I_CryptFreeLruCache(ptr long long) @ stdcall I_CryptFreeTls(long long) @ stub I_CryptGetDefaultCryptProv @ stub I_CryptGetDefaultCryptProvForEncrypt diff --git a/reactos/lib/crypt32/crypt32.xml b/reactos/lib/crypt32/crypt32.xml index c64f88735d2..c817a0b0fd4 100644 --- a/reactos/lib/crypt32/crypt32.xml +++ b/reactos/lib/crypt32/crypt32.xml @@ -11,6 +11,7 @@ main.c encode.c cert.c + oid.c protectdata.c crypt32.rc crypt32.spec diff --git a/reactos/lib/crypt32/crypt32_private.h b/reactos/lib/crypt32/crypt32_private.h index 9b593533723..1bf5f6fa210 100644 --- a/reactos/lib/crypt32/crypt32_private.h +++ b/reactos/lib/crypt32/crypt32_private.h @@ -24,4 +24,7 @@ */ HCRYPTPROV CRYPT_GetDefaultProvider(void); +void CRYPT_InitFunctionSets(void); +void CRYPT_FreeFunctionSets(void); + #endif diff --git a/reactos/lib/crypt32/encode.c b/reactos/lib/crypt32/encode.c index c65941f4b3f..bea24dd2689 100644 --- a/reactos/lib/crypt32/encode.c +++ b/reactos/lib/crypt32/encode.c @@ -1,5 +1,4 @@ /* - * Copyright 2002 Mike McCormack for CodeWeavers * Copyright 2005 Juan Lang * * This library is free software; you can redistribute it and/or @@ -67,8 +66,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(crypt); -static const WCHAR szDllName[] = { 'D','l','l',0 }; - typedef BOOL (WINAPI *CryptEncodeObjectFunc)(DWORD, LPCSTR, const void *, BYTE *, DWORD *); typedef BOOL (WINAPI *CryptEncodeObjectExFunc)(DWORD, LPCSTR, const void *, @@ -182,260 +179,12 @@ static WINE_EXCEPTION_FILTER(page_fault) return EXCEPTION_CONTINUE_SEARCH; } -static char *CRYPT_GetKeyName(DWORD dwEncodingType, LPCSTR pszFuncName, - LPCSTR pszOID) -{ - static const char szEncodingTypeFmt[] = - "Software\\Microsoft\\Cryptography\\OID\\EncodingType %ld\\%s\\%s"; - UINT len; - char numericOID[7]; /* enough for "#65535" */ - const char *oid; - LPSTR szKey; - - /* MSDN says the encoding type is a mask, but it isn't treated that way. - * (E.g., if dwEncodingType were 3, the key names "EncodingType 1" and - * "EncodingType 2" would be expected if it were a mask. Instead native - * stores values in "EncodingType 3". - */ - if (!HIWORD(pszOID)) - { - snprintf(numericOID, sizeof(numericOID), "#%d", LOWORD(pszOID)); - oid = numericOID; - } - else - oid = pszOID; - - /* This is enough: the lengths of the two string parameters are explicitly - * counted, and we need up to five additional characters for the encoding - * type. These are covered by the "%d", "%s", and "%s" characters in the - * format specifier that are removed by sprintf. - */ - len = sizeof(szEncodingTypeFmt) + lstrlenA(pszFuncName) + lstrlenA(oid); - szKey = CryptMemAlloc(len); - if (szKey) - sprintf(szKey, szEncodingTypeFmt, dwEncodingType, pszFuncName, oid); - return szKey; -} - -BOOL WINAPI CryptRegisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName, - LPCSTR pszOID, LPCWSTR pwszDll, LPCSTR pszOverrideFuncName) -{ - LONG r; - HKEY hKey; - LPSTR szKey; - - TRACE("%lx %s %s %s %s\n", dwEncodingType, pszFuncName, pszOID, - debugstr_w(pwszDll), pszOverrideFuncName); - - /* This only registers functions for encoding certs, not messages */ - if (!GET_CERT_ENCODING_TYPE(dwEncodingType)) - return TRUE; - - /* Native does nothing pwszDll is NULL */ - if (!pwszDll) - return TRUE; - - /* I'm not matching MS bug for bug here, because I doubt any app depends on - * it: - * - native "succeeds" if pszFuncName is NULL, but the nonsensical entry - * it creates would never be used - * - native returns an HRESULT rather than a Win32 error if pszOID is NULL. - * Instead I disallow both of these with ERROR_INVALID_PARAMETER. - */ - if (!pszFuncName || !pszOID) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - - szKey = CRYPT_GetKeyName(dwEncodingType, pszFuncName, pszOID); - TRACE("Key name is %s\n", debugstr_a(szKey)); - - if (!szKey) - return FALSE; - - r = RegCreateKeyA(HKEY_LOCAL_MACHINE, szKey, &hKey); - CryptMemFree(szKey); - if(r != ERROR_SUCCESS) - return FALSE; - - /* write the values */ - if (pszOverrideFuncName) - RegSetValueExA(hKey, "FuncName", 0, REG_SZ, (const BYTE*)pszOverrideFuncName, - lstrlenA(pszOverrideFuncName) + 1); - RegSetValueExW(hKey, szDllName, 0, REG_SZ, (const BYTE*) pwszDll, - (lstrlenW(pwszDll) + 1) * sizeof (WCHAR)); - - RegCloseKey(hKey); - return TRUE; -} - -BOOL WINAPI CryptUnregisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName, - LPCSTR pszOID) -{ - LPSTR szKey; - LONG rc; - - TRACE("%lx %s %s\n", dwEncodingType, pszFuncName, pszOID); - - if (!GET_CERT_ENCODING_TYPE(dwEncodingType)) - return TRUE; - - if (!pszFuncName || !pszOID) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - - szKey = CRYPT_GetKeyName(dwEncodingType, pszFuncName, pszOID); - rc = RegDeleteKeyA(HKEY_LOCAL_MACHINE, szKey); - CryptMemFree(szKey); - if (rc) - SetLastError(rc); - return rc ? FALSE : TRUE; -} - -BOOL WINAPI CryptGetOIDFunctionValue(DWORD dwEncodingType, LPCSTR pszFuncName, - LPCSTR pszOID, LPCWSTR pwszValueName, DWORD *pdwValueType, BYTE *pbValueData, - DWORD *pcbValueData) -{ - LPSTR szKey; - LONG rc; - HKEY hKey; - - TRACE("%lx %s %s %s %p %p %p\n", dwEncodingType, debugstr_a(pszFuncName), - debugstr_a(pszOID), debugstr_w(pwszValueName), pdwValueType, pbValueData, - pcbValueData); - - if (!GET_CERT_ENCODING_TYPE(dwEncodingType)) - return TRUE; - - if (!pszFuncName || !pszOID || !pwszValueName) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - - szKey = CRYPT_GetKeyName(dwEncodingType, pszFuncName, pszOID); - rc = RegOpenKeyA(HKEY_LOCAL_MACHINE, szKey, &hKey); - CryptMemFree(szKey); - if (rc) - SetLastError(rc); - else - { - rc = RegQueryValueExW(hKey, pwszValueName, NULL, pdwValueType, - pbValueData, pcbValueData); - if (rc) - SetLastError(rc); - RegCloseKey(hKey); - } - return rc ? FALSE : TRUE; -} - -BOOL WINAPI CryptSetOIDFunctionValue(DWORD dwEncodingType, LPCSTR pszFuncName, - LPCSTR pszOID, LPCWSTR pwszValueName, DWORD dwValueType, - const BYTE *pbValueData, DWORD cbValueData) -{ - LPSTR szKey; - LONG rc; - HKEY hKey; - - TRACE("%lx %s %s %s %ld %p %ld\n", dwEncodingType, debugstr_a(pszFuncName), - debugstr_a(pszOID), debugstr_w(pwszValueName), dwValueType, pbValueData, - cbValueData); - - if (!GET_CERT_ENCODING_TYPE(dwEncodingType)) - return TRUE; - - if (!pszFuncName || !pszOID || !pwszValueName) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - - szKey = CRYPT_GetKeyName(dwEncodingType, pszFuncName, pszOID); - rc = RegOpenKeyA(HKEY_LOCAL_MACHINE, szKey, &hKey); - CryptMemFree(szKey); - if (rc) - SetLastError(rc); - else - { - rc = RegSetValueExW(hKey, pwszValueName, 0, dwValueType, pbValueData, - cbValueData); - if (rc) - SetLastError(rc); - RegCloseKey(hKey); - } - return rc ? FALSE : TRUE; -} - -/* Gets the registered function named szFuncName for dwCertEncodingType and - * lpszStructType, or NULL if one could not be found. *lib will be set to the - * handle of the module it's in, or NULL if no module was loaded. If the - * return value is NULL, *lib will also be NULL, to simplify error handling. - */ -static void *CRYPT_GetFunc(DWORD dwCertEncodingType, LPCSTR lpszStructType, - LPCSTR szFuncName, HMODULE *lib) -{ - void *ret = NULL; - char *szKey = CRYPT_GetKeyName(dwCertEncodingType, szFuncName, - lpszStructType); - const char *funcName; - long r; - HKEY hKey; - DWORD type, size = 0; - - TRACE("(%08lx %s %s %p)\n", dwCertEncodingType, debugstr_a(lpszStructType), - debugstr_a(szFuncName), lib); - - *lib = NULL; - r = RegOpenKeyA(HKEY_LOCAL_MACHINE, szKey, &hKey); - CryptMemFree(szKey); - if(r != ERROR_SUCCESS) - return NULL; - - RegQueryValueExA(hKey, "FuncName", NULL, &type, NULL, &size); - if (GetLastError() == ERROR_MORE_DATA && type == REG_SZ) - { - funcName = CryptMemAlloc(size); - RegQueryValueExA(hKey, "FuncName", NULL, &type, (LPBYTE)funcName, - &size); - } - else - funcName = szFuncName; - RegQueryValueExW(hKey, szDllName, NULL, &type, NULL, &size); - if (GetLastError() == ERROR_MORE_DATA && type == REG_SZ) - { - LPWSTR dllName = CryptMemAlloc(size); - - RegQueryValueExW(hKey, szDllName, NULL, &type, (LPBYTE)dllName, - &size); - *lib = LoadLibraryW(dllName); - if (*lib) - { - ret = GetProcAddress(*lib, funcName); - if (!ret) - { - /* Unload the library, the caller doesn't want to unload it - * when the return value is NULL. - */ - FreeLibrary(*lib); - *lib = NULL; - } - } - CryptMemFree(dllName); - } - if (funcName != szFuncName) - CryptMemFree((char *)funcName); - TRACE("returning %p\n", ret); - return ret; -} - BOOL WINAPI CryptEncodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo, BYTE *pbEncoded, DWORD *pcbEncoded) { + static HCRYPTOIDFUNCSET set = NULL; BOOL ret = FALSE; - HMODULE lib; + HCRYPTOIDFUNCADDR hFunc; CryptEncodeObjectFunc pCryptEncodeObject; TRACE("(0x%08lx, %s, %p, %p, %p)\n", dwCertEncodingType, @@ -449,14 +198,15 @@ BOOL WINAPI CryptEncodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType, } /* Try registered DLL first.. */ - pCryptEncodeObject = - (CryptEncodeObjectFunc)CRYPT_GetFunc(dwCertEncodingType, - lpszStructType, CRYPT_OID_ENCODE_OBJECT_FUNC, &lib); + if (!set) + set = CryptInitOIDFunctionSet(CRYPT_OID_ENCODE_OBJECT_FUNC, 0); + CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0, + (void **)&pCryptEncodeObject, &hFunc); if (pCryptEncodeObject) { ret = pCryptEncodeObject(dwCertEncodingType, lpszStructType, pvStructInfo, pbEncoded, pcbEncoded); - FreeLibrary(lib); + CryptFreeOIDFunctionAddress(hFunc, 0); } else { @@ -2272,9 +2022,10 @@ BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, void *pvEncoded, DWORD *pcbEncoded) { + static HCRYPTOIDFUNCSET set = NULL; BOOL ret = FALSE; - HMODULE lib = NULL; CryptEncodeObjectExFunc encodeFunc = NULL; + HCRYPTOIDFUNCADDR hFunc = NULL; TRACE("(0x%08lx, %s, %p, 0x%08lx, %p, %p, %p)\n", dwCertEncodingType, debugstr_a(lpszStructType), pvStructInfo, dwFlags, pEncodePara, @@ -2384,15 +2135,19 @@ BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, TRACE("OID %s not found or unimplemented, looking for DLL\n", debugstr_a(lpszStructType)); if (!encodeFunc) - encodeFunc = (CryptEncodeObjectExFunc)CRYPT_GetFunc(dwCertEncodingType, - lpszStructType, CRYPT_OID_ENCODE_OBJECT_EX_FUNC, &lib); + { + if (!set) + set = CryptInitOIDFunctionSet(CRYPT_OID_ENCODE_OBJECT_EX_FUNC, 0); + CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0, + (void **)&encodeFunc, &hFunc); + } if (encodeFunc) ret = encodeFunc(dwCertEncodingType, lpszStructType, pvStructInfo, dwFlags, pEncodePara, pvEncoded, pcbEncoded); else SetLastError(ERROR_FILE_NOT_FOUND); - if (lib) - FreeLibrary(lib); + if (hFunc) + CryptFreeOIDFunctionAddress(hFunc, 0); return ret; } @@ -2400,9 +2155,10 @@ BOOL WINAPI CryptDecodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo) { + static HCRYPTOIDFUNCSET set = NULL; BOOL ret = FALSE; - HMODULE lib; CryptDecodeObjectFunc pCryptDecodeObject; + HCRYPTOIDFUNCADDR hFunc; TRACE("(0x%08lx, %s, %p, %ld, 0x%08lx, %p, %p)\n", dwCertEncodingType, debugstr_a(lpszStructType), pbEncoded, cbEncoded, dwFlags, @@ -2415,14 +2171,15 @@ BOOL WINAPI CryptDecodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType, } /* Try registered DLL first.. */ - pCryptDecodeObject = - (CryptDecodeObjectFunc)CRYPT_GetFunc(dwCertEncodingType, - lpszStructType, CRYPT_OID_DECODE_OBJECT_FUNC, &lib); + if (!set) + set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC, 0); + CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0, + (void **)&pCryptDecodeObject, &hFunc); if (pCryptDecodeObject) { ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType, pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo); - FreeLibrary(lib); + CryptFreeOIDFunctionAddress(hFunc, 0); } else { @@ -5386,9 +5143,10 @@ BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) { + static HCRYPTOIDFUNCSET set = NULL; BOOL ret = FALSE; - HMODULE lib = NULL; CryptDecodeObjectExFunc decodeFunc = NULL; + HCRYPTOIDFUNCADDR hFunc = NULL; TRACE("(0x%08lx, %s, %p, %ld, 0x%08lx, %p, %p, %p)\n", dwCertEncodingType, debugstr_a(lpszStructType), pbEncoded, @@ -5508,15 +5266,19 @@ BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, TRACE("OID %s not found or unimplemented, looking for DLL\n", debugstr_a(lpszStructType)); if (!decodeFunc) - decodeFunc = (CryptDecodeObjectExFunc)CRYPT_GetFunc(dwCertEncodingType, - lpszStructType, CRYPT_OID_DECODE_OBJECT_EX_FUNC, &lib); + { + if (!set) + set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC, 0); + CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0, + (void **)&decodeFunc, &hFunc); + } if (decodeFunc) ret = decodeFunc(dwCertEncodingType, lpszStructType, pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo); else SetLastError(ERROR_FILE_NOT_FOUND); - if (lib) - FreeLibrary(lib); + if (hFunc) + CryptFreeOIDFunctionAddress(hFunc, 0); return ret; } @@ -5609,9 +5371,10 @@ BOOL WINAPI CryptExportPublicKeyInfoEx(HCRYPTPROV hCryptProv, DWORD dwKeySpec, DWORD dwCertEncodingType, LPSTR pszPublicKeyObjId, DWORD dwFlags, void *pvAuxInfo, PCERT_PUBLIC_KEY_INFO pInfo, DWORD *pcbInfo) { + static HCRYPTOIDFUNCSET set = NULL; BOOL ret; ExportPublicKeyInfoExFunc exportFunc = NULL; - HMODULE lib = NULL; + HCRYPTOIDFUNCADDR hFunc = NULL; TRACE("(%ld, %ld, %08lx, %s, %08lx, %p, %p, %p)\n", hCryptProv, dwKeySpec, dwCertEncodingType, debugstr_a(pszPublicKeyObjId), dwFlags, pvAuxInfo, @@ -5624,14 +5387,19 @@ BOOL WINAPI CryptExportPublicKeyInfoEx(HCRYPTPROV hCryptProv, DWORD dwKeySpec, } if (pszPublicKeyObjId) - exportFunc = CRYPT_GetFunc(dwCertEncodingType, pszPublicKeyObjId, - CRYPT_OID_EXPORT_PUBLIC_KEY_INFO_FUNC, &lib); + { + if (!set) + set = CryptInitOIDFunctionSet(CRYPT_OID_EXPORT_PUBLIC_KEY_INFO_FUNC, + 0); + CryptGetOIDFunctionAddress(set, dwCertEncodingType, pszPublicKeyObjId, + 0, (void **)&exportFunc, &hFunc); + } if (!exportFunc) exportFunc = CRYPT_ExportRsaPublicKeyInfoEx; ret = exportFunc(hCryptProv, dwKeySpec, dwCertEncodingType, pszPublicKeyObjId, dwFlags, pvAuxInfo, pInfo, pcbInfo); - if (lib) - FreeLibrary(lib); + if (hFunc) + CryptFreeOIDFunctionAddress(hFunc, 0); return ret; } @@ -5682,20 +5450,23 @@ BOOL WINAPI CryptImportPublicKeyInfoEx(HCRYPTPROV hCryptProv, DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo, ALG_ID aiKeyAlg, DWORD dwFlags, void *pvAuxInfo, HCRYPTKEY *phKey) { + static HCRYPTOIDFUNCSET set = NULL; BOOL ret; ImportPublicKeyInfoExFunc importFunc = NULL; - HMODULE lib = NULL; + HCRYPTOIDFUNCADDR hFunc = NULL; TRACE("(%ld, %ld, %p, %d, %08lx, %p, %p)\n", hCryptProv, dwCertEncodingType, pInfo, aiKeyAlg, dwFlags, pvAuxInfo, phKey); - importFunc = CRYPT_GetFunc(dwCertEncodingType, pInfo->Algorithm.pszObjId, - CRYPT_OID_IMPORT_PUBLIC_KEY_INFO_FUNC, &lib); + if (!set) + set = CryptInitOIDFunctionSet(CRYPT_OID_IMPORT_PUBLIC_KEY_INFO_FUNC, 0); + CryptGetOIDFunctionAddress(set, dwCertEncodingType, + pInfo->Algorithm.pszObjId, 0, (void **)&importFunc, &hFunc); if (!importFunc) importFunc = CRYPT_ImportRsaPublicKeyInfoEx; ret = importFunc(hCryptProv, dwCertEncodingType, pInfo, aiKeyAlg, dwFlags, pvAuxInfo, phKey); - if (lib) - FreeLibrary(lib); + if (hFunc) + CryptFreeOIDFunctionAddress(hFunc, 0); return ret; } diff --git a/reactos/lib/crypt32/main.c b/reactos/lib/crypt32/main.c index 039449fbc23..df30206cb3c 100644 --- a/reactos/lib/crypt32/main.c +++ b/reactos/lib/crypt32/main.c @@ -38,7 +38,11 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved) { switch (fdwReason) { + case DLL_PROCESS_ATTACH: + CRYPT_InitFunctionSets(); + break; case DLL_PROCESS_DETACH: + CRYPT_FreeFunctionSets(); if (hDefProv) CryptReleaseContext(hDefProv, 0); break; } @@ -53,30 +57,37 @@ HCRYPTPROV CRYPT_GetDefaultProvider(void) return hDefProv; } -/* this function is called by Internet Explorer when it is about to verify a downloaded component */ -BOOL WINAPI I_CryptCreateLruCache(DWORD x, DWORD y) +typedef void * HLRUCACHE; + +/* this function is called by Internet Explorer when it is about to verify a + * downloaded component. The first parameter appears to be a pointer to an + * unknown type, native fails unless it points to a buffer of at least 20 bytes. + * The second parameter appears to be an out parameter, whatever it's set to is + * passed (by cryptnet.dll) to I_CryptFlushLruCache. + */ +BOOL WINAPI I_CryptCreateLruCache(void *unknown, HLRUCACHE *out) { - FIXME("stub!\n"); + FIXME("(%p, %p): stub!\n", unknown, out); + *out = (void *)0xbaadf00d; + return TRUE; +} + +BOOL WINAPI I_CryptFindLruEntryData(DWORD unk0, DWORD unk1, DWORD unk2) +{ + FIXME("(%08lx, %08lx, %08lx): stub!\n", unk0, unk1, unk2); return FALSE; } -/* these functions all have an unknown number of args */ -BOOL WINAPI I_CryptFindLruEntryData(DWORD x) +DWORD WINAPI I_CryptFlushLruCache(HLRUCACHE h, DWORD unk0, DWORD unk1) { - FIXME("stub!\n"); - return FALSE; + FIXME("(%p, %08lx, %08lx): stub!\n", h, unk0, unk1); + return 0; } -BOOL WINAPI I_CryptFlushLruCache(DWORD x) +HLRUCACHE WINAPI I_CryptFreeLruCache(HLRUCACHE h, DWORD unk0, DWORD unk1) { - FIXME("stub!\n"); - return FALSE; -} - -BOOL WINAPI I_CryptFreeLruCache(DWORD x) -{ - FIXME("stub!\n"); - return FALSE; + FIXME("(%p, %08lx, %08lx): stub!\n", h, unk0, unk1); + return h; } BOOL WINAPI CryptSIPRemoveProvider(GUID *pgProv) @@ -206,15 +217,6 @@ BOOL WINAPI CryptSIPLoad return FALSE; } -BOOL WINAPI CryptRegisterDefaultOIDFunction(DWORD dwEncodingType, - LPCSTR pszFuncName, DWORD dwIndex, - LPCWSTR pwszDll) -{ - FIXME("(%lx,%s,%lx,%s) stub!\n", dwEncodingType, pszFuncName, dwIndex, - debugstr_w(pwszDll)); - return FALSE; -} - struct OIDToAlgID { LPCSTR oid; diff --git a/reactos/lib/crypt32/oid.c b/reactos/lib/crypt32/oid.c new file mode 100644 index 00000000000..e9733a1acce --- /dev/null +++ b/reactos/lib/crypt32/oid.c @@ -0,0 +1,558 @@ +/* + * Copyright 2002 Mike McCormack for CodeWeavers + * Copyright 2005 Juan Lang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include "windef.h" +#include "winbase.h" +#include "wincrypt.h" +#include "winreg.h" +#include "wine/debug.h" +#include "wine/list.h" +#include "crypt32_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(crypt); + +static const WCHAR DllW[] = { 'D','l','l',0 }; +CRITICAL_SECTION funcSetCS; +struct list funcSets; + +struct OIDFunctionSet +{ + LPSTR name; + CRITICAL_SECTION cs; /* protects functions */ + struct list functions; + struct list next; +}; + +struct OIDFunction +{ + DWORD encoding; + CRYPT_OID_FUNC_ENTRY entry; + struct list next; +}; + +void CRYPT_InitFunctionSets(void) +{ + InitializeCriticalSection(&funcSetCS); + list_init(&funcSets); +} + +void CRYPT_FreeFunctionSets(void) +{ + struct OIDFunctionSet *setCursor, *setNext; + + LIST_FOR_EACH_ENTRY_SAFE(setCursor, setNext, &funcSets, + struct OIDFunctionSet, next) + { + struct OIDFunction *functionCursor, *funcNext; + + list_remove(&setCursor->next); + CryptMemFree(setCursor->name); + CryptMemFree(setCursor); + LIST_FOR_EACH_ENTRY_SAFE(functionCursor, funcNext, + &setCursor->functions, struct OIDFunction, next) + { + list_remove(&functionCursor->next); + CryptMemFree(functionCursor); + } + DeleteCriticalSection(&setCursor->cs); + } + DeleteCriticalSection(&funcSetCS); +} + +/* There is no free function associated with this; therefore, the sets are + * freed when crypt32.dll is unloaded. + */ +HCRYPTOIDFUNCSET WINAPI CryptInitOIDFunctionSet(LPCSTR pszFuncName, + DWORD dwFlags) +{ + struct OIDFunctionSet *cursor, *ret = NULL; + + TRACE("(%s, %lx)\n", debugstr_a(pszFuncName), dwFlags); + + EnterCriticalSection(&funcSetCS); + LIST_FOR_EACH_ENTRY(cursor, &funcSets, struct OIDFunctionSet, next) + { + if (!strcasecmp(pszFuncName, cursor->name)) + { + ret = (HCRYPTOIDFUNCSET)cursor; + break; + } + } + if (!ret) + { + ret = CryptMemAlloc(sizeof(struct OIDFunctionSet)); + if (ret) + { + memset(ret, 0, sizeof(*ret)); + ret->name = CryptMemAlloc(strlen(pszFuncName) + 1); + if (ret->name) + { + InitializeCriticalSection(&ret->cs); + list_init(&ret->functions); + strcpy(ret->name, pszFuncName); + list_add_tail(&funcSets, &ret->next); + } + else + { + CryptMemFree(ret); + ret = NULL; + } + } + } + LeaveCriticalSection(&funcSetCS); + + return (HCRYPTOIDFUNCSET)ret; +} + +static char *CRYPT_GetKeyName(DWORD dwEncodingType, LPCSTR pszFuncName, + LPCSTR pszOID) +{ + static const char szEncodingTypeFmt[] = + "Software\\Microsoft\\Cryptography\\OID\\EncodingType %ld\\%s\\%s"; + UINT len; + char numericOID[7]; /* enough for "#65535" */ + const char *oid; + LPSTR szKey; + + /* MSDN says the encoding type is a mask, but it isn't treated that way. + * (E.g., if dwEncodingType were 3, the key names "EncodingType 1" and + * "EncodingType 2" would be expected if it were a mask. Instead native + * stores values in "EncodingType 3". + */ + if (!HIWORD(pszOID)) + { + snprintf(numericOID, sizeof(numericOID), "#%d", LOWORD(pszOID)); + oid = numericOID; + } + else + oid = pszOID; + + /* This is enough: the lengths of the two string parameters are explicitly + * counted, and we need up to five additional characters for the encoding + * type. These are covered by the "%d", "%s", and "%s" characters in the + * format specifier that are removed by sprintf. + */ + len = sizeof(szEncodingTypeFmt) + lstrlenA(pszFuncName) + lstrlenA(oid); + szKey = CryptMemAlloc(len); + if (szKey) + sprintf(szKey, szEncodingTypeFmt, dwEncodingType, pszFuncName, oid); + return szKey; +} + +BOOL WINAPI CryptGetDefaultOIDDllList(HCRYPTOIDFUNCSET hFuncSet, + DWORD dwEncodingType, LPWSTR pwszDllList, DWORD *pcchDllList) +{ + BOOL ret = TRUE; + struct OIDFunctionSet *set = (struct OIDFunctionSet *)hFuncSet; + char *keyName; + HKEY key; + long rc; + + TRACE("(%p, %ld, %p, %p)\n", hFuncSet, dwEncodingType, pwszDllList, + pcchDllList); + + keyName = CRYPT_GetKeyName(dwEncodingType, set->name, "DEFAULT"); + rc = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, NULL, 0, + KEY_READ, NULL, &key, NULL); + if (!rc) + { + DWORD size = *pcchDllList * sizeof(WCHAR); + + rc = RegQueryValueExW(key, DllW, NULL, NULL, (LPBYTE)pwszDllList, + &size); + if (!rc) + *pcchDllList = size / sizeof(WCHAR); + else + { + /* No value, return an empty list */ + if (*pcchDllList) + *pwszDllList = '\0'; + *pcchDllList = 1; + } + RegCloseKey(key); + } + else + { + SetLastError(rc); + ret = FALSE; + } + CryptMemFree(keyName); + + return ret; +} + +BOOL WINAPI CryptInstallOIDFunctionAddress(HMODULE hModule, + DWORD dwEncodingType, LPCSTR pszFuncName, DWORD cFuncEntry, + const CRYPT_OID_FUNC_ENTRY rgFuncEntry[], DWORD dwFlags) +{ + BOOL ret = TRUE; + struct OIDFunctionSet *set; + + TRACE("(%p, %ld, %s, %ld, %p, %08lx)\n", hModule, dwEncodingType, + debugstr_a(pszFuncName), cFuncEntry, rgFuncEntry, dwFlags); + + set = (struct OIDFunctionSet *)CryptInitOIDFunctionSet(pszFuncName, 0); + if (set) + { + DWORD i; + + EnterCriticalSection(&set->cs); + for (i = 0; ret && i < cFuncEntry; i++) + { + struct OIDFunction *func; + + if (HIWORD(rgFuncEntry[i].pszOID)) + func = CryptMemAlloc(sizeof(struct OIDFunction) + + strlen(rgFuncEntry[i].pszOID) + 1); + else + func = CryptMemAlloc(sizeof(struct OIDFunction)); + if (func) + { + func->encoding = dwEncodingType; + if (HIWORD(rgFuncEntry[i].pszOID)) + { + func->entry.pszOID = (LPSTR)((LPBYTE)func + sizeof(*func)); + strcpy((LPSTR)func->entry.pszOID, rgFuncEntry[i].pszOID); + } + else + func->entry.pszOID = rgFuncEntry[i].pszOID; + func->entry.pvFuncAddr = rgFuncEntry[i].pvFuncAddr; + list_add_tail(&set->functions, &func->next); + } + else + ret = FALSE; + } + LeaveCriticalSection(&set->cs); + } + else + ret = FALSE; + return ret; +} + +static BOOL CRYPT_GetFuncFromReg(DWORD dwEncodingType, LPCSTR pszOID, + LPCSTR szFuncName, LPVOID *ppvFuncAddr, HCRYPTOIDFUNCADDR *phFuncAddr) +{ + BOOL ret = FALSE; + char *keyName; + const char *funcName; + HKEY key; + long rc; + + keyName = CRYPT_GetKeyName(dwEncodingType, szFuncName, pszOID); + rc = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, KEY_READ, &key); + if (!rc) + { + DWORD type, size = 0; + + rc = RegQueryValueExA(key, "FuncName", NULL, &type, NULL, &size); + if (rc == ERROR_MORE_DATA && type == REG_SZ) + { + funcName = CryptMemAlloc(size); + rc = RegQueryValueExA(key, "FuncName", NULL, &type, + (LPBYTE)funcName, &size); + } + else + funcName = szFuncName; + rc = RegQueryValueExW(key, DllW, NULL, &type, NULL, &size); + if (rc == ERROR_MORE_DATA && type == REG_SZ) + { + LPWSTR dllName = CryptMemAlloc(size); + + if (dllName) + { + rc = RegQueryValueExW(key, DllW, NULL, NULL, + (LPBYTE)dllName, &size); + if (!rc) + { + HMODULE lib; + + /* This is a bit of a hack; MSDN describes a more + * complicated unload routine than this will allow. + * Still, this seems to suffice for now. + */ + lib = LoadLibraryW(dllName); + if (lib) + { + *ppvFuncAddr = GetProcAddress(lib, szFuncName); + if (*ppvFuncAddr) + { + *phFuncAddr = (HCRYPTOIDFUNCADDR)lib; + ret = TRUE; + } + else + { + /* Unload the library, the caller doesn't want + * to unload it when the return value is NULL. + */ + FreeLibrary(lib); + } + } + } + else + SetLastError(rc); + CryptMemFree(dllName); + } + } + else + SetLastError(rc); + if (funcName != szFuncName) + CryptMemFree((char *)funcName); + RegCloseKey(key); + } + else + SetLastError(rc); + CryptMemFree(keyName); + return ret; +} + +BOOL WINAPI CryptGetOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet, + DWORD dwEncodingType, LPCSTR pszOID, DWORD dwFlags, void **ppvFuncAddr, + HCRYPTOIDFUNCADDR *phFuncAddr) +{ + BOOL ret = FALSE; + struct OIDFunctionSet *set = (struct OIDFunctionSet *)hFuncSet; + + TRACE("(%p, %ld, %s, %08lx, %p, %p)\n", hFuncSet, dwEncodingType, + debugstr_a(pszOID), dwFlags, ppvFuncAddr, phFuncAddr); + + *ppvFuncAddr = NULL; + if (!(dwFlags & CRYPT_GET_INSTALLED_OID_FUNC_FLAG)) + { + struct OIDFunction *function; + + EnterCriticalSection(&set->cs); + LIST_FOR_EACH_ENTRY(function, &set->functions, struct OIDFunction, next) + { + if (function->encoding == dwEncodingType) + { + if (HIWORD(pszOID)) + { + if (HIWORD(function->entry.pszOID && + !strcasecmp(function->entry.pszOID, pszOID))) + { + *ppvFuncAddr = function->entry.pvFuncAddr; + *phFuncAddr = NULL; /* FIXME: what should it be? */ + ret = TRUE; + break; + } + } + else if (function->entry.pszOID == pszOID) + { + *ppvFuncAddr = function->entry.pvFuncAddr; + *phFuncAddr = NULL; /* FIXME: what should it be? */ + ret = TRUE; + break; + } + } + } + LeaveCriticalSection(&set->cs); + } + if (!*ppvFuncAddr) + ret = CRYPT_GetFuncFromReg(dwEncodingType, pszOID, set->name, + ppvFuncAddr, phFuncAddr); + return ret; +} + +BOOL WINAPI CryptFreeOIDFunctionAddress(HCRYPTOIDFUNCADDR hFuncAddr, + DWORD dwFlags) +{ + TRACE("(%p, %08lx)\n", hFuncAddr, dwFlags); + + /* FIXME: as MSDN states, need to check for DllCanUnloadNow in the DLL, + * and only unload it if it can be unloaded. Also need to implement ref + * counting on the functions. + */ + FreeLibrary((HMODULE)hFuncAddr); + return TRUE; +} + +BOOL WINAPI CryptRegisterDefaultOIDFunction(DWORD dwEncodingType, + LPCSTR pszFuncName, DWORD dwIndex, LPCWSTR pwszDll) +{ + FIXME("(%lx,%s,%lx,%s) stub!\n", dwEncodingType, pszFuncName, dwIndex, + debugstr_w(pwszDll)); + return FALSE; +} + +BOOL WINAPI CryptUnregisterDefaultOIDFunction(DWORD dwEncodingType, + LPCSTR pszFuncName, LPCWSTR pwszDll) +{ + FIXME("(%lx %s %s): stub\n", dwEncodingType, debugstr_a(pszFuncName), + debugstr_w(pwszDll)); + return FALSE; +} + +BOOL WINAPI CryptGetDefaultOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet, + DWORD dwEncodingType, LPCWSTR pwszDll, DWORD dwFlags, void *ppvFuncAddr, + HCRYPTOIDFUNCADDR *phFuncAddr) +{ + FIXME("(%p, %ld, %s, %08lx, %p, %p): stub\n", hFuncSet, dwEncodingType, + debugstr_w(pwszDll), dwFlags, ppvFuncAddr, phFuncAddr); + return FALSE; +} + +BOOL WINAPI CryptRegisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName, + LPCSTR pszOID, LPCWSTR pwszDll, LPCSTR pszOverrideFuncName) +{ + LONG r; + HKEY hKey; + LPSTR szKey; + + TRACE("(%lx, %s, %s, %s, %s)\n", dwEncodingType, pszFuncName, pszOID, + debugstr_w(pwszDll), pszOverrideFuncName); + + /* This only registers functions for encoding certs, not messages */ + if (!GET_CERT_ENCODING_TYPE(dwEncodingType)) + return TRUE; + + /* Native does nothing pwszDll is NULL */ + if (!pwszDll) + return TRUE; + + /* I'm not matching MS bug for bug here, because I doubt any app depends on + * it: native "succeeds" if pszFuncName is NULL, but the nonsensical entry + * it creates would never be used. + */ + if (!pszFuncName || !pszOID) + { + SetLastError(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER)); + return FALSE; + } + + szKey = CRYPT_GetKeyName(dwEncodingType, pszFuncName, pszOID); + TRACE("Key name is %s\n", debugstr_a(szKey)); + + if (!szKey) + return FALSE; + + r = RegCreateKeyA(HKEY_LOCAL_MACHINE, szKey, &hKey); + CryptMemFree(szKey); + if(r != ERROR_SUCCESS) + return FALSE; + + /* write the values */ + if (pszOverrideFuncName) + RegSetValueExA(hKey, "FuncName", 0, REG_SZ, + (const BYTE*)pszOverrideFuncName, lstrlenA(pszOverrideFuncName) + 1); + RegSetValueExW(hKey, DllW, 0, REG_SZ, (const BYTE*) pwszDll, + (lstrlenW(pwszDll) + 1) * sizeof (WCHAR)); + + RegCloseKey(hKey); + return TRUE; +} + +BOOL WINAPI CryptUnregisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName, + LPCSTR pszOID) +{ + LPSTR szKey; + LONG rc; + + TRACE("%lx %s %s\n", dwEncodingType, pszFuncName, pszOID); + + if (!GET_CERT_ENCODING_TYPE(dwEncodingType)) + return TRUE; + + if (!pszFuncName || !pszOID) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + szKey = CRYPT_GetKeyName(dwEncodingType, pszFuncName, pszOID); + rc = RegDeleteKeyA(HKEY_LOCAL_MACHINE, szKey); + CryptMemFree(szKey); + if (rc) + SetLastError(rc); + return rc ? FALSE : TRUE; +} + +BOOL WINAPI CryptGetOIDFunctionValue(DWORD dwEncodingType, LPCSTR pszFuncName, + LPCSTR pszOID, LPCWSTR pwszValueName, DWORD *pdwValueType, BYTE *pbValueData, + DWORD *pcbValueData) +{ + LPSTR szKey; + LONG rc; + HKEY hKey; + + TRACE("%lx %s %s %s %p %p %p\n", dwEncodingType, debugstr_a(pszFuncName), + debugstr_a(pszOID), debugstr_w(pwszValueName), pdwValueType, pbValueData, + pcbValueData); + + if (!GET_CERT_ENCODING_TYPE(dwEncodingType)) + return TRUE; + + if (!pszFuncName || !pszOID || !pwszValueName) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + szKey = CRYPT_GetKeyName(dwEncodingType, pszFuncName, pszOID); + rc = RegOpenKeyA(HKEY_LOCAL_MACHINE, szKey, &hKey); + CryptMemFree(szKey); + if (rc) + SetLastError(rc); + else + { + rc = RegQueryValueExW(hKey, pwszValueName, NULL, pdwValueType, + pbValueData, pcbValueData); + if (rc) + SetLastError(rc); + RegCloseKey(hKey); + } + return rc ? FALSE : TRUE; +} + +BOOL WINAPI CryptSetOIDFunctionValue(DWORD dwEncodingType, LPCSTR pszFuncName, + LPCSTR pszOID, LPCWSTR pwszValueName, DWORD dwValueType, + const BYTE *pbValueData, DWORD cbValueData) +{ + LPSTR szKey; + LONG rc; + HKEY hKey; + + TRACE("%lx %s %s %s %ld %p %ld\n", dwEncodingType, debugstr_a(pszFuncName), + debugstr_a(pszOID), debugstr_w(pwszValueName), dwValueType, pbValueData, + cbValueData); + + if (!GET_CERT_ENCODING_TYPE(dwEncodingType)) + return TRUE; + + if (!pszFuncName || !pszOID || !pwszValueName) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + szKey = CRYPT_GetKeyName(dwEncodingType, pszFuncName, pszOID); + rc = RegOpenKeyA(HKEY_LOCAL_MACHINE, szKey, &hKey); + CryptMemFree(szKey); + if (rc) + SetLastError(rc); + else + { + rc = RegSetValueExW(hKey, pwszValueName, 0, dwValueType, pbValueData, + cbValueData); + if (rc) + SetLastError(rc); + RegCloseKey(hKey); + } + return rc ? FALSE : TRUE; +} diff --git a/reactos/w32api/include/wincrypt.h b/reactos/w32api/include/wincrypt.h index 8e0f7779127..782371ff2fc 100644 --- a/reactos/w32api/include/wincrypt.h +++ b/reactos/w32api/include/wincrypt.h @@ -967,6 +967,8 @@ static const WCHAR CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH[] = #define CRYPT_UNICODE_NAME_DECODE_DISABLE_IE4_UTF8_FLAG \ CERT_RDN_DISABLE_IE4_UTF8_FLAG +#define CRYPT_GET_INSTALLED_OID_FUNC_FLAG 0x1 + /* types for CertOpenStore dwEncodingType */ #define CERT_ENCODING_TYPE_MASK 0x0000ffff #define CMSG_ENCODING_TYPE_MASK 0xffff0000 @@ -1699,6 +1701,16 @@ typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_SET_CTL_PROPERTY)( typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_CONTROL)(HCERTSTOREPROV hStoreProv, DWORD dwFlags, DWORD dwCtrlType, void const *pvCtrlPara); +typedef struct _CRYPT_OID_FUNC_ENTRY { + LPCSTR pszOID; + void *pvFuncAddr; +} CRYPT_OID_FUNC_ENTRY, *PCRYPT_OID_FUNC_ENTRY; + +typedef BOOL (WINAPI *PFN_CRYPT_ENUM_OID_FUNC)(DWORD dwEncodingType, + LPCSTR pszFuncName, LPCSTR pszOID, DWORD cValue, const DWORD rgdwValueType[], + LPCWSTR const rgpwszValueName[], const BYTE * const rgpbValueData[], + const DWORD rgcbValueData[], void *pvArg); + /* subject types for CryptVerifyCertificateSignatureEx */ #define CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB 1 #define CRYPT_VERIFY_CERT_SIGN_SUBJECT_CERT 2 @@ -1817,6 +1829,34 @@ BOOL WINAPI CryptSetProviderExW(LPCWSTR,DWORD,DWORD*,DWORD); BOOL WINAPI CryptEncodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo, BYTE *pbEncoded, DWORD *pcbEncoded); BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, void *pvEncoded, DWORD *pcbEncoded); +BOOL WINAPI CryptRegisterDefaultOIDFunction(DWORD,LPCSTR,DWORD,LPCWSTR); +BOOL WINAPI CryptRegisterOIDFunction(DWORD,LPCSTR,LPCSTR,LPCWSTR,LPCSTR); +BOOL WINAPI CryptGetOIDFunctionValue(DWORD dwEncodingType, LPCSTR pszFuncName, + LPCSTR pszOID, LPCWSTR szValueName, DWORD *pdwValueType, + BYTE *pbValueData, DWORD *pcbValueData); +BOOL WINAPI CryptSetOIDFunctionValue(DWORD dwEncodingType, LPCSTR pszFuncName, + LPCSTR pszOID, LPCWSTR pwszValueName, DWORD dwValueType, + const BYTE *pbValueData, DWORD cbValueData); +BOOL WINAPI CryptUnregisterDefaultOIDFunction(DWORD,LPCSTR,LPCWSTR); +BOOL WINAPI CryptUnregisterOIDFunction(DWORD,LPCSTR,LPCSTR); +BOOL WINAPI CryptEnumOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName, + LPCSTR pszOID, DWORD dwFlags, void *pvArg, + PFN_CRYPT_ENUM_OID_FUNC pfnEnumOIDFunc); +HCRYPTOIDFUNCSET WINAPI CryptInitOIDFunctionSet(LPCSTR,DWORD); +BOOL WINAPI CryptGetDefaultOIDDllList(HCRYPTOIDFUNCSET hFuncSet, + DWORD dwEncodingType, LPWSTR pwszDllList, DWORD *pcchDllList); +BOOL WINAPI CryptGetDefaultOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet, + DWORD dwEncodingType, LPCWSTR pwszDll, DWORD dwFlags, void *ppvFuncAddr, + HCRYPTOIDFUNCADDR *phFuncAddr); +BOOL WINAPI CryptGetOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet, + DWORD dwEncodingType, LPCSTR pszOID, DWORD dwFlags, void **ppvFuncAddr, + HCRYPTOIDFUNCADDR *phFuncAddr); +BOOL WINAPI CryptFreeOIDFunctionAddress(HCRYPTOIDFUNCADDR hFuncAddr, + DWORD dwFlags); +BOOL WINAPI CryptInstallOIDFunctionAddress(HMODULE hModule, + DWORD dwEncodingType, LPCSTR pszFuncName, DWORD cFuncEntry, + const CRYPT_OID_FUNC_ENTRY rgFuncEntry[], DWORD dwFlags); + #ifdef UNICODE #define CertNameToStr CertNameToStrW #define CryptAcquireContext CryptAcquireContextW