Wine-0_9_4 vendor drop Modified: vendor/wine/dlls/comctl32/current/tooltips.c Modified: vendor/wine/dlls/comctl32/current/treeview.c Modified: vendor/wine/dlls/commdlg/current/finddlg32.c Modified: vendor/wine/dlls/commdlg/current/fontdlg.c Modified: vendor/wine/dlls/crypt32/current/cert.c Modified: vendor/wine/dlls/crypt32/current/encode.c Modified: vendor/wine/dlls/mpr/current/mpr_main.c Modified: vendor/wine/dlls/msi/current/dialog.c Modified: vendor/wine/dlls/msi/current/format.c Modified: vendor/wine/dlls/ole32/current/errorinfo.c Modified: vendor/wine/dlls/ole32/current/ole16.c Modified: vendor/wine/dlls/ole32/current/ole2.c Modified: vendor/wine/dlls/ole32/current/rpc.c Modified: vendor/wine/dlls/ole32/current/stg_stream.c Modified: vendor/wine/dlls/ole32/current/storage32.c Modified: vendor/wine/dlls/ole32/current/storage32.h Modified: vendor/wine/dlls/oleaut32/current/oleaut.c Modified: vendor/wine/dlls/oleaut32/current/safearray.c Modified: vendor/wine/dlls/oleaut32/current/typelib.c Modified: vendor/wine/dlls/riched20/current/editor.c Modified: vendor/wine/dlls/shell32/current/shellpath.c Modified: vendor/wine/dlls/shell32/current/shlview.c Modified: vendor/wine/dlls/shlwapi/current/regstream.c Modified: vendor/wine/dlls/urlmon/current/binding.c Modified: vendor/wine/dlls/urlmon/current/file.c Modified: vendor/wine/dlls/urlmon/current/umstream.c Modified: vendor/wine/tools/winebuild/current/build.h Modified: vendor/wine/tools/winebuild/current/import.c Modified: vendor/wine/tools/winebuild/current/parser.c Modified: vendor/wine/tools/winebuild/current/relay.c Modified: vendor/wine/tools/winebuild/current/spec32.c Modified: vendor/wine/tools/winebuild/current/utils.c Modified: vendor/wine/tools/winebuild/current/winebuild.man.in _____
Modified: vendor/wine/dlls/comctl32/current/tooltips.c --- vendor/wine/dlls/comctl32/current/tooltips.c 2005-12-26 20:40:45 UTC (rev 20339) +++ vendor/wine/dlls/comctl32/current/tooltips.c 2005-12-26 20:46:36 UTC (rev 20340) @@ -2400,7 +2400,7 @@
DWORD dwStyle = GetWindowLongW (hwnd, GWL_STYLE); DWORD dwExStyle = GetWindowLongW (hwnd, GWL_EXSTYLE);
- dwStyle &= 0x0000FFFF; + dwStyle &= ~(WS_CHILD | /*WS_MAXIMIZE |*/ WS_BORDER | WS_DLGFRAME); dwStyle |= (WS_POPUP | WS_BORDER | WS_CLIPSIBLINGS);
/* WS_BORDER only draws a border round the window rect, not the _____
Modified: vendor/wine/dlls/comctl32/current/treeview.c --- vendor/wine/dlls/comctl32/current/treeview.c 2005-12-26 20:40:45 UTC (rev 20339) +++ vendor/wine/dlls/comctl32/current/treeview.c 2005-12-26 20:46:36 UTC (rev 20340) @@ -565,7 +565,7 @@
TRACE("code:%d action:%x olditem:%p newitem:%p\n", code, action, oldItem, newItem);
- ZeroMemory(&nmhdr, sizeof(NMTREEVIEWA)); + ZeroMemory(&nmhdr, sizeof(NMTREEVIEWW));
nmhdr.hdr.hwndFrom = hwnd; nmhdr.hdr.idFrom = GetWindowLongPtrW(hwnd, GWLP_ID); _____
Modified: vendor/wine/dlls/commdlg/current/finddlg32.c --- vendor/wine/dlls/commdlg/current/finddlg32.c 2005-12-26 20:40:45 UTC (rev 20339) +++ vendor/wine/dlls/commdlg/current/finddlg32.c 2005-12-26 20:46:36 UTC (rev 20340) @@ -385,7 +385,7 @@
hmod = (HMODULE)pdata->fr.hInstance; if(pdata->fr.Flags & FR_WINE_UNICODE) { - htemplate = FindResourceW(hmod, (LPWSTR)pdata->fr.lpTemplateName, (LPWSTR)RT_DIALOG); + htemplate = FindResourceW(hmod, (LPCWSTR)pdata->fr.lpTemplateName, (LPWSTR)RT_DIALOG); } else { _____
Modified: vendor/wine/dlls/commdlg/current/fontdlg.c --- vendor/wine/dlls/commdlg/current/fontdlg.c 2005-12-26 20:40:45 UTC (rev 20339) +++ vendor/wine/dlls/commdlg/current/fontdlg.c 2005-12-26 20:46:36 UTC (rev 20340) @@ -1076,7 +1076,6 @@
HDC hdc; HPEN hOrigPen; HFONT hOrigFont; - COLORREF rgbPrev; LOGFONTW lf = *(lpcf->lpLogFont);
MapWindowPoints( 0, hDlg, (LPPOINT) &info.rcWindow, 2); @@ -1104,7 +1103,7 @@ info.rcWindow.top++; info.rcWindow.left++; hOrigFont = SelectObject( hdc, CreateFontIndirectW( &lf ) ); - rgbPrev=SetTextColor( hdc, lpcf->rgbColors ); + SetTextColor( hdc, lpcf->rgbColors );
DrawTextW( hdc,
sample_lang_text[CHARSET_ORDER[lpcf->lpLogFont->lfCharSet]], _____
Modified: vendor/wine/dlls/crypt32/current/cert.c --- vendor/wine/dlls/crypt32/current/cert.c 2005-12-26 20:40:45 UTC (rev 20339) +++ vendor/wine/dlls/crypt32/current/cert.c 2005-12-26 20:46:36 UTC (rev 20340) @@ -313,14 +313,6 @@
static const void * WINAPI CRYPT_ReadSerializedElement(const BYTE *pbElement, DWORD cbElement, DWORD dwContextTypeFlags, DWORD *pdwContentType);
-/* filter for page-fault exceptions */ -static WINE_EXCEPTION_FILTER(page_fault) -{ - if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION) - return EXCEPTION_EXECUTE_HANDLER; - return EXCEPTION_CONTINUE_SEARCH; -} - static void CRYPT_InitStore(WINECRYPT_CERTSTORE *store, HCRYPTPROV hCryptProv, DWORD dwFlags, CertStoreType type) { @@ -1885,6 +1877,22 @@ return ret; }
+static BOOL CRYPT_GetCertHashProp(PWINE_CERT_CONTEXT context, DWORD dwPropId, + ALG_ID algID, const BYTE *toHash, DWORD toHashLen, void *pvData, + DWORD *pcbData) +{ + BOOL ret = CryptHashCertificate(0, algID, 0, toHash, toHashLen, pvData, + pcbData); + if (ret) + { + CRYPT_DATA_BLOB blob = { *pcbData, pvData }; + + ret = CRYPT_SetCertificateContextProperty(context, dwPropId, + 0, &blob); + } + return ret; +} + static BOOL WINAPI CRYPT_GetCertificateContextProperty( PWINE_CERT_CONTEXT context, DWORD dwPropId, void *pvData, DWORD *pcbData) { @@ -1927,26 +1935,34 @@ switch (dwPropId) { case CERT_SHA1_HASH_PROP_ID: - ret = CryptHashCertificate(0, CALG_SHA1, 0, + ret = CRYPT_GetCertHashProp(context, dwPropId, CALG_SHA1, context->cert.pbCertEncoded, context->cert.cbCertEncoded, pvData, pcbData); - if (ret) - { - CRYPT_DATA_BLOB blob = { *pcbData, pvData }; - - ret = CRYPT_SetCertificateContextProperty(context, dwPropId, - 0, &blob); - } break; - case CERT_KEY_PROV_INFO_PROP_ID: case CERT_MD5_HASH_PROP_ID: + ret = CRYPT_GetCertHashProp(context, dwPropId, CALG_MD5, + context->cert.pbCertEncoded, context->cert.cbCertEncoded, pvData, + pcbData); + break; + case CERT_SUBJECT_NAME_MD5_HASH_PROP_ID: + ret = CRYPT_GetCertHashProp(context, dwPropId, CALG_MD5, + context->cert.pCertInfo->Subject.pbData, + context->cert.pCertInfo->Subject.cbData, + pvData, pcbData); + break; + case CERT_SUBJECT_PUBLIC_KEY_MD5_HASH_PROP_ID: + ret = CRYPT_GetCertHashProp(context, dwPropId, CALG_MD5, + context->cert.pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData, + context->cert.pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData, + pvData, pcbData); + break; case CERT_SIGNATURE_HASH_PROP_ID: - case CERT_KEY_IDENTIFIER_PROP_ID: - case CERT_SUBJECT_PUBLIC_KEY_MD5_HASH_PROP_ID: case CERT_ISSUER_SERIAL_NUMBER_MD5_HASH_PROP_ID: - case CERT_SUBJECT_NAME_MD5_HASH_PROP_ID: FIXME("implicit property %ld\n", dwPropId); + SetLastError(CRYPT_E_NOT_FOUND); break; + default: + SetLastError(CRYPT_E_NOT_FOUND); } } LeaveCriticalSection(&context->cs); @@ -2108,6 +2124,7 @@ case CERT_PVK_FILE_PROP_ID: case CERT_SIGNATURE_HASH_PROP_ID: case CERT_ISSUER_PUBLIC_KEY_MD5_HASH_PROP_ID: + case CERT_SUBJECT_NAME_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: @@ -2787,7 +2804,7 @@ } } } - __EXCEPT(page_fault) + __EXCEPT_PAGE_FAULT { SetLastError(STATUS_ACCESS_VIOLATION); context = NULL; _____
Modified: vendor/wine/dlls/crypt32/current/encode.c --- vendor/wine/dlls/crypt32/current/encode.c 2005-12-26 20:40:45 UTC (rev 20339) +++ vendor/wine/dlls/crypt32/current/encode.c 2005-12-26 20:46:36 UTC (rev 20340) @@ -61,8 +61,8 @@
#define ASN_UTCTIME (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x17) #define ASN_GENERALTIME (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x18)
-#define ASN_FLAGS_MASK 0xf0 -#define ASN_TYPE_MASK 0x0f +#define ASN_FLAGS_MASK 0xe0 +#define ASN_TYPE_MASK 0x1f
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
@@ -134,10 +134,11 @@ PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo); static BOOL WINAPI CRYPT_AsnDecodeOid(const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, LPSTR pszObjId, DWORD *pcbObjId); -/* Assumes algo->Parameters.pbData is set ahead of time */ +/* Assumes algo->Parameters.pbData is set ahead of time. Internal func. */ static BOOL WINAPI CRYPT_AsnDecodeAlgorithmId(DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo); +/* Internal function */ static BOOL WINAPI CRYPT_AsnDecodeBool(DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo); @@ -171,14 +172,6 @@ DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo);
-/* filter for page-fault exceptions */ -static WINE_EXCEPTION_FILTER(page_fault) -{ - if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION) - return EXCEPTION_EXECUTE_HANDLER; - return EXCEPTION_CONTINUE_SEARCH; -} - BOOL WINAPI CryptEncodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo, BYTE *pbEncoded, DWORD *pcbEncoded) { @@ -311,6 +304,9 @@ ret = items[i].encodeFunc(dwCertEncodingType, NULL, items[i].pvStructInfo, dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, NULL, &items[i].size); + /* Some functions propagate their errors through the size */ + if (!ret) + *pcbEncoded = items[i].size; dataLen += items[i].size; } if (ret) @@ -336,6 +332,9 @@ ret = items[i].encodeFunc(dwCertEncodingType, NULL, items[i].pvStructInfo, dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, pbEncoded, &items[i].size); + /* Some functions propagate their errors through the size */ + if (!ret) + *pcbEncoded = items[i].size; pbEncoded += items[i].size; } } @@ -381,11 +380,47 @@ ret = item->encodeFunc(dwCertEncodingType, lpszStructType, item->pvStructInfo, dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, pbEncoded, &len); + if (!ret) + { + /* Some functions propagate their errors through the size */ + *pcbEncoded = len; + } } } + else + { + /* Some functions propagate their errors through the size */ + *pcbEncoded = len; + } return ret; }
+struct AsnEncodeTagSwappedItem +{ + BYTE tag; + const void *pvStructInfo; + CryptEncodeObjectExFunc encodeFunc; +}; + +/* Sort of a wacky hack, it encodes something using the struct + * AsnEncodeTagSwappedItem's encodeFunc, then replaces the tag byte with the tag + * given in the struct AsnEncodeTagSwappedItem. + */ +static BOOL WINAPI CRYPT_AsnEncodeSwapTag(DWORD dwCertEncodingType, + LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, + PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded) +{ + BOOL ret; + const struct AsnEncodeTagSwappedItem *item = + (const struct AsnEncodeTagSwappedItem *)pvStructInfo; + + ret = item->encodeFunc(dwCertEncodingType, lpszStructType, + item->pvStructInfo, dwFlags, pEncodePara, pbEncoded, pcbEncoded); + if (ret && pbEncoded) + *pbEncoded = item->tag; + return ret; +} + static BOOL WINAPI CRYPT_AsnEncodeCertVersion(DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded) @@ -495,7 +530,7 @@ sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded, pcbEncoded); } - __EXCEPT(page_fault) + __EXCEPT_PAGE_FAULT { SetLastError(STATUS_ACCESS_VIOLATION); ret = FALSE; @@ -526,7 +561,7 @@ sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded, pcbEncoded); } - __EXCEPT(page_fault) + __EXCEPT_PAGE_FAULT { SetLastError(STATUS_ACCESS_VIOLATION); ret = FALSE; @@ -595,7 +630,7 @@ ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, cItem, dwFlags, pEncodePara, pbEncoded, pcbEncoded); } - __EXCEPT(page_fault) + __EXCEPT_PAGE_FAULT { SetLastError(STATUS_ACCESS_VIOLATION); ret = FALSE; @@ -739,7 +774,7 @@ ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, cItem, dwFlags, pEncodePara, pbEncoded, pcbEncoded); } - __EXCEPT(page_fault) + __EXCEPT_PAGE_FAULT { SetLastError(STATUS_ACCESS_VIOLATION); ret = FALSE; @@ -823,7 +858,7 @@ } } } - __EXCEPT(page_fault) + __EXCEPT_PAGE_FAULT { SetLastError(STATUS_ACCESS_VIOLATION); ret = FALSE; @@ -1031,7 +1066,7 @@ } else { - *pbEncoded++ = ASN_CONSTRUCTOR | ASN_SEQUENCE; + *pbEncoded++ = ASN_SEQUENCE; CRYPT_EncodeLen(bytesNeeded - lenBytes - 1, pbEncoded, &lenBytes); pbEncoded += lenBytes; @@ -1140,7 +1175,7 @@ CryptMemFree(blobs[i].pbData); } } - __EXCEPT(page_fault) + __EXCEPT_PAGE_FAULT { SetLastError(STATUS_ACCESS_VIOLATION); ret = FALSE; @@ -1202,7 +1237,7 @@ } } } - __EXCEPT(page_fault) + __EXCEPT_PAGE_FAULT { SetLastError(STATUS_ACCESS_VIOLATION); ret = FALSE; @@ -1339,7 +1374,6 @@ { const CERT_ALT_NAME_INFO *info = (const CERT_ALT_NAME_INFO *)pvStructInfo; - DWORD bytesNeeded, dataLen, lenBytes, i;
ret = TRUE; @@ -1399,7 +1433,7 @@ } } } - __EXCEPT(page_fault) + __EXCEPT_PAGE_FAULT { SetLastError(STATUS_ACCESS_VIOLATION); ret = FALSE; @@ -1436,7 +1470,7 @@ ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, cItem, dwFlags, pEncodePara, pbEncoded, pcbEncoded); } - __EXCEPT(page_fault) + __EXCEPT_PAGE_FAULT { SetLastError(STATUS_ACCESS_VIOLATION); ret = FALSE; @@ -1477,7 +1511,7 @@ pcbEncoded); } } - __EXCEPT(page_fault) + __EXCEPT_PAGE_FAULT { SetLastError(STATUS_ACCESS_VIOLATION); ret = FALSE; @@ -1522,7 +1556,7 @@ } } } - __EXCEPT(page_fault) + __EXCEPT_PAGE_FAULT { SetLastError(STATUS_ACCESS_VIOLATION); ret = FALSE; @@ -1593,7 +1627,7 @@ } } } - __EXCEPT(page_fault) + __EXCEPT_PAGE_FAULT { SetLastError(STATUS_ACCESS_VIOLATION); ret = FALSE; @@ -1632,7 +1666,7 @@ &newBlob, dwFlags, pEncodePara, pbEncoded, pcbEncoded); CryptMemFree(newBlob.pbData); } - __EXCEPT(page_fault) + __EXCEPT_PAGE_FAULT { SetLastError(STATUS_ACCESS_VIOLATION); ret = FALSE; @@ -1731,7 +1765,7 @@ } } } - __EXCEPT(page_fault) + __EXCEPT_PAGE_FAULT { SetLastError(STATUS_ACCESS_VIOLATION); ret = FALSE; @@ -1802,7 +1836,7 @@ } } } - __EXCEPT(page_fault) + __EXCEPT_PAGE_FAULT { SetLastError(STATUS_ACCESS_VIOLATION); ret = FALSE; @@ -1881,7 +1915,7 @@ } } } - __EXCEPT(page_fault) + __EXCEPT_PAGE_FAULT { SetLastError(STATUS_ACCESS_VIOLATION); ret = FALSE; @@ -1930,7 +1964,7 @@ } } } - __EXCEPT(page_fault) + __EXCEPT_PAGE_FAULT { SetLastError(STATUS_ACCESS_VIOLATION); ret = FALSE; @@ -1960,7 +1994,7 @@ lpszStructType, pvStructInfo, dwFlags, pEncodePara, pbEncoded, pcbEncoded); } - __EXCEPT(page_fault) + __EXCEPT_PAGE_FAULT { SetLastError(STATUS_ACCESS_VIOLATION); ret = FALSE; @@ -2009,7 +2043,7 @@ } } } - __EXCEPT(page_fault) + __EXCEPT_PAGE_FAULT { SetLastError(STATUS_ACCESS_VIOLATION); ret = FALSE; @@ -2018,6 +2052,145 @@ return ret; }
+static BOOL CRYPT_AsnEncodeDistPoint(const CRL_DIST_POINT *distPoint, + BYTE *pbEncoded, DWORD *pcbEncoded) +{ + BOOL ret = TRUE; + struct AsnEncodeSequenceItem items[3] = { { 0 } }; + struct AsnConstructedItem constructed = { 0 }; + struct AsnEncodeTagSwappedItem swapped[3] = { { 0 } }; + DWORD cItem = 0, cSwapped = 0; + + switch (distPoint->DistPointName.dwDistPointNameChoice) + { + case CRL_DIST_POINT_NO_NAME: + /* do nothing */ + break; + case CRL_DIST_POINT_FULL_NAME: + swapped[cSwapped].tag = ASN_CONTEXT | ASN_CONSTRUCTOR | 0; + swapped[cSwapped].pvStructInfo = &distPoint->DistPointName.u.FullName; + swapped[cSwapped].encodeFunc = CRYPT_AsnEncodeAltName; + constructed.tag = 0; + constructed.pvStructInfo = &swapped[cSwapped]; + constructed.encodeFunc = CRYPT_AsnEncodeSwapTag; + items[cItem].pvStructInfo = &constructed; + items[cItem].encodeFunc = CRYPT_AsnEncodeConstructed; + cSwapped++; + cItem++; + break; + case CRL_DIST_POINT_ISSUER_RDN_NAME: + FIXME("unimplemented for CRL_DIST_POINT_ISSUER_RDN_NAME\n"); + ret = FALSE; + break; + default: + ret = FALSE; + } + if (ret && distPoint->ReasonFlags.cbData) + { + swapped[cSwapped].tag = ASN_CONTEXT | 1; + swapped[cSwapped].pvStructInfo = &distPoint->ReasonFlags; + swapped[cSwapped].encodeFunc = CRYPT_AsnEncodeBits; + items[cItem].pvStructInfo = &swapped[cSwapped]; + items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag; + cSwapped++; + cItem++; + } + if (ret && distPoint->CRLIssuer.cAltEntry) + { + swapped[cSwapped].tag = ASN_CONTEXT | ASN_CONSTRUCTOR | 2; + swapped[cSwapped].pvStructInfo = &distPoint->CRLIssuer; + swapped[cSwapped].encodeFunc = CRYPT_AsnEncodeAltName; + items[cItem].pvStructInfo = &swapped[cSwapped]; + items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag; + cSwapped++; + cItem++; + } + if (ret) + ret = CRYPT_AsnEncodeSequence(X509_ASN_ENCODING, items, cItem, 0, NULL, + pbEncoded, pcbEncoded); + return ret; +} + +static BOOL WINAPI CRYPT_AsnEncodeCRLDistPoints(DWORD dwCertEncodingType, + LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, + PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded) +{ + BOOL ret; + + __TRY + { + const CRL_DIST_POINTS_INFO *info = + (const CRL_DIST_POINTS_INFO *)pvStructInfo; + + if (!info->cDistPoint) + { + SetLastError(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER)); + ret = FALSE; + } + else + { + DWORD bytesNeeded, dataLen, lenBytes, i; + + ret = TRUE; + for (i = 0, dataLen = 0; ret && i < info->cDistPoint; i++) + { + DWORD len; + + ret = CRYPT_AsnEncodeDistPoint(&info->rgDistPoint[i], NULL, + &len); + if (ret) + dataLen += len; + else if (GetLastError() == CRYPT_E_INVALID_IA5_STRING) + { + /* Have to propagate index of failing character */ + *pcbEncoded = len; + } + } + if (ret) + { + CRYPT_EncodeLen(dataLen, NULL, &lenBytes); + bytesNeeded = 1 + lenBytes + dataLen; + if (!pbEncoded) + { + *pcbEncoded = bytesNeeded; + ret = TRUE; + } + else + { + if ((ret = CRYPT_EncodeEnsureSpace(dwFlags, pEncodePara, + pbEncoded, pcbEncoded, bytesNeeded))) + { + if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG) + pbEncoded = *(BYTE **)pbEncoded; + *pbEncoded++ = ASN_SEQUENCEOF; + CRYPT_EncodeLen(dataLen, pbEncoded, &lenBytes); + pbEncoded += lenBytes; + for (i = 0; ret && i < info->cDistPoint; i++) + { + DWORD len = dataLen; + + ret = CRYPT_AsnEncodeDistPoint( + &info->rgDistPoint[i], pbEncoded, &len); + if (ret) + { + pbEncoded += len; + dataLen -= len; + } + } + } + } + } + } + } + __EXCEPT_PAGE_FAULT + { + SetLastError(STATUS_ACCESS_VIOLATION); + ret = FALSE; + } + __ENDTRY + return ret; +} + BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, void *pvEncoded, DWORD *pcbEncoded) @@ -2105,6 +2278,9 @@ case (WORD)PKCS_UTC_TIME: encodeFunc = CRYPT_AsnEncodeUtcTime; break; + case (WORD)X509_CRL_DIST_POINTS: + encodeFunc = CRYPT_AsnEncodeCRLDistPoints; + break; default: FIXME("%d: unimplemented\n", LOWORD(lpszStructType)); } @@ -2291,7 +2467,9 @@ return ret; }
-/* A few of the members need explanation: +/* tag: + * The expected tag of the item. If tag is 0, decodeFunc is called + * regardless of the tag value seen. * offset: * A sequence is decoded into a struct. The offset member is the * offset of this item within that struct. @@ -2301,9 +2479,9 @@ * minSize: * The minimum amount of space occupied after decoding. You must set this. * optional: - * If true, and a decoding function fails with CRYPT_E_ASN1_BADTAG, then - * minSize space is filled with 0 for this member. (Any other failure - * results in CRYPT_AsnDecodeSequence failing.) + * If true, and the tag doesn't match the expected tag for this item, + * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is + * filled with 0 for this member. * hasPointer, pointerOffset, minSize: * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to * the offset within the (outer) struct of the data pointer (or to the @@ -2313,6 +2491,7 @@ */ struct AsnDecodeSequenceItem { + BYTE tag; DWORD offset; CryptDecodeObjectExFunc decodeFunc; DWORD minSize; @@ -2322,6 +2501,114 @@ DWORD size; };
+static BOOL CRYPT_AsnDecodeSequenceItems(DWORD dwCertEncodingType, + struct AsnDecodeSequenceItem items[], DWORD cItem, const BYTE *pbEncoded, + DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, BYTE *nextData) +{ + BOOL ret; + DWORD i; + const BYTE *ptr; + + ptr = pbEncoded + 1 + GET_LEN_BYTES(pbEncoded[1]); + for (i = 0, ret = TRUE; ret && i < cItem; i++) + { + if (cbEncoded - (ptr - pbEncoded) != 0) + { + DWORD nextItemLen; + + if ((ret = CRYPT_GetLen(ptr, cbEncoded - (ptr - pbEncoded), + &nextItemLen))) + { + BYTE nextItemLenBytes = GET_LEN_BYTES(ptr[1]); + + if (ptr[0] == items[i].tag || !items[i].tag) + { + if (nextData && pvStructInfo && items[i].hasPointer) + { + TRACE("Setting next pointer to %p\n", + nextData); + *(BYTE **)((BYTE *)pvStructInfo + + items[i].pointerOffset) = nextData; + } + if (items[i].decodeFunc) + { + if (pvStructInfo) + TRACE("decoding item %ld\n", i); + else + TRACE("sizing item %ld\n", i); + ret = items[i].decodeFunc(dwCertEncodingType, + NULL, ptr, 1 + nextItemLenBytes + nextItemLen, + dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, + pvStructInfo ? (BYTE *)pvStructInfo + items[i].offset + : NULL, &items[i].size); + if (ret) + { + if (nextData && items[i].hasPointer && + items[i].size > items[i].minSize) + { + nextData += items[i].size - items[i].minSize; + /* align nextData to DWORD boundaries */ + if (items[i].size % sizeof(DWORD)) + nextData += sizeof(DWORD) - items[i].size % + sizeof(DWORD); + } + /* Account for alignment padding */ + if (items[i].size % sizeof(DWORD)) + items[i].size += sizeof(DWORD) - + items[i].size % sizeof(DWORD); + ptr += 1 + nextItemLenBytes + nextItemLen; + } + else if (items[i].optional && + GetLastError() == CRYPT_E_ASN1_BADTAG) + { + TRACE("skipping optional item %ld\n", i); + items[i].size = items[i].minSize; + SetLastError(NOERROR); + ret = TRUE; + } + else + TRACE("item %ld failed: %08lx\n", i, + GetLastError()); + } + else + items[i].size = items[i].minSize; + } + else if (items[i].optional) + { + TRACE("skipping optional item %ld\n", i); + items[i].size = items[i].minSize; + } + else + { + TRACE("tag %02x doesn't match expected %02x\n", + ptr[0], items[i].tag); + SetLastError(CRYPT_E_ASN1_BADTAG); + ret = FALSE; + } + } + } + else if (items[i].optional) + { + TRACE("missing optional item %ld, skipping\n", i); + items[i].size = items[i].minSize; + } + else + { + TRACE("not enough bytes for item %ld, failing\n", i); + SetLastError(CRYPT_E_ASN1_CORRUPT); + ret = FALSE; + } + } + if (cbEncoded - (ptr - pbEncoded) != 0) + { + TRACE("%ld remaining bytes, failing\n", cbEncoded - + (ptr - pbEncoded)); + SetLastError(CRYPT_E_ASN1_CORRUPT); + ret = FALSE; + } + return ret; +} + /* This decodes an arbitrary sequence into a contiguous block of memory * (basically, a struct.) Each element being decoded is described by a struct * AsnDecodeSequenceItem, see above. @@ -2348,70 +2635,160 @@
if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) { + DWORD i; + + ret = CRYPT_AsnDecodeSequenceItems(dwFlags, items, cItem, pbEncoded, + cbEncoded, dwFlags, NULL, NULL); + if (ret) + { + DWORD bytesNeeded = 0, structSize = 0; + + for (i = 0; i < cItem; i++) + { + bytesNeeded += items[i].size; + structSize += items[i].minSize; + } + if (!pvStructInfo) + *pcbStructInfo = bytesNeeded; + else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, + pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded))) + { + BYTE *nextData; + + if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) + pvStructInfo = *(BYTE **)pvStructInfo; + if (startingPointer) + nextData = (BYTE *)startingPointer; + else + nextData = (BYTE *)pvStructInfo + structSize; + memset(pvStructInfo, 0, structSize); + ret = CRYPT_AsnDecodeSequenceItems(dwFlags, items, cItem, + pbEncoded, cbEncoded, dwFlags, pvStructInfo, nextData); + } + } + } + } + else + { + SetLastError(CRYPT_E_ASN1_BADTAG); + ret = FALSE; + } + TRACE("returning %d (%08lx)\n", ret, GetLastError()); + return ret; +} + +/* tag: + * The expected tag of the entire encoded array (usually a variant + * of ASN_SETOF or ASN_SEQUENCEOF.) + * decodeFunc: + * used to decode each item in the array + * itemSize: + * is the minimum size of each decoded item + * hasPointer: + * indicates whether each item has a dynamic pointer + * pointerOffset: + * indicates the offset within itemSize at which the pointer exists + */ +struct AsnArrayDescriptor +{ + BYTE tag; + CryptDecodeObjectExFunc decodeFunc; + DWORD itemSize; + BOOL hasPointer; + DWORD pointerOffset; +}; + +struct AsnArrayItemSize +{ + DWORD encodedLen; + DWORD size; +}; + +struct GenericArray +{ + DWORD cItems; + BYTE *rgItems; +}; + +/* Decodes an array of like types into a struct GenericArray. + * The layout and decoding of the array are described by a struct + * AsnArrayDescriptor. + */ +static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc, + const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, + PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo, + void *startingPointer) +{ + BOOL ret = TRUE; + + TRACE("%p, %p, %ld, %08lx, %p, %p, %ld, %p\n", arrayDesc, pbEncoded, + cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo, + startingPointer); + + if (pbEncoded[0] == arrayDesc->tag) + { + DWORD dataLen; + + if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) + { + DWORD bytesNeeded, cItems = 0; BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); - DWORD i, bytesNeeded = 0, minSize = 0; - const BYTE *ptr; + /* There can be arbitrarily many items, but there is often only one. + */ + struct AsnArrayItemSize itemSize = { 0 }, *itemSizes = &itemSize;
- ptr = pbEncoded + 1 + lenBytes; - for (i = 0; ret && i < cItem; i++) + bytesNeeded = sizeof(struct GenericArray); + if (dataLen) { - DWORD nextItemLen; + const BYTE *ptr;
- minSize += items[i].minSize; - if (cbEncoded - (ptr - pbEncoded) != 0) + for (ptr = pbEncoded + 1 + lenBytes; ret && + ptr - pbEncoded - 1 - lenBytes < dataLen; ) { - if ((ret = CRYPT_GetLen(ptr, cbEncoded - (ptr - pbEncoded), - &nextItemLen))) + DWORD itemLenBytes, itemDataLen, size; + + itemLenBytes = GET_LEN_BYTES(ptr[1]); + /* Each item decoded may not tolerate extraneous bytes, so + * get the length of the next element and pass it directly. + */ + ret = CRYPT_GetLen(ptr, cbEncoded - (ptr - pbEncoded), + &itemDataLen); + if (ret) + ret = arrayDesc->decodeFunc(X509_ASN_ENCODING, 0, ptr, + 1 + itemLenBytes + itemDataLen, + dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL, + &size); + if (ret) { - BYTE nextItemLenBytes = GET_LEN_BYTES(ptr[1]); + DWORD nextLen;
- if (items[i].decodeFunc) + cItems++; + if (itemSizes != &itemSize) + itemSizes = CryptMemRealloc(itemSizes, + cItems * sizeof(struct AsnArrayItemSize)); + else { - TRACE("sizing item %ld\n", i); - ret = items[i].decodeFunc(dwCertEncodingType, NULL, - ptr, 1 + nextItemLenBytes + nextItemLen, - dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL, - &items[i].size); + itemSizes = + CryptMemAlloc( + cItems * sizeof(struct AsnArrayItemSize)); + memcpy(itemSizes, &itemSize, sizeof(itemSize)); + } + if (itemSizes) + { + itemSizes[cItems - 1].encodedLen = 1 + itemLenBytes + + itemDataLen; + itemSizes[cItems - 1].size = size; + bytesNeeded += size; + ret = CRYPT_GetLen(ptr, + cbEncoded - (ptr - pbEncoded), &nextLen); if (ret) - { - /* Account for alignment padding */ - bytesNeeded += items[i].size; - if (items[i].size % sizeof(DWORD)) - bytesNeeded += sizeof(DWORD) - - items[i].size % sizeof(DWORD); - ptr += 1 + nextItemLenBytes + nextItemLen; - } - else if (items[i].optional && - GetLastError() == CRYPT_E_ASN1_BADTAG) - { - TRACE("skipping optional item %ld\n", i); - bytesNeeded += items[i].minSize; - SetLastError(NOERROR); - ret = TRUE; - } - else - TRACE("item %ld failed: %08lx\n", i, - GetLastError()); + ptr += nextLen + 1 + GET_LEN_BYTES(ptr[1]); } else - bytesNeeded += items[i].minSize; + ret = FALSE; } } - else if (items[i].optional) - bytesNeeded += items[i].minSize; - else - { - SetLastError(CRYPT_E_ASN1_CORRUPT); - ret = FALSE; - } } - if (cbEncoded - (ptr - pbEncoded) != 0) - { - TRACE("%ld remaining bytes, failing\n", cbEncoded - - (ptr - pbEncoded)); - SetLastError(CRYPT_E_ASN1_CORRUPT); - ret = FALSE; - } if (ret) { if (!pvStructInfo) @@ -2419,75 +2796,49 @@ else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded))) { + DWORD i; BYTE *nextData; + const BYTE *ptr; + struct GenericArray *array;
if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) pvStructInfo = *(BYTE **)pvStructInfo; + array = (struct GenericArray *)pvStructInfo; + array->cItems = cItems; if (startingPointer) - nextData = (BYTE *)startingPointer; + array->rgItems = startingPointer; else - nextData = (BYTE *)pvStructInfo + minSize; - memset(pvStructInfo, 0, minSize); - ptr = pbEncoded + 1 + lenBytes; - for (i = 0; ret && i < cItem; i++) [truncated at 1000 lines; 2943 more skipped]