https://git.reactos.org/?p=reactos.git;a=commitdiff;h=b1b70ef9edbf71facc1c4…
commit b1b70ef9edbf71facc1c430a6e84a71e01d94559
Author: Amine Khaldi <amine.khaldi(a)reactos.org>
AuthorDate: Fri Jan 25 13:19:03 2019 +0100
Commit: Amine Khaldi <amine.khaldi(a)reactos.org>
CommitDate: Fri Jan 25 13:19:03 2019 +0100
[CRYPT32] Sync with Wine Staging 4.0. CORE-15682
---
dll/win32/crypt32/cert.c | 100 +++++++-----
dll/win32/crypt32/crypt32.spec | 3 +-
dll/win32/crypt32/crypt32_private.h | 3 +-
dll/win32/crypt32/decode.c | 48 +-----
dll/win32/crypt32/encode.c | 125 +++++++++++++--
dll/win32/crypt32/main.c | 75 ++++++++-
dll/win32/crypt32/msg.c | 58 ++++---
dll/win32/crypt32/oid.c | 297 +++++++++++++++++++++++++++++++++++-
media/doc/README.WINE | 2 +-
9 files changed, 584 insertions(+), 127 deletions(-)
diff --git a/dll/win32/crypt32/cert.c b/dll/win32/crypt32/cert.c
index 0088f006d3..0065ba69d4 100644
--- a/dll/win32/crypt32/cert.c
+++ b/dll/win32/crypt32/cert.c
@@ -28,6 +28,7 @@
#include "wine/winternl.h"
#define CRYPT_OID_INFO_HAS_EXTRA_FIELDS
#include "wincrypt.h"
+#include "snmp.h"
#include "bcrypt.h"
#include "winnls.h"
#include "rpc.h"
@@ -532,14 +533,19 @@ void CRYPT_FixKeyProvInfoPointers(PCRYPT_KEY_PROV_INFO info)
provNameLen = (lstrlenW(info->pwszProvName) + 1) * sizeof(WCHAR);
data += provNameLen;
- info->rgProvParam = (PCRYPT_KEY_PROV_PARAM)data;
- data += info->cProvParam * sizeof(CRYPT_KEY_PROV_PARAM);
-
- for (i = 0; i < info->cProvParam; i++)
+ if (info->cProvParam)
{
- info->rgProvParam[i].pbData = data;
- data += info->rgProvParam[i].cbData;
+ info->rgProvParam = (PCRYPT_KEY_PROV_PARAM)data;
+ data += info->cProvParam * sizeof(CRYPT_KEY_PROV_PARAM);
+
+ for (i = 0; i < info->cProvParam; i++)
+ {
+ info->rgProvParam[i].pbData = data;
+ data += info->rgProvParam[i].cbData;
+ }
}
+ else
+ info->rgProvParam = NULL;
}
BOOL WINAPI CertGetCertificateContextProperty(PCCERT_CONTEXT pCertContext,
@@ -1242,6 +1248,12 @@ BOOL WINAPI CertComparePublicKeyInfo(DWORD dwCertEncodingType,
TRACE("(%08x, %p, %p)\n", dwCertEncodingType, pPublicKey1, pPublicKey2);
+ /* RSA public key data should start with ASN_SEQUENCE,
+ * otherwise it's not a RSA_CSP_PUBLICKEYBLOB.
+ */
+ if (!pPublicKey1->PublicKey.cbData || pPublicKey1->PublicKey.pbData[0] !=
ASN_SEQUENCE)
+ dwCertEncodingType = 0;
+
switch (GET_CERT_ENCODING_TYPE(dwCertEncodingType))
{
case 0: /* Seems to mean "raw binary bits" */
@@ -1267,32 +1279,21 @@ BOOL WINAPI CertComparePublicKeyInfo(DWORD dwCertEncodingType,
ret = FALSE;
if (CryptDecodeObject(dwCertEncodingType, RSA_CSP_PUBLICKEYBLOB,
pPublicKey1->PublicKey.pbData, pPublicKey1->PublicKey.cbData,
- 0, NULL, &length))
+ CRYPT_DECODE_ALLOC_FLAG, &pblob1, &length))
{
- pblob1 = CryptMemAlloc(length);
if (CryptDecodeObject(dwCertEncodingType, RSA_CSP_PUBLICKEYBLOB,
- pPublicKey1->PublicKey.pbData, pPublicKey1->PublicKey.cbData,
- 0, pblob1, &length))
+ pPublicKey2->PublicKey.pbData,
pPublicKey2->PublicKey.cbData,
+ CRYPT_DECODE_ALLOC_FLAG, &pblob2, &length))
{
- if (CryptDecodeObject(dwCertEncodingType, RSA_CSP_PUBLICKEYBLOB,
- pPublicKey2->PublicKey.pbData,
pPublicKey2->PublicKey.cbData,
- 0, NULL, &length))
- {
- pblob2 = CryptMemAlloc(length);
- if (CryptDecodeObject(dwCertEncodingType, RSA_CSP_PUBLICKEYBLOB,
- pPublicKey2->PublicKey.pbData,
pPublicKey2->PublicKey.cbData,
- 0, pblob2, &length))
- {
- /* The RSAPUBKEY structure directly follows the BLOBHEADER */
- RSAPUBKEY *pk1 = (LPVOID)(pblob1 + 1),
- *pk2 = (LPVOID)(pblob2 + 1);
- ret = (pk1->bitlen == pk2->bitlen) &&
(pk1->pubexp == pk2->pubexp)
- && !memcmp(pk1 + 1, pk2 + 1, pk1->bitlen/8);
- }
- CryptMemFree(pblob2);
- }
+ /* The RSAPUBKEY structure directly follows the BLOBHEADER */
+ RSAPUBKEY *pk1 = (LPVOID)(pblob1 + 1),
+ *pk2 = (LPVOID)(pblob2 + 1);
+ ret = (pk1->bitlen == pk2->bitlen) && (pk1->pubexp ==
pk2->pubexp)
+ && !memcmp(pk1 + 1, pk2 + 1, pk1->bitlen/8);
+
+ LocalFree(pblob2);
}
- CryptMemFree(pblob1);
+ LocalFree(pblob1);
}
break;
@@ -1321,9 +1322,30 @@ DWORD WINAPI CertGetPublicKeyLength(DWORD dwCertEncodingType,
}
else
{
+ PCCRYPT_OID_INFO info;
DWORD size;
PBYTE buf;
- BOOL ret = CryptDecodeObjectEx(dwCertEncodingType,
+ BOOL ret;
+
+ info = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
pPublicKey->Algorithm.pszObjId, 0);
+ if (info)
+ {
+ HCRYPTKEY key;
+
+ TRACE("public key algid %#x (%s)\n", info->u.Algid,
debugstr_a(pPublicKey->Algorithm.pszObjId));
+
+ ret = CryptImportPublicKeyInfo(I_CryptGetDefaultCryptProv(info->u.Algid),
dwCertEncodingType, pPublicKey, &key);
+ if (ret)
+ {
+ size = sizeof(len);
+ ret = CryptGetKeyParam(key, KP_KEYLEN, (BYTE *)&len, &size, 0);
+ CryptDestroyKey(key);
+ return len;
+ }
+ /* fallback to RSA */
+ }
+
+ ret = CryptDecodeObjectEx(dwCertEncodingType,
RSA_CSP_PUBLICKEYBLOB, pPublicKey->PublicKey.pbData,
pPublicKey->PublicKey.cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
&size);
@@ -1794,7 +1816,7 @@ PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE
hCertStore,
}
if (find)
- ret = find(hCertStore, dwFlags, dwType, pvPara, pPrevCertContext);
+ ret = find(hCertStore, dwType, dwFlags, pvPara, pPrevCertContext);
else if (compare)
ret = cert_compare_certs_in_store(hCertStore, pPrevCertContext,
compare, dwType, dwFlags, pvPara);
@@ -2173,7 +2195,7 @@ BOOL WINAPI CryptHashCertificate(HCRYPTPROV_LEGACY hCryptProv,
ALG_ID Algid,
pbEncoded, cbEncoded, pbComputedHash, pcbComputedHash);
if (!hCryptProv)
- hCryptProv = CRYPT_GetDefaultProvider();
+ hCryptProv = I_CryptGetDefaultCryptProv(0);
if (!Algid)
Algid = CALG_SHA1;
if (ret)
@@ -2202,7 +2224,7 @@ BOOL WINAPI CryptHashPublicKeyInfo(HCRYPTPROV_LEGACY hCryptProv,
ALG_ID Algid,
dwCertEncodingType, pInfo, pbComputedHash, pcbComputedHash);
if (!hCryptProv)
- hCryptProv = CRYPT_GetDefaultProvider();
+ hCryptProv = I_CryptGetDefaultCryptProv(0);
if (!Algid)
Algid = CALG_MD5;
if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING)
@@ -2254,7 +2276,7 @@ BOOL WINAPI CryptHashToBeSigned(HCRYPTPROV_LEGACY hCryptProv,
HCRYPTHASH hHash;
if (!hCryptProv)
- hCryptProv = CRYPT_GetDefaultProvider();
+ hCryptProv = I_CryptGetDefaultCryptProv(0);
oidInfo = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
info->SignatureAlgorithm.pszObjId, 0);
if (!oidInfo)
@@ -2303,7 +2325,7 @@ BOOL WINAPI CryptSignCertificate(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE
hCryptProv,
if (info->dwGroupId == CRYPT_HASH_ALG_OID_GROUP_ID)
{
if (!hCryptProv)
- hCryptProv = CRYPT_GetDefaultProvider();
+ hCryptProv = I_CryptGetDefaultCryptProv(0);
ret = CryptCreateHash(hCryptProv, info->u.Algid, 0, 0, &hHash);
if (ret)
{
@@ -2427,7 +2449,7 @@ static BOOL CRYPT_VerifySignature(HCRYPTPROV_LEGACY hCryptProv,
DWORD dwCertEnco
pubKeyID = hashID;
/* Load the default provider if necessary */
if (!hCryptProv)
- hCryptProv = CRYPT_GetDefaultProvider();
+ hCryptProv = I_CryptGetDefaultCryptProv(0);
ret = CryptImportPublicKeyInfoEx(hCryptProv, dwCertEncodingType,
pubKeyInfo, pubKeyID, 0, NULL, &key);
if (ret)
@@ -3685,3 +3707,11 @@ const void * WINAPI CertCreateContext(DWORD dwContextType, DWORD
dwEncodingType,
return NULL;
}
}
+
+BOOL WINAPI CryptSetKeyIdentifierProperty(const CRYPT_HASH_BLOB *pKeyIdentifier, DWORD
dwPropId,
+ DWORD dwFlags, LPCWSTR pwszComputerName, void *pvReserved, const void *pvData)
+{
+ FIXME("(%p, 0x%x, 0x%x, %s, %p, %p): stub\n", pKeyIdentifier, dwPropId,
dwFlags,
+ debugstr_w(pwszComputerName), pvReserved, pvData);
+ return FALSE;
+}
diff --git a/dll/win32/crypt32/crypt32.spec b/dll/win32/crypt32/crypt32.spec
index 0bc78a158d..fc32570b52 100644
--- a/dll/win32/crypt32/crypt32.spec
+++ b/dll/win32/crypt32/crypt32.spec
@@ -180,6 +180,7 @@
@ stdcall CryptSIPRetrieveSubjectGuidForCatalogFile(wstr long ptr)
@ stdcall CryptSIPVerifyIndirectData(ptr ptr)
@ stub CryptSetAsyncParam
+@ stdcall CryptSetKeyIdentifierProperty(ptr long long wstr ptr ptr)
@ stdcall CryptSetOIDFunctionValue(long str str wstr long ptr long)
@ stub CryptSetProviderU
@ stdcall CryptSignAndEncodeCertificate(long long long str ptr ptr ptr ptr ptr)
@@ -194,7 +195,7 @@
@ stdcall CryptUnprotectMemory(ptr long long)
@ stdcall CryptUnregisterDefaultOIDFunction(long str wstr)
@ stdcall CryptUnregisterOIDFunction(long str str)
-@ stub CryptUnregisterOIDInfo
+@ stdcall CryptUnregisterOIDInfo(ptr)
@ stdcall CryptVerifyCertificateSignature(long long ptr long ptr)
@ stdcall CryptVerifyCertificateSignatureEx(long long long ptr long ptr long ptr)
@ stdcall CryptVerifyDetachedMessageHash(ptr ptr long long ptr ptr ptr ptr)
diff --git a/dll/win32/crypt32/crypt32_private.h b/dll/win32/crypt32/crypt32_private.h
index e58db989b7..ac70fe04f8 100644
--- a/dll/win32/crypt32/crypt32_private.h
+++ b/dll/win32/crypt32/crypt32_private.h
@@ -116,6 +116,7 @@ typedef struct _CRYPT_SIGNED_INFO
CRYPT_CONTENT_INFO content;
DWORD cSignerInfo;
PCMSG_CMS_SIGNER_INFO rgSignerInfo;
+ PDWORD signerKeySpec;
} CRYPT_SIGNED_INFO;
BOOL CRYPT_AsnEncodeCMSSignedInfo(CRYPT_SIGNED_INFO *, void *pvData,
@@ -149,7 +150,7 @@ BOOL WINAPI CRYPT_AsnEncodePubKeyInfoNoNull(DWORD dwCertEncodingType,
/* Returns a handle to the default crypto provider; loads it if necessary.
* Returns NULL on failure.
*/
-HCRYPTPROV CRYPT_GetDefaultProvider(void) DECLSPEC_HIDDEN;
+HCRYPTPROV WINAPI I_CryptGetDefaultCryptProv(ALG_ID);
HINSTANCE hInstance DECLSPEC_HIDDEN;
diff --git a/dll/win32/crypt32/decode.c b/dll/win32/crypt32/decode.c
index f77393eced..6f51632dce 100644
--- a/dll/win32/crypt32/decode.c
+++ b/dll/win32/crypt32/decode.c
@@ -215,7 +215,7 @@ static BOOL CRYPT_DecodeEnsureSpace(DWORD dwFlags,
if (pDecodePara && pDecodePara->pfnAlloc)
*(BYTE **)pvStructInfo = pDecodePara->pfnAlloc(bytesNeeded);
else
- *(BYTE **)pvStructInfo = LocalAlloc(0, bytesNeeded);
+ *(BYTE **)pvStructInfo = LocalAlloc(LPTR, bytesNeeded);
if (!*(BYTE **)pvStructInfo)
ret = FALSE;
else
@@ -1550,7 +1550,7 @@ static BOOL CRYPT_AsnDecodeNameValueInternal(const BYTE *pbEncoded,
case ASN_UTF8STRING:
valueType = CERT_RDN_UTF8_STRING;
bytesNeeded += MultiByteToWideChar(CP_UTF8, 0,
- (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * 2;
+ (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * sizeof(WCHAR);
break;
default:
SetLastError(CRYPT_E_ASN1_BADTAG);
@@ -6279,48 +6279,8 @@ BOOL WINAPI CryptDecodeObject(DWORD dwCertEncodingType, LPCSTR
lpszStructType,
const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
DWORD *pcbStructInfo)
{
- BOOL ret = FALSE;
- CryptDecodeObjectFunc pCryptDecodeObject = NULL;
- CryptDecodeObjectExFunc pCryptDecodeObjectEx = NULL;
- HCRYPTOIDFUNCADDR hFunc = NULL;
-
- TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n",
dwCertEncodingType,
- debugstr_a(lpszStructType), pbEncoded, cbEncoded, dwFlags,
- pvStructInfo, pcbStructInfo);
-
- if (!pvStructInfo && !pcbStructInfo)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
- if (cbEncoded > MAX_ENCODED_LEN)
- {
- SetLastError(CRYPT_E_ASN1_LARGE);
- return FALSE;
- }
-
- if (!(pCryptDecodeObjectEx = CRYPT_GetBuiltinDecoder(dwCertEncodingType,
- lpszStructType)))
- {
- TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n",
- debugstr_a(lpszStructType));
- pCryptDecodeObject = CRYPT_LoadDecoderFunc(dwCertEncodingType,
- lpszStructType, &hFunc);
- if (!pCryptDecodeObject)
- pCryptDecodeObjectEx = CRYPT_LoadDecoderExFunc(dwCertEncodingType,
- lpszStructType, &hFunc);
- }
- if (pCryptDecodeObject)
- ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
- pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
- else if (pCryptDecodeObjectEx)
- ret = pCryptDecodeObjectEx(dwCertEncodingType, lpszStructType,
- pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL,
- pvStructInfo, pcbStructInfo);
- if (hFunc)
- CryptFreeOIDFunctionAddress(hFunc, 0);
- TRACE_(crypt)("returning %d\n", ret);
- return ret;
+ return CryptDecodeObjectEx(dwCertEncodingType, lpszStructType,
+ pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo);
}
BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
diff --git a/dll/win32/crypt32/encode.c b/dll/win32/crypt32/encode.c
index 62d2bc91f7..9d052b61c1 100644
--- a/dll/win32/crypt32/encode.c
+++ b/dll/win32/crypt32/encode.c
@@ -4779,20 +4779,22 @@ BOOL WINAPI
CryptExportPublicKeyInfo(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv,
NULL, 0, NULL, pInfo, pcbInfo);
}
-static BOOL WINAPI CRYPT_ExportRsaPublicKeyInfoEx(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE
hCryptProv,
+typedef BOOL (WINAPI *EncodePublicKeyAndParametersFunc)(DWORD dwCertEncodingType,
+ LPSTR pszPublicKeyObjId, BYTE *pbPubKey, DWORD cbPubKey, DWORD dwFlags, void
*pvAuxInfo,
+ BYTE **ppPublicKey, DWORD *pcbPublicKey, BYTE **ppbParams, DWORD *pcbParams);
+
+static BOOL WINAPI CRYPT_ExportPublicKeyInfoEx(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE
hCryptProv,
DWORD dwKeySpec, DWORD dwCertEncodingType, LPSTR pszPublicKeyObjId,
DWORD dwFlags, void *pvAuxInfo, PCERT_PUBLIC_KEY_INFO pInfo, DWORD *pcbInfo)
{
BOOL ret;
HCRYPTKEY key;
- static CHAR oid[] = szOID_RSA_RSA;
+ static CHAR rsa_oid[] = szOID_RSA_RSA;
TRACE_(crypt)("(%08lx, %d, %08x, %s, %08x, %p, %p, %d)\n", hCryptProv,
dwKeySpec, dwCertEncodingType, debugstr_a(pszPublicKeyObjId), dwFlags,
pvAuxInfo, pInfo, pInfo ? *pcbInfo : 0);
- if (!pszPublicKeyObjId)
- pszPublicKeyObjId = oid;
if ((ret = CryptGetUserKey(hCryptProv, dwKeySpec, &key)))
{
DWORD keySize = 0;
@@ -4800,16 +4802,86 @@ static BOOL WINAPI
CRYPT_ExportRsaPublicKeyInfoEx(HCRYPTPROV_OR_NCRYPT_KEY_HANDL
ret = CryptExportKey(key, 0, PUBLICKEYBLOB, 0, NULL, &keySize);
if (ret)
{
- LPBYTE pubKey = CryptMemAlloc(keySize);
+ PUBLICKEYSTRUC *pubKey = CryptMemAlloc(keySize);
if (pubKey)
{
- ret = CryptExportKey(key, 0, PUBLICKEYBLOB, 0, pubKey,
- &keySize);
+ ret = CryptExportKey(key, 0, PUBLICKEYBLOB, 0, (BYTE *)pubKey,
&keySize);
if (ret)
{
- DWORD encodedLen = 0;
+ DWORD encodedLen;
+
+ if (!pszPublicKeyObjId)
+ {
+ static HCRYPTOIDFUNCSET set;
+ EncodePublicKeyAndParametersFunc encodeFunc = NULL;
+ HCRYPTOIDFUNCADDR hFunc = NULL;
+
+ pszPublicKeyObjId = (LPSTR)CertAlgIdToOID(pubKey->aiKeyAlg);
+ TRACE("public key algid %#x (%s)\n",
pubKey->aiKeyAlg, debugstr_a(pszPublicKeyObjId));
+
+ if (!set) /* FIXME: there is no a public macro */
+ set =
CryptInitOIDFunctionSet("CryptDllEncodePublicKeyAndParameters", 0);
+
+ CryptGetOIDFunctionAddress(set, dwCertEncodingType,
pszPublicKeyObjId, 0, (void **)&encodeFunc, &hFunc);
+ if (encodeFunc)
+ {
+ BYTE *key_data = NULL;
+ DWORD key_size = 0;
+ BYTE *params = NULL;
+ DWORD params_size = 0;
+ ret = encodeFunc(dwCertEncodingType, pszPublicKeyObjId, (BYTE
*)pubKey, keySize,
+ dwFlags, pvAuxInfo, &key_data,
&key_size, ¶ms, ¶ms_size);
+ if (ret)
+ {
+ DWORD oid_size = strlen(pszPublicKeyObjId) + 1;
+ DWORD size_needed = sizeof(*pInfo) + oid_size + key_size
+ params_size;
+
+ if (!pInfo)
+ *pcbInfo = size_needed;
+ else if (*pcbInfo < size_needed)
+ {
+ *pcbInfo = size_needed;
+ SetLastError(ERROR_MORE_DATA);
+ ret = FALSE;
+ }
+ else
+ {
+ *pcbInfo = size_needed;
+ pInfo->Algorithm.pszObjId = (char *)(pInfo + 1);
+ lstrcpyA(pInfo->Algorithm.pszObjId,
pszPublicKeyObjId);
+ if (params)
+ {
+ pInfo->Algorithm.Parameters.cbData =
params_size;
+ pInfo->Algorithm.Parameters.pbData = (BYTE
*)pInfo->Algorithm.pszObjId + oid_size;
+ memcpy(pInfo->Algorithm.Parameters.pbData,
params, params_size);
+ }
+ else
+ {
+ pInfo->Algorithm.Parameters.cbData = 0;
+ pInfo->Algorithm.Parameters.pbData = NULL;
+ }
+ pInfo->PublicKey.pbData = (BYTE
*)pInfo->Algorithm.pszObjId + oid_size + params_size;
+ pInfo->PublicKey.cbData = key_size;
+ memcpy(pInfo->PublicKey.pbData, key_data,
key_size);
+ pInfo->PublicKey.cUnusedBits = 0;
+ }
+
+ CryptMemFree(key_data);
+ CryptMemFree(params);
+ }
+
+ CryptMemFree(pubKey);
+ CryptFreeOIDFunctionAddress(hFunc, 0);
+ return ret;
+ }
+
+ /* fallback to RSA */
+ pszPublicKeyObjId = rsa_oid;
+ }
+
+ encodedLen = 0;
ret = CryptEncodeObject(dwCertEncodingType,
RSA_CSP_PUBLICKEYBLOB, pubKey, NULL, &encodedLen);
if (ret)
@@ -4887,7 +4959,7 @@ BOOL WINAPI
CryptExportPublicKeyInfoEx(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptPro
0, (void **)&exportFunc, &hFunc);
}
if (!exportFunc)
- exportFunc = CRYPT_ExportRsaPublicKeyInfoEx;
+ exportFunc = CRYPT_ExportPublicKeyInfoEx;
ret = exportFunc(hCryptProv, dwKeySpec, dwCertEncodingType,
pszPublicKeyObjId, dwFlags, pvAuxInfo, pInfo, pcbInfo);
if (hFunc)
@@ -4902,21 +4974,48 @@ BOOL WINAPI CryptImportPublicKeyInfo(HCRYPTPROV hCryptProv,
0, 0, NULL, phKey);
}
-static BOOL WINAPI CRYPT_ImportRsaPublicKeyInfoEx(HCRYPTPROV hCryptProv,
+typedef BOOL (WINAPI *ConvertPublicKeyInfoFunc)(DWORD dwCertEncodingType,
+ PCERT_PUBLIC_KEY_INFO pInfo, ALG_ID aiKeyAlg, DWORD dwFlags,
+ BYTE **ppbData, DWORD *dwDataLen);
+
+static BOOL WINAPI CRYPT_ImportPublicKeyInfoEx(HCRYPTPROV hCryptProv,
DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo, ALG_ID aiKeyAlg,
DWORD dwFlags, void *pvAuxInfo, HCRYPTKEY *phKey)
{
+ static HCRYPTOIDFUNCSET set = NULL;
+ ConvertPublicKeyInfoFunc convertFunc = NULL;
+ HCRYPTOIDFUNCADDR hFunc = NULL;
BOOL ret;
- DWORD pubKeySize = 0;
+ DWORD pubKeySize;
+ LPBYTE pubKey;
TRACE_(crypt)("(%08lx, %08x, %p, %08x, %08x, %p, %p)\n", hCryptProv,
dwCertEncodingType, pInfo, aiKeyAlg, dwFlags, pvAuxInfo, phKey);
+ if (!set)
+ set = CryptInitOIDFunctionSet(CRYPT_OID_CONVERT_PUBLIC_KEY_INFO_FUNC, 0);
+ CryptGetOIDFunctionAddress(set, dwCertEncodingType, pInfo->Algorithm.pszObjId,
+ 0, (void **)&convertFunc, &hFunc);
+ if (convertFunc)
+ {
+ pubKey = NULL;
+ pubKeySize = 0;
+ ret = convertFunc(dwCertEncodingType, pInfo, aiKeyAlg, dwFlags, &pubKey,
&pubKeySize);
+ if (ret)
+ {
+ ret = CryptImportKey(hCryptProv, pubKey, pubKeySize, 0, 0, phKey);
+ CryptMemFree(pubKey);
+ }
+
+ CryptFreeOIDFunctionAddress(hFunc, 0);
+ return ret;
+ }
+
ret = CryptDecodeObject(dwCertEncodingType, RSA_CSP_PUBLICKEYBLOB,
pInfo->PublicKey.pbData, pInfo->PublicKey.cbData, 0, NULL, &pubKeySize);
if (ret)
{
- LPBYTE pubKey = CryptMemAlloc(pubKeySize);
+ pubKey = CryptMemAlloc(pubKeySize);
if (pubKey)
{
@@ -4959,7 +5058,7 @@ BOOL WINAPI CryptImportPublicKeyInfoEx(HCRYPTPROV hCryptProv,
CryptGetOIDFunctionAddress(set, dwCertEncodingType,
pInfo->Algorithm.pszObjId, 0, (void **)&importFunc, &hFunc);
if (!importFunc)
- importFunc = CRYPT_ImportRsaPublicKeyInfoEx;
+ importFunc = CRYPT_ImportPublicKeyInfoEx;
ret = importFunc(hCryptProv, dwCertEncodingType, pInfo, aiKeyAlg, dwFlags,
pvAuxInfo, phKey);
if (hFunc)
diff --git a/dll/win32/crypt32/main.c b/dll/win32/crypt32/main.c
index 79a0ce1fd3..d0643f4107 100644
--- a/dll/win32/crypt32/main.c
+++ b/dll/win32/crypt32/main.c
@@ -35,6 +35,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(crypt);
static HCRYPTPROV hDefProv;
HINSTANCE hInstance;
+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 };
+
BOOL WINAPI DllMain(HINSTANCE hInst, DWORD fdwReason, PVOID pvReserved)
{
switch (fdwReason)
@@ -56,7 +66,7 @@ BOOL WINAPI DllMain(HINSTANCE hInst, DWORD fdwReason, PVOID pvReserved)
return TRUE;
}
-HCRYPTPROV CRYPT_GetDefaultProvider(void)
+static HCRYPTPROV CRYPT_GetDefaultProvider(void)
{
if (!hDefProv)
{
@@ -174,20 +184,69 @@ BOOL WINAPI I_CryptGetOssGlobal(DWORD x)
return FALSE;
}
-HCRYPTPROV WINAPI I_CryptGetDefaultCryptProv(DWORD reserved)
+static BOOL is_supported_algid(HCRYPTPROV prov, ALG_ID algid)
+{
+ PROV_ENUMALGS prov_algs;
+ DWORD size = sizeof(prov_algs);
+ BOOL ret = FALSE;
+
+ /* This enumeration is not thread safe */
+ EnterCriticalSection(&prov_param_cs);
+ if (CryptGetProvParam(prov, PP_ENUMALGS, (BYTE *)&prov_algs, &size,
CRYPT_FIRST))
+ {
+ do
+ {
+ if (prov_algs.aiAlgid == algid)
+ {
+ ret = TRUE;
+ break;
+ }
+ } while (CryptGetProvParam(prov, PP_ENUMALGS, (BYTE *)&prov_algs, &size,
CRYPT_NEXT));
+ }
+ LeaveCriticalSection(&prov_param_cs);
+ return ret;
+}
+
+HCRYPTPROV WINAPI DECLSPEC_HOTPATCH I_CryptGetDefaultCryptProv(ALG_ID algid)
{
- HCRYPTPROV ret;
+ HCRYPTPROV prov, defprov;
+
+ TRACE("(%08x)\n", algid);
- TRACE("(%08x)\n", reserved);
+ defprov = CRYPT_GetDefaultProvider();
- if (reserved)
+ if (algid && !is_supported_algid(defprov, algid))
{
+ DWORD i = 0, type, size;
+
+ while (CryptEnumProvidersW(i, NULL, 0, &type, NULL, &size))
+ {
+ WCHAR *name = CryptMemAlloc(size);
+ if (name)
+ {
+ if (CryptEnumProvidersW(i, NULL, 0, &type, name, &size))
+ {
+ if (CryptAcquireContextW(&prov, NULL, name, type,
CRYPT_VERIFYCONTEXT))
+ {
+ if (is_supported_algid(prov, algid))
+ {
+ CryptMemFree(name);
+ return prov;
+ }
+ CryptReleaseContext(prov, 0);
+ }
+ }
+ CryptMemFree(name);
+ }
+ i++;
+ }
+
SetLastError(E_INVALIDARG);
return 0;
}
- ret = CRYPT_GetDefaultProvider();
- CryptContextAddRef(ret, NULL, 0);
- return ret;
+
+ CryptContextAddRef(defprov, NULL, 0);
+ return defprov;
}
BOOL WINAPI I_CryptReadTrustedPublisherDWORDValueFromRegistry(LPCWSTR name,
diff --git a/dll/win32/crypt32/msg.c b/dll/win32/crypt32/msg.c
index 005fbf2c1f..4132390855 100644
--- a/dll/win32/crypt32/msg.c
+++ b/dll/win32/crypt32/msg.c
@@ -567,7 +567,12 @@ static HCRYPTMSG CHashEncodeMsg_Open(DWORD dwFlags, const void
*pvMsgEncodeInfo,
prov = info->hCryptProv;
else
{
- prov = CRYPT_GetDefaultProvider();
+ prov = I_CryptGetDefaultCryptProv(algID);
+ if (!prov)
+ {
+ SetLastError(E_INVALIDARG);
+ return NULL;
+ }
dwFlags &= ~CMSG_CRYPT_RELEASE_CONTEXT_FLAG;
}
msg = CryptMemAlloc(sizeof(CHashEncodeMsg));
@@ -921,17 +926,25 @@ typedef struct _CSignedMsgData
* been constructed.
*/
static BOOL CSignedMsgData_ConstructSignerHandles(CSignedMsgData *msg_data,
- DWORD signerIndex, HCRYPTPROV crypt_prov)
+ DWORD signerIndex, HCRYPTPROV *crypt_prov, DWORD *flags)
{
ALG_ID algID;
BOOL ret;
algID = CertOIDToAlgId(
msg_data->info->rgSignerInfo[signerIndex].HashAlgorithm.pszObjId);
- ret = CryptCreateHash(crypt_prov, algID, 0, 0,
+
+ if (!*crypt_prov)
+ {
+ *crypt_prov = I_CryptGetDefaultCryptProv(algID);
+ if (!*crypt_prov) return FALSE;
+ *flags &= ~CMSG_CRYPT_RELEASE_CONTEXT_FLAG;
+ }
+
+ ret = CryptCreateHash(*crypt_prov, algID, 0, 0,
&msg_data->signerHandles->contentHash);
if (ret && msg_data->info->rgSignerInfo[signerIndex].AuthAttrs.cAttr
> 0)
- ret = CryptCreateHash(crypt_prov, algID, 0, 0,
+ ret = CryptCreateHash(*crypt_prov, algID, 0, 0,
&msg_data->signerHandles->authAttrHash);
return ret;
}
@@ -1125,12 +1138,15 @@ static BOOL CSignedMsgData_Sign(CSignedMsgData *msg_data)
for (i = 0; ret && i < msg_data->info->cSignerInfo; i++)
{
HCRYPTHASH hash;
+ DWORD keySpec = msg_data->info->signerKeySpec[i];
+ if (!keySpec)
+ keySpec = AT_SIGNATURE;
if (msg_data->info->rgSignerInfo[i].AuthAttrs.cAttr)
hash = msg_data->signerHandles[i].authAttrHash;
else
hash = msg_data->signerHandles[i].contentHash;
- ret = CryptSignHashW(hash, AT_SIGNATURE, NULL, 0, NULL,
+ ret = CryptSignHashW(hash, keySpec, NULL, 0, NULL,
&msg_data->info->rgSignerInfo[i].EncryptedHash.cbData);
if (ret)
{
@@ -1139,7 +1155,7 @@ static BOOL CSignedMsgData_Sign(CSignedMsgData *msg_data)
msg_data->info->rgSignerInfo[i].EncryptedHash.cbData);
if (msg_data->info->rgSignerInfo[i].EncryptedHash.pbData)
{
- ret = CryptSignHashW(hash, AT_SIGNATURE, NULL, 0,
+ ret = CryptSignHashW(hash, keySpec, NULL, 0,
msg_data->info->rgSignerInfo[i].EncryptedHash.pbData,
&msg_data->info->rgSignerInfo[i].EncryptedHash.cbData);
if (ret)
@@ -1189,6 +1205,7 @@ static void CSignedEncodeMsg_Close(HCRYPTMSG hCryptMsg)
for (i = 0; i < msg->msg_data.info->cSignerInfo; i++)
CSignerInfo_Free(&msg->msg_data.info->rgSignerInfo[i]);
CSignedMsgData_CloseHandles(&msg->msg_data);
+ CryptMemFree(msg->msg_data.info->signerKeySpec);
CryptMemFree(msg->msg_data.info->rgSignerInfo);
CryptMemFree(msg->msg_data.info);
}
@@ -1411,6 +1428,9 @@ static HCRYPTMSG CSignedEncodeMsg_Open(DWORD dwFlags,
msg->msg_data.info->cSignerInfo *
sizeof(CMSG_CMS_SIGNER_INFO));
ret = CSignedMsgData_AllocateHandles(&msg->msg_data);
+ msg->msg_data.info->signerKeySpec =
CryptMemAlloc(info->cSigners * sizeof(DWORD));
+ if (!msg->msg_data.info->signerKeySpec)
+ ret = FALSE;
for (i = 0; ret && i <
msg->msg_data.info->cSignerInfo; i++)
{
if (info->rgSigners[i].SignerId.dwIdChoice ==
@@ -1422,11 +1442,13 @@ static HCRYPTMSG CSignedEncodeMsg_Open(DWORD dwFlags,
if (ret)
{
ret = CSignedMsgData_ConstructSignerHandles(
- &msg->msg_data, i,
info->rgSigners[i].hCryptProv);
+ &msg->msg_data, i,
&info->rgSigners[i].hCryptProv, &dwFlags);
if (dwFlags & CMSG_CRYPT_RELEASE_CONTEXT_FLAG)
CryptReleaseContext(info->rgSigners[i].hCryptProv,
0);
}
+ msg->msg_data.info->signerKeySpec[i] =
+ info->rgSigners[i].dwKeySpec;
}
}
else
@@ -1956,7 +1978,7 @@ static HCRYPTMSG CEnvelopedEncodeMsg_Open(DWORD dwFlags,
prov = info->hCryptProv;
else
{
- prov = CRYPT_GetDefaultProvider();
+ prov = I_CryptGetDefaultCryptProv(0);
dwFlags &= ~CMSG_CRYPT_RELEASE_CONTEXT_FLAG;
}
msg = CryptMemAlloc(sizeof(CEnvelopedEncodeMsg));
@@ -2078,7 +2100,7 @@ static void CDecodeMsg_Close(HCRYPTMSG hCryptMsg)
{
CDecodeMsg *msg = hCryptMsg;
- if (msg->base.open_flags & CMSG_CRYPT_RELEASE_CONTEXT_FLAG)
+ if (msg->crypt_prov && msg->base.open_flags &
CMSG_CRYPT_RELEASE_CONTEXT_FLAG)
CryptReleaseContext(msg->crypt_prov, 0);
switch (msg->type)
{
@@ -2329,6 +2351,14 @@ static BOOL CDecodeMsg_FinalizeHashedContent(CDecodeMsg *msg,
&size);
if (ret)
algID = CertOIDToAlgId(hashAlgoID->pszObjId);
+
+ if (!msg->crypt_prov)
+ {
+ msg->crypt_prov = I_CryptGetDefaultCryptProv(algID);
+ if (msg->crypt_prov)
+ msg->base.open_flags &= ~CMSG_CRYPT_RELEASE_CONTEXT_FLAG;
+ }
+
ret = CryptCreateHash(msg->crypt_prov, algID, 0, 0, &msg->u.hash);
if (ret)
{
@@ -2375,7 +2405,7 @@ static BOOL CDecodeMsg_FinalizeSignedContent(CDecodeMsg *msg,
ret = CSignedMsgData_AllocateHandles(&msg->u.signed_data);
for (i = 0; ret && i < msg->u.signed_data.info->cSignerInfo; i++)
ret = CSignedMsgData_ConstructSignerHandles(&msg->u.signed_data, i,
- msg->crypt_prov);
+ &msg->crypt_prov, &msg->base.open_flags);
if (ret)
{
CRYPT_DATA_BLOB *content;
@@ -3541,13 +3571,7 @@ HCRYPTMSG WINAPI CryptMsgOpenToDecode(DWORD dwMsgEncodingType,
DWORD dwFlags,
CDecodeMsg_Close, CDecodeMsg_GetParam, CDecodeMsg_Update,
CDecodeMsg_Control);
msg->type = dwMsgType;
- if (hCryptProv)
- msg->crypt_prov = hCryptProv;
- else
- {
- msg->crypt_prov = CRYPT_GetDefaultProvider();
- msg->base.open_flags &= ~CMSG_CRYPT_RELEASE_CONTEXT_FLAG;
- }
+ msg->crypt_prov = hCryptProv;
memset(&msg->u, 0, sizeof(msg->u));
msg->msg_data.cbData = 0;
msg->msg_data.pbData = NULL;
diff --git a/dll/win32/crypt32/oid.c b/dll/win32/crypt32/oid.c
index c9b0b412cf..773264d399 100644
--- a/dll/win32/crypt32/oid.c
+++ b/dll/win32/crypt32/oid.c
@@ -1,6 +1,7 @@
/*
* Copyright 2002 Mike McCormack for CodeWeavers
* Copyright 2005-2006 Juan Lang
+ * Copyright 2018 Dmitry Timoshkov
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -22,6 +23,9 @@
#include <stdio.h>
#include <stdarg.h>
+#ifdef __REACTOS__
+#include <stdlib.h>
+#endif
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
@@ -58,6 +62,7 @@ struct OIDFunctionSet
struct OIDFunction
{
+ HMODULE hModule;
DWORD encoding;
CRYPT_OID_FUNC_ENTRY entry;
struct list next;
@@ -72,6 +77,13 @@ static const WCHAR DISALLOWED[] =
{'D','i','s','a','l','l','o','w','e','d',0};
static const LPCWSTR LocalizedKeys[] =
{ROOT,MY,CA,ADDRESSBOOK,TRUSTEDPUBLISHER,DISALLOWED};
static WCHAR LocalizedNames[ARRAY_SIZE(LocalizedKeys)][256];
+static const WCHAR nameW[] = { 'N','a','m','e',0 };
+static const WCHAR algidW[] = {
'A','l','g','i','d',0 };
+static const WCHAR extraW[] = {
'E','x','t','r','a','I','n','f','o',0
};
+static const WCHAR cngalgidW[] = {
'C','N','G','A','l','g','i','d',0
};
+static const WCHAR cngextraalgidW[] = {
'C','N','G','E','x','t','r','a','A','l','g','i','d',0
};
+static const WCHAR flagsW[] = {
'F','l','a','g','s',0 };
+
static void free_function_sets(void)
{
struct OIDFunctionSet *setCursor, *setNext;
@@ -242,6 +254,8 @@ BOOL WINAPI CryptInstallOIDFunctionAddress(HMODULE hModule,
{
struct OIDFunction *func;
+ TRACE("OID %s, func %p\n", debugstr_a(rgFuncEntry[i].pszOID),
rgFuncEntry[i].pvFuncAddr);
+
if (!IS_INTOID(rgFuncEntry[i].pszOID))
func = CryptMemAlloc(sizeof(struct OIDFunction)
+ strlen(rgFuncEntry[i].pszOID) + 1);
@@ -261,6 +275,7 @@ BOOL WINAPI CryptInstallOIDFunctionAddress(HMODULE hModule,
else
func->entry.pszOID = rgFuncEntry[i].pszOID;
func->entry.pvFuncAddr = rgFuncEntry[i].pvFuncAddr;
+ func->hModule = hModule;
list_add_tail(&set->functions, &func->next);
}
else
@@ -418,6 +433,38 @@ BOOL WINAPI CryptGetOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet,
return ret;
}
+static BOOL is_module_registered(HMODULE hModule)
+{
+ struct OIDFunctionSet *set;
+ BOOL ret = FALSE;
+
+ EnterCriticalSection(&funcSetCS);
+
+ LIST_FOR_EACH_ENTRY(set, &funcSets, struct OIDFunctionSet, next)
+ {
+ struct OIDFunction *function;
+
+ EnterCriticalSection(&set->cs);
+
+ LIST_FOR_EACH_ENTRY(function, &set->functions, struct OIDFunction, next)
+ {
+ if (function->hModule == hModule)
+ {
+ ret = TRUE;
+ break;
+ }
+ }
+
+ LeaveCriticalSection(&set->cs);
+
+ if (ret) break;
+ }
+
+ LeaveCriticalSection(&funcSetCS);
+
+ return ret;
+}
+
BOOL WINAPI CryptFreeOIDFunctionAddress(HCRYPTOIDFUNCADDR hFuncAddr,
DWORD dwFlags)
{
@@ -431,9 +478,12 @@ BOOL WINAPI CryptFreeOIDFunctionAddress(HCRYPTOIDFUNCADDR hFuncAddr,
{
struct FuncAddr *addr = hFuncAddr;
- CryptMemFree(addr->dllList);
- FreeLibrary(addr->lib);
- CryptMemFree(addr);
+ if (!is_module_registered(addr->lib))
+ {
+ CryptMemFree(addr->dllList);
+ FreeLibrary(addr->lib);
+ CryptMemFree(addr);
+ }
}
return TRUE;
}
@@ -652,14 +702,127 @@ error_close_key:
return TRUE;
}
+/***********************************************************************
+ * CryptUnregisterOIDInfo (CRYPT32.@)
+ */
+BOOL WINAPI CryptUnregisterOIDInfo(PCCRYPT_OID_INFO info)
+{
+ char *key_name;
+ HKEY root;
+ DWORD err;
+
+ TRACE("(%p)\n", info);
+
+ if (!info || info->cbSize != sizeof(*info) || !info->pszOID)
+ {
+ SetLastError(E_INVALIDARG);
+ return FALSE;
+ }
+
+ err = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
"Software\\Microsoft\\Cryptography\\OID\\EncodingType 0\\CryptDllFindOIDInfo",
0, KEY_ALL_ACCESS, &root);
+ if (err != ERROR_SUCCESS)
+ {
+ SetLastError(err);
+ return FALSE;
+ }
+
+ key_name = CryptMemAlloc(strlen(info->pszOID) + 16);
+ if (key_name)
+ {
+ sprintf(key_name, "%s!%u", info->pszOID, info->dwGroupId);
+ err = RegDeleteKeyA(root, key_name);
+ }
+ else
+ err = ERROR_OUTOFMEMORY;
+
+ CryptMemFree(key_name);
+ RegCloseKey(root);
+
+ if (err)
+ SetLastError(err);
+
+ return !err;
+}
+
/***********************************************************************
* CryptRegisterOIDInfo (CRYPT32.@)
*/
-BOOL WINAPI CryptRegisterOIDInfo(PCCRYPT_OID_INFO pInfo, DWORD dwFlags)
+BOOL WINAPI CryptRegisterOIDInfo(PCCRYPT_OID_INFO info, DWORD flags)
{
- FIXME("(%p, %x): stub\n", pInfo, dwFlags );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ char *key_name;
+ HKEY root = 0, key = 0;
+ DWORD err;
+
+ TRACE("(%p, %x)\n", info, flags );
+
+ if (!info || info->cbSize != sizeof(*info) || !info->pszOID)
+ {
+ SetLastError(E_INVALIDARG);
+ return FALSE;
+ }
+
+ if (!info->dwGroupId) return TRUE;
+
+ key_name = CryptMemAlloc(strlen(info->pszOID) + 16);
+ if (!key_name)
+ {
+ err = ERROR_OUTOFMEMORY;
+ goto done;
+ }
+
+ err = RegCreateKeyExA(HKEY_LOCAL_MACHINE,
"Software\\Microsoft\\Cryptography\\OID\\EncodingType 0\\CryptDllFindOIDInfo",
+ 0, NULL, 0, KEY_ALL_ACCESS, NULL, &root, NULL);
+ if (err != ERROR_SUCCESS) goto done;
+
+ sprintf(key_name, "%s!%u", info->pszOID, info->dwGroupId);
+ err = RegCreateKeyA(root, key_name, &key);
+ if (err != ERROR_SUCCESS) goto done;
+
+ if (flags)
+ {
+ err = RegSetValueExW(key, flagsW, 0, REG_DWORD, (const BYTE *)&flags,
sizeof(flags));
+ if (err != ERROR_SUCCESS) goto done;
+ }
+
+ if (info->pwszName)
+ {
+ err = RegSetValueExW(key, nameW, 0, REG_SZ, (const BYTE *)info->pwszName,
(lstrlenW(info->pwszName) + 1) * sizeof(WCHAR));
+ if (err != ERROR_SUCCESS) goto done;
+ }
+
+ if (info->u.Algid)
+ {
+ err = RegSetValueExW(key, algidW, 0, REG_DWORD, (const BYTE
*)&info->u.Algid, sizeof(info->u.Algid));
+ if (err != ERROR_SUCCESS) goto done;
+ }
+
+ if (info->ExtraInfo.cbData && info->ExtraInfo.pbData)
+ {
+ err = RegSetValueExW(key, extraW, 0, REG_BINARY, info->ExtraInfo.pbData,
info->ExtraInfo.cbData);
+ if (err != ERROR_SUCCESS) goto done;
+ }
+
+ if (info->pwszCNGAlgid)
+ {
+ err = RegSetValueExW(key, cngalgidW, 0, REG_SZ, (const BYTE
*)info->pwszCNGAlgid, (lstrlenW(info->pwszCNGAlgid) + 1) * sizeof(WCHAR));
+ if (err != ERROR_SUCCESS) goto done;
+ }
+
+ if (info->pwszCNGExtraAlgid)
+ {
+ err = RegSetValueExW(key, cngextraalgidW, 0, REG_SZ, (const BYTE
*)info->pwszCNGExtraAlgid, (lstrlenW(info->pwszCNGExtraAlgid) + 1) *
sizeof(WCHAR));
+ if (err != ERROR_SUCCESS) goto done;
+ }
+
+done:
+ CryptMemFree(key_name);
+ if (key) RegCloseKey(key);
+ if (root) RegCloseKey(root);
+
+ if (err)
+ SetLastError(err);
+
+ return !err;
}
/***********************************************************************
@@ -1405,6 +1568,125 @@ struct OIDInfo {
struct list entry;
};
+static struct OIDInfo *read_oid_info(HKEY root, char *key_name, DWORD *flags)
+{
+ HKEY key;
+ DWORD len, oid_len, name_len = 0, extra_len = 0, cngalgid_len = 0, cngextra_len = 0,
group_id = 0;
+ struct OIDInfo *info;
+ char *p;
+
+ if (RegOpenKeyExA(root, key_name, 0, KEY_READ, &key))
+ return NULL;
+
+ p = strchr(key_name, '!');
+ if (p)
+ {
+ group_id = strtol(p + 1, NULL, 10);
+ *p = 0;
+ }
+
+ oid_len = strlen(key_name) + 1;
+
+ RegQueryValueExW(key, nameW, NULL, NULL, NULL, &name_len);
+ RegQueryValueExW(key, extraW, NULL, NULL, NULL, &extra_len);
+ RegQueryValueExW(key, cngalgidW, NULL, NULL, NULL, &cngalgid_len);
+ RegQueryValueExW(key, cngextraalgidW, NULL, NULL, NULL, &cngextra_len);
+
+ info = CryptMemAlloc(sizeof(*info) + oid_len + name_len + extra_len + cngalgid_len +
cngextra_len);
+ if (info)
+ {
+ *flags = 0;
+ len = sizeof(*flags);
+ RegQueryValueExW(key, flagsW, NULL, NULL, (BYTE *)flags, &len);
+
+ memset(info, 0, sizeof(*info));
+ info->info.cbSize = sizeof(info->info);
+
+ p = (char *)(info + 1);
+
+ info->info.pszOID = p;
+ strcpy((char *)info->info.pszOID, key_name);
+ p += oid_len;
+
+ if (name_len)
+ {
+ info->info.pwszName = (WCHAR *)p;
+ RegQueryValueExW(key, nameW, NULL, NULL, (BYTE *)info->info.pwszName,
&name_len);
+ p += name_len;
+ }
+
+ info->info.dwGroupId = group_id;
+
+ len = sizeof(info->info.u.Algid);
+ RegQueryValueExW(key, algidW, NULL, NULL, (BYTE *)&info->info.u.Algid,
&len);
+
+ if (extra_len)
+ {
+ info->info.ExtraInfo.cbData = extra_len;
+ info->info.ExtraInfo.pbData = (BYTE *)p;
+ RegQueryValueExW(key, extraW, NULL, NULL, info->info.ExtraInfo.pbData,
&extra_len);
+ p += extra_len;
+ }
+
+ if (cngalgid_len)
+ {
+ info->info.pwszCNGAlgid = (WCHAR *)p;
+ RegQueryValueExW(key, cngalgidW, NULL, NULL, (BYTE
*)info->info.pwszCNGAlgid, &cngalgid_len);
+ p += cngalgid_len;
+ }
+
+ if (cngextra_len)
+ {
+ info->info.pwszCNGExtraAlgid = (WCHAR *)p;
+ RegQueryValueExW(key, cngextraalgidW, NULL, NULL, (BYTE
*)info->info.pwszCNGExtraAlgid, &cngalgid_len);
+ }
+ }
+
+ RegCloseKey(key);
+
+ return info;
+}
+
+static void init_registered_oid_info(void)
+{
+ DWORD err, idx;
+ HKEY root;
+
+ err = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
"Software\\Microsoft\\Cryptography\\OID\\EncodingType 0\\CryptDllFindOIDInfo",
+ 0, KEY_ALL_ACCESS, &root);
+ if (err != ERROR_SUCCESS) return;
+
+ idx = 0;
+ for (;;)
+ {
+ char key_name[MAX_PATH];
+ struct OIDInfo *info;
+ DWORD flags;
+
+ err = RegEnumKeyA(root, idx++, key_name, MAX_PATH);
+ if (err == ERROR_NO_MORE_ITEMS)
+ break;
+
+ if (err == ERROR_SUCCESS)
+ {
+ if ((info = read_oid_info(root, key_name, &flags)))
+ {
+ TRACE("adding oid %s, name %s, groupid %u, algid %u, extra %u, CNG
algid %s, CNG extra %s\n",
+ debugstr_a(info->info.pszOID),
debugstr_w(info->info.pwszName),
+ info->info.dwGroupId, info->info.u.Algid,
info->info.ExtraInfo.cbData,
+ debugstr_w(info->info.pwszCNGAlgid),
debugstr_w(info->info.pwszCNGExtraAlgid));
+
+ if (flags & CRYPT_INSTALL_OID_INFO_BEFORE_FLAG)
+ list_add_head(&oidInfo, &info->entry);
+ else
+ list_add_tail(&oidInfo, &info->entry);
+ }
+ }
+ }
+
+ RegCloseKey(root);
+}
+
static void init_oid_info(void)
{
DWORD i;
@@ -1632,6 +1914,7 @@ DWORD WINAPI CertOIDToAlgId(LPCSTR pszObjId)
void crypt_oid_init(void)
{
init_oid_info();
+ init_registered_oid_info();
}
void crypt_oid_free(void)
diff --git a/media/doc/README.WINE b/media/doc/README.WINE
index 532d520a7e..cdf4cda9c6 100644
--- a/media/doc/README.WINE
+++ b/media/doc/README.WINE
@@ -58,7 +58,7 @@ reactos/dll/win32/comctl32 # Synced to Wine-3.0
reactos/dll/win32/comdlg32 # Synced to WineStaging-4.0
reactos/dll/win32/compstui # Synced to WineStaging-3.3
reactos/dll/win32/credui # Synced to WineStaging-4.0
-reactos/dll/win32/crypt32 # Synced to WineStaging-3.17
+reactos/dll/win32/crypt32 # Synced to WineStaging-4.0
reactos/dll/win32/cryptdlg # Synced to WineStaging-3.3
reactos/dll/win32/cryptdll # Synced to WineStaging-3.3
reactos/dll/win32/cryptnet # Synced to WineStaging-3.3