[Wine-patches] [eter-1.0.12 3/3] crypt32: Find a provider for used algorithm (eterbug #5665).
Alexander Morozov
amorozov на etersoft.ru
Чт Июн 24 17:50:54 MSD 2010
----------- следующая часть -----------
From 282037871a29ae439a121c380abf264c721c5dad Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Thu, 24 Jun 2010 15:44:32 +0400
Subject: [eter-1.0.12 3/3] crypt32: Find a provider for used algorithm (eterbug #5665).
---
dlls/crypt32/cert.c | 67 ++++++++++++++++++++++++++++---------
dlls/crypt32/crypt32_private.h | 2 +
dlls/crypt32/main.c | 71 ++++++++++++++++++++++++++++++++++++++++
dlls/crypt32/msg.c | 65 ------------------------------------
4 files changed, 124 insertions(+), 81 deletions(-)
diff --git a/dlls/crypt32/cert.c b/dlls/crypt32/cert.c
index 2780cba..9e25413 100644
--- a/dlls/crypt32/cert.c
+++ b/dlls/crypt32/cert.c
@@ -1742,16 +1742,20 @@ BOOL WINAPI CryptHashCertificate(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid,
DWORD dwFlags, const BYTE *pbEncoded, DWORD cbEncoded, BYTE *pbComputedHash,
DWORD *pcbComputedHash)
{
- BOOL ret = TRUE;
+ BOOL ret = TRUE, releaseProv = FALSE;
HCRYPTHASH hHash = 0;
TRACE("(%08lx, %d, %08x, %p, %d, %p, %p)\n", hCryptProv, Algid, dwFlags,
pbEncoded, cbEncoded, pbComputedHash, pcbComputedHash);
- if (!hCryptProv)
- hCryptProv = CRYPT_GetDefaultProvider();
if (!Algid)
Algid = CALG_SHA1;
+ if (!hCryptProv)
+ {
+ hCryptProv = CRYPT_GetProvForAlgId(Algid);
+ if (!hCryptProv) return FALSE;
+ releaseProv = TRUE;
+ }
if (ret)
{
ret = CryptCreateHash(hCryptProv, Algid, 0, 0, &hHash);
@@ -1764,6 +1768,8 @@ BOOL WINAPI CryptHashCertificate(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid,
CryptDestroyHash(hHash);
}
}
+ if (releaseProv)
+ CryptReleaseContext(hCryptProv, 0);
return ret;
}
@@ -1771,16 +1777,20 @@ BOOL WINAPI CryptHashPublicKeyInfo(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid,
DWORD dwFlags, DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo,
BYTE *pbComputedHash, DWORD *pcbComputedHash)
{
- BOOL ret = TRUE;
+ BOOL ret = TRUE, releaseProv = FALSE;
HCRYPTHASH hHash = 0;
TRACE("(%08lx, %d, %08x, %d, %p, %p, %p)\n", hCryptProv, Algid, dwFlags,
dwCertEncodingType, pInfo, pbComputedHash, pcbComputedHash);
- if (!hCryptProv)
- hCryptProv = CRYPT_GetDefaultProvider();
if (!Algid)
Algid = CALG_MD5;
+ if (!hCryptProv)
+ {
+ hCryptProv = CRYPT_GetProvForAlgId(Algid);
+ if (!hCryptProv) return FALSE;
+ releaseProv = TRUE;
+ }
if (ret)
{
BYTE *buf;
@@ -1802,6 +1812,8 @@ BOOL WINAPI CryptHashPublicKeyInfo(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid,
LocalFree(buf);
}
}
+ if (releaseProv)
+ CryptReleaseContext(hCryptProv, 0);
return ret;
}
@@ -1809,7 +1821,7 @@ BOOL WINAPI CryptHashToBeSigned(HCRYPTPROV_LEGACY hCryptProv,
DWORD dwCertEncodingType, const BYTE *pbEncoded, DWORD cbEncoded,
BYTE *pbComputedHash, DWORD *pcbComputedHash)
{
- BOOL ret;
+ BOOL ret, releaseProv = FALSE;
CERT_SIGNED_CONTENT_INFO *info;
DWORD size;
@@ -1823,8 +1835,6 @@ BOOL WINAPI CryptHashToBeSigned(HCRYPTPROV_LEGACY hCryptProv,
PCCRYPT_OID_INFO oidInfo;
HCRYPTHASH hHash;
- if (!hCryptProv)
- hCryptProv = CRYPT_GetDefaultProvider();
oidInfo = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
info->SignatureAlgorithm.pszObjId, 0);
if (!oidInfo)
@@ -1834,7 +1844,16 @@ BOOL WINAPI CryptHashToBeSigned(HCRYPTPROV_LEGACY hCryptProv,
}
else
{
- ret = CryptCreateHash(hCryptProv, oidInfo->u.Algid, 0, 0, &hHash);
+ if (!hCryptProv)
+ {
+ hCryptProv = CRYPT_GetProvForAlgId(oidInfo->u.Algid);
+ if (hCryptProv)
+ releaseProv = TRUE;
+ else
+ ret = FALSE;
+ }
+ if (ret)
+ ret = CryptCreateHash(hCryptProv, oidInfo->u.Algid, 0, 0, &hHash);
if (ret)
{
ret = CryptHashData(hHash, info->ToBeSigned.pbData,
@@ -1844,6 +1863,8 @@ BOOL WINAPI CryptHashToBeSigned(HCRYPTPROV_LEGACY hCryptProv,
pcbComputedHash, 0);
CryptDestroyHash(hHash);
}
+ if (releaseProv)
+ CryptReleaseContext(hCryptProv, 0);
}
LocalFree(info);
}
@@ -1855,7 +1876,7 @@ BOOL WINAPI CryptSignCertificate(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv,
DWORD cbEncodedToBeSigned, PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm,
const void *pvHashAuxInfo, BYTE *pbSignature, DWORD *pcbSignature)
{
- BOOL ret;
+ BOOL ret = TRUE, releaseProv = FALSE;
PCCRYPT_OID_INFO info;
HCRYPTHASH hHash;
@@ -1873,8 +1894,15 @@ BOOL WINAPI CryptSignCertificate(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv,
if (info->dwGroupId == CRYPT_HASH_ALG_OID_GROUP_ID)
{
if (!hCryptProv)
- hCryptProv = CRYPT_GetDefaultProvider();
- ret = CryptCreateHash(hCryptProv, info->u.Algid, 0, 0, &hHash);
+ {
+ hCryptProv = CRYPT_GetProvForAlgId(info->u.Algid);
+ if (hCryptProv)
+ releaseProv = TRUE;
+ else
+ ret = FALSE;
+ }
+ if (ret)
+ ret = CryptCreateHash(hCryptProv, info->u.Algid, 0, 0, &hHash);
if (ret)
{
ret = CryptHashData(hHash, pbEncodedToBeSigned,
@@ -1884,6 +1912,8 @@ BOOL WINAPI CryptSignCertificate(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv,
pcbSignature, 0);
CryptDestroyHash(hHash);
}
+ if (releaseProv)
+ CryptReleaseContext(hCryptProv, 0);
}
else
{
@@ -1983,7 +2013,7 @@ static BOOL CRYPT_VerifyCertSignatureFromPublicKeyInfo(HCRYPTPROV_LEGACY hCryptP
DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pubKeyInfo,
const CERT_SIGNED_CONTENT_INFO *signedCert)
{
- BOOL ret;
+ BOOL ret, releaseProv = FALSE;
HCRYPTKEY key;
PCCRYPT_OID_INFO info;
ALG_ID pubKeyID, hashID;
@@ -2000,9 +2030,12 @@ static BOOL CRYPT_VerifyCertSignatureFromPublicKeyInfo(HCRYPTPROV_LEGACY hCryptP
pubKeyID = *(ALG_ID *)info->ExtraInfo.pbData;
else
pubKeyID = hashID;
- /* Load the default provider if necessary */
if (!hCryptProv)
- hCryptProv = CRYPT_GetDefaultProvider();
+ {
+ hCryptProv = CRYPT_GetProvForAlgId(pubKeyID);
+ if (!hCryptProv) return FALSE;
+ releaseProv = TRUE;
+ }
ret = CryptImportPublicKeyInfoEx(hCryptProv, dwCertEncodingType,
pubKeyInfo, pubKeyID, 0, NULL, &key);
if (ret)
@@ -2021,6 +2054,8 @@ static BOOL CRYPT_VerifyCertSignatureFromPublicKeyInfo(HCRYPTPROV_LEGACY hCryptP
}
CryptDestroyKey(key);
}
+ if (releaseProv)
+ CryptReleaseContext(hCryptProv, 0);
return ret;
}
diff --git a/dlls/crypt32/crypt32_private.h b/dlls/crypt32/crypt32_private.h
index 46d4797..f6fe119 100644
--- a/dlls/crypt32/crypt32_private.h
+++ b/dlls/crypt32/crypt32_private.h
@@ -123,6 +123,8 @@ BOOL CRYPT_AsnDecodePKCSDigestedData(const BYTE *pbEncoded, DWORD cbEncoded,
*/
HCRYPTPROV CRYPT_GetDefaultProvider(void);
+HCRYPTPROV CRYPT_GetProvForAlgId(ALG_ID algID);
+
HINSTANCE hInstance;
void crypt_oid_init(void);
diff --git a/dlls/crypt32/main.c b/dlls/crypt32/main.c
index d93163c..c38dd52 100644
--- a/dlls/crypt32/main.c
+++ b/dlls/crypt32/main.c
@@ -74,6 +74,77 @@ HCRYPTPROV CRYPT_GetDefaultProvider(void)
return hDefProv;
}
+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;
+}
+
+HCRYPTPROV CRYPT_GetProvForAlgId(ALG_ID algID)
+{
+ LPWSTR provName;
+ HCRYPTPROV prov;
+ DWORD i = 0, type, nameSize;
+
+ if (CRYPT_AlgIsSupported(hDefProv, algID))
+ {
+ CryptContextAddRef(hDefProv, NULL, 0);
+ return hDefProv;
+ }
+
+ 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;
+}
+
typedef void * HLRUCACHE;
/* this function is called by Internet Explorer when it is about to verify a
diff --git a/dlls/crypt32/msg.c b/dlls/crypt32/msg.c
index bb89ae6..8851de2 100644
--- a/dlls/crypt32/msg.c
+++ b/dlls/crypt32/msg.c
@@ -550,71 +550,6 @@ 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)
{
--
1.6.5.8
Подробная информация о списке рассылки Wine-patches