Commit f8b25614 authored by Juan Lang's avatar Juan Lang Committed by Alexandre Julliard

Use registered DLLs for encode/decode.

parent e3406b87
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(crypt); WINE_DEFAULT_DEBUG_CHANNEL(crypt);
static const WCHAR szDllName[] = { 'D','l','l',0 };
static char *CRYPT_GetKeyName(DWORD dwEncodingType, LPCSTR pszFuncName, static char *CRYPT_GetKeyName(DWORD dwEncodingType, LPCSTR pszFuncName,
LPCSTR pszOID) LPCSTR pszOID)
{ {
...@@ -65,17 +67,14 @@ BOOL WINAPI CryptRegisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName, ...@@ -65,17 +67,14 @@ BOOL WINAPI CryptRegisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName,
LPCSTR pszOID, LPCWSTR pwszDll, LPCSTR pszOverrideFuncName) LPCSTR pszOID, LPCWSTR pwszDll, LPCSTR pszOverrideFuncName)
{ {
LONG r; LONG r;
static const WCHAR szDllName[] = { 'D','l','l',0 };
HKEY hKey; HKEY hKey;
LPSTR szKey; LPSTR szKey;
TRACE("%lx %s %s %s %s\n", dwEncodingType, pszFuncName, pszOID, TRACE("%lx %s %s %s %s\n", dwEncodingType, pszFuncName, pszOID,
debugstr_w(pwszDll), pszOverrideFuncName); debugstr_w(pwszDll), pszOverrideFuncName);
/* MSDN states dwEncodingType is a mask, but it isn't really treated as /* This only registers functions for encoding certs, not messages */
* such. Values 65536 or greater are ignored. if (!GET_CERT_ENCODING_TYPE(dwEncodingType))
*/
if (dwEncodingType >= PKCS_7_ASN_ENCODING)
return TRUE; return TRUE;
/* I'm not matching MS bug for bug here, because I doubt any app depends on /* I'm not matching MS bug for bug here, because I doubt any app depends on
...@@ -122,7 +121,7 @@ BOOL WINAPI CryptUnregisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName, ...@@ -122,7 +121,7 @@ BOOL WINAPI CryptUnregisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName,
TRACE("%lx %s %s\n", dwEncodingType, pszFuncName, pszOID); TRACE("%lx %s %s\n", dwEncodingType, pszFuncName, pszOID);
if (dwEncodingType >= PKCS_7_ASN_ENCODING) if (!GET_CERT_ENCODING_TYPE(dwEncodingType))
return TRUE; return TRUE;
if (!pszFuncName || !pszOID) if (!pszFuncName || !pszOID)
...@@ -138,44 +137,231 @@ BOOL WINAPI CryptUnregisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName, ...@@ -138,44 +137,231 @@ BOOL WINAPI CryptUnregisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName,
return rc ? FALSE : TRUE; 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;
*lib = NULL;
r = RegOpenKeyA(HKEY_LOCAL_MACHINE, szKey, &hKey);
HeapFree(GetProcessHeap(), 0, szKey);
if(r != ERROR_SUCCESS)
return NULL;
RegQueryValueExA(hKey, "FuncName", NULL, &type, NULL, &size);
if (GetLastError() == ERROR_MORE_DATA && type == REG_SZ)
{
funcName = HeapAlloc(GetProcessHeap(), 0, 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 = HeapAlloc(GetProcessHeap(), 0, 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;
}
}
HeapFree(GetProcessHeap(), 0, dllName);
}
if (funcName != szFuncName)
HeapFree(GetProcessHeap(), 0, (char *)funcName);
return ret;
}
typedef BOOL (WINAPI *CryptEncodeObjectFunc)(DWORD, LPCSTR, const void *,
BYTE *, DWORD *);
BOOL WINAPI CryptEncodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType, BOOL WINAPI CryptEncodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType,
const void *pvStructInfo, BYTE *pbEncoded, DWORD *pcbEncoded) const void *pvStructInfo, BYTE *pbEncoded, DWORD *pcbEncoded)
{ {
FIXME("(0x%08lx, %s, %p, %p, %p): stub\n", BOOL ret = FALSE;
HMODULE lib;
CryptEncodeObjectFunc pCryptEncodeObject;
TRACE("(0x%08lx, %s, %p, %p, %p)\n",
dwCertEncodingType, HIWORD(lpszStructType) ? debugstr_a(lpszStructType) : dwCertEncodingType, HIWORD(lpszStructType) ? debugstr_a(lpszStructType) :
"(integer value)", pvStructInfo, pbEncoded, pcbEncoded); "(integer value)", pvStructInfo, pbEncoded, pcbEncoded);
if (!pbEncoded && !pcbEncoded)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
}
/* Try registered DLL first.. */
pCryptEncodeObject =
(CryptEncodeObjectFunc)CRYPT_GetFunc(dwCertEncodingType,
lpszStructType, "CryptEncodeObject", &lib);
if (pCryptEncodeObject)
{
ret = pCryptEncodeObject(dwCertEncodingType, lpszStructType,
pvStructInfo, pbEncoded, pcbEncoded);
FreeLibrary(lib);
}
else
{
/* If not, use CryptEncodeObjectEx */
ret = CryptEncodeObjectEx(dwCertEncodingType, lpszStructType,
pvStructInfo, 0, NULL, pbEncoded, pcbEncoded);
}
return ret;
} }
typedef BOOL (WINAPI *CryptEncodeObjectExFunc)(DWORD, LPCSTR, const void *,
DWORD, PCRYPT_ENCODE_PARA, BYTE *, DWORD *);
BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
const void *pvStructInfo, DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, const void *pvStructInfo, DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara,
BYTE *pbEncoded, DWORD *pcbEncoded) BYTE *pbEncoded, DWORD *pcbEncoded)
{ {
BOOL ret = FALSE, encoded = FALSE;
FIXME("(0x%08lx, %s, %p, 0x%08lx, %p, %p, %p): stub\n", FIXME("(0x%08lx, %s, %p, 0x%08lx, %p, %p, %p): stub\n",
dwCertEncodingType, HIWORD(lpszStructType) ? debugstr_a(lpszStructType) : dwCertEncodingType, HIWORD(lpszStructType) ? debugstr_a(lpszStructType) :
"(integer value)", pvStructInfo, dwFlags, pEncodePara, pbEncoded, "(integer value)", pvStructInfo, dwFlags, pEncodePara, pbEncoded,
pcbEncoded); pcbEncoded);
if (!pbEncoded && !pcbEncoded)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
}
if (!HIWORD(lpszStructType))
{
switch (LOWORD(lpszStructType))
{
default:
FIXME("%d: unimplemented\n", LOWORD(lpszStructType));
}
}
if (!encoded)
{
HMODULE lib;
CryptEncodeObjectExFunc pCryptEncodeObjectEx =
(CryptEncodeObjectExFunc)CRYPT_GetFunc(dwCertEncodingType,
lpszStructType, "CryptEncodeObjectEx", &lib);
if (pCryptEncodeObjectEx)
{
ret = pCryptEncodeObjectEx(dwCertEncodingType, lpszStructType,
pvStructInfo, dwFlags, pEncodePara, pbEncoded, pcbEncoded);
FreeLibrary(lib);
}
}
return ret;
} }
typedef BOOL (WINAPI *CryptDecodeObjectFunc)(DWORD, LPCSTR, const BYTE *,
DWORD, DWORD, void *, DWORD *);
BOOL WINAPI CryptDecodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType, BOOL WINAPI CryptDecodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType,
const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
DWORD *pcbStructInfo) DWORD *pcbStructInfo)
{ {
FIXME("(0x%08lx, %s, %p, %ld, 0x%08lx, %p, %p): stub\n", BOOL ret = FALSE;
HMODULE lib;
CryptDecodeObjectFunc pCryptDecodeObject;
TRACE("(0x%08lx, %s, %p, %ld, 0x%08lx, %p, %p)\n",
dwCertEncodingType, HIWORD(lpszStructType) ? debugstr_a(lpszStructType) : dwCertEncodingType, HIWORD(lpszStructType) ? debugstr_a(lpszStructType) :
"(integer value)", pbEncoded, cbEncoded, dwFlags, pvStructInfo, "(integer value)", pbEncoded, cbEncoded, dwFlags, pvStructInfo,
pcbStructInfo); pcbStructInfo);
if (!pvStructInfo && !pcbStructInfo)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
}
/* Try registered DLL first.. */
pCryptDecodeObject =
(CryptDecodeObjectFunc)CRYPT_GetFunc(dwCertEncodingType,
lpszStructType, "CryptDecodeObject", &lib);
if (pCryptDecodeObject)
{
ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
FreeLibrary(lib);
}
else
{
/* If not, use CryptDecodeObjectEx */
ret = CryptDecodeObjectEx(dwCertEncodingType, lpszStructType, pbEncoded,
cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo);
}
return ret;
} }
typedef BOOL (WINAPI *CryptDecodeObjectExFunc)(DWORD, LPCSTR, const BYTE *,
DWORD, DWORD, PCRYPT_DECODE_PARA, void *, DWORD *);
BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{ {
BOOL ret = FALSE, decoded = FALSE;
FIXME("(0x%08lx, %s, %p, %ld, 0x%08lx, %p, %p, %p): stub\n", FIXME("(0x%08lx, %s, %p, %ld, 0x%08lx, %p, %p, %p): stub\n",
dwCertEncodingType, HIWORD(lpszStructType) ? debugstr_a(lpszStructType) : dwCertEncodingType, HIWORD(lpszStructType) ? debugstr_a(lpszStructType) :
"(integer value)", pbEncoded, cbEncoded, dwFlags, pDecodePara, "(integer value)", pbEncoded, cbEncoded, dwFlags, pDecodePara,
pvStructInfo, pcbStructInfo); pvStructInfo, pcbStructInfo);
if (!pvStructInfo && !pcbStructInfo)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
}
if (!HIWORD(lpszStructType))
{
switch (LOWORD(lpszStructType))
{
default:
FIXME("%d: unimplemented\n", LOWORD(lpszStructType));
}
}
if (!decoded)
{
HMODULE lib;
CryptDecodeObjectExFunc pCryptDecodeObjectEx =
(CryptDecodeObjectExFunc)CRYPT_GetFunc(dwCertEncodingType,
lpszStructType, "CryptDecodeObjectEx", &lib);
if (pCryptDecodeObjectEx)
{
ret = pCryptDecodeObjectEx(dwCertEncodingType, lpszStructType,
pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
pcbStructInfo);
FreeLibrary(lib);
}
}
return ret;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment