/*
- * Copyright 2005-2008 Juan Lang
+ * Copyright 2005-2009 Juan Lang
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
WINE_DEFAULT_DEBUG_CHANNEL(cryptasn);
WINE_DECLARE_DEBUG_CHANNEL(crypt);
-struct GenericArray
-{
- DWORD cItems;
- BYTE *rgItems;
-};
-
typedef BOOL (WINAPI *CryptDecodeObjectFunc)(DWORD, LPCSTR, const BYTE *,
DWORD, DWORD, void *, DWORD *);
typedef BOOL (WINAPI *CryptDecodeObjectExFunc)(DWORD, LPCSTR, const BYTE *,
static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded,
DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
DWORD *pcbDecoded);
-/* Like CRYPT_AsnDecodeExtensions, except assumes rgExtension is set ahead of
- * time, doesn't do memory allocation, and doesn't do exception handling.
+/* Assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set ahead of time.
*/
-static BOOL CRYPT_AsnDecodeExtensionsInternal(const BYTE *pbEncoded,
- DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
- DWORD *pcbDecoded);
+static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded,
+ DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
/* Assumes algo->Parameters.pbData is set ahead of time. */
static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded,
DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
DWORD *pcbDecoded);
+/* Doesn't check the tag, assumes the caller does so */
static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded,
DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
DWORD *pcbDecoded);
-static BOOL CRYPT_AsnDecodePKCSAttributesInternal(const BYTE *pbEncoded,
+static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded,
DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
DWORD *pcbDecoded);
DWORD size;
};
+#define FINALMEMBERSIZE(s, member) (sizeof(s) - offsetof(s, member))
+#define MEMBERSIZE(s, member, nextmember) \
+ (offsetof(s, nextmember) - offsetof(s, member))
+
/* Decodes the items in a sequence, where the items are described in items,
* the encoded data are in pbEncoded with length cbEncoded. Decodes into
* pvStructInfo. nextData is a pointer to the memory location at which the
: NULL, &items[i].size, &itemDecoded);
if (ret)
{
+ if (items[i].size < items[i].minSize)
+ items[i].size = items[i].minSize;
+ else if (items[i].size > items[i].minSize)
+ {
/* Account for alignment padding */
- if (items[i].size % sizeof(DWORD_PTR))
- items[i].size += sizeof(DWORD_PTR) -
- items[i].size % sizeof(DWORD_PTR);
+ items[i].size = ALIGN_DWORD_PTR(items[i].size);
+ }
TRACE("item %d size: %d\n", i, items[i].size);
if (nextData && items[i].hasPointer &&
items[i].size > items[i].minSize)
}
else
{
- 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);
- }
+ ptr += itemDecoded;
+ decoded += itemDecoded;
+ TRACE("item %d: decoded %d bytes\n", i,
+ itemDecoded);
}
}
else if (items[i].optional &&
cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo,
startingPointer);
+ if (!cbEncoded)
+ {
+ SetLastError(CRYPT_E_ASN1_EOD);
+ return FALSE;
+ }
if (pbEncoded[0] == ASN_SEQUENCE)
{
DWORD dataLen;
for (i = 0; i < cItem; i++)
{
bytesNeeded += items[i].size;
- structSize += items[i].minSize;
+ structSize = max( structSize, items[i].offset + items[i].minSize );
}
if (pcbDecoded)
*pcbDecoded = 1 + lenBytes + cbDecoded;
if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
pvStructInfo = *(BYTE **)pvStructInfo;
if (startingPointer)
- nextData = (BYTE *)startingPointer;
+ nextData = startingPointer;
else
nextData = (BYTE *)pvStructInfo + structSize;
memset(pvStructInfo, 0, structSize);
* The expected tag of the entire encoded array (usually a variant
* of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
* regardless of the tag seen.
+ * countOffset:
+ * The offset within the outer structure at which the count exists.
+ * For example, a structure such as CRYPT_ATTRIBUTES has countOffset == 0,
+ * while CRYPT_ATTRIBUTE has countOffset ==
+ * offsetof(CRYPT_ATTRIBUTE, cValue).
+ * arrayOffset:
+ * The offset within the outer structure at which the array pointer exists.
+ * For example, CRYPT_ATTRIBUTES has arrayOffset ==
+ * offsetof(CRYPT_ATTRIBUTES, rgAttr).
+ * minArraySize:
+ * The minimum size of the decoded array. On WIN32, this is always 8:
+ * sizeof(DWORD) + sizeof(void *). On WIN64, it can be larger due to
+ * alignment.
* decodeFunc:
* used to decode each item in the array
* itemSize:
struct AsnArrayDescriptor
{
BYTE tag;
+ DWORD countOffset;
+ DWORD arrayOffset;
+ DWORD minArraySize;
InternalDecodeFunc decodeFunc;
DWORD itemSize;
BOOL hasPointer;
DWORD size;
};
-/* Decodes an array of like types into a struct GenericArray.
- * The layout and decoding of the array are described by a struct
+/* Decodes an array of like types into a structure 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,
- DWORD *pcbDecoded, void *startingPointer)
+ DWORD *pcbDecoded)
{
BOOL ret = TRUE;
- TRACE("%p, %p, %d, %08x, %p, %p, %d, %p\n", arrayDesc, pbEncoded,
- cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo,
- startingPointer);
+ TRACE("%p, %p, %d, %p, %d\n", arrayDesc, pbEncoded,
+ cbEncoded, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
- if (!arrayDesc->tag || pbEncoded[0] == arrayDesc->tag)
+ if (!cbEncoded)
+ {
+ SetLastError(CRYPT_E_ASN1_EOD);
+ ret = FALSE;
+ }
+ else if (!arrayDesc->tag || pbEncoded[0] == arrayDesc->tag)
{
DWORD dataLen;
if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
{
- DWORD bytesNeeded, cItems = 0, decoded;
+ DWORD bytesNeeded = arrayDesc->minArraySize, cItems = 0, decoded;
BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
/* There can be arbitrarily many items, but there is often only one.
*/
struct AsnArrayItemSize itemSize = { 0 }, *itemSizes = &itemSize;
decoded = 1 + lenBytes;
- bytesNeeded = sizeof(struct GenericArray);
if (dataLen)
{
const BYTE *ptr;
*pcbDecoded = decoded;
if (!pvStructInfo)
*pcbStructInfo = bytesNeeded;
- else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
- pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
+ else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
+ pvStructInfo, pcbStructInfo, bytesNeeded)))
{
- DWORD i;
+ DWORD i, *pcItems;
BYTE *nextData;
const BYTE *ptr;
- struct GenericArray *array;
+ void *rgItems;
if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
- pvStructInfo = *(BYTE **)pvStructInfo;
- array = (struct GenericArray *)pvStructInfo;
- array->cItems = cItems;
- if (startingPointer)
- array->rgItems = startingPointer;
+ pvStructInfo = *(void **)pvStructInfo;
+ pcItems = pvStructInfo;
+ *pcItems = cItems;
+ if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
+ {
+ rgItems = (BYTE *)pvStructInfo +
+ arrayDesc->minArraySize;
+ *(void **)((BYTE *)pcItems -
+ arrayDesc->countOffset + arrayDesc->arrayOffset) =
+ rgItems;
+ }
else
- array->rgItems = (BYTE *)array +
- sizeof(struct GenericArray);
- nextData = array->rgItems +
- array->cItems * arrayDesc->itemSize;
+ rgItems = *(void **)((BYTE *)pcItems -
+ arrayDesc->countOffset + arrayDesc->arrayOffset);
+ nextData = (BYTE *)rgItems + cItems * arrayDesc->itemSize;
for (i = 0, ptr = pbEncoded + 1 + lenBytes; ret &&
i < cItems && ptr - pbEncoded - 1 - lenBytes <
dataLen; i++)
DWORD itemDecoded;
if (arrayDesc->hasPointer)
- *(BYTE **)(array->rgItems + i * arrayDesc->itemSize
+ *(BYTE **)((BYTE *)rgItems + i * arrayDesc->itemSize
+ arrayDesc->pointerOffset) = nextData;
ret = arrayDesc->decodeFunc(ptr,
itemSizes[i].encodedLen,
dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
- array->rgItems + i * arrayDesc->itemSize,
+ (BYTE *)rgItems + i * arrayDesc->itemSize,
&itemSizes[i].size, &itemDecoded);
if (ret)
{
ptr += itemDecoded;
}
}
- if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
- CRYPT_FreeSpace(pDecodePara, pvStructInfo);
}
}
if (itemSizes != &itemSize)
if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
pvStructInfo = *(BYTE **)pvStructInfo;
- blob = (CRYPT_DER_BLOB *)pvStructInfo;
+ blob = pvStructInfo;
blob->cbData = 1 + lenBytes + dataLen;
if (blob->cbData)
{
pcbDecoded);
if (ret && pvStructInfo)
{
- CRYPT_BIT_BLOB *blob = (CRYPT_BIT_BLOB *)pvStructInfo;
+ CRYPT_BIT_BLOB *blob = pvStructInfo;
if (blob->cbData)
{
return ret;
}
+static BOOL CRYPT_AsnDecodeCertExtensionsInternal(const BYTE *pbEncoded,
+ DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
+ DWORD *pcbDecoded)
+{
+ BOOL ret = TRUE;
+ struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
+ offsetof(CERT_INFO, cExtension), offsetof(CERT_INFO, rgExtension),
+ FINALMEMBERSIZE(CERT_INFO, cExtension),
+ CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
+ offsetof(CERT_EXTENSION, pszObjId) };
+
+ TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
+ pvStructInfo, *pcbStructInfo, pcbDecoded);
+
+ ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
+ dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
+ return ret;
+}
+
static BOOL CRYPT_AsnDecodeCertExtensions(const BYTE *pbEncoded,
DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
DWORD *pcbDecoded)
{
BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
- ret = CRYPT_AsnDecodeExtensionsInternal(pbEncoded + 1 + lenBytes,
+ ret = CRYPT_AsnDecodeCertExtensionsInternal(pbEncoded + 1 + lenBytes,
dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
if (ret && pcbDecoded)
*pcbDecoded = 1 + lenBytes + dataLen;
return ret;
}
-static BOOL WINAPI CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType,
+static BOOL CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
CRYPT_AsnDecodePubKeyInfoInternal, sizeof(CERT_PUBLIC_KEY_INFO),
FALSE, TRUE, offsetof(CERT_INFO,
SubjectPublicKeyInfo.Algorithm.Parameters.pbData), 0 },
- { ASN_BITSTRING, offsetof(CERT_INFO, IssuerUniqueId),
+ { ASN_CONTEXT | 1, offsetof(CERT_INFO, IssuerUniqueId),
CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
offsetof(CERT_INFO, IssuerUniqueId.pbData), 0 },
- { ASN_BITSTRING, offsetof(CERT_INFO, SubjectUniqueId),
+ { ASN_CONTEXT | 2, 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 },
+ CRYPT_AsnDecodeCertExtensions, FINALMEMBERSIZE(CERT_INFO, cExtension),
+ TRUE, TRUE, offsetof(CERT_INFO, rgExtension), 0 },
};
TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
info = *(CERT_INFO **)pvStructInfo;
else
- info = (CERT_INFO *)pvStructInfo;
+ info = pvStructInfo;
if (!info->SerialNumber.cbData || !info->Issuer.cbData ||
!info->Subject.cbData)
{
ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
- (BYTE *)&signedCert, &size);
+ &signedCert, &size);
if (ret)
{
size = 0;
return ret;
}
+static BOOL CRYPT_AsnDecodeCRLEntryExtensions(const BYTE *pbEncoded,
+ DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
+ DWORD *pcbDecoded)
+{
+ BOOL ret = TRUE;
+ struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
+ offsetof(CRL_ENTRY, cExtension), offsetof(CRL_ENTRY, rgExtension),
+ FINALMEMBERSIZE(CRL_ENTRY, cExtension),
+ CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
+ offsetof(CERT_EXTENSION, pszObjId) };
+
+ TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
+ pvStructInfo, *pcbStructInfo, pcbDecoded);
+
+ ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
+ dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
+ return ret;
+}
+
static BOOL CRYPT_AsnDecodeCRLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
{ 0, offsetof(CRL_ENTRY, RevocationDate),
CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
{ ASN_SEQUENCEOF, offsetof(CRL_ENTRY, cExtension),
- CRYPT_AsnDecodeExtensionsInternal, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
+ CRYPT_AsnDecodeCRLEntryExtensions,
+ FINALMEMBERSIZE(CRL_ENTRY, cExtension), TRUE, TRUE,
offsetof(CRL_ENTRY, rgExtension), 0 },
};
- PCRL_ENTRY entry = (PCRL_ENTRY)pvStructInfo;
+ PCRL_ENTRY entry = pvStructInfo;
TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
*pcbStructInfo);
return ret;
}
-/* Warning: assumes pvStructInfo is a struct GenericArray whose rgItems has
- * been set prior to calling.
+/* Warning: assumes pvStructInfo points to the cCRLEntry member of a CRL_INFO
+ * whose rgCRLEntry member has been set prior to calling.
*/
static BOOL CRYPT_AsnDecodeCRLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
BOOL ret;
struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
+ offsetof(CRL_INFO, cCRLEntry), offsetof(CRL_INFO, rgCRLEntry),
+ MEMBERSIZE(CRL_INFO, cCRLEntry, cExtension),
CRYPT_AsnDecodeCRLEntry, sizeof(CRL_ENTRY), TRUE,
offsetof(CRL_ENTRY, SerialNumber.pbData) };
- struct GenericArray *entries = (struct GenericArray *)pvStructInfo;
TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo, pcbDecoded);
- ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
- NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
- entries ? entries->rgItems : NULL);
+ ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
+ dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
TRACE("Returning %d (%08x)\n", ret, GetLastError());
return ret;
}
-static BOOL WINAPI CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType,
+static BOOL CRYPT_AsnDecodeCRLExtensionsInternal(const BYTE *pbEncoded,
+ DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
+ DWORD *pcbDecoded)
+{
+ BOOL ret = TRUE;
+ struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
+ offsetof(CRL_INFO, cExtension), offsetof(CRL_INFO, rgExtension),
+ FINALMEMBERSIZE(CRL_INFO, cExtension),
+ CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
+ offsetof(CERT_EXTENSION, pszObjId) };
+
+ TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
+ pvStructInfo, *pcbStructInfo, pcbDecoded);
+
+ ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
+ dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
+ return ret;
+}
+
+static BOOL CRYPT_AsnDecodeCRLExtensions(const BYTE *pbEncoded,
+ DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
+ DWORD *pcbDecoded)
+{
+ BOOL ret;
+ DWORD dataLen;
+
+ if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
+ {
+ BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
+
+ ret = CRYPT_AsnDecodeCRLExtensionsInternal(pbEncoded + 1 + lenBytes,
+ dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
+ if (ret && pcbDecoded)
+ *pcbDecoded = 1 + lenBytes + dataLen;
+ }
+ return ret;
+}
+
+static BOOL CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
{ 0, offsetof(CRL_INFO, NextUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
sizeof(FILETIME), TRUE, FALSE, 0 },
{ ASN_SEQUENCEOF, offsetof(CRL_INFO, cCRLEntry),
- CRYPT_AsnDecodeCRLEntries, sizeof(struct GenericArray), TRUE, TRUE,
- offsetof(CRL_INFO, rgCRLEntry), 0 },
+ CRYPT_AsnDecodeCRLEntries, MEMBERSIZE(CRL_INFO, cCRLEntry, cExtension),
+ TRUE, TRUE, offsetof(CRL_INFO, rgCRLEntry), 0 },
{ ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_INFO, cExtension),
- CRYPT_AsnDecodeCertExtensions, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
- offsetof(CRL_INFO, rgExtension), 0 },
+ CRYPT_AsnDecodeCRLExtensions, FINALMEMBERSIZE(CRL_INFO, cExtension),
+ TRUE, TRUE, offsetof(CRL_INFO, rgExtension), 0 },
};
BOOL ret = TRUE;
ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
- (BYTE *)&signedCrl, &size);
+ &signedCrl, &size);
if (ret)
{
size = 0;
return ret;
}
-/* Warning: assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set
- * ahead of time!
- */
static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded,
DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
offsetof(CERT_EXTENSION, Value.pbData) },
};
BOOL ret = TRUE;
- PCERT_EXTENSION ext = (PCERT_EXTENSION)pvStructInfo;
+ PCERT_EXTENSION ext = pvStructInfo;
TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, ext,
*pcbStructInfo);
return ret;
}
-static BOOL CRYPT_AsnDecodeExtensionsInternal(const BYTE *pbEncoded,
- DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
- DWORD *pcbDecoded)
-{
- BOOL ret = TRUE;
- struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
- CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
- offsetof(CERT_EXTENSION, pszObjId) };
- PCERT_EXTENSIONS exts = (PCERT_EXTENSIONS)pvStructInfo;
-
- TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
- pvStructInfo, *pcbStructInfo, pcbDecoded);
-
- ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
- NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
- exts ? exts->rgExtension : NULL);
- return ret;
-}
-
static BOOL WINAPI CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
BOOL ret = TRUE;
+ TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
+ pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
+
__TRY
{
- ret = CRYPT_AsnDecodeExtensionsInternal(pbEncoded, cbEncoded,
- dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
- if (ret && pvStructInfo)
- {
- ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
- pcbStructInfo, *pcbStructInfo);
- if (ret)
- {
- CERT_EXTENSIONS *exts;
-
- if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
- pvStructInfo = *(BYTE **)pvStructInfo;
- exts = (CERT_EXTENSIONS *)pvStructInfo;
- exts->rgExtension = (CERT_EXTENSION *)((BYTE *)exts +
- sizeof(CERT_EXTENSIONS));
- ret = CRYPT_AsnDecodeExtensionsInternal(pbEncoded, cbEncoded,
- dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
- pcbStructInfo, NULL);
+ struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
+ offsetof(CERT_EXTENSIONS, cExtension),
+ offsetof(CERT_EXTENSIONS, rgExtension),
+ sizeof(CERT_EXTENSIONS),
+ CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
+ offsetof(CERT_EXTENSION, pszObjId) };
+
+ ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
+ dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
}
- }
- }
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
{
BOOL ret = TRUE;
DWORD dataLen;
- CERT_NAME_VALUE *value = (CERT_NAME_VALUE *)pvStructInfo;
+ CERT_NAME_VALUE *value = pvStructInfo;
if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
{
if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
pvStructInfo = *(BYTE **)pvStructInfo;
- value = (CERT_NAME_VALUE *)pvStructInfo;
+ value = pvStructInfo;
value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
ret = CRYPT_AsnDecodeNameValueInternal( pbEncoded, cbEncoded,
dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
{
BOOL ret = TRUE;
DWORD dataLen;
- CERT_NAME_VALUE *value = (CERT_NAME_VALUE *)pvStructInfo;
+ CERT_NAME_VALUE *value = pvStructInfo;
if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
{
{
case ASN_NUMERICSTRING:
valueType = CERT_RDN_NUMERIC_STRING;
- bytesNeeded += dataLen * 2;
+ if (dataLen)
+ bytesNeeded += (dataLen + 1) * 2;
break;
case ASN_PRINTABLESTRING:
valueType = CERT_RDN_PRINTABLE_STRING;
- bytesNeeded += dataLen * 2;
+ if (dataLen)
+ bytesNeeded += (dataLen + 1) * 2;
break;
case ASN_IA5STRING:
valueType = CERT_RDN_IA5_STRING;
- bytesNeeded += dataLen * 2;
+ if (dataLen)
+ bytesNeeded += (dataLen + 1) * 2;
break;
case ASN_T61STRING:
valueType = CERT_RDN_T61_STRING;
- bytesNeeded += dataLen * 2;
+ if (dataLen)
+ bytesNeeded += (dataLen + 1) * 2;
break;
case ASN_VIDEOTEXSTRING:
valueType = CERT_RDN_VIDEOTEX_STRING;
- bytesNeeded += dataLen * 2;
+ if (dataLen)
+ bytesNeeded += (dataLen + 1) * 2;
break;
case ASN_GRAPHICSTRING:
valueType = CERT_RDN_GRAPHIC_STRING;
- bytesNeeded += dataLen * 2;
+ if (dataLen)
+ bytesNeeded += (dataLen + 1) * 2;
break;
case ASN_VISIBLESTRING:
valueType = CERT_RDN_VISIBLE_STRING;
- bytesNeeded += dataLen * 2;
+ if (dataLen)
+ bytesNeeded += (dataLen + 1) * 2;
break;
case ASN_GENERALSTRING:
valueType = CERT_RDN_GENERAL_STRING;
- bytesNeeded += dataLen * 2;
+ if (dataLen)
+ bytesNeeded += (dataLen + 1) * 2;
break;
case ASN_UNIVERSALSTRING:
valueType = CERT_RDN_UNIVERSAL_STRING;
- bytesNeeded += dataLen / 2;
+ if (dataLen)
+ bytesNeeded += dataLen / 2 + sizeof(WCHAR);
break;
case ASN_BMPSTRING:
valueType = CERT_RDN_BMP_STRING;
- bytesNeeded += dataLen;
+ if (dataLen)
+ bytesNeeded += dataLen + sizeof(WCHAR);
break;
case ASN_UTF8STRING:
valueType = CERT_RDN_UTF8_STRING;
- bytesNeeded += MultiByteToWideChar(CP_UTF8, 0,
- (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * 2;
+ if (dataLen)
+ bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0,
+ (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2;
break;
default:
SetLastError(CRYPT_E_ASN1_BADTAG);
value->Value.cbData = dataLen * 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;
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;
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,
(LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
- str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
+ str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * sizeof(WCHAR);
+ *(WCHAR *)(value->Value.pbData + value->Value.cbData) = 0;
+ value->Value.cbData += sizeof(WCHAR);
break;
}
}
if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
pvStructInfo = *(BYTE **)pvStructInfo;
- value = (CERT_NAME_VALUE *)pvStructInfo;
+ value = pvStructInfo;
value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded,
cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
CRYPT_AsnDecodeNameValueInternal, sizeof(CERT_NAME_VALUE),
FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
};
- CERT_RDN_ATTR *attr = (CERT_RDN_ATTR *)pvStructInfo;
+ CERT_RDN_ATTR *attr = pvStructInfo;
TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo);
{
BOOL ret = TRUE;
struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
+ offsetof(CERT_RDN, cRDNAttr), offsetof(CERT_RDN, rgRDNAttr),
+ sizeof(CERT_RDN),
CRYPT_AsnDecodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
offsetof(CERT_RDN_ATTR, pszObjId) };
- PCERT_RDN rdn = (PCERT_RDN)pvStructInfo;
ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
- NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
- rdn ? rdn->rgRDNAttr : NULL);
+ NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
return ret;
}
__TRY
{
struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
+ offsetof(CERT_NAME_INFO, cRDN), offsetof(CERT_NAME_INFO, rgRDN),
+ sizeof(CERT_NAME_INFO),
CRYPT_AsnDecodeRdn, sizeof(CERT_RDN), TRUE,
offsetof(CERT_RDN, rgRDNAttr) };
+ DWORD bytesNeeded;
+
+ ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
+ dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL, &bytesNeeded,
+ NULL);
+ if (ret)
+ {
+ if (!pvStructInfo)
+ *pcbStructInfo = bytesNeeded;
+ else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
+ pvStructInfo, pcbStructInfo, bytesNeeded)))
+ {
+ CERT_NAME_INFO *info;
- ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
- pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
+ if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
+ pvStructInfo = *(BYTE **)pvStructInfo;
+ info = pvStructInfo;
+ info->rgRDN = (CERT_RDN *)((BYTE *)pvStructInfo +
+ sizeof(CERT_NAME_INFO));
+ ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
+ dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pvStructInfo,
+ &bytesNeeded, NULL);
+ }
+ }
}
__EXCEPT_PAGE_FAULT
{
CRYPT_AsnDecodeUnicodeNameValueInternal, sizeof(CERT_NAME_VALUE),
FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
};
- CERT_RDN_ATTR *attr = (CERT_RDN_ATTR *)pvStructInfo;
+ CERT_RDN_ATTR *attr = pvStructInfo;
TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo);
{
BOOL ret = TRUE;
struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
+ offsetof(CERT_RDN, cRDNAttr), offsetof(CERT_RDN, rgRDNAttr),
+ sizeof(CERT_RDN),
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,
- NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
- rdn ? rdn->rgRDNAttr : NULL);
+ NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
return ret;
}
__TRY
{
struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
+ offsetof(CERT_NAME_INFO, cRDN), offsetof(CERT_NAME_INFO, rgRDN),
+ sizeof(CERT_NAME_INFO),
CRYPT_AsnDecodeUnicodeRdn, sizeof(CERT_RDN), TRUE,
offsetof(CERT_RDN, rgRDNAttr) };
+ DWORD bytesNeeded;
+
+ ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
+ dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL, &bytesNeeded,
+ NULL);
+ if (ret)
+ {
+ if (!pvStructInfo)
+ *pcbStructInfo = bytesNeeded;
+ else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
+ pvStructInfo, pcbStructInfo, bytesNeeded)))
+ {
+ CERT_NAME_INFO *info;
- ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
- pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
+ if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
+ pvStructInfo = *(BYTE **)pvStructInfo;
+ info = pvStructInfo;
+ info->rgRDN = (CERT_RDN *)((BYTE *)pvStructInfo +
+ sizeof(CERT_NAME_INFO));
+ ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
+ dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pvStructInfo,
+ &bytesNeeded, NULL);
+ }
+ }
}
__EXCEPT_PAGE_FAULT
{
}
else
{
- PCRYPT_OBJID_BLOB blob = (PCRYPT_OBJID_BLOB)pvStructInfo;
+ PCRYPT_OBJID_BLOB blob = pvStructInfo;
*pcbStructInfo = bytesNeeded;
blob->cbData = encodedLen;
return ret;
}
-static BOOL CRYPT_DecodeDERArray(const BYTE *pbEncoded, DWORD cbEncoded,
+static BOOL CRYPT_AsnDecodeCTLUsage(const BYTE *pbEncoded, DWORD cbEncoded,
DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
BOOL ret;
- struct AsnArrayDescriptor arrayDesc = { 0, CRYPT_AsnDecodeCopyBytes,
- sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
- struct GenericArray *array = (struct GenericArray *)pvStructInfo;
-
- TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
- pvStructInfo, *pcbStructInfo, pcbDecoded);
+ struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
+ offsetof(CTL_USAGE, cUsageIdentifier),
+ offsetof(CTL_USAGE, rgpszUsageIdentifier),
+ sizeof(CTL_USAGE),
+ CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
- NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
- array ? array->rgItems : NULL);
+ NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
return ret;
}
-static BOOL CRYPT_AsnDecodeCTLUsage(const BYTE *pbEncoded, DWORD cbEncoded,
- DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
+static BOOL CRYPT_AsnDecodeCTLEntryAttributes(const BYTE *pbEncoded,
+ DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
+ DWORD *pcbDecoded)
{
+ struct AsnArrayDescriptor arrayDesc = { 0,
+ offsetof(CTL_ENTRY, cAttribute), offsetof(CTL_ENTRY, rgAttribute),
+ FINALMEMBERSIZE(CTL_ENTRY, cAttribute),
+ CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE,
+ offsetof(CRYPT_ATTRIBUTE, pszObjId) };
BOOL ret;
- struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
- CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
- CTL_USAGE *usage = (CTL_USAGE *)pvStructInfo;
- ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
- NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
- usage ? usage->rgpszUsageIdentifier : NULL);
+ ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
+ dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
return ret;
}
CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), FALSE, TRUE,
offsetof(CTL_ENTRY, SubjectIdentifier.pbData), 0 },
{ ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CTL_ENTRY, cAttribute),
- CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES), FALSE,
- TRUE, offsetof(CTL_ENTRY, rgAttribute), 0 },
+ CRYPT_AsnDecodeCTLEntryAttributes,
+ FINALMEMBERSIZE(CTL_ENTRY, cAttribute), FALSE, TRUE,
+ offsetof(CTL_ENTRY, rgAttribute), 0 },
};
BOOL ret = TRUE;
- CTL_ENTRY *entry = (CTL_ENTRY *)pvStructInfo;
+ CTL_ENTRY *entry = pvStructInfo;
TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
*pcbStructInfo);
{
BOOL ret;
struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
+ offsetof(CTL_INFO, cCTLEntry), offsetof(CTL_INFO, rgCTLEntry),
+ FINALMEMBERSIZE(CTL_INFO, cExtension),
CRYPT_AsnDecodeCTLEntry, sizeof(CTL_ENTRY), TRUE,
offsetof(CTL_ENTRY, SubjectIdentifier.pbData) };
- struct GenericArray *entries = (struct GenericArray *)pvStructInfo;
TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo, pcbDecoded);
- ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
- NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
- entries ? entries->rgItems : NULL);
+ ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
+ dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
+ return ret;
+}
+
+static BOOL CRYPT_AsnDecodeCTLExtensionsInternal(const BYTE *pbEncoded,
+ DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
+ DWORD *pcbDecoded)
+{
+ BOOL ret = TRUE;
+ struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
+ offsetof(CTL_INFO, cExtension), offsetof(CTL_INFO, rgExtension),
+ FINALMEMBERSIZE(CTL_INFO, cExtension),
+ CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
+ offsetof(CERT_EXTENSION, pszObjId) };
+
+ TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
+ pvStructInfo, *pcbStructInfo, pcbDecoded);
+
+ ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
+ dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
+ return ret;
+}
+
+static BOOL CRYPT_AsnDecodeCTLExtensions(const BYTE *pbEncoded,
+ DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
+ DWORD *pcbDecoded)
+{
+ BOOL ret;
+ DWORD dataLen;
+
+ if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
+ {
+ BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
+
+ ret = CRYPT_AsnDecodeCTLExtensionsInternal(pbEncoded + 1 + lenBytes,
+ dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
+ if (ret && pcbDecoded)
+ *pcbDecoded = 1 + lenBytes + dataLen;
+ }
return ret;
}
CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
FALSE, TRUE, offsetof(CTL_INFO, SubjectAlgorithm.pszObjId), 0 },
{ ASN_SEQUENCEOF, offsetof(CTL_INFO, cCTLEntry),
- CRYPT_AsnDecodeCTLEntries, sizeof(struct GenericArray),
+ CRYPT_AsnDecodeCTLEntries,
+ MEMBERSIZE(CTL_INFO, cCTLEntry, cExtension),
TRUE, TRUE, offsetof(CTL_INFO, rgCTLEntry), 0 },
{ ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CTL_INFO, cExtension),
- CRYPT_AsnDecodeCertExtensions, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
- offsetof(CTL_INFO, rgExtension), 0 },
+ CRYPT_AsnDecodeCTLExtensions, FINALMEMBERSIZE(CTL_INFO, cExtension),
+ TRUE, TRUE, offsetof(CTL_INFO, rgExtension), 0 },
};
- TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
- pDecodePara, pvStructInfo, *pcbStructInfo);
-
ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
pcbStructInfo, NULL, NULL);
CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
offsetof(CRYPT_SMIME_CAPABILITY, Parameters.pbData), 0 },
};
- PCRYPT_SMIME_CAPABILITY capability = (PCRYPT_SMIME_CAPABILITY)pvStructInfo;
+ PCRYPT_SMIME_CAPABILITY capability = pvStructInfo;
TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo);
return ret;
}
-static BOOL CRYPT_AsnDecodeSMIMECapabilitiesInternal(const BYTE *pbEncoded,
- DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
- DWORD *pcbDecoded)
-{
- struct AsnArrayDescriptor arrayDesc = { 0,
- CRYPT_AsnDecodeSMIMECapability, sizeof(CRYPT_SMIME_CAPABILITY), TRUE,
- offsetof(CRYPT_SMIME_CAPABILITY, pszObjId) };
- PCRYPT_SMIME_CAPABILITIES capabilities =
- (PCRYPT_SMIME_CAPABILITIES)pvStructInfo;
- BOOL ret;
-
- ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
- NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
- capabilities ? capabilities->rgCapability : NULL);
- return ret;
-}
-
static BOOL WINAPI CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
__TRY
{
- DWORD bytesNeeded;
-
- if (!cbEncoded)
- SetLastError(CRYPT_E_ASN1_EOD);
- else if (pbEncoded[0] != ASN_SEQUENCEOF)
- SetLastError(CRYPT_E_ASN1_CORRUPT);
- else if ((ret = CRYPT_AsnDecodeSMIMECapabilitiesInternal(pbEncoded,
- cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
- NULL)))
- {
- if (!pvStructInfo)
- *pcbStructInfo = bytesNeeded;
- else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
- pvStructInfo, pcbStructInfo, bytesNeeded)))
- {
- PCRYPT_SMIME_CAPABILITIES capabilities;
-
- if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
- pvStructInfo = *(BYTE **)pvStructInfo;
- capabilities = (PCRYPT_SMIME_CAPABILITIES)pvStructInfo;
- capabilities->rgCapability =
- (PCRYPT_SMIME_CAPABILITY)((BYTE *)pvStructInfo +
- sizeof(CRYPT_SMIME_CAPABILITIES));
- ret = CRYPT_AsnDecodeSMIMECapabilitiesInternal(pbEncoded,
- cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
- &bytesNeeded, NULL);
+ struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
+ offsetof(CRYPT_SMIME_CAPABILITIES, cCapability),
+ offsetof(CRYPT_SMIME_CAPABILITIES, rgCapability),
+ sizeof(CRYPT_SMIME_CAPABILITIES),
+ CRYPT_AsnDecodeSMIMECapability, sizeof(CRYPT_SMIME_CAPABILITY), TRUE,
+ offsetof(CRYPT_SMIME_CAPABILITY, pszObjId) };
+
+ ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
+ dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
}
- }
+ __EXCEPT_PAGE_FAULT
+ {
+ SetLastError(STATUS_ACCESS_VIOLATION);
+ }
+ __ENDTRY
+ TRACE("returning %d\n", ret);
+ return ret;
+}
+
+static BOOL CRYPT_AsnDecodeIA5String(const BYTE *pbEncoded,
+ DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
+ DWORD *pcbDecoded)
+{
+ BOOL ret = TRUE;
+ DWORD dataLen;
+ LPSTR *pStr = pvStructInfo;
+
+ if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
+ {
+ BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
+ DWORD bytesNeeded = sizeof(LPSTR) + sizeof(char);
+
+ if (pbEncoded[0] != ASN_IA5STRING)
+ {
+ SetLastError(CRYPT_E_ASN1_CORRUPT);
+ ret = FALSE;
+ }
+ else
+ {
+ bytesNeeded += dataLen;
+ if (pcbDecoded)
+ *pcbDecoded = 1 + lenBytes + dataLen;
+ if (!pvStructInfo)
+ *pcbStructInfo = bytesNeeded;
+ else if (*pcbStructInfo < bytesNeeded)
+ {
+ *pcbStructInfo = bytesNeeded;
+ SetLastError(ERROR_MORE_DATA);
+ ret = FALSE;
+ }
+ else
+ {
+ *pcbStructInfo = bytesNeeded;
+ if (dataLen)
+ {
+ LPSTR str = *pStr;
+
+ assert(str);
+ memcpy(str, pbEncoded + 1 + lenBytes, dataLen);
+ str[dataLen] = 0;
+ }
+ else
+ *pStr = NULL;
+ }
+ }
+ }
+ return ret;
+}
+
+static BOOL CRYPT_AsnDecodeNoticeNumbers(const BYTE *pbEncoded,
+ DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
+ DWORD *pcbDecoded)
+{
+ struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
+ offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers),
+ offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, rgNoticeNumbers),
+ FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers),
+ CRYPT_AsnDecodeIntInternal, sizeof(int), FALSE, 0 };
+ BOOL ret;
+
+ TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded, cbEncoded, dwFlags,
+ pvStructInfo, pvStructInfo ? *pcbDecoded : 0);
+
+ ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
+ dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
+ TRACE("returning %d\n", ret);
+ return ret;
+}
+
+static BOOL CRYPT_AsnDecodeNoticeReference(const BYTE *pbEncoded,
+ DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
+ DWORD *pcbDecoded)
+{
+ BOOL ret;
+ struct AsnDecodeSequenceItem items[] = {
+ { ASN_IA5STRING, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
+ pszOrganization), CRYPT_AsnDecodeIA5String, sizeof(LPSTR), FALSE, TRUE,
+ offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, pszOrganization), 0 },
+ { ASN_SEQUENCEOF, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
+ cNoticeNumbers), CRYPT_AsnDecodeNoticeNumbers,
+ FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers),
+ FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
+ rgNoticeNumbers), 0 },
+ };
+ DWORD bytesNeeded;
+
+ TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
+ pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
+
+ ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ pbEncoded, cbEncoded, dwFlags, NULL, NULL, &bytesNeeded, pcbDecoded,
+ NULL);
+ if (ret)
+ {
+ /* The caller is expecting a pointer to a
+ * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas
+ * CRYPT_AsnDecodeSequence is decoding a
+ * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE. Increment the bytes
+ * needed, and decode again if the requisite space is available.
+ */
+ bytesNeeded += sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE);
+ if (!pvStructInfo)
+ *pcbStructInfo = bytesNeeded;
+ else if (*pcbStructInfo < bytesNeeded)
+ {
+ *pcbStructInfo = bytesNeeded;
+ SetLastError(ERROR_MORE_DATA);
+ ret = FALSE;
+ }
+ else
+ {
+ PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE noticeRef;
+
+ *pcbStructInfo = bytesNeeded;
+ /* The pointer (pvStructInfo) passed in points to the first dynamic
+ * pointer, so use it as the pointer to the
+ * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the
+ * appropriate offset for the first dynamic pointer within the
+ * notice reference by pointing to the first memory location past
+ * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.
+ */
+ noticeRef =
+ *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE *)pvStructInfo;
+ noticeRef->pszOrganization = (LPSTR)((LPBYTE)noticeRef +
+ sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE));
+ ret = CRYPT_AsnDecodeSequence(items,
+ sizeof(items) / sizeof(items[0]), pbEncoded, cbEncoded, dwFlags,
+ NULL, noticeRef, &bytesNeeded, pcbDecoded,
+ noticeRef->pszOrganization);
+ }
+ }
+ TRACE("returning %d\n", ret);
+ return ret;
+}
+
+static BOOL CRYPT_AsnDecodeUnicodeString(const BYTE *pbEncoded,
+ DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
+ DWORD *pcbDecoded)
+{
+ BOOL ret = TRUE;
+ DWORD dataLen;
+
+ if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
+ {
+ BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
+ DWORD bytesNeeded = sizeof(LPWSTR);
+
+ switch (pbEncoded[0])
+ {
+ case ASN_NUMERICSTRING:
+ if (dataLen)
+ bytesNeeded += (dataLen + 1) * 2;
+ break;
+ case ASN_PRINTABLESTRING:
+ if (dataLen)
+ bytesNeeded += (dataLen + 1) * 2;
+ break;
+ case ASN_IA5STRING:
+ if (dataLen)
+ bytesNeeded += (dataLen + 1) * 2;
+ break;
+ case ASN_T61STRING:
+ if (dataLen)
+ bytesNeeded += (dataLen + 1) * 2;
+ break;
+ case ASN_VIDEOTEXSTRING:
+ if (dataLen)
+ bytesNeeded += (dataLen + 1) * 2;
+ break;
+ case ASN_GRAPHICSTRING:
+ if (dataLen)
+ bytesNeeded += (dataLen + 1) * 2;
+ break;
+ case ASN_VISIBLESTRING:
+ if (dataLen)
+ bytesNeeded += (dataLen + 1) * 2;
+ break;
+ case ASN_GENERALSTRING:
+ if (dataLen)
+ bytesNeeded += (dataLen + 1) * 2;
+ break;
+ case ASN_UNIVERSALSTRING:
+ if (dataLen)
+ bytesNeeded += dataLen / 2 + sizeof(WCHAR);
+ break;
+ case ASN_BMPSTRING:
+ if (dataLen)
+ bytesNeeded += dataLen + sizeof(WCHAR);
+ break;
+ case ASN_UTF8STRING:
+ if (dataLen)
+ bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0,
+ (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2;
+ break;
+ default:
+ SetLastError(CRYPT_E_ASN1_BADTAG);
+ return FALSE;
+ }
+
+ if (pcbDecoded)
+ *pcbDecoded = 1 + lenBytes + dataLen;
+ if (!pvStructInfo)
+ *pcbStructInfo = bytesNeeded;
+ else if (*pcbStructInfo < bytesNeeded)
+ {
+ *pcbStructInfo = bytesNeeded;
+ SetLastError(ERROR_MORE_DATA);
+ ret = FALSE;
+ }
+ else
+ {
+ LPWSTR *pStr = pvStructInfo;
+
+ *pcbStructInfo = bytesNeeded;
+ if (dataLen)
+ {
+ DWORD i;
+ LPWSTR str = *(LPWSTR *)pStr;
+
+ assert(str);
+ 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:
+ for (i = 0; i < dataLen; i++)
+ str[i] = pbEncoded[1 + lenBytes + i];
+ str[i] = 0;
+ break;
+ case ASN_UNIVERSALSTRING:
+ 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:
+ 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:
+ {
+ int len = MultiByteToWideChar(CP_UTF8, 0,
+ (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
+ str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
+ str[len] = 0;
+ break;
+ }
+ }
+ }
+ else
+ *pStr = NULL;
+ }
+ }
+ return ret;
+}
+
+static BOOL CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
+ const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
+ DWORD *pcbStructInfo, DWORD *pcbDecoded)
+{
+ BOOL ret;
+ struct AsnDecodeSequenceItem items[] = {
+ { ASN_SEQUENCE, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE,
+ pNoticeReference), CRYPT_AsnDecodeNoticeReference,
+ sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE), TRUE, TRUE,
+ offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pNoticeReference), 0 },
+ { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText),
+ CRYPT_AsnDecodeUnicodeString, sizeof(LPWSTR), TRUE, TRUE,
+ offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText), 0 },
+ };
+ PCERT_POLICY_QUALIFIER_USER_NOTICE notice = pvStructInfo;
+
+ TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
+ pvStructInfo, *pcbStructInfo);
+
+ ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
+ pcbDecoded, notice ? notice->pNoticeReference : NULL);
+ TRACE("returning %d\n", ret);
+ return ret;
+}
+
+static BOOL WINAPI CRYPT_AsnDecodePolicyQualifierUserNotice(
+ DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded,
+ DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
+ void *pvStructInfo, DWORD *pcbStructInfo)
+{
+ BOOL ret = FALSE;
+
+ TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
+ pDecodePara, pvStructInfo, *pcbStructInfo);
+
+ __TRY
+ {
+ DWORD bytesNeeded;
+
+ ret = CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(pbEncoded,
+ cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
+ NULL);
+ if (ret)
+ {
+ if (!pvStructInfo)
+ *pcbStructInfo = bytesNeeded;
+ else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
+ pvStructInfo, pcbStructInfo, bytesNeeded)))
+ {
+ PCERT_POLICY_QUALIFIER_USER_NOTICE notice;
+
+ if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
+ pvStructInfo = *(BYTE **)pvStructInfo;
+ notice = pvStructInfo;
+ notice->pNoticeReference =
+ (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE)
+ ((BYTE *)pvStructInfo +
+ sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE));
+ ret = CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
+ pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
+ pvStructInfo, &bytesNeeded, NULL);
+ }
+ }
}
__EXCEPT_PAGE_FAULT
{
return ret;
}
+static BOOL CRYPT_AsnDecodePKCSAttributeValue(const BYTE *pbEncoded,
+ DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
+ DWORD *pcbDecoded)
+{
+ BOOL ret;
+ struct AsnArrayDescriptor arrayDesc = { 0,
+ offsetof(CRYPT_ATTRIBUTE, cValue), offsetof(CRYPT_ATTRIBUTE, rgValue),
+ FINALMEMBERSIZE(CRYPT_ATTRIBUTE, cValue),
+ CRYPT_AsnDecodeCopyBytes,
+ sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
+
+ TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
+ pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded);
+
+ ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
+ dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
+ return ret;
+}
+
static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded,
DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
DWORD *pcbDecoded)
CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
offsetof(CRYPT_ATTRIBUTE, pszObjId), 0 },
{ ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_ATTRIBUTE, cValue),
- CRYPT_DecodeDERArray, sizeof(struct GenericArray), FALSE, TRUE,
- offsetof(CRYPT_ATTRIBUTE, rgValue), 0 },
+ CRYPT_AsnDecodePKCSAttributeValue,
+ FINALMEMBERSIZE(CRYPT_ATTRIBUTE, cValue), FALSE,
+ TRUE, offsetof(CRYPT_ATTRIBUTE, rgValue), 0 },
};
- PCRYPT_ATTRIBUTE attr = (PCRYPT_ATTRIBUTE)pvStructInfo;
+ PCRYPT_ATTRIBUTE attr = pvStructInfo;
TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo);
if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
pvStructInfo = *(BYTE **)pvStructInfo;
- attr = (PCRYPT_ATTRIBUTE)pvStructInfo;
+ attr = pvStructInfo;
attr->pszObjId = (LPSTR)((BYTE *)pvStructInfo +
sizeof(CRYPT_ATTRIBUTE));
ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
DWORD *pcbDecoded)
{
struct AsnArrayDescriptor arrayDesc = { 0,
+ offsetof(CRYPT_ATTRIBUTES, cAttr), offsetof(CRYPT_ATTRIBUTES, rgAttr),
+ sizeof(CRYPT_ATTRIBUTES),
CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE,
offsetof(CRYPT_ATTRIBUTE, pszObjId) };
- PCRYPT_ATTRIBUTES attrs = (PCRYPT_ATTRIBUTES)pvStructInfo;
BOOL ret;
ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
- NULL, pvStructInfo, pcbStructInfo, pcbDecoded, attrs ? attrs->rgAttr :
- NULL);
+ NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
return ret;
}
__TRY
{
- DWORD bytesNeeded;
+ struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
+ offsetof(CRYPT_ATTRIBUTES, cAttr), offsetof(CRYPT_ATTRIBUTES, rgAttr),
+ sizeof(CRYPT_ATTRIBUTES),
+ CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE),
+ TRUE, offsetof(CRYPT_ATTRIBUTE, pszObjId) };
- if (!cbEncoded)
- SetLastError(CRYPT_E_ASN1_EOD);
- else if (pbEncoded[0] != (ASN_CONSTRUCTOR | ASN_SETOF))
- SetLastError(CRYPT_E_ASN1_CORRUPT);
- else if ((ret = CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded,
- cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
- NULL)))
- {
- if (!pvStructInfo)
- *pcbStructInfo = bytesNeeded;
- else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
- pvStructInfo, pcbStructInfo, bytesNeeded)))
- {
- PCRYPT_ATTRIBUTES attrs;
-
- if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
- pvStructInfo = *(BYTE **)pvStructInfo;
- attrs = (PCRYPT_ATTRIBUTES)pvStructInfo;
- attrs->rgAttr = (PCRYPT_ATTRIBUTE)((BYTE *)pvStructInfo +
- sizeof(CRYPT_ATTRIBUTES));
- ret = CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded,
- cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
- &bytesNeeded, NULL);
+ ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
+ dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
}
- }
- }
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
- CRYPT_ALGORITHM_IDENTIFIER *algo =
- (CRYPT_ALGORITHM_IDENTIFIER *)pvStructInfo;
+ CRYPT_ALGORITHM_IDENTIFIER *algo = pvStructInfo;
BOOL ret = TRUE;
struct AsnDecodeSequenceItem items[] = {
{ ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId),
CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
offsetof(CERT_PUBLIC_KEY_INFO, PublicKey.pbData) },
};
- PCERT_PUBLIC_KEY_INFO info = (PCERT_PUBLIC_KEY_INFO)pvStructInfo;
+ PCERT_PUBLIC_KEY_INFO info = pvStructInfo;
ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
pvStructInfo = *(BYTE **)pvStructInfo;
- info = (PCERT_PUBLIC_KEY_INFO)pvStructInfo;
+ info = pvStructInfo;
info->Algorithm.Parameters.pbData = (BYTE *)pvStructInfo +
sizeof(CERT_PUBLIC_KEY_INFO);
ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
static BOOL CRYPT_AsnDecodeAltNameEntry(const BYTE *pbEncoded, DWORD cbEncoded,
DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
- PCERT_ALT_NAME_ENTRY entry = (PCERT_ALT_NAME_ENTRY)pvStructInfo;
+ PCERT_ALT_NAME_ENTRY entry = pvStructInfo;
DWORD dataLen, lenBytes, bytesNeeded = sizeof(CERT_ALT_NAME_ENTRY);
BOOL ret;
case 1: /* rfc822Name */
case 2: /* dNSName */
case 6: /* uniformResourceIdentifier */
+ if (memchr(pbEncoded + 1 + lenBytes, 0, dataLen))
+ {
+ SetLastError(CRYPT_E_ASN1_RULE);
+ ret = FALSE;
+ }
+ else
bytesNeeded += (dataLen + 1) * sizeof(WCHAR);
break;
case 4: /* directoryName */
{
*pcbStructInfo = bytesNeeded;
/* MS used values one greater than the asn1 ones.. sigh */
- entry->dwAltNameChoice = (pbEncoded[0] & 0x7f) + 1;
+ entry->dwAltNameChoice = (pbEncoded[0] & ASN_TYPE_MASK) + 1;
switch (pbEncoded[0] & ASN_TYPE_MASK)
{
case 1: /* rfc822Name */
break;
}
case 4: /* directoryName */
- entry->dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
/* The data are memory-equivalent with the IPAddress case,
* fall-through
*/
DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
DWORD *pcbDecoded)
{
- BOOL ret = TRUE;
+ BOOL ret;
struct AsnArrayDescriptor arrayDesc = { 0,
+ offsetof(CERT_ALT_NAME_INFO, cAltEntry),
+ offsetof(CERT_ALT_NAME_INFO, rgAltEntry),
+ sizeof(CERT_ALT_NAME_INFO),
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, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo, pcbDecoded);
- if (info)
- TRACE("info->rgAltEntry is %p\n", info->rgAltEntry);
ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
- NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
- info ? info->rgAltEntry : NULL);
+ NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
return ret;
}
pcbDecoded);
if (ret && pvStructInfo)
{
- CRYPT_DATA_BLOB *blob = (CRYPT_DATA_BLOB *)pvStructInfo;
+ CRYPT_DATA_BLOB *blob = pvStructInfo;
if (blob->cbData)
{
CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), FALSE,
TRUE, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation.u.pwszURL), 0 },
};
- CERT_ACCESS_DESCRIPTION *descr = (CERT_ACCESS_DESCRIPTION *)pvStructInfo;
+ CERT_ACCESS_DESCRIPTION *descr = pvStructInfo;
return CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
__TRY
{
struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
+ offsetof(CERT_AUTHORITY_INFO_ACCESS, cAccDescr),
+ offsetof(CERT_AUTHORITY_INFO_ACCESS, rgAccDescr),
+ sizeof(CERT_AUTHORITY_INFO_ACCESS),
CRYPT_AsnDecodeAccessDescription, sizeof(CERT_ACCESS_DESCRIPTION),
TRUE, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod) };
- ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
- pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
+ ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
+ dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
}
__EXCEPT_PAGE_FAULT
{
DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
DWORD *pcbDecoded)
{
- CRYPT_CONTENT_INFO *info = (CRYPT_CONTENT_INFO *)pvStructInfo;
+ CRYPT_CONTENT_INFO *info = pvStructInfo;
struct AsnDecodeSequenceItem items[] = {
{ ASN_OBJECTIDENTIFIER, offsetof(CRYPT_CONTENT_INFO, pszObjId),
CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
pvStructInfo = *(BYTE **)pvStructInfo;
- info = (CRYPT_CONTENT_INFO *)pvStructInfo;
+ info = pvStructInfo;
info->pszObjId = (LPSTR)((BYTE *)info +
sizeof(CRYPT_CONTENT_INFO));
ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded,
if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
pvStructInfo = *(BYTE **)pvStructInfo;
- name = (CERT_ALT_NAME_INFO *)pvStructInfo;
+ name = pvStructInfo;
name->rgAltEntry = (PCERT_ALT_NAME_ENTRY)
((BYTE *)pvStructInfo + sizeof(CERT_ALT_NAME_INFO));
ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
}
else
{
- struct PATH_LEN_CONSTRAINT *constraint =
- (struct PATH_LEN_CONSTRAINT *)pvStructInfo;
+ struct PATH_LEN_CONSTRAINT *constraint = pvStructInfo;
*pcbStructInfo = bytesNeeded;
size = sizeof(constraint->dwPathLenConstraint);
TRACE("got an int, dwPathLenConstraint is %d\n",
constraint->dwPathLenConstraint);
}
- TRACE("returning %d (%08x)\n", ret, GetLastError());
+ TRACE("returning %d (%08x)\n", ret, GetLastError());
+ return ret;
+}
+
+static BOOL CRYPT_AsnDecodeSubtreeConstraints(const BYTE *pbEncoded,
+ DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
+ DWORD *pcbDecoded)
+{
+ BOOL ret;
+ struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
+ offsetof(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint),
+ offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint),
+ FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint),
+ CRYPT_AsnDecodeCopyBytes, sizeof(CERT_NAME_BLOB), TRUE,
+ offsetof(CERT_NAME_BLOB, pbData) };
+
+ TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
+ pvStructInfo, *pcbStructInfo, pcbDecoded);
+
+ ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
+ dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
+ TRACE("Returning %d (%08x)\n", ret, GetLastError());
+ return ret;
+}
+
+static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints(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_BITSTRING, offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType),
+ CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
+ offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType.pbData), 0 },
+ { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
+ fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
+ sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
+ { ASN_SEQUENCEOF, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
+ cSubtreesConstraint), CRYPT_AsnDecodeSubtreeConstraints,
+ FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint),
+ TRUE, TRUE,
+ offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint), 0 },
+ };
+
+ ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
+ pcbStructInfo, NULL, NULL);
+ }
+ __EXCEPT_PAGE_FAULT
+ {
+ SetLastError(STATUS_ACCESS_VIOLATION);
+ ret = FALSE;
+ }
+ __ENDTRY
+ return ret;
+}
+
+static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints2(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_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(items, sizeof(items) / sizeof(items[0]),
+ pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
+ pcbStructInfo, NULL, NULL);
+ }
+ __EXCEPT_PAGE_FAULT
+ {
+ SetLastError(STATUS_ACCESS_VIOLATION);
+ ret = FALSE;
+ }
+ __ENDTRY
+ return ret;
+}
+
+static BOOL CRYPT_AsnDecodePolicyQualifier(const BYTE *pbEncoded,
+ DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
+ DWORD *pcbDecoded)
+{
+ struct AsnDecodeSequenceItem items[] = {
+ { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_QUALIFIER_INFO,
+ pszPolicyQualifierId), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR),
+ FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_INFO, pszPolicyQualifierId),
+ 0 },
+ { 0, offsetof(CERT_POLICY_QUALIFIER_INFO, Qualifier),
+ CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
+ offsetof(CERT_POLICY_QUALIFIER_INFO, Qualifier.pbData), 0 },
+ };
+ BOOL ret;
+ CERT_POLICY_QUALIFIER_INFO *qualifier = pvStructInfo;
+
+ TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
+ pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
+
+ ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
+ pcbDecoded, qualifier ? qualifier->pszPolicyQualifierId : NULL);
+ return ret;
+}
+
+static BOOL CRYPT_AsnDecodePolicyQualifiers(const BYTE *pbEncoded,
+ DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
+ DWORD *pcbDecoded)
+{
+ BOOL ret;
+ struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
+ offsetof(CERT_POLICY_INFO, cPolicyQualifier),
+ offsetof(CERT_POLICY_INFO, rgPolicyQualifier),
+ FINALMEMBERSIZE(CERT_POLICY_INFO, cPolicyQualifier),
+ CRYPT_AsnDecodePolicyQualifier, sizeof(CERT_POLICY_QUALIFIER_INFO), TRUE,
+ offsetof(CERT_POLICY_QUALIFIER_INFO, pszPolicyQualifierId) };
+
+ TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
+ pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
+
+ ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
+ dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
+ TRACE("Returning %d (%08x)\n", ret, GetLastError());
+ return ret;
+}
+
+static BOOL CRYPT_AsnDecodeCertPolicy(const BYTE *pbEncoded, DWORD cbEncoded,
+ DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
+{
+ struct AsnDecodeSequenceItem items[] = {
+ { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_INFO, pszPolicyIdentifier),
+ CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE,
+ offsetof(CERT_POLICY_INFO, pszPolicyIdentifier), 0 },
+ { ASN_SEQUENCEOF, offsetof(CERT_POLICY_INFO, cPolicyQualifier),
+ CRYPT_AsnDecodePolicyQualifiers,
+ FINALMEMBERSIZE(CERT_POLICY_INFO, cPolicyQualifier), TRUE,
+ TRUE, offsetof(CERT_POLICY_INFO, rgPolicyQualifier), 0 },
+ };
+ CERT_POLICY_INFO *info = pvStructInfo;
+ BOOL ret;
+
+ TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
+ pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
+
+ ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
+ pcbDecoded, info ? info->pszPolicyIdentifier : NULL);
+ return ret;
+}
+
+static BOOL WINAPI CRYPT_AsnDecodeCertPolicies(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
+ PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
+{
+ BOOL ret = FALSE;
+
+ TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
+ pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
+
+ __TRY
+ {
+ struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
+ offsetof(CERT_POLICIES_INFO, cPolicyInfo),
+ offsetof(CERT_POLICIES_INFO, rgPolicyInfo),
+ sizeof(CERT_POLICIES_INFO),
+ CRYPT_AsnDecodeCertPolicy, sizeof(CERT_POLICY_INFO), TRUE,
+ offsetof(CERT_POLICY_INFO, pszPolicyIdentifier) };
+
+ ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
+ dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
+ }
+ __EXCEPT_PAGE_FAULT
+ {
+ SetLastError(STATUS_ACCESS_VIOLATION);
+ }
+ __ENDTRY
+ return ret;
+}
+
+static BOOL CRYPT_AsnDecodeCertPolicyMapping(const BYTE *pbEncoded,
+ DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
+ DWORD *pcbDecoded)
+{
+ struct AsnDecodeSequenceItem items[] = {
+ { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_MAPPING,
+ pszIssuerDomainPolicy), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR),
+ FALSE, TRUE, offsetof(CERT_POLICY_MAPPING, pszIssuerDomainPolicy), 0 },
+ { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_MAPPING,
+ pszSubjectDomainPolicy), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR),
+ FALSE, TRUE, offsetof(CERT_POLICY_MAPPING, pszSubjectDomainPolicy), 0 },
+ };
+ CERT_POLICY_MAPPING *mapping = pvStructInfo;
+ BOOL ret;
+
+ TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
+ pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
+
+ ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
+ pcbDecoded, mapping ? mapping->pszIssuerDomainPolicy : NULL);
+ return ret;
+}
+
+static BOOL WINAPI CRYPT_AsnDecodeCertPolicyMappings(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
+ PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
+{
+ BOOL ret = FALSE;
+
+ TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
+ pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
+
+ __TRY
+ {
+ struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
+ offsetof(CERT_POLICY_MAPPINGS_INFO, cPolicyMapping),
+ offsetof(CERT_POLICY_MAPPINGS_INFO, rgPolicyMapping),
+ sizeof(CERT_POLICY_MAPPING),
+ CRYPT_AsnDecodeCertPolicyMapping, sizeof(CERT_POLICY_MAPPING), TRUE,
+ offsetof(CERT_POLICY_MAPPING, pszIssuerDomainPolicy) };
+
+ ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
+ dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
+ }
+ __EXCEPT_PAGE_FAULT
+ {
+ SetLastError(STATUS_ACCESS_VIOLATION);
+ }
+ __ENDTRY
+ return ret;
+}
+
+static BOOL CRYPT_AsnDecodeRequireExplicit(const BYTE *pbEncoded,
+ DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
+ DWORD *pcbDecoded)
+{
+ BOOL ret;
+ DWORD skip, size = sizeof(skip);
+
+ if (!cbEncoded)
+ {
+ SetLastError(CRYPT_E_ASN1_EOD);
+ return FALSE;
+ }
+ if (pbEncoded[0] != (ASN_CONTEXT | 0))
+ {
+ SetLastError(CRYPT_E_ASN1_BADTAG);
+ return FALSE;
+ }
+ if ((ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
+ &skip, &size, pcbDecoded)))
+ {
+ DWORD bytesNeeded = MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO,
+ fRequireExplicitPolicy, fInhibitPolicyMapping);
+
+ if (!pvStructInfo)
+ *pcbStructInfo = bytesNeeded;
+ else if (*pcbStructInfo < bytesNeeded)
+ {
+ *pcbStructInfo = bytesNeeded;
+ SetLastError(ERROR_MORE_DATA);
+ ret = FALSE;
+ }
+ else
+ {
+ CERT_POLICY_CONSTRAINTS_INFO *info =
+ (CERT_POLICY_CONSTRAINTS_INFO *)((BYTE *)pvStructInfo -
+ offsetof(CERT_POLICY_CONSTRAINTS_INFO, fRequireExplicitPolicy));
+
+ *pcbStructInfo = bytesNeeded;
+ /* The BOOL is implicit: if the integer is present, then it's
+ * TRUE.
+ */
+ info->fRequireExplicitPolicy = TRUE;
+ info->dwRequireExplicitPolicySkipCerts = skip;
+ }
+ }
return ret;
}
-static BOOL CRYPT_AsnDecodeSubtreeConstraints(const BYTE *pbEncoded,
+static BOOL CRYPT_AsnDecodeInhibitMapping(const BYTE *pbEncoded,
DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
DWORD *pcbDecoded)
{
BOOL ret;
- struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
- CRYPT_AsnDecodeCopyBytes, sizeof(CERT_NAME_BLOB), TRUE,
- offsetof(CERT_NAME_BLOB, pbData) };
- struct GenericArray *entries = (struct GenericArray *)pvStructInfo;
-
- TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
- pvStructInfo, *pcbStructInfo, pcbDecoded);
-
- ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
- NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
- entries ? entries->rgItems : NULL);
- TRACE("Returning %d (%08x)\n", ret, GetLastError());
- return ret;
-}
-
-static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType,
- LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
- PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
-{
- BOOL ret;
+ DWORD skip, size = sizeof(skip);
- __TRY
+ if (!cbEncoded)
{
- struct AsnDecodeSequenceItem items[] = {
- { ASN_BITSTRING, offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType),
- CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
- offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType.pbData), 0 },
- { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
- fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
- sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
- { ASN_SEQUENCEOF, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
- cSubtreesConstraint), CRYPT_AsnDecodeSubtreeConstraints,
- sizeof(struct GenericArray), TRUE, TRUE,
- offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint), 0 },
- };
-
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
- pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
- pcbStructInfo, NULL, NULL);
+ SetLastError(CRYPT_E_ASN1_EOD);
+ return FALSE;
}
- __EXCEPT_PAGE_FAULT
+ if (pbEncoded[0] != (ASN_CONTEXT | 1))
{
- SetLastError(STATUS_ACCESS_VIOLATION);
- ret = FALSE;
+ SetLastError(CRYPT_E_ASN1_BADTAG);
+ return FALSE;
+ }
+ if ((ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
+ &skip, &size, pcbDecoded)))
+ {
+ DWORD bytesNeeded = FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO,
+ fInhibitPolicyMapping);
+
+ if (!pvStructInfo)
+ *pcbStructInfo = bytesNeeded;
+ else if (*pcbStructInfo < bytesNeeded)
+ {
+ *pcbStructInfo = bytesNeeded;
+ SetLastError(ERROR_MORE_DATA);
+ ret = FALSE;
+ }
+ else
+ {
+ CERT_POLICY_CONSTRAINTS_INFO *info =
+ (CERT_POLICY_CONSTRAINTS_INFO *)((BYTE *)pvStructInfo -
+ offsetof(CERT_POLICY_CONSTRAINTS_INFO, fInhibitPolicyMapping));
+
+ *pcbStructInfo = bytesNeeded;
+ /* The BOOL is implicit: if the integer is present, then it's
+ * TRUE.
+ */
+ info->fInhibitPolicyMapping = TRUE;
+ info->dwInhibitPolicyMappingSkipCerts = skip;
+ }
}
- __ENDTRY
return ret;
}
-static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType,
- LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
- PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
+static BOOL WINAPI CRYPT_AsnDecodeCertPolicyConstraints(
+ DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded,
+ DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
+ void *pvStructInfo, DWORD *pcbStructInfo)
{
- BOOL ret;
+ BOOL ret = FALSE;
+
+ TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
+ pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
__TRY
{
struct AsnDecodeSequenceItem items[] = {
- { 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 },
+ { ASN_CONTEXT | 0,
+ offsetof(CERT_POLICY_CONSTRAINTS_INFO, fRequireExplicitPolicy),
+ CRYPT_AsnDecodeRequireExplicit,
+ MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO, fRequireExplicitPolicy,
+ fInhibitPolicyMapping), TRUE, FALSE, 0, 0 },
+ { ASN_CONTEXT | 1,
+ offsetof(CERT_POLICY_CONSTRAINTS_INFO, fInhibitPolicyMapping),
+ CRYPT_AsnDecodeInhibitMapping,
+ FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO, fInhibitPolicyMapping),
+ TRUE, FALSE, 0, 0 },
};
ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
- ret = FALSE;
}
__ENDTRY
return ret;
if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
pvStructInfo = *(BYTE **)pvStructInfo;
- hdr = (BLOBHEADER *)pvStructInfo;
+ hdr = pvStructInfo;
hdr->bType = PUBLICKEYBLOB;
hdr->bVersion = CUR_BLOB_VERSION;
hdr->reserved = 0;
CRYPT_DATA_BLOB *blob;
*pcbStructInfo = bytesNeeded;
- blob = (CRYPT_DATA_BLOB *)pvStructInfo;
+ blob = pvStructInfo;
blob->cbData = dataLen;
if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
blob->pbData = (BYTE *)pbEncoded + 1 + lenBytes;
if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
pvStructInfo = *(BYTE **)pvStructInfo;
- blob = (CRYPT_DATA_BLOB *)pvStructInfo;
+ blob = pvStructInfo;
blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_DATA_BLOB);
ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
BOOL ret;
+ DWORD bytesNeeded, dataLen;
+ BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo, pcbDecoded);
- if (pbEncoded[0] == ASN_BITSTRING)
+ if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
{
- DWORD bytesNeeded, dataLen;
- BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
-
- if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
+ 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;
+ SetLastError(ERROR_MORE_DATA);
+ ret = FALSE;
+ }
+ else
{
+ CRYPT_BIT_BLOB *blob;
+
+ *pcbStructInfo = bytesNeeded;
+ blob = pvStructInfo;
+ blob->cbData = dataLen - 1;
+ blob->cUnusedBits = *(pbEncoded + 1 + lenBytes);
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;
- SetLastError(ERROR_MORE_DATA);
- ret = FALSE;
+ blob->pbData = (BYTE *)pbEncoded + 2 + lenBytes;
}
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)
- {
- blob->pbData = (BYTE *)pbEncoded + 2 + lenBytes;
- }
- else
+ assert(blob->pbData);
+ if (blob->cbData)
{
- assert(blob->pbData);
- if (blob->cbData)
- {
- BYTE mask = 0xff << blob->cUnusedBits;
+ BYTE mask = 0xff << blob->cUnusedBits;
- memcpy(blob->pbData, pbEncoded + 2 + lenBytes,
- blob->cbData);
- blob->pbData[blob->cbData - 1] &= mask;
- }
+ memcpy(blob->pbData, pbEncoded + 2 + lenBytes,
+ blob->cbData);
+ blob->pbData[blob->cbData - 1] &= mask;
}
}
}
}
- else
- {
- SetLastError(CRYPT_E_ASN1_BADTAG);
- ret = FALSE;
- }
- TRACE("returning %d (%08x)\n", ret, GetLastError());
return ret;
}
{
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)))
{
if (!pvStructInfo)
if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
pvStructInfo = *(BYTE **)pvStructInfo;
- blob = (CRYPT_BIT_BLOB *)pvStructInfo;
+ blob = pvStructInfo;
blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_BIT_BLOB);
ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
BOOL ret;
- BYTE buf[sizeof(CRYPT_INTEGER_BLOB) + sizeof(int)];
- CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf;
- DWORD size = sizeof(buf);
+ DWORD dataLen;
- blob->pbData = buf + sizeof(CRYPT_INTEGER_BLOB);
- ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded, 0, buf,
- &size, pcbDecoded);
- if (ret)
+ if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
{
- if (!pvStructInfo)
+ BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
+
+ if (pcbDecoded)
+ *pcbDecoded = 1 + lenBytes + dataLen;
+ if (dataLen > sizeof(int))
+ {
+ SetLastError(CRYPT_E_ASN1_LARGE);
+ ret = FALSE;
+ }
+ else if (!pvStructInfo)
*pcbStructInfo = sizeof(int);
else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, sizeof(int))))
{
int val, i;
- if (blob->pbData[blob->cbData - 1] & 0x80)
+ if (dataLen && pbEncoded[1 + lenBytes] & 0x80)
{
/* initialize to a negative value to sign-extend */
val = -1;
}
else
val = 0;
- for (i = 0; i < blob->cbData; i++)
+ for (i = 0; i < dataLen; i++)
{
val <<= 8;
- val |= blob->pbData[blob->cbData - i - 1];
+ val |= pbEncoded[1 + lenBytes + i];
}
memcpy(pvStructInfo, &val, sizeof(int));
}
}
- else if (GetLastError() == ERROR_MORE_DATA)
- SetLastError(CRYPT_E_ASN1_LARGE);
return ret;
}
if (!cbEncoded)
{
- SetLastError(CRYPT_E_ASN1_CORRUPT);
+ SetLastError(CRYPT_E_ASN1_EOD);
ret = FALSE;
}
else if (pbEncoded[0] != ASN_INTEGER)
}
else
{
- CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)pvStructInfo;
+ CRYPT_INTEGER_BLOB *blob = pvStructInfo;
*pcbStructInfo = bytesNeeded;
blob->cbData = dataLen;
if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
pvStructInfo = *(BYTE **)pvStructInfo;
- blob = (CRYPT_INTEGER_BLOB *)pvStructInfo;
+ blob = pvStructInfo;
blob->pbData = (BYTE *)pvStructInfo +
sizeof(CRYPT_INTEGER_BLOB);
ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
}
else
{
- CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)pvStructInfo;
+ CRYPT_INTEGER_BLOB *blob = pvStructInfo;
*pcbStructInfo = bytesNeeded;
blob->cbData = dataLen;
if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
pvStructInfo = *(BYTE **)pvStructInfo;
- blob = (CRYPT_INTEGER_BLOB *)pvStructInfo;
+ blob = pvStructInfo;
blob->pbData = (BYTE *)pvStructInfo +
sizeof(CRYPT_INTEGER_BLOB);
ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded,
*pcbStructInfo = sizeof(FILETIME);
else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo,
sizeof(FILETIME))))
- ret = SystemTimeToFileTime(&sysTime,
- (FILETIME *)pvStructInfo);
+ ret = SystemTimeToFileTime(&sysTime, pvStructInfo);
}
}
}
*pcbStructInfo = sizeof(FILETIME);
else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo,
sizeof(FILETIME))))
- ret = SystemTimeToFileTime(&sysTime,
- (FILETIME *)pvStructInfo);
+ ret = SystemTimeToFileTime(&sysTime, pvStructInfo);
}
}
}
{
if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
pvStructInfo = *(BYTE **)pvStructInfo;
- seq = (CRYPT_SEQUENCE_OF_ANY *)pvStructInfo;
+ seq = pvStructInfo;
seq->cValue = cValue;
seq->rgValue = (CRYPT_DER_BLOB *)((BYTE *)seq +
sizeof(*seq));
if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
{
struct AsnArrayDescriptor arrayDesc = {
- ASN_CONTEXT | ASN_CONSTRUCTOR | 0, CRYPT_AsnDecodeAltNameEntry,
- sizeof(CERT_ALT_NAME_ENTRY), TRUE,
+ ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
+ offsetof(CRL_DIST_POINT_NAME, u.FullName.cAltEntry),
+ offsetof(CRL_DIST_POINT_NAME, u.FullName.rgAltEntry),
+ FINALMEMBERSIZE(CRL_DIST_POINT_NAME, u),
+ CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE,
offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
DWORD nameLen;
{
ret = CRYPT_AsnDecodeArray(&arrayDesc,
pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
- 0, NULL, NULL, &nameLen, NULL, NULL);
- /* The CERT_ALT_NAME_INFO's size is included by CRYPT_AsnDecodeArray
- * as the sizeof(struct GenericArray), so don't include it in the
- * total bytes needed.
- */
+ dwFlags, NULL, NULL, &nameLen, NULL);
bytesNeeded = sizeof(CRL_DIST_POINT_NAME) + nameLen -
- sizeof(CERT_ALT_NAME_INFO);
+ FINALMEMBERSIZE(CRL_DIST_POINT_NAME, u);
}
else
bytesNeeded = sizeof(CRL_DIST_POINT_NAME);
}
else
{
- CRL_DIST_POINT_NAME *name = (CRL_DIST_POINT_NAME *)pvStructInfo;
+ CRL_DIST_POINT_NAME *name = pvStructInfo;
*pcbStructInfo = bytesNeeded;
if (dataLen)
name->dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
ret = CRYPT_AsnDecodeArray(&arrayDesc,
pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
- 0, NULL, &name->u.FullName, &nameLen, NULL,
- name->u.FullName.rgAltEntry);
+ dwFlags, NULL, &name->u.FullName.cAltEntry, &nameLen,
+ NULL);
}
else
name->dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE, TRUE,
offsetof(CRL_DIST_POINT, CRLIssuer.rgAltEntry), 0 },
};
+ CRL_DIST_POINT *point = pvStructInfo;
BOOL ret;
ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
- pcbDecoded, NULL);
+ pcbDecoded, point ? point->DistPointName.u.FullName.rgAltEntry : NULL);
return ret;
}
__TRY
{
struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
+ offsetof(CRL_DIST_POINTS_INFO, cDistPoint),
+ offsetof(CRL_DIST_POINTS_INFO, rgDistPoint),
+ sizeof(CRL_DIST_POINTS_INFO),
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, NULL);
+ ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
+ dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
}
__EXCEPT_PAGE_FAULT
{
__TRY
{
struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
+ offsetof(CERT_ENHKEY_USAGE, cUsageIdentifier),
+ offsetof(CERT_ENHKEY_USAGE, rgpszUsageIdentifier),
+ sizeof(CERT_ENHKEY_USAGE),
CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
- ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
- pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
+ ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
+ dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
}
__EXCEPT_PAGE_FAULT
{
DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
DWORD *pcbDecoded)
{
- BOOL ret = FALSE;
+ BOOL ret;
+ DWORD max, size = sizeof(max);
TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo, pcbDecoded);
SetLastError(CRYPT_E_ASN1_BADTAG);
return FALSE;
}
- /* The BOOL is implicit: if the integer is present, then it's TRUE */
- ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
- pvStructInfo ? (BYTE *)pvStructInfo + sizeof(BOOL) : NULL, pcbStructInfo,
- pcbDecoded);
- if (ret && pvStructInfo)
- *(BOOL *)pvStructInfo = TRUE;
+ if ((ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
+ &max, &size, pcbDecoded)))
+ {
+ DWORD bytesNeeded = FINALMEMBERSIZE(CERT_GENERAL_SUBTREE, fMaximum);
+
+ if (!pvStructInfo)
+ *pcbStructInfo = bytesNeeded;
+ else if (*pcbStructInfo < bytesNeeded)
+ {
+ *pcbStructInfo = bytesNeeded;
+ SetLastError(ERROR_MORE_DATA);
+ ret = FALSE;
+ }
+ else
+ {
+ CERT_GENERAL_SUBTREE *subtree = (CERT_GENERAL_SUBTREE *)
+ ((BYTE *)pvStructInfo - offsetof(CERT_GENERAL_SUBTREE, fMaximum));
+
+ *pcbStructInfo = bytesNeeded;
+ /* The BOOL is implicit: if the integer is present, then it's
+ * TRUE.
+ */
+ subtree->fMaximum = TRUE;
+ subtree->dwMaximum = max;
+ }
+ }
TRACE("returning %d\n", ret);
return ret;
}
{ ASN_CONTEXT | 0, offsetof(CERT_GENERAL_SUBTREE, dwMinimum),
CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
{ ASN_CONTEXT | 1, offsetof(CERT_GENERAL_SUBTREE, fMaximum),
- CRYPT_AsnDecodeMaximum, sizeof(BOOL) + sizeof(DWORD), TRUE, FALSE, 0,
- 0 },
+ CRYPT_AsnDecodeMaximum, FINALMEMBERSIZE(CERT_GENERAL_SUBTREE, fMaximum),
+ TRUE, FALSE, 0, 0 },
};
- CERT_GENERAL_SUBTREE *subtree = (CERT_GENERAL_SUBTREE *)pvStructInfo;
+ CERT_GENERAL_SUBTREE *subtree = pvStructInfo;
TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo, pcbDecoded);
ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
- pcbDecoded, subtree ? (BYTE *)subtree->Base.u.pwszURL : NULL);
+ pcbDecoded, subtree ? subtree->Base.u.pwszURL : NULL);
if (pcbDecoded)
{
TRACE("%d\n", *pcbDecoded);
return ret;
}
-static BOOL CRYPT_AsnDecodeSubtreeArray(const BYTE *pbEncoded,
+static BOOL CRYPT_AsnDecodePermittedSubtree(const BYTE *pbEncoded,
DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
DWORD *pcbDecoded)
{
BOOL ret = TRUE;
struct AsnArrayDescriptor arrayDesc = { 0,
+ offsetof(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree),
+ offsetof(CERT_NAME_CONSTRAINTS_INFO, rgPermittedSubtree),
+ MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree,
+ cExcludedSubtree),
CRYPT_AsnDecodeSubtree, sizeof(CERT_GENERAL_SUBTREE), TRUE,
offsetof(CERT_GENERAL_SUBTREE, Base.u.pwszURL) };
- struct GenericArray *array = (struct GenericArray *)pvStructInfo;
TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo, pcbDecoded);
- ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
- NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
- array ? array->rgItems : NULL);
+ ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
+ dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
return ret;
}
+static BOOL CRYPT_AsnDecodeExcludedSubtree(const BYTE *pbEncoded,
+ DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
+ DWORD *pcbDecoded)
+{
+ BOOL ret = TRUE;
+ struct AsnArrayDescriptor arrayDesc = { 0,
+ offsetof(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
+ offsetof(CERT_NAME_CONSTRAINTS_INFO, rgExcludedSubtree),
+ FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
+ CRYPT_AsnDecodeSubtree, sizeof(CERT_GENERAL_SUBTREE), TRUE,
+ offsetof(CERT_GENERAL_SUBTREE, Base.u.pwszURL) };
+
+ TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
+ pvStructInfo, *pcbStructInfo, pcbDecoded);
+
+ ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
+ dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
+ return ret;
+}
static BOOL WINAPI CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
struct AsnDecodeSequenceItem items[] = {
{ ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
offsetof(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree),
- CRYPT_AsnDecodeSubtreeArray, sizeof(struct GenericArray), TRUE, TRUE,
+ CRYPT_AsnDecodePermittedSubtree,
+ MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree,
+ cExcludedSubtree), TRUE, TRUE,
offsetof(CERT_NAME_CONSTRAINTS_INFO, rgPermittedSubtree), 0 },
{ ASN_CONTEXT | ASN_CONSTRUCTOR | 1,
offsetof(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
- CRYPT_AsnDecodeSubtreeArray, sizeof(struct GenericArray), TRUE, TRUE,
+ CRYPT_AsnDecodeExcludedSubtree,
+ FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
+ TRUE, TRUE,
offsetof(CERT_NAME_CONSTRAINTS_INFO, rgExcludedSubtree), 0 },
};
CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber.pbData), 0 },
};
- CERT_ISSUER_SERIAL_NUMBER *issuerSerial =
- (CERT_ISSUER_SERIAL_NUMBER *)pvStructInfo;
+ CERT_ISSUER_SERIAL_NUMBER *issuerSerial = pvStructInfo;
TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo, pcbDecoded);
DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
DWORD *pcbDecoded)
{
- CMSG_SIGNER_INFO *info = (CMSG_SIGNER_INFO *)pvStructInfo;
+ CMSG_SIGNER_INFO *info = pvStructInfo;
struct AsnDecodeSequenceItem items[] = {
{ ASN_INTEGER, offsetof(CMSG_SIGNER_INFO, dwVersion),
CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
pvStructInfo = *(BYTE **)pvStructInfo;
- info = (CMSG_SIGNER_INFO *)pvStructInfo;
+ info = pvStructInfo;
info->Issuer.pbData = ((BYTE *)info +
sizeof(CMSG_SIGNER_INFO));
ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded,
return ret;
}
+static BOOL CRYPT_AsnDecodeCMSCertEncoded(const BYTE *pbEncoded,
+ DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
+ DWORD *pcbDecoded)
+{
+ BOOL ret;
+ struct AsnArrayDescriptor arrayDesc = { 0,
+ offsetof(CRYPT_SIGNED_INFO, cCertEncoded),
+ offsetof(CRYPT_SIGNED_INFO, rgCertEncoded),
+ MEMBERSIZE(CRYPT_SIGNED_INFO, cCertEncoded, cCrlEncoded),
+ CRYPT_AsnDecodeCopyBytes,
+ sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
+
+ TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
+ pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded);
+
+ ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
+ dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
+ return ret;
+}
+
+static BOOL CRYPT_AsnDecodeCMSCrlEncoded(const BYTE *pbEncoded,
+ DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
+ DWORD *pcbDecoded)
+{
+ BOOL ret;
+ struct AsnArrayDescriptor arrayDesc = { 0,
+ offsetof(CRYPT_SIGNED_INFO, cCrlEncoded),
+ offsetof(CRYPT_SIGNED_INFO, rgCrlEncoded),
+ MEMBERSIZE(CRYPT_SIGNED_INFO, cCrlEncoded, content),
+ CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_DER_BLOB),
+ TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
+
+ TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
+ pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded);
+
+ ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
+ dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
+ return ret;
+}
+
static BOOL CRYPT_AsnDecodeCMSSignerId(const BYTE *pbEncoded,
DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
DWORD *pcbDecoded)
{
- CERT_ID *id = (CERT_ID *)pvStructInfo;
+ CERT_ID *id = pvStructInfo;
BOOL ret = FALSE;
if (*pbEncoded == ASN_SEQUENCEOF)
DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
DWORD *pcbDecoded)
{
- CMSG_CMS_SIGNER_INFO *info = (CMSG_CMS_SIGNER_INFO *)pvStructInfo;
+ CMSG_CMS_SIGNER_INFO *info = pvStructInfo;
struct AsnDecodeSequenceItem items[] = {
{ ASN_INTEGER, offsetof(CMSG_CMS_SIGNER_INFO, dwVersion),
CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
pvStructInfo = *(BYTE **)pvStructInfo;
- info = (CMSG_CMS_SIGNER_INFO *)pvStructInfo;
+ info = pvStructInfo;
info->SignerId.u.KeyId.pbData = ((BYTE *)info +
sizeof(CMSG_CMS_SIGNER_INFO));
ret = CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded,
{
BOOL ret;
struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
+ offsetof(CRYPT_SIGNED_INFO, cSignerInfo),
+ offsetof(CRYPT_SIGNED_INFO, rgSignerInfo),
+ FINALMEMBERSIZE(CRYPT_SIGNED_INFO, cSignerInfo),
CRYPT_AsnDecodeCMSSignerInfoInternal, sizeof(CMSG_CMS_SIGNER_INFO), TRUE,
offsetof(CMSG_CMS_SIGNER_INFO, SignerId.u.KeyId.pbData) };
- struct GenericArray *array = (struct GenericArray *)pvStructInfo;
TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo, pcbDecoded);
- ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
- NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
- array ? array->rgItems : NULL);
+ ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
+ dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
return ret;
}
CRYPT_AsnDecodePKCSContentInfoInternal, sizeof(CRYPT_CONTENT_INFO),
FALSE, TRUE, offsetof(CRYPT_SIGNED_INFO, content.pszObjId), 0 },
{ ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
- offsetof(CRYPT_SIGNED_INFO, cCertEncoded),
- CRYPT_DecodeDERArray, sizeof(struct GenericArray), TRUE, TRUE,
+ offsetof(CRYPT_SIGNED_INFO, cCertEncoded), CRYPT_AsnDecodeCMSCertEncoded,
+ MEMBERSIZE(CRYPT_SIGNED_INFO, cCertEncoded, cCrlEncoded), TRUE, TRUE,
offsetof(CRYPT_SIGNED_INFO, rgCertEncoded), 0 },
{ ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
- offsetof(CRYPT_SIGNED_INFO, cCrlEncoded), CRYPT_DecodeDERArray,
- sizeof(struct GenericArray), TRUE, TRUE,
+ offsetof(CRYPT_SIGNED_INFO, cCrlEncoded), CRYPT_AsnDecodeCMSCrlEncoded,
+ MEMBERSIZE(CRYPT_SIGNED_INFO, cCrlEncoded, content), TRUE, TRUE,
offsetof(CRYPT_SIGNED_INFO, rgCrlEncoded), 0 },
{ ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_SIGNED_INFO, cSignerInfo),
- CRYPT_DecodeSignerArray, sizeof(struct GenericArray), TRUE, TRUE,
+ CRYPT_DecodeSignerArray,
+ FINALMEMBERSIZE(CRYPT_SIGNED_INFO, cSignerInfo), TRUE, TRUE,
offsetof(CRYPT_SIGNED_INFO, rgSignerInfo), 0 },
};
case LOWORD(X509_BASIC_CONSTRAINTS2):
decodeFunc = CRYPT_AsnDecodeBasicConstraints2;
break;
+ case LOWORD(X509_CERT_POLICIES):
+ decodeFunc = CRYPT_AsnDecodeCertPolicies;
+ break;
case LOWORD(RSA_CSP_PUBLICKEYBLOB):
decodeFunc = CRYPT_AsnDecodeRsaPubKey;
break;
case LOWORD(PKCS_SMIME_CAPABILITIES):
decodeFunc = CRYPT_AsnDecodeSMIMECapabilities;
break;
+ case LOWORD(X509_PKIX_POLICY_QUALIFIER_USERNOTICE):
+ decodeFunc = CRYPT_AsnDecodePolicyQualifierUserNotice;
+ break;
case LOWORD(PKCS_ATTRIBUTES):
decodeFunc = CRYPT_AsnDecodePKCSAttributes;
break;
case LOWORD(X509_NAME_CONSTRAINTS):
decodeFunc = CRYPT_AsnDecodeNameConstraints;
break;
+ case LOWORD(X509_POLICY_MAPPINGS):
+ decodeFunc = CRYPT_AsnDecodeCertPolicyMappings;
+ break;
+ case LOWORD(X509_POLICY_CONSTRAINTS):
+ decodeFunc = CRYPT_AsnDecodeCertPolicyConstraints;
+ break;
case LOWORD(PKCS7_SIGNER_INFO):
decodeFunc = CRYPT_AsnDecodePKCSSignerInfo;
break;
decodeFunc = CRYPT_AsnDecodeSMIMECapabilities;
else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER))
decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
+ else if (!strcmp(lpszStructType, szOID_LEGACY_POLICY_MAPPINGS))
+ decodeFunc = CRYPT_AsnDecodeCertPolicyMappings;
else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER2))
decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2;
else if (!strcmp(lpszStructType, szOID_CRL_REASON_CODE))
decodeFunc = CRYPT_AsnDecodeAltName;
else if (!strcmp(lpszStructType, szOID_CRL_DIST_POINTS))
decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
+ else if (!strcmp(lpszStructType, szOID_CERT_POLICIES))
+ decodeFunc = CRYPT_AsnDecodeCertPolicies;
+ else if (!strcmp(lpszStructType, szOID_POLICY_MAPPINGS))
+ decodeFunc = CRYPT_AsnDecodeCertPolicyMappings;
+ else if (!strcmp(lpszStructType, szOID_POLICY_CONSTRAINTS))
+ decodeFunc = CRYPT_AsnDecodeCertPolicyConstraints;
else if (!strcmp(lpszStructType, szOID_ENHANCED_KEY_USAGE))
decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
else if (!strcmp(lpszStructType, szOID_ISSUING_DIST_POINT))
decodeFunc = CRYPT_AsnDecodeNameConstraints;
else if (!strcmp(lpszStructType, szOID_AUTHORITY_INFO_ACCESS))
decodeFunc = CRYPT_AsnDecodeAuthorityInfoAccess;
+ else if (!strcmp(lpszStructType, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE))
+ decodeFunc = CRYPT_AsnDecodePolicyQualifierUserNotice;
else if (!strcmp(lpszStructType, szOID_CTL))
decodeFunc = CRYPT_AsnDecodeCTL;
return decodeFunc;
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
- if (!cbEncoded)
- {
- SetLastError(CRYPT_E_ASN1_EOD);
- return FALSE;
- }
if (cbEncoded > MAX_ENCODED_LEN)
{
SetLastError(CRYPT_E_ASN1_LARGE);
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
- if (!cbEncoded)
- {
- SetLastError(CRYPT_E_ASN1_EOD);
- return FALSE;
- }
if (cbEncoded > MAX_ENCODED_LEN)
{
SetLastError(CRYPT_E_ASN1_LARGE);
TRACE_(crypt)("returning %d\n", ret);
return ret;
}
+
+BOOL WINAPI PFXIsPFXBlob(CRYPT_DATA_BLOB *pPFX)
+{
+ BOOL ret;
+
+ TRACE_(crypt)("(%p)\n", pPFX);
+
+ /* A PFX blob is an asn.1-encoded sequence, consisting of at least a
+ * version integer of length 1 (3 encoded byes) and at least one other
+ * datum (two encoded bytes), plus at least two bytes for the outer
+ * sequence. Thus, even an empty PFX blob is at least 7 bytes in length.
+ */
+ if (pPFX->cbData < 7)
+ ret = FALSE;
+ else if (pPFX->pbData[0] == ASN_SEQUENCE)
+ {
+ DWORD len;
+
+ if ((ret = CRYPT_GetLengthIndefinite(pPFX->pbData, pPFX->cbData, &len)))
+ {
+ BYTE lenLen = GET_LEN_BYTES(pPFX->pbData[1]);
+
+ /* Need at least three bytes for the integer version */
+ if (pPFX->cbData < 1 + lenLen + 3)
+ ret = FALSE;
+ else if (pPFX->pbData[1 + lenLen] != ASN_INTEGER || /* Tag */
+ pPFX->pbData[1 + lenLen + 1] != 1 || /* Definite length */
+ pPFX->pbData[1 + lenLen + 2] != 3) /* PFX version */
+ ret = FALSE;
+ }
+ }
+ else
+ ret = FALSE;
+ return ret;
+}
+
+HCERTSTORE WINAPI PFXImportCertStore(CRYPT_DATA_BLOB *pPFX, LPCWSTR szPassword,
+ DWORD dwFlags)
+{
+ FIXME_(crypt)("(%p, %p, %08x): stub\n", pPFX, szPassword, dwFlags);
+ return NULL;
+}