📄 encode.c
字号:
pbEncoded += size;
size = bytesNeeded - 1 - lenBytes - size;
ret = nameValueEncodeFunc(dwCertEncodingType,
NULL, (CERT_NAME_VALUE *)&attr->dwValueType,
0, NULL, pbEncoded, &size);
if (!ret)
*pcbEncoded = size;
}
}
}
if (ret)
*pcbEncoded = bytesNeeded;
}
else
{
/* Have to propagate index of failing character */
*pcbEncoded = size;
}
}
return ret;
}
static int BLOBComp(const void *l, const void *r)
{
const CRYPT_DER_BLOB *a = (const CRYPT_DER_BLOB *)l, *b = (const CRYPT_DER_BLOB *)r;
int ret;
if (!(ret = memcmp(a->pbData, b->pbData, min(a->cbData, b->cbData))))
ret = a->cbData - b->cbData;
return ret;
}
/* This encodes as a SET OF, which in DER must be lexicographically sorted.
*/
static BOOL WINAPI CRYPT_AsnEncodeRdn(DWORD dwCertEncodingType, CERT_RDN *rdn,
CryptEncodeObjectExFunc nameValueEncodeFunc, BYTE *pbEncoded,
DWORD *pcbEncoded)
{
BOOL ret;
CRYPT_DER_BLOB *blobs = NULL;
__TRY
{
DWORD bytesNeeded = 0, lenBytes, i;
blobs = NULL;
ret = TRUE;
if (rdn->cRDNAttr)
{
blobs = CryptMemAlloc(rdn->cRDNAttr * sizeof(CRYPT_DER_BLOB));
if (!blobs)
ret = FALSE;
else
memset(blobs, 0, rdn->cRDNAttr * sizeof(CRYPT_DER_BLOB));
}
for (i = 0; ret && i < rdn->cRDNAttr; i++)
{
ret = CRYPT_AsnEncodeRdnAttr(dwCertEncodingType, &rdn->rgRDNAttr[i],
nameValueEncodeFunc, NULL, &blobs[i].cbData);
if (ret)
bytesNeeded += blobs[i].cbData;
else
{
/* Have to propagate index of failing character */
*pcbEncoded = blobs[i].cbData;
}
}
if (ret)
{
CRYPT_EncodeLen(bytesNeeded, NULL, &lenBytes);
bytesNeeded += 1 + lenBytes;
if (pbEncoded)
{
if (*pcbEncoded < bytesNeeded)
{
SetLastError(ERROR_MORE_DATA);
ret = FALSE;
}
else
{
for (i = 0; ret && i < rdn->cRDNAttr; i++)
{
blobs[i].pbData = CryptMemAlloc(blobs[i].cbData);
if (!blobs[i].pbData)
ret = FALSE;
else
{
ret = CRYPT_AsnEncodeRdnAttr(dwCertEncodingType,
&rdn->rgRDNAttr[i], nameValueEncodeFunc,
blobs[i].pbData, &blobs[i].cbData);
if (!ret)
*pcbEncoded = blobs[i].cbData;
}
}
if (ret)
{
qsort(blobs, rdn->cRDNAttr, sizeof(CRYPT_DER_BLOB),
BLOBComp);
*pbEncoded++ = ASN_CONSTRUCTOR | ASN_SETOF;
CRYPT_EncodeLen(bytesNeeded - lenBytes - 1, pbEncoded,
&lenBytes);
pbEncoded += lenBytes;
for (i = 0; ret && i < rdn->cRDNAttr; i++)
{
memcpy(pbEncoded, blobs[i].pbData, blobs[i].cbData);
pbEncoded += blobs[i].cbData;
}
}
}
}
if (ret)
*pcbEncoded = bytesNeeded;
}
if (blobs)
{
for (i = 0; i < rdn->cRDNAttr; i++)
CryptMemFree(blobs[i].pbData);
}
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
ret = FALSE;
}
__ENDTRY
CryptMemFree(blobs);
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeUnicodeNameValue(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded);
static BOOL WINAPI CRYPT_AsnEncodeOrCopyUnicodeNameValue(
DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo,
DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded,
DWORD *pcbEncoded)
{
const CERT_NAME_VALUE *value = (const CERT_NAME_VALUE *)pvStructInfo;
BOOL ret;
if (value->dwValueType == CERT_RDN_ENCODED_BLOB)
ret = CRYPT_CopyEncodedBlob(dwCertEncodingType, NULL, &value->Value,
dwFlags, pEncodePara, pbEncoded, pcbEncoded);
else
ret = CRYPT_AsnEncodeUnicodeNameValue(dwCertEncodingType, NULL, value,
dwFlags, pEncodePara, pbEncoded, pcbEncoded);
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeUnicodeName(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret = TRUE;
__TRY
{
const CERT_NAME_INFO *info = (const CERT_NAME_INFO *)pvStructInfo;
DWORD bytesNeeded = 0, lenBytes, size, i;
TRACE("encoding name with %d RDNs\n", info->cRDN);
ret = TRUE;
for (i = 0; ret && i < info->cRDN; i++)
{
ret = CRYPT_AsnEncodeRdn(dwCertEncodingType, &info->rgRDN[i],
CRYPT_AsnEncodeOrCopyUnicodeNameValue, NULL, &size);
if (ret)
bytesNeeded += size;
else
*pcbEncoded = size;
}
CRYPT_EncodeLen(bytesNeeded, NULL, &lenBytes);
bytesNeeded += 1 + lenBytes;
if (ret)
{
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(bytesNeeded - lenBytes - 1, pbEncoded,
&lenBytes);
pbEncoded += lenBytes;
for (i = 0; ret && i < info->cRDN; i++)
{
size = bytesNeeded;
ret = CRYPT_AsnEncodeRdn(dwCertEncodingType,
&info->rgRDN[i], CRYPT_AsnEncodeOrCopyUnicodeNameValue,
pbEncoded, &size);
if (ret)
{
pbEncoded += size;
bytesNeeded -= size;
}
else
*pcbEncoded = size;
}
}
}
}
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
ret = FALSE;
}
__ENDTRY
return ret;
}
static BOOL CRYPT_AsnEncodeUnicodeStringCoerce(const CERT_NAME_VALUE *value,
BYTE tag, DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded,
DWORD *pcbEncoded)
{
BOOL ret = TRUE;
LPCWSTR str = (LPCWSTR)value->Value.pbData;
DWORD bytesNeeded, lenBytes, encodedLen;
encodedLen = value->Value.cbData ? value->Value.cbData / sizeof(WCHAR) :
lstrlenW(str);
CRYPT_EncodeLen(encodedLen, NULL, &lenBytes);
bytesNeeded = 1 + lenBytes + encodedLen;
if (!pbEncoded)
*pcbEncoded = bytesNeeded;
else
{
if ((ret = CRYPT_EncodeEnsureSpace(dwFlags, pEncodePara,
pbEncoded, pcbEncoded, bytesNeeded)))
{
DWORD i;
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
pbEncoded = *(BYTE **)pbEncoded;
*pbEncoded++ = tag;
CRYPT_EncodeLen(encodedLen, pbEncoded, &lenBytes);
pbEncoded += lenBytes;
for (i = 0; i < encodedLen; i++)
*pbEncoded++ = (BYTE)str[i];
}
}
return ret;
}
static BOOL CRYPT_AsnEncodeNumericString(const CERT_NAME_VALUE *value,
DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded,
DWORD *pcbEncoded)
{
BOOL ret = TRUE;
LPCWSTR str = (LPCWSTR)value->Value.pbData;
DWORD bytesNeeded, lenBytes, encodedLen;
encodedLen = value->Value.cbData ? value->Value.cbData / sizeof(WCHAR) :
lstrlenW(str);
CRYPT_EncodeLen(encodedLen, NULL, &lenBytes);
bytesNeeded = 1 + lenBytes + encodedLen;
if (!pbEncoded)
*pcbEncoded = bytesNeeded;
else
{
if ((ret = CRYPT_EncodeEnsureSpace(dwFlags, pEncodePara,
pbEncoded, pcbEncoded, bytesNeeded)))
{
DWORD i;
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
pbEncoded = *(BYTE **)pbEncoded;
*pbEncoded++ = ASN_NUMERICSTRING;
CRYPT_EncodeLen(encodedLen, pbEncoded, &lenBytes);
pbEncoded += lenBytes;
for (i = 0; ret && i < encodedLen; i++)
{
if (isdigitW(str[i]))
*pbEncoded++ = (BYTE)str[i];
else
{
*pcbEncoded = i;
SetLastError(CRYPT_E_INVALID_NUMERIC_STRING);
ret = FALSE;
}
}
}
}
return ret;
}
static inline int isprintableW(WCHAR wc)
{
return isalnumW(wc) || isspaceW(wc) || wc == '\'' || wc == '(' ||
wc == ')' || wc == '+' || wc == ',' || wc == '-' || wc == '.' ||
wc == '/' || wc == ':' || wc == '=' || wc == '?';
}
static BOOL CRYPT_AsnEncodePrintableString(const CERT_NAME_VALUE *value,
DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded,
DWORD *pcbEncoded)
{
BOOL ret = TRUE;
LPCWSTR str = (LPCWSTR)value->Value.pbData;
DWORD bytesNeeded, lenBytes, encodedLen;
encodedLen = value->Value.cbData ? value->Value.cbData / sizeof(WCHAR) :
lstrlenW(str);
CRYPT_EncodeLen(encodedLen, NULL, &lenBytes);
bytesNeeded = 1 + lenBytes + encodedLen;
if (!pbEncoded)
*pcbEncoded = bytesNeeded;
else
{
if ((ret = CRYPT_EncodeEnsureSpace(dwFlags, pEncodePara,
pbEncoded, pcbEncoded, bytesNeeded)))
{
DWORD i;
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
pbEncoded = *(BYTE **)pbEncoded;
*pbEncoded++ = ASN_PRINTABLESTRING;
CRYPT_EncodeLen(encodedLen, pbEncoded, &lenBytes);
pbEncoded += lenBytes;
for (i = 0; ret && i < encodedLen; i++)
{
if (isprintableW(str[i]))
*pbEncoded++ = (BYTE)str[i];
else
{
*pcbEncoded = i;
SetLastError(CRYPT_E_INVALID_PRINTABLE_STRING);
ret = FALSE;
}
}
}
}
return ret;
}
static BOOL CRYPT_AsnEncodeIA5String(const CERT_NAME_VALUE *value,
DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded,
DWORD *pcbEncoded)
{
BOOL ret = TRUE;
LPCWSTR str = (LPCWSTR)value->Value.pbData;
DWORD bytesNeeded, lenBytes, encodedLen;
encodedLen = value->Value.cbData ? value->Value.cbData / sizeof(WCHAR) :
lstrlenW(str);
CRYPT_EncodeLen(encodedLen, NULL, &lenBytes);
bytesNeeded = 1 + lenBytes + encodedLen;
if (!pbEncoded)
*pcbEncoded = bytesNeeded;
else
{
if ((ret = CRYPT_EncodeEnsureSpace(dwFlags, pEncodePara,
pbEncoded, pcbEncoded, bytesNeeded)))
{
DWORD i;
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
pbEncoded = *(BYTE **)pbEncoded;
*pbEncoded++ = ASN_IA5STRING;
CRYPT_EncodeLen(encodedLen, pbEncoded, &lenBytes);
pbEncoded += lenBytes;
for (i = 0; ret && i < encodedLen; i++)
{
if (str[i] <= 0x7f)
*pbEncoded++ = (BYTE)str[i];
else
{
*pcbEncoded = i;
SetLastError(CRYPT_E_INVALID_IA5_STRING);
ret = FALSE;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -