📄 decode.c
字号:
pDecodePara, pvStructInfo, *pcbStructInfo);
__TRY
{
PCERT_SIGNED_CONTENT_INFO signedCrl = NULL;
DWORD size = 0;
/* First try to decode it as a signed crl. */
ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType, X509_CERT,
pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
(BYTE *)&signedCrl, &size);
if (ret)
{
size = 0;
ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
X509_CERT_CRL_TO_BE_SIGNED, signedCrl->ToBeSigned.pbData,
signedCrl->ToBeSigned.cbData, dwFlags, pDecodePara,
pvStructInfo, pcbStructInfo);
LocalFree(signedCrl);
}
/* Failing that, try it as an unsigned crl */
if (!ret)
{
size = 0;
ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
X509_CERT_CRL_TO_BE_SIGNED, pbEncoded, cbEncoded,
dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
}
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
ret = FALSE;
}
__ENDTRY
TRACE("Returning %d (%08x)\n", ret, GetLastError());
return ret;
}
static BOOL WINAPI CRYPT_AsnDecodeOidInternal(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, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pDecodePara, pvStructInfo, *pcbStructInfo);
if (pbEncoded[0] == ASN_OBJECTIDENTIFIER)
{
DWORD dataLen;
if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
{
BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
DWORD bytesNeeded = sizeof(LPSTR);
if (dataLen)
{
/* The largest possible string for the first two components
* is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
*/
char firstTwo[6];
const BYTE *ptr;
snprintf(firstTwo, sizeof(firstTwo), "%d.%d",
pbEncoded[1 + lenBytes] / 40,
pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] / 40)
* 40);
bytesNeeded += strlen(firstTwo) + 1;
for (ptr = pbEncoded + 2 + lenBytes; ret &&
ptr - pbEncoded - 1 - lenBytes < dataLen; )
{
/* large enough for ".4000000" */
char str[9];
int val = 0;
while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
(*ptr & 0x80))
{
val <<= 7;
val |= *ptr & 0x7f;
ptr++;
}
if (ptr - pbEncoded - 1 - lenBytes >= dataLen ||
(*ptr & 0x80))
{
SetLastError(CRYPT_E_ASN1_CORRUPT);
ret = FALSE;
}
else
{
val <<= 7;
val |= *ptr++;
snprintf(str, sizeof(str), ".%d", val);
bytesNeeded += strlen(str);
}
}
}
if (!pvStructInfo)
*pcbStructInfo = bytesNeeded;
else if (*pcbStructInfo < bytesNeeded)
{
*pcbStructInfo = bytesNeeded;
SetLastError(ERROR_MORE_DATA);
ret = FALSE;
}
else
{
if (dataLen)
{
const BYTE *ptr;
LPSTR pszObjId = *(LPSTR *)pvStructInfo;
*pszObjId = 0;
sprintf(pszObjId, "%d.%d", pbEncoded[1 + lenBytes] / 40,
pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] /
40) * 40);
pszObjId += strlen(pszObjId);
for (ptr = pbEncoded + 2 + lenBytes; ret &&
ptr - pbEncoded - 1 - lenBytes < dataLen; )
{
int val = 0;
while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
(*ptr & 0x80))
{
val <<= 7;
val |= *ptr & 0x7f;
ptr++;
}
val <<= 7;
val |= *ptr++;
sprintf(pszObjId, ".%d", val);
pszObjId += strlen(pszObjId);
}
}
else
*(LPSTR *)pvStructInfo = NULL;
*pcbStructInfo = bytesNeeded;
}
}
}
return ret;
}
/* Warning: assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set
* ahead of time!
*/
static BOOL WINAPI CRYPT_AsnDecodeExtension(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
struct AsnDecodeSequenceItem items[] = {
{ ASN_OBJECTIDENTIFIER, offsetof(CERT_EXTENSION, pszObjId),
CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE,
offsetof(CERT_EXTENSION, pszObjId), 0 },
{ ASN_BOOL, offsetof(CERT_EXTENSION, fCritical), CRYPT_AsnDecodeBool,
sizeof(BOOL), TRUE, FALSE, 0, 0 },
{ ASN_OCTETSTRING, offsetof(CERT_EXTENSION, Value),
CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_OBJID_BLOB), FALSE, TRUE,
offsetof(CERT_EXTENSION, Value.pbData) },
};
BOOL ret = TRUE;
PCERT_EXTENSION ext = (PCERT_EXTENSION)pvStructInfo;
TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, ext,
*pcbStructInfo);
if (ext)
TRACE("ext->pszObjId is %p\n", ext->pszObjId);
ret = CRYPT_AsnDecodeSequence(X509_ASN_ENCODING, items,
sizeof(items) / sizeof(items[0]), pbEncoded, cbEncoded, dwFlags, NULL,
ext, pcbStructInfo, ext ? ext->pszObjId : NULL);
if (ext)
TRACE("ext->pszObjId is %p (%s)\n", ext->pszObjId,
debugstr_a(ext->pszObjId));
TRACE("returning %d (%08x)\n", ret, GetLastError());
return ret;
}
static BOOL WINAPI CRYPT_AsnDecodeExtensionsInternal(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
BOOL ret = TRUE;
struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
offsetof(CERT_EXTENSION, pszObjId) };
PCERT_EXTENSIONS exts = (PCERT_EXTENSIONS)pvStructInfo;
TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pDecodePara, pvStructInfo, *pcbStructInfo);
ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
pDecodePara, pvStructInfo, pcbStructInfo, 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;
__TRY
{
ret = CRYPT_AsnDecodeExtensionsInternal(dwCertEncodingType,
lpszStructType, pbEncoded, cbEncoded,
dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL, pcbStructInfo);
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(dwCertEncodingType,
lpszStructType, pbEncoded, cbEncoded,
dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pvStructInfo,
pcbStructInfo);
}
}
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
ret = FALSE;
}
__ENDTRY
return ret;
}
/* Warning: this assumes the address of value->Value.pbData is already set, in
* order to avoid overwriting memory. (In some cases, it may change it, if it
* doesn't copy anything to memory.) Be sure to set it correctly!
*/
static BOOL WINAPI CRYPT_AsnDecodeNameValueInternal(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
BOOL ret = TRUE;
DWORD dataLen;
CERT_NAME_VALUE *value = (CERT_NAME_VALUE *)pvStructInfo;
if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
{
BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
switch (pbEncoded[0])
{
case ASN_OCTETSTRING:
valueType = CERT_RDN_OCTET_STRING;
if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
bytesNeeded += dataLen;
break;
case ASN_NUMERICSTRING:
valueType = CERT_RDN_NUMERIC_STRING;
if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
bytesNeeded += dataLen;
break;
case ASN_PRINTABLESTRING:
valueType = CERT_RDN_PRINTABLE_STRING;
if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
bytesNeeded += dataLen;
break;
case ASN_IA5STRING:
valueType = CERT_RDN_IA5_STRING;
if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
bytesNeeded += dataLen;
break;
case ASN_T61STRING:
valueType = CERT_RDN_T61_STRING;
if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
bytesNeeded += dataLen;
break;
case ASN_VIDEOTEXSTRING:
valueType = CERT_RDN_VIDEOTEX_STRING;
if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
bytesNeeded += dataLen;
break;
case ASN_GRAPHICSTRING:
valueType = CERT_RDN_GRAPHIC_STRING;
if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
bytesNeeded += dataLen;
break;
case ASN_VISIBLESTRING:
valueType = CERT_RDN_VISIBLE_STRING;
if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
bytesNeeded += dataLen;
break;
case ASN_GENERALSTRING:
valueType = CERT_RDN_GENERAL_STRING;
if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
bytesNeeded += dataLen;
break;
case ASN_UNIVERSALSTRING:
FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
SetLastError(CRYPT_E_ASN1_BADTAG);
return FALSE;
case ASN_BMPSTRING:
valueType = CERT_RDN_BMP_STRING;
bytesNeeded += dataLen;
break;
case ASN_UTF8STRING:
valueType = CERT_RDN_UTF8_STRING;
bytesNeeded += MultiByteToWideChar(CP_UTF8, 0,
(LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * 2;
break;
default:
SetLastError(CRYPT_E_ASN1_BADTAG);
return FALSE;
}
if (!value)
*pcbStructInfo = bytesNeeded;
else if (*pcbStructInfo < bytesNeeded)
{
*pcbStructInfo = bytesNeeded;
SetLastError(ERROR_MORE_DATA);
ret = FALSE;
}
else
{
*pcbStructInfo = bytesNeeded;
value->dwValueType = valueType;
if (dataLen)
{
DWORD i;
assert(value->Value.pbData);
switch (pbEncoded[0])
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -