crypt32: Explicitly count bytes to copy in DecodeCopyBytes.

This commit is contained in:
Juan Lang 2007-09-17 17:55:13 -07:00 committed by Alexandre Julliard
parent 7e475b4a77
commit 9c4c856fde
2 changed files with 101 additions and 27 deletions

View File

@ -361,10 +361,26 @@ static BOOL CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items[],
}
else
{
ptr += itemDecoded;
decoded += itemDecoded;
TRACE("item %d: decoded %d bytes\n", i,
itemDecoded);
if (itemLen == CMSG_INDEFINITE_LENGTH)
{
if (itemDecoded > itemEncodedLen - 2 ||
*(ptr + itemDecoded) != 0 ||
*(ptr + itemDecoded + 1) != 0)
{
TRACE("expected 0 TLV\n");
SetLastError(CRYPT_E_ASN1_CORRUPT);
ret = FALSE;
}
else
itemDecoded += 2;
}
if (ret)
{
ptr += itemDecoded;
decoded += itemDecoded;
TRACE("item %d: decoded %d bytes\n", i,
itemDecoded);
}
}
}
else if (items[i].optional &&
@ -1875,41 +1891,100 @@ static BOOL WINAPI CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType,
return ret;
}
static BOOL CRYPT_FindEncodedLen(const BYTE *pbEncoded, DWORD cbEncoded,
DWORD *pcbDecoded)
{
BOOL ret = TRUE, done = FALSE;
DWORD indefiniteNestingLevels = 0, decoded = 0;
TRACE("(%p, %d)\n", pbEncoded, cbEncoded);
do {
DWORD dataLen;
if (!cbEncoded)
done = TRUE;
else if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded,
&dataLen)))
{
BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
if (dataLen == CMSG_INDEFINITE_LENGTH)
{
indefiniteNestingLevels++;
pbEncoded += 1 + lenBytes;
cbEncoded -= 1 + lenBytes;
decoded += 1 + lenBytes;
TRACE("indefiniteNestingLevels = %d\n",
indefiniteNestingLevels);
}
else
{
if (pbEncoded[0] == 0 && pbEncoded[1] == 0 &&
indefiniteNestingLevels)
{
indefiniteNestingLevels--;
TRACE("indefiniteNestingLevels = %d\n",
indefiniteNestingLevels);
}
pbEncoded += 1 + lenBytes + dataLen;
cbEncoded -= 1 + lenBytes + dataLen;
decoded += 1 + lenBytes + dataLen;
if (!indefiniteNestingLevels)
done = TRUE;
}
}
} while (ret && !done);
/* If we haven't found all 0 TLVs, we haven't found the end */
if (ret && indefiniteNestingLevels)
{
SetLastError(CRYPT_E_ASN1_EOD);
ret = FALSE;
}
if (ret)
*pcbDecoded = decoded;
TRACE("returning %d (%d)\n", ret, ret ? *pcbDecoded : 0);
return ret;
}
static BOOL CRYPT_AsnDecodeCopyBytes(const BYTE *pbEncoded,
DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
DWORD *pcbDecoded)
{
BOOL ret = TRUE;
DWORD bytesNeeded = sizeof(CRYPT_OBJID_BLOB);
DWORD bytesNeeded = sizeof(CRYPT_OBJID_BLOB), encodedLen = 0;
TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo);
if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
bytesNeeded += cbEncoded;
if (pcbDecoded)
*pcbDecoded = cbEncoded;
if (!pvStructInfo)
*pcbStructInfo = bytesNeeded;
else if (*pcbStructInfo < bytesNeeded)
if ((ret = CRYPT_FindEncodedLen(pbEncoded, cbEncoded, &encodedLen)))
{
SetLastError(ERROR_MORE_DATA);
*pcbStructInfo = bytesNeeded;
ret = FALSE;
}
else
{
PCRYPT_OBJID_BLOB blob = (PCRYPT_OBJID_BLOB)pvStructInfo;
*pcbStructInfo = bytesNeeded;
blob->cbData = cbEncoded;
if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
blob->pbData = (LPBYTE)pbEncoded;
if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
bytesNeeded += encodedLen;
if (!pvStructInfo)
*pcbStructInfo = bytesNeeded;
else if (*pcbStructInfo < bytesNeeded)
{
SetLastError(ERROR_MORE_DATA);
*pcbStructInfo = bytesNeeded;
ret = FALSE;
}
else
{
assert(blob->pbData);
memcpy(blob->pbData, pbEncoded, blob->cbData);
PCRYPT_OBJID_BLOB blob = (PCRYPT_OBJID_BLOB)pvStructInfo;
*pcbStructInfo = bytesNeeded;
blob->cbData = encodedLen;
if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
blob->pbData = (LPBYTE)pbEncoded;
else
{
assert(blob->pbData);
memcpy(blob->pbData, pbEncoded, blob->cbData);
}
}
if (pcbDecoded)
*pcbDecoded = encodedLen;
}
return ret;
}

View File

@ -4891,7 +4891,6 @@ static void test_decodePKCSContentInfo(DWORD dwEncoding)
ok(!strcmp(info->pszObjId, szOID_RSA_signedData),
"Expected %s, got %s\n", szOID_RSA_signedData, info->pszObjId);
todo_wine
ok(info->Content.cbData == 392, "Expected 392, got %d\n",
info->Content.cbData);
LocalFree(buf);