[Wine-patches] [2/2] crypt32: Use a provider which supports required algorithm (eterbug #5348).
Alexander Morozov
amorozov на etersoft.ru
Вт Апр 20 17:53:06 MSD 2010
----------- следующая часть -----------
From aa77d71daf22d36162bf4411d65a21103d1955d2 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Tue, 20 Apr 2010 16:52:44 +0400
Subject: [PATCH 2/2] crypt32: Use a provider which supports required algorithm (eterbug #5348).
---
dlls/crypt32/msg.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 70 insertions(+), 2 deletions(-)
diff --git a/dlls/crypt32/msg.c b/dlls/crypt32/msg.c
index a16eef1..bb89ae6 100644
--- a/dlls/crypt32/msg.c
+++ b/dlls/crypt32/msg.c
@@ -550,6 +550,71 @@ static BOOL CHashEncodeMsg_Update(HCRYPTMSG hCryptMsg, const BYTE *pbData,
return ret;
}
+static CRITICAL_SECTION prov_param_cs;
+static CRITICAL_SECTION_DEBUG prov_param_cs_debug =
+{
+ 0, 0, &prov_param_cs,
+ { &prov_param_cs_debug.ProcessLocksList,
+ &prov_param_cs_debug.ProcessLocksList },
+ 0, 0, { (DWORD_PTR)(__FILE__ ": prov_param_cs") }
+};
+static CRITICAL_SECTION prov_param_cs = { &prov_param_cs_debug, -1, 0, 0, 0, 0 };
+
+static BOOL CRYPT_AlgIsSupported(HCRYPTPROV hProv, ALG_ID algID)
+{
+ PROV_ENUMALGS provEnumalgs;
+ DWORD size = sizeof(provEnumalgs);
+
+ /* This enumeration is not thread safe */
+ EnterCriticalSection(&prov_param_cs);
+ if (CryptGetProvParam(hProv, PP_ENUMALGS, (BYTE *)&provEnumalgs, &size,
+ CRYPT_FIRST))
+ {
+ do {
+ if (algID == provEnumalgs.aiAlgid)
+ return TRUE;
+ } while (CryptGetProvParam(hProv, PP_ENUMALGS, (BYTE *)&provEnumalgs,
+ &size, CRYPT_NEXT));
+ }
+ LeaveCriticalSection(&prov_param_cs);
+ return FALSE;
+}
+
+static HCRYPTPROV CRYPT_GetProvForAlgId(ALG_ID algID)
+{
+ LPWSTR provName;
+ HCRYPTPROV prov;
+ DWORD i = 0, type, nameSize;
+
+ while (CryptEnumProvidersW(i, NULL, 0, &type, NULL, &nameSize))
+ {
+ provName = CryptMemAlloc(nameSize);
+ if (!provName)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return 0;
+ }
+ if (!CryptEnumProvidersW(i, NULL, 0, &type, provName, &nameSize))
+ {
+ CryptMemFree(provName);
+ return 0;
+ }
+ if (!CryptAcquireContextW(&prov, NULL, provName, type,
+ CRYPT_VERIFYCONTEXT))
+ {
+ CryptMemFree(provName);
+ return 0;
+ }
+ CryptMemFree(provName);
+ if (CRYPT_AlgIsSupported(prov, algID))
+ return prov;
+ CryptReleaseContext(prov, 0);
+ ++i;
+ }
+ SetLastError(NTE_BAD_ALGID);
+ return 0;
+}
+
static HCRYPTMSG CHashEncodeMsg_Open(DWORD dwFlags, const void *pvMsgEncodeInfo,
LPSTR pszInnerContentObjID, PCMSG_STREAM_INFO pStreamInfo)
{
@@ -572,8 +637,9 @@ static HCRYPTMSG CHashEncodeMsg_Open(DWORD dwFlags, const void *pvMsgEncodeInfo,
prov = info->hCryptProv;
else
{
- prov = CRYPT_GetDefaultProvider();
- dwFlags &= ~CMSG_CRYPT_RELEASE_CONTEXT_FLAG;
+ prov = CRYPT_GetProvForAlgId(algID);
+ if (!prov) return NULL;
+ dwFlags |= CMSG_CRYPT_RELEASE_CONTEXT_FLAG;
}
msg = CryptMemAlloc(sizeof(CHashEncodeMsg));
if (msg)
@@ -590,6 +656,8 @@ static HCRYPTMSG CHashEncodeMsg_Open(DWORD dwFlags, const void *pvMsgEncodeInfo,
msg = NULL;
}
}
+ else if (dwFlags & CMSG_CRYPT_RELEASE_CONTEXT_FLAG)
+ CryptReleaseContext(prov, 0);
return msg;
}
--
1.6.5.8
Подробная информация о списке рассылки Wine-patches