Commit 93aed4b0 authored by Juan Lang's avatar Juan Lang Committed by Alexandre Julliard

crypt32: Accept any string format as the display text of a user notice policy qualifier.

parent b3bf746f
...@@ -2392,54 +2392,129 @@ static BOOL CRYPT_AsnDecodeNoticeReference(const BYTE *pbEncoded, ...@@ -2392,54 +2392,129 @@ static BOOL CRYPT_AsnDecodeNoticeReference(const BYTE *pbEncoded,
return ret; return ret;
} }
static BOOL CRYPT_AsnDecodeBMPString(const BYTE *pbEncoded, static BOOL CRYPT_AsnDecodeUnicodeString(const BYTE *pbEncoded,
DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
DWORD *pcbDecoded) DWORD *pcbDecoded)
{ {
BOOL ret = TRUE; BOOL ret = TRUE;
DWORD dataLen; DWORD dataLen;
LPWSTR *pStr = pvStructInfo;
if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
{ {
BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
DWORD bytesNeeded = sizeof(LPWSTR) + sizeof(WCHAR); DWORD bytesNeeded = sizeof(LPWSTR);
if (pbEncoded[0] != ASN_BMPSTRING) switch (pbEncoded[0])
{ {
SetLastError(CRYPT_E_ASN1_CORRUPT); case ASN_NUMERICSTRING:
if (dataLen)
bytesNeeded += (dataLen + 1) * 2;
break;
case ASN_PRINTABLESTRING:
if (dataLen)
bytesNeeded += (dataLen + 1) * 2;
break;
case ASN_IA5STRING:
if (dataLen)
bytesNeeded += (dataLen + 1) * 2;
break;
case ASN_T61STRING:
if (dataLen)
bytesNeeded += (dataLen + 1) * 2;
break;
case ASN_VIDEOTEXSTRING:
if (dataLen)
bytesNeeded += (dataLen + 1) * 2;
break;
case ASN_GRAPHICSTRING:
if (dataLen)
bytesNeeded += (dataLen + 1) * 2;
break;
case ASN_VISIBLESTRING:
if (dataLen)
bytesNeeded += (dataLen + 1) * 2;
break;
case ASN_GENERALSTRING:
if (dataLen)
bytesNeeded += (dataLen + 1) * 2;
break;
case ASN_UNIVERSALSTRING:
if (dataLen)
bytesNeeded += dataLen / 2 + sizeof(WCHAR);
break;
case ASN_BMPSTRING:
if (dataLen)
bytesNeeded += dataLen + sizeof(WCHAR);
break;
case ASN_UTF8STRING:
if (dataLen)
bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0,
(LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2;
break;
default:
SetLastError(CRYPT_E_ASN1_BADTAG);
return FALSE;
}
if (pcbDecoded)
*pcbDecoded = 1 + lenBytes + dataLen;
if (!pvStructInfo)
*pcbStructInfo = bytesNeeded;
else if (*pcbStructInfo < bytesNeeded)
{
*pcbStructInfo = bytesNeeded;
SetLastError(ERROR_MORE_DATA);
ret = FALSE; ret = FALSE;
} }
else else
{ {
bytesNeeded += dataLen; LPWSTR *pStr = pvStructInfo;
if (pcbDecoded)
*pcbDecoded = 1 + lenBytes + dataLen; *pcbStructInfo = bytesNeeded;
if (!pvStructInfo) if (dataLen)
*pcbStructInfo = bytesNeeded;
else if (*pcbStructInfo < bytesNeeded)
{
*pcbStructInfo = bytesNeeded;
SetLastError(ERROR_MORE_DATA);
ret = FALSE;
}
else
{ {
*pcbStructInfo = bytesNeeded; DWORD i;
if (dataLen) LPWSTR str = *(LPWSTR *)pStr;
{
DWORD i;
LPWSTR str = *pStr;
assert(str); assert(str);
switch (pbEncoded[0])
{
case ASN_NUMERICSTRING:
case ASN_PRINTABLESTRING:
case ASN_IA5STRING:
case ASN_T61STRING:
case ASN_VIDEOTEXSTRING:
case ASN_GRAPHICSTRING:
case ASN_VISIBLESTRING:
case ASN_GENERALSTRING:
for (i = 0; i < dataLen; i++)
str[i] = pbEncoded[1 + lenBytes + i];
str[i] = 0;
break;
case ASN_UNIVERSALSTRING:
for (i = 0; i < dataLen / 4; i++)
str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
| pbEncoded[1 + lenBytes + 2 * i + 3];
str[i] = 0;
break;
case ASN_BMPSTRING:
for (i = 0; i < dataLen / 2; i++) for (i = 0; i < dataLen / 2; i++)
str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) | str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
pbEncoded[1 + lenBytes + 2 * i + 1]; pbEncoded[1 + lenBytes + 2 * i + 1];
str[i] = 0; str[i] = 0;
break;
case ASN_UTF8STRING:
{
int len = MultiByteToWideChar(CP_UTF8, 0,
(LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
str[len] = 0;
break;
}
} }
else
*pStr = NULL;
} }
else
*pStr = NULL;
} }
} }
return ret; return ret;
...@@ -2455,8 +2530,8 @@ static BOOL CRYPT_AsnDecodePolicyQualifierUserNoticeInternal( ...@@ -2455,8 +2530,8 @@ static BOOL CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
pNoticeReference), CRYPT_AsnDecodeNoticeReference, pNoticeReference), CRYPT_AsnDecodeNoticeReference,
sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE), TRUE, TRUE, sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE), TRUE, TRUE,
offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pNoticeReference), 0 }, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pNoticeReference), 0 },
{ ASN_BMPSTRING, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText),
pszDisplayText), CRYPT_AsnDecodeBMPString, sizeof(LPWSTR), TRUE, TRUE, CRYPT_AsnDecodeUnicodeString, sizeof(LPWSTR), TRUE, TRUE,
offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText), 0 }, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText), 0 },
}; };
PCERT_POLICY_QUALIFIER_USER_NOTICE notice = pvStructInfo; PCERT_POLICY_QUALIFIER_USER_NOTICE notice = pvStructInfo;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment