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);
CryptDestroyHash(hHash);
}
}
+ if (releaseProv)
+ CryptReleaseContext(hCryptProv, 0);
return ret;
}
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;
LocalFree(buf);
}
}
+ if (releaseProv)
+ CryptReleaseContext(hCryptProv, 0);
return ret;
}
DWORD dwCertEncodingType, const BYTE *pbEncoded, DWORD cbEncoded,
BYTE *pbComputedHash, DWORD *pcbComputedHash)
{
- BOOL ret;
+ BOOL ret, releaseProv = FALSE;
CERT_SIGNED_CONTENT_INFO *info;
DWORD size;
PCCRYPT_OID_INFO oidInfo;
HCRYPTHASH hHash;
- if (!hCryptProv)
- hCryptProv = CRYPT_GetDefaultProvider();
oidInfo = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
info->SignatureAlgorithm.pszObjId, 0);
if (!oidInfo)
}
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,
pcbComputedHash, 0);
CryptDestroyHash(hHash);
}
+ if (releaseProv)
+ CryptReleaseContext(hCryptProv, 0);
}
LocalFree(info);
}
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;
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,
pcbSignature, 0);
CryptDestroyHash(hHash);
}
+ if (releaseProv)
+ CryptReleaseContext(hCryptProv, 0);
}
else
{
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;
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)
}
CryptDestroyKey(key);
}
+ if (releaseProv)
+ CryptReleaseContext(hCryptProv, 0);
return ret;
}
*/
HCRYPTPROV CRYPT_GetDefaultProvider(void);
+HCRYPTPROV CRYPT_GetProvForAlgId(ALG_ID algID);
+
HINSTANCE hInstance;
void crypt_oid_init(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
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)
{