📄 encode.c
字号:
return ret;
}
static BOOL CRYPT_AsnEncodeUniversalString(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, strLen;
/* FIXME: doesn't handle composite characters */
strLen = value->Value.cbData ? value->Value.cbData / sizeof(WCHAR) :
lstrlenW(str);
CRYPT_EncodeLen(strLen * 4, NULL, &lenBytes);
bytesNeeded = 1 + lenBytes + strLen * 4;
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_UNIVERSALSTRING;
CRYPT_EncodeLen(strLen * 4, pbEncoded, &lenBytes);
pbEncoded += lenBytes;
for (i = 0; i < strLen; i++)
{
*pbEncoded++ = 0;
*pbEncoded++ = 0;
*pbEncoded++ = (BYTE)((str[i] & 0xff00) >> 8);
*pbEncoded++ = (BYTE)(str[i] & 0x00ff);
}
}
}
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeUnicodeNameValue(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret = FALSE;
__TRY
{
const CERT_NAME_VALUE *value = (const CERT_NAME_VALUE *)pvStructInfo;
switch (value->dwValueType)
{
case CERT_RDN_ANY_TYPE:
case CERT_RDN_ENCODED_BLOB:
case CERT_RDN_OCTET_STRING:
SetLastError(CRYPT_E_NOT_CHAR_STRING);
break;
case CERT_RDN_NUMERIC_STRING:
ret = CRYPT_AsnEncodeNumericString(value, dwFlags, pEncodePara,
pbEncoded, pcbEncoded);
break;
case CERT_RDN_PRINTABLE_STRING:
ret = CRYPT_AsnEncodePrintableString(value, dwFlags, pEncodePara,
pbEncoded, pcbEncoded);
break;
case CERT_RDN_TELETEX_STRING:
ret = CRYPT_AsnEncodeUnicodeStringCoerce(value, ASN_T61STRING,
dwFlags, pEncodePara, pbEncoded, pcbEncoded);
break;
case CERT_RDN_VIDEOTEX_STRING:
ret = CRYPT_AsnEncodeUnicodeStringCoerce(value,
ASN_VIDEOTEXSTRING, dwFlags, pEncodePara, pbEncoded, pcbEncoded);
break;
case CERT_RDN_IA5_STRING:
ret = CRYPT_AsnEncodeIA5String(value, dwFlags, pEncodePara,
pbEncoded, pcbEncoded);
break;
case CERT_RDN_GRAPHIC_STRING:
ret = CRYPT_AsnEncodeUnicodeStringCoerce(value, ASN_GRAPHICSTRING,
dwFlags, pEncodePara, pbEncoded, pcbEncoded);
break;
case CERT_RDN_VISIBLE_STRING:
ret = CRYPT_AsnEncodeUnicodeStringCoerce(value, ASN_VISIBLESTRING,
dwFlags, pEncodePara, pbEncoded, pcbEncoded);
break;
case CERT_RDN_GENERAL_STRING:
ret = CRYPT_AsnEncodeUnicodeStringCoerce(value, ASN_GENERALSTRING,
dwFlags, pEncodePara, pbEncoded, pcbEncoded);
break;
case CERT_RDN_UNIVERSAL_STRING:
ret = CRYPT_AsnEncodeUniversalString(value, dwFlags, pEncodePara,
pbEncoded, pcbEncoded);
break;
case CERT_RDN_BMP_STRING:
ret = CRYPT_AsnEncodeBMPString(value, dwFlags, pEncodePara,
pbEncoded, pcbEncoded);
break;
case CERT_RDN_UTF8_STRING:
ret = CRYPT_AsnEncodeUTF8String(value, dwFlags, pEncodePara,
pbEncoded, pcbEncoded);
break;
default:
SetLastError(CRYPT_E_ASN1_CHOICE);
}
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
}
__ENDTRY
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeName(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret;
__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_AsnEncodeNameValue, NULL, &size);
if (ret)
bytesNeeded += 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_AsnEncodeNameValue, pbEncoded,
&size);
if (ret)
{
pbEncoded += size;
bytesNeeded -= size;
}
}
}
}
}
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
ret = FALSE;
}
__ENDTRY
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeBool(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL val = *(const BOOL *)pvStructInfo, ret;
TRACE("%d\n", val);
if (!pbEncoded)
{
*pcbEncoded = 3;
ret = TRUE;
}
else if (*pcbEncoded < 3)
{
*pcbEncoded = 3;
SetLastError(ERROR_MORE_DATA);
ret = FALSE;
}
else
{
*pcbEncoded = 3;
*pbEncoded++ = ASN_BOOL;
*pbEncoded++ = 1;
*pbEncoded++ = val ? 0xff : 0;
ret = TRUE;
}
TRACE("returning %d (%08x)\n", ret, GetLastError());
return ret;
}
static BOOL CRYPT_AsnEncodeAltNameEntry(const CERT_ALT_NAME_ENTRY *entry,
BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret;
DWORD dataLen;
ret = TRUE;
switch (entry->dwAltNameChoice)
{
case CERT_ALT_NAME_RFC822_NAME:
case CERT_ALT_NAME_DNS_NAME:
case CERT_ALT_NAME_URL:
if (entry->u.pwszURL)
{
DWORD i;
/* Not + 1: don't encode the NULL-terminator */
dataLen = lstrlenW(entry->u.pwszURL);
for (i = 0; ret && i < dataLen; i++)
{
if (entry->u.pwszURL[i] > 0x7f)
{
SetLastError(CRYPT_E_INVALID_IA5_STRING);
ret = FALSE;
*pcbEncoded = i;
}
}
}
else
dataLen = 0;
break;
case CERT_ALT_NAME_IP_ADDRESS:
dataLen = entry->u.IPAddress.cbData;
break;
case CERT_ALT_NAME_REGISTERED_ID:
/* FIXME: encode OID */
case CERT_ALT_NAME_OTHER_NAME:
case CERT_ALT_NAME_DIRECTORY_NAME:
FIXME("name type %d unimplemented\n", entry->dwAltNameChoice);
return FALSE;
default:
SetLastError(E_INVALIDARG);
return FALSE;
}
if (ret)
{
DWORD bytesNeeded, lenBytes;
CRYPT_EncodeLen(dataLen, NULL, &lenBytes);
bytesNeeded = 1 + dataLen + lenBytes;
if (!pbEncoded)
*pcbEncoded = bytesNeeded;
else if (*pcbEncoded < bytesNeeded)
{
SetLastError(ERROR_MORE_DATA);
*pcbEncoded = bytesNeeded;
ret = FALSE;
}
else
{
*pbEncoded++ = ASN_CONTEXT | (entry->dwAltNameChoice - 1);
CRYPT_EncodeLen(dataLen, pbEncoded, &lenBytes);
pbEncoded += lenBytes;
switch (entry->dwAltNameChoice)
{
case CERT_ALT_NAME_RFC822_NAME:
case CERT_ALT_NAME_DNS_NAME:
case CERT_ALT_NAME_URL:
{
DWORD i;
for (i = 0; i < dataLen; i++)
*pbEncoded++ = (BYTE)entry->u.pwszURL[i];
break;
}
case CERT_ALT_NAME_IP_ADDRESS:
memcpy(pbEncoded, entry->u.IPAddress.pbData, dataLen);
break;
}
if (ret)
*pcbEncoded = bytesNeeded;
}
}
TRACE("returning %d (%08x)\n", ret, GetLastError());
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeAuthorityKeyId(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret;
__TRY
{
const CERT_AUTHORITY_KEY_ID_INFO *info =
(const CERT_AUTHORITY_KEY_ID_INFO *)pvStructInfo;
struct AsnEncodeSequenceItem items[3] = { { 0 } };
struct AsnEncodeTagSwappedItem swapped[3] = { { 0 } };
struct AsnConstructedItem constructed = { 0 };
DWORD cItem = 0, cSwapped = 0;
if (info->KeyId.cbData)
{
swapped[cSwapped].tag = ASN_CONTEXT | 0;
swapped[cSwapped].pvStructInfo = &info->KeyId;
swapped[cSwapped].encodeFunc = CRYPT_AsnEncodeInteger;
items[cItem].pvStructInfo = &swapped[cSwapped];
items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag;
cSwapped++;
cItem++;
}
if (info->CertIssuer.cbData)
{
constructed.tag = 1;
constructed.pvStructInfo = &info->CertIssuer;
constructed.encodeFunc = CRYPT_CopyEncodedBlob;
items[cItem].pvStructInfo = &constructed;
items[cItem].encodeFunc = CRYPT_AsnEncodeConstructed;
cItem++;
}
if (info->CertSerialNumber.cbData)
{
swapped[cSwapped].tag = ASN_CONTEXT | 2;
swapped[cSwapped].pvStructInfo = &info->CertSerialNumber;
swapped[cSwapped].encodeFunc = CRYPT_AsnEncodeInteger;
items[cItem].pvStructInfo = &swapped[cSwapped];
items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag;
cSwapped++;
cItem++;
}
ret = CRYPT_AsnEncodeSequence(X509_ASN_ENCODING, items, cItem, dwFlags,
pEncodePara, pbEncoded, pcbEncoded);
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
ret = FALSE;
}
__ENDTRY
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeAltName(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret;
__TRY
{
const CERT_ALT_NAME_INFO *info =
(const CERT_ALT_NAME_INFO *)pvStructInfo;
DWORD bytesNeeded, dataLen, lenBytes, i;
ret = TRUE;
/* FIXME: should check that cAltEntry is not bigger than 0xff, since we
* can't encode an erroneous entry index if it's bigger than this.
*/
for (i = 0, dataLen = 0; ret && i < info->cAltEntry; i++)
{
DWORD len;
ret = CRYPT_AsnEncodeAltNameEntry(&info->rgAltEntry[i], NULL,
&len);
if (ret)
dataLen += len;
else if (GetLastError() == CRYPT_E_INVALID_IA5_STRING)
{
/* CRYPT_AsnEncodeAltNameEntry encoded the index of
* the bad character, now
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -