diff --git a/reactos/dll/win32/crypt32/base64.c b/reactos/dll/win32/crypt32/base64.c index e4c2dd49255..72cfe13e203 100644 --- a/reactos/dll/win32/crypt32/base64.c +++ b/reactos/dll/win32/crypt32/base64.c @@ -222,7 +222,7 @@ BOOL WINAPI CryptBinaryToStringA(const BYTE *pbBinary, { BinaryToStringAFunc encoder = NULL; - TRACE("(%p, %ld, %08lx, %p, %p)\n", pbBinary, cbBinary, dwFlags, pszString, + TRACE("(%p, %d, %08x, %p, %p)\n", pbBinary, cbBinary, dwFlags, pszString, pcchString); if (!pbBinary) @@ -251,7 +251,7 @@ BOOL WINAPI CryptBinaryToStringA(const BYTE *pbBinary, case CRYPT_STRING_HEXASCII: case CRYPT_STRING_HEXADDR: case CRYPT_STRING_HEXASCIIADDR: - FIXME("Unimplemented type %ld\n", dwFlags & 0x7fffffff); + FIXME("Unimplemented type %d\n", dwFlags & 0x7fffffff); /* fall through */ default: SetLastError(ERROR_INVALID_PARAMETER); @@ -523,7 +523,7 @@ BOOL WINAPI CryptStringToBinaryA(LPCSTR pszString, StringToBinaryAFunc decoder; LONG ret; - TRACE("(%s, %ld, %08lx, %p, %p, %p, %p)\n", debugstr_a(pszString), + TRACE("(%s, %d, %08x, %p, %p, %p, %p)\n", debugstr_a(pszString), cchString, dwFlags, pbBinary, pcbBinary, pdwSkip, pdwFlags); if (!pszString) @@ -564,7 +564,7 @@ BOOL WINAPI CryptStringToBinaryA(LPCSTR pszString, case CRYPT_STRING_HEXASCII: case CRYPT_STRING_HEXADDR: case CRYPT_STRING_HEXASCIIADDR: - FIXME("Unimplemented type %ld\n", dwFlags & 0x7fffffff); + FIXME("Unimplemented type %d\n", dwFlags & 0x7fffffff); /* fall through */ default: SetLastError(ERROR_INVALID_PARAMETER); diff --git a/reactos/dll/win32/crypt32/cert.c b/reactos/dll/win32/crypt32/cert.c index 6297e722f0e..d20a49f8f5c 100644 --- a/reactos/dll/win32/crypt32/cert.c +++ b/reactos/dll/win32/crypt32/cert.c @@ -19,6 +19,8 @@ #include #include + +#define NONAMELESSUNION #include "windef.h" #include "winbase.h" #include "wincrypt.h" @@ -54,7 +56,7 @@ BOOL WINAPI CertAddEncodedCertificateToStore(HCERTSTORE hCertStore, pbCertEncoded, cbCertEncoded); BOOL ret; - TRACE("(%p, %08lx, %p, %ld, %08lx, %p)\n", hCertStore, dwCertEncodingType, + TRACE("(%p, %08x, %p, %d, %08x, %p)\n", hCertStore, dwCertEncodingType, pbCertEncoded, cbCertEncoded, dwAddDisposition, ppCertContext); if (cert) @@ -76,7 +78,7 @@ PCCERT_CONTEXT WINAPI CertCreateCertificateContext(DWORD dwCertEncodingType, PCERT_INFO certInfo = NULL; DWORD size = 0; - TRACE("(%08lx, %p, %ld)\n", dwCertEncodingType, pbCertEncoded, + TRACE("(%08x, %p, %d)\n", dwCertEncodingType, pbCertEncoded, cbCertEncoded); ret = CryptDecodeObjectEx(dwCertEncodingType, X509_CERT_TO_BE_SIGNED, @@ -141,7 +143,7 @@ DWORD WINAPI CertEnumCertificateContextProperties(PCCERT_CONTEXT pCertContext, (void *)pCertContext, sizeof(CERT_CONTEXT)); DWORD ret; - TRACE("(%p, %ld)\n", pCertContext, dwPropId); + TRACE("(%p, %d)\n", pCertContext, dwPropId); if (properties) ret = ContextPropertyList_EnumPropIDs(properties, dwPropId); @@ -174,7 +176,7 @@ static BOOL WINAPI CertContext_GetProperty(void *context, DWORD dwPropId, BOOL ret; CRYPT_DATA_BLOB blob; - TRACE("(%p, %ld, %p, %p)\n", context, dwPropId, pvData, pcbData); + TRACE("(%p, %d, %p, %p)\n", context, dwPropId, pvData, pcbData); if (properties) ret = ContextPropertyList_FindProperty(properties, dwPropId, &blob); @@ -272,7 +274,7 @@ BOOL WINAPI CertGetCertificateContextProperty(PCCERT_CONTEXT pCertContext, { BOOL ret; - TRACE("(%p, %ld, %p, %p)\n", pCertContext, dwPropId, pvData, pcbData); + TRACE("(%p, %d, %p, %p)\n", pCertContext, dwPropId, pvData, pcbData); switch (dwPropId) { @@ -362,17 +364,27 @@ BOOL WINAPI CertGetCertificateContextProperty(PCCERT_CONTEXT pCertContext, * - rgProvParam[0]... */ static void CRYPT_CopyKeyProvInfo(PCRYPT_KEY_PROV_INFO to, - PCRYPT_KEY_PROV_INFO from) + const CRYPT_KEY_PROV_INFO *from) { DWORD i; LPBYTE nextData = (LPBYTE)to + sizeof(CRYPT_KEY_PROV_INFO); - to->pwszContainerName = (LPWSTR)nextData; - lstrcpyW(to->pwszContainerName, from->pwszContainerName); - nextData += (lstrlenW(from->pwszContainerName) + 1) * sizeof(WCHAR); - to->pwszProvName = (LPWSTR)nextData; - lstrcpyW(to->pwszProvName, from->pwszProvName); - nextData += (lstrlenW(from->pwszProvName) + 1) * sizeof(WCHAR); + if (from->pwszContainerName) + { + to->pwszContainerName = (LPWSTR)nextData; + lstrcpyW(to->pwszContainerName, from->pwszContainerName); + nextData += (lstrlenW(from->pwszContainerName) + 1) * sizeof(WCHAR); + } + else + to->pwszContainerName = NULL; + if (from->pwszProvName) + { + to->pwszProvName = (LPWSTR)nextData; + lstrcpyW(to->pwszProvName, from->pwszProvName); + nextData += (lstrlenW(from->pwszProvName) + 1) * sizeof(WCHAR); + } + else + to->pwszProvName = NULL; to->dwProvType = from->dwProvType; to->dwFlags = from->dwFlags; to->cProvParam = from->cProvParam; @@ -391,14 +403,20 @@ static void CRYPT_CopyKeyProvInfo(PCRYPT_KEY_PROV_INFO to, } static BOOL CertContext_SetKeyProvInfoProperty(PCONTEXT_PROPERTY_LIST properties, - PCRYPT_KEY_PROV_INFO info) + const CRYPT_KEY_PROV_INFO *info) { BOOL ret; LPBYTE buf = NULL; DWORD size = sizeof(CRYPT_KEY_PROV_INFO), i, containerSize, provNameSize; - containerSize = (lstrlenW(info->pwszContainerName) + 1) * sizeof(WCHAR); - provNameSize = (lstrlenW(info->pwszProvName) + 1) * sizeof(WCHAR); + if (info->pwszContainerName) + containerSize = (lstrlenW(info->pwszContainerName) + 1) * sizeof(WCHAR); + else + containerSize = 0; + if (info->pwszProvName) + provNameSize = (lstrlenW(info->pwszProvName) + 1) * sizeof(WCHAR); + else + provNameSize = 0; size += containerSize + provNameSize; for (i = 0; i < info->cProvParam; i++) size += sizeof(CRYPT_KEY_PROV_PARAM) + info->rgProvParam[i].cbData; @@ -422,7 +440,7 @@ static BOOL WINAPI CertContext_SetProperty(void *context, DWORD dwPropId, Context_GetProperties(context, sizeof(CERT_CONTEXT)); BOOL ret; - TRACE("(%p, %ld, %08lx, %p)\n", context, dwPropId, dwFlags, pvData); + TRACE("(%p, %d, %08x, %p)\n", context, dwPropId, dwFlags, pvData); if (!properties) ret = FALSE; @@ -450,7 +468,7 @@ static BOOL WINAPI CertContext_SetProperty(void *context, DWORD dwPropId, { if (pvData) { - PCRYPT_DATA_BLOB blob = (PCRYPT_DATA_BLOB)pvData; + const CRYPT_DATA_BLOB *blob = (const CRYPT_DATA_BLOB *)pvData; ret = ContextPropertyList_SetProperty(properties, dwPropId, blob->pbData, blob->cbData); @@ -465,7 +483,7 @@ static BOOL WINAPI CertContext_SetProperty(void *context, DWORD dwPropId, case CERT_DATE_STAMP_PROP_ID: if (pvData) ret = ContextPropertyList_SetProperty(properties, dwPropId, - (LPBYTE)pvData, sizeof(FILETIME)); + (const BYTE *)pvData, sizeof(FILETIME)); else { ContextPropertyList_RemoveProperty(properties, dwPropId); @@ -476,7 +494,7 @@ static BOOL WINAPI CertContext_SetProperty(void *context, DWORD dwPropId, { if (pvData) { - PCERT_KEY_CONTEXT keyContext = (PCERT_KEY_CONTEXT)pvData; + const CERT_KEY_CONTEXT *keyContext = (const CERT_KEY_CONTEXT *)pvData; ret = ContextPropertyList_SetProperty(properties, dwPropId, (const BYTE *)keyContext, keyContext->cbSize); @@ -491,7 +509,7 @@ static BOOL WINAPI CertContext_SetProperty(void *context, DWORD dwPropId, case CERT_KEY_PROV_INFO_PROP_ID: if (pvData) ret = CertContext_SetKeyProvInfoProperty(properties, - (PCRYPT_KEY_PROV_INFO)pvData); + (const CRYPT_KEY_PROV_INFO *)pvData); else { ContextPropertyList_RemoveProperty(properties, dwPropId); @@ -510,7 +528,7 @@ static BOOL WINAPI CertContext_SetProperty(void *context, DWORD dwPropId, if (!(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG)) CryptReleaseContext(keyContext.hCryptProv, 0); if (pvData) - keyContext.hCryptProv = *(HCRYPTPROV *)pvData; + keyContext.hCryptProv = *(const HCRYPTPROV *)pvData; else keyContext.hCryptProv = 0; ret = CertContext_SetProperty(context, CERT_KEY_CONTEXT_PROP_ID, @@ -519,7 +537,7 @@ static BOOL WINAPI CertContext_SetProperty(void *context, DWORD dwPropId, break; } default: - FIXME("%ld: stub\n", dwPropId); + FIXME("%d: stub\n", dwPropId); ret = FALSE; } } @@ -532,7 +550,7 @@ BOOL WINAPI CertSetCertificateContextProperty(PCCERT_CONTEXT pCertContext, { BOOL ret; - TRACE("(%p, %ld, %08lx, %p)\n", pCertContext, dwPropId, dwFlags, pvData); + TRACE("(%p, %d, %08x, %p)\n", pCertContext, dwPropId, dwFlags, pvData); /* Handle special cases for "read-only"/invalid prop IDs. Windows just * crashes on most of these, I'll be safer. @@ -613,7 +631,7 @@ BOOL WINAPI CryptAcquireCertificatePrivateKey(PCCERT_CONTEXT pCert, CERT_KEY_CONTEXT keyContext; DWORD size; - TRACE("(%p, %08lx, %p, %p, %p, %p)\n", pCert, dwFlags, pvReserved, + TRACE("(%p, %08x, %p, %p, %p, %p)\n", pCert, dwFlags, pvReserved, phCryptProv, pdwKeySpec, pfCallerFreeProv); if (dwFlags & CRYPT_ACQUIRE_USE_PROV_INFO_FLAG) @@ -682,7 +700,7 @@ BOOL WINAPI CryptAcquireCertificatePrivateKey(PCCERT_CONTEXT pCert, BOOL WINAPI CertCompareCertificate(DWORD dwCertEncodingType, PCERT_INFO pCertId1, PCERT_INFO pCertId2) { - TRACE("(%08lx, %p, %p)\n", dwCertEncodingType, pCertId1, pCertId2); + TRACE("(%08x, %p, %p)\n", dwCertEncodingType, pCertId1, pCertId2); return CertCompareCertificateName(dwCertEncodingType, &pCertId1->Issuer, &pCertId2->Issuer) && CertCompareIntegerBlob(&pCertId1->SerialNumber, @@ -694,7 +712,7 @@ BOOL WINAPI CertCompareCertificateName(DWORD dwCertEncodingType, { BOOL ret; - TRACE("(%08lx, %p, %p)\n", dwCertEncodingType, pCertName1, pCertName2); + TRACE("(%08x, %p, %p)\n", dwCertEncodingType, pCertName1, pCertName2); if (pCertName1->cbData == pCertName2->cbData) { @@ -713,7 +731,7 @@ BOOL WINAPI CertCompareCertificateName(DWORD dwCertEncodingType, * insignificant if it's a leading 0 for positive numbers or a leading 0xff * for negative numbers. pInt is assumed to be little-endian. */ -static DWORD CRYPT_significantBytes(PCRYPT_INTEGER_BLOB pInt) +static DWORD CRYPT_significantBytes(const CRYPT_INTEGER_BLOB *pInt) { DWORD ret = pInt->cbData; @@ -756,7 +774,7 @@ BOOL WINAPI CertComparePublicKeyInfo(DWORD dwCertEncodingType, { BOOL ret; - TRACE("(%08lx, %p, %p)\n", dwCertEncodingType, pPublicKey1, pPublicKey2); + TRACE("(%08x, %p, %p)\n", dwCertEncodingType, pPublicKey1, pPublicKey2); if (pPublicKey1->PublicKey.cbData == pPublicKey2->PublicKey.cbData && pPublicKey1->PublicKey.cUnusedBits == pPublicKey2->PublicKey.cUnusedBits) @@ -772,6 +790,45 @@ BOOL WINAPI CertComparePublicKeyInfo(DWORD dwCertEncodingType, return ret; } +DWORD WINAPI CertGetPublicKeyLength(DWORD dwCertEncodingType, + PCERT_PUBLIC_KEY_INFO pPublicKey) +{ + DWORD len = 0; + + TRACE("(%08x, %p)\n", dwCertEncodingType, pPublicKey); + + if (dwCertEncodingType != X509_ASN_ENCODING) + { + SetLastError(ERROR_FILE_NOT_FOUND); + return 0; + } + if (pPublicKey->Algorithm.pszObjId && + !strcmp(pPublicKey->Algorithm.pszObjId, szOID_RSA_DH)) + { + FIXME("unimplemented for DH public keys\n"); + SetLastError(CRYPT_E_ASN1_BADTAG); + } + else + { + DWORD size; + PBYTE buf; + BOOL ret = CryptDecodeObjectEx(dwCertEncodingType, + RSA_CSP_PUBLICKEYBLOB, pPublicKey->PublicKey.pbData, + pPublicKey->PublicKey.cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, + &size); + + if (ret) + { + RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)((LPBYTE)buf + + sizeof(BLOBHEADER)); + + len = rsaPubKey->bitlen; + LocalFree(buf); + } + } + return len; +} + typedef BOOL (*CertCompareFunc)(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD dwFlags, const void *pvPara); @@ -861,7 +918,7 @@ PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore, PCCERT_CONTEXT ret; CertCompareFunc compare; - TRACE("(%p, %ld, %ld, %ld, %p, %p)\n", hCertStore, dwCertEncodingType, + TRACE("(%p, %d, %d, %d, %p, %p)\n", hCertStore, dwCertEncodingType, dwFlags, dwType, pvPara, pPrevCertContext); switch (dwType >> CERT_COMPARE_SHIFT) @@ -885,7 +942,7 @@ PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore, compare = compare_cert_by_issuer; break; default: - FIXME("find type %08lx unimplemented\n", dwType); + FIXME("find type %08x unimplemented\n", dwType); compare = NULL; } @@ -913,7 +970,7 @@ PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore, PCCERT_CONTEXT WINAPI CertGetSubjectCertificateFromStore(HCERTSTORE hCertStore, DWORD dwCertEncodingType, PCERT_INFO pCertId) { - TRACE("(%p, %08lx, %p)\n", hCertStore, dwCertEncodingType, pCertId); + TRACE("(%p, %08x, %p)\n", hCertStore, dwCertEncodingType, pCertId); if (!pCertId) { @@ -972,7 +1029,7 @@ PCCERT_CONTEXT WINAPI CertGetIssuerCertificateFromStore(HCERTSTORE hCertStore, { PCCERT_CONTEXT ret; - TRACE("(%p, %p, %p, %08lx)\n", hCertStore, pSubjectContext, + TRACE("(%p, %p, %p, %08x)\n", hCertStore, pSubjectContext, pPrevIssuerContext, *pdwFlags); if (!pSubjectContext) @@ -1003,7 +1060,7 @@ PCRYPT_ATTRIBUTE WINAPI CertFindAttribute(LPCSTR pszObjId, DWORD cAttr, PCRYPT_ATTRIBUTE ret = NULL; DWORD i; - TRACE("%s %ld %p\n", debugstr_a(pszObjId), cAttr, rgAttr); + TRACE("%s %d %p\n", debugstr_a(pszObjId), cAttr, rgAttr); if (!cAttr) return NULL; @@ -1025,7 +1082,7 @@ PCERT_EXTENSION WINAPI CertFindExtension(LPCSTR pszObjId, DWORD cExtensions, PCERT_EXTENSION ret = NULL; DWORD i; - TRACE("%s %ld %p\n", debugstr_a(pszObjId), cExtensions, rgExtensions); + TRACE("%s %d %p\n", debugstr_a(pszObjId), cExtensions, rgExtensions); if (!cExtensions) return NULL; @@ -1086,6 +1143,15 @@ LONG WINAPI CertVerifyTimeValidity(LPFILETIME pTimeToVerify, return ret; } +BOOL WINAPI CertVerifyValidityNesting(PCERT_INFO pSubjectInfo, + PCERT_INFO pIssuerInfo) +{ + TRACE("(%p, %p)\n", pSubjectInfo, pIssuerInfo); + + return CertVerifyTimeValidity(&pSubjectInfo->NotBefore, pIssuerInfo) == 0 + && CertVerifyTimeValidity(&pSubjectInfo->NotAfter, pIssuerInfo) == 0; +} + BOOL WINAPI CryptHashCertificate(HCRYPTPROV hCryptProv, ALG_ID Algid, DWORD dwFlags, const BYTE *pbEncoded, DWORD cbEncoded, BYTE *pbComputedHash, DWORD *pcbComputedHash) @@ -1093,7 +1159,7 @@ BOOL WINAPI CryptHashCertificate(HCRYPTPROV hCryptProv, ALG_ID Algid, BOOL ret = TRUE; HCRYPTHASH hHash = 0; - TRACE("(%ld, %d, %08lx, %p, %ld, %p, %p)\n", hCryptProv, Algid, dwFlags, + TRACE("(%08lx, %d, %08x, %p, %d, %p, %p)\n", hCryptProv, Algid, dwFlags, pbEncoded, cbEncoded, pbComputedHash, pcbComputedHash); if (!hCryptProv) @@ -1115,39 +1181,160 @@ BOOL WINAPI CryptHashCertificate(HCRYPTPROV hCryptProv, ALG_ID Algid, return ret; } +BOOL WINAPI CryptHashPublicKeyInfo(HCRYPTPROV hCryptProv, ALG_ID Algid, + DWORD dwFlags, DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo, + BYTE *pbComputedHash, DWORD *pcbComputedHash) +{ + BOOL ret = TRUE; + 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 (ret) + { + BYTE *buf; + DWORD size = 0; + + ret = CryptEncodeObjectEx(dwCertEncodingType, X509_PUBLIC_KEY_INFO, + pInfo, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); + if (ret) + { + ret = CryptCreateHash(hCryptProv, Algid, 0, 0, &hHash); + if (ret) + { + ret = CryptHashData(hHash, buf, size, 0); + if (ret) + ret = CryptGetHashParam(hHash, HP_HASHVAL, pbComputedHash, + pcbComputedHash, 0); + CryptDestroyHash(hHash); + } + LocalFree(buf); + } + } + return ret; +} + BOOL WINAPI CryptSignCertificate(HCRYPTPROV hCryptProv, DWORD dwKeySpec, DWORD dwCertEncodingType, const BYTE *pbEncodedToBeSigned, DWORD cbEncodedToBeSigned, PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm, const void *pvHashAuxInfo, BYTE *pbSignature, DWORD *pcbSignature) { BOOL ret; - ALG_ID algID; + PCCRYPT_OID_INFO info; HCRYPTHASH hHash; - TRACE("(%08lx, %ld, %ld, %p, %ld, %p, %p, %p, %p)\n", hCryptProv, + TRACE("(%08lx, %d, %d, %p, %d, %p, %p, %p, %p)\n", hCryptProv, dwKeySpec, dwCertEncodingType, pbEncodedToBeSigned, cbEncodedToBeSigned, pSignatureAlgorithm, pvHashAuxInfo, pbSignature, pcbSignature); - algID = CertOIDToAlgId(pSignatureAlgorithm->pszObjId); - if (!algID) + info = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY, + pSignatureAlgorithm->pszObjId, 0); + if (!info) { SetLastError(NTE_BAD_ALGID); return FALSE; } - if (!hCryptProv) + if (info->dwGroupId == CRYPT_HASH_ALG_OID_GROUP_ID) { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; + if (!hCryptProv) + hCryptProv = CRYPT_GetDefaultProvider(); + ret = CryptCreateHash(hCryptProv, info->u.Algid, 0, 0, &hHash); + if (ret) + { + ret = CryptHashData(hHash, pbEncodedToBeSigned, + cbEncodedToBeSigned, 0); + if (ret) + ret = CryptGetHashParam(hHash, HP_HASHVAL, pbSignature, + pcbSignature, 0); + CryptDestroyHash(hHash); + } } + else + { + if (!hCryptProv) + { + SetLastError(ERROR_INVALID_PARAMETER); + ret = FALSE; + } + else + { + ret = CryptCreateHash(hCryptProv, info->u.Algid, 0, 0, &hHash); + if (ret) + { + ret = CryptHashData(hHash, pbEncodedToBeSigned, + cbEncodedToBeSigned, 0); + if (ret) + ret = CryptSignHashW(hHash, dwKeySpec, NULL, 0, pbSignature, + pcbSignature); + CryptDestroyHash(hHash); + } + } + } + return ret; +} - ret = CryptCreateHash(hCryptProv, algID, 0, 0, &hHash); +BOOL WINAPI CryptSignAndEncodeCertificate(HCRYPTPROV hCryptProv, + DWORD dwKeySpec, DWORD dwCertEncodingType, LPCSTR lpszStructType, + const void *pvStructInfo, PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm, + const void *pvHashAuxInfo, PBYTE pbEncoded, DWORD *pcbEncoded) +{ + BOOL ret; + DWORD encodedSize, hashSize; + + TRACE("(%08lx, %d, %d, %s, %p, %p, %p, %p, %p)\n", hCryptProv, dwKeySpec, + dwCertEncodingType, debugstr_a(lpszStructType), pvStructInfo, + pSignatureAlgorithm, pvHashAuxInfo, pbEncoded, pcbEncoded); + + ret = CryptEncodeObject(dwCertEncodingType, lpszStructType, pvStructInfo, + NULL, &encodedSize); if (ret) { - ret = CryptHashData(hHash, pbEncodedToBeSigned, cbEncodedToBeSigned, 0); - if (ret) - ret = CryptSignHashW(hHash, dwKeySpec, NULL, 0, pbSignature, - pcbSignature); - CryptDestroyHash(hHash); + PBYTE encoded = CryptMemAlloc(encodedSize); + + if (encoded) + { + ret = CryptEncodeObject(dwCertEncodingType, lpszStructType, + pvStructInfo, encoded, &encodedSize); + if (ret) + { + ret = CryptSignCertificate(hCryptProv, dwKeySpec, + dwCertEncodingType, encoded, encodedSize, pSignatureAlgorithm, + pvHashAuxInfo, NULL, &hashSize); + if (ret) + { + PBYTE hash = CryptMemAlloc(hashSize); + + if (hash) + { + ret = CryptSignCertificate(hCryptProv, dwKeySpec, + dwCertEncodingType, encoded, encodedSize, + pSignatureAlgorithm, pvHashAuxInfo, hash, &hashSize); + if (ret) + { + CERT_SIGNED_CONTENT_INFO info = { { 0 } }; + + info.ToBeSigned.cbData = encodedSize; + info.ToBeSigned.pbData = encoded; + memcpy(&info.SignatureAlgorithm, + pSignatureAlgorithm, + sizeof(info.SignatureAlgorithm)); + info.Signature.cbData = hashSize; + info.Signature.pbData = hash; + info.Signature.cUnusedBits = 0; + ret = CryptEncodeObject(dwCertEncodingType, + X509_CERT, &info, pbEncoded, pcbEncoded); + } + CryptMemFree(hash); + } + } + } + CryptMemFree(encoded); + } } return ret; } @@ -1163,25 +1350,56 @@ BOOL WINAPI CryptVerifyCertificateSignature(HCRYPTPROV hCryptProv, static BOOL CRYPT_VerifyCertSignatureFromPublicKeyInfo(HCRYPTPROV hCryptProv, DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pubKeyInfo, - PCERT_SIGNED_CONTENT_INFO signedCert) + const CERT_SIGNED_CONTENT_INFO *signedCert) { BOOL ret; - ALG_ID algID = CertOIDToAlgId(pubKeyInfo->Algorithm.pszObjId); HCRYPTKEY key; + PCCRYPT_OID_INFO info; + ALG_ID pubKeyID, hashID; + info = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY, + pubKeyInfo->Algorithm.pszObjId, 0); + if (!info || (info->dwGroupId != CRYPT_PUBKEY_ALG_OID_GROUP_ID && + info->dwGroupId != CRYPT_SIGN_ALG_OID_GROUP_ID)) + { + SetLastError(NTE_BAD_ALGID); + return FALSE; + } + if (info->dwGroupId == CRYPT_PUBKEY_ALG_OID_GROUP_ID) + { + switch (info->u.Algid) + { + case CALG_RSA_KEYX: + pubKeyID = CALG_RSA_SIGN; + hashID = CALG_SHA1; + break; + case CALG_RSA_SIGN: + pubKeyID = CALG_RSA_SIGN; + hashID = CALG_SHA1; + break; + default: + FIXME("unimplemented for %s\n", pubKeyInfo->Algorithm.pszObjId); + return FALSE; + } + } + else + { + hashID = info->u.Algid; + if (info->ExtraInfo.cbData >= sizeof(ALG_ID)) + pubKeyID = *(ALG_ID *)info->ExtraInfo.pbData; + else + pubKeyID = hashID; + } /* Load the default provider if necessary */ if (!hCryptProv) hCryptProv = CRYPT_GetDefaultProvider(); ret = CryptImportPublicKeyInfoEx(hCryptProv, dwCertEncodingType, - pubKeyInfo, algID, 0, NULL, &key); + pubKeyInfo, pubKeyID, 0, NULL, &key); if (ret) { HCRYPTHASH hash; - /* Some key algorithms aren't hash algorithms, so map them */ - if (algID == CALG_RSA_SIGN || algID == CALG_RSA_KEYX) - algID = CALG_SHA1; - ret = CryptCreateHash(hCryptProv, algID, 0, 0, &hash); + ret = CryptCreateHash(hCryptProv, hashID, 0, 0, &hash); if (ret) { ret = CryptHashData(hash, signedCert->ToBeSigned.pbData, @@ -1203,7 +1421,7 @@ BOOL WINAPI CryptVerifyCertificateSignatureEx(HCRYPTPROV hCryptProv, BOOL ret = TRUE; CRYPT_DATA_BLOB subjectBlob; - TRACE("(%08lx, %ld, %ld, %p, %ld, %p, %08lx, %p)\n", hCryptProv, + TRACE("(%08lx, %d, %d, %p, %d, %p, %08x, %p)\n", hCryptProv, dwCertEncodingType, dwSubjectType, pvSubject, dwIssuerType, pvIssuer, dwFlags, pvReserved); @@ -1302,7 +1520,7 @@ BOOL WINAPI CertGetEnhancedKeyUsage(PCCERT_CONTEXT pCertContext, DWORD dwFlags, return FALSE; } - TRACE("(%p, %08lx, %p, %ld)\n", pCertContext, dwFlags, pUsage, *pcbUsage); + TRACE("(%p, %08x, %p, %d)\n", pCertContext, dwFlags, pUsage, *pcbUsage); if (!(dwFlags & CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG)) { @@ -1556,7 +1774,7 @@ BOOL WINAPI CertGetValidUsages(DWORD cCerts, PCCERT_CONTEXT *rghCerts, BOOL allUsagesValid = TRUE; CERT_ENHKEY_USAGE validUsages = { 0, NULL }; - TRACE("(%ld, %p, %p, %p, %ld)\n", cCerts, *rghCerts, cNumOIDSs, + TRACE("(%d, %p, %p, %p, %d)\n", cCerts, *rghCerts, cNumOIDSs, rghOIDs, *pcbOIDs); for (i = 0; ret && i < cCerts; i++) @@ -1693,7 +1911,7 @@ BOOL WINAPI CertGetValidUsages(DWORD cCerts, PCCERT_CONTEXT *rghCerts, * pInfo is NULL, from the attributes of hProv. */ static void CertContext_SetKeyProvInfo(PCCERT_CONTEXT context, - PCRYPT_KEY_PROV_INFO pInfo, HCRYPTPROV hProv) + const CRYPT_KEY_PROV_INFO *pInfo, HCRYPTPROV hProv) { CRYPT_KEY_PROV_INFO info = { 0 }; BOOL ret; @@ -1777,7 +1995,7 @@ static void CertContext_SetKeyProvInfo(PCCERT_CONTEXT context, /* Creates a signed certificate context from the unsigned, encoded certificate * in blob, using the crypto provider hProv and the signature algorithm sigAlgo. */ -static PCCERT_CONTEXT CRYPT_CreateSignedCert(PCRYPT_DER_BLOB blob, +static PCCERT_CONTEXT CRYPT_CreateSignedCert(const CRYPT_DER_BLOB *blob, HCRYPTPROV hProv, PCRYPT_ALGORITHM_IDENTIFIER sigAlgo) { PCCERT_CONTEXT context = NULL; @@ -1832,11 +2050,11 @@ static PCCERT_CONTEXT CRYPT_CreateSignedCert(PCRYPT_DER_BLOB blob, * pubKey: The public key of the certificate. Must not be NULL. * pExtensions: Extensions to be included with the certificate. Optional. */ -static void CRYPT_MakeCertInfo(PCERT_INFO info, PCRYPT_DATA_BLOB pSerialNumber, - PCERT_NAME_BLOB pSubjectIssuerBlob, - PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm, PSYSTEMTIME pStartTime, - PSYSTEMTIME pEndTime, PCERT_PUBLIC_KEY_INFO pubKey, - PCERT_EXTENSIONS pExtensions) +static void CRYPT_MakeCertInfo(PCERT_INFO info, const CRYPT_DATA_BLOB *pSerialNumber, + const CERT_NAME_BLOB *pSubjectIssuerBlob, + const CRYPT_ALGORITHM_IDENTIFIER *pSignatureAlgorithm, const SYSTEMTIME *pStartTime, + const SYSTEMTIME *pEndTime, const CERT_PUBLIC_KEY_INFO *pubKey, + const CERT_EXTENSIONS *pExtensions) { static CHAR oid[] = szOID_RSA_SHA1RSA; @@ -1952,7 +2170,7 @@ PCCERT_CONTEXT WINAPI CertCreateSelfSignCertificate(HCRYPTPROV hProv, PCERT_PUBLIC_KEY_INFO pubKey = NULL; DWORD pubKeySize = 0; - TRACE("(0x%08lx, %p, %08lx, %p, %p, %p, %p, %p)\n", hProv, + TRACE("(%08lx, %p, %08x, %p, %p, %p, %p, %p)\n", hProv, pSubjectIssuerBlob, dwFlags, pKeyProvInfo, pSignatureAlgorithm, pStartTime, pExtensions, pExtensions); diff --git a/reactos/dll/win32/crypt32/chain.c b/reactos/dll/win32/crypt32/chain.c new file mode 100644 index 00000000000..03267db076e --- /dev/null +++ b/reactos/dll/win32/crypt32/chain.c @@ -0,0 +1,172 @@ +/* + * Copyright 2006 Juan Lang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ +#include +#include "windef.h" +#include "winbase.h" +#include "wincrypt.h" +#include "wine/debug.h" +#include "crypt32_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(crypt); + +/* This represents a subset of a certificate chain engine: it doesn't include + * the "hOther" store described by MSDN, because I'm not sure how that's used. + * It also doesn't include the "hTrust" store, because I don't yet implement + * CTLs or complex certificate chains. + */ +typedef struct _CertificateChainEngine +{ + LONG ref; + HCERTSTORE hRoot; + HCERTSTORE hWorld; + DWORD dwFlags; + DWORD dwUrlRetrievalTimeout; + DWORD MaximumCachedCertificates; + DWORD CycleDetectionModulus; +} CertificateChainEngine, *PCertificateChainEngine; + +static inline void CRYPT_AddStoresToCollection(HCERTSTORE collection, + DWORD cStores, HCERTSTORE *stores) +{ + DWORD i; + + for (i = 0; i < cStores; i++) + CertAddStoreToCollection(collection, stores[i], 0, 0); +} + +static inline void CRYPT_CloseStores(DWORD cStores, HCERTSTORE *stores) +{ + DWORD i; + + for (i = 0; i < cStores; i++) + CertCloseStore(stores[i], 0); +} + +static const WCHAR rootW[] = { 'R','o','o','t',0 }; + +static BOOL CRYPT_CheckRestrictedRoot(HCERTSTORE store) +{ + BOOL ret = TRUE; + + if (store) + { + HCERTSTORE rootStore = CertOpenSystemStoreW(0, rootW); + PCCERT_CONTEXT cert = NULL, check; + BYTE hash[20]; + DWORD size; + + do { + cert = CertEnumCertificatesInStore(store, cert); + if (cert) + { + size = sizeof(hash); + + ret = CertGetCertificateContextProperty(cert, CERT_HASH_PROP_ID, + hash, &size); + if (ret) + { + CRYPT_HASH_BLOB blob = { sizeof(hash), hash }; + + check = CertFindCertificateInStore(rootStore, + cert->dwCertEncodingType, 0, CERT_FIND_SHA1_HASH, &blob, + NULL); + if (!check) + ret = FALSE; + else + CertFreeCertificateContext(check); + } + } + } while (ret && cert); + if (cert) + CertFreeCertificateContext(cert); + CertCloseStore(rootStore, 0); + } + return ret; +} + +BOOL WINAPI CertCreateCertificateChainEngine(PCERT_CHAIN_ENGINE_CONFIG pConfig, + HCERTCHAINENGINE *phChainEngine) +{ + static const WCHAR caW[] = { 'C','A',0 }; + static const WCHAR myW[] = { 'M','y',0 }; + static const WCHAR trustW[] = { 'T','r','u','s','t',0 }; + BOOL ret; + + TRACE("(%p, %p)\n", pConfig, phChainEngine); + + if (pConfig->cbSize != sizeof(*pConfig)) + { + SetLastError(E_INVALIDARG); + return FALSE; + } + *phChainEngine = NULL; + ret = CRYPT_CheckRestrictedRoot(pConfig->hRestrictedRoot); + if (ret) + { + PCertificateChainEngine engine = + CryptMemAlloc(sizeof(CertificateChainEngine)); + + if (engine) + { + HCERTSTORE worldStores[4]; + + engine->ref = 1; + if (pConfig->hRestrictedRoot) + engine->hRoot = CertDuplicateStore(pConfig->hRestrictedRoot); + else + engine->hRoot = CertOpenSystemStoreW(0, rootW); + engine->hWorld = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0, + CERT_STORE_CREATE_NEW_FLAG, NULL); + worldStores[0] = CertDuplicateStore(engine->hRoot); + worldStores[1] = CertOpenSystemStoreW(0, caW); + worldStores[2] = CertOpenSystemStoreW(0, myW); + worldStores[3] = CertOpenSystemStoreW(0, trustW); + CRYPT_AddStoresToCollection(engine->hWorld, + sizeof(worldStores) / sizeof(worldStores[0]), worldStores); + CRYPT_AddStoresToCollection(engine->hWorld, + pConfig->cAdditionalStore, pConfig->rghAdditionalStore); + CRYPT_CloseStores(sizeof(worldStores) / sizeof(worldStores[0]), + worldStores); + engine->dwFlags = pConfig->dwFlags; + engine->dwUrlRetrievalTimeout = pConfig->dwUrlRetrievalTimeout; + engine->MaximumCachedCertificates = + pConfig->MaximumCachedCertificates; + engine->CycleDetectionModulus = pConfig->CycleDetectionModulus; + *phChainEngine = (HCERTCHAINENGINE)engine; + ret = TRUE; + } + else + ret = FALSE; + } + return ret; +} + +void WINAPI CertFreeCertificateChainEngine(HCERTCHAINENGINE hChainEngine) +{ + PCertificateChainEngine engine = (PCertificateChainEngine)hChainEngine; + + TRACE("(%p)\n", hChainEngine); + + if (engine && InterlockedDecrement(&engine->ref) == 0) + { + CertCloseStore(engine->hWorld, 0); + CertCloseStore(engine->hRoot, 0); + CryptMemFree(engine); + } +} diff --git a/reactos/dll/win32/crypt32/context.c b/reactos/dll/win32/crypt32/context.c index 1b2f7d1682b..ab57c5709b8 100644 --- a/reactos/dll/win32/crypt32/context.c +++ b/reactos/dll/win32/crypt32/context.c @@ -94,7 +94,7 @@ void *Context_CreateLinkContext(unsigned int contextSize, void *linked, unsigned linkContext->linked = linkedBase; if (addRef) InterlockedIncrement(&linkedBase->ref); - TRACE("%p's ref count is %ld\n", context, linkContext->ref); + TRACE("%p's ref count is %d\n", context, linkContext->ref); } return context; } @@ -161,7 +161,7 @@ void Context_Release(void *context, size_t contextSize, CryptMemFree(context); } else - TRACE("%p's ref count is %ld\n", context, base->ref); + TRACE("%p's ref count is %d\n", context, base->ref); } void Context_CopyProperties(const void *to, const void *from, @@ -192,6 +192,7 @@ struct ContextList *ContextList_Create( list->contextInterface = contextInterface; list->contextSize = contextSize; InitializeCriticalSection(&list->cs); + list->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ContextList.cs"); list_init(&list->contexts); } return list; @@ -303,6 +304,7 @@ void ContextList_Empty(struct ContextList *list) void ContextList_Free(struct ContextList *list) { ContextList_Empty(list); + list->cs.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&list->cs); CryptMemFree(list); } diff --git a/reactos/dll/win32/crypt32/crl.c b/reactos/dll/win32/crypt32/crl.c index bd0136a7555..32c4f3aa797 100644 --- a/reactos/dll/win32/crypt32/crl.c +++ b/reactos/dll/win32/crypt32/crl.c @@ -35,7 +35,7 @@ PCCRL_CONTEXT WINAPI CertCreateCRLContext(DWORD dwCertEncodingType, PCRL_INFO crlInfo = NULL; DWORD size = 0; - TRACE("(%08lx, %p, %ld)\n", dwCertEncodingType, pbCrlEncoded, + TRACE("(%08x, %p, %d)\n", dwCertEncodingType, pbCrlEncoded, cbCrlEncoded); if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING) @@ -80,7 +80,7 @@ BOOL WINAPI CertAddEncodedCRLToStore(HCERTSTORE hCertStore, pbCrlEncoded, cbCrlEncoded); BOOL ret; - TRACE("(%p, %08lx, %p, %ld, %08lx, %p)\n", hCertStore, dwCertEncodingType, + TRACE("(%p, %08x, %p, %d, %08x, %p)\n", hCertStore, dwCertEncodingType, pbCrlEncoded, cbCrlEncoded, dwAddDisposition, ppCrlContext); if (crl) @@ -144,7 +144,7 @@ PCCRL_CONTEXT WINAPI CertFindCRLInStore(HCERTSTORE hCertStore, PCCRL_CONTEXT ret; CrlCompareFunc compare; - TRACE("(%p, %ld, %ld, %ld, %p, %p)\n", hCertStore, dwCertEncodingType, + TRACE("(%p, %d, %d, %d, %p, %p)\n", hCertStore, dwCertEncodingType, dwFindFlags, dwFindType, pvFindPara, pPrevCrlContext); switch (dwFindType) @@ -159,7 +159,7 @@ PCCRL_CONTEXT WINAPI CertFindCRLInStore(HCERTSTORE hCertStore, compare = compare_crl_existing; break; default: - FIXME("find type %08lx unimplemented\n", dwFindType); + FIXME("find type %08x unimplemented\n", dwFindType); compare = NULL; } @@ -192,7 +192,7 @@ PCCRL_CONTEXT WINAPI CertGetCRLFromStore(HCERTSTORE hCertStore, CERT_STORE_DELTA_CRL_FLAG; PCCRL_CONTEXT ret; - TRACE("(%p, %p, %p, %08lx)\n", hCertStore, pIssuerContext, pPrevCrlContext, + TRACE("(%p, %p, %p, %08x)\n", hCertStore, pIssuerContext, pPrevCrlContext, *pdwFlags); if (*pdwFlags & ~supportedFlags) @@ -257,7 +257,7 @@ DWORD WINAPI CertEnumCRLContextProperties(PCCRL_CONTEXT pCRLContext, (void *)pCRLContext, sizeof(CRL_CONTEXT)); DWORD ret; - TRACE("(%p, %ld)\n", pCRLContext, dwPropId); + TRACE("(%p, %d)\n", pCRLContext, dwPropId); if (properties) ret = ContextPropertyList_EnumPropIDs(properties, dwPropId); @@ -293,7 +293,7 @@ static BOOL WINAPI CRLContext_GetProperty(void *context, DWORD dwPropId, BOOL ret; CRYPT_DATA_BLOB blob; - TRACE("(%p, %ld, %p, %p)\n", context, dwPropId, pvData, pcbData); + TRACE("(%p, %d, %p, %p)\n", context, dwPropId, pvData, pcbData); if (properties) ret = ContextPropertyList_FindProperty(properties, dwPropId, &blob); @@ -346,7 +346,7 @@ BOOL WINAPI CertGetCRLContextProperty(PCCRL_CONTEXT pCRLContext, { BOOL ret; - TRACE("(%p, %ld, %p, %p)\n", pCRLContext, dwPropId, pvData, pcbData); + TRACE("(%p, %d, %p, %p)\n", pCRLContext, dwPropId, pvData, pcbData); switch (dwPropId) { @@ -390,7 +390,7 @@ static BOOL WINAPI CRLContext_SetProperty(void *context, DWORD dwPropId, Context_GetProperties(context, sizeof(CERT_CONTEXT)); BOOL ret; - TRACE("(%p, %ld, %08lx, %p)\n", context, dwPropId, dwFlags, pvData); + TRACE("(%p, %d, %08x, %p)\n", context, dwPropId, dwFlags, pvData); if (!properties) ret = FALSE; @@ -429,10 +429,10 @@ static BOOL WINAPI CRLContext_SetProperty(void *context, DWORD dwPropId, } case CERT_DATE_STAMP_PROP_ID: ret = ContextPropertyList_SetProperty(properties, dwPropId, - (LPBYTE)pvData, sizeof(FILETIME)); + (const BYTE *)pvData, sizeof(FILETIME)); break; default: - FIXME("%ld: stub\n", dwPropId); + FIXME("%d: stub\n", dwPropId); ret = FALSE; } } @@ -445,7 +445,7 @@ BOOL WINAPI CertSetCRLContextProperty(PCCRL_CONTEXT pCRLContext, { BOOL ret; - TRACE("(%p, %ld, %08lx, %p)\n", pCRLContext, dwPropId, dwFlags, pvData); + TRACE("(%p, %d, %08x, %p)\n", pCRLContext, dwPropId, dwFlags, pvData); /* Handle special cases for "read-only"/invalid prop IDs. Windows just * crashes on most of these, I'll be safer. @@ -469,11 +469,11 @@ BOOL WINAPI CertSetCRLContextProperty(PCCRL_CONTEXT pCRLContext, BOOL WINAPI CertIsValidCRLForCertificate(PCCERT_CONTEXT pCert, PCCRL_CONTEXT pCrl, DWORD dwFlags, void *pvReserved) { - TRACE("(%p, %p, %08lx, %p)\n", pCert, pCrl, dwFlags, pvReserved); + TRACE("(%p, %p, %08x, %p)\n", pCert, pCrl, dwFlags, pvReserved); return TRUE; } -static PCRL_ENTRY CRYPT_FindCertificateInCRL(PCERT_INFO cert, PCRL_INFO crl) +static PCRL_ENTRY CRYPT_FindCertificateInCRL(PCERT_INFO cert, const CRL_INFO *crl) { DWORD i; PCRL_ENTRY entry = NULL; @@ -489,7 +489,7 @@ BOOL WINAPI CertFindCertificateInCRL(PCCERT_CONTEXT pCert, PCCRL_CONTEXT pCrlContext, DWORD dwFlags, void *pvReserved, PCRL_ENTRY *ppCrlEntry) { - TRACE("(%p, %p, %08lx, %p, %p)\n", pCert, pCrlContext, dwFlags, pvReserved, + TRACE("(%p, %p, %08x, %p, %p)\n", pCert, pCrlContext, dwFlags, pvReserved, ppCrlEntry); *ppCrlEntry = CRYPT_FindCertificateInCRL(pCert->pCertInfo, @@ -503,7 +503,7 @@ BOOL WINAPI CertVerifyCRLRevocation(DWORD dwCertEncodingType, DWORD i; PCRL_ENTRY entry = NULL; - TRACE("(%08lx, %p, %ld, %p)\n", dwCertEncodingType, pCertId, cCrlInfo, + TRACE("(%08x, %p, %d, %p)\n", dwCertEncodingType, pCertId, cCrlInfo, rgpCrlInfo); for (i = 0; !entry && i < cCrlInfo; i++) diff --git a/reactos/dll/win32/crypt32/crypt32.rbuild b/reactos/dll/win32/crypt32/crypt32.rbuild index c7abccf7416..d8bbbaded56 100644 --- a/reactos/dll/win32/crypt32/crypt32.rbuild +++ b/reactos/dll/win32/crypt32/crypt32.rbuild @@ -15,6 +15,7 @@ ntdll base64.c cert.c + chain.c crl.c context.c decode.c @@ -23,6 +24,7 @@ proplist.c protectdata.c serialize.c + sip.c store.c str.c main.c diff --git a/reactos/dll/win32/crypt32/crypt32.rc b/reactos/dll/win32/crypt32/crypt32.rc index 1fe23cdf33a..675469368a0 100644 --- a/reactos/dll/win32/crypt32/crypt32.rc +++ b/reactos/dll/win32/crypt32/crypt32.rc @@ -32,5 +32,6 @@ #include "crypt32_De.rc" #include "crypt32_En.rc" +#include "crypt32_Fr.rc" #include "crypt32_Ko.rc" #include "crypt32_No.rc" diff --git a/reactos/dll/win32/crypt32/crypt32.spec b/reactos/dll/win32/crypt32/crypt32.spec index 04b028c4719..7ee23f4e683 100644 --- a/reactos/dll/win32/crypt32/crypt32.spec +++ b/reactos/dll/win32/crypt32/crypt32.spec @@ -18,7 +18,7 @@ @ stdcall CertControlStore(long long long ptr) @ stdcall CertCreateCRLContext(long ptr long) @ stdcall CertCreateCTLContext(long ptr long) -@ stub CertCreateCertificateChainEngine +@ stdcall CertCreateCertificateChainEngine(ptr ptr) @ stdcall CertCreateCertificateContext(long ptr long) @ stdcall CertCreateSelfSignCertificate(long ptr long ptr ptr ptr ptr ptr) @ stdcall CertDeleteCRLFromStore(ptr) @@ -45,7 +45,7 @@ @ stdcall CertFreeCRLContext(ptr) @ stdcall CertFreeCTLContext(ptr) @ stub CertFreeCertificateChain -@ stub CertFreeCertificateChainEngine +@ stdcall CertFreeCertificateChainEngine(ptr) @ stdcall CertFreeCertificateContext(ptr) @ stdcall CertGetCRLContextProperty(ptr long ptr ptr) @ stdcall CertGetCRLFromStore(ptr ptr ptr ptr) @@ -57,7 +57,7 @@ @ stdcall CertGetIssuerCertificateFromStore(long ptr ptr ptr) @ stdcall CertGetNameStringA(ptr long long ptr ptr long) @ stdcall CertGetNameStringW(ptr long long ptr ptr long) -@ stub CertGetPublicKeyLength +@ stdcall CertGetPublicKeyLength(long ptr) @ stdcall CertGetSubjectCertificateFromStore(ptr long ptr) @ stdcall CertGetValidUsages(long ptr ptr ptr ptr) @ stub CertIsRDNAttrsInCertificateName @@ -80,21 +80,21 @@ @ stdcall CertSetCTLContextProperty(ptr long long ptr) @ stdcall CertSetCertificateContextProperty(ptr long long ptr) @ stdcall CertSetEnhancedKeyUsage(ptr ptr) -@ stub CertStrToNameA -@ stub CertStrToNameW +@ stdcall CertStrToNameA(long str long ptr ptr ptr ptr) +@ stdcall CertStrToNameW(long wstr long ptr ptr ptr ptr) @ stdcall CertVerifyCRLRevocation(long ptr long ptr) @ stdcall CertVerifyCRLTimeValidity(ptr ptr) @ stub CertVerifyCTLUsage @ stub CertVerifyRevocation @ stdcall CertVerifySubjectCertificateContext(ptr ptr ptr) @ stdcall CertVerifyTimeValidity(ptr ptr) -@ stub CertVerifyValidityNesting +@ stdcall CertVerifyValidityNesting(ptr ptr) @ stdcall CreateFileU(wstr long long ptr long long ptr) kernel32.CreateFileW @ stdcall CryptBinaryToStringA(ptr long long ptr ptr) @ stub CryptBinaryToStringW # (ptr long long ptr ptr) @ stdcall CryptStringToBinaryA(str long long ptr ptr ptr ptr) @ stub CryptStringToBinaryW # (wstr long long ptr ptr ptr ptr) -@ stub CryptAcquireContextU +@ stdcall CryptAcquireContextU(ptr wstr wstr long long) advapi32.CryptAcquireContextW @ stdcall CryptAcquireCertificatePrivateKey(ptr long ptr ptr ptr ptr) @ stub CryptCloseAsyncHandle @ stub CryptCreateAsyncHandle @@ -113,7 +113,7 @@ @ stdcall CryptExportPublicKeyInfo(long long long ptr ptr) @ stdcall CryptExportPublicKeyInfoEx(long long long str long ptr ptr ptr) @ stdcall CryptFindOIDInfo(long ptr long) -@ stub CryptFormatObject +@ stdcall CryptFormatObject(long long long ptr str ptr long ptr ptr) @ stdcall CryptFreeOIDFunctionAddress(long long) @ stub CryptGetAsyncParam @ stdcall CryptGetDefaultOIDDllList(long long ptr ptr) @@ -124,7 +124,7 @@ @ stdcall CryptGetOIDFunctionValue(long str str wstr ptr ptr ptr) @ stdcall CryptHashCertificate(long long long ptr long ptr ptr) @ stub CryptHashMessage -@ stub CryptHashPublicKeyInfo +@ stdcall CryptHashPublicKeyInfo(long long long long ptr ptr ptr) @ stub CryptHashToBeSigned @ stub CryptImportPKCS8 @ stdcall CryptImportPublicKeyInfo(long long ptr ptr) @@ -154,13 +154,18 @@ @ stdcall CryptRegisterOIDFunction(long str str wstr str) @ stub CryptRegisterOIDInfo @ stdcall CryptSIPAddProvider(ptr) +@ stdcall CryptSIPCreateIndirectData(ptr ptr ptr) +@ stdcall CryptSIPGetSignedDataMsg(ptr ptr long ptr ptr) @ stdcall CryptSIPLoad(ptr long ptr) +@ stdcall CryptSIPPutSignedDataMsg(ptr long ptr long ptr) @ stdcall CryptSIPRemoveProvider(ptr) +@ stdcall CryptSIPRemoveSignedDataMsg(ptr long) @ stdcall CryptSIPRetrieveSubjectGuid(wstr long ptr) +@ stdcall CryptSIPVerifyIndirectData(ptr ptr) @ stub CryptSetAsyncParam @ stdcall CryptSetOIDFunctionValue(long str str wstr long ptr long) @ stub CryptSetProviderU -@ stub CryptSignAndEncodeCertificate +@ stdcall CryptSignAndEncodeCertificate(long long long str ptr ptr ptr ptr ptr) @ stub CryptSignAndEncryptMessage @ stdcall CryptSignCertificate(long long long ptr long ptr ptr ptr ptr) @ stub CryptSignHashU @@ -186,15 +191,17 @@ @ stdcall I_CryptFlushLruCache(ptr long long) @ stdcall I_CryptFreeLruCache(ptr long long) @ stdcall I_CryptFreeTls(long long) -@ stub I_CryptGetDefaultCryptProv +@ stdcall I_CryptGetDefaultCryptProv(long) @ stub I_CryptGetDefaultCryptProvForEncrypt @ stdcall I_CryptGetOssGlobal(long) @ stdcall I_CryptGetTls(long) @ stub I_CryptInsertLruEntry @ stdcall I_CryptInstallAsn1Module(long long long) @ stdcall I_CryptInstallOssGlobal(long long long) +@ stdcall I_CryptReadTrustedPublisherDWORDValueFromRegistry(wstr ptr) @ stub I_CryptReleaseLruEntry @ stdcall I_CryptSetTls(long ptr) +@ stdcall I_CryptUninstallAsn1Module(ptr) @ stub I_CryptUninstallOssGlobal @ stub PFXExportCertStore @ stub PFXImportCertStore diff --git a/reactos/dll/win32/crypt32/crypt32_De.rc b/reactos/dll/win32/crypt32/crypt32_De.rc index 272210ab82b..6c109edd839 100644 --- a/reactos/dll/win32/crypt32/crypt32_De.rc +++ b/reactos/dll/win32/crypt32/crypt32_De.rc @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -LANGUAGE LANG_GERMAN, SUBLANG_DEFAULT +LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE { diff --git a/reactos/dll/win32/crypt32/crypt32_Fr.rc b/reactos/dll/win32/crypt32/crypt32_Fr.rc new file mode 100644 index 00000000000..f77a77ddfb1 --- /dev/null +++ b/reactos/dll/win32/crypt32/crypt32_Fr.rc @@ -0,0 +1,166 @@ +/* + * crypt32 dll French resources + * + * Copyright 2006 Jonathan Ernst + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL + +STRINGTABLE DISCARDABLE +{ + IDS_AUTHORITY_KEY_ID "Authority Key Identifier" + IDS_KEY_ATTRIBUTES "Key Attributes" + IDS_KEY_USAGE_RESTRICTION "Key Usage Restriction" + IDS_SUBJECT_ALT_NAME "Subject Alternative Name" + IDS_ISSUER_ALT_NAME "Issuer Alternative Name" + IDS_BASIC_CONSTRAINTS "Basic Constraints" + IDS_KEY_USAGE "Key Usage" + IDS_CERT_POLICIES "Certificate Policies" + IDS_SUBJECT_KEY_IDENTIFIER "Subject Key Identifier" + IDS_CRL_REASON_CODE "CRL Reason Code" + IDS_CRL_DIST_POINTS "CRL Distribution Points" + IDS_ENHANCED_KEY_USAGE "Enhanced Key Usage" + IDS_AUTHORITY_INFO_ACCESS "Authority Information Access" + IDS_CERT_EXTENSIONS "Certificate Extensions" + IDS_NEXT_UPDATE_LOCATION "Next Update Location" + IDS_YES_OR_NO_TRUST "Yes or No Trust" + IDS_EMAIL_ADDRESS "Email Address" + IDS_UNSTRUCTURED_NAME "Unstructured Name" + IDS_CONTENT_TYPE "Content Type" + IDS_MESSAGE_DIGEST "Message Digest" + IDS_SIGNING_TIME "Signing Time" + IDS_COUNTER_SIGN "Counter Sign" + IDS_CHALLENGE_PASSWORD "Challenge Password" + IDS_UNSTRUCTURED_ADDRESS "Unstructured Address" + IDS_SMIME_CAPABILITIES "SMIME Capabilities" + IDS_PREFER_SIGNED_DATA "Prefer Signed Data" + IDS_CPS "CPS" + IDS_USER_NOTICE "User Notice" + IDS_OCSP "On-line Certificate Status Protocol" + IDS_CA_ISSUER "Certification Authority Issuer" + IDS_CERT_TEMPLATE_NAME "Certification Template Name" + IDS_CERT_TYPE "Certificate Type" + IDS_CERT_MANIFOLD "Certificate Manifold" + IDS_NETSCAPE_CERT_TYPE "Type de certificat Netscape" + IDS_NETSCAPE_BASE_URL "URL Netscape de base" + IDS_NETSCAPE_REVOCATION_URL "URL Netscape de révocation" + IDS_NETSCAPE_CA_REVOCATION_URL "URL Netscape de révocation du certificat" + IDS_NETSCAPE_CERT_RENEWAL_URL "URL Netscape de renouvellement du certificat" + IDS_NETSCAPE_CA_POLICY_URL "Netscape CA Policy URL" + IDS_NETSCAPE_SSL_SERVER_NAME "Netscape SSL ServerName" + IDS_NETSCAPE_COMMENT "Commentaire Netscape" + IDS_SPC_SP_AGENCY_INFO "SpcSpAgencyInfo" + IDS_SPC_FINANCIAL_CRITERIA "SpcFinancialCriteria" + IDS_SPC_MINIMAL_CRITERIA "SpcMinimalCriteria" + IDS_COUNTRY "Pays/Région" + IDS_ORGANIZATION "Organisation" + IDS_ORGANIZATIONAL_UNIT "Unité d'organisation" + IDS_COMMON_NAME "Nom commun" + IDS_LOCALITY "Locality" + IDS_STATE_OR_PROVINCE "État ou province" + IDS_TITLE "Titre" + IDS_GIVEN_NAME "Nom donné" + IDS_INITIALS "Initiales" + IDS_SUR_NAME "Nom de famille" + IDS_DOMAIN_COMPONENT "Domain Component" + IDS_STREET_ADDRESS "Adresse" + IDS_SERIAL_NUMBER "Numéro de série" + IDS_CA_VERSION "Version du CA" + IDS_CROSS_CA_VERSION "Cross CA Version" + IDS_SERIALIZED_SIG_SERIAL_NUMBER "Serialized Signature Serial Number" + IDS_PRINCIPAL_NAME "Nom principal" + IDS_WINDOWS_PRODUCT_UPDATE "Mise à jour de Windows" + IDS_ENROLLMENT_NAME_VALUE_PAIR "Enrollment Name Value Pair" + IDS_OS_VERSION "Version du système d'exploitation" + IDS_ENROLLMENT_CSP "Enrollment CSP" + IDS_CRL_NUMBER "CRL Number" + IDS_DELTA_CRL_INDICATOR "Delta CRL Indicator" + IDS_ISSUING_DIST_POINT "Issuing Distribution Point" + IDS_FRESHEST_CRL "Freshest CRL" + IDS_NAME_CONSTRAINTS "Contraintes de nom" + IDS_POLICY_MAPPINGS "Policy Mappings" + IDS_POLICY_CONSTRAINTS "Policy Constraints" + IDS_CROSS_CERT_DIST_POINTS "Cross-Certificate Distribution Points" + IDS_APPLICATION_POLICIES "Application Policies" + IDS_APPLICATION_POLICY_MAPPINGS "Application Policy Mappings" + IDS_APPLICATION_POLICY_CONSTRAINTS "Application Policy Constraints" + IDS_CMC_DATA "CMC Data" + IDS_CMC_RESPONSE "CMC Response" + IDS_UNSIGNED_CMC_REQUEST "Unsigned CMC Request" + IDS_CMC_STATUS_INFO "CMC Status Info" + IDS_CMC_EXTENSIONS "CMC Extensions" + IDS_CMC_ATTRIBUTES "CMC Attributes" + IDS_PKCS_7_DATA "Données PKCS 7" + IDS_PKCS_7_SIGNED "Signé avec PKCS 7" + IDS_PKCS_7_ENVELOPED "Enveloppé avec PKCS 7" + IDS_PKCS_7_SIGNED_ENVELOPED "Enveloppé et signé avec PKCS 7" + IDS_PKCS_7_DIGESTED "Haché avec PKCS 7" + IDS_PKCS_7_ENCRYPTED "Chiffré avec PKCS 7" + IDS_PREVIOUS_CA_CERT_HASH "Previous CA Certificate Hash" + IDS_CRL_VIRTUAL_BASE "Virtual Base CRL Number" + IDS_CRL_NEXT_PUBLISH "Next CRL Publish" + IDS_CA_EXCHANGE "Certificat de chiffrement CA" + IDS_KEY_RECOVERY_AGENT "Key Recovery Agent" + IDS_CERTIFICATE_TEMPLATE "Certificate Template Information" + IDS_ENTERPRISE_ROOT_OID "Enterprise Root OID" + IDS_RDN_DUMMY_SIGNER "Signataire factice" + IDS_ARCHIVED_KEY_ATTR "Clé de chiffrement privée" + IDS_CRL_SELF_CDP "Published CRL Locations" + IDS_REQUIRE_CERT_CHAIN_POLICY "Enforce Certificate Chain Policy" + IDS_TRANSACTION_ID "Transaction Id" + IDS_SENDER_NONCE "Sender Nonce" + IDS_RECIPIENT_NONCE "Recipient Nonce" + IDS_REG_INFO "Reg Info" + IDS_GET_CERTIFICATE "Get Certificate" + IDS_GET_CRL "Get CRL" + IDS_REVOKE_REQUEST "Revoke Request" + IDS_QUERY_PENDING "Query Pending" + IDS_SORTED_CTL "Certificate Trust List" + IDS_ARCHIVED_KEY_CERT_HASH "Archived Key Certificate Hash" + IDS_PRIVATE_KEY_USAGE_PERIOD "Private Key Usage Period" + IDS_CLIENT_INFORMATION "Client Information" + IDS_SERVER_AUTHENTICATION "Server Authentication" + IDS_CLIENT_AUTHENTICATION "Client Authentication" + IDS_CODE_SIGNING "Code Signing" + IDS_SECURE_EMAIL "Secure Email" + IDS_TIME_STAMPING "Time Stamping" + IDS_MICROSOFT_TRUST_LIST_SIGNING "Microsoft Trust List Signing" + IDS_MICROSOFT_TIME_STAMPING "Microsoft Time Stamping" + IDS_IPSEC_END_SYSTEM "IP security end system" + IDS_IPSEC_TUNNEL "IP security tunnel termination" + IDS_IPSEC_USER "IP security user" + IDS_EFS "Encrypting File System" + IDS_WHQL_CRYPTO "Windows Hardware Driver Verification" + IDS_NT5_CRYPTO "Windows System Component Verification" + IDS_OEM_WHQL_CRYPTO "OEM Windows System Component Verification" + IDS_EMBEDDED_NT_CRYPTO "Embedded Windows System Component Verification" + IDS_KEY_PACK_LICENSES "Key Pack Licenses" + IDS_LICENSE_SERVER "License Server Verification" + IDS_SMART_CARD_LOGON "Smart Card Logon" + IDS_DIGITAL_RIGHTS "Digital Rights" + IDS_QUALIFIED_SUBORDINATION "Qualified Subordination" + IDS_KEY_RECOVERY "Récupération de clé" + IDS_DOCUMENT_SIGNING "Signature de document" + IDS_IPSEC_IKE_INTERMEDIATE "IP security IKE intermediate" + IDS_FILE_RECOVERY "Récupération de fichier" + IDS_ROOT_LIST_SIGNER "Root List Signer" + IDS_ANY_APPLICATION_POLICIES "All application policies" + IDS_DS_EMAIL_REPLICATION "Directory Service Email Replication" + IDS_ENROLLMENT_AGENT "Certificate Request Agent" + IDS_LIFETIME_SIGNING "Lifetime Signing" + IDS_ANY_CERT_POLICY "All issuance policies" +} diff --git a/reactos/dll/win32/crypt32/crypt32_Ko.rc b/reactos/dll/win32/crypt32/crypt32_Ko.rc index 418e04514b7..2f6367b052a 100644 --- a/reactos/dll/win32/crypt32/crypt32_Ko.rc +++ b/reactos/dll/win32/crypt32/crypt32_Ko.rc @@ -19,7 +19,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT +LANGUAGE LANG_KOREAN, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE { diff --git a/reactos/dll/win32/crypt32/crypt32_private.h b/reactos/dll/win32/crypt32/crypt32_private.h index db8719378c5..8aa544b2f06 100644 --- a/reactos/dll/win32/crypt32/crypt32_private.h +++ b/reactos/dll/win32/crypt32/crypt32_private.h @@ -104,6 +104,14 @@ extern PCWINE_CONTEXT_INTERFACE pCTLInterface; const void *CRYPT_ReadSerializedElement(const BYTE *pbElement, DWORD cbElement, DWORD dwContextTypeFlags, DWORD *pdwContentType); +/* Writes contexts from the memory store to the file. */ +BOOL CRYPT_WriteSerializedFile(HANDLE file, HCERTSTORE store); + +/* Reads contexts serialized in the file into the memory store. Returns FALSE + * if the file is not of the expected format. + */ +BOOL CRYPT_ReadSerializedFile(HANDLE file, HCERTSTORE store); + /* Fixes up the the pointers in info, where info is assumed to be a * CRYPT_KEY_PROV_INFO, followed by its container name, provider name, and any * provider parameters, in a contiguous buffer, but where info's pointers are diff --git a/reactos/dll/win32/crypt32/decode.c b/reactos/dll/win32/crypt32/decode.c index f4e18853ccc..cb83a80a0bb 100644 --- a/reactos/dll/win32/crypt32/decode.c +++ b/reactos/dll/win32/crypt32/decode.c @@ -113,7 +113,8 @@ static BOOL WINAPI CRYPT_AsnDecodeInt(DWORD dwCertEncodingType, PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo); /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData * member has been initialized, doesn't do exception handling, and doesn't do - * memory allocation. + * memory allocation. Also doesn't check tag, assumes the caller has checked + * it. */ static BOOL WINAPI CRYPT_AsnDecodeIntegerInternal(DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, @@ -133,7 +134,7 @@ BOOL WINAPI CryptDecodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType, CryptDecodeObjectFunc pCryptDecodeObject; HCRYPTOIDFUNCADDR hFunc; - TRACE("(0x%08lx, %s, %p, %ld, 0x%08lx, %p, %p)\n", dwCertEncodingType, + TRACE("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType, debugstr_a(lpszStructType), pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo); @@ -330,9 +331,9 @@ static BOOL CRYPT_AsnDecodeSequenceItems(DWORD dwCertEncodingType, if (items[i].decodeFunc) { if (pvStructInfo) - TRACE("decoding item %ld\n", i); + TRACE("decoding item %d\n", i); else - TRACE("sizing item %ld\n", i); + TRACE("sizing item %d\n", i); ret = items[i].decodeFunc(dwCertEncodingType, NULL, ptr, 1 + nextItemLenBytes + nextItemLen, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, @@ -358,13 +359,13 @@ static BOOL CRYPT_AsnDecodeSequenceItems(DWORD dwCertEncodingType, else if (items[i].optional && GetLastError() == CRYPT_E_ASN1_BADTAG) { - TRACE("skipping optional item %ld\n", i); + TRACE("skipping optional item %d\n", i); items[i].size = items[i].minSize; SetLastError(NOERROR); ret = TRUE; } else - TRACE("item %ld failed: %08lx\n", i, + TRACE("item %d failed: %08x\n", i, GetLastError()); } else @@ -372,7 +373,7 @@ static BOOL CRYPT_AsnDecodeSequenceItems(DWORD dwCertEncodingType, } else if (items[i].optional) { - TRACE("skipping optional item %ld\n", i); + TRACE("skipping optional item %d\n", i); items[i].size = items[i].minSize; } else @@ -386,19 +387,19 @@ static BOOL CRYPT_AsnDecodeSequenceItems(DWORD dwCertEncodingType, } else if (items[i].optional) { - TRACE("missing optional item %ld, skipping\n", i); + TRACE("missing optional item %d, skipping\n", i); items[i].size = items[i].minSize; } else { - TRACE("not enough bytes for item %ld, failing\n", i); + TRACE("not enough bytes for item %d, failing\n", i); SetLastError(CRYPT_E_ASN1_CORRUPT); ret = FALSE; } } if (cbEncoded - (ptr - pbEncoded) != 0) { - TRACE("%ld remaining bytes, failing\n", cbEncoded - + TRACE("%d remaining bytes, failing\n", cbEncoded - (ptr - pbEncoded)); SetLastError(CRYPT_E_ASN1_CORRUPT); ret = FALSE; @@ -422,7 +423,7 @@ static BOOL CRYPT_AsnDecodeSequence(DWORD dwCertEncodingType, { BOOL ret; - TRACE("%p, %ld, %p, %ld, %08lx, %p, %p, %ld, %p\n", items, cItem, pbEncoded, + TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items, cItem, pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo, startingPointer); @@ -470,7 +471,7 @@ static BOOL CRYPT_AsnDecodeSequence(DWORD dwCertEncodingType, SetLastError(CRYPT_E_ASN1_BADTAG); ret = FALSE; } - TRACE("returning %d (%08lx)\n", ret, GetLastError()); + TRACE("returning %d (%08x)\n", ret, GetLastError()); return ret; } @@ -512,7 +513,7 @@ static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc, { BOOL ret = TRUE; - TRACE("%p, %p, %ld, %08lx, %p, %p, %ld, %p\n", arrayDesc, pbEncoded, + TRACE("%p, %p, %d, %08x, %p, %p, %d, %p\n", arrayDesc, pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo, startingPointer); @@ -700,7 +701,7 @@ static BOOL WINAPI CRYPT_AsnDecodeBitsSwapBytes(DWORD dwCertEncodingType, { BOOL ret; - TRACE("(%p, %ld, 0x%08lx, %p, %p, %ld)\n", pbEncoded, cbEncoded, dwFlags, + TRACE("(%p, %d, 0x%08x, %p, %p, %d)\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in- @@ -726,7 +727,7 @@ static BOOL WINAPI CRYPT_AsnDecodeBitsSwapBytes(DWORD dwCertEncodingType, } } } - TRACE("returning %d (%08lx)\n", ret, GetLastError()); + TRACE("returning %d (%08x)\n", ret, GetLastError()); return ret; } @@ -736,7 +737,7 @@ static BOOL WINAPI CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType, { BOOL ret = TRUE; - TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); __TRY @@ -767,7 +768,7 @@ static BOOL WINAPI CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType, } __ENDTRY - TRACE("Returning %d (%08lx)\n", ret, GetLastError()); + TRACE("Returning %d (%08x)\n", ret, GetLastError()); return ret; } @@ -866,14 +867,14 @@ static BOOL WINAPI CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType, offsetof(CERT_INFO, rgExtension), 0 }, }; - TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); ret = CRYPT_AsnDecodeSequence(dwCertEncodingType, items, sizeof(items) / sizeof(items[0]), pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL); - TRACE("Returning %d (%08lx)\n", ret, GetLastError()); + TRACE("Returning %d (%08x)\n", ret, GetLastError()); return ret; } @@ -883,7 +884,7 @@ static BOOL WINAPI CRYPT_AsnDecodeCert(DWORD dwCertEncodingType, { BOOL ret = TRUE; - TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); __TRY @@ -920,7 +921,7 @@ static BOOL WINAPI CRYPT_AsnDecodeCert(DWORD dwCertEncodingType, } __ENDTRY - TRACE("Returning %d (%08lx)\n", ret, GetLastError()); + TRACE("Returning %d (%08x)\n", ret, GetLastError()); return ret; } @@ -941,7 +942,7 @@ static BOOL WINAPI CRYPT_AsnDecodeCRLEntry(DWORD dwCertEncodingType, }; PCRL_ENTRY entry = (PCRL_ENTRY)pvStructInfo; - TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, entry, + TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry, *pcbStructInfo); ret = CRYPT_AsnDecodeSequence(X509_ASN_ENCODING, items, @@ -963,13 +964,13 @@ static BOOL WINAPI CRYPT_AsnDecodeCRLEntries(DWORD dwCertEncodingType, offsetof(CRL_ENTRY, SerialNumber.pbData) }; struct GenericArray *entries = (struct GenericArray *)pvStructInfo; - TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, entries ? entries->rgItems : NULL); - TRACE("Returning %d (%08lx)\n", ret, GetLastError()); + TRACE("Returning %d (%08x)\n", ret, GetLastError()); return ret; } @@ -999,14 +1000,14 @@ static BOOL WINAPI CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType, }; BOOL ret = TRUE; - TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); ret = CRYPT_AsnDecodeSequence(dwCertEncodingType, items, sizeof(items) / sizeof(items[0]), pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL); - TRACE("Returning %d (%08lx)\n", ret, GetLastError()); + TRACE("Returning %d (%08x)\n", ret, GetLastError()); return ret; } @@ -1016,7 +1017,7 @@ static BOOL WINAPI CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType, { BOOL ret = TRUE; - TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); __TRY @@ -1053,7 +1054,7 @@ static BOOL WINAPI CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType, } __ENDTRY - TRACE("Returning %d (%08lx)\n", ret, GetLastError()); + TRACE("Returning %d (%08x)\n", ret, GetLastError()); return ret; } @@ -1063,7 +1064,7 @@ static BOOL WINAPI CRYPT_AsnDecodeOidInternal(DWORD dwCertEncodingType, { BOOL ret = TRUE; - TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); if (pbEncoded[0] == ASN_OBJECTIDENTIFIER) @@ -1184,7 +1185,7 @@ static BOOL WINAPI CRYPT_AsnDecodeExtension(DWORD dwCertEncodingType, BOOL ret = TRUE; PCERT_EXTENSION ext = (PCERT_EXTENSION)pvStructInfo; - TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, ext, + TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, ext, *pcbStructInfo); if (ext) @@ -1195,7 +1196,7 @@ static BOOL WINAPI CRYPT_AsnDecodeExtension(DWORD dwCertEncodingType, if (ext) TRACE("ext->pszObjId is %p (%s)\n", ext->pszObjId, debugstr_a(ext->pszObjId)); - TRACE("returning %d (%08lx)\n", ret, GetLastError()); + TRACE("returning %d (%08x)\n", ret, GetLastError()); return ret; } @@ -1209,7 +1210,7 @@ static BOOL WINAPI CRYPT_AsnDecodeExtensionsInternal(DWORD dwCertEncodingType, offsetof(CERT_EXTENSION, pszObjId) }; PCERT_EXTENSIONS exts = (PCERT_EXTENSIONS)pvStructInfo; - TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, @@ -1324,8 +1325,7 @@ static BOOL WINAPI CRYPT_AsnDecodeNameValueInternal(DWORD dwCertEncodingType, case ASN_UNIVERSALSTRING: FIXME("ASN_UNIVERSALSTRING: unimplemented\n"); SetLastError(CRYPT_E_ASN1_BADTAG); - ret = FALSE; - break; + return FALSE; case ASN_BMPSTRING: valueType = CERT_RDN_BMP_STRING; bytesNeeded += dataLen; @@ -1333,79 +1333,77 @@ static BOOL WINAPI CRYPT_AsnDecodeNameValueInternal(DWORD dwCertEncodingType, case ASN_UTF8STRING: valueType = CERT_RDN_UTF8_STRING; bytesNeeded += MultiByteToWideChar(CP_UTF8, 0, - (LPSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * 2; + (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * 2; break; default: SetLastError(CRYPT_E_ASN1_BADTAG); + return FALSE; + } + + if (!value) + *pcbStructInfo = bytesNeeded; + else if (*pcbStructInfo < bytesNeeded) + { + *pcbStructInfo = bytesNeeded; + SetLastError(ERROR_MORE_DATA); ret = FALSE; } - if (ret) + else { - if (!value) - *pcbStructInfo = bytesNeeded; - else if (*pcbStructInfo < bytesNeeded) + *pcbStructInfo = bytesNeeded; + value->dwValueType = valueType; + if (dataLen) { - *pcbStructInfo = bytesNeeded; - SetLastError(ERROR_MORE_DATA); - ret = FALSE; + DWORD i; + + assert(value->Value.pbData); + switch (pbEncoded[0]) + { + case ASN_OCTETSTRING: + case ASN_NUMERICSTRING: + case ASN_PRINTABLESTRING: + case ASN_IA5STRING: + case ASN_T61STRING: + case ASN_VIDEOTEXSTRING: + case ASN_GRAPHICSTRING: + case ASN_VISIBLESTRING: + case ASN_GENERALSTRING: + value->Value.cbData = dataLen; + if (dataLen) + { + if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG)) + memcpy(value->Value.pbData, + pbEncoded + 1 + lenBytes, dataLen); + else + value->Value.pbData = (LPBYTE)pbEncoded + 1 + + lenBytes; + } + break; + case ASN_BMPSTRING: + { + LPWSTR str = (LPWSTR)value->Value.pbData; + + value->Value.cbData = dataLen; + for (i = 0; i < dataLen / 2; i++) + str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) | + pbEncoded[1 + lenBytes + 2 * i + 1]; + break; + } + case ASN_UTF8STRING: + { + LPWSTR str = (LPWSTR)value->Value.pbData; + + value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0, + (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, + str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2; + break; + } + } } else { - *pcbStructInfo = bytesNeeded; - value->dwValueType = valueType; - if (dataLen) - { - DWORD i; - - assert(value->Value.pbData); - switch (pbEncoded[0]) - { - case ASN_OCTETSTRING: - case ASN_NUMERICSTRING: - case ASN_PRINTABLESTRING: - case ASN_IA5STRING: - case ASN_T61STRING: - case ASN_VIDEOTEXSTRING: - case ASN_GRAPHICSTRING: - case ASN_VISIBLESTRING: - case ASN_GENERALSTRING: - value->Value.cbData = dataLen; - if (dataLen) - { - if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG)) - memcpy(value->Value.pbData, - pbEncoded + 1 + lenBytes, dataLen); - else - value->Value.pbData = (LPBYTE)pbEncoded + 1 + - lenBytes; - } - break; - case ASN_BMPSTRING: - { - LPWSTR str = (LPWSTR)value->Value.pbData; - - value->Value.cbData = dataLen; - for (i = 0; i < dataLen / 2; i++) - str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) | - pbEncoded[1 + lenBytes + 2 * i + 1]; - break; - } - case ASN_UTF8STRING: - { - LPWSTR str = (LPWSTR)value->Value.pbData; - - value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0, - (LPSTR)pbEncoded + 1 + lenBytes, dataLen, - str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2; - break; - } - } - } - else - { - value->Value.cbData = 0; - value->Value.pbData = NULL; - } + value->Value.cbData = 0; + value->Value.pbData = NULL; } } } @@ -1469,116 +1467,109 @@ static BOOL WINAPI CRYPT_AsnDecodeUnicodeNameValueInternal( { case ASN_NUMERICSTRING: valueType = CERT_RDN_NUMERIC_STRING; - bytesNeeded += (dataLen + 1) * 2; + bytesNeeded += dataLen * 2; break; case ASN_PRINTABLESTRING: valueType = CERT_RDN_PRINTABLE_STRING; - bytesNeeded += (dataLen + 1) * 2; + bytesNeeded += dataLen * 2; break; case ASN_IA5STRING: valueType = CERT_RDN_IA5_STRING; - bytesNeeded += (dataLen + 1) * 2; + bytesNeeded += dataLen * 2; break; case ASN_T61STRING: valueType = CERT_RDN_T61_STRING; - bytesNeeded += (dataLen + 1) * 2; + bytesNeeded += dataLen * 2; break; case ASN_VIDEOTEXSTRING: valueType = CERT_RDN_VIDEOTEX_STRING; - bytesNeeded += (dataLen + 1) * 2; + bytesNeeded += dataLen * 2; break; case ASN_GRAPHICSTRING: valueType = CERT_RDN_GRAPHIC_STRING; - bytesNeeded += (dataLen + 1) * 2; + bytesNeeded += dataLen * 2; break; case ASN_VISIBLESTRING: valueType = CERT_RDN_VISIBLE_STRING; - bytesNeeded += (dataLen + 1) * 2; + bytesNeeded += dataLen * 2; break; case ASN_GENERALSTRING: valueType = CERT_RDN_GENERAL_STRING; - bytesNeeded += (dataLen + 1) * 2; + bytesNeeded += dataLen * 2; break; case ASN_UNIVERSALSTRING: valueType = CERT_RDN_UNIVERSAL_STRING; - bytesNeeded += dataLen / 2 + 2; + bytesNeeded += dataLen / 2; break; case ASN_BMPSTRING: valueType = CERT_RDN_BMP_STRING; - bytesNeeded += dataLen + 2; + bytesNeeded += dataLen; break; case ASN_UTF8STRING: valueType = CERT_RDN_UTF8_STRING; bytesNeeded += MultiByteToWideChar(CP_UTF8, 0, - (LPSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * 2 + 2; + (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * 2; break; default: SetLastError(CRYPT_E_ASN1_BADTAG); + return FALSE; + } + + if (!value) + *pcbStructInfo = bytesNeeded; + else if (*pcbStructInfo < bytesNeeded) + { + *pcbStructInfo = bytesNeeded; + SetLastError(ERROR_MORE_DATA); ret = FALSE; } - if (ret) + else { - if (!value) - *pcbStructInfo = bytesNeeded; - else if (*pcbStructInfo < bytesNeeded) + *pcbStructInfo = bytesNeeded; + value->dwValueType = valueType; + if (dataLen) { - *pcbStructInfo = bytesNeeded; - SetLastError(ERROR_MORE_DATA); - ret = FALSE; + DWORD i; + LPWSTR str = (LPWSTR)value->Value.pbData; + + assert(value->Value.pbData); + switch (pbEncoded[0]) + { + case ASN_NUMERICSTRING: + case ASN_PRINTABLESTRING: + case ASN_IA5STRING: + case ASN_T61STRING: + case ASN_VIDEOTEXSTRING: + case ASN_GRAPHICSTRING: + case ASN_VISIBLESTRING: + case ASN_GENERALSTRING: + value->Value.cbData = dataLen * 2; + for (i = 0; i < dataLen; i++) + str[i] = pbEncoded[1 + lenBytes + i]; + break; + case ASN_UNIVERSALSTRING: + value->Value.cbData = dataLen / 2; + for (i = 0; i < dataLen / 4; i++) + str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8) + | pbEncoded[1 + lenBytes + 2 * i + 3]; + break; + case ASN_BMPSTRING: + value->Value.cbData = dataLen; + for (i = 0; i < dataLen / 2; i++) + str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) | + pbEncoded[1 + lenBytes + 2 * i + 1]; + break; + case ASN_UTF8STRING: + value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0, + (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, + str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2; + break; + } } else { - *pcbStructInfo = bytesNeeded; - value->dwValueType = valueType; - if (dataLen) - { - DWORD i; - LPWSTR str = (LPWSTR)value->Value.pbData; - - assert(value->Value.pbData); - switch (pbEncoded[0]) - { - case ASN_NUMERICSTRING: - case ASN_PRINTABLESTRING: - case ASN_IA5STRING: - case ASN_T61STRING: - case ASN_VIDEOTEXSTRING: - case ASN_GRAPHICSTRING: - case ASN_VISIBLESTRING: - case ASN_GENERALSTRING: - value->Value.cbData = dataLen * 2 + 2; - for (i = 0; i < dataLen; i++) - str[i] = pbEncoded[1 + lenBytes + i]; - str[i] = 0; - break; - case ASN_UNIVERSALSTRING: - value->Value.cbData = dataLen / 2 + 2; - for (i = 0; i < dataLen / 4; i++) - str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8) - | pbEncoded[1 + lenBytes + 2 * i + 3]; - str[i] = 0; - break; - case ASN_BMPSTRING: - value->Value.cbData = dataLen + 2; - for (i = 0; i < dataLen / 2; i++) - str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) | - pbEncoded[1 + lenBytes + 2 * i + 1]; - str[i] = 0; - break; - case ASN_UTF8STRING: - value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0, - (LPSTR)pbEncoded + 1 + lenBytes, dataLen, - str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2; - str[value->Value.cbData / 2] = 0; - value->Value.cbData += 2; - break; - } - } - else - { - value->Value.cbData = 0; - value->Value.pbData = NULL; - } + value->Value.cbData = 0; + value->Value.pbData = NULL; } } } @@ -1639,7 +1630,7 @@ static BOOL WINAPI CRYPT_AsnDecodeRdnAttr(DWORD dwCertEncodingType, }; CERT_RDN_ATTR *attr = (CERT_RDN_ATTR *)pvStructInfo; - TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo); if (attr) @@ -1651,9 +1642,9 @@ static BOOL WINAPI CRYPT_AsnDecodeRdnAttr(DWORD dwCertEncodingType, { TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId, debugstr_a(attr->pszObjId)); - TRACE("attr->dwValueType is %ld\n", attr->dwValueType); + TRACE("attr->dwValueType is %d\n", attr->dwValueType); } - TRACE("returning %d (%08lx)\n", ret, GetLastError()); + TRACE("returning %d (%08x)\n", ret, GetLastError()); return ret; } @@ -1696,6 +1687,78 @@ static BOOL WINAPI CRYPT_AsnDecodeName(DWORD dwCertEncodingType, return ret; } +static BOOL WINAPI CRYPT_AsnDecodeUnicodeRdnAttr(DWORD dwCertEncodingType, + LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, + PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) +{ + BOOL ret; + struct AsnDecodeSequenceItem items[] = { + { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId), + CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE, + offsetof(CERT_RDN_ATTR, pszObjId), 0 }, + { 0, offsetof(CERT_RDN_ATTR, dwValueType), + CRYPT_AsnDecodeUnicodeNameValueInternal, sizeof(CERT_NAME_VALUE), + FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 }, + }; + CERT_RDN_ATTR *attr = (CERT_RDN_ATTR *)pvStructInfo; + + TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + pvStructInfo, *pcbStructInfo); + + if (attr) + TRACE("attr->pszObjId is %p\n", attr->pszObjId); + ret = CRYPT_AsnDecodeSequence(X509_ASN_ENCODING, items, + sizeof(items) / sizeof(items[0]), pbEncoded, cbEncoded, dwFlags, NULL, + attr, pcbStructInfo, attr ? attr->pszObjId : NULL); + if (attr) + { + TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId, + debugstr_a(attr->pszObjId)); + TRACE("attr->dwValueType is %d\n", attr->dwValueType); + } + TRACE("returning %d (%08x)\n", ret, GetLastError()); + return ret; +} + +static BOOL WINAPI CRYPT_AsnDecodeUnicodeRdn(DWORD dwCertEncodingType, + LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, + PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) +{ + BOOL ret = TRUE; + struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF, + CRYPT_AsnDecodeUnicodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE, + offsetof(CERT_RDN_ATTR, pszObjId) }; + PCERT_RDN rdn = (PCERT_RDN)pvStructInfo; + + ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, + pDecodePara, pvStructInfo, pcbStructInfo, rdn ? rdn->rgRDNAttr : NULL); + return ret; +} + +static BOOL WINAPI CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType, + LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, + PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) +{ + BOOL ret = TRUE; + + __TRY + { + struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, + CRYPT_AsnDecodeUnicodeRdn, sizeof(CERT_RDN), TRUE, + offsetof(CERT_RDN, rgRDNAttr) }; + + ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, + pDecodePara, pvStructInfo, pcbStructInfo, NULL); + } + __EXCEPT_PAGE_FAULT + { + SetLastError(STATUS_ACCESS_VIOLATION); + ret = FALSE; + } + __ENDTRY + return ret; +} + static BOOL WINAPI CRYPT_AsnDecodeCopyBytes(DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) @@ -1703,7 +1766,7 @@ static BOOL WINAPI CRYPT_AsnDecodeCopyBytes(DWORD dwCertEncodingType, BOOL ret = TRUE; DWORD bytesNeeded = sizeof(CRYPT_OBJID_BLOB); - TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG)) @@ -1749,7 +1812,7 @@ static BOOL WINAPI CRYPT_AsnDecodeAlgorithmId(DWORD dwCertEncodingType, offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters.pbData), 0 }, }; - TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); ret = CRYPT_AsnDecodeSequence(dwCertEncodingType, items, @@ -1865,7 +1928,7 @@ static BOOL WINAPI CRYPT_AsnDecodeBool(DWORD dwCertEncodingType, *(BOOL *)pvStructInfo = pbEncoded[2] ? TRUE : FALSE; ret = TRUE; } - TRACE("returning %d (%08lx)\n", ret, GetLastError()); + TRACE("returning %d (%08x)\n", ret, GetLastError()); return ret; } @@ -1877,7 +1940,7 @@ static BOOL WINAPI CRYPT_AsnDecodeAltNameEntry(DWORD dwCertEncodingType, DWORD dataLen, lenBytes, bytesNeeded = sizeof(CERT_ALT_NAME_ENTRY); BOOL ret; - TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); if (cbEncoded < 2) @@ -1982,7 +2045,7 @@ static BOOL WINAPI CRYPT_AsnDecodeAltNameInternal(DWORD dwCertEncodingType, offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) }; PCERT_ALT_NAME_INFO info = (PCERT_ALT_NAME_INFO)pvStructInfo; - TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); if (info) @@ -1992,13 +2055,48 @@ static BOOL WINAPI CRYPT_AsnDecodeAltNameInternal(DWORD dwCertEncodingType, return ret; } +static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType, + LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, + PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) +{ + BOOL ret; + + __TRY + { + struct AsnDecodeSequenceItem items[] = { + { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId), + CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_DATA_BLOB), + TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId.pbData), 0 }, + { ASN_CONTEXT | ASN_CONSTRUCTOR| 1, + offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer), + CRYPT_AsnDecodeOctetsInternal, sizeof(CERT_NAME_BLOB), TRUE, TRUE, + offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer.pbData), 0 }, + { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO, + CertSerialNumber), CRYPT_AsnDecodeIntegerInternal, + sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE, + offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertSerialNumber.pbData), 0 }, + }; + + ret = CRYPT_AsnDecodeSequence(dwCertEncodingType, items, + sizeof(items) / sizeof(items[0]), pbEncoded, cbEncoded, dwFlags, + pDecodePara, pvStructInfo, pcbStructInfo, NULL); + } + __EXCEPT_PAGE_FAULT + { + SetLastError(STATUS_ACCESS_VIOLATION); + ret = FALSE; + } + __ENDTRY + return ret; +} + static BOOL WINAPI CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) { BOOL ret = TRUE; - TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); __TRY @@ -2031,7 +2129,7 @@ static BOOL WINAPI CRYPT_AsnDecodePathLenConstraint(DWORD dwCertEncodingType, { BOOL ret = TRUE; - TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo); if (cbEncoded) @@ -2059,7 +2157,7 @@ static BOOL WINAPI CRYPT_AsnDecodePathLenConstraint(DWORD dwCertEncodingType, &constraint->dwPathLenConstraint, &size); if (ret) constraint->fPathLenConstraint = TRUE; - TRACE("got an int, dwPathLenConstraint is %ld\n", + TRACE("got an int, dwPathLenConstraint is %d\n", constraint->dwPathLenConstraint); } } @@ -2069,7 +2167,7 @@ static BOOL WINAPI CRYPT_AsnDecodePathLenConstraint(DWORD dwCertEncodingType, ret = FALSE; } } - TRACE("returning %d (%08lx)\n", ret, GetLastError()); + TRACE("returning %d (%08x)\n", ret, GetLastError()); return ret; } @@ -2083,13 +2181,13 @@ static BOOL WINAPI CRYPT_AsnDecodeSubtreeConstraints(DWORD dwCertEncodingType, offsetof(CERT_NAME_BLOB, pbData) }; struct GenericArray *entries = (struct GenericArray *)pvStructInfo; - TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, entries ? entries->rgItems : NULL); - TRACE("Returning %d (%08lx)\n", ret, GetLastError()); + TRACE("Returning %d (%08x)\n", ret, GetLastError()); return ret; } @@ -2237,7 +2335,7 @@ static BOOL WINAPI CRYPT_AsnDecodeOctetsInternal(DWORD dwCertEncodingType, BOOL ret; DWORD bytesNeeded, dataLen; - TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) @@ -2281,7 +2379,7 @@ static BOOL WINAPI CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType, { BOOL ret; - TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); __TRY @@ -2335,7 +2433,7 @@ static BOOL WINAPI CRYPT_AsnDecodeBitsInternal(DWORD dwCertEncodingType, { BOOL ret; - TRACE("(%p, %ld, 0x%08lx, %p, %p, %ld)\n", pbEncoded, cbEncoded, dwFlags, + TRACE("(%p, %d, 0x%08x, %p, %p, %d)\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); if (pbEncoded[0] == ASN_BITSTRING) @@ -2389,7 +2487,7 @@ static BOOL WINAPI CRYPT_AsnDecodeBitsInternal(DWORD dwCertEncodingType, SetLastError(CRYPT_E_ASN1_BADTAG); ret = FALSE; } - TRACE("returning %d (%08lx)\n", ret, GetLastError()); + TRACE("returning %d (%08x)\n", ret, GetLastError()); return ret; } @@ -2399,7 +2497,7 @@ static BOOL WINAPI CRYPT_AsnDecodeBits(DWORD dwCertEncodingType, { BOOL ret; - TRACE("(%p, %ld, 0x%08lx, %p, %p, %p)\n", pbEncoded, cbEncoded, dwFlags, + TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo); __TRY @@ -2434,7 +2532,7 @@ static BOOL WINAPI CRYPT_AsnDecodeBits(DWORD dwCertEncodingType, ret = FALSE; } __ENDTRY - TRACE("returning %d (%08lx)\n", ret, GetLastError()); + TRACE("returning %d (%08x)\n", ret, GetLastError()); return ret; } @@ -2456,8 +2554,15 @@ static BOOL WINAPI CRYPT_AsnDecodeInt(DWORD dwCertEncodingType, DWORD size = sizeof(buf); blob->pbData = buf + sizeof(CRYPT_INTEGER_BLOB); - ret = CRYPT_AsnDecodeIntegerInternal(dwCertEncodingType, - X509_MULTI_BYTE_INTEGER, pbEncoded, cbEncoded, 0, NULL, &buf, &size); + if (pbEncoded[0] != ASN_INTEGER) + { + SetLastError(CRYPT_E_ASN1_BADTAG); + ret = FALSE; + } + else + ret = CRYPT_AsnDecodeIntegerInternal(dwCertEncodingType, + X509_MULTI_BYTE_INTEGER, pbEncoded, cbEncoded, 0, NULL, &buf, + &size); if (ret) { if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, @@ -2499,48 +2604,39 @@ static BOOL WINAPI CRYPT_AsnDecodeIntegerInternal(DWORD dwCertEncodingType, PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) { BOOL ret; + DWORD bytesNeeded, dataLen; - if (pbEncoded[0] == ASN_INTEGER) + if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) { - DWORD bytesNeeded, dataLen; + BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); - if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) + bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB); + if (!pvStructInfo) + *pcbStructInfo = bytesNeeded; + else if (*pcbStructInfo < bytesNeeded) { - BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); + *pcbStructInfo = bytesNeeded; + SetLastError(ERROR_MORE_DATA); + ret = FALSE; + } + else + { + CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)pvStructInfo; - bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB); - if (!pvStructInfo) - *pcbStructInfo = bytesNeeded; - else if (*pcbStructInfo < bytesNeeded) + blob->cbData = dataLen; + assert(blob->pbData); + if (blob->cbData) { - *pcbStructInfo = bytesNeeded; - SetLastError(ERROR_MORE_DATA); - ret = FALSE; - } - else - { - CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)pvStructInfo; + DWORD i; - blob->cbData = dataLen; - assert(blob->pbData); - if (blob->cbData) + for (i = 0; i < blob->cbData; i++) { - DWORD i; - - for (i = 0; i < blob->cbData; i++) - { - blob->pbData[i] = *(pbEncoded + 1 + lenBytes + - dataLen - i - 1); - } + blob->pbData[i] = *(pbEncoded + 1 + lenBytes + + dataLen - i - 1); } } } } - else - { - SetLastError(CRYPT_E_ASN1_BADTAG); - ret = FALSE; - } return ret; } @@ -2554,9 +2650,16 @@ static BOOL WINAPI CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType, { DWORD bytesNeeded; - if ((ret = CRYPT_AsnDecodeIntegerInternal(dwCertEncodingType, - lpszStructType, pbEncoded, cbEncoded, - dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, NULL, &bytesNeeded))) + if (pbEncoded[0] != ASN_INTEGER) + { + SetLastError(CRYPT_E_ASN1_BADTAG); + ret = FALSE; + } + else + ret = CRYPT_AsnDecodeIntegerInternal(dwCertEncodingType, + lpszStructType, pbEncoded, cbEncoded, + dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, NULL, &bytesNeeded); + if (ret) { if (!pvStructInfo) *pcbStructInfo = bytesNeeded; @@ -3253,7 +3356,7 @@ static BOOL WINAPI CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType, { BOOL ret; - TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); __TRY @@ -3280,7 +3383,7 @@ static BOOL WINAPI CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType, { BOOL ret; - TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); __TRY @@ -3306,7 +3409,7 @@ static BOOL WINAPI CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType, { BOOL ret; - TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, + TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo); __TRY @@ -3353,7 +3456,7 @@ BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, CryptDecodeObjectExFunc decodeFunc = NULL; HCRYPTOIDFUNCADDR hFunc = NULL; - TRACE("(0x%08lx, %s, %p, %ld, 0x%08lx, %p, %p, %p)\n", + TRACE("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n", dwCertEncodingType, debugstr_a(lpszStructType), pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo); @@ -3407,6 +3510,9 @@ BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, case (WORD)X509_PUBLIC_KEY_INFO: decodeFunc = CRYPT_AsnDecodePubKeyInfo; break; + case (WORD)X509_AUTHORITY_KEY_ID: + decodeFunc = CRYPT_AsnDecodeAuthorityKeyId; + break; case (WORD)X509_ALTERNATE_NAME: decodeFunc = CRYPT_AsnDecodeAltName; break; @@ -3419,6 +3525,9 @@ BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, case (WORD)RSA_CSP_PUBLICKEYBLOB: decodeFunc = CRYPT_AsnDecodeRsaPubKey; break; + case (WORD)X509_UNICODE_NAME: + decodeFunc = CRYPT_AsnDecodeUnicodeName; + break; case (WORD)X509_UNICODE_NAME_VALUE: decodeFunc = CRYPT_AsnDecodeUnicodeNameValue; break; @@ -3467,6 +3576,8 @@ BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, decodeFunc = CRYPT_AsnDecodeExtensions; else if (!strcmp(lpszStructType, szOID_RSA_signingTime)) decodeFunc = CRYPT_AsnDecodeUtcTime; + else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER)) + decodeFunc = CRYPT_AsnDecodeAuthorityKeyId; else if (!strcmp(lpszStructType, szOID_CRL_REASON_CODE)) decodeFunc = CRYPT_AsnDecodeEnumerated; else if (!strcmp(lpszStructType, szOID_KEY_USAGE)) diff --git a/reactos/dll/win32/crypt32/encode.c b/reactos/dll/win32/crypt32/encode.c index d1c8ff72489..d897617d9b9 100644 --- a/reactos/dll/win32/crypt32/encode.c +++ b/reactos/dll/win32/crypt32/encode.c @@ -106,7 +106,7 @@ BOOL WINAPI CryptEncodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType, HCRYPTOIDFUNCADDR hFunc; CryptEncodeObjectFunc pCryptEncodeObject; - TRACE("(0x%08lx, %s, %p, %p, %p)\n", dwCertEncodingType, + TRACE("(0x%08x, %s, %p, %p, %p)\n", dwCertEncodingType, debugstr_a(lpszStructType), pvStructInfo, pbEncoded, pcbEncoded); @@ -225,7 +225,7 @@ static BOOL WINAPI CRYPT_AsnEncodeSequence(DWORD dwCertEncodingType, BOOL ret; DWORD i, dataLen = 0; - TRACE("%p, %ld, %08lx, %p, %p, %ld\n", items, cItem, dwFlags, pEncodePara, + TRACE("%p, %d, %08x, %p, %p, %d\n", items, cItem, dwFlags, pEncodePara, pbEncoded, *pcbEncoded); for (i = 0, ret = TRUE; ret && i < cItem; i++) { @@ -268,7 +268,7 @@ static BOOL WINAPI CRYPT_AsnEncodeSequence(DWORD dwCertEncodingType, } } } - TRACE("returning %d (%08lx)\n", ret, GetLastError()); + TRACE("returning %d (%08x)\n", ret, GetLastError()); return ret; } @@ -590,7 +590,7 @@ static BOOL WINAPI CRYPT_AsnEncodeCRLEntry(const CRL_ENTRY *entry, ret = CRYPT_AsnEncodeSequence(X509_ASN_ENCODING, items, cItem, 0, NULL, pbEncoded, pcbEncoded); - TRACE("returning %d (%08lx)\n", ret, GetLastError()); + TRACE("returning %d (%08x)\n", ret, GetLastError()); return ret; } @@ -600,7 +600,7 @@ static BOOL WINAPI CRYPT_AsnEncodeCRLEntries(DWORD dwCertEncodingType, { DWORD cCRLEntry = *(const DWORD *)pvStructInfo; DWORD bytesNeeded, dataLen, lenBytes, i; - const CRL_ENTRY *rgCRLEntry = *(const CRL_ENTRY **) + const CRL_ENTRY *rgCRLEntry = *(const CRL_ENTRY *const *) ((const BYTE *)pvStructInfo + sizeof(DWORD)); BOOL ret = TRUE; @@ -727,7 +727,7 @@ static BOOL CRYPT_AsnEncodeExtension(CERT_EXTENSION *ext, BYTE *pbEncoded, }; DWORD cItem = 1; - TRACE("%p, %p, %ld\n", ext, pbEncoded, *pcbEncoded); + TRACE("%p, %p, %d\n", ext, pbEncoded, *pcbEncoded); if (ext->fCritical) { @@ -741,7 +741,7 @@ static BOOL CRYPT_AsnEncodeExtension(CERT_EXTENSION *ext, BYTE *pbEncoded, ret = CRYPT_AsnEncodeSequence(X509_ASN_ENCODING, items, cItem, 0, NULL, pbEncoded, pcbEncoded); - TRACE("returning %d (%08lx)\n", ret, GetLastError()); + TRACE("returning %d (%08x)\n", ret, GetLastError()); return ret; } @@ -1019,7 +1019,7 @@ static BOOL WINAPI CRYPT_AsnEncodeNameValue(DWORD dwCertEncodingType, __TRY { - const CERT_NAME_VALUE *value = (CERT_NAME_VALUE *)pvStructInfo; + const CERT_NAME_VALUE *value = (const CERT_NAME_VALUE *)pvStructInfo; switch (value->dwValueType) { @@ -1095,6 +1095,262 @@ static BOOL WINAPI CRYPT_AsnEncodeNameValue(DWORD dwCertEncodingType, return ret; } +static BOOL WINAPI CRYPT_AsnEncodeRdnAttr(DWORD dwCertEncodingType, + CERT_RDN_ATTR *attr, CryptEncodeObjectExFunc nameValueEncodeFunc, + BYTE *pbEncoded, DWORD *pcbEncoded) +{ + DWORD bytesNeeded = 0, lenBytes, size; + BOOL ret; + + ret = CRYPT_AsnEncodeOid(dwCertEncodingType, NULL, attr->pszObjId, + 0, NULL, NULL, &size); + if (ret) + { + bytesNeeded += size; + /* hack: a CERT_RDN_ATTR is identical to a CERT_NAME_VALUE beginning + * with dwValueType, so "cast" it to get its encoded size + */ + ret = nameValueEncodeFunc(dwCertEncodingType, NULL, + (CERT_NAME_VALUE *)&attr->dwValueType, 0, NULL, NULL, &size); + if (ret) + { + bytesNeeded += size; + CRYPT_EncodeLen(bytesNeeded, NULL, &lenBytes); + bytesNeeded += 1 + lenBytes; + if (pbEncoded) + { + if (*pcbEncoded < bytesNeeded) + { + SetLastError(ERROR_MORE_DATA); + ret = FALSE; + } + else + { + *pbEncoded++ = ASN_SEQUENCE; + CRYPT_EncodeLen(bytesNeeded - lenBytes - 1, pbEncoded, + &lenBytes); + pbEncoded += lenBytes; + size = bytesNeeded - 1 - lenBytes; + ret = CRYPT_AsnEncodeOid(dwCertEncodingType, NULL, + attr->pszObjId, 0, NULL, pbEncoded, &size); + if (ret) + { + pbEncoded += size; + size = bytesNeeded - 1 - lenBytes - size; + ret = nameValueEncodeFunc(dwCertEncodingType, + NULL, (CERT_NAME_VALUE *)&attr->dwValueType, + 0, NULL, pbEncoded, &size); + if (!ret) + *pcbEncoded = size; + } + } + } + if (ret) + *pcbEncoded = bytesNeeded; + } + else + { + /* Have to propagate index of failing character */ + *pcbEncoded = size; + } + } + return ret; +} + +static int BLOBComp(const void *l, const void *r) +{ + const CRYPT_DER_BLOB *a = (const CRYPT_DER_BLOB *)l, *b = (const CRYPT_DER_BLOB *)r; + int ret; + + if (!(ret = memcmp(a->pbData, b->pbData, min(a->cbData, b->cbData)))) + ret = a->cbData - b->cbData; + return ret; +} + +/* This encodes as a SET OF, which in DER must be lexicographically sorted. + */ +static BOOL WINAPI CRYPT_AsnEncodeRdn(DWORD dwCertEncodingType, CERT_RDN *rdn, + CryptEncodeObjectExFunc nameValueEncodeFunc, BYTE *pbEncoded, + DWORD *pcbEncoded) +{ + BOOL ret; + CRYPT_DER_BLOB *blobs = NULL; + + __TRY + { + DWORD bytesNeeded = 0, lenBytes, i; + + blobs = NULL; + ret = TRUE; + if (rdn->cRDNAttr) + { + blobs = CryptMemAlloc(rdn->cRDNAttr * sizeof(CRYPT_DER_BLOB)); + if (!blobs) + ret = FALSE; + else + memset(blobs, 0, rdn->cRDNAttr * sizeof(CRYPT_DER_BLOB)); + } + for (i = 0; ret && i < rdn->cRDNAttr; i++) + { + ret = CRYPT_AsnEncodeRdnAttr(dwCertEncodingType, &rdn->rgRDNAttr[i], + nameValueEncodeFunc, NULL, &blobs[i].cbData); + if (ret) + bytesNeeded += blobs[i].cbData; + else + { + /* Have to propagate index of failing character */ + *pcbEncoded = blobs[i].cbData; + } + } + if (ret) + { + CRYPT_EncodeLen(bytesNeeded, NULL, &lenBytes); + bytesNeeded += 1 + lenBytes; + if (pbEncoded) + { + if (*pcbEncoded < bytesNeeded) + { + SetLastError(ERROR_MORE_DATA); + ret = FALSE; + } + else + { + for (i = 0; ret && i < rdn->cRDNAttr; i++) + { + blobs[i].pbData = CryptMemAlloc(blobs[i].cbData); + if (!blobs[i].pbData) + ret = FALSE; + else + { + ret = CRYPT_AsnEncodeRdnAttr(dwCertEncodingType, + &rdn->rgRDNAttr[i], nameValueEncodeFunc, + blobs[i].pbData, &blobs[i].cbData); + if (!ret) + *pcbEncoded = blobs[i].cbData; + } + } + if (ret) + { + qsort(blobs, rdn->cRDNAttr, sizeof(CRYPT_DER_BLOB), + BLOBComp); + *pbEncoded++ = ASN_CONSTRUCTOR | ASN_SETOF; + CRYPT_EncodeLen(bytesNeeded - lenBytes - 1, pbEncoded, + &lenBytes); + pbEncoded += lenBytes; + for (i = 0; ret && i < rdn->cRDNAttr; i++) + { + memcpy(pbEncoded, blobs[i].pbData, blobs[i].cbData); + pbEncoded += blobs[i].cbData; + } + } + } + } + if (ret) + *pcbEncoded = bytesNeeded; + } + if (blobs) + { + for (i = 0; i < rdn->cRDNAttr; i++) + CryptMemFree(blobs[i].pbData); + } + } + __EXCEPT_PAGE_FAULT + { + SetLastError(STATUS_ACCESS_VIOLATION); + ret = FALSE; + } + __ENDTRY + CryptMemFree(blobs); + return ret; +} + +static BOOL WINAPI CRYPT_AsnEncodeUnicodeNameValue(DWORD dwCertEncodingType, + LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, + PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded); + +static BOOL WINAPI CRYPT_AsnEncodeOrCopyUnicodeNameValue( + DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo, + DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, + DWORD *pcbEncoded) +{ + const CERT_NAME_VALUE *value = (const CERT_NAME_VALUE *)pvStructInfo; + BOOL ret; + + if (value->dwValueType == CERT_RDN_ENCODED_BLOB) + ret = CRYPT_CopyEncodedBlob(dwCertEncodingType, NULL, &value->Value, + dwFlags, pEncodePara, pbEncoded, pcbEncoded); + else + ret = CRYPT_AsnEncodeUnicodeNameValue(dwCertEncodingType, NULL, value, + dwFlags, pEncodePara, pbEncoded, pcbEncoded); + return ret; +} + +static BOOL WINAPI CRYPT_AsnEncodeUnicodeName(DWORD dwCertEncodingType, + LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, + PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded) +{ + BOOL ret = TRUE; + + __TRY + { + const CERT_NAME_INFO *info = (const CERT_NAME_INFO *)pvStructInfo; + DWORD bytesNeeded = 0, lenBytes, size, i; + + TRACE("encoding name with %d RDNs\n", info->cRDN); + ret = TRUE; + for (i = 0; ret && i < info->cRDN; i++) + { + ret = CRYPT_AsnEncodeRdn(dwCertEncodingType, &info->rgRDN[i], + CRYPT_AsnEncodeOrCopyUnicodeNameValue, NULL, &size); + if (ret) + bytesNeeded += size; + else + *pcbEncoded = size; + } + CRYPT_EncodeLen(bytesNeeded, NULL, &lenBytes); + bytesNeeded += 1 + lenBytes; + if (ret) + { + if (!pbEncoded) + *pcbEncoded = bytesNeeded; + else + { + if ((ret = CRYPT_EncodeEnsureSpace(dwFlags, pEncodePara, + pbEncoded, pcbEncoded, bytesNeeded))) + { + if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG) + pbEncoded = *(BYTE **)pbEncoded; + *pbEncoded++ = ASN_SEQUENCEOF; + CRYPT_EncodeLen(bytesNeeded - lenBytes - 1, pbEncoded, + &lenBytes); + pbEncoded += lenBytes; + for (i = 0; ret && i < info->cRDN; i++) + { + size = bytesNeeded; + ret = CRYPT_AsnEncodeRdn(dwCertEncodingType, + &info->rgRDN[i], CRYPT_AsnEncodeOrCopyUnicodeNameValue, + pbEncoded, &size); + if (ret) + { + pbEncoded += size; + bytesNeeded -= size; + } + else + *pcbEncoded = size; + } + } + } + } + } + __EXCEPT_PAGE_FAULT + { + SetLastError(STATUS_ACCESS_VIOLATION); + ret = FALSE; + } + __ENDTRY + return ret; +} + static BOOL CRYPT_AsnEncodeUnicodeStringCoerce(const CERT_NAME_VALUE *value, BYTE tag, DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded) @@ -1308,7 +1564,7 @@ static BOOL WINAPI CRYPT_AsnEncodeUnicodeNameValue(DWORD dwCertEncodingType, __TRY { - const CERT_NAME_VALUE *value = (CERT_NAME_VALUE *)pvStructInfo; + const CERT_NAME_VALUE *value = (const CERT_NAME_VALUE *)pvStructInfo; switch (value->dwValueType) { @@ -1373,155 +1629,6 @@ static BOOL WINAPI CRYPT_AsnEncodeUnicodeNameValue(DWORD dwCertEncodingType, return ret; } -static BOOL WINAPI CRYPT_AsnEncodeRdnAttr(DWORD dwCertEncodingType, - CERT_RDN_ATTR *attr, BYTE *pbEncoded, DWORD *pcbEncoded) -{ - DWORD bytesNeeded = 0, lenBytes, size; - BOOL ret; - - ret = CRYPT_AsnEncodeOid(dwCertEncodingType, NULL, attr->pszObjId, - 0, NULL, NULL, &size); - if (ret) - { - bytesNeeded += size; - /* hack: a CERT_RDN_ATTR is identical to a CERT_NAME_VALUE beginning - * with dwValueType, so "cast" it to get its encoded size - */ - ret = CRYPT_AsnEncodeNameValue(dwCertEncodingType, X509_NAME_VALUE, - (CERT_NAME_VALUE *)&attr->dwValueType, 0, NULL, NULL, &size); - if (ret) - { - bytesNeeded += size; - CRYPT_EncodeLen(bytesNeeded, NULL, &lenBytes); - bytesNeeded += 1 + lenBytes; - if (pbEncoded) - { - if (*pcbEncoded < bytesNeeded) - { - SetLastError(ERROR_MORE_DATA); - ret = FALSE; - } - else - { - *pbEncoded++ = ASN_SEQUENCE; - CRYPT_EncodeLen(bytesNeeded - lenBytes - 1, pbEncoded, - &lenBytes); - pbEncoded += lenBytes; - size = bytesNeeded - 1 - lenBytes; - ret = CRYPT_AsnEncodeOid(dwCertEncodingType, NULL, - attr->pszObjId, 0, NULL, pbEncoded, &size); - if (ret) - { - pbEncoded += size; - size = bytesNeeded - 1 - lenBytes - size; - ret = CRYPT_AsnEncodeNameValue(dwCertEncodingType, - X509_NAME_VALUE, (CERT_NAME_VALUE *)&attr->dwValueType, - 0, NULL, pbEncoded, &size); - } - } - } - *pcbEncoded = bytesNeeded; - } - } - return ret; -} - -static int BLOBComp(const void *l, const void *r) -{ - CRYPT_DER_BLOB *a = (CRYPT_DER_BLOB *)l, *b = (CRYPT_DER_BLOB *)r; - int ret; - - if (!(ret = memcmp(a->pbData, b->pbData, min(a->cbData, b->cbData)))) - ret = a->cbData - b->cbData; - return ret; -} - -/* This encodes as a SET OF, which in DER must be lexicographically sorted. - */ -static BOOL WINAPI CRYPT_AsnEncodeRdn(DWORD dwCertEncodingType, CERT_RDN *rdn, - BYTE *pbEncoded, DWORD *pcbEncoded) -{ - BOOL ret; - CRYPT_DER_BLOB *blobs = NULL; - - __TRY - { - DWORD bytesNeeded = 0, lenBytes, i; - - blobs = NULL; - ret = TRUE; - if (rdn->cRDNAttr) - { - blobs = CryptMemAlloc(rdn->cRDNAttr * sizeof(CRYPT_DER_BLOB)); - if (!blobs) - ret = FALSE; - else - memset(blobs, 0, rdn->cRDNAttr * sizeof(CRYPT_DER_BLOB)); - } - for (i = 0; ret && i < rdn->cRDNAttr; i++) - { - ret = CRYPT_AsnEncodeRdnAttr(dwCertEncodingType, &rdn->rgRDNAttr[i], - NULL, &blobs[i].cbData); - if (ret) - bytesNeeded += blobs[i].cbData; - } - if (ret) - { - CRYPT_EncodeLen(bytesNeeded, NULL, &lenBytes); - bytesNeeded += 1 + lenBytes; - if (pbEncoded) - { - if (*pcbEncoded < bytesNeeded) - { - SetLastError(ERROR_MORE_DATA); - ret = FALSE; - } - else - { - for (i = 0; ret && i < rdn->cRDNAttr; i++) - { - blobs[i].pbData = CryptMemAlloc(blobs[i].cbData); - if (!blobs[i].pbData) - ret = FALSE; - else - ret = CRYPT_AsnEncodeRdnAttr(dwCertEncodingType, - &rdn->rgRDNAttr[i], blobs[i].pbData, - &blobs[i].cbData); - } - if (ret) - { - qsort(blobs, rdn->cRDNAttr, sizeof(CRYPT_DER_BLOB), - BLOBComp); - *pbEncoded++ = ASN_CONSTRUCTOR | ASN_SETOF; - CRYPT_EncodeLen(bytesNeeded - lenBytes - 1, pbEncoded, - &lenBytes); - pbEncoded += lenBytes; - for (i = 0; ret && i < rdn->cRDNAttr; i++) - { - memcpy(pbEncoded, blobs[i].pbData, blobs[i].cbData); - pbEncoded += blobs[i].cbData; - } - } - } - } - *pcbEncoded = bytesNeeded; - } - if (blobs) - { - for (i = 0; i < rdn->cRDNAttr; i++) - CryptMemFree(blobs[i].pbData); - } - } - __EXCEPT_PAGE_FAULT - { - SetLastError(STATUS_ACCESS_VIOLATION); - ret = FALSE; - } - __ENDTRY - CryptMemFree(blobs); - return ret; -} - static BOOL WINAPI CRYPT_AsnEncodeName(DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded) @@ -1533,12 +1640,12 @@ static BOOL WINAPI CRYPT_AsnEncodeName(DWORD dwCertEncodingType, const CERT_NAME_INFO *info = (const CERT_NAME_INFO *)pvStructInfo; DWORD bytesNeeded = 0, lenBytes, size, i; - TRACE("encoding name with %ld RDNs\n", info->cRDN); + TRACE("encoding name with %d RDNs\n", info->cRDN); ret = TRUE; for (i = 0; ret && i < info->cRDN; i++) { - ret = CRYPT_AsnEncodeRdn(dwCertEncodingType, &info->rgRDN[i], NULL, - &size); + ret = CRYPT_AsnEncodeRdn(dwCertEncodingType, &info->rgRDN[i], + CRYPT_AsnEncodeNameValue, NULL, &size); if (ret) bytesNeeded += size; } @@ -1563,7 +1670,8 @@ static BOOL WINAPI CRYPT_AsnEncodeName(DWORD dwCertEncodingType, { size = bytesNeeded; ret = CRYPT_AsnEncodeRdn(dwCertEncodingType, - &info->rgRDN[i], pbEncoded, &size); + &info->rgRDN[i], CRYPT_AsnEncodeNameValue, pbEncoded, + &size); if (ret) { pbEncoded += size; @@ -1610,7 +1718,7 @@ static BOOL WINAPI CRYPT_AsnEncodeBool(DWORD dwCertEncodingType, *pbEncoded++ = val ? 0xff : 0; ret = TRUE; } - TRACE("returning %d (%08lx)\n", ret, GetLastError()); + TRACE("returning %d (%08x)\n", ret, GetLastError()); return ret; } @@ -1652,7 +1760,7 @@ static BOOL CRYPT_AsnEncodeAltNameEntry(const CERT_ALT_NAME_ENTRY *entry, /* FIXME: encode OID */ case CERT_ALT_NAME_OTHER_NAME: case CERT_ALT_NAME_DIRECTORY_NAME: - FIXME("name type %ld unimplemented\n", entry->dwAltNameChoice); + FIXME("name type %d unimplemented\n", entry->dwAltNameChoice); return FALSE; default: SetLastError(E_INVALIDARG); @@ -1697,7 +1805,63 @@ static BOOL CRYPT_AsnEncodeAltNameEntry(const CERT_ALT_NAME_ENTRY *entry, *pcbEncoded = bytesNeeded; } } - TRACE("returning %d (%08lx)\n", ret, GetLastError()); + TRACE("returning %d (%08x)\n", ret, GetLastError()); + return ret; +} + +static BOOL WINAPI CRYPT_AsnEncodeAuthorityKeyId(DWORD dwCertEncodingType, + LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, + PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded) +{ + BOOL ret; + + __TRY + { + const CERT_AUTHORITY_KEY_ID_INFO *info = + (const CERT_AUTHORITY_KEY_ID_INFO *)pvStructInfo; + struct AsnEncodeSequenceItem items[3] = { { 0 } }; + struct AsnEncodeTagSwappedItem swapped[3] = { { 0 } }; + struct AsnConstructedItem constructed = { 0 }; + DWORD cItem = 0, cSwapped = 0; + + if (info->KeyId.cbData) + { + swapped[cSwapped].tag = ASN_CONTEXT | 0; + swapped[cSwapped].pvStructInfo = &info->KeyId; + swapped[cSwapped].encodeFunc = CRYPT_AsnEncodeInteger; + items[cItem].pvStructInfo = &swapped[cSwapped]; + items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag; + cSwapped++; + cItem++; + } + if (info->CertIssuer.cbData) + { + constructed.tag = 1; + constructed.pvStructInfo = &info->CertIssuer; + constructed.encodeFunc = CRYPT_CopyEncodedBlob; + items[cItem].pvStructInfo = &constructed; + items[cItem].encodeFunc = CRYPT_AsnEncodeConstructed; + cItem++; + } + if (info->CertSerialNumber.cbData) + { + swapped[cSwapped].tag = ASN_CONTEXT | 2; + swapped[cSwapped].pvStructInfo = &info->CertSerialNumber; + swapped[cSwapped].encodeFunc = CRYPT_AsnEncodeInteger; + items[cItem].pvStructInfo = &swapped[cSwapped]; + items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag; + cSwapped++; + cItem++; + } + ret = CRYPT_AsnEncodeSequence(X509_ASN_ENCODING, items, cItem, dwFlags, + pEncodePara, pbEncoded, pcbEncoded); + } + __EXCEPT_PAGE_FAULT + { + SetLastError(STATUS_ACCESS_VIOLATION); + ret = FALSE; + } + __ENDTRY return ret; } @@ -1908,7 +2072,7 @@ static BOOL WINAPI CRYPT_AsnEncodeOctets(DWORD dwCertEncodingType, const CRYPT_DATA_BLOB *blob = (const CRYPT_DATA_BLOB *)pvStructInfo; DWORD bytesNeeded, lenBytes; - TRACE("(%ld, %p), %08lx, %p, %p, %ld\n", blob->cbData, blob->pbData, + TRACE("(%d, %p), %08x, %p, %p, %d\n", blob->cbData, blob->pbData, dwFlags, pEncodePara, pbEncoded, *pcbEncoded); CRYPT_EncodeLen(blob->cbData, NULL, &lenBytes); @@ -1939,7 +2103,7 @@ static BOOL WINAPI CRYPT_AsnEncodeOctets(DWORD dwCertEncodingType, ret = FALSE; } __ENDTRY - TRACE("returning %d (%08lx)\n", ret, GetLastError()); + TRACE("returning %d (%08x)\n", ret, GetLastError()); return ret; } @@ -2731,7 +2895,7 @@ BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, CryptEncodeObjectExFunc encodeFunc = NULL; HCRYPTOIDFUNCADDR hFunc = NULL; - TRACE("(0x%08lx, %s, %p, 0x%08lx, %p, %p, %p)\n", dwCertEncodingType, + TRACE("(0x%08x, %s, %p, 0x%08x, %p, %p, %p)\n", dwCertEncodingType, debugstr_a(lpszStructType), pvStructInfo, dwFlags, pEncodePara, pvEncoded, pcbEncoded); @@ -2775,6 +2939,9 @@ BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, case (WORD)X509_PUBLIC_KEY_INFO: encodeFunc = CRYPT_AsnEncodePubKeyInfo; break; + case (WORD)X509_AUTHORITY_KEY_ID: + encodeFunc = CRYPT_AsnEncodeAuthorityKeyId; + break; case (WORD)X509_ALTERNATE_NAME: encodeFunc = CRYPT_AsnEncodeAltName; break; @@ -2787,6 +2954,9 @@ BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, case (WORD)RSA_CSP_PUBLICKEYBLOB: encodeFunc = CRYPT_AsnEncodeRsaPubKey; break; + case (WORD)X509_UNICODE_NAME: + encodeFunc = CRYPT_AsnEncodeUnicodeName; + break; case (WORD)X509_UNICODE_NAME_VALUE: encodeFunc = CRYPT_AsnEncodeUnicodeNameValue; break; @@ -2835,6 +3005,8 @@ BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, encodeFunc = CRYPT_AsnEncodeExtensions; else if (!strcmp(lpszStructType, szOID_RSA_signingTime)) encodeFunc = CRYPT_AsnEncodeUtcTime; + else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER)) + encodeFunc = CRYPT_AsnEncodeAuthorityKeyId; else if (!strcmp(lpszStructType, szOID_CRL_REASON_CODE)) encodeFunc = CRYPT_AsnEncodeEnumerated; else if (!strcmp(lpszStructType, szOID_KEY_USAGE)) @@ -2896,7 +3068,7 @@ static BOOL WINAPI CRYPT_ExportRsaPublicKeyInfoEx(HCRYPTPROV hCryptProv, HCRYPTKEY key; static CHAR oid[] = szOID_RSA_RSA; - TRACE("(%ld, %ld, %08lx, %s, %08lx, %p, %p, %p)\n", hCryptProv, dwKeySpec, + TRACE("(%08lx, %d, %08x, %s, %08x, %p, %p, %p)\n", hCryptProv, dwKeySpec, dwCertEncodingType, debugstr_a(pszPublicKeyObjId), dwFlags, pvAuxInfo, pInfo, pcbInfo); @@ -2976,7 +3148,7 @@ BOOL WINAPI CryptExportPublicKeyInfoEx(HCRYPTPROV hCryptProv, DWORD dwKeySpec, ExportPublicKeyInfoExFunc exportFunc = NULL; HCRYPTOIDFUNCADDR hFunc = NULL; - TRACE("(%ld, %ld, %08lx, %s, %08lx, %p, %p, %p)\n", hCryptProv, dwKeySpec, + TRACE("(%08lx, %d, %08x, %s, %08x, %p, %p, %p)\n", hCryptProv, dwKeySpec, dwCertEncodingType, debugstr_a(pszPublicKeyObjId), dwFlags, pvAuxInfo, pInfo, pcbInfo); @@ -3017,7 +3189,7 @@ static BOOL WINAPI CRYPT_ImportRsaPublicKeyInfoEx(HCRYPTPROV hCryptProv, BOOL ret; DWORD pubKeySize = 0; - TRACE("(%ld, %ld, %p, %d, %08lx, %p, %p)\n", hCryptProv, + TRACE("(%08lx, %d, %p, %d, %08x, %p, %p)\n", hCryptProv, dwCertEncodingType, pInfo, aiKeyAlg, dwFlags, pvAuxInfo, phKey); ret = CryptDecodeObject(dwCertEncodingType, RSA_CSP_PUBLICKEYBLOB, @@ -3055,7 +3227,7 @@ BOOL WINAPI CryptImportPublicKeyInfoEx(HCRYPTPROV hCryptProv, ImportPublicKeyInfoExFunc importFunc = NULL; HCRYPTOIDFUNCADDR hFunc = NULL; - TRACE("(%ld, %ld, %p, %d, %08lx, %p, %p)\n", hCryptProv, + TRACE("(%08lx, %d, %p, %d, %08x, %p, %p)\n", hCryptProv, dwCertEncodingType, pInfo, aiKeyAlg, dwFlags, pvAuxInfo, phKey); if (!set) diff --git a/reactos/dll/win32/crypt32/main.c b/reactos/dll/win32/crypt32/main.c index f3e8a38d490..f5d68d55f88 100644 --- a/reactos/dll/win32/crypt32/main.c +++ b/reactos/dll/win32/crypt32/main.c @@ -27,6 +27,8 @@ #include "winreg.h" #include "winnls.h" #include "mssip.h" +#include "winuser.h" +#include "advpub.h" #include "crypt32_private.h" #include "wine/debug.h" @@ -75,149 +77,22 @@ BOOL WINAPI I_CryptCreateLruCache(void *unknown, HLRUCACHE *out) BOOL WINAPI I_CryptFindLruEntryData(DWORD unk0, DWORD unk1, DWORD unk2) { - FIXME("(%08lx, %08lx, %08lx): stub!\n", unk0, unk1, unk2); + FIXME("(%08x, %08x, %08x): stub!\n", unk0, unk1, unk2); return FALSE; } DWORD WINAPI I_CryptFlushLruCache(HLRUCACHE h, DWORD unk0, DWORD unk1) { - FIXME("(%p, %08lx, %08lx): stub!\n", h, unk0, unk1); + FIXME("(%p, %08x, %08x): stub!\n", h, unk0, unk1); return 0; } HLRUCACHE WINAPI I_CryptFreeLruCache(HLRUCACHE h, DWORD unk0, DWORD unk1) { - FIXME("(%p, %08lx, %08lx): stub!\n", h, unk0, unk1); + FIXME("(%p, %08x, %08x): stub!\n", h, unk0, unk1); return h; } -BOOL WINAPI CryptSIPRemoveProvider(GUID *pgProv) -{ - FIXME("stub!\n"); - return FALSE; -} - -/* convert a guid to a wide character string */ -static void CRYPT_guid2wstr( LPGUID guid, LPWSTR wstr ) -{ - char str[40]; - - sprintf(str, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", - guid->Data1, guid->Data2, guid->Data3, - guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], - guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] ); - MultiByteToWideChar( CP_ACP, 0, str, -1, wstr, 40 ); -} - -/* - * Helper for CryptSIPAddProvider - * - * Add a registry key containing a dll name and function under - * "Software\\Microsoft\\Cryptography\\OID\\EncodingType 0\\\\" - */ -static LONG CRYPT_SIPWriteFunction( LPGUID guid, LPCWSTR szKey, - LPCWSTR szDll, LPCWSTR szFunction ) -{ - static const WCHAR szOID[] = { - 'S','o','f','t','w','a','r','e','\\', - 'M','i','c','r','o','s','o','f','t','\\', - 'C','r','y','p','t','o','g','r','a','p','h','y','\\', - 'O','I','D','\\', - 'E','n','c','o','d','i','n','g','T','y','p','e',' ','0','\\', - 'C','r','y','p','t','S','I','P','D','l','l', 0 }; - static const WCHAR szBackSlash[] = { '\\', 0 }; - static const WCHAR szDllName[] = { 'D','l','l',0 }; - static const WCHAR szFuncName[] = { 'F','u','n','c','N','a','m','e',0 }; - WCHAR szFullKey[ 0x100 ]; - LONG r; - HKEY hKey; - - if( !szFunction ) - return ERROR_SUCCESS; - - /* max length of szFullKey depends on our code only, so we won't overrun */ - lstrcpyW( szFullKey, szOID ); - lstrcatW( szFullKey, szKey ); - lstrcatW( szFullKey, szBackSlash ); - CRYPT_guid2wstr( guid, &szFullKey[ lstrlenW( szFullKey ) ] ); - lstrcatW( szFullKey, szBackSlash ); - - TRACE("key is %s\n", debugstr_w( szFullKey ) ); - - r = RegCreateKeyW( HKEY_LOCAL_MACHINE, szFullKey, &hKey ); - if( r != ERROR_SUCCESS ) - return r; - - /* write the values */ - RegSetValueExW( hKey, szFuncName, 0, REG_SZ, (const BYTE*) szFunction, - ( lstrlenW( szFunction ) + 1 ) * sizeof (WCHAR) ); - RegSetValueExW( hKey, szDllName, 0, REG_SZ, (const BYTE*) szDll, - ( lstrlenW( szDll ) + 1) * sizeof (WCHAR) ); - - RegCloseKey( hKey ); - - return ERROR_SUCCESS; -} - -BOOL WINAPI CryptSIPAddProvider(SIP_ADD_NEWPROVIDER *psNewProv) -{ - static const WCHAR szCreate[] = { - 'C','r','e','a','t','e', - 'I','n','d','i','r','e','c','t','D','a','t','a',0}; - static const WCHAR szGetSigned[] = { - 'G','e','t','S','i','g','n','e','d','D','a','t','a','M','s','g',0}; - static const WCHAR szIsMyFile[] = { - 'I','s','M','y','F','i','l','e','T','y','p','e', 0 }; - static const WCHAR szPutSigned[] = { - 'P','u','t','S','i','g','n','e','d','D','a','t','a','M','s','g',0}; - static const WCHAR szRemoveSigned[] = { - 'R','e','m','o','v','e', - 'S','i','g','n','e','d','D','a','t','a','M','s','g',0}; - static const WCHAR szVerify[] = { - 'V','e','r','i','f','y', - 'I','n','d','i','r','e','c','t','D','a','t','a',0}; - - TRACE("%p\n", psNewProv); - - if( !psNewProv ) - return FALSE; - - TRACE("%s %s %s %s\n", - debugstr_guid( psNewProv->pgSubject ), - debugstr_w( psNewProv->pwszDLLFileName ), - debugstr_w( psNewProv->pwszMagicNumber ), - debugstr_w( psNewProv->pwszIsFunctionName ) ); - -#define CRYPT_SIPADDPROV( key, field ) \ - CRYPT_SIPWriteFunction( psNewProv->pgSubject, key, \ - psNewProv->pwszDLLFileName, psNewProv->field) - - CRYPT_SIPADDPROV( szGetSigned, pwszGetFuncName ); - CRYPT_SIPADDPROV( szPutSigned, pwszPutFuncName ); - CRYPT_SIPADDPROV( szCreate, pwszCreateFuncName ); - CRYPT_SIPADDPROV( szVerify, pwszVerifyFuncName ); - CRYPT_SIPADDPROV( szRemoveSigned, pwszRemoveFuncName ); - CRYPT_SIPADDPROV( szIsMyFile, pwszIsFunctionNameFmt2 ); - -#undef CRYPT_SIPADDPROV - - return TRUE; -} - -BOOL WINAPI CryptSIPRetrieveSubjectGuid - (LPCWSTR FileName, HANDLE hFileIn, GUID *pgSubject) -{ - FIXME("stub!\n"); - return FALSE; -} - -BOOL WINAPI CryptSIPLoad - (const GUID *pgSubject, DWORD dwFlags, SIP_DISPATCH_INFO *pSipDispatch) -{ - FIXME("stub!\n"); - return FALSE; -} - LPVOID WINAPI CryptMemAlloc(ULONG cbSize) { return HeapAlloc(GetProcessHeap(), 0, cbSize); @@ -259,35 +134,97 @@ BOOL WINAPI I_CryptSetTls(DWORD dwTlsIndex, LPVOID lpTlsValue) BOOL WINAPI I_CryptFreeTls(DWORD dwTlsIndex, DWORD unknown) { - TRACE("(%ld, %ld)\n", dwTlsIndex, unknown); + TRACE("(%d, %d)\n", dwTlsIndex, unknown); return TlsFree(dwTlsIndex); } BOOL WINAPI I_CryptGetOssGlobal(DWORD x) { - FIXME("%08lx\n", x); + FIXME("%08x\n", x); return FALSE; } -BOOL WINAPI I_CryptInstallOssGlobal(DWORD x, DWORD y, DWORD z) +HCRYPTPROV WINAPI I_CryptGetDefaultCryptProv(DWORD reserved) { - FIXME("%08lx %08lx %08lx\n", x, y, z); - return FALSE; + HCRYPTPROV ret; + + TRACE("(%08x)\n", reserved); + + if (reserved) + { + SetLastError(E_INVALIDARG); + return (HCRYPTPROV)0; + } + ret = CRYPT_GetDefaultProvider(); + CryptContextAddRef(ret, NULL, 0); + return ret; +} + +BOOL WINAPI I_CryptReadTrustedPublisherDWORDValueFromRegistry(LPCWSTR name, + DWORD *value) +{ + static const WCHAR safer[] = { + 'S','o','f','t','w','a','r','e','\\','P','o','l','i','c','i','e','s','\\', + 'M','i','c','r','o','s','o','f','t','\\','S','y','s','t','e','m', + 'C','e','r','t','i','f','i','c','a','t','e','s','\\', + 'T','r','u','s','t','e','d','P','u','b','l','i','s','h','e','r','\\', + 'S','a','f','e','r',0 }; + HKEY key; + LONG rc; + BOOL ret = FALSE; + + TRACE("(%s, %p)\n", debugstr_w(name), value); + + *value = 0; + rc = RegCreateKeyW(HKEY_LOCAL_MACHINE, safer, &key); + if (rc == ERROR_SUCCESS) + { + DWORD size = sizeof(DWORD); + + if (!RegQueryValueExW(key, name, NULL, NULL, (LPBYTE)value, &size)) + ret = TRUE; + RegCloseKey(key); + } + return ret; +} + +int WINAPI I_CryptInstallOssGlobal(DWORD x, DWORD y, DWORD z) +{ + static int ret = 8; + ret++; + FIXME("%08x %08x %08x, return value %d\n", x, y, z,ret); + return ret; } BOOL WINAPI I_CryptInstallAsn1Module(void *x, DWORD y, DWORD z) { - FIXME("%p %08lx %08lx\n", x, y, z); + FIXME("%p %08x %08x\n", x, y, z); return TRUE; } +BOOL WINAPI I_CryptUninstallAsn1Module(void *x) +{ + FIXME("%p\n", x); + return TRUE; +} + +BOOL WINAPI CryptFormatObject(DWORD dwCertEncodingType, DWORD dwFormatType, + DWORD dwFormatStrType, void *pFormatStruct, LPCSTR lpszStructType, + const BYTE *pbEncoded, DWORD cbEncoded, void *pbFormat, DWORD *pcbFormat) +{ + FIXME("(%08x, %d, %d, %p, %s, %p, %d, %p, %p): stub\n", + dwCertEncodingType, dwFormatType, dwFormatStrType, pFormatStruct, + debugstr_a(lpszStructType), pbEncoded, cbEncoded, pbFormat, pcbFormat); + return FALSE; +} + BOOL WINAPI CryptQueryObject(DWORD dwObjectType, const void* pvObject, DWORD dwExpectedContentTypeFlags, DWORD dwExpectedFormatTypeFlags, DWORD dwFlags, DWORD* pdwMsgAndCertEncodingType, DWORD* pdwContentType, DWORD* pdwFormatType, HCERTSTORE* phCertStore, HCRYPTMSG* phMsg, const void** ppvContext) { - FIXME( "%08lx %p %08lx %08lx %08lx %p %p %p %p %p %p", dwObjectType, + FIXME( "%08x %p %08x %08x %08x %p %p %p %p %p %p\n", dwObjectType, pvObject, dwExpectedContentTypeFlags, dwExpectedFormatTypeFlags, dwFlags, pdwMsgAndCertEncodingType, pdwContentType, pdwFormatType, phCertStore, phMsg, ppvContext); @@ -298,8 +235,10 @@ BOOL WINAPI CryptVerifyMessageSignature(PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, DWORD dwSignerIndex, const BYTE* pbSignedBlob, DWORD cbSignedBlob, BYTE* pbDecoded, DWORD* pcbDecoded, PCCERT_CONTEXT* ppSignerCert) { - FIXME("stub: %p, %ld, %p, %ld, %p, %p, %p\n", + FIXME("stub: %p, %d, %p, %d, %p, %p, %p\n", pVerifyPara, dwSignerIndex, pbSignedBlob, cbSignedBlob, pbDecoded, pcbDecoded, ppSignerCert); + if (ppSignerCert) + *ppSignerCert = NULL; return FALSE; } diff --git a/reactos/dll/win32/crypt32/oid.c b/reactos/dll/win32/crypt32/oid.c index bbe4225529f..bbad49178a9 100644 --- a/reactos/dll/win32/crypt32/oid.c +++ b/reactos/dll/win32/crypt32/oid.c @@ -16,6 +16,10 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ + +#include "config.h" +#include "wine/port.h" + #include #include #define NONAMELESSUNION @@ -71,6 +75,7 @@ struct OIDFunction static void init_function_sets(void) { InitializeCriticalSection(&funcSetCS); + funcSetCS.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": funcSetCS"); list_init(&funcSets); } @@ -91,9 +96,11 @@ static void free_function_sets(void) list_remove(&functionCursor->next); CryptMemFree(functionCursor); } + setCursor->cs.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&setCursor->cs); CryptMemFree(setCursor); } + funcSetCS.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&funcSetCS); } @@ -105,7 +112,7 @@ HCRYPTOIDFUNCSET WINAPI CryptInitOIDFunctionSet(LPCSTR pszFuncName, { struct OIDFunctionSet *cursor, *ret = NULL; - TRACE("(%s, %lx)\n", debugstr_a(pszFuncName), dwFlags); + TRACE("(%s, %x)\n", debugstr_a(pszFuncName), dwFlags); EnterCriticalSection(&funcSetCS); LIST_FOR_EACH_ENTRY(cursor, &funcSets, struct OIDFunctionSet, next) @@ -126,6 +133,7 @@ HCRYPTOIDFUNCSET WINAPI CryptInitOIDFunctionSet(LPCSTR pszFuncName, if (ret->name) { InitializeCriticalSection(&ret->cs); + ret->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": OIDFunctionSet.cs"); list_init(&ret->functions); strcpy(ret->name, pszFuncName); list_add_tail(&funcSets, &ret->next); @@ -146,7 +154,7 @@ static char *CRYPT_GetKeyName(DWORD dwEncodingType, LPCSTR pszFuncName, LPCSTR pszOID) { static const char szEncodingTypeFmt[] = - "Software\\Microsoft\\Cryptography\\OID\\EncodingType %ld\\%s\\%s"; + "Software\\Microsoft\\Cryptography\\OID\\EncodingType %d\\%s\\%s"; UINT len; char numericOID[7]; /* enough for "#65535" */ const char *oid; @@ -186,7 +194,7 @@ BOOL WINAPI CryptGetDefaultOIDDllList(HCRYPTOIDFUNCSET hFuncSet, HKEY key; long rc; - TRACE("(%p, %ld, %p, %p)\n", hFuncSet, dwEncodingType, pwszDllList, + TRACE("(%p, %d, %p, %p)\n", hFuncSet, dwEncodingType, pwszDllList, pcchDllList); keyName = CRYPT_GetKeyName(dwEncodingType, set->name, "DEFAULT"); @@ -226,7 +234,7 @@ BOOL WINAPI CryptInstallOIDFunctionAddress(HMODULE hModule, BOOL ret = TRUE; struct OIDFunctionSet *set; - TRACE("(%p, %ld, %s, %ld, %p, %08lx)\n", hModule, dwEncodingType, + TRACE("(%p, %d, %s, %d, %p, %08x)\n", hModule, dwEncodingType, debugstr_a(pszFuncName), cFuncEntry, rgFuncEntry, dwFlags); set = (struct OIDFunctionSet *)CryptInitOIDFunctionSet(pszFuncName, 0); @@ -249,8 +257,11 @@ BOOL WINAPI CryptInstallOIDFunctionAddress(HMODULE hModule, func->encoding = dwEncodingType; if (HIWORD(rgFuncEntry[i].pszOID)) { - func->entry.pszOID = (LPSTR)((LPBYTE)func + sizeof(*func)); - strcpy((LPSTR)func->entry.pszOID, rgFuncEntry[i].pszOID); + LPSTR oid; + + oid = (LPSTR)((LPBYTE)func + sizeof(*func)); + strcpy(oid, rgFuncEntry[i].pszOID); + func->entry.pszOID = oid; } else func->entry.pszOID = rgFuncEntry[i].pszOID; @@ -350,7 +361,7 @@ BOOL WINAPI CryptGetOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet, BOOL ret = FALSE; struct OIDFunctionSet *set = (struct OIDFunctionSet *)hFuncSet; - TRACE("(%p, %ld, %s, %08lx, %p, %p)\n", hFuncSet, dwEncodingType, + TRACE("(%p, %d, %s, %08x, %p, %p)\n", hFuncSet, dwEncodingType, debugstr_a(pszOID), dwFlags, ppvFuncAddr, phFuncAddr); *ppvFuncAddr = NULL; @@ -365,8 +376,8 @@ BOOL WINAPI CryptGetOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet, { if (HIWORD(pszOID)) { - if (HIWORD(function->entry.pszOID && - !strcasecmp(function->entry.pszOID, pszOID))) + if (HIWORD(function->entry.pszOID) && + !strcasecmp(function->entry.pszOID, pszOID)) { *ppvFuncAddr = function->entry.pvFuncAddr; *phFuncAddr = NULL; /* FIXME: what should it be? */ @@ -394,7 +405,7 @@ BOOL WINAPI CryptGetOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet, BOOL WINAPI CryptFreeOIDFunctionAddress(HCRYPTOIDFUNCADDR hFuncAddr, DWORD dwFlags) { - TRACE("(%p, %08lx)\n", hFuncAddr, dwFlags); + TRACE("(%p, %08x)\n", hFuncAddr, dwFlags); /* FIXME: as MSDN states, need to check for DllCanUnloadNow in the DLL, * and only unload it if it can be unloaded. Also need to implement ref @@ -404,31 +415,35 @@ BOOL WINAPI CryptFreeOIDFunctionAddress(HCRYPTOIDFUNCADDR hFuncAddr, return TRUE; } -BOOL WINAPI CryptRegisterDefaultOIDFunction(DWORD dwEncodingType, - LPCSTR pszFuncName, DWORD dwIndex, LPCWSTR pwszDll) -{ - FIXME("(%lx,%s,%lx,%s) stub!\n", dwEncodingType, pszFuncName, dwIndex, - debugstr_w(pwszDll)); - return FALSE; -} - -BOOL WINAPI CryptUnregisterDefaultOIDFunction(DWORD dwEncodingType, - LPCSTR pszFuncName, LPCWSTR pwszDll) -{ - FIXME("(%lx %s %s): stub\n", dwEncodingType, debugstr_a(pszFuncName), - debugstr_w(pwszDll)); - return FALSE; -} - BOOL WINAPI CryptGetDefaultOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet, DWORD dwEncodingType, LPCWSTR pwszDll, DWORD dwFlags, void *ppvFuncAddr, HCRYPTOIDFUNCADDR *phFuncAddr) { - FIXME("(%p, %ld, %s, %08lx, %p, %p): stub\n", hFuncSet, dwEncodingType, + FIXME("(%p, %d, %s, %08x, %p, %p): stub\n", hFuncSet, dwEncodingType, debugstr_w(pwszDll), dwFlags, ppvFuncAddr, phFuncAddr); return FALSE; } +/*********************************************************************** + * CryptRegisterOIDFunction (CRYPT32.@) + * + * Register the DLL and the functions it uses to cover the combination + * of encoding type, functionname and OID. + * + * PARAMS + * dwEncodingType [I] Encoding type to be used. + * pszFuncName [I] Name of the function to be registered. + * pszOID [I] OID of the function (numeric or string). + * pwszDll [I] The DLL that is to be registered. + * pszOverrideFuncName [I] Name of the function in the DLL. + * + * RETURNS + * Success: TRUE. + * Failure: FALSE. (Look at GetLastError()). + * + * NOTES + * Registry errors are always reported via SetLastError(). + */ BOOL WINAPI CryptRegisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName, LPCSTR pszOID, LPCWSTR pwszDll, LPCSTR pszOverrideFuncName) { @@ -436,8 +451,8 @@ BOOL WINAPI CryptRegisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName, HKEY hKey; LPSTR szKey; - TRACE("(%lx, %s, %s, %s, %s)\n", dwEncodingType, pszFuncName, pszOID, - debugstr_w(pwszDll), pszOverrideFuncName); + TRACE("(%x, %s, %s, %s, %s)\n", dwEncodingType, pszFuncName, + debugstr_a(pszOID), debugstr_w(pwszDll), pszOverrideFuncName); /* This only registers functions for encoding certs, not messages */ if (!GET_CERT_ENCODING_TYPE(dwEncodingType)) @@ -465,27 +480,42 @@ BOOL WINAPI CryptRegisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName, r = RegCreateKeyA(HKEY_LOCAL_MACHINE, szKey, &hKey); CryptMemFree(szKey); - if(r != ERROR_SUCCESS) - return FALSE; + + if (r != ERROR_SUCCESS) goto error_close_key; /* write the values */ if (pszOverrideFuncName) - RegSetValueExA(hKey, "FuncName", 0, REG_SZ, - (const BYTE*)pszOverrideFuncName, lstrlenA(pszOverrideFuncName) + 1); - RegSetValueExW(hKey, DllW, 0, REG_SZ, (const BYTE*) pwszDll, - (lstrlenW(pwszDll) + 1) * sizeof (WCHAR)); + { + r = RegSetValueExA(hKey, "FuncName", 0, REG_SZ, + (const BYTE*)pszOverrideFuncName, lstrlenA(pszOverrideFuncName) + 1); + if (r != ERROR_SUCCESS) goto error_close_key; + } + r = RegSetValueExW(hKey, DllW, 0, REG_SZ, (const BYTE*) pwszDll, + (lstrlenW(pwszDll) + 1) * sizeof (WCHAR)); + +error_close_key: RegCloseKey(hKey); + + if (r != ERROR_SUCCESS) + { + SetLastError(r); + return FALSE; + } + return TRUE; } +/*********************************************************************** + * CryptUnregisterOIDFunction (CRYPT32.@) + */ BOOL WINAPI CryptUnregisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName, LPCSTR pszOID) { LPSTR szKey; LONG rc; - TRACE("%lx %s %s\n", dwEncodingType, pszFuncName, pszOID); + TRACE("%x %s %s\n", dwEncodingType, pszFuncName, pszOID); if (!GET_CERT_ENCODING_TYPE(dwEncodingType)) return TRUE; @@ -512,7 +542,7 @@ BOOL WINAPI CryptGetOIDFunctionValue(DWORD dwEncodingType, LPCSTR pszFuncName, LONG rc; HKEY hKey; - TRACE("%lx %s %s %s %p %p %p\n", dwEncodingType, debugstr_a(pszFuncName), + TRACE("%x %s %s %s %p %p %p\n", dwEncodingType, debugstr_a(pszFuncName), debugstr_a(pszOID), debugstr_w(pwszValueName), pdwValueType, pbValueData, pcbValueData); @@ -549,7 +579,7 @@ BOOL WINAPI CryptSetOIDFunctionValue(DWORD dwEncodingType, LPCSTR pszFuncName, LONG rc; HKEY hKey; - TRACE("%lx %s %s %s %ld %p %ld\n", dwEncodingType, debugstr_a(pszFuncName), + TRACE("%x %s %s %s %d %p %d\n", dwEncodingType, debugstr_a(pszFuncName), debugstr_a(pszOID), debugstr_w(pwszValueName), dwValueType, pbValueData, cbValueData); @@ -578,6 +608,237 @@ BOOL WINAPI CryptSetOIDFunctionValue(DWORD dwEncodingType, LPCSTR pszFuncName, return rc ? FALSE : TRUE; } +static LPCWSTR CRYPT_FindStringInMultiString(LPCWSTR multi, LPCWSTR toFind) +{ + LPCWSTR ret = NULL, ptr; + + for (ptr = multi; ptr && *ptr && !ret; ptr += lstrlenW(ptr) + 1) + { + if (!lstrcmpiW(ptr, toFind)) + ret = ptr; + } + return ret; +} + +static DWORD CRYPT_GetMultiStringCharacterLen(LPCWSTR multi) +{ + DWORD ret; + + if (multi) + { + LPCWSTR ptr; + + /* Count terminating empty string */ + ret = 1; + for (ptr = multi; *ptr; ptr += lstrlenW(ptr) + 1) + ret += lstrlenW(ptr) + 1; + } + else + ret = 0; + return ret; +} + +static LPWSTR CRYPT_AddStringToMultiString(LPWSTR multi, LPCWSTR toAdd, + DWORD index) +{ + LPWSTR ret; + + if (!multi) + { + /* FIXME: ignoring index, is that okay? */ + ret = CryptMemAlloc((lstrlenW(toAdd) + 2) * sizeof(WCHAR)); + if (ret) + { + /* copy string, including NULL terminator */ + memcpy(ret, toAdd, (lstrlenW(toAdd) + 1) * sizeof(WCHAR)); + /* add terminating empty string */ + *(ret + lstrlenW(toAdd) + 1) = 0; + } + } + else + { + DWORD len = CRYPT_GetMultiStringCharacterLen(multi); + + ret = CryptMemRealloc(multi, (len + lstrlenW(toAdd) + 1) * + sizeof(WCHAR)); + if (ret) + { + LPWSTR spotToAdd; + + if (index == CRYPT_REGISTER_LAST_INDEX) + spotToAdd = ret + len - 1; + else + { + DWORD i; + + /* FIXME: if index is too large for the string, toAdd is + * added to the end. Is that okay? + */ + for (i = 0, spotToAdd = ret; i < index && *spotToAdd; + spotToAdd += lstrlenW(spotToAdd) + 1) + ; + } + if (spotToAdd) + { + /* Copy existing string "right" */ + memmove(spotToAdd + lstrlenW(toAdd) + 1, spotToAdd, + (len - (spotToAdd - ret)) * sizeof(WCHAR)); + /* Copy new string */ + memcpy(spotToAdd, toAdd, (lstrlenW(toAdd) + 1) * sizeof(WCHAR)); + } + else + { + CryptMemFree(ret); + ret = NULL; + } + } + } + return ret; +} + +static BOOL CRYPT_RemoveStringFromMultiString(LPWSTR multi, LPCWSTR toRemove) +{ + LPWSTR spotToRemove = (LPWSTR)CRYPT_FindStringInMultiString(multi, + toRemove); + BOOL ret; + + if (spotToRemove) + { + DWORD len = CRYPT_GetMultiStringCharacterLen(multi); + + /* Copy remainder of string "left" */ + memmove(spotToRemove, spotToRemove + lstrlenW(toRemove) + 1, + (len - (spotToRemove - multi)) * sizeof(WCHAR)); + ret = TRUE; + } + else + { + SetLastError(ERROR_FILE_NOT_FOUND); + ret = FALSE; + } + return ret; +} + +static BOOL CRYPT_GetDefaultOIDKey(DWORD dwEncodingType, LPCSTR pszFuncName, + PHKEY key) +{ + LPSTR keyName; + LONG r; + + keyName = CRYPT_GetKeyName(dwEncodingType, pszFuncName, "DEFAULT"); + TRACE("Key name is %s\n", debugstr_a(keyName)); + + if (!keyName) + return FALSE; + + r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, NULL, 0, KEY_ALL_ACCESS, + NULL, key, NULL); + CryptMemFree(keyName); + if (r != ERROR_SUCCESS) + { + SetLastError(r); + return FALSE; + } + return TRUE; +} + +static LPWSTR CRYPT_GetDefaultOIDDlls(HKEY key) +{ + LONG r; + DWORD type, size; + LPWSTR dlls; + + r = RegQueryValueExW(key, DllW, NULL, &type, NULL, &size); + if (r == ERROR_SUCCESS && type == REG_MULTI_SZ) + { + dlls = CryptMemAlloc(size); + r = RegQueryValueExW(key, DllW, NULL, &type, (LPBYTE)dlls, &size); + if (r != ERROR_SUCCESS) + { + CryptMemFree(dlls); + dlls = NULL; + } + } + else + dlls = NULL; + return dlls; +} + +static inline BOOL CRYPT_SetDefaultOIDDlls(HKEY key, LPCWSTR dlls) +{ + DWORD len = CRYPT_GetMultiStringCharacterLen(dlls); + LONG r; + + if ((r = RegSetValueExW(key, DllW, 0, REG_MULTI_SZ, (const BYTE *)dlls, + len * sizeof (WCHAR)))) + SetLastError(r); + return r == ERROR_SUCCESS; +} + +/*********************************************************************** + * CryptRegisterDefaultOIDFunction (CRYPT32.@) + */ +BOOL WINAPI CryptRegisterDefaultOIDFunction(DWORD dwEncodingType, + LPCSTR pszFuncName, DWORD dwIndex, LPCWSTR pwszDll) +{ + HKEY key; + LPWSTR dlls; + LPCWSTR existing; + BOOL ret = FALSE; + + TRACE("(%x, %s, %x, %s)\n", dwEncodingType, pszFuncName, dwIndex, + debugstr_w(pwszDll)); + + if (!pwszDll) + { + SetLastError(E_INVALIDARG); + return FALSE; + } + + if (!CRYPT_GetDefaultOIDKey(dwEncodingType, pszFuncName, &key)) + return FALSE; + + dlls = CRYPT_GetDefaultOIDDlls(key); + if ((existing = CRYPT_FindStringInMultiString(dlls, pwszDll))) + SetLastError(ERROR_FILE_EXISTS); + else + { + dlls = CRYPT_AddStringToMultiString(dlls, pwszDll, dwIndex); + if (dlls) + ret = CRYPT_SetDefaultOIDDlls(key, dlls); + } + CryptMemFree(dlls); + RegCloseKey(key); + return ret; +} + +BOOL WINAPI CryptUnregisterDefaultOIDFunction(DWORD dwEncodingType, + LPCSTR pszFuncName, LPCWSTR pwszDll) +{ + HKEY key; + LPWSTR dlls; + BOOL ret; + + TRACE("(%x, %s, %s)\n", dwEncodingType, debugstr_a(pszFuncName), + debugstr_w(pwszDll)); + + if (!pwszDll) + { + SetLastError(E_INVALIDARG); + return FALSE; + } + + if (!CRYPT_GetDefaultOIDKey(dwEncodingType, pszFuncName, &key)) + return FALSE; + + dlls = CRYPT_GetDefaultOIDDlls(key); + if ((ret = CRYPT_RemoveStringFromMultiString(dlls, pwszDll))) + ret = CRYPT_SetDefaultOIDDlls(key, dlls); + CryptMemFree(dlls); + RegCloseKey(key); + return ret; +} + static CRITICAL_SECTION oidInfoCS; static struct list oidInfo; @@ -921,6 +1182,7 @@ static void init_oid_info(HINSTANCE hinst) DWORD i; InitializeCriticalSection(&oidInfoCS); + oidInfoCS.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": oidInfoCS"); list_init(&oidInfo); for (i = 0; i < sizeof(oidInfoConstructors) / sizeof(oidInfoConstructors[0]); i++) @@ -993,16 +1255,20 @@ static void free_oid_info(void) list_remove(&info->entry); CryptMemFree(info); } + oidInfoCS.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&oidInfoCS); } +/*********************************************************************** + * CryptEnumOIDInfo (CRYPT32.@) + */ BOOL WINAPI CryptEnumOIDInfo(DWORD dwGroupId, DWORD dwFlags, void *pvArg, PFN_CRYPT_ENUM_OID_INFO pfnEnumOIDInfo) { BOOL ret = TRUE; struct OIDInfo *info; - TRACE("(%ld, %08lx, %p, %p)\n", dwGroupId, dwFlags, pvArg, + TRACE("(%d, %08x, %p, %p)\n", dwGroupId, dwFlags, pvArg, pfnEnumOIDInfo); EnterCriticalSection(&oidInfoCS); @@ -1024,7 +1290,7 @@ PCCRYPT_OID_INFO WINAPI CryptFindOIDInfo(DWORD dwKeyType, void *pvKey, { PCCRYPT_OID_INFO ret = NULL; - TRACE("(%ld, %p, %ld)\n", dwKeyType, pvKey, dwGroupId); + TRACE("(%d, %p, %d)\n", dwKeyType, pvKey, dwGroupId); switch(dwKeyType) { @@ -1032,6 +1298,7 @@ PCCRYPT_OID_INFO WINAPI CryptFindOIDInfo(DWORD dwKeyType, void *pvKey, { struct OIDInfo *info; + TRACE("CRYPT_OID_INFO_ALGID_KEY: %d\n", *(DWORD *)pvKey); EnterCriticalSection(&oidInfoCS); LIST_FOR_EACH_ENTRY(info, &oidInfo, struct OIDInfo, entry) { @@ -1049,6 +1316,7 @@ PCCRYPT_OID_INFO WINAPI CryptFindOIDInfo(DWORD dwKeyType, void *pvKey, { struct OIDInfo *info; + TRACE("CRYPT_OID_INFO_NAME_KEY: %s\n", debugstr_w((LPWSTR)pvKey)); EnterCriticalSection(&oidInfoCS); LIST_FOR_EACH_ENTRY(info, &oidInfo, struct OIDInfo, entry) { @@ -1067,6 +1335,7 @@ PCCRYPT_OID_INFO WINAPI CryptFindOIDInfo(DWORD dwKeyType, void *pvKey, struct OIDInfo *info; LPSTR oid = (LPSTR)pvKey; + TRACE("CRYPT_OID_INFO_OID_KEY: %s\n", debugstr_a(oid)); EnterCriticalSection(&oidInfoCS); LIST_FOR_EACH_ENTRY(info, &oidInfo, struct OIDInfo, entry) { @@ -1084,6 +1353,7 @@ PCCRYPT_OID_INFO WINAPI CryptFindOIDInfo(DWORD dwKeyType, void *pvKey, { struct OIDInfo *info; + TRACE("CRYPT_OID_INFO_SIGN_KEY: %d\n", *(DWORD *)pvKey); EnterCriticalSection(&oidInfoCS); LIST_FOR_EACH_ENTRY(info, &oidInfo, struct OIDInfo, entry) { diff --git a/reactos/dll/win32/crypt32/proplist.c b/reactos/dll/win32/crypt32/proplist.c index b6bd7d20906..31cd53b6f40 100644 --- a/reactos/dll/win32/crypt32/proplist.c +++ b/reactos/dll/win32/crypt32/proplist.c @@ -47,6 +47,7 @@ PCONTEXT_PROPERTY_LIST ContextPropertyList_Create(void) if (list) { InitializeCriticalSection(&list->cs); + list->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PCONTEXT_PROPERTY_LIST->cs"); list_init(&list->properties); } return list; @@ -63,6 +64,7 @@ void ContextPropertyList_Free(PCONTEXT_PROPERTY_LIST list) CryptMemFree(prop->pbData); CryptMemFree(prop); } + list->cs.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&list->cs); CryptMemFree(list); } @@ -73,7 +75,7 @@ BOOL ContextPropertyList_FindProperty(PCONTEXT_PROPERTY_LIST list, DWORD id, PCONTEXT_PROPERTY prop; BOOL ret = FALSE; - TRACE("(%p, %ld, %p)\n", list, id, blob); + TRACE("(%p, %d, %p)\n", list, id, blob); EnterCriticalSection(&list->cs); LIST_FOR_EACH_ENTRY(prop, &list->properties, CONTEXT_PROPERTY, entry) diff --git a/reactos/dll/win32/crypt32/protectdata.c b/reactos/dll/win32/crypt32/protectdata.c index 4b7cfc9f605..1957e7cb4bb 100644 --- a/reactos/dll/win32/crypt32/protectdata.c +++ b/reactos/dll/win32/crypt32/protectdata.c @@ -111,7 +111,7 @@ static const char crypt_magic_str[] = "Wine Crypt32 ok"; /* debugging tool to print strings of hex chars */ static const char * -hex_str(unsigned char *p, int n) +hex_str(const unsigned char *p, int n) { const char * ptr; char report[80]; @@ -146,7 +146,7 @@ void serialize_dword(DWORD value,BYTE ** ptr) } static -void serialize_string(BYTE * str,BYTE ** ptr,DWORD len, DWORD width, +void serialize_string(const BYTE *str, BYTE **ptr, DWORD len, DWORD width, BOOL prepend_len) { /*TRACE("called %ux%u\n",(unsigned int)len,(unsigned int)width);*/ @@ -160,7 +160,7 @@ void serialize_string(BYTE * str,BYTE ** ptr,DWORD len, DWORD width, } static -BOOL unserialize_dword(BYTE * ptr, DWORD *index, DWORD size, DWORD * value) +BOOL unserialize_dword(const BYTE *ptr, DWORD *index, DWORD size, DWORD *value) { /*TRACE("called\n");*/ @@ -178,7 +178,7 @@ BOOL unserialize_dword(BYTE * ptr, DWORD *index, DWORD size, DWORD * value) } static -BOOL unserialize_string(BYTE * ptr, DWORD *index, DWORD size, +BOOL unserialize_string(const BYTE *ptr, DWORD *index, DWORD size, DWORD len, DWORD width, BOOL inline_len, BYTE ** data, DWORD * stored) { @@ -212,7 +212,7 @@ BOOL unserialize_string(BYTE * ptr, DWORD *index, DWORD size, } static -BOOL serialize(struct protect_data_t * pInfo, DATA_BLOB * pSerial) +BOOL serialize(const struct protect_data_t *pInfo, DATA_BLOB *pSerial) { BYTE * ptr; DWORD dwStrLen; @@ -340,7 +340,7 @@ BOOL serialize(struct protect_data_t * pInfo, DATA_BLOB * pSerial) } static -BOOL unserialize(DATA_BLOB * pSerial, struct protect_data_t * pInfo) +BOOL unserialize(const DATA_BLOB *pSerial, struct protect_data_t *pInfo) { BYTE * ptr; DWORD index; @@ -484,7 +484,7 @@ BOOL unserialize(DATA_BLOB * pSerial, struct protect_data_t * pInfo) /* perform sanity checks */ static -BOOL valid_protect_data(struct protect_data_t * pInfo) +BOOL valid_protect_data(const struct protect_data_t *pInfo) { BOOL status=TRUE; @@ -537,25 +537,18 @@ void free_protect_data(struct protect_data_t * pInfo) if (!pInfo) return; - if (pInfo->info0.pbData) - CryptMemFree(pInfo->info0.pbData); - if (pInfo->info1.pbData) - CryptMemFree(pInfo->info1.pbData); - if (pInfo->szDataDescr) - CryptMemFree(pInfo->szDataDescr); - if (pInfo->data0.pbData) - CryptMemFree(pInfo->data0.pbData); - if (pInfo->salt.pbData) - CryptMemFree(pInfo->salt.pbData); - if (pInfo->cipher.pbData) - CryptMemFree(pInfo->cipher.pbData); - if (pInfo->fingerprint.pbData) - CryptMemFree(pInfo->fingerprint.pbData); + CryptMemFree(pInfo->info0.pbData); + CryptMemFree(pInfo->info1.pbData); + CryptMemFree(pInfo->szDataDescr); + CryptMemFree(pInfo->data0.pbData); + CryptMemFree(pInfo->salt.pbData); + CryptMemFree(pInfo->cipher.pbData); + CryptMemFree(pInfo->fingerprint.pbData); } /* copies a string into a data blob */ static -BYTE * convert_str_to_blob(char* str, DATA_BLOB* blob) +BYTE *convert_str_to_blob(LPCSTR str, DATA_BLOB *blob) { if (!str || !blob) return NULL; @@ -590,11 +583,11 @@ BOOL fill_protect_data(struct protect_data_t * pInfo, LPCWSTR szDataDescr, pInfo->count0=0x0001; - convert_str_to_blob((char*)crypt_magic_str,&pInfo->info0); + convert_str_to_blob(crypt_magic_str, &pInfo->info0); pInfo->count1=0x0001; - convert_str_to_blob((char*)crypt_magic_str,&pInfo->info1); + convert_str_to_blob(crypt_magic_str, &pInfo->info1); pInfo->null0=0x0000; @@ -606,7 +599,7 @@ BOOL fill_protect_data(struct protect_data_t * pInfo, LPCWSTR szDataDescr, pInfo->unknown0=0x0000; pInfo->unknown1=0x0000; - convert_str_to_blob((char*)crypt_magic_str,&pInfo->data0); + convert_str_to_blob(crypt_magic_str, &pInfo->data0); pInfo->null1=0x0000; pInfo->unknown2=0x0000; @@ -688,7 +681,7 @@ BOOL convert_hash_to_blob(HCRYPTHASH hHash, DATA_BLOB * blob) /* test that a given hash matches an exported-to-blob hash value */ static -BOOL hash_matches_blob(HCRYPTHASH hHash, DATA_BLOB * two) +BOOL hash_matches_blob(HCRYPTHASH hHash, const DATA_BLOB *two) { BOOL rc = FALSE; DATA_BLOB one; @@ -711,8 +704,8 @@ BOOL hash_matches_blob(HCRYPTHASH hHash, DATA_BLOB * two) /* create an encryption key from a given salt and optional entropy */ static -BOOL load_encryption_key(HCRYPTPROV hProv, DATA_BLOB * salt, - DATA_BLOB * pOptionalEntropy, HCRYPTKEY * phKey) +BOOL load_encryption_key(HCRYPTPROV hProv, const DATA_BLOB *salt, + const DATA_BLOB *pOptionalEntropy, HCRYPTKEY *phKey) { BOOL rc = TRUE; HCRYPTHASH hSaltHash; @@ -768,14 +761,14 @@ BOOL load_encryption_key(HCRYPTPROV hProv, DATA_BLOB * salt, /* clean up */ CryptDestroyHash(hSaltHash); - if (szUsername) CryptMemFree(szUsername); + CryptMemFree(szUsername); return rc; } /* debugging tool to print the structures of a ProtectData call */ static void -report(DATA_BLOB* pDataIn, DATA_BLOB* pOptionalEntropy, +report(const DATA_BLOB* pDataIn, const DATA_BLOB* pOptionalEntropy, CRYPTPROTECT_PROMPTSTRUCT* pPromptStruct, DWORD dwFlags) { TRACE("pPromptStruct: %p\n", pPromptStruct); diff --git a/reactos/dll/win32/crypt32/serialize.c b/reactos/dll/win32/crypt32/serialize.c index afcd13f1043..49749e38a16 100644 --- a/reactos/dll/win32/crypt32/serialize.c +++ b/reactos/dll/win32/crypt32/serialize.c @@ -38,13 +38,13 @@ typedef struct _WINE_CERT_PROP_HEADER static BOOL CRYPT_SerializeStoreElement(const void *context, const BYTE *encodedContext, DWORD cbEncodedContext, DWORD contextPropID, - PCWINE_CONTEXT_INTERFACE contextInterface, DWORD dwFlags, BYTE *pbElement, - DWORD *pcbElement) + PCWINE_CONTEXT_INTERFACE contextInterface, DWORD dwFlags, BOOL omitHashes, + BYTE *pbElement, DWORD *pcbElement) { BOOL ret; - TRACE("(%p, %p, %08lx, %p, %p)\n", context, contextInterface, dwFlags, - pbElement, pcbElement); + TRACE("(%p, %p, %08x, %d, %p, %p)\n", context, contextInterface, dwFlags, + omitHashes, pbElement, pcbElement); if (context) { @@ -54,7 +54,7 @@ static BOOL CRYPT_SerializeStoreElement(const void *context, ret = TRUE; do { prop = contextInterface->enumProps(context, prop); - if (prop) + if (prop && (!omitHashes || !IS_CERT_HASH_PROP_ID(prop))) { DWORD propSize = 0; @@ -84,7 +84,7 @@ static BOOL CRYPT_SerializeStoreElement(const void *context, prop = 0; do { prop = contextInterface->enumProps(context, prop); - if (prop) + if (prop && (!omitHashes || !IS_CERT_HASH_PROP_ID(prop))) { DWORD propSize = 0; @@ -143,7 +143,7 @@ BOOL WINAPI CertSerializeCertificateStoreElement(PCCERT_CONTEXT pCertContext, { return CRYPT_SerializeStoreElement(pCertContext, pCertContext->pbCertEncoded, pCertContext->cbCertEncoded, - CERT_CERT_PROP_ID, pCertInterface, dwFlags, pbElement, pcbElement); + CERT_CERT_PROP_ID, pCertInterface, dwFlags, FALSE, pbElement, pcbElement); } BOOL WINAPI CertSerializeCRLStoreElement(PCCRL_CONTEXT pCrlContext, @@ -151,7 +151,7 @@ BOOL WINAPI CertSerializeCRLStoreElement(PCCRL_CONTEXT pCrlContext, { return CRYPT_SerializeStoreElement(pCrlContext, pCrlContext->pbCrlEncoded, pCrlContext->cbCrlEncoded, - CERT_CRL_PROP_ID, pCRLInterface, dwFlags, pbElement, pcbElement); + CERT_CRL_PROP_ID, pCRLInterface, dwFlags, FALSE, pbElement, pcbElement); } BOOL WINAPI CertSerializeCTLStoreElement(PCCTL_CONTEXT pCtlContext, @@ -159,7 +159,7 @@ BOOL WINAPI CertSerializeCTLStoreElement(PCCTL_CONTEXT pCtlContext, { return CRYPT_SerializeStoreElement(pCtlContext, pCtlContext->pbCtlEncoded, pCtlContext->cbCtlEncoded, - CERT_CTL_PROP_ID, pCRLInterface, dwFlags, pbElement, pcbElement); + CERT_CTL_PROP_ID, pCTLInterface, dwFlags, FALSE, pbElement, pcbElement); } /* Looks for the property with ID propID in the buffer buf. Returns a pointer @@ -215,12 +215,86 @@ static const WINE_CERT_PROP_HEADER *CRYPT_findPropID(const BYTE *buf, return ret; } +static BOOL CRYPT_ReadContextProp( + const WINE_CONTEXT_INTERFACE *contextInterface, const void *context, + const WINE_CERT_PROP_HEADER *hdr, const BYTE *pbElement, DWORD cbElement) +{ + BOOL ret; + + if (cbElement < hdr->cb) + { + SetLastError(E_INVALIDARG); + ret = FALSE; + } + else if (hdr->unknown != 1) + { + SetLastError(ERROR_FILE_NOT_FOUND); + ret = FALSE; + } + else if (hdr->propID != CERT_CERT_PROP_ID && + hdr->propID != CERT_CRL_PROP_ID && hdr->propID != CERT_CTL_PROP_ID) + { + /* Have to create a blob for most types, but not + * for all.. arghh. + */ + switch (hdr->propID) + { + case CERT_AUTO_ENROLL_PROP_ID: + case CERT_CTL_USAGE_PROP_ID: + case CERT_DESCRIPTION_PROP_ID: + case CERT_FRIENDLY_NAME_PROP_ID: + case CERT_HASH_PROP_ID: + case CERT_KEY_IDENTIFIER_PROP_ID: + case CERT_MD5_HASH_PROP_ID: + case CERT_NEXT_UPDATE_LOCATION_PROP_ID: + case CERT_PUBKEY_ALG_PARA_PROP_ID: + case CERT_PVK_FILE_PROP_ID: + case CERT_SIGNATURE_HASH_PROP_ID: + case CERT_ISSUER_PUBLIC_KEY_MD5_HASH_PROP_ID: + case CERT_SUBJECT_PUBLIC_KEY_MD5_HASH_PROP_ID: + case CERT_ENROLLMENT_PROP_ID: + case CERT_CROSS_CERT_DIST_POINTS_PROP_ID: + case CERT_RENEWAL_PROP_ID: + { + CRYPT_DATA_BLOB blob = { hdr->cb, + (LPBYTE)pbElement }; + + ret = contextInterface->setProp(context, + hdr->propID, 0, &blob); + break; + } + case CERT_DATE_STAMP_PROP_ID: + ret = contextInterface->setProp(context, + hdr->propID, 0, pbElement); + break; + case CERT_KEY_PROV_INFO_PROP_ID: + { + PCRYPT_KEY_PROV_INFO info = + (PCRYPT_KEY_PROV_INFO)pbElement; + + CRYPT_FixKeyProvInfoPointers(info); + ret = contextInterface->setProp(context, + hdr->propID, 0, pbElement); + break; + } + default: + ret = FALSE; + } + } + else + { + /* ignore the context itself */ + ret = TRUE; + } + return ret; +} + const void *CRYPT_ReadSerializedElement(const BYTE *pbElement, DWORD cbElement, DWORD dwContextTypeFlags, DWORD *pdwContentType) { const void *context; - TRACE("(%p, %ld, %08lx, %p)\n", pbElement, cbElement, dwContextTypeFlags, + TRACE("(%p, %d, %08x, %p)\n", pbElement, cbElement, dwContextTypeFlags, pdwContentType); if (!cbElement) @@ -307,76 +381,18 @@ const void *CRYPT_ReadSerializedElement(const BYTE *pbElement, DWORD cbElement, const WINE_CERT_PROP_HEADER *hdr = (const WINE_CERT_PROP_HEADER *)pbElement; - TRACE("prop is %ld\n", hdr->propID); + TRACE("prop is %d\n", hdr->propID); cbElement -= sizeof(WINE_CERT_PROP_HEADER); pbElement += sizeof(WINE_CERT_PROP_HEADER); - if (cbElement < hdr->cb) - { - SetLastError(E_INVALIDARG); - ret = FALSE; - } - else if (!hdr->propID) + if (!hdr->propID) { /* Like in CRYPT_findPropID, stop if the propID is zero */ noMoreProps = TRUE; } - else if (hdr->unknown != 1) - { - SetLastError(ERROR_FILE_NOT_FOUND); - ret = FALSE; - } - else if (hdr->propID != CERT_CERT_PROP_ID && - hdr->propID != CERT_CRL_PROP_ID && hdr->propID != - CERT_CTL_PROP_ID) - { - /* Have to create a blob for most types, but not - * for all.. arghh. - */ - switch (hdr->propID) - { - case CERT_AUTO_ENROLL_PROP_ID: - case CERT_CTL_USAGE_PROP_ID: - case CERT_DESCRIPTION_PROP_ID: - case CERT_FRIENDLY_NAME_PROP_ID: - case CERT_HASH_PROP_ID: - case CERT_KEY_IDENTIFIER_PROP_ID: - case CERT_MD5_HASH_PROP_ID: - case CERT_NEXT_UPDATE_LOCATION_PROP_ID: - case CERT_PUBKEY_ALG_PARA_PROP_ID: - case CERT_PVK_FILE_PROP_ID: - case CERT_SIGNATURE_HASH_PROP_ID: - case CERT_ISSUER_PUBLIC_KEY_MD5_HASH_PROP_ID: - case CERT_SUBJECT_PUBLIC_KEY_MD5_HASH_PROP_ID: - case CERT_ENROLLMENT_PROP_ID: - case CERT_CROSS_CERT_DIST_POINTS_PROP_ID: - case CERT_RENEWAL_PROP_ID: - { - CRYPT_DATA_BLOB blob = { hdr->cb, - (LPBYTE)pbElement }; - - ret = contextInterface->setProp(context, - hdr->propID, 0, &blob); - break; - } - case CERT_DATE_STAMP_PROP_ID: - ret = contextInterface->setProp(context, - hdr->propID, 0, pbElement); - break; - case CERT_KEY_PROV_INFO_PROP_ID: - { - PCRYPT_KEY_PROV_INFO info = - (PCRYPT_KEY_PROV_INFO)pbElement; - - CRYPT_FixKeyProvInfoPointers(info); - ret = contextInterface->setProp(context, - hdr->propID, 0, pbElement); - break; - } - default: - FIXME("prop ID %ld: stub\n", hdr->propID); - } - } + else + ret = CRYPT_ReadContextProp(contextInterface, context, + hdr, pbElement, cbElement); pbElement += hdr->cb; cbElement -= hdr->cb; if (!cbElement) @@ -404,6 +420,184 @@ const void *CRYPT_ReadSerializedElement(const BYTE *pbElement, DWORD cbElement, return context; } +static const BYTE fileHeader[] = { 0, 0, 0, 0, 'C','E','R','T' }; + +BOOL CRYPT_ReadSerializedFile(HANDLE file, HCERTSTORE store) +{ + BYTE fileHeaderBuf[sizeof(fileHeader)]; + DWORD read; + BOOL ret; + + /* Failure reading is non-critical, we'll leave the store empty */ + ret = ReadFile(file, fileHeaderBuf, sizeof(fileHeaderBuf), &read, NULL); + if (ret) + { + if (!memcmp(fileHeaderBuf, fileHeader, read)) + { + WINE_CERT_PROP_HEADER propHdr; + const void *context = NULL; + const WINE_CONTEXT_INTERFACE *contextInterface = NULL; + LPBYTE buf = NULL; + DWORD bufSize = 0; + + do { + ret = ReadFile(file, &propHdr, sizeof(propHdr), &read, NULL); + if (ret && read == sizeof(propHdr)) + { + if (contextInterface && context && + (propHdr.propID == CERT_CERT_PROP_ID || + propHdr.propID == CERT_CRL_PROP_ID || + propHdr.propID == CERT_CTL_PROP_ID)) + { + /* We have a new context, so free the existing one */ + contextInterface->free(context); + } + if (propHdr.cb > bufSize) + { + /* Not reusing realloc, because the old data aren't + * needed any longer. + */ + CryptMemFree(buf); + buf = CryptMemAlloc(propHdr.cb); + bufSize = propHdr.cb; + } + if (buf) + { + ret = ReadFile(file, buf, propHdr.cb, &read, NULL); + if (ret && read == propHdr.cb) + { + if (propHdr.propID == CERT_CERT_PROP_ID) + { + contextInterface = pCertInterface; + ret = contextInterface->addEncodedToStore(store, + X509_ASN_ENCODING, buf, read, + CERT_STORE_ADD_NEW, &context); + } + else if (propHdr.propID == CERT_CRL_PROP_ID) + { + contextInterface = pCRLInterface; + ret = contextInterface->addEncodedToStore(store, + X509_ASN_ENCODING, buf, read, + CERT_STORE_ADD_NEW, &context); + } + else if (propHdr.propID == CERT_CTL_PROP_ID) + { + contextInterface = pCTLInterface; + ret = contextInterface->addEncodedToStore(store, + X509_ASN_ENCODING, buf, read, + CERT_STORE_ADD_NEW, &context); + } + else + ret = CRYPT_ReadContextProp(contextInterface, + context, &propHdr, buf, read); + } + } + else + ret = FALSE; + } + } while (ret && read > 0); + if (contextInterface && context) + { + /* Free the last context added */ + contextInterface->free(context); + } + CryptMemFree(buf); + ret = TRUE; + } + } + else + ret = TRUE; + return ret; +} + +static BOOL WINAPI CRYPT_SerializeCertNoHash(PCCERT_CONTEXT pCertContext, + DWORD dwFlags, BYTE *pbElement, DWORD *pcbElement) +{ + return CRYPT_SerializeStoreElement(pCertContext, + pCertContext->pbCertEncoded, pCertContext->cbCertEncoded, + CERT_CERT_PROP_ID, pCertInterface, dwFlags, TRUE, pbElement, pcbElement); +} + +static BOOL WINAPI CRYPT_SerializeCRLNoHash(PCCRL_CONTEXT pCrlContext, + DWORD dwFlags, BYTE *pbElement, DWORD *pcbElement) +{ + return CRYPT_SerializeStoreElement(pCrlContext, + pCrlContext->pbCrlEncoded, pCrlContext->cbCrlEncoded, + CERT_CRL_PROP_ID, pCRLInterface, dwFlags, TRUE, pbElement, pcbElement); +} + +static BOOL WINAPI CRYPT_SerializeCTLNoHash(PCCTL_CONTEXT pCtlContext, + DWORD dwFlags, BYTE *pbElement, DWORD *pcbElement) +{ + return CRYPT_SerializeStoreElement(pCtlContext, + pCtlContext->pbCtlEncoded, pCtlContext->cbCtlEncoded, + CERT_CTL_PROP_ID, pCTLInterface, dwFlags, TRUE, pbElement, pcbElement); +} + +static BOOL CRYPT_SerializeContextsToFile(HANDLE file, + const WINE_CONTEXT_INTERFACE *contextInterface, HCERTSTORE store) +{ + const void *context = NULL; + BOOL ret; + + do { + context = contextInterface->enumContextsInStore(store, context); + if (context) + { + DWORD size = 0; + LPBYTE buf = NULL; + + ret = contextInterface->serialize(context, 0, NULL, &size); + if (size) + buf = CryptMemAlloc(size); + if (buf) + { + ret = contextInterface->serialize(context, 0, buf, &size); + if (ret) + ret = WriteFile(file, buf, size, &size, NULL); + } + CryptMemFree(buf); + } + else + ret = TRUE; + } while (ret && context != NULL); + if (context) + contextInterface->free(context); + return ret; +} + +BOOL CRYPT_WriteSerializedFile(HANDLE file, HCERTSTORE store) +{ + static const BYTE fileTrailer[12] = { 0 }; + WINE_CONTEXT_INTERFACE interface; + BOOL ret; + DWORD size; + + SetFilePointer(file, 0, NULL, FILE_BEGIN); + ret = WriteFile(file, fileHeader, sizeof(fileHeader), &size, NULL); + if (ret) + { + memcpy(&interface, pCertInterface, sizeof(interface)); + interface.serialize = (SerializeElementFunc)CRYPT_SerializeCertNoHash; + ret = CRYPT_SerializeContextsToFile(file, &interface, store); + } + if (ret) + { + memcpy(&interface, pCRLInterface, sizeof(interface)); + interface.serialize = (SerializeElementFunc)CRYPT_SerializeCRLNoHash; + ret = CRYPT_SerializeContextsToFile(file, &interface, store); + } + if (ret) + { + memcpy(&interface, pCTLInterface, sizeof(interface)); + interface.serialize = (SerializeElementFunc)CRYPT_SerializeCTLNoHash; + ret = CRYPT_SerializeContextsToFile(file, &interface, store); + } + if (ret) + ret = WriteFile(file, fileTrailer, sizeof(fileTrailer), &size, NULL); + return ret; +} + BOOL WINAPI CertAddSerializedElementToStore(HCERTSTORE hCertStore, const BYTE *pbElement, DWORD cbElement, DWORD dwAddDisposition, DWORD dwFlags, DWORD dwContextTypeFlags, DWORD *pdwContentType, const void **ppvContext) @@ -412,7 +606,7 @@ BOOL WINAPI CertAddSerializedElementToStore(HCERTSTORE hCertStore, DWORD type; BOOL ret; - TRACE("(%p, %p, %ld, %08lx, %08lx, %08lx, %p, %p)\n", hCertStore, + TRACE("(%p, %p, %d, %08x, %08x, %08x, %p, %p)\n", hCertStore, pbElement, cbElement, dwAddDisposition, dwFlags, dwContextTypeFlags, pdwContentType, ppvContext); diff --git a/reactos/dll/win32/crypt32/sip.c b/reactos/dll/win32/crypt32/sip.c new file mode 100644 index 00000000000..1e24455aa13 --- /dev/null +++ b/reactos/dll/win32/crypt32/sip.c @@ -0,0 +1,451 @@ +/* + * Copyright 2002 Mike McCormack for CodeWeavers + * Copyright 2005 Juan Lang + * Copyright 2006 Paul Vriens + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include + +#include "windef.h" +#include "winbase.h" +#include "wincrypt.h" +#include "winreg.h" +#include "winnls.h" +#include "mssip.h" +#include "winuser.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(crypt); + +static const WCHAR szOID[] = { + 'S','o','f','t','w','a','r','e','\\', + 'M','i','c','r','o','s','o','f','t','\\', + 'C','r','y','p','t','o','g','r','a','p','h','y','\\', + 'O','I','D','\\', + 'E','n','c','o','d','i','n','g','T','y','p','e',' ','0','\\', + 'C','r','y','p','t','S','I','P','D','l','l', 0 }; + +static const WCHAR szPutSigned[] = { + 'P','u','t','S','i','g','n','e','d','D','a','t','a','M','s','g','\\',0}; +static const WCHAR szGetSigned[] = { + 'G','e','t','S','i','g','n','e','d','D','a','t','a','M','s','g','\\',0}; +static const WCHAR szRemoveSigned[] = { + 'R','e','m','o','v','e','S','i','g','n','e','d','D','a','t','a','M','s','g','\\',0}; +static const WCHAR szCreate[] = { + 'C','r','e','a','t','e','I','n','d','i','r','e','c','t','D','a','t','a','\\',0}; +static const WCHAR szVerify[] = { + 'V','e','r','i','f','y','I','n','d','i','r','e','c','t','D','a','t','a','\\',0}; +static const WCHAR szIsMyFile[] = { + 'I','s','M','y','F','i','l','e','T','y','p','e','\\',0}; +static const WCHAR szIsMyFile2[] = { + 'I','s','M','y','F','i','l','e','T','y','p','e','2','\\',0}; + +static const WCHAR szDllName[] = { 'D','l','l',0 }; +static const WCHAR szFuncName[] = { 'F','u','n','c','N','a','m','e',0 }; + +/* convert a guid to a wide character string */ +static void CRYPT_guid2wstr( const GUID *guid, LPWSTR wstr ) +{ + char str[40]; + + sprintf(str, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", + guid->Data1, guid->Data2, guid->Data3, + guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], + guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] ); + MultiByteToWideChar( CP_ACP, 0, str, -1, wstr, 40 ); +} + +/*********************************************************************** + * CRYPT_SIPDeleteFunction + * + * Helper function for CryptSIPRemoveProvider + */ +static LONG CRYPT_SIPDeleteFunction( const GUID *guid, LPCWSTR szKey ) +{ + WCHAR szFullKey[ 0x100 ]; + LONG r = ERROR_SUCCESS; + + /* max length of szFullKey depends on our code only, so we won't overrun */ + lstrcpyW( szFullKey, szOID ); + lstrcatW( szFullKey, szKey ); + CRYPT_guid2wstr( guid, &szFullKey[ lstrlenW( szFullKey ) ] ); + + r = RegDeleteKeyW(HKEY_LOCAL_MACHINE, szFullKey); + + return r; +} + +/*********************************************************************** + * CryptSIPRemoveProvider (CRYPT32.@) + * + * Remove a SIP provider and its functions from the registry. + * + * PARAMS + * pgProv [I] Pointer to a GUID for this SIP provider + * + * RETURNS + * Success: TRUE. + * Failure: FALSE. (Look at GetLastError()). + * + * NOTES + * Registry errors are always reported via SetLastError(). Every registry + * deletion will be tried. + */ +BOOL WINAPI CryptSIPRemoveProvider(GUID *pgProv) +{ + LONG r = ERROR_SUCCESS; + LONG remove_error = ERROR_SUCCESS; + + TRACE("%s\n", debugstr_guid(pgProv)); + + if (!pgProv) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + +#define CRYPT_SIPREMOVEPROV( key ) \ + r = CRYPT_SIPDeleteFunction( pgProv, key); \ + if (r != ERROR_SUCCESS) remove_error = r + + CRYPT_SIPREMOVEPROV( szPutSigned); + CRYPT_SIPREMOVEPROV( szGetSigned); + CRYPT_SIPREMOVEPROV( szRemoveSigned); + CRYPT_SIPREMOVEPROV( szCreate); + CRYPT_SIPREMOVEPROV( szVerify); + CRYPT_SIPREMOVEPROV( szIsMyFile); + CRYPT_SIPREMOVEPROV( szIsMyFile2); + +#undef CRYPT_SIPREMOVEPROV + + if (remove_error != ERROR_SUCCESS) + { + SetLastError(remove_error); + return FALSE; + } + + return TRUE; +} + +/* + * Helper for CryptSIPAddProvider + * + * Add a registry key containing a dll name and function under + * "Software\\Microsoft\\Cryptography\\OID\\EncodingType 0\\\\" + */ +static LONG CRYPT_SIPWriteFunction( const GUID *guid, LPCWSTR szKey, + LPCWSTR szDll, LPCWSTR szFunction ) +{ + WCHAR szFullKey[ 0x100 ]; + LONG r = ERROR_SUCCESS; + HKEY hKey; + + if( !szFunction ) + return ERROR_SUCCESS; + + /* max length of szFullKey depends on our code only, so we won't overrun */ + lstrcpyW( szFullKey, szOID ); + lstrcatW( szFullKey, szKey ); + CRYPT_guid2wstr( guid, &szFullKey[ lstrlenW( szFullKey ) ] ); + + TRACE("key is %s\n", debugstr_w( szFullKey ) ); + + r = RegCreateKeyW( HKEY_LOCAL_MACHINE, szFullKey, &hKey ); + if( r != ERROR_SUCCESS ) goto error_close_key; + + /* write the values */ + r = RegSetValueExW( hKey, szFuncName, 0, REG_SZ, (const BYTE*) szFunction, + ( lstrlenW( szFunction ) + 1 ) * sizeof (WCHAR) ); + if( r != ERROR_SUCCESS ) goto error_close_key; + r = RegSetValueExW( hKey, szDllName, 0, REG_SZ, (const BYTE*) szDll, + ( lstrlenW( szDll ) + 1) * sizeof (WCHAR) ); + +error_close_key: + + RegCloseKey( hKey ); + + return r; +} + +/*********************************************************************** + * CryptSIPAddProvider (CRYPT32.@) + * + * Add a SIP provider and its functions to the registry. + * + * PARAMS + * psNewProv [I] Pointer to a structure with information about + * the functions this SIP provider can perform. + * + * RETURNS + * Success: TRUE. + * Failure: FALSE. (Look at GetLastError()). + * + * NOTES + * Registry errors are always reported via SetLastError(). If a + * registry error occurs the rest of the registry write operations + * will be skipped. + */ +BOOL WINAPI CryptSIPAddProvider(SIP_ADD_NEWPROVIDER *psNewProv) +{ + LONG r = ERROR_SUCCESS; + + TRACE("%p\n", psNewProv); + + if (!psNewProv || + psNewProv->cbStruct != sizeof(SIP_ADD_NEWPROVIDER) || + !psNewProv->pwszGetFuncName || + !psNewProv->pwszPutFuncName || + !psNewProv->pwszCreateFuncName || + !psNewProv->pwszVerifyFuncName || + !psNewProv->pwszRemoveFuncName) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + TRACE("%s %s %s %s %s\n", + debugstr_guid( psNewProv->pgSubject ), + debugstr_w( psNewProv->pwszDLLFileName ), + debugstr_w( psNewProv->pwszMagicNumber ), + debugstr_w( psNewProv->pwszIsFunctionName ), + debugstr_w( psNewProv->pwszIsFunctionNameFmt2 ) ); + +#define CRYPT_SIPADDPROV( key, field ) \ + r = CRYPT_SIPWriteFunction( psNewProv->pgSubject, key, \ + psNewProv->pwszDLLFileName, psNewProv->field); \ + if (r != ERROR_SUCCESS) goto end_function + + CRYPT_SIPADDPROV( szPutSigned, pwszPutFuncName ); + CRYPT_SIPADDPROV( szGetSigned, pwszGetFuncName ); + CRYPT_SIPADDPROV( szRemoveSigned, pwszRemoveFuncName ); + CRYPT_SIPADDPROV( szCreate, pwszCreateFuncName ); + CRYPT_SIPADDPROV( szVerify, pwszVerifyFuncName ); + CRYPT_SIPADDPROV( szIsMyFile, pwszIsFunctionName ); + CRYPT_SIPADDPROV( szIsMyFile2, pwszIsFunctionNameFmt2 ); + +#undef CRYPT_SIPADDPROV + +end_function: + + if (r != ERROR_SUCCESS) + { + SetLastError(r); + return FALSE; + } + + return TRUE; +} + +/*********************************************************************** + * CryptSIPRetrieveSubjectGuid (CRYPT32.@) + * + * Determine the right SIP GUID for the given file. + * + * PARAMS + * FileName [I] Filename. + * hFileIn [I] Optional handle to the file. + * pgSubject [O] The SIP's GUID. + * + * RETURNS + * Success: TRUE. pgSubject contains the SIP GUID. + * Failure: FALSE. (Look at GetLastError()). + * + * NOTES + * On failure pgSubject will contain a NULL GUID. + * The handle is always preferred above the filename. + */ +BOOL WINAPI CryptSIPRetrieveSubjectGuid + (LPCWSTR FileName, HANDLE hFileIn, GUID *pgSubject) +{ + HANDLE hFile; + HANDLE hFilemapped; + LPVOID pMapped; + BOOL bRet = FALSE; + DWORD fileSize; + IMAGE_DOS_HEADER *dos; + /* FIXME, find out if there is a name for this GUID */ + static const GUID unknown = { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47,0x00,0xC0,0x4F,0xC2,0x95,0xEE }}; + + TRACE("(%s %p %p)\n", wine_dbgstr_w(FileName), hFileIn, pgSubject); + + if (!pgSubject || (!FileName && !hFileIn)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + /* Set pgSubject to zero's */ + memset(pgSubject, 0 , sizeof(GUID)); + + if (hFileIn) + /* Use the given handle, make sure not to close this one ourselves */ + hFile = hFileIn; + else + { + hFile = CreateFileW(FileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + /* Last error is set by CreateFile */ + if (hFile == INVALID_HANDLE_VALUE) return FALSE; + } + + hFilemapped = CreateFileMappingA(hFile, NULL, PAGE_READONLY, 0, 0, NULL); + /* Last error is set by CreateFileMapping */ + if (!hFilemapped) goto cleanup3; + + pMapped = MapViewOfFile(hFilemapped, FILE_MAP_READ, 0, 0, 0); + /* Last error is set by MapViewOfFile */ + if (!pMapped) goto cleanup2; + + /* Native checks it right here */ + fileSize = GetFileSize(hFile, NULL); + if (fileSize < 4) + { + SetLastError(ERROR_INVALID_PARAMETER); + goto cleanup1; + } + + /* As everything is in place now we start looking at the file header */ + dos = (IMAGE_DOS_HEADER *)pMapped; + if (dos->e_magic == IMAGE_DOS_SIGNATURE) + { + memcpy(pgSubject, &unknown, sizeof(GUID)); + SetLastError(S_OK); + bRet = TRUE; + goto cleanup1; + } + + /* FIXME + * There is a lot more to be checked: + * - Check for MSFC in the header + * - Check for the keys CryptSIPDllIsMyFileType and CryptSIPDllIsMyFileType2 + * under HKLM\Software\Microsoft\Cryptography\OID\EncodingType 0. Here are + * functions listed that need check if a SIP Provider can deal with the + * given file. + */ + + /* Let's set the most common error for now */ + SetLastError(TRUST_E_SUBJECT_FORM_UNKNOWN); + + /* The 3 different cleanups are here because we shouldn't overwrite the last error */ +cleanup1: + UnmapViewOfFile(pMapped); +cleanup2: + CloseHandle(hFilemapped); +cleanup3: + /* If we didn't open this one we shouldn't close it (hFile is a copy) */ + if (!hFileIn) CloseHandle(hFile); + + return bRet; +} + +/*********************************************************************** + * CryptSIPLoad (CRYPT32.@) + * + * Load some internal crypt32 functions into a SIP_DISPATCH_INFO structure. + * + * PARAMS + * pgSubject [I] The GUID. + * dwFlags [I] Flags. + * pSipDispatch [I] The loaded functions. + * + * RETURNS + * Success: TRUE. pSipDispatch contains the functions. + * Failure: FALSE. (Look at GetLastError()). + * + * NOTES + * CryptSIPLoad uses caching for the list of GUIDs and whether a SIP is + * already loaded. + * + * An application calls CryptSipLoad which will return a structure with the + * function addresses of some internal crypt32 functions. The application will + * then call these functions which will be forwarded to the appropriate SIP. + * + * CryptSIPLoad will load the needed SIP but doesn't unload this dll. The unloading + * is done when crypt32 is unloaded. + */ +BOOL WINAPI CryptSIPLoad + (const GUID *pgSubject, DWORD dwFlags, SIP_DISPATCH_INFO *pSipDispatch) +{ + FIXME("(%s %d %p) stub!\n", debugstr_guid(pgSubject), dwFlags, pSipDispatch); + + if (!pgSubject || dwFlags != 0 || !pSipDispatch) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + return FALSE; +} + +/*********************************************************************** + * CryptSIPCreateIndirectData (CRYPT32.@) + */ +BOOL WINAPI CryptSIPCreateIndirectData(SIP_SUBJECTINFO* pSubjectInfo, DWORD* pcbIndirectData, + SIP_INDIRECT_DATA* pIndirectData) +{ + FIXME("(%p %p %p) stub\n", pSubjectInfo, pcbIndirectData, pIndirectData); + + return FALSE; +} + +/*********************************************************************** + * CryptSIPGetSignedDataMsg (CRYPT32.@) + */ +BOOL WINAPI CryptSIPGetSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo, DWORD* pdwEncodingType, + DWORD dwIndex, DWORD* pcbSignedDataMsg, BYTE* pbSignedDataMsg) +{ + FIXME("(%p %p %d %p %p) stub\n", pSubjectInfo, pdwEncodingType, dwIndex, + pcbSignedDataMsg, pbSignedDataMsg); + + return FALSE; +} + +/*********************************************************************** + * CryptSIPPutSignedDataMsg (CRYPT32.@) + */ +BOOL WINAPI CryptSIPPutSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo, DWORD pdwEncodingType, + DWORD* pdwIndex, DWORD cbSignedDataMsg, BYTE* pbSignedDataMsg) +{ + FIXME("(%p %d %p %d %p) stub\n", pSubjectInfo, pdwEncodingType, pdwIndex, + cbSignedDataMsg, pbSignedDataMsg); + + return FALSE; +} + +/*********************************************************************** + * CryptSIPRemoveSignedDataMsg (CRYPT32.@) + */ +BOOL WINAPI CryptSIPRemoveSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo, + DWORD dwIndex) +{ + FIXME("(%p %d) stub\n", pSubjectInfo, dwIndex); + + return FALSE; +} + +/*********************************************************************** + * CryptSIPVerifyIndirectData (CRYPT32.@) + */ +BOOL WINAPI CryptSIPVerifyIndirectData(SIP_SUBJECTINFO* pSubjectInfo, + SIP_INDIRECT_DATA* pIndirectData) +{ + FIXME("(%p %p) stub\n", pSubjectInfo, pIndirectData); + + return FALSE; +} diff --git a/reactos/dll/win32/crypt32/store.c b/reactos/dll/win32/crypt32/store.c index f1cca0e7c1f..3b9bcb815ce 100644 --- a/reactos/dll/win32/crypt32/store.c +++ b/reactos/dll/win32/crypt32/store.c @@ -23,6 +23,9 @@ * - Many flags, options and whatnot are unimplemented. */ +#include "config.h" +#include "wine/port.h" + #include #include #include "windef.h" @@ -163,6 +166,15 @@ typedef struct _WINE_REGSTOREINFO struct list crlsToDelete; } WINE_REGSTOREINFO, *PWINE_REGSTOREINFO; +typedef struct _WINE_FILESTOREINFO +{ + DWORD dwOpenFlags; + HCRYPTPROV cryptProv; + PWINECRYPT_CERTSTORE memStore; + HANDLE file; + BOOL dirty; +} WINE_FILESTOREINFO, *PWINE_FILESTOREINFO; + typedef struct _WINE_STORE_LIST_ENTRY { PWINECRYPT_CERTSTORE store; @@ -299,9 +311,9 @@ static void WINAPI CRYPT_MemCloseStore(HCERTSTORE hCertStore, DWORD dwFlags) { WINE_MEMSTORE *store = (WINE_MEMSTORE *)hCertStore; - TRACE("(%p, %08lx)\n", store, dwFlags); + TRACE("(%p, %08x)\n", store, dwFlags); if (dwFlags) - FIXME("Unimplemented flags: %08lx\n", dwFlags); + FIXME("Unimplemented flags: %08x\n", dwFlags); ContextList_Free(store->certs); ContextList_Free(store->crls); @@ -313,7 +325,7 @@ static WINECRYPT_CERTSTORE *CRYPT_MemOpenStore(HCRYPTPROV hCryptProv, { PWINE_MEMSTORE store; - TRACE("(%ld, %08lx, %p)\n", hCryptProv, dwFlags, pvPara); + TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara); if (dwFlags & CERT_STORE_DELETE_FLAG) { @@ -349,7 +361,7 @@ static void WINAPI CRYPT_CollectionCloseStore(HCERTSTORE store, DWORD dwFlags) PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store; PWINE_STORE_LIST_ENTRY entry, next; - TRACE("(%p, %08lx)\n", store, dwFlags); + TRACE("(%p, %08x)\n", store, dwFlags); LIST_FOR_EACH_ENTRY_SAFE(entry, next, &cs->stores, WINE_STORE_LIST_ENTRY, entry) @@ -358,6 +370,7 @@ static void WINAPI CRYPT_CollectionCloseStore(HCERTSTORE store, DWORD dwFlags) CertCloseStore((HCERTSTORE)entry->store, dwFlags); CryptMemFree(entry); } + cs->cs.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&cs->cs); CryptMemFree(cs); } @@ -663,6 +676,7 @@ static WINECRYPT_CERTSTORE *CRYPT_CollectionOpenStore(HCRYPTPROV hCryptProv, store->hdr.crls.enumContext = CRYPT_CollectionEnumCRL; store->hdr.crls.deleteContext = CRYPT_CollectionDeleteCRL; InitializeCriticalSection(&store->cs); + store->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PWINE_COLLECTIONSTORE->cs"); list_init(&store->stores); } } @@ -673,7 +687,7 @@ static void WINAPI CRYPT_ProvCloseStore(HCERTSTORE hCertStore, DWORD dwFlags) { PWINE_PROVIDERSTORE store = (PWINE_PROVIDERSTORE)hCertStore; - TRACE("(%p, %08lx)\n", store, dwFlags); + TRACE("(%p, %08x)\n", store, dwFlags); if (store->provCloseStore) store->provCloseStore(store->hStoreProv, dwFlags); @@ -695,21 +709,13 @@ static BOOL CRYPT_ProvAddCert(PWINECRYPT_CERTSTORE store, void *cert, (const void **)ppStoreContext); else { - if (ps->hdr.dwOpenFlags & CERT_STORE_READONLY_FLAG) - { - SetLastError(ERROR_ACCESS_DENIED); - ret = FALSE; - } - else - { - ret = TRUE; - if (ps->provWriteCert) - ret = ps->provWriteCert(ps->hStoreProv, (PCCERT_CONTEXT)cert, - CERT_STORE_PROV_WRITE_ADD_FLAG); - if (ret) - ret = ps->memStore->certs.addContext(ps->memStore, cert, NULL, - (const void **)ppStoreContext); - } + ret = TRUE; + if (ps->provWriteCert) + ret = ps->provWriteCert(ps->hStoreProv, (PCCERT_CONTEXT)cert, + CERT_STORE_PROV_WRITE_ADD_FLAG); + if (ret) + ret = ps->memStore->certs.addContext(ps->memStore, cert, NULL, + (const void **)ppStoreContext); } /* dirty trick: replace the returned context's hCertStore with * store. @@ -822,7 +828,7 @@ static BOOL WINAPI CRYPT_ProvControl(HCERTSTORE hCertStore, DWORD dwFlags, PWINE_PROVIDERSTORE store = (PWINE_PROVIDERSTORE)hCertStore; BOOL ret = TRUE; - TRACE("(%p, %08lx, %ld, %p)\n", hCertStore, dwFlags, dwCtrlType, + TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType, pvCtrlPara); if (store->provControl) @@ -832,7 +838,7 @@ static BOOL WINAPI CRYPT_ProvControl(HCERTSTORE hCertStore, DWORD dwFlags, } static PWINECRYPT_CERTSTORE CRYPT_ProvCreateStore(HCRYPTPROV hCryptProv, - DWORD dwFlags, PWINECRYPT_CERTSTORE memStore, PCERT_STORE_PROV_INFO pProvInfo) + DWORD dwFlags, PWINECRYPT_CERTSTORE memStore, const CERT_STORE_PROV_INFO *pProvInfo) { PWINE_PROVIDERSTORE ret = (PWINE_PROVIDERSTORE)CryptMemAlloc( sizeof(WINE_PROVIDERSTORE)); @@ -940,7 +946,7 @@ static PWINECRYPT_CERTSTORE CRYPT_ProvOpenStore(LPCSTR lpszStoreProvider, return ret; } -static void CRYPT_HashToStr(LPBYTE hash, LPWSTR asciiHash) +static void CRYPT_HashToStr(const BYTE *hash, LPWSTR asciiHash) { static const WCHAR fmt[] = { '%','0','2','X',0 }; DWORD i; @@ -958,7 +964,7 @@ static const WCHAR CRLsW[] = { 'C','R','L','s',0 }; static const WCHAR CTLsW[] = { 'C','T','L','s',0 }; static const WCHAR BlobW[] = { 'B','l','o','b',0 }; -static void CRYPT_RegReadSerializedFromReg(PWINE_REGSTOREINFO store, HKEY key, +static void CRYPT_RegReadSerializedFromReg(const WINE_REGSTOREINFO *store, HKEY key, DWORD contextType) { LONG rc; @@ -1051,9 +1057,9 @@ static void CRYPT_RegReadSerializedFromReg(PWINE_REGSTOREINFO store, HKEY key, } while (!rc); } -static void CRYPT_RegReadFromReg(PWINE_REGSTOREINFO store) +static void CRYPT_RegReadFromReg(const WINE_REGSTOREINFO *store) { - static const WCHAR *subKeys[] = { CertsW, CRLsW, CTLsW }; + static const WCHAR * const subKeys[] = { CertsW, CRLsW, CTLsW }; static const DWORD contextFlags[] = { CERT_STORE_CERTIFICATE_CONTEXT_FLAG, CERT_STORE_CRL_CONTEXT_FLAG, CERT_STORE_CTL_CONTEXT_FLAG }; DWORD i; @@ -1074,7 +1080,7 @@ static void CRYPT_RegReadFromReg(PWINE_REGSTOREINFO store) } /* Hash is assumed to be 20 bytes in length (a SHA-1 hash) */ -static BOOL CRYPT_WriteSerializedToReg(HKEY key, LPBYTE hash, LPBYTE buf, +static BOOL CRYPT_WriteSerializedToReg(HKEY key, const BYTE *hash, const BYTE *buf, DWORD len) { WCHAR asciiHash[20 * 2 + 1]; @@ -1142,8 +1148,8 @@ static BOOL CRYPT_SerializeContextsToReg(HKEY key, static BOOL CRYPT_RegWriteToReg(PWINE_REGSTOREINFO store) { - static const WCHAR *subKeys[] = { CertsW, CRLsW, CTLsW }; - static const WINE_CONTEXT_INTERFACE *interfaces[] = { &gCertInterface, + static const WCHAR * const subKeys[] = { CertsW, CRLsW, CTLsW }; + static const WINE_CONTEXT_INTERFACE * const interfaces[] = { &gCertInterface, &gCRLInterface, &gCTLInterface }; struct list *listToDelete[] = { &store->certsToDelete, &store->crlsToDelete, NULL }; @@ -1215,12 +1221,13 @@ static void WINAPI CRYPT_RegCloseStore(HCERTSTORE hCertStore, DWORD dwFlags) { PWINE_REGSTOREINFO store = (PWINE_REGSTOREINFO)hCertStore; - TRACE("(%p, %08lx)\n", store, dwFlags); + TRACE("(%p, %08x)\n", store, dwFlags); if (dwFlags) - FIXME("Unimplemented flags: %08lx\n", dwFlags); + FIXME("Unimplemented flags: %08x\n", dwFlags); CRYPT_RegFlushStore(store, FALSE); RegCloseKey(store->key); + store->cs.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&store->cs); CryptMemFree(store); } @@ -1287,7 +1294,7 @@ static BOOL WINAPI CRYPT_RegWriteCert(HCERTSTORE hCertStore, { PWINE_REGSTOREINFO store = (PWINE_REGSTOREINFO)hCertStore; - TRACE("(%p, %p, %ld)\n", hCertStore, cert, dwFlags); + TRACE("(%p, %p, %d)\n", hCertStore, cert, dwFlags); return CRYPT_RegWriteContext(store, cert, dwFlags); } @@ -1297,7 +1304,7 @@ static BOOL WINAPI CRYPT_RegDeleteCert(HCERTSTORE hCertStore, { PWINE_REGSTOREINFO store = (PWINE_REGSTOREINFO)hCertStore; - TRACE("(%p, %p, %08lx)\n", store, pCertContext, dwFlags); + TRACE("(%p, %p, %08x)\n", store, pCertContext, dwFlags); return CRYPT_RegDeleteContext(store, &store->certsToDelete, pCertContext, pCertInterface); @@ -1308,7 +1315,7 @@ static BOOL WINAPI CRYPT_RegWriteCRL(HCERTSTORE hCertStore, { PWINE_REGSTOREINFO store = (PWINE_REGSTOREINFO)hCertStore; - TRACE("(%p, %p, %ld)\n", hCertStore, crl, dwFlags); + TRACE("(%p, %p, %d)\n", hCertStore, crl, dwFlags); return CRYPT_RegWriteContext(store, crl, dwFlags); } @@ -1318,7 +1325,7 @@ static BOOL WINAPI CRYPT_RegDeleteCRL(HCERTSTORE hCertStore, { PWINE_REGSTOREINFO store = (PWINE_REGSTOREINFO)hCertStore; - TRACE("(%p, %p, %08lx)\n", store, pCrlContext, dwFlags); + TRACE("(%p, %p, %08x)\n", store, pCrlContext, dwFlags); return CRYPT_RegDeleteContext(store, &store->crlsToDelete, pCrlContext, pCRLInterface); @@ -1330,7 +1337,7 @@ static BOOL WINAPI CRYPT_RegControl(HCERTSTORE hCertStore, DWORD dwFlags, PWINE_REGSTOREINFO store = (PWINE_REGSTOREINFO)hCertStore; BOOL ret; - TRACE("(%p, %08lx, %ld, %p)\n", hCertStore, dwFlags, dwCtrlType, + TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType, pvCtrlPara); switch (dwCtrlType) @@ -1346,7 +1353,7 @@ static BOOL WINAPI CRYPT_RegControl(HCERTSTORE hCertStore, DWORD dwFlags, dwFlags & CERT_STORE_CTRL_COMMIT_FORCE_FLAG); break; default: - FIXME("%ld: stub\n", dwCtrlType); + FIXME("%d: stub\n", dwCtrlType); ret = FALSE; } return ret; @@ -1427,7 +1434,7 @@ static WINECRYPT_CERTSTORE *CRYPT_RegOpenStore(HCRYPTPROV hCryptProv, { PWINECRYPT_CERTSTORE store = NULL; - TRACE("(%ld, %08lx, %p)\n", hCryptProv, dwFlags, pvPara); + TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara); if (dwFlags & CERT_STORE_DELETE_FLAG) { @@ -1467,6 +1474,7 @@ static WINECRYPT_CERTSTORE *CRYPT_RegOpenStore(HCRYPTPROV hCryptProv, regInfo->memStore = memStore; regInfo->key = key; InitializeCriticalSection(®Info->cs); + regInfo->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PWINE_REGSTOREINFO->cs"); list_init(®Info->certsToDelete); list_init(®Info->crlsToDelete); CRYPT_RegReadFromReg(regInfo); @@ -1502,7 +1510,7 @@ static PWINECRYPT_CERTSTORE CRYPT_SysRegOpenStoreW(HCRYPTPROV hCryptProv, LPCWSTR base; BOOL ret; - TRACE("(%ld, %08lx, %s)\n", hCryptProv, dwFlags, + TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags, debugstr_w((LPCWSTR)pvPara)); if (!pvPara) @@ -1602,7 +1610,7 @@ static PWINECRYPT_CERTSTORE CRYPT_SysRegOpenStoreA(HCRYPTPROV hCryptProv, int len; PWINECRYPT_CERTSTORE ret = NULL; - TRACE("(%ld, %08lx, %s)\n", hCryptProv, dwFlags, + TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags, debugstr_a((LPCSTR)pvPara)); if (!pvPara) @@ -1631,7 +1639,7 @@ static PWINECRYPT_CERTSTORE CRYPT_SysOpenStoreW(HCRYPTPROV hCryptProv, HCERTSTORE store = 0; BOOL ret; - TRACE("(%ld, %08lx, %s)\n", hCryptProv, dwFlags, + TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags, debugstr_w((LPCWSTR)pvPara)); if (!pvPara) @@ -1700,7 +1708,7 @@ static PWINECRYPT_CERTSTORE CRYPT_SysOpenStoreA(HCRYPTPROV hCryptProv, int len; PWINECRYPT_CERTSTORE ret = NULL; - TRACE("(%ld, %08lx, %s)\n", hCryptProv, dwFlags, + TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags, debugstr_a((LPCSTR)pvPara)); if (!pvPara) @@ -1723,12 +1731,215 @@ static PWINECRYPT_CERTSTORE CRYPT_SysOpenStoreA(HCRYPTPROV hCryptProv, return ret; } +static void WINAPI CRYPT_FileCloseStore(HCERTSTORE hCertStore, DWORD dwFlags) +{ + PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore; + + TRACE("(%p, %08x)\n", store, dwFlags); + if (store->dirty) + CRYPT_WriteSerializedFile(store->file, store->memStore); + CertCloseStore(store->memStore, dwFlags); + CloseHandle(store->file); + CryptMemFree(store); +} + +static BOOL WINAPI CRYPT_FileWriteCert(HCERTSTORE hCertStore, + PCCERT_CONTEXT cert, DWORD dwFlags) +{ + PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore; + + TRACE("(%p, %p, %d)\n", hCertStore, cert, dwFlags); + store->dirty = TRUE; + return TRUE; +} + +static BOOL WINAPI CRYPT_FileDeleteCert(HCERTSTORE hCertStore, + PCCERT_CONTEXT pCertContext, DWORD dwFlags) +{ + PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore; + + TRACE("(%p, %p, %08x)\n", hCertStore, pCertContext, dwFlags); + store->dirty = TRUE; + return TRUE; +} + +static BOOL WINAPI CRYPT_FileWriteCRL(HCERTSTORE hCertStore, + PCCRL_CONTEXT crl, DWORD dwFlags) +{ + PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore; + + TRACE("(%p, %p, %d)\n", hCertStore, crl, dwFlags); + store->dirty = TRUE; + return TRUE; +} + +static BOOL WINAPI CRYPT_FileDeleteCRL(HCERTSTORE hCertStore, + PCCRL_CONTEXT pCrlContext, DWORD dwFlags) +{ + PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore; + + TRACE("(%p, %p, %08x)\n", hCertStore, pCrlContext, dwFlags); + store->dirty = TRUE; + return TRUE; +} + +static BOOL WINAPI CRYPT_FileControl(HCERTSTORE hCertStore, DWORD dwFlags, + DWORD dwCtrlType, void const *pvCtrlPara) +{ + PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore; + BOOL ret; + + TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType, + pvCtrlPara); + + switch (dwCtrlType) + { + case CERT_STORE_CTRL_RESYNC: + CRYPT_MemEmptyStore((PWINE_MEMSTORE)store->memStore); + CRYPT_ReadSerializedFile(store->file, store); + ret = TRUE; + break; + case CERT_STORE_CTRL_COMMIT: + if (!(store->dwOpenFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG)) + { + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + ret = FALSE; + } + else if (store->dirty) + ret = CRYPT_WriteSerializedFile(store->file, store->memStore); + else + ret = TRUE; + break; + default: + FIXME("%d: stub\n", dwCtrlType); + ret = FALSE; + } + return ret; +} + +static void *fileProvFuncs[] = { + CRYPT_FileCloseStore, + NULL, /* CERT_STORE_PROV_READ_CERT_FUNC */ + CRYPT_FileWriteCert, + CRYPT_FileDeleteCert, + NULL, /* CERT_STORE_PROV_SET_CERT_PROPERTY_FUNC */ + NULL, /* CERT_STORE_PROV_READ_CRL_FUNC */ + CRYPT_FileWriteCRL, + CRYPT_FileDeleteCRL, + NULL, /* CERT_STORE_PROV_SET_CRL_PROPERTY_FUNC */ + NULL, /* CERT_STORE_PROV_READ_CTL_FUNC */ + NULL, /* CERT_STORE_PROV_WRITE_CTL_FUNC */ + NULL, /* CERT_STORE_PROV_DELETE_CTL_FUNC */ + NULL, /* CERT_STORE_PROV_SET_CTL_PROPERTY_FUNC */ + CRYPT_FileControl, +}; + +static PWINECRYPT_CERTSTORE CRYPT_FileOpenStore(HCRYPTPROV hCryptProv, + DWORD dwFlags, const void *pvPara) +{ + PWINECRYPT_CERTSTORE store = NULL; + HANDLE file = (HANDLE)pvPara; + + TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara); + + if (!pvPara) + { + SetLastError(ERROR_INVALID_HANDLE); + return NULL; + } + if (dwFlags & CERT_STORE_DELETE_FLAG) + { + SetLastError(E_INVALIDARG); + return NULL; + } + if ((dwFlags & CERT_STORE_READONLY_FLAG) && + (dwFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG)) + { + SetLastError(E_INVALIDARG); + return NULL; + } + + if (DuplicateHandle(GetCurrentProcess(), (HANDLE)pvPara, + GetCurrentProcess(), &file, dwFlags & CERT_STORE_READONLY_FLAG ? + GENERIC_READ : GENERIC_READ | GENERIC_WRITE, TRUE, 0)) + { + PWINECRYPT_CERTSTORE memStore; + + memStore = CRYPT_MemOpenStore(hCryptProv, dwFlags, NULL); + if (memStore) + { + if (CRYPT_ReadSerializedFile(file, memStore)) + { + PWINE_FILESTOREINFO info = CryptMemAlloc( + sizeof(WINE_FILESTOREINFO)); + + if (info) + { + CERT_STORE_PROV_INFO provInfo = { 0 }; + + info->dwOpenFlags = dwFlags; + info->cryptProv = hCryptProv; + info->memStore = memStore; + info->file = file; + info->dirty = FALSE; + provInfo.cbSize = sizeof(provInfo); + provInfo.cStoreProvFunc = sizeof(fileProvFuncs) / + sizeof(fileProvFuncs[0]); + provInfo.rgpvStoreProvFunc = fileProvFuncs; + provInfo.hStoreProv = info; + store = CRYPT_ProvCreateStore(hCryptProv, dwFlags, memStore, + &provInfo); + } + } + } + } + TRACE("returning %p\n", store); + return store; +} + static PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreW(HCRYPTPROV hCryptProv, DWORD dwFlags, const void *pvPara) { - FIXME("(%ld, %08lx, %s): stub\n", hCryptProv, dwFlags, - debugstr_w((LPCWSTR)pvPara)); - return NULL; + HCERTSTORE store = 0; + LPCWSTR fileName = (LPCWSTR)pvPara; + DWORD access, create; + HANDLE file; + + TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags, debugstr_w(fileName)); + + if (!fileName) + { + SetLastError(ERROR_PATH_NOT_FOUND); + return NULL; + } + if (!(dwFlags & (CERT_FILE_STORE_COMMIT_ENABLE_FLAG | + CERT_STORE_READONLY_FLAG))) + { + SetLastError(ERROR_FILE_NOT_FOUND); + return NULL; + } + + access = GENERIC_READ; + if (dwFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG) + access |= GENERIC_WRITE; + if (dwFlags & CERT_STORE_CREATE_NEW_FLAG) + create = CREATE_NEW; + else if (dwFlags & CERT_STORE_OPEN_EXISTING_FLAG) + create = OPEN_EXISTING; + else + create = OPEN_ALWAYS; + file = CreateFileW(fileName, access, FILE_SHARE_READ, NULL, create, + FILE_ATTRIBUTE_NORMAL, NULL); + if (file != INVALID_HANDLE_VALUE) + { + /* FIXME: need to check whether it's a serialized store; if not, fall + * back to a PKCS#7 signed message, then to a single serialized cert. + */ + store = CertOpenStore(CERT_STORE_PROV_FILE, 0, hCryptProv, dwFlags, + file); + CloseHandle(file); + } + return (PWINECRYPT_CERTSTORE)store; } static PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreA(HCRYPTPROV hCryptProv, @@ -1737,7 +1948,7 @@ static PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreA(HCRYPTPROV hCryptProv, int len; PWINECRYPT_CERTSTORE ret = NULL; - TRACE("(%ld, %08lx, %s)\n", hCryptProv, dwFlags, + TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags, debugstr_a((LPCSTR)pvPara)); if (!pvPara) @@ -1764,9 +1975,9 @@ static PWINECRYPT_CERTSTORE CRYPT_PhysOpenStoreW(HCRYPTPROV hCryptProv, DWORD dwFlags, const void *pvPara) { if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG) - FIXME("(%ld, %08lx, %p): stub\n", hCryptProv, dwFlags, pvPara); + FIXME("(%ld, %08x, %p): stub\n", hCryptProv, dwFlags, pvPara); else - FIXME("(%ld, %08lx, %s): stub\n", hCryptProv, dwFlags, + FIXME("(%ld, %08x, %s): stub\n", hCryptProv, dwFlags, debugstr_w((LPCWSTR)pvPara)); return NULL; } @@ -1778,7 +1989,7 @@ HCERTSTORE WINAPI CertOpenStore(LPCSTR lpszStoreProvider, WINECRYPT_CERTSTORE *hcs; StoreOpenFunc openFunc = NULL; - TRACE("(%s, %08lx, %08lx, %08lx, %p)\n", debugstr_a(lpszStoreProvider), + TRACE("(%s, %08x, %08lx, %08x, %p)\n", debugstr_a(lpszStoreProvider), dwMsgAndCertEncodingType, hCryptProv, dwFlags, pvPara); if (!HIWORD(lpszStoreProvider)) @@ -1788,6 +1999,9 @@ HCERTSTORE WINAPI CertOpenStore(LPCSTR lpszStoreProvider, case (int)CERT_STORE_PROV_MEMORY: openFunc = CRYPT_MemOpenStore; break; + case (int)CERT_STORE_PROV_FILE: + openFunc = CRYPT_FileOpenStore; + break; case (int)CERT_STORE_PROV_REG: openFunc = CRYPT_RegOpenStore; break; @@ -1822,6 +2036,8 @@ HCERTSTORE WINAPI CertOpenStore(LPCSTR lpszStoreProvider, } else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_MEMORY)) openFunc = CRYPT_MemOpenStore; + else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_FILENAME_W)) + openFunc = CRYPT_FileOpenStore; else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_SYSTEM)) openFunc = CRYPT_SysOpenStoreW; else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_COLLECTION)) @@ -1869,7 +2085,7 @@ HCERTSTORE WINAPI CertOpenSystemStoreW(HCRYPTPROV hProv, BOOL WINAPI CertSaveStore(HCERTSTORE hCertStore, DWORD dwMsgAndCertEncodingType, DWORD dwSaveAs, DWORD dwSaveTo, void* pvSaveToPara, DWORD dwFlags) { - FIXME("(%p,%ld,%ld,%ld,%p,%08lx) stub!\n", hCertStore, + FIXME("(%p,%d,%d,%d,%p,%08x) stub!\n", hCertStore, dwMsgAndCertEncodingType, dwSaveAs, dwSaveTo, pvSaveToPara, dwFlags); return TRUE; } @@ -1900,7 +2116,7 @@ BOOL WINAPI CertAddCertificateContextToStore(HCERTSTORE hCertStore, BOOL ret = TRUE; PCCERT_CONTEXT toAdd = NULL, existing = NULL; - TRACE("(%p, %p, %08lx, %p)\n", hCertStore, pCertContext, + TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCertContext, dwAddDisposition, ppStoreContext); /* Weird case to pass a test */ @@ -1954,7 +2170,7 @@ BOOL WINAPI CertAddCertificateContextToStore(HCERTSTORE hCertStore, CertContext_CopyProperties(existing, pCertContext); break; default: - FIXME("Unimplemented add disposition %ld\n", dwAddDisposition); + FIXME("Unimplemented add disposition %d\n", dwAddDisposition); ret = FALSE; } @@ -2027,7 +2243,7 @@ BOOL WINAPI CertAddCRLContextToStore(HCERTSTORE hCertStore, BOOL ret = TRUE; PCCRL_CONTEXT toAdd = NULL, existing = NULL; - TRACE("(%p, %p, %08lx, %p)\n", hCertStore, pCrlContext, + TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCrlContext, dwAddDisposition, ppStoreContext); /* Weird case to pass a test */ @@ -2088,7 +2304,7 @@ BOOL WINAPI CertAddCRLContextToStore(HCERTSTORE hCertStore, CrlContext_CopyProperties(existing, pCrlContext); break; default: - FIXME("Unimplemented add disposition %ld\n", dwAddDisposition); + FIXME("Unimplemented add disposition %d\n", dwAddDisposition); ret = FALSE; } @@ -2153,7 +2369,7 @@ PCCRL_CONTEXT WINAPI CertEnumCRLsInStore(HCERTSTORE hCertStore, PCCTL_CONTEXT WINAPI CertCreateCTLContext(DWORD dwCertEncodingType, const BYTE* pbCtlEncoded, DWORD cbCtlEncoded) { - FIXME("(%08lx, %p, %08lx): stub\n", dwCertEncodingType, pbCtlEncoded, + FIXME("(%08x, %p, %08x): stub\n", dwCertEncodingType, pbCtlEncoded, cbCtlEncoded); return NULL; } @@ -2162,7 +2378,7 @@ BOOL WINAPI CertAddEncodedCTLToStore(HCERTSTORE hCertStore, DWORD dwMsgAndCertEncodingType, const BYTE *pbCtlEncoded, DWORD cbCtlEncoded, DWORD dwAddDisposition, PCCTL_CONTEXT *ppCtlContext) { - FIXME("(%p, %08lx, %p, %ld, %08lx, %p): stub\n", hCertStore, + FIXME("(%p, %08x, %p, %d, %08x, %p): stub\n", hCertStore, dwMsgAndCertEncodingType, pbCtlEncoded, cbCtlEncoded, dwAddDisposition, ppCtlContext); return FALSE; @@ -2172,7 +2388,7 @@ BOOL WINAPI CertAddCTLContextToStore(HCERTSTORE hCertStore, PCCTL_CONTEXT pCtlContext, DWORD dwAddDisposition, PCCTL_CONTEXT* ppStoreContext) { - FIXME("(%p, %p, %08lx, %p): stub\n", hCertStore, pCtlContext, + FIXME("(%p, %p, %08x, %p): stub\n", hCertStore, pCtlContext, dwAddDisposition, ppStoreContext); return TRUE; } @@ -2217,7 +2433,7 @@ BOOL WINAPI CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags) { WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *) hCertStore; - TRACE("(%p, %08lx)\n", hCertStore, dwFlags); + TRACE("(%p, %08x)\n", hCertStore, dwFlags); if( ! hCertStore ) return TRUE; @@ -2234,7 +2450,7 @@ BOOL WINAPI CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags) hcs->closeStore(hcs, dwFlags); } else - TRACE("%p's ref count is %ld\n", hcs, hcs->ref); + TRACE("%p's ref count is %d\n", hcs, hcs->ref); return TRUE; } @@ -2244,7 +2460,7 @@ BOOL WINAPI CertControlStore(HCERTSTORE hCertStore, DWORD dwFlags, WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *)hCertStore; BOOL ret; - TRACE("(%p, %08lx, %ld, %p)\n", hCertStore, dwFlags, dwCtrlType, + TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType, pvCtrlPara); if (!hcs) @@ -2264,21 +2480,21 @@ BOOL WINAPI CertControlStore(HCERTSTORE hCertStore, DWORD dwFlags, DWORD WINAPI CertEnumCTLContextProperties(PCCTL_CONTEXT pCTLContext, DWORD dwPropId) { - FIXME("(%p, %ld): stub\n", pCTLContext, dwPropId); + FIXME("(%p, %d): stub\n", pCTLContext, dwPropId); return 0; } BOOL WINAPI CertGetCTLContextProperty(PCCTL_CONTEXT pCTLContext, DWORD dwPropId, void *pvData, DWORD *pcbData) { - FIXME("(%p, %ld, %p, %p): stub\n", pCTLContext, dwPropId, pvData, pcbData); + FIXME("(%p, %d, %p, %p): stub\n", pCTLContext, dwPropId, pvData, pcbData); return FALSE; } BOOL WINAPI CertSetCTLContextProperty(PCCTL_CONTEXT pCTLContext, DWORD dwPropId, DWORD dwFlags, const void *pvData) { - FIXME("(%p, %ld, %08lx, %p): stub\n", pCTLContext, dwPropId, dwFlags, + FIXME("(%p, %d, %08x, %p): stub\n", pCTLContext, dwPropId, dwFlags, pvData); return FALSE; } @@ -2291,7 +2507,7 @@ BOOL WINAPI CertAddStoreToCollection(HCERTSTORE hCollectionStore, PWINE_STORE_LIST_ENTRY entry; BOOL ret; - TRACE("(%p, %p, %08lx, %ld)\n", hCollectionStore, hSiblingStore, + TRACE("(%p, %p, %08x, %d)\n", hCollectionStore, hSiblingStore, dwUpdateFlags, dwPriority); if (!collection || !sibling) @@ -2316,12 +2532,12 @@ BOOL WINAPI CertAddStoreToCollection(HCERTSTORE hCollectionStore, if (entry) { InterlockedIncrement(&sibling->ref); - TRACE("sibling %p's ref count is %ld\n", sibling, sibling->ref); + TRACE("sibling %p's ref count is %d\n", sibling, sibling->ref); entry->store = sibling; entry->dwUpdateFlags = dwUpdateFlags; entry->dwPriority = dwPriority; list_init(&entry->entry); - TRACE("%p: adding %p, priority %ld\n", collection, entry, dwPriority); + TRACE("%p: adding %p, priority %d\n", collection, entry, dwPriority); EnterCriticalSection(&collection->cs); if (dwPriority) { diff --git a/reactos/dll/win32/crypt32/str.c b/reactos/dll/win32/crypt32/str.c index 32986524b9b..a4e9e92141e 100644 --- a/reactos/dll/win32/crypt32/str.c +++ b/reactos/dll/win32/crypt32/str.c @@ -19,8 +19,10 @@ #include "windef.h" #include "winbase.h" #include "winnls.h" +#include "winuser.h" #include "wincrypt.h" #include "wine/debug.h" +#include "wine/unicode.h" WINE_DEFAULT_DEBUG_CHANNEL(crypt); @@ -29,14 +31,20 @@ DWORD WINAPI CertRDNValueToStrA(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue, { DWORD ret = 0; - TRACE("(%ld, %p, %p, %ld)\n", dwValueType, pValue, psz, csz); + TRACE("(%d, %p, %p, %d)\n", dwValueType, pValue, psz, csz); switch (dwValueType) { case CERT_RDN_ANY_TYPE: break; + case CERT_RDN_NUMERIC_STRING: case CERT_RDN_PRINTABLE_STRING: + case CERT_RDN_TELETEX_STRING: + case CERT_RDN_VIDEOTEX_STRING: case CERT_RDN_IA5_STRING: + case CERT_RDN_GRAPHIC_STRING: + case CERT_RDN_VISIBLE_STRING: + case CERT_RDN_GENERAL_STRING: if (!psz || !csz) ret = pValue->cbData; else @@ -52,7 +60,7 @@ DWORD WINAPI CertRDNValueToStrA(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue, } break; default: - FIXME("string type %ld unimplemented\n", dwValueType); + FIXME("string type %d unimplemented\n", dwValueType); } if (psz && csz) { @@ -62,7 +70,7 @@ DWORD WINAPI CertRDNValueToStrA(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue, } else ret++; - TRACE("returning %ld (%s)\n", ret, debugstr_a(psz)); + TRACE("returning %d (%s)\n", ret, debugstr_a(psz)); return ret; } @@ -71,14 +79,20 @@ DWORD WINAPI CertRDNValueToStrW(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue, { DWORD ret = 0; - TRACE("(%ld, %p, %p, %ld)\n", dwValueType, pValue, psz, csz); + TRACE("(%d, %p, %p, %d)\n", dwValueType, pValue, psz, csz); switch (dwValueType) { case CERT_RDN_ANY_TYPE: break; + case CERT_RDN_NUMERIC_STRING: case CERT_RDN_PRINTABLE_STRING: + case CERT_RDN_TELETEX_STRING: + case CERT_RDN_VIDEOTEX_STRING: case CERT_RDN_IA5_STRING: + case CERT_RDN_GRAPHIC_STRING: + case CERT_RDN_VISIBLE_STRING: + case CERT_RDN_GENERAL_STRING: if (!psz || !csz) ret = pValue->cbData; else @@ -97,7 +111,7 @@ DWORD WINAPI CertRDNValueToStrW(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue, } break; default: - FIXME("string type %ld unimplemented\n", dwValueType); + FIXME("string type %d unimplemented\n", dwValueType); } if (psz && csz) { @@ -107,7 +121,7 @@ DWORD WINAPI CertRDNValueToStrW(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue, } else ret++; - TRACE("returning %ld (%s)\n", ret, debugstr_w(psz)); + TRACE("returning %d (%s)\n", ret, debugstr_w(psz)); return ret; } @@ -120,7 +134,7 @@ static DWORD CRYPT_AddPrefixA(LPCSTR prefix, LPSTR psz, DWORD csz) { DWORD chars; - TRACE("(%s, %p, %ld)\n", debugstr_a(prefix), psz, csz); + TRACE("(%s, %p, %d)\n", debugstr_a(prefix), psz, csz); if (psz) { @@ -150,10 +164,10 @@ DWORD WINAPI CertNameToStrA(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName, BOOL bRet; CERT_NAME_INFO *info; - TRACE("(%ld, %p, %08lx, %p, %ld)\n", dwCertEncodingType, pName, dwStrType, + TRACE("(%d, %p, %08x, %p, %d)\n", dwCertEncodingType, pName, dwStrType, psz, csz); if (dwStrType & unsupportedFlags) - FIXME("unsupported flags: %08lx\n", dwStrType & unsupportedFlags); + FIXME("unsupported flags: %08x\n", dwStrType & unsupportedFlags); bRet = CryptDecodeObjectEx(dwCertEncodingType, X509_NAME, pName->pbData, pName->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &bytes); @@ -253,7 +267,7 @@ static DWORD CRYPT_AddPrefixAToW(LPCSTR prefix, LPWSTR psz, DWORD csz) { DWORD chars; - TRACE("(%s, %p, %ld)\n", debugstr_a(prefix), psz, csz); + TRACE("(%s, %p, %d)\n", debugstr_a(prefix), psz, csz); if (psz) { @@ -281,7 +295,7 @@ static DWORD CRYPT_AddPrefixW(LPCWSTR prefix, LPWSTR psz, DWORD csz) { DWORD chars; - TRACE("(%s, %p, %ld)\n", debugstr_w(prefix), psz, csz); + TRACE("(%s, %p, %d)\n", debugstr_w(prefix), psz, csz); if (psz) { @@ -311,10 +325,10 @@ DWORD WINAPI CertNameToStrW(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName, BOOL bRet; CERT_NAME_INFO *info; - TRACE("(%ld, %p, %08lx, %p, %ld)\n", dwCertEncodingType, pName, dwStrType, + TRACE("(%d, %p, %08x, %p, %d)\n", dwCertEncodingType, pName, dwStrType, psz, csz); if (dwStrType & unsupportedFlags) - FIXME("unsupported flags: %08lx\n", dwStrType & unsupportedFlags); + FIXME("unsupported flags: %08x\n", dwStrType & unsupportedFlags); bRet = CryptDecodeObjectEx(dwCertEncodingType, X509_NAME, pName->pbData, pName->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &bytes); @@ -408,12 +422,383 @@ DWORD WINAPI CertNameToStrW(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName, return ret; } +BOOL WINAPI CertStrToNameA(DWORD dwCertEncodingType, LPCSTR pszX500, + DWORD dwStrType, void *pvReserved, BYTE *pbEncoded, DWORD *pcbEncoded, + LPCSTR *ppszError) +{ + LPWSTR x500, errorStr; + BOOL ret; + int len; + + TRACE("(%08x, %s, %08x, %p, %p, %p, %p)\n", dwCertEncodingType, + debugstr_a(pszX500), dwStrType, pvReserved, pbEncoded, pcbEncoded, + ppszError); + + len = MultiByteToWideChar(CP_ACP, 0, pszX500, -1, NULL, 0); + x500 = CryptMemAlloc(len * sizeof(WCHAR)); + if (x500) + { + MultiByteToWideChar(CP_ACP, 0, pszX500, -1, x500, len); + ret = CertStrToNameW(dwCertEncodingType, x500, dwStrType, pvReserved, + pbEncoded, pcbEncoded, ppszError ? (LPCWSTR *)&errorStr : NULL); + if (ppszError) + { + DWORD i; + + *ppszError = pszX500; + for (i = 0; i < errorStr - x500; i++) + CharNextA(*ppszError); + } + CryptMemFree(x500); + } + else + ret = FALSE; + return ret; +} + +struct KeynameKeeper +{ + WCHAR buf[10]; /* big enough for L"GivenName" */ + LPWSTR keyName; /* usually = buf, but may be allocated */ + DWORD keyLen; +}; + +static void CRYPT_InitializeKeynameKeeper(struct KeynameKeeper *keeper) +{ + keeper->keyName = keeper->buf; + keeper->keyLen = sizeof(keeper->buf) / sizeof(keeper->buf[0]); +} + +static void CRYPT_FreeKeynameKeeper(struct KeynameKeeper *keeper) +{ + if (keeper->keyName != keeper->buf) + CryptMemFree(keeper->keyName); +} + +struct X500TokenW +{ + LPCWSTR start; + LPCWSTR end; +}; + +static void CRYPT_KeynameKeeperFromTokenW(struct KeynameKeeper *keeper, + const struct X500TokenW *key) +{ + DWORD len = key->end - key->start; + + if (len > keeper->keyLen) + { + if (keeper->keyName == keeper->buf) + keeper->keyName = CryptMemAlloc(len * sizeof(WCHAR)); + else + keeper->keyName = CryptMemRealloc(keeper->keyName, + len * sizeof(WCHAR)); + keeper->keyLen = len; + } + memcpy(keeper->keyName, key->start, (key->end - key->start) * + sizeof(WCHAR)); + keeper->keyName[len] = '\0'; + TRACE("Keyname is %s\n", debugstr_w(keeper->keyName)); +} + +static DWORD CRYPT_GetNextKeyW(LPCWSTR str, struct X500TokenW *token, + LPCWSTR *ppszError) +{ + DWORD ret = ERROR_SUCCESS; + + while (*str && isspaceW(*str)) + str++; + if (*str) + { + token->start = str; + while (*str && *str != '=' && !isspaceW(*str)) + str++; + if (*str && (*str == '=' || isspaceW(*str))) + token->end = str; + else + { + TRACE("missing equals char at %s\n", debugstr_w(token->start)); + if (ppszError) + *ppszError = token->start; + ret = CRYPT_E_INVALID_X500_STRING; + } + } + else + token->start = NULL; + return ret; +} + +/* Assumes separators are characters in the 0-255 range */ +static DWORD CRYPT_GetNextValueW(LPCWSTR str, DWORD dwFlags, LPCWSTR separators, + struct X500TokenW *token, LPCWSTR *ppszError) +{ + DWORD ret = ERROR_SUCCESS; + + TRACE("(%s, %s, %p, %p)\n", debugstr_w(str), debugstr_w(separators), token, + ppszError); + + while (*str && isspaceW(*str)) + str++; + if (*str) + { + token->start = str; + if (!(dwFlags & CERT_NAME_STR_NO_QUOTING_FLAG) && *str == '"') + { + token->end = NULL; + str++; + while (!token->end && !ret) + { + while (*str && *str != '"') + str++; + if (*str == '"') + { + if (*(str + 1) != '"') + token->end = str + 1; + else + str += 2; + } + else + { + TRACE("unterminated quote at %s\n", debugstr_w(str)); + if (ppszError) + *ppszError = str; + ret = CRYPT_E_INVALID_X500_STRING; + } + } + } + else + { + WCHAR map[256] = { 0 }; + + while (*separators) + map[*separators++] = 1; + while (*str && (*str >= 0xff || !map[*(const unsigned short *)str])) + str++; + token->end = str; + } + } + else + { + TRACE("missing value at %s\n", debugstr_w(str)); + if (ppszError) + *ppszError = str; + ret = CRYPT_E_INVALID_X500_STRING; + } + return ret; +} + +/* Encodes the string represented by value as the string type type into the + * CERT_NAME_BLOB output. If there is an error and ppszError is not NULL, + * *ppszError is set to the first failing character. If there is no error, + * output's pbData must be freed with LocalFree. + */ +static BOOL CRYPT_EncodeValueWithType(DWORD dwCertEncodingType, + const struct X500TokenW *value, PCERT_NAME_BLOB output, DWORD type, + LPCWSTR *ppszError) +{ + CERT_NAME_VALUE nameValue = { type, { 0, NULL } }; + BOOL ret = FALSE; + + nameValue.Value.pbData = CryptMemAlloc((value->end - value->start) * + sizeof(WCHAR)); + if (nameValue.Value.pbData) + { + DWORD i; + LPWSTR ptr = (LPWSTR)nameValue.Value.pbData; + + for (i = 0; i < value->end - value->start; i++) + { + *ptr++ = value->start[i]; + if (value->start[i] == '"') + i++; + } + nameValue.Value.cbData = (LPBYTE)ptr - nameValue.Value.pbData; + ret = CryptEncodeObjectEx(dwCertEncodingType, X509_UNICODE_NAME_VALUE, + &nameValue, CRYPT_ENCODE_ALLOC_FLAG, NULL, &output->pbData, + &output->cbData); + if (!ret && ppszError) + { + if (type == CERT_RDN_NUMERIC_STRING && + GetLastError() == CRYPT_E_INVALID_NUMERIC_STRING) + *ppszError = value->start + output->cbData; + else if (type == CERT_RDN_PRINTABLE_STRING && + GetLastError() == CRYPT_E_INVALID_PRINTABLE_STRING) + *ppszError = value->start + output->cbData; + else if (type == CERT_RDN_IA5_STRING && + GetLastError() == CRYPT_E_INVALID_IA5_STRING) + *ppszError = value->start + output->cbData; + } + CryptMemFree(nameValue.Value.pbData); + } + return ret; +} + +static BOOL CRYPT_EncodeValue(DWORD dwCertEncodingType, + const struct X500TokenW *value, PCERT_NAME_BLOB output, const DWORD *types, + LPCWSTR *ppszError) +{ + DWORD i; + BOOL ret; + + ret = FALSE; + for (i = 0; !ret && types[i]; i++) + ret = CRYPT_EncodeValueWithType(dwCertEncodingType, value, output, + types[i], ppszError); + return ret; +} + +static BOOL CRYPT_ValueToRDN(DWORD dwCertEncodingType, PCERT_NAME_INFO info, + PCCRYPT_OID_INFO keyOID, struct X500TokenW *value, LPCWSTR *ppszError) +{ + BOOL ret = FALSE; + + TRACE("OID %s, value %s\n", debugstr_a(keyOID->pszOID), + debugstr_wn(value->start, value->end - value->start)); + + if (!info->rgRDN) + info->rgRDN = CryptMemAlloc(sizeof(CERT_RDN)); + else + info->rgRDN = CryptMemRealloc(info->rgRDN, + (info->cRDN + 1) * sizeof(CERT_RDN)); + if (info->rgRDN) + { + /* FIXME: support multiple RDN attrs */ + info->rgRDN[info->cRDN].rgRDNAttr = + CryptMemAlloc(sizeof(CERT_RDN_ATTR)); + if (info->rgRDN[info->cRDN].rgRDNAttr) + { + static const DWORD defaultTypes[] = { CERT_RDN_PRINTABLE_STRING, + CERT_RDN_BMP_STRING, 0 }; + const DWORD *types; + + info->rgRDN[info->cRDN].cRDNAttr = 1; + info->rgRDN[info->cRDN].rgRDNAttr[0].pszObjId = + (LPSTR)keyOID->pszOID; + info->rgRDN[info->cRDN].rgRDNAttr[0].dwValueType = + CERT_RDN_ENCODED_BLOB; + if (keyOID->ExtraInfo.cbData) + types = (const DWORD *)keyOID->ExtraInfo.pbData; + else + types = defaultTypes; + + /* Remove surrounding quotes */ + if (value->start[0] == '"') + { + value->start++; + value->end--; + } + ret = CRYPT_EncodeValue(dwCertEncodingType, value, + &info->rgRDN[info->cRDN].rgRDNAttr[0].Value, types, ppszError); + } + } + if (ret) + info->cRDN++; + return ret; +} + +BOOL WINAPI CertStrToNameW(DWORD dwCertEncodingType, LPCWSTR pszX500, + DWORD dwStrType, void *pvReserved, BYTE *pbEncoded, DWORD *pcbEncoded, + LPCWSTR *ppszError) +{ + CERT_NAME_INFO info = { 0, NULL }; + LPCWSTR str; + struct KeynameKeeper keeper; + DWORD i, error = ERROR_SUCCESS; + BOOL ret = TRUE; + + TRACE("(%08x, %s, %08x, %p, %p, %p, %p)\n", dwCertEncodingType, + debugstr_w(pszX500), dwStrType, pvReserved, pbEncoded, pcbEncoded, + ppszError); + + CRYPT_InitializeKeynameKeeper(&keeper); + str = pszX500; + while (str && *str && !error && ret) + { + struct X500TokenW token; + + error = CRYPT_GetNextKeyW(str, &token, ppszError); + if (!error && token.start) + { + PCCRYPT_OID_INFO keyOID; + + CRYPT_KeynameKeeperFromTokenW(&keeper, &token); + keyOID = CryptFindOIDInfo(CRYPT_OID_INFO_NAME_KEY, keeper.keyName, + CRYPT_RDN_ATTR_OID_GROUP_ID); + if (!keyOID) + { + if (ppszError) + *ppszError = token.start; + error = CRYPT_E_INVALID_X500_STRING; + } + else + { + str = token.end; + while (isspace(*str)) + str++; + if (*str != '=') + { + if (ppszError) + *ppszError = str; + error = CRYPT_E_INVALID_X500_STRING; + } + else + { + static const WCHAR commaSep[] = { ',',0 }; + static const WCHAR semiSep[] = { ';',0 }; + static const WCHAR crlfSep[] = { '\r','\n',0 }; + static const WCHAR allSeps[] = { ',',';','\r','\n',0 }; + LPCWSTR sep; + + str++; + if (dwStrType & CERT_NAME_STR_COMMA_FLAG) + sep = commaSep; + else if (dwStrType & CERT_NAME_STR_SEMICOLON_FLAG) + sep = semiSep; + else if (dwStrType & CERT_NAME_STR_CRLF_FLAG) + sep = crlfSep; + else + sep = allSeps; + error = CRYPT_GetNextValueW(str, dwStrType, sep, &token, + ppszError); + if (!error) + { + str = token.end; + ret = CRYPT_ValueToRDN(dwCertEncodingType, &info, + keyOID, &token, ppszError); + } + } + } + } + } + CRYPT_FreeKeynameKeeper(&keeper); + if (!error) + { + ret = CryptEncodeObjectEx(dwCertEncodingType, X509_NAME, &info, + 0, NULL, pbEncoded, pcbEncoded); + for (i = 0; i < info.cRDN; i++) + { + DWORD j; + + for (j = 0; j < info.rgRDN[i].cRDNAttr; j++) + LocalFree(info.rgRDN[i].rgRDNAttr[j].Value.pbData); + CryptMemFree(info.rgRDN[i].rgRDNAttr); + } + CryptMemFree(info.rgRDN); + } + else + { + SetLastError(error); + ret = FALSE; + } + return ret; +} + DWORD WINAPI CertGetNameStringA(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD dwFlags, void *pvTypePara, LPSTR pszNameString, DWORD cchNameString) { DWORD ret; - TRACE("(%p, %ld, %08lx, %p, %p, %ld)\n", pCertContext, dwType, dwFlags, + TRACE("(%p, %d, %08x, %p, %p, %d)\n", pCertContext, dwType, dwFlags, pvTypePara, pszNameString, cchNameString); if (pszNameString) @@ -458,7 +843,7 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType, PCERT_NAME_BLOB name; LPCSTR altNameOID; - TRACE("(%p, %ld, %08lx, %p, %p, %ld)\n", pCertContext, dwType, + TRACE("(%p, %d, %08x, %p, %p, %d)\n", pCertContext, dwType, dwFlags, pvTypePara, pszNameString, cchNameString); if (dwFlags & CERT_NAME_ISSUER_FLAG) @@ -534,7 +919,7 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType, break; } default: - FIXME("unimplemented for type %ld\n", dwType); + FIXME("unimplemented for type %d\n", dwType); ret = 0; } return ret;