encode.c
来自「一个类似windows」· C语言 代码 · 共 1,906 行 · 第 1/5 页
C
1,906 行
}
static BOOL WINAPI CRYPT_AsnEncodeRsaPubKey(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret;
__TRY
{
const BLOBHEADER *hdr =
(const BLOBHEADER *)pvStructInfo;
if (hdr->bType != PUBLICKEYBLOB)
{
SetLastError(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER));
ret = FALSE;
}
else
{
const RSAPUBKEY *rsaPubKey = (const RSAPUBKEY *)
((const BYTE *)pvStructInfo + sizeof(BLOBHEADER));
CRYPT_INTEGER_BLOB blob = { rsaPubKey->bitlen / 8,
(BYTE *)pvStructInfo + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) };
struct AsnEncodeSequenceItem items[] = {
{ &blob, CRYPT_AsnEncodeUnsignedInteger, 0 },
{ &rsaPubKey->pubexp, CRYPT_AsnEncodeInt, 0 },
};
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_AsnEncodeOctets(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret;
__TRY
{
const CRYPT_DATA_BLOB *blob = (const CRYPT_DATA_BLOB *)pvStructInfo;
DWORD bytesNeeded, lenBytes;
TRACE("(%ld, %p), %08lx, %p, %p, %ld\n", blob->cbData, blob->pbData,
dwFlags, pEncodePara, pbEncoded, *pcbEncoded);
CRYPT_EncodeLen(blob->cbData, NULL, &lenBytes);
bytesNeeded = 1 + lenBytes + blob->cbData;
if (!pbEncoded)
{
*pcbEncoded = bytesNeeded;
ret = TRUE;
}
else
{
if ((ret = CRYPT_EncodeEnsureSpace(dwFlags, pEncodePara, pbEncoded,
pcbEncoded, bytesNeeded)))
{
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
pbEncoded = *(BYTE **)pbEncoded;
*pbEncoded++ = ASN_OCTETSTRING;
CRYPT_EncodeLen(blob->cbData, pbEncoded, &lenBytes);
pbEncoded += lenBytes;
if (blob->cbData)
memcpy(pbEncoded, blob->pbData, blob->cbData);
}
}
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
ret = FALSE;
}
__ENDTRY
TRACE("returning %d (%08lx)\n", ret, GetLastError());
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeBits(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret;
__TRY
{
const CRYPT_BIT_BLOB *blob = (const CRYPT_BIT_BLOB *)pvStructInfo;
DWORD bytesNeeded, lenBytes, dataBytes;
BYTE unusedBits;
/* yep, MS allows cUnusedBits to be >= 8 */
if (!blob->cUnusedBits)
{
dataBytes = blob->cbData;
unusedBits = 0;
}
else if (blob->cbData * 8 > blob->cUnusedBits)
{
dataBytes = (blob->cbData * 8 - blob->cUnusedBits) / 8 + 1;
unusedBits = blob->cUnusedBits >= 8 ? blob->cUnusedBits / 8 :
blob->cUnusedBits;
}
else
{
dataBytes = 0;
unusedBits = 0;
}
CRYPT_EncodeLen(dataBytes + 1, NULL, &lenBytes);
bytesNeeded = 1 + lenBytes + dataBytes + 1;
if (!pbEncoded)
{
*pcbEncoded = bytesNeeded;
ret = TRUE;
}
else
{
if ((ret = CRYPT_EncodeEnsureSpace(dwFlags, pEncodePara, pbEncoded,
pcbEncoded, bytesNeeded)))
{
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
pbEncoded = *(BYTE **)pbEncoded;
*pbEncoded++ = ASN_BITSTRING;
CRYPT_EncodeLen(dataBytes + 1, pbEncoded, &lenBytes);
pbEncoded += lenBytes;
*pbEncoded++ = unusedBits;
if (dataBytes)
{
BYTE mask = 0xff << unusedBits;
if (dataBytes > 1)
{
memcpy(pbEncoded, blob->pbData, dataBytes - 1);
pbEncoded += dataBytes - 1;
}
*pbEncoded = *(blob->pbData + dataBytes - 1) & mask;
}
}
}
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
ret = FALSE;
}
__ENDTRY
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeBitsSwapBytes(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret;
__TRY
{
const CRYPT_BIT_BLOB *blob = (const CRYPT_BIT_BLOB *)pvStructInfo;
CRYPT_BIT_BLOB newBlob = { blob->cbData, NULL, blob->cUnusedBits };
ret = TRUE;
if (newBlob.cbData)
{
newBlob.pbData = CryptMemAlloc(newBlob.cbData);
if (newBlob.pbData)
{
DWORD i;
for (i = 0; i < newBlob.cbData; i++)
newBlob.pbData[newBlob.cbData - i - 1] = blob->pbData[i];
}
else
ret = FALSE;
}
if (ret)
ret = CRYPT_AsnEncodeBits(dwCertEncodingType, lpszStructType,
&newBlob, dwFlags, pEncodePara, pbEncoded, pcbEncoded);
CryptMemFree(newBlob.pbData);
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
ret = FALSE;
}
__ENDTRY
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeInt(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
CRYPT_INTEGER_BLOB blob = { sizeof(INT), (BYTE *)pvStructInfo };
return CRYPT_AsnEncodeInteger(dwCertEncodingType, X509_MULTI_BYTE_INTEGER,
&blob, dwFlags, pEncodePara, pbEncoded, pcbEncoded);
}
static BOOL WINAPI CRYPT_AsnEncodeInteger(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret;
__TRY
{
DWORD significantBytes, lenBytes;
BYTE padByte = 0, bytesNeeded;
BOOL pad = FALSE;
const CRYPT_INTEGER_BLOB *blob =
(const CRYPT_INTEGER_BLOB *)pvStructInfo;
significantBytes = blob->cbData;
if (significantBytes)
{
if (blob->pbData[significantBytes - 1] & 0x80)
{
/* negative, lop off leading (little-endian) 0xffs */
for (; significantBytes > 0 &&
blob->pbData[significantBytes - 1] == 0xff; significantBytes--)
;
if (blob->pbData[significantBytes - 1] < 0x80)
{
padByte = 0xff;
pad = TRUE;
}
}
else
{
/* positive, lop off leading (little-endian) zeroes */
for (; significantBytes > 0 &&
!blob->pbData[significantBytes - 1]; significantBytes--)
;
if (significantBytes == 0)
significantBytes = 1;
if (blob->pbData[significantBytes - 1] > 0x7f)
{
padByte = 0;
pad = TRUE;
}
}
}
if (pad)
CRYPT_EncodeLen(significantBytes + 1, NULL, &lenBytes);
else
CRYPT_EncodeLen(significantBytes, NULL, &lenBytes);
bytesNeeded = 1 + lenBytes + significantBytes;
if (pad)
bytesNeeded++;
if (!pbEncoded)
{
*pcbEncoded = bytesNeeded;
ret = TRUE;
}
else
{
if ((ret = CRYPT_EncodeEnsureSpace(dwFlags, pEncodePara, pbEncoded,
pcbEncoded, bytesNeeded)))
{
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
pbEncoded = *(BYTE **)pbEncoded;
*pbEncoded++ = ASN_INTEGER;
if (pad)
{
CRYPT_EncodeLen(significantBytes + 1, pbEncoded, &lenBytes);
pbEncoded += lenBytes;
*pbEncoded++ = padByte;
}
else
{
CRYPT_EncodeLen(significantBytes, pbEncoded, &lenBytes);
pbEncoded += lenBytes;
}
for (; significantBytes > 0; significantBytes--)
*(pbEncoded++) = blob->pbData[significantBytes - 1];
}
}
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
ret = FALSE;
}
__ENDTRY
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeUnsignedInteger(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret;
__TRY
{
DWORD significantBytes, lenBytes;
BYTE bytesNeeded;
BOOL pad = FALSE;
const CRYPT_INTEGER_BLOB *blob =
(const CRYPT_INTEGER_BLOB *)pvStructInfo;
significantBytes = blob->cbData;
if (significantBytes)
{
/* positive, lop off leading (little-endian) zeroes */
for (; significantBytes > 0 && !blob->pbData[significantBytes - 1];
significantBytes--)
;
if (significantBytes == 0)
significantBytes = 1;
if (blob->pbData[significantBytes - 1] > 0x7f)
pad = TRUE;
}
if (pad)
CRYPT_EncodeLen(significantBytes + 1, NULL, &lenBytes);
else
CRYPT_EncodeLen(significantBytes, NULL, &lenBytes);
bytesNeeded = 1 + lenBytes + significantBytes;
if (pad)
bytesNeeded++;
if (!pbEncoded)
{
*pcbEncoded = bytesNeeded;
ret = TRUE;
}
else
{
if ((ret = CRYPT_EncodeEnsureSpace(dwFlags, pEncodePara, pbEncoded,
pcbEncoded, bytesNeeded)))
{
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
pbEncoded = *(BYTE **)pbEncoded;
*pbEncoded++ = ASN_INTEGER;
if (pad)
{
CRYPT_EncodeLen(significantBytes + 1, pbEncoded, &lenBytes);
pbEncoded += lenBytes;
*pbEncoded++ = 0;
}
else
{
CRYPT_EncodeLen(significantBytes, pbEncoded, &lenBytes);
pbEncoded += lenBytes;
}
for (; significantBytes > 0; significantBytes--)
*(pbEncoded++) = blob->pbData[significantBytes - 1];
}
}
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
ret = FALSE;
}
__ENDTRY
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeEnumerated(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
CRYPT_INTEGER_BLOB blob;
BOOL ret;
/* Encode as an unsigned integer, then change the tag to enumerated */
blob.cbData = sizeof(DWORD);
blob.pb
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?