📄 encode.c
字号:
BOOL ret;
if (!pbEncoded)
{
*pcbEncoded = blob->cbData;
ret = TRUE;
}
else
{
if ((ret = CRYPT_EncodeEnsureSpace(dwFlags, pEncodePara, pbEncoded,
pcbEncoded, blob->cbData)))
{
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
pbEncoded = *(BYTE **)pbEncoded;
if (blob->cbData)
memcpy(pbEncoded, blob->pbData, blob->cbData);
*pcbEncoded = blob->cbData;
ret = TRUE;
}
}
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeValidity(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret;
/* This has two filetimes in a row, a NotBefore and a NotAfter */
const FILETIME *timePtr = (const FILETIME *)pvStructInfo;
struct AsnEncodeSequenceItem items[] = {
{ timePtr++, CRYPT_AsnEncodeChoiceOfTime, 0 },
{ timePtr, CRYPT_AsnEncodeChoiceOfTime, 0 },
};
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
pcbEncoded);
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeAlgorithmId(
DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo,
DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded,
DWORD *pcbEncoded)
{
const CRYPT_ALGORITHM_IDENTIFIER *algo =
(const CRYPT_ALGORITHM_IDENTIFIER *)pvStructInfo;
BOOL ret;
struct AsnEncodeSequenceItem items[] = {
{ algo->pszObjId, CRYPT_AsnEncodeOid, 0 },
{ &algo->Parameters, CRYPT_CopyEncodedBlob, 0 },
};
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
pcbEncoded);
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodePubKeyInfo(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret;
__TRY
{
const CERT_PUBLIC_KEY_INFO *info =
(const CERT_PUBLIC_KEY_INFO *)pvStructInfo;
struct AsnEncodeSequenceItem items[] = {
{ &info->Algorithm, CRYPT_AsnEncodeAlgorithmId, 0 },
{ &info->PublicKey, CRYPT_AsnEncodeBits, 0 },
};
TRACE("Encoding public key with OID %s\n",
debugstr_a(info->Algorithm.pszObjId));
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
pcbEncoded);
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
ret = FALSE;
}
__ENDTRY
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeCert(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret;
__TRY
{
const CERT_SIGNED_CONTENT_INFO *info =
(const CERT_SIGNED_CONTENT_INFO *)pvStructInfo;
struct AsnEncodeSequenceItem items[] = {
{ &info->ToBeSigned, CRYPT_CopyEncodedBlob, 0 },
{ &info->SignatureAlgorithm, CRYPT_AsnEncodeAlgorithmId, 0 },
{ &info->Signature, CRYPT_AsnEncodeBitsSwapBytes, 0 },
};
if (dwFlags & CRYPT_ENCODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG)
items[2].encodeFunc = CRYPT_AsnEncodeBits;
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
pcbEncoded);
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
ret = FALSE;
}
__ENDTRY
return ret;
}
/* Like in Windows, this blithely ignores the validity of the passed-in
* CERT_INFO, and just encodes it as-is. The resulting encoded data may not
* decode properly, see CRYPT_AsnDecodeCertInfo.
*/
static BOOL WINAPI CRYPT_AsnEncodeCertInfo(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret;
__TRY
{
const CERT_INFO *info = (const CERT_INFO *)pvStructInfo;
struct AsnEncodeSequenceItem items[10] = {
{ &info->dwVersion, CRYPT_AsnEncodeCertVersion, 0 },
{ &info->SerialNumber, CRYPT_AsnEncodeInteger, 0 },
{ &info->SignatureAlgorithm, CRYPT_AsnEncodeAlgorithmId, 0 },
{ &info->Issuer, CRYPT_CopyEncodedBlob, 0 },
{ &info->NotBefore, CRYPT_AsnEncodeValidity, 0 },
{ &info->Subject, CRYPT_CopyEncodedBlob, 0 },
{ &info->SubjectPublicKeyInfo, CRYPT_AsnEncodePubKeyInfo, 0 },
{ 0 }
};
struct AsnConstructedItem constructed[3] = { { 0 } };
DWORD cItem = 7, cConstructed = 0;
if (info->IssuerUniqueId.cbData)
{
constructed[cConstructed].tag = 1;
constructed[cConstructed].pvStructInfo = &info->IssuerUniqueId;
constructed[cConstructed].encodeFunc = CRYPT_AsnEncodeBits;
items[cItem].pvStructInfo = &constructed[cConstructed];
items[cItem].encodeFunc = CRYPT_AsnEncodeConstructed;
cConstructed++;
cItem++;
}
if (info->SubjectUniqueId.cbData)
{
constructed[cConstructed].tag = 2;
constructed[cConstructed].pvStructInfo = &info->SubjectUniqueId;
constructed[cConstructed].encodeFunc = CRYPT_AsnEncodeBits;
items[cItem].pvStructInfo = &constructed[cConstructed];
items[cItem].encodeFunc = CRYPT_AsnEncodeConstructed;
cConstructed++;
cItem++;
}
if (info->cExtension)
{
constructed[cConstructed].tag = 3;
constructed[cConstructed].pvStructInfo = &info->cExtension;
constructed[cConstructed].encodeFunc = CRYPT_AsnEncodeExtensions;
items[cItem].pvStructInfo = &constructed[cConstructed];
items[cItem].encodeFunc = CRYPT_AsnEncodeConstructed;
cConstructed++;
cItem++;
}
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, cItem,
dwFlags, pEncodePara, pbEncoded, pcbEncoded);
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
ret = FALSE;
}
__ENDTRY
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeCRLEntry(const CRL_ENTRY *entry,
BYTE *pbEncoded, DWORD *pcbEncoded)
{
struct AsnEncodeSequenceItem items[3] = {
{ &entry->SerialNumber, CRYPT_AsnEncodeInteger, 0 },
{ &entry->RevocationDate, CRYPT_AsnEncodeChoiceOfTime, 0 },
{ 0 }
};
DWORD cItem = 2;
BOOL ret;
TRACE("%p, %p, %p\n", entry, pbEncoded, pcbEncoded);
if (entry->cExtension)
{
items[cItem].pvStructInfo = &entry->cExtension;
items[cItem].encodeFunc = CRYPT_AsnEncodeExtensions;
cItem++;
}
ret = CRYPT_AsnEncodeSequence(X509_ASN_ENCODING, items, cItem, 0, NULL,
pbEncoded, pcbEncoded);
TRACE("returning %d (%08x)\n", ret, GetLastError());
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeCRLEntries(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
DWORD cCRLEntry = *(const DWORD *)pvStructInfo;
DWORD bytesNeeded, dataLen, lenBytes, i;
const CRL_ENTRY *rgCRLEntry = *(const CRL_ENTRY *const *)
((const BYTE *)pvStructInfo + sizeof(DWORD));
BOOL ret = TRUE;
for (i = 0, dataLen = 0; ret && i < cCRLEntry; i++)
{
DWORD size;
ret = CRYPT_AsnEncodeCRLEntry(&rgCRLEntry[i], NULL, &size);
if (ret)
dataLen += size;
}
CRYPT_EncodeLen(dataLen, NULL, &lenBytes);
bytesNeeded = 1 + lenBytes + dataLen;
if (!pbEncoded)
*pcbEncoded = bytesNeeded;
else
{
if ((ret = CRYPT_EncodeEnsureSpace(dwFlags, pEncodePara, pbEncoded,
pcbEncoded, bytesNeeded)))
{
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
pbEncoded = *(BYTE **)pbEncoded;
*pbEncoded++ = ASN_SEQUENCEOF;
CRYPT_EncodeLen(dataLen, pbEncoded, &lenBytes);
pbEncoded += lenBytes;
for (i = 0; i < cCRLEntry; i++)
{
DWORD size = dataLen;
ret = CRYPT_AsnEncodeCRLEntry(&rgCRLEntry[i], pbEncoded, &size);
pbEncoded += size;
dataLen -= size;
}
}
}
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeCRLVersion(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
const DWORD *ver = (const DWORD *)pvStructInfo;
BOOL ret;
/* CRL_V1 is not encoded */
if (*ver == CRL_V1)
{
*pcbEncoded = 0;
ret = TRUE;
}
else
ret = CRYPT_AsnEncodeInt(dwCertEncodingType, X509_INTEGER, ver,
dwFlags, pEncodePara, pbEncoded, pcbEncoded);
return ret;
}
/* Like in Windows, this blithely ignores the validity of the passed-in
* CRL_INFO, and just encodes it as-is. The resulting encoded data may not
* decode properly, see CRYPT_AsnDecodeCRLInfo.
*/
static BOOL WINAPI CRYPT_AsnEncodeCRLInfo(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret;
__TRY
{
const CRL_INFO *info = (const CRL_INFO *)pvStructInfo;
struct AsnEncodeSequenceItem items[7] = {
{ &info->dwVersion, CRYPT_AsnEncodeCRLVersion, 0 },
{ &info->SignatureAlgorithm, CRYPT_AsnEncodeAlgorithmId, 0 },
{ &info->Issuer, CRYPT_CopyEncodedBlob, 0 },
{ &info->ThisUpdate, CRYPT_AsnEncodeChoiceOfTime, 0 },
{ 0 }
};
struct AsnConstructedItem constructed[1] = { { 0 } };
DWORD cItem = 4, cConstructed = 0;
if (info->NextUpdate.dwLowDateTime || info->NextUpdate.dwHighDateTime)
{
items[cItem].pvStructInfo = &info->NextUpdate;
items[cItem].encodeFunc = CRYPT_AsnEncodeChoiceOfTime;
cItem++;
}
if (info->cCRLEntry)
{
items[cItem].pvStructInfo = &info->cCRLEntry;
items[cItem].encodeFunc = CRYPT_AsnEncodeCRLEntries;
cItem++;
}
if (info->cExtension)
{
constructed[cConstructed].tag = 0;
constructed[cConstructed].pvStructInfo = &info->cExtension;
constructed[cConstructed].encodeFunc = CRYPT_AsnEncodeExtensions;
items[cItem].pvStructInfo = &constructed[cConstructed];
items[cItem].encodeFunc = CRYPT_AsnEncodeConstructed;
cConstructed++;
cItem++;
}
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, cItem,
dwFlags, pEncodePara, pbEncoded, pcbEncoded);
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
ret = FALSE;
}
__ENDTRY
return ret;
}
static BOOL CRYPT_AsnEncodeExtension(CERT_EXTENSION *ext, BYTE *pbEncoded,
DWORD *pcbEncoded)
{
BOOL ret;
struct AsnEncodeSequenceItem items[3] = {
{ ext->pszObjId, CRYPT_AsnEncodeOid, 0 },
{ NULL, NULL, 0 },
{ NULL, NULL, 0 },
};
DWORD cItem = 1;
TRACE("%p, %p, %d\n", ext, pbEncoded, *pcbEncoded);
if (ext->fCritical)
{
items[cItem].pvStructInfo = &ext->fCritical;
items[cItem].encodeFunc = CRYPT_AsnEncodeBool;
cItem++;
}
items[cItem].pvStructInfo = &ext->Value;
items[cItem].encodeFunc = CRYPT_AsnEncodeOctets;
cItem++;
ret = CRYPT_AsnEncodeSequence(X509_ASN_ENCODING, items, cItem, 0, NULL,
pbEncoded, pcbEncoded);
TRACE("returning %d (%08x)\n", ret, GetLastError());
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeExtensions(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret;
__TRY
{
DWORD bytesNeeded, dataLen, lenBytes, i;
const CERT_EXTENSIONS *exts = (const CERT_EXTENSIONS *)pvStructInfo;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -