crypt32: Separate checking the tag of encoded bits from decoding the bits.
This commit is contained in:
parent
ed2ba3a467
commit
aa1effe3b2
|
@ -96,6 +96,7 @@ static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
|
||||||
static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded,
|
static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded,
|
||||||
DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
|
DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
|
||||||
DWORD *pcbDecoded);
|
DWORD *pcbDecoded);
|
||||||
|
/* Doesn't check the tag, assumes the caller does so */
|
||||||
static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
|
static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
|
||||||
DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
|
DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
|
||||||
static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
|
static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
|
||||||
|
@ -3298,64 +3299,54 @@ static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
|
||||||
DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
|
DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
|
||||||
{
|
{
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
|
DWORD bytesNeeded, dataLen;
|
||||||
|
BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
|
||||||
|
|
||||||
TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
|
TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
|
||||||
pvStructInfo, *pcbStructInfo, pcbDecoded);
|
pvStructInfo, *pcbStructInfo, pcbDecoded);
|
||||||
|
|
||||||
if (pbEncoded[0] == ASN_BITSTRING)
|
if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
|
||||||
{
|
{
|
||||||
DWORD bytesNeeded, dataLen;
|
if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
|
||||||
BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
|
bytesNeeded = sizeof(CRYPT_BIT_BLOB);
|
||||||
|
else
|
||||||
if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
|
bytesNeeded = dataLen - 1 + sizeof(CRYPT_BIT_BLOB);
|
||||||
|
if (pcbDecoded)
|
||||||
|
*pcbDecoded = 1 + lenBytes + dataLen;
|
||||||
|
if (!pvStructInfo)
|
||||||
|
*pcbStructInfo = bytesNeeded;
|
||||||
|
else if (*pcbStructInfo < bytesNeeded)
|
||||||
{
|
{
|
||||||
|
*pcbStructInfo = bytesNeeded;
|
||||||
|
SetLastError(ERROR_MORE_DATA);
|
||||||
|
ret = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CRYPT_BIT_BLOB *blob;
|
||||||
|
|
||||||
|
*pcbStructInfo = bytesNeeded;
|
||||||
|
blob = (CRYPT_BIT_BLOB *)pvStructInfo;
|
||||||
|
blob->cbData = dataLen - 1;
|
||||||
|
blob->cUnusedBits = *(pbEncoded + 1 + lenBytes);
|
||||||
if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
|
if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
|
||||||
bytesNeeded = sizeof(CRYPT_BIT_BLOB);
|
|
||||||
else
|
|
||||||
bytesNeeded = dataLen - 1 + sizeof(CRYPT_BIT_BLOB);
|
|
||||||
if (pcbDecoded)
|
|
||||||
*pcbDecoded = 1 + lenBytes + dataLen;
|
|
||||||
if (!pvStructInfo)
|
|
||||||
*pcbStructInfo = bytesNeeded;
|
|
||||||
else if (*pcbStructInfo < bytesNeeded)
|
|
||||||
{
|
{
|
||||||
*pcbStructInfo = bytesNeeded;
|
blob->pbData = (BYTE *)pbEncoded + 2 + lenBytes;
|
||||||
SetLastError(ERROR_MORE_DATA);
|
|
||||||
ret = FALSE;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CRYPT_BIT_BLOB *blob;
|
assert(blob->pbData);
|
||||||
|
if (blob->cbData)
|
||||||
*pcbStructInfo = bytesNeeded;
|
|
||||||
blob = (CRYPT_BIT_BLOB *)pvStructInfo;
|
|
||||||
blob->cbData = dataLen - 1;
|
|
||||||
blob->cUnusedBits = *(pbEncoded + 1 + lenBytes);
|
|
||||||
if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
|
|
||||||
{
|
{
|
||||||
blob->pbData = (BYTE *)pbEncoded + 2 + lenBytes;
|
BYTE mask = 0xff << blob->cUnusedBits;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
assert(blob->pbData);
|
|
||||||
if (blob->cbData)
|
|
||||||
{
|
|
||||||
BYTE mask = 0xff << blob->cUnusedBits;
|
|
||||||
|
|
||||||
memcpy(blob->pbData, pbEncoded + 2 + lenBytes,
|
memcpy(blob->pbData, pbEncoded + 2 + lenBytes,
|
||||||
blob->cbData);
|
blob->cbData);
|
||||||
blob->pbData[blob->cbData - 1] &= mask;
|
blob->pbData[blob->cbData - 1] &= mask;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
SetLastError(CRYPT_E_ASN1_BADTAG);
|
|
||||||
ret = FALSE;
|
|
||||||
}
|
|
||||||
TRACE("returning %d (%08x)\n", ret, GetLastError());
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3372,7 +3363,17 @@ static BOOL WINAPI CRYPT_AsnDecodeBits(DWORD dwCertEncodingType,
|
||||||
{
|
{
|
||||||
DWORD bytesNeeded;
|
DWORD bytesNeeded;
|
||||||
|
|
||||||
if ((ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
|
if (!cbEncoded)
|
||||||
|
{
|
||||||
|
SetLastError(CRYPT_E_ASN1_CORRUPT);
|
||||||
|
ret = FALSE;
|
||||||
|
}
|
||||||
|
else if (pbEncoded[0] != ASN_BITSTRING)
|
||||||
|
{
|
||||||
|
SetLastError(CRYPT_E_ASN1_BADTAG);
|
||||||
|
ret = FALSE;
|
||||||
|
}
|
||||||
|
else if ((ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
|
||||||
dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
|
dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
|
||||||
{
|
{
|
||||||
if (!pvStructInfo)
|
if (!pvStructInfo)
|
||||||
|
|
|
@ -3323,7 +3323,6 @@ static void test_decodeCRLDistPoints(DWORD dwEncoding)
|
||||||
ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
|
ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
|
||||||
distPointWithReason, distPointWithReason[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
|
distPointWithReason, distPointWithReason[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
|
||||||
NULL, (BYTE *)&buf, &size);
|
NULL, (BYTE *)&buf, &size);
|
||||||
todo_wine
|
|
||||||
ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
|
ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue