[CRYPT32] Sync with Wine Staging 4.0. CORE-15682

This commit is contained in:
Amine Khaldi 2019-01-25 13:19:03 +01:00
parent 9755a82226
commit b1b70ef9ed
9 changed files with 585 additions and 128 deletions

View file

@ -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;
}

View file

@ -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)

View file

@ -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;

View file

@ -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,

View file

@ -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, &params, &params_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)

View file

@ -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)
{
HCRYPTPROV ret;
PROV_ENUMALGS prov_algs;
DWORD size = sizeof(prov_algs);
BOOL ret = FALSE;
TRACE("(%08x)\n", reserved);
if (reserved)
/* 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 prov, defprov;
TRACE("(%08x)\n", algid);
defprov = CRYPT_GetDefaultProvider();
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,

View file

@ -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;

View file

@ -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)

View file

@ -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