mirror of
https://github.com/reactos/wine.git
synced 2024-11-29 06:30:37 +00:00
crypt32: Implement CRLDistPoints encoding/decoding.
- rewrite sequence decoding to support context-specific tags, and eliminate duplicated code - implement encoding and decoding of CRLDistPoints
This commit is contained in:
parent
a4af4b95b5
commit
628ede4783
@ -134,10 +134,11 @@ static BOOL WINAPI CRYPT_AsnDecodeExtensionsInternal(DWORD dwCertEncodingType,
|
||||
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);
|
||||
@ -402,6 +403,32 @@ static BOOL WINAPI CRYPT_AsnEncodeConstructed(DWORD dwCertEncodingType,
|
||||
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)
|
||||
@ -2033,6 +2060,145 @@ static BOOL WINAPI CRYPT_AsnEncodeSequenceOfAny(DWORD dwCertEncodingType,
|
||||
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)
|
||||
@ -2120,6 +2286,9 @@ BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
|
||||
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));
|
||||
}
|
||||
@ -2306,7 +2475,9 @@ static BOOL CRYPT_DecodeEnsureSpace(DWORD dwFlags,
|
||||
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.
|
||||
@ -2316,9 +2487,9 @@ static BOOL CRYPT_DecodeEnsureSpace(DWORD dwFlags,
|
||||
* 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
|
||||
@ -2328,6 +2499,7 @@ static BOOL CRYPT_DecodeEnsureSpace(DWORD dwFlags,
|
||||
*/
|
||||
struct AsnDecodeSequenceItem
|
||||
{
|
||||
BYTE tag;
|
||||
DWORD offset;
|
||||
CryptDecodeObjectExFunc decodeFunc;
|
||||
DWORD minSize;
|
||||
@ -2337,6 +2509,114 @@ struct AsnDecodeSequenceItem
|
||||
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.
|
||||
@ -2363,72 +2643,19 @@ static BOOL CRYPT_AsnDecodeSequence(DWORD dwCertEncodingType,
|
||||
|
||||
if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
|
||||
{
|
||||
BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
|
||||
DWORD i, bytesNeeded = 0, minSize = 0;
|
||||
const BYTE *ptr;
|
||||
DWORD i;
|
||||
|
||||
ptr = pbEncoded + 1 + lenBytes;
|
||||
for (i = 0; ret && i < cItem; i++)
|
||||
{
|
||||
DWORD nextItemLen;
|
||||
|
||||
minSize += items[i].minSize;
|
||||
if (cbEncoded - (ptr - pbEncoded) != 0)
|
||||
{
|
||||
if ((ret = CRYPT_GetLen(ptr, cbEncoded - (ptr - pbEncoded),
|
||||
&nextItemLen)))
|
||||
{
|
||||
BYTE nextItemLenBytes = GET_LEN_BYTES(ptr[1]);
|
||||
|
||||
if (items[i].decodeFunc)
|
||||
{
|
||||
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);
|
||||
ret = CRYPT_AsnDecodeSequenceItems(dwFlags, items, cItem, pbEncoded,
|
||||
cbEncoded, dwFlags, NULL, NULL);
|
||||
if (ret)
|
||||
{
|
||||
/* Account for alignment padding */
|
||||
DWORD bytesNeeded = 0, structSize = 0;
|
||||
|
||||
for (i = 0; i < cItem; i++)
|
||||
{
|
||||
bytesNeeded += items[i].size;
|
||||
if (items[i].size % sizeof(DWORD))
|
||||
bytesNeeded += sizeof(DWORD) -
|
||||
items[i].size % sizeof(DWORD);
|
||||
ptr += 1 + nextItemLenBytes + nextItemLen;
|
||||
structSize += items[i].minSize;
|
||||
}
|
||||
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());
|
||||
}
|
||||
else
|
||||
bytesNeeded += items[i].minSize;
|
||||
}
|
||||
}
|
||||
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)
|
||||
*pcbStructInfo = bytesNeeded;
|
||||
else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
|
||||
@ -2441,69 +2668,10 @@ static BOOL CRYPT_AsnDecodeSequence(DWORD dwCertEncodingType,
|
||||
if (startingPointer)
|
||||
nextData = (BYTE *)startingPointer;
|
||||
else
|
||||
nextData = (BYTE *)pvStructInfo + minSize;
|
||||
memset(pvStructInfo, 0, minSize);
|
||||
ptr = pbEncoded + 1 + lenBytes;
|
||||
for (i = 0; ret && i < cItem; i++)
|
||||
{
|
||||
if (cbEncoded - (ptr - pbEncoded) != 0)
|
||||
{
|
||||
DWORD nextItemLen;
|
||||
BYTE nextItemLenBytes = GET_LEN_BYTES(ptr[1]);
|
||||
|
||||
CRYPT_GetLen(ptr, cbEncoded - (ptr - pbEncoded),
|
||||
&nextItemLen);
|
||||
if (items[i].hasPointer)
|
||||
{
|
||||
TRACE("Setting next pointer to %p\n", nextData);
|
||||
*(BYTE **)((BYTE *)pvStructInfo +
|
||||
items[i].pointerOffset) = nextData;
|
||||
}
|
||||
if (items[i].decodeFunc)
|
||||
{
|
||||
TRACE("decoding item %ld, offset %ld (%p)\n",
|
||||
i, items[i].offset,
|
||||
(BYTE *)pvStructInfo + items[i].offset);
|
||||
ret = items[i].decodeFunc(dwCertEncodingType,
|
||||
NULL, ptr, 1 + nextItemLenBytes + nextItemLen,
|
||||
dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL,
|
||||
(BYTE *)pvStructInfo + items[i].offset,
|
||||
&items[i].size);
|
||||
if (!ret)
|
||||
TRACE("item %ld failed: %08lx\n", i,
|
||||
GetLastError());
|
||||
}
|
||||
else
|
||||
items[i].size = items[i].minSize;
|
||||
if (ret)
|
||||
{
|
||||
if (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);
|
||||
}
|
||||
}
|
||||
ptr += 1 + nextItemLenBytes + nextItemLen;
|
||||
}
|
||||
else if (items[i].optional &&
|
||||
GetLastError() == CRYPT_E_ASN1_BADTAG)
|
||||
{
|
||||
SetLastError(NOERROR);
|
||||
ret = TRUE;
|
||||
}
|
||||
}
|
||||
else if (!items[i].optional)
|
||||
{
|
||||
SetLastError(CRYPT_E_ASN1_CORRUPT);
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
nextData = (BYTE *)pvStructInfo + structSize;
|
||||
memset(pvStructInfo, 0, structSize);
|
||||
ret = CRYPT_AsnDecodeSequenceItems(dwFlags, items, cItem,
|
||||
pbEncoded, cbEncoded, dwFlags, pvStructInfo, nextData);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2790,14 +2958,14 @@ static BOOL WINAPI CRYPT_AsnDecodeCert(DWORD dwCertEncodingType,
|
||||
__TRY
|
||||
{
|
||||
struct AsnDecodeSequenceItem items[] = {
|
||||
{ offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned),
|
||||
{ 0, offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned),
|
||||
CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_DER_BLOB), FALSE, TRUE,
|
||||
offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned.pbData), 0 },
|
||||
{ offsetof(CERT_SIGNED_CONTENT_INFO, SignatureAlgorithm),
|
||||
CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
|
||||
FALSE, TRUE, offsetof(CERT_SIGNED_CONTENT_INFO,
|
||||
SignatureAlgorithm.pszObjId), 0 },
|
||||
{ offsetof(CERT_SIGNED_CONTENT_INFO, Signature),
|
||||
{ ASN_SEQUENCEOF, offsetof(CERT_SIGNED_CONTENT_INFO,
|
||||
SignatureAlgorithm), CRYPT_AsnDecodeAlgorithmId,
|
||||
sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE,
|
||||
offsetof(CERT_SIGNED_CONTENT_INFO, SignatureAlgorithm.pszObjId), 0 },
|
||||
{ ASN_BITSTRING, offsetof(CERT_SIGNED_CONTENT_INFO, Signature),
|
||||
CRYPT_AsnDecodeBitsSwapBytes, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
|
||||
offsetof(CERT_SIGNED_CONTENT_INFO, Signature.pbData), 0 },
|
||||
};
|
||||
@ -2817,14 +2985,12 @@ static BOOL WINAPI CRYPT_AsnDecodeCert(DWORD dwCertEncodingType,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Internal function */
|
||||
static BOOL WINAPI CRYPT_AsnDecodeCertVersion(DWORD dwCertEncodingType,
|
||||
LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
|
||||
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
if (pbEncoded[0] == (ASN_CONTEXT | ASN_CONSTRUCTOR))
|
||||
{
|
||||
DWORD dataLen;
|
||||
|
||||
if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
|
||||
@ -2835,12 +3001,6 @@ static BOOL WINAPI CRYPT_AsnDecodeCertVersion(DWORD dwCertEncodingType,
|
||||
pbEncoded + 1 + lenBytes, dataLen, dwFlags, pDecodePara,
|
||||
pvStructInfo, pcbStructInfo);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError(CRYPT_E_ASN1_BADTAG);
|
||||
ret = FALSE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2851,9 +3011,9 @@ static BOOL WINAPI CRYPT_AsnDecodeValidity(DWORD dwCertEncodingType,
|
||||
BOOL ret;
|
||||
|
||||
struct AsnDecodeSequenceItem items[] = {
|
||||
{ offsetof(CERT_PRIVATE_KEY_VALIDITY, NotBefore),
|
||||
{ 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotBefore),
|
||||
CRYPT_AsnDecodeChoiceOfTime, sizeof(FILETIME), FALSE, FALSE, 0 },
|
||||
{ offsetof(CERT_PRIVATE_KEY_VALIDITY, NotAfter),
|
||||
{ 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotAfter),
|
||||
CRYPT_AsnDecodeChoiceOfTime, sizeof(FILETIME), FALSE, FALSE, 0 },
|
||||
};
|
||||
|
||||
@ -2863,14 +3023,12 @@ static BOOL WINAPI CRYPT_AsnDecodeValidity(DWORD dwCertEncodingType,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Internal function */
|
||||
static BOOL WINAPI CRYPT_AsnDecodeCertExtensions(DWORD dwCertEncodingType,
|
||||
LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
|
||||
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
if (pbEncoded[0] == (ASN_CONTEXT | ASN_CONSTRUCTOR | 3))
|
||||
{
|
||||
DWORD dataLen;
|
||||
|
||||
if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
|
||||
@ -2881,12 +3039,6 @@ static BOOL WINAPI CRYPT_AsnDecodeCertExtensions(DWORD dwCertEncodingType,
|
||||
X509_EXTENSIONS, pbEncoded + 1 + lenBytes, dataLen, dwFlags,
|
||||
pDecodePara, pvStructInfo, pcbStructInfo);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError(CRYPT_E_ASN1_BADTAG);
|
||||
ret = FALSE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2902,34 +3054,39 @@ static BOOL WINAPI CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType,
|
||||
__TRY
|
||||
{
|
||||
struct AsnDecodeSequenceItem items[] = {
|
||||
{ offsetof(CERT_INFO, dwVersion), CRYPT_AsnDecodeCertVersion,
|
||||
sizeof(DWORD), TRUE, FALSE, 0, 0 },
|
||||
{ offsetof(CERT_INFO, SerialNumber), CRYPT_AsnDecodeIntegerInternal,
|
||||
sizeof(CRYPT_INTEGER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
|
||||
SerialNumber.pbData), 0 },
|
||||
{ offsetof(CERT_INFO, SignatureAlgorithm), CRYPT_AsnDecodeAlgorithmId,
|
||||
sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE, offsetof(CERT_INFO,
|
||||
SignatureAlgorithm.pszObjId), 0 },
|
||||
{ offsetof(CERT_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
|
||||
{ ASN_CONTEXT | ASN_CONSTRUCTOR, offsetof(CERT_INFO, dwVersion),
|
||||
CRYPT_AsnDecodeCertVersion, sizeof(DWORD), TRUE, FALSE, 0, 0 },
|
||||
{ ASN_INTEGER, offsetof(CERT_INFO, SerialNumber),
|
||||
CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
|
||||
TRUE, offsetof(CERT_INFO, SerialNumber.pbData), 0 },
|
||||
{ ASN_SEQUENCEOF, offsetof(CERT_INFO, SignatureAlgorithm),
|
||||
CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
|
||||
FALSE, TRUE, offsetof(CERT_INFO, SignatureAlgorithm.pszObjId), 0 },
|
||||
{ 0, offsetof(CERT_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
|
||||
sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
|
||||
Issuer.pbData) },
|
||||
{ offsetof(CERT_INFO, NotBefore), CRYPT_AsnDecodeValidity,
|
||||
sizeof(CERT_PRIVATE_KEY_VALIDITY), FALSE, FALSE, 0 },
|
||||
{ offsetof(CERT_INFO, Subject), CRYPT_AsnDecodeDerBlob,
|
||||
{ ASN_SEQUENCEOF, offsetof(CERT_INFO, NotBefore),
|
||||
CRYPT_AsnDecodeValidity, sizeof(CERT_PRIVATE_KEY_VALIDITY), FALSE,
|
||||
FALSE, 0 },
|
||||
{ 0, offsetof(CERT_INFO, Subject), CRYPT_AsnDecodeDerBlob,
|
||||
sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
|
||||
Subject.pbData) },
|
||||
{ offsetof(CERT_INFO, SubjectPublicKeyInfo), CRYPT_AsnDecodePubKeyInfo,
|
||||
sizeof(CERT_PUBLIC_KEY_INFO), FALSE, TRUE, offsetof(CERT_INFO,
|
||||
/* jil FIXME: shouldn't this have an internal version, which expects
|
||||
* the pbData to be set?
|
||||
*/
|
||||
{ ASN_SEQUENCEOF, offsetof(CERT_INFO, SubjectPublicKeyInfo),
|
||||
CRYPT_AsnDecodePubKeyInfo, sizeof(CERT_PUBLIC_KEY_INFO), FALSE,
|
||||
TRUE, offsetof(CERT_INFO,
|
||||
SubjectPublicKeyInfo.Algorithm.Parameters.pbData), 0 },
|
||||
{ offsetof(CERT_INFO, IssuerUniqueId), CRYPT_AsnDecodeBitsInternal,
|
||||
sizeof(CRYPT_BIT_BLOB), TRUE, TRUE, offsetof(CERT_INFO,
|
||||
IssuerUniqueId.pbData), 0 },
|
||||
{ offsetof(CERT_INFO, SubjectUniqueId), CRYPT_AsnDecodeBitsInternal,
|
||||
sizeof(CRYPT_BIT_BLOB), TRUE, TRUE, offsetof(CERT_INFO,
|
||||
SubjectUniqueId.pbData), 0 },
|
||||
{ offsetof(CERT_INFO, cExtension), CRYPT_AsnDecodeCertExtensions,
|
||||
sizeof(CERT_EXTENSIONS), TRUE, TRUE, offsetof(CERT_INFO,
|
||||
rgExtension), 0 },
|
||||
{ ASN_BITSTRING, offsetof(CERT_INFO, IssuerUniqueId),
|
||||
CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
|
||||
offsetof(CERT_INFO, IssuerUniqueId.pbData), 0 },
|
||||
{ ASN_BITSTRING, offsetof(CERT_INFO, SubjectUniqueId),
|
||||
CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
|
||||
offsetof(CERT_INFO, SubjectUniqueId.pbData), 0 },
|
||||
{ ASN_CONTEXT | ASN_CONSTRUCTOR | 3, offsetof(CERT_INFO, cExtension),
|
||||
CRYPT_AsnDecodeCertExtensions, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
|
||||
offsetof(CERT_INFO, rgExtension), 0 },
|
||||
};
|
||||
|
||||
ret = CRYPT_AsnDecodeSequence(dwCertEncodingType, items,
|
||||
@ -2951,14 +3108,14 @@ static BOOL WINAPI CRYPT_AsnDecodeCRLEntry(DWORD dwCertEncodingType,
|
||||
{
|
||||
BOOL ret;
|
||||
struct AsnDecodeSequenceItem items[] = {
|
||||
{ offsetof(CRL_ENTRY, SerialNumber), CRYPT_AsnDecodeIntegerInternal,
|
||||
sizeof(CRYPT_INTEGER_BLOB), FALSE, TRUE, offsetof(CRL_ENTRY,
|
||||
SerialNumber.pbData), 0 },
|
||||
{ offsetof(CRL_ENTRY, RevocationDate), CRYPT_AsnDecodeChoiceOfTime,
|
||||
{ ASN_INTEGER, offsetof(CRL_ENTRY, SerialNumber),
|
||||
CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE, TRUE,
|
||||
offsetof(CRL_ENTRY, SerialNumber.pbData), 0 },
|
||||
{ 0, offsetof(CRL_ENTRY, RevocationDate), CRYPT_AsnDecodeChoiceOfTime,
|
||||
sizeof(FILETIME), FALSE, FALSE, 0 },
|
||||
{ offsetof(CRL_ENTRY, cExtension), CRYPT_AsnDecodeExtensionsInternal,
|
||||
sizeof(CERT_EXTENSIONS), TRUE, TRUE, offsetof(CRL_ENTRY,
|
||||
rgExtension), 0 },
|
||||
{ ASN_SEQUENCEOF, offsetof(CRL_ENTRY, cExtension),
|
||||
CRYPT_AsnDecodeExtensionsInternal, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
|
||||
offsetof(CRL_ENTRY, rgExtension), 0 },
|
||||
};
|
||||
PCRL_ENTRY entry = (PCRL_ENTRY)pvStructInfo;
|
||||
|
||||
@ -2971,12 +3128,7 @@ static BOOL WINAPI CRYPT_AsnDecodeCRLEntry(DWORD dwCertEncodingType,
|
||||
return ret;
|
||||
}
|
||||
|
||||
typedef struct _WINE_CRL_ENTRIES {
|
||||
DWORD cCRLEntry;
|
||||
PCRL_ENTRY rgCRLEntry;
|
||||
} WINE_CRL_ENTRIES, *PWINE_CRL_ENTRIES;
|
||||
|
||||
/* Warning: assumes pvStructInfo is a WINE_CRL_ENTRIES whose rgCRLEntry has
|
||||
/* Warning: assumes pvStructInfo is a struct GenericArray whose rgItems has
|
||||
* been set prior to calling.
|
||||
*/
|
||||
static BOOL WINAPI CRYPT_AsnDecodeCRLEntries(DWORD dwCertEncodingType,
|
||||
@ -2987,14 +3139,14 @@ static BOOL WINAPI CRYPT_AsnDecodeCRLEntries(DWORD dwCertEncodingType,
|
||||
struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
|
||||
CRYPT_AsnDecodeCRLEntry, sizeof(CRL_ENTRY), TRUE,
|
||||
offsetof(CRL_ENTRY, SerialNumber.pbData) };
|
||||
PWINE_CRL_ENTRIES entries = (PWINE_CRL_ENTRIES)pvStructInfo;
|
||||
struct GenericArray *entries = (struct GenericArray *)pvStructInfo;
|
||||
|
||||
TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags,
|
||||
pDecodePara, pvStructInfo, *pcbStructInfo);
|
||||
|
||||
ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
|
||||
pDecodePara, pvStructInfo, pcbStructInfo,
|
||||
entries ? entries->rgCRLEntry : NULL);
|
||||
entries ? entries->rgItems : NULL);
|
||||
TRACE("Returning %d (%08lx)\n", ret, GetLastError());
|
||||
return ret;
|
||||
}
|
||||
@ -3011,24 +3163,24 @@ static BOOL WINAPI CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType,
|
||||
__TRY
|
||||
{
|
||||
struct AsnDecodeSequenceItem items[] = {
|
||||
{ offsetof(CRL_INFO, dwVersion), CRYPT_AsnDecodeCertVersion,
|
||||
sizeof(DWORD), TRUE, FALSE, 0, 0 },
|
||||
{ offsetof(CRL_INFO, SignatureAlgorithm), CRYPT_AsnDecodeAlgorithmId,
|
||||
sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE, offsetof(CRL_INFO,
|
||||
SignatureAlgorithm.pszObjId), 0 },
|
||||
{ offsetof(CRL_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
|
||||
{ ASN_CONTEXT | ASN_CONSTRUCTOR, offsetof(CRL_INFO, dwVersion),
|
||||
CRYPT_AsnDecodeCertVersion, sizeof(DWORD), TRUE, FALSE, 0, 0 },
|
||||
{ ASN_SEQUENCEOF, offsetof(CRL_INFO, SignatureAlgorithm),
|
||||
CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
|
||||
FALSE, TRUE, offsetof(CRL_INFO, SignatureAlgorithm.pszObjId), 0 },
|
||||
{ 0, offsetof(CRL_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
|
||||
sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CRL_INFO,
|
||||
Issuer.pbData) },
|
||||
{ offsetof(CRL_INFO, ThisUpdate), CRYPT_AsnDecodeChoiceOfTime,
|
||||
{ 0, offsetof(CRL_INFO, ThisUpdate), CRYPT_AsnDecodeChoiceOfTime,
|
||||
sizeof(FILETIME), FALSE, FALSE, 0 },
|
||||
{ offsetof(CRL_INFO, NextUpdate), CRYPT_AsnDecodeChoiceOfTime,
|
||||
{ 0, offsetof(CRL_INFO, NextUpdate), CRYPT_AsnDecodeChoiceOfTime,
|
||||
sizeof(FILETIME), TRUE, FALSE, 0 },
|
||||
{ offsetof(CRL_INFO, cCRLEntry), CRYPT_AsnDecodeCRLEntries,
|
||||
sizeof(WINE_CRL_ENTRIES), TRUE, TRUE, offsetof(CRL_INFO,
|
||||
rgCRLEntry), 0 },
|
||||
{ ASN_SEQUENCEOF, offsetof(CRL_INFO, cCRLEntry),
|
||||
CRYPT_AsnDecodeCRLEntries, sizeof(struct GenericArray), TRUE, TRUE,
|
||||
offsetof(CRL_INFO, rgCRLEntry), 0 },
|
||||
/* Note that the extensions are ignored by MS, so I'll ignore them too
|
||||
*/
|
||||
{ offsetof(CRL_INFO, cExtension), NULL,
|
||||
{ 0, offsetof(CRL_INFO, cExtension), NULL,
|
||||
sizeof(CERT_EXTENSIONS), TRUE, FALSE, 0 },
|
||||
};
|
||||
|
||||
@ -3079,13 +3231,14 @@ static BOOL WINAPI CRYPT_AsnDecodeExtension(DWORD dwCertEncodingType,
|
||||
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
|
||||
{
|
||||
struct AsnDecodeSequenceItem items[] = {
|
||||
{ offsetof(CERT_EXTENSION, pszObjId), CRYPT_AsnDecodeOidWrapper,
|
||||
sizeof(LPSTR), FALSE, TRUE, offsetof(CERT_EXTENSION, pszObjId), 0 },
|
||||
{ offsetof(CERT_EXTENSION, fCritical), CRYPT_AsnDecodeBool,
|
||||
{ ASN_OBJECTIDENTIFIER, offsetof(CERT_EXTENSION, pszObjId),
|
||||
CRYPT_AsnDecodeOidWrapper, sizeof(LPSTR), FALSE, TRUE,
|
||||
offsetof(CERT_EXTENSION, pszObjId), 0 },
|
||||
{ ASN_BOOL, offsetof(CERT_EXTENSION, fCritical), CRYPT_AsnDecodeBool,
|
||||
sizeof(BOOL), TRUE, FALSE, 0, 0 },
|
||||
{ offsetof(CERT_EXTENSION, Value), CRYPT_AsnDecodeOctetsInternal,
|
||||
sizeof(CRYPT_OBJID_BLOB), FALSE, TRUE, offsetof(CERT_EXTENSION,
|
||||
Value.pbData) },
|
||||
{ ASN_OCTETSTRING, offsetof(CERT_EXTENSION, Value),
|
||||
CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_OBJID_BLOB), FALSE, TRUE,
|
||||
offsetof(CERT_EXTENSION, Value.pbData) },
|
||||
};
|
||||
BOOL ret = TRUE;
|
||||
PCERT_EXTENSION ext = (PCERT_EXTENSION)pvStructInfo;
|
||||
@ -3394,9 +3547,10 @@ static BOOL WINAPI CRYPT_AsnDecodeRdnAttr(DWORD dwCertEncodingType,
|
||||
__TRY
|
||||
{
|
||||
struct AsnDecodeSequenceItem items[] = {
|
||||
{ offsetof(CERT_RDN_ATTR, pszObjId), CRYPT_AsnDecodeOidWrapper,
|
||||
sizeof(LPSTR), FALSE, TRUE, offsetof(CERT_RDN_ATTR, pszObjId), 0 },
|
||||
{ offsetof(CERT_RDN_ATTR, dwValueType), CRYPT_AsnDecodeNameValue,
|
||||
{ ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
|
||||
CRYPT_AsnDecodeOidWrapper, sizeof(LPSTR), FALSE, TRUE,
|
||||
offsetof(CERT_RDN_ATTR, pszObjId), 0 },
|
||||
{ 0, offsetof(CERT_RDN_ATTR, dwValueType), CRYPT_AsnDecodeNameValue,
|
||||
sizeof(CERT_NAME_VALUE), FALSE, TRUE, offsetof(CERT_RDN_ATTR,
|
||||
Value.pbData), 0 },
|
||||
};
|
||||
@ -3514,10 +3668,10 @@ static BOOL WINAPI CRYPT_AsnDecodeAlgorithmId(DWORD dwCertEncodingType,
|
||||
(CRYPT_ALGORITHM_IDENTIFIER *)pvStructInfo;
|
||||
BOOL ret = TRUE;
|
||||
struct AsnDecodeSequenceItem items[] = {
|
||||
{ offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId),
|
||||
{ ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId),
|
||||
CRYPT_AsnDecodeOidWrapper, sizeof(LPSTR), FALSE, TRUE,
|
||||
offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId), 0 },
|
||||
{ offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters),
|
||||
{ 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters),
|
||||
CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
|
||||
offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters.pbData), 0 },
|
||||
};
|
||||
@ -3545,11 +3699,11 @@ static BOOL WINAPI CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType,
|
||||
__TRY
|
||||
{
|
||||
struct AsnDecodeSequenceItem items[] = {
|
||||
{ offsetof(CERT_PUBLIC_KEY_INFO, Algorithm),
|
||||
{ ASN_SEQUENCEOF, offsetof(CERT_PUBLIC_KEY_INFO, Algorithm),
|
||||
CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
|
||||
FALSE, TRUE, offsetof(CERT_PUBLIC_KEY_INFO,
|
||||
Algorithm.pszObjId) },
|
||||
{ offsetof(CERT_PUBLIC_KEY_INFO, PublicKey),
|
||||
{ ASN_BITSTRING, offsetof(CERT_PUBLIC_KEY_INFO, PublicKey),
|
||||
CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
|
||||
offsetof(CERT_PUBLIC_KEY_INFO, PublicKey.pbData) },
|
||||
};
|
||||
@ -3578,11 +3732,6 @@ static BOOL WINAPI CRYPT_AsnDecodeBool(DWORD dwCertEncodingType,
|
||||
SetLastError(CRYPT_E_ASN1_CORRUPT);
|
||||
return FALSE;
|
||||
}
|
||||
if (pbEncoded[0] != ASN_BOOL)
|
||||
{
|
||||
SetLastError(CRYPT_E_ASN1_BADTAG);
|
||||
return FALSE;
|
||||
}
|
||||
if (GET_LEN_BYTES(pbEncoded[1]) > 1)
|
||||
{
|
||||
SetLastError(CRYPT_E_ASN1_CORRUPT);
|
||||
@ -3696,6 +3845,8 @@ static BOOL WINAPI CRYPT_AsnDecodeAltNameEntry(DWORD dwCertEncodingType,
|
||||
entry->u.pwszURL[i] =
|
||||
(WCHAR)pbEncoded[1 + lenBytes + i];
|
||||
entry->u.pwszURL[i] = 0;
|
||||
TRACE("URL is %p (%s)\n", entry->u.pwszURL,
|
||||
debugstr_w(entry->u.pwszURL));
|
||||
break;
|
||||
}
|
||||
case 7: /* iPAddress */
|
||||
@ -3714,6 +3865,26 @@ static BOOL WINAPI CRYPT_AsnDecodeAltNameEntry(DWORD dwCertEncodingType,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRYPT_AsnDecodeAltNameInternal(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_SEQUENCEOF,
|
||||
CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE,
|
||||
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,
|
||||
pDecodePara, pvStructInfo, *pcbStructInfo);
|
||||
|
||||
if (info)
|
||||
TRACE("info->rgAltEntry is %p\n", info->rgAltEntry);
|
||||
ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
|
||||
pDecodePara, pvStructInfo, pcbStructInfo, info ? info->rgAltEntry : NULL);
|
||||
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)
|
||||
@ -3753,6 +3924,9 @@ static BOOL WINAPI CRYPT_AsnDecodePathLenConstraint(DWORD dwCertEncodingType,
|
||||
{
|
||||
BOOL ret = TRUE;
|
||||
|
||||
TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded, cbEncoded, dwFlags,
|
||||
pvStructInfo, *pcbStructInfo);
|
||||
|
||||
if (cbEncoded)
|
||||
{
|
||||
if (pbEncoded[0] == ASN_INTEGER)
|
||||
@ -3801,11 +3975,11 @@ static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType,
|
||||
__TRY
|
||||
{
|
||||
struct AsnDecodeSequenceItem items[] = {
|
||||
{ offsetof(CERT_BASIC_CONSTRAINTS2_INFO, fCA), CRYPT_AsnDecodeBool,
|
||||
sizeof(BOOL), TRUE, FALSE, 0, 0 },
|
||||
{ offsetof(CERT_BASIC_CONSTRAINTS2_INFO, fPathLenConstraint),
|
||||
CRYPT_AsnDecodePathLenConstraint, sizeof(struct PATH_LEN_CONSTRAINT),
|
||||
TRUE, FALSE, 0, 0 },
|
||||
{ ASN_BOOL, offsetof(CERT_BASIC_CONSTRAINTS2_INFO, fCA),
|
||||
CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0, 0 },
|
||||
{ ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS2_INFO,
|
||||
fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
|
||||
sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
|
||||
};
|
||||
|
||||
ret = CRYPT_AsnDecodeSequence(dwCertEncodingType, items,
|
||||
@ -3838,11 +4012,11 @@ static BOOL WINAPI CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType,
|
||||
__TRY
|
||||
{
|
||||
struct AsnDecodeSequenceItem items[] = {
|
||||
{ offsetof(struct DECODED_RSA_PUB_KEY, modulus),
|
||||
{ ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, modulus),
|
||||
CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
|
||||
FALSE, TRUE, offsetof(struct DECODED_RSA_PUB_KEY, modulus.pbData),
|
||||
0 },
|
||||
{ offsetof(struct DECODED_RSA_PUB_KEY, pubexp),
|
||||
{ ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, pubexp),
|
||||
CRYPT_AsnDecodeInt, sizeof(DWORD), FALSE, FALSE, 0, 0 },
|
||||
};
|
||||
struct DECODED_RSA_PUB_KEY *decodedKey = NULL;
|
||||
@ -3900,14 +4074,11 @@ static BOOL WINAPI CRYPT_AsnDecodeOctetsInternal(DWORD dwCertEncodingType,
|
||||
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
|
||||
{
|
||||
BOOL ret;
|
||||
DWORD bytesNeeded, dataLen;
|
||||
|
||||
TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags,
|
||||
pDecodePara, pvStructInfo, *pcbStructInfo);
|
||||
|
||||
if (pbEncoded[0] == ASN_OCTETSTRING)
|
||||
{
|
||||
DWORD bytesNeeded, dataLen;
|
||||
|
||||
if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
|
||||
{
|
||||
if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
|
||||
@ -3940,12 +4111,6 @@ static BOOL WINAPI CRYPT_AsnDecodeOctetsInternal(DWORD dwCertEncodingType,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError(CRYPT_E_ASN1_BADTAG);
|
||||
ret = FALSE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -3962,7 +4127,17 @@ static BOOL WINAPI CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType,
|
||||
{
|
||||
DWORD bytesNeeded;
|
||||
|
||||
if ((ret = CRYPT_AsnDecodeOctetsInternal(dwCertEncodingType,
|
||||
if (!cbEncoded)
|
||||
{
|
||||
SetLastError(CRYPT_E_ASN1_CORRUPT);
|
||||
ret = FALSE;
|
||||
}
|
||||
else if (pbEncoded[0] != ASN_OCTETSTRING)
|
||||
{
|
||||
SetLastError(CRYPT_E_ASN1_BADTAG);
|
||||
ret = FALSE;
|
||||
}
|
||||
else if ((ret = CRYPT_AsnDecodeOctetsInternal(dwCertEncodingType,
|
||||
lpszStructType, pbEncoded, cbEncoded,
|
||||
dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL, &bytesNeeded)))
|
||||
{
|
||||
@ -3983,11 +4158,6 @@ static BOOL WINAPI CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType,
|
||||
&bytesNeeded);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError(CRYPT_E_ASN1_BADTAG);
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
__EXCEPT(page_fault)
|
||||
{
|
||||
@ -4830,6 +5000,57 @@ static BOOL WINAPI CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRYPT_AsnDecodeDistPoint(DWORD dwCertEncodingType,
|
||||
LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
|
||||
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
|
||||
{
|
||||
struct AsnDecodeSequenceItem items[] = {
|
||||
{ ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_DIST_POINT,
|
||||
DistPointName), CRYPT_AsnDecodeAltNameInternal,
|
||||
sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE, offsetof(CRL_DIST_POINT,
|
||||
DistPointName.u.FullName.rgAltEntry), 0 },
|
||||
{ ASN_CONTEXT | 1, offsetof(CRL_DIST_POINT, ReasonFlags),
|
||||
CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
|
||||
offsetof(CRL_DIST_POINT, ReasonFlags.pbData), 0 },
|
||||
{ ASN_CONTEXT | ASN_CONSTRUCTOR | 2, offsetof(CRL_DIST_POINT, CRLIssuer),
|
||||
CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE, TRUE,
|
||||
offsetof(CRL_DIST_POINT, CRLIssuer.rgAltEntry), 0 },
|
||||
};
|
||||
BOOL ret;
|
||||
|
||||
ret = CRYPT_AsnDecodeSequence(dwCertEncodingType, items,
|
||||
sizeof(items) / sizeof(items[0]), pbEncoded, cbEncoded,
|
||||
dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType,
|
||||
LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
|
||||
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags,
|
||||
pDecodePara, pvStructInfo, *pcbStructInfo);
|
||||
|
||||
__TRY
|
||||
{
|
||||
struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
|
||||
CRYPT_AsnDecodeDistPoint, sizeof(CRL_DIST_POINT), TRUE,
|
||||
offsetof(CRL_DIST_POINT, DistPointName.u.FullName.rgAltEntry) };
|
||||
|
||||
ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
|
||||
pDecodePara, pvStructInfo, pcbStructInfo, NULL);
|
||||
}
|
||||
__EXCEPT(page_fault)
|
||||
{
|
||||
SetLastError(STATUS_ACCESS_VIOLATION);
|
||||
ret = FALSE;
|
||||
}
|
||||
__ENDTRY
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
|
||||
const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
|
||||
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
|
||||
@ -4927,6 +5148,9 @@ BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
|
||||
case (WORD)PKCS_UTC_TIME:
|
||||
decodeFunc = CRYPT_AsnDecodeUtcTime;
|
||||
break;
|
||||
case (WORD)X509_CRL_DIST_POINTS:
|
||||
decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
|
||||
break;
|
||||
default:
|
||||
FIXME("%d: unimplemented\n", LOWORD(lpszStructType));
|
||||
}
|
||||
|
@ -1379,14 +1379,15 @@ static void test_decodeBasicConstraints(DWORD dwEncoding)
|
||||
ret = CryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
|
||||
constraints2[i].encoded, constraints2[i].encoded[1] + 2,
|
||||
CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
|
||||
ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
|
||||
ok(ret, "CryptDecodeObjectEx failed for item %ld: %08lx\n", i,
|
||||
GetLastError());
|
||||
if (buf)
|
||||
{
|
||||
CERT_BASIC_CONSTRAINTS2_INFO *info =
|
||||
(CERT_BASIC_CONSTRAINTS2_INFO *)buf;
|
||||
|
||||
ok(!memcmp(info, &constraints2[i].info, sizeof(*info)),
|
||||
"Unexpected value\n");
|
||||
"Unexpected value for item %ld\n", i);
|
||||
LocalFree(buf);
|
||||
}
|
||||
}
|
||||
@ -2222,6 +2223,227 @@ static void test_decodeCert(DWORD dwEncoding)
|
||||
}
|
||||
}
|
||||
|
||||
static const BYTE emptyDistPoint[] = { 0x30, 0x02, 0x30, 0x00 };
|
||||
static const BYTE distPointWithUrl[] = { 0x30, 0x19, 0x30, 0x17, 0xa0, 0x15,
|
||||
0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69,
|
||||
0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
|
||||
static const BYTE distPointWithReason[] = { 0x30, 0x06, 0x30, 0x04, 0x81, 0x02,
|
||||
0x00, 0x03 };
|
||||
static const BYTE distPointWithIssuer[] = { 0x30, 0x17, 0x30, 0x15, 0xa2, 0x13,
|
||||
0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65,
|
||||
0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
|
||||
static const BYTE distPointWithUrlAndIssuer[] = { 0x30, 0x2e, 0x30, 0x2c, 0xa0,
|
||||
0x15, 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
|
||||
0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67, 0xa2, 0x13, 0x86, 0x11,
|
||||
0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71,
|
||||
0x2e, 0x6f, 0x72, 0x67 };
|
||||
static const BYTE crlReason = CRL_REASON_KEY_COMPROMISE |
|
||||
CRL_REASON_AFFILIATION_CHANGED;
|
||||
|
||||
static void test_encodeCRLDistPoints(DWORD dwEncoding)
|
||||
{
|
||||
CRL_DIST_POINTS_INFO info = { 0 };
|
||||
CRL_DIST_POINT point = { { 0 } };
|
||||
CERT_ALT_NAME_ENTRY entry = { 0 };
|
||||
BOOL ret;
|
||||
BYTE *buf = NULL;
|
||||
DWORD size = 0;
|
||||
|
||||
/* Test with an empty info */
|
||||
ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
|
||||
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
|
||||
ok(!ret && GetLastError() == HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER),
|
||||
"Expected HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), got %08lx\n",
|
||||
GetLastError());
|
||||
/* Test with one empty dist point */
|
||||
info.cDistPoint = 1;
|
||||
info.rgDistPoint = &point;
|
||||
ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
|
||||
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
|
||||
if (buf)
|
||||
{
|
||||
ok(size == sizeof(emptyDistPoint), "Expected size %d, got %ld\n",
|
||||
sizeof(emptyDistPoint), size);
|
||||
ok(!memcmp(buf, emptyDistPoint, size), "Unexpected value\n");
|
||||
LocalFree(buf);
|
||||
}
|
||||
/* A dist point with an invalid name */
|
||||
point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
|
||||
entry.dwAltNameChoice = CERT_ALT_NAME_URL;
|
||||
entry.pwszURL = (LPWSTR)nihongoURL;
|
||||
point.DistPointName.FullName.cAltEntry = 1;
|
||||
point.DistPointName.FullName.rgAltEntry = &entry;
|
||||
ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
|
||||
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
|
||||
ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
|
||||
"Expected CRYPT_E_INVALID_IA5_STRING, got %08lx\n", GetLastError());
|
||||
/* The first invalid character is at index 7 */
|
||||
ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
|
||||
"Expected invalid char at index 7, got %ld\n",
|
||||
GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
|
||||
/* A dist point with (just) a valid name */
|
||||
entry.pwszURL = (LPWSTR)url;
|
||||
ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
|
||||
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
|
||||
if (buf)
|
||||
{
|
||||
ok(size == sizeof(distPointWithUrl), "Expected size %d, got %ld\n",
|
||||
sizeof(distPointWithUrl), size);
|
||||
ok(!memcmp(buf, distPointWithUrl, size), "Unexpected value\n");
|
||||
LocalFree(buf);
|
||||
}
|
||||
/* A dist point with (just) reason flags */
|
||||
point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
|
||||
point.ReasonFlags.cbData = sizeof(crlReason);
|
||||
point.ReasonFlags.pbData = (LPBYTE)&crlReason;
|
||||
ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
|
||||
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
|
||||
if (buf)
|
||||
{
|
||||
ok(size == sizeof(distPointWithReason), "Expected size %d, got %ld\n",
|
||||
sizeof(distPointWithReason), size);
|
||||
ok(!memcmp(buf, distPointWithReason, size), "Unexpected value\n");
|
||||
LocalFree(buf);
|
||||
}
|
||||
/* A dist point with just an issuer */
|
||||
point.ReasonFlags.cbData = 0;
|
||||
point.CRLIssuer.cAltEntry = 1;
|
||||
point.CRLIssuer.rgAltEntry = &entry;
|
||||
ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
|
||||
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
|
||||
if (buf)
|
||||
{
|
||||
ok(size == sizeof(distPointWithIssuer), "Expected size %d, got %ld\n",
|
||||
sizeof(distPointWithIssuer), size);
|
||||
ok(!memcmp(buf, distPointWithIssuer, size), "Unexpected value\n");
|
||||
LocalFree(buf);
|
||||
}
|
||||
/* A dist point with both a name and an issuer */
|
||||
point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
|
||||
ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
|
||||
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
|
||||
if (buf)
|
||||
{
|
||||
ok(size == sizeof(distPointWithUrlAndIssuer),
|
||||
"Expected size %d, got %ld\n", sizeof(distPointWithUrlAndIssuer),
|
||||
size);
|
||||
ok(!memcmp(buf, distPointWithUrlAndIssuer, size), "Unexpected value\n");
|
||||
LocalFree(buf);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_decodeCRLDistPoints(DWORD dwEncoding)
|
||||
{
|
||||
BOOL ret;
|
||||
BYTE *buf = NULL;
|
||||
DWORD size = 0;
|
||||
PCRL_DIST_POINTS_INFO info;
|
||||
PCRL_DIST_POINT point;
|
||||
PCERT_ALT_NAME_ENTRY entry;
|
||||
|
||||
ret = CryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
|
||||
emptyDistPoint, emptyDistPoint[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
|
||||
(BYTE *)&buf, &size);
|
||||
if (ret)
|
||||
{
|
||||
info = (PCRL_DIST_POINTS_INFO)buf;
|
||||
ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
|
||||
"Expected size at least %d, got %ld\n",
|
||||
sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT), size);
|
||||
ok(info->cDistPoint == 1, "Expected 1 dist points, got %ld\n",
|
||||
info->cDistPoint);
|
||||
point = info->rgDistPoint;
|
||||
ok(point->DistPointName.dwDistPointNameChoice == CRL_DIST_POINT_NO_NAME,
|
||||
"Expected CRL_DIST_POINT_NO_NAME, got %ld\n",
|
||||
point->DistPointName.dwDistPointNameChoice);
|
||||
ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
|
||||
ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
|
||||
LocalFree(buf);
|
||||
}
|
||||
ret = CryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
|
||||
distPointWithUrl, distPointWithUrl[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
|
||||
(BYTE *)&buf, &size);
|
||||
if (ret)
|
||||
{
|
||||
info = (PCRL_DIST_POINTS_INFO)buf;
|
||||
ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
|
||||
"Expected size at least %d, got %ld\n",
|
||||
sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT), size);
|
||||
ok(info->cDistPoint == 1, "Expected 1 dist points, got %ld\n",
|
||||
info->cDistPoint);
|
||||
point = info->rgDistPoint;
|
||||
ok(point->DistPointName.dwDistPointNameChoice ==
|
||||
CRL_DIST_POINT_FULL_NAME,
|
||||
"Expected CRL_DIST_POINT_FULL_NAME, got %ld\n",
|
||||
point->DistPointName.dwDistPointNameChoice);
|
||||
ok(point->DistPointName.FullName.cAltEntry == 1,
|
||||
"Expected 1 name entry, got %ld\n",
|
||||
point->DistPointName.FullName.cAltEntry);
|
||||
entry = point->DistPointName.FullName.rgAltEntry;
|
||||
ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
|
||||
"Expected CERT_ALT_NAME_URL, got %ld\n", entry->dwAltNameChoice);
|
||||
ok(!lstrcmpW(entry->pwszURL, url), "Unexpected name\n");
|
||||
ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
|
||||
ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
|
||||
LocalFree(buf);
|
||||
}
|
||||
ret = CryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
|
||||
distPointWithReason, distPointWithReason[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
|
||||
NULL, (BYTE *)&buf, &size);
|
||||
if (ret)
|
||||
{
|
||||
info = (PCRL_DIST_POINTS_INFO)buf;
|
||||
ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
|
||||
"Expected size at least %d, got %ld\n",
|
||||
sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT), size);
|
||||
ok(info->cDistPoint == 1, "Expected 1 dist points, got %ld\n",
|
||||
info->cDistPoint);
|
||||
point = info->rgDistPoint;
|
||||
ok(point->DistPointName.dwDistPointNameChoice ==
|
||||
CRL_DIST_POINT_NO_NAME,
|
||||
"Expected CRL_DIST_POINT_NO_NAME, got %ld\n",
|
||||
point->DistPointName.dwDistPointNameChoice);
|
||||
ok(point->ReasonFlags.cbData == sizeof(crlReason),
|
||||
"Expected reason length\n");
|
||||
ok(!memcmp(point->ReasonFlags.pbData, &crlReason, sizeof(crlReason)),
|
||||
"Unexpected reason\n");
|
||||
ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
|
||||
LocalFree(buf);
|
||||
}
|
||||
ret = CryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
|
||||
distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2,
|
||||
CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
|
||||
if (ret)
|
||||
{
|
||||
info = (PCRL_DIST_POINTS_INFO)buf;
|
||||
ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
|
||||
"Expected size at least %d, got %ld\n",
|
||||
sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT), size);
|
||||
ok(info->cDistPoint == 1, "Expected 1 dist points, got %ld\n",
|
||||
info->cDistPoint);
|
||||
point = info->rgDistPoint;
|
||||
ok(point->DistPointName.dwDistPointNameChoice ==
|
||||
CRL_DIST_POINT_FULL_NAME,
|
||||
"Expected CRL_DIST_POINT_FULL_NAME, got %ld\n",
|
||||
point->DistPointName.dwDistPointNameChoice);
|
||||
ok(point->DistPointName.FullName.cAltEntry == 1,
|
||||
"Expected 1 name entry, got %ld\n",
|
||||
point->DistPointName.FullName.cAltEntry);
|
||||
entry = point->DistPointName.FullName.rgAltEntry;
|
||||
ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
|
||||
"Expected CERT_ALT_NAME_URL, got %ld\n", entry->dwAltNameChoice);
|
||||
ok(!lstrcmpW(entry->pwszURL, url), "Unexpected name\n");
|
||||
ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
|
||||
ok(point->CRLIssuer.cAltEntry == 1,
|
||||
"Expected 1 issuer entry, got %ld\n", point->CRLIssuer.cAltEntry);
|
||||
entry = point->CRLIssuer.rgAltEntry;
|
||||
ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
|
||||
"Expected CERT_ALT_NAME_URL, got %ld\n", entry->dwAltNameChoice);
|
||||
ok(!lstrcmpW(entry->pwszURL, url), "Unexpected name\n");
|
||||
LocalFree(buf);
|
||||
}
|
||||
}
|
||||
|
||||
static const BYTE v1CRL[] = { 0x30, 0x15, 0x30, 0x02, 0x06, 0x00, 0x18, 0x0f,
|
||||
0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x5a };
|
||||
@ -2594,6 +2816,8 @@ START_TEST(encode)
|
||||
test_decodeCertToBeSigned(encodings[i]);
|
||||
test_encodeCert(encodings[i]);
|
||||
test_decodeCert(encodings[i]);
|
||||
test_encodeCRLDistPoints(encodings[i]);
|
||||
test_decodeCRLDistPoints(encodings[i]);
|
||||
test_encodeCRLToBeSigned(encodings[i]);
|
||||
test_decodeCRLToBeSigned(encodings[i]);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user