📄 decode.c
字号:
else
{
assert(blob->pbData);
memcpy(blob->pbData, pbEncoded, blob->cbData);
}
}
else
{
SetLastError(CRYPT_E_ASN1_CORRUPT);
ret = FALSE;
}
}
}
return ret;
}
/* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
static BOOL WINAPI CRYPT_AsnDecodeBitsSwapBytes(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
BOOL ret;
TRACE("(%p, %d, 0x%08x, %p, %p, %d)\n", pbEncoded, cbEncoded, dwFlags,
pDecodePara, pvStructInfo, *pcbStructInfo);
/* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
* place.
*/
ret = CRYPT_AsnDecodeBitsInternal(dwCertEncodingType, lpszStructType,
pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pDecodePara,
pvStructInfo, pcbStructInfo);
if (ret && pvStructInfo)
{
CRYPT_BIT_BLOB *blob = (CRYPT_BIT_BLOB *)pvStructInfo;
if (blob->cbData)
{
DWORD i;
BYTE temp;
for (i = 0; i < blob->cbData / 2; i++)
{
temp = blob->pbData[i];
blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
blob->pbData[blob->cbData - i - 1] = temp;
}
}
}
TRACE("returning %d (%08x)\n", ret, GetLastError());
return ret;
}
static BOOL WINAPI CRYPT_AsnDecodeCertSignedContent(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);
__TRY
{
struct AsnDecodeSequenceItem items[] = {
{ 0, offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned),
CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_DER_BLOB), FALSE, TRUE,
offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned.pbData), 0 },
{ ASN_SEQUENCEOF, offsetof(CERT_SIGNED_CONTENT_INFO,
SignatureAlgorithm), CRYPT_AsnDecodeAlgorithmId,
sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE,
offsetof(CERT_SIGNED_CONTENT_INFO, SignatureAlgorithm.pszObjId), 0 },
{ ASN_BITSTRING, offsetof(CERT_SIGNED_CONTENT_INFO, Signature),
CRYPT_AsnDecodeBitsSwapBytes, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
offsetof(CERT_SIGNED_CONTENT_INFO, Signature.pbData), 0 },
};
if (dwFlags & CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG)
items[2].decodeFunc = CRYPT_AsnDecodeBitsInternal;
ret = CRYPT_AsnDecodeSequence(dwCertEncodingType, items,
sizeof(items) / sizeof(items[0]), pbEncoded, cbEncoded, dwFlags,
pDecodePara, pvStructInfo, pcbStructInfo, NULL);
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
ret = FALSE;
}
__ENDTRY
TRACE("Returning %d (%08x)\n", ret, GetLastError());
return ret;
}
/* Internal function */
static BOOL WINAPI CRYPT_AsnDecodeCertVersion(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
BOOL ret;
DWORD dataLen;
if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
{
BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
ret = CRYPT_AsnDecodeInt(dwCertEncodingType, X509_INTEGER,
pbEncoded + 1 + lenBytes, dataLen, dwFlags, pDecodePara,
pvStructInfo, pcbStructInfo);
}
return ret;
}
static BOOL WINAPI CRYPT_AsnDecodeValidity(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
BOOL ret;
struct AsnDecodeSequenceItem items[] = {
{ 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotBefore),
CRYPT_AsnDecodeChoiceOfTime, sizeof(FILETIME), FALSE, FALSE, 0 },
{ 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotAfter),
CRYPT_AsnDecodeChoiceOfTime, sizeof(FILETIME), FALSE, FALSE, 0 },
};
ret = CRYPT_AsnDecodeSequence(dwCertEncodingType, items,
sizeof(items) / sizeof(items[0]), pbEncoded, cbEncoded, dwFlags,
pDecodePara, pvStructInfo, pcbStructInfo, NULL);
return ret;
}
/* Internal function */
static BOOL WINAPI CRYPT_AsnDecodeCertExtensions(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
BOOL ret;
DWORD dataLen;
if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
{
BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
ret = CRYPT_AsnDecodeExtensionsInternal(dwCertEncodingType,
X509_EXTENSIONS, pbEncoded + 1 + lenBytes, dataLen, dwFlags,
pDecodePara, pvStructInfo, pcbStructInfo);
}
return ret;
}
static BOOL WINAPI CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
BOOL ret = TRUE;
struct AsnDecodeSequenceItem items[] = {
{ ASN_CONTEXT | ASN_CONSTRUCTOR, offsetof(CERT_INFO, dwVersion),
CRYPT_AsnDecodeCertVersion, sizeof(DWORD), TRUE, FALSE, 0, 0 },
{ ASN_INTEGER, offsetof(CERT_INFO, SerialNumber),
CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
TRUE, offsetof(CERT_INFO, SerialNumber.pbData), 0 },
{ ASN_SEQUENCEOF, offsetof(CERT_INFO, SignatureAlgorithm),
CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
FALSE, TRUE, offsetof(CERT_INFO, SignatureAlgorithm.pszObjId), 0 },
{ 0, offsetof(CERT_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
Issuer.pbData) },
{ ASN_SEQUENCEOF, offsetof(CERT_INFO, NotBefore),
CRYPT_AsnDecodeValidity, sizeof(CERT_PRIVATE_KEY_VALIDITY), FALSE,
FALSE, 0 },
{ 0, offsetof(CERT_INFO, Subject), CRYPT_AsnDecodeDerBlob,
sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
Subject.pbData) },
{ ASN_SEQUENCEOF, offsetof(CERT_INFO, SubjectPublicKeyInfo),
CRYPT_AsnDecodePubKeyInfoInternal, sizeof(CERT_PUBLIC_KEY_INFO),
FALSE, TRUE, offsetof(CERT_INFO,
SubjectPublicKeyInfo.Algorithm.Parameters.pbData), 0 },
{ ASN_BITSTRING, offsetof(CERT_INFO, IssuerUniqueId),
CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
offsetof(CERT_INFO, IssuerUniqueId.pbData), 0 },
{ ASN_BITSTRING, offsetof(CERT_INFO, SubjectUniqueId),
CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
offsetof(CERT_INFO, SubjectUniqueId.pbData), 0 },
{ ASN_CONTEXT | ASN_CONSTRUCTOR | 3, offsetof(CERT_INFO, cExtension),
CRYPT_AsnDecodeCertExtensions, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
offsetof(CERT_INFO, rgExtension), 0 },
};
TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pDecodePara, pvStructInfo, *pcbStructInfo);
ret = CRYPT_AsnDecodeSequence(dwCertEncodingType, items,
sizeof(items) / sizeof(items[0]), pbEncoded, cbEncoded, dwFlags,
pDecodePara, pvStructInfo, pcbStructInfo, NULL);
TRACE("Returning %d (%08x)\n", ret, GetLastError());
return ret;
}
static BOOL WINAPI CRYPT_AsnDecodeCert(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);
__TRY
{
PCERT_SIGNED_CONTENT_INFO signedCert = NULL;
DWORD size = 0;
/* First try to decode it as a signed cert. */
ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType, X509_CERT,
pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
(BYTE *)&signedCert, &size);
if (ret)
{
size = 0;
ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
X509_CERT_TO_BE_SIGNED, signedCert->ToBeSigned.pbData,
signedCert->ToBeSigned.cbData, dwFlags, pDecodePara, pvStructInfo,
pcbStructInfo);
LocalFree(signedCert);
}
/* Failing that, try it as an unsigned cert */
if (!ret)
{
size = 0;
ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
X509_CERT_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_AsnDecodeCRLEntry(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
BOOL ret;
struct AsnDecodeSequenceItem items[] = {
{ ASN_INTEGER, offsetof(CRL_ENTRY, SerialNumber),
CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE, TRUE,
offsetof(CRL_ENTRY, SerialNumber.pbData), 0 },
{ 0, offsetof(CRL_ENTRY, RevocationDate), CRYPT_AsnDecodeChoiceOfTime,
sizeof(FILETIME), FALSE, FALSE, 0 },
{ ASN_SEQUENCEOF, offsetof(CRL_ENTRY, cExtension),
CRYPT_AsnDecodeExtensionsInternal, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
offsetof(CRL_ENTRY, rgExtension), 0 },
};
PCRL_ENTRY entry = (PCRL_ENTRY)pvStructInfo;
TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
*pcbStructInfo);
ret = CRYPT_AsnDecodeSequence(X509_ASN_ENCODING, items,
sizeof(items) / sizeof(items[0]), pbEncoded, cbEncoded, dwFlags,
NULL, entry, pcbStructInfo, entry ? entry->SerialNumber.pbData : NULL);
return ret;
}
/* Warning: assumes pvStructInfo is a struct GenericArray whose rgItems has
* been set prior to calling.
*/
static BOOL WINAPI CRYPT_AsnDecodeCRLEntries(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
BOOL ret;
struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
CRYPT_AsnDecodeCRLEntry, sizeof(CRL_ENTRY), TRUE,
offsetof(CRL_ENTRY, SerialNumber.pbData) };
struct GenericArray *entries = (struct GenericArray *)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,
entries ? entries->rgItems : NULL);
TRACE("Returning %d (%08x)\n", ret, GetLastError());
return ret;
}
static BOOL WINAPI CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
struct AsnDecodeSequenceItem items[] = {
{ ASN_INTEGER, offsetof(CRL_INFO, dwVersion),
CRYPT_AsnDecodeInt, sizeof(DWORD), TRUE, FALSE, 0, 0 },
{ ASN_SEQUENCEOF, offsetof(CRL_INFO, SignatureAlgorithm),
CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
FALSE, TRUE, offsetof(CRL_INFO, SignatureAlgorithm.pszObjId), 0 },
{ 0, offsetof(CRL_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CRL_INFO,
Issuer.pbData) },
{ 0, offsetof(CRL_INFO, ThisUpdate), CRYPT_AsnDecodeChoiceOfTime,
sizeof(FILETIME), FALSE, FALSE, 0 },
{ 0, offsetof(CRL_INFO, NextUpdate), CRYPT_AsnDecodeChoiceOfTime,
sizeof(FILETIME), TRUE, FALSE, 0 },
{ ASN_SEQUENCEOF, offsetof(CRL_INFO, cCRLEntry),
CRYPT_AsnDecodeCRLEntries, sizeof(struct GenericArray), 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 },
};
BOOL ret = TRUE;
TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pDecodePara, pvStructInfo, *pcbStructInfo);
ret = CRYPT_AsnDecodeSequence(dwCertEncodingType, items,
sizeof(items) / sizeof(items[0]), pbEncoded, cbEncoded, dwFlags,
pDecodePara, pvStructInfo, pcbStructInfo, NULL);
TRACE("Returning %d (%08x)\n", ret, GetLastError());
return ret;
}
static BOOL WINAPI CRYPT_AsnDecodeCRL(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,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -