crypt32: Implement X509_NAME_VALUE encoding/decoding.
diff --git a/dlls/crypt32/crypt32_private.h b/dlls/crypt32/crypt32_private.h
index f8365d6..8ac0484 100644
--- a/dlls/crypt32/crypt32_private.h
+++ b/dlls/crypt32/crypt32_private.h
@@ -26,6 +26,7 @@
#define ASN_SETOF (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x11)
#define ASN_NUMERICSTRING (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x12)
#define ASN_PRINTABLESTRING (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x13)
+#define ASN_T61STRING (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x14)
#define ASN_IA5STRING (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x16)
#define ASN_UTCTIME (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x17)
#define ASN_GENERALTIME (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x18)
diff --git a/dlls/crypt32/decode.c b/dlls/crypt32/decode.c
index d2be521..cd0e644 100644
--- a/dlls/crypt32/decode.c
+++ b/dlls/crypt32/decode.c
@@ -1182,7 +1182,7 @@
* order to avoid overwriting memory. (In some cases, it may change it, if it
* doesn't copy anything to memory.) Be sure to set it correctly!
*/
-static BOOL WINAPI CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType,
+static BOOL WINAPI CRYPT_AsnDecodeNameValueInternal(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
@@ -1199,6 +1199,7 @@
case ASN_NUMERICSTRING:
case ASN_PRINTABLESTRING:
case ASN_IA5STRING:
+ case ASN_T61STRING:
break;
default:
FIXME("Unimplemented string type %02x\n", pbEncoded[0]);
@@ -1214,6 +1215,7 @@
case ASN_NUMERICSTRING:
case ASN_PRINTABLESTRING:
case ASN_IA5STRING:
+ case ASN_T61STRING:
if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
bytesNeeded += dataLen;
break;
@@ -1240,6 +1242,9 @@
case ASN_IA5STRING:
value->dwValueType = CERT_RDN_IA5_STRING;
break;
+ case ASN_T61STRING:
+ value->dwValueType = CERT_RDN_T61_STRING;
+ break;
}
if (dataLen)
{
@@ -1248,6 +1253,7 @@
case ASN_NUMERICSTRING:
case ASN_PRINTABLESTRING:
case ASN_IA5STRING:
+ case ASN_T61STRING:
value->Value.cbData = dataLen;
if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
value->Value.pbData = (BYTE *)pbEncoded + 1 +
@@ -1272,6 +1278,45 @@
return ret;
}
+static BOOL WINAPI CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
+ PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
+{
+ BOOL ret = TRUE;
+
+ __TRY
+ {
+ ret = CRYPT_AsnDecodeNameValueInternal(dwCertEncodingType,
+ lpszStructType, pbEncoded, cbEncoded,
+ dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL, pcbStructInfo);
+ if (ret && pvStructInfo)
+ {
+ ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
+ pcbStructInfo, *pcbStructInfo);
+ if (ret)
+ {
+ CERT_NAME_VALUE *value;
+
+ if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
+ pvStructInfo = *(BYTE **)pvStructInfo;
+ value = (CERT_NAME_VALUE *)pvStructInfo;
+ value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
+ ret = CRYPT_AsnDecodeNameValueInternal(dwCertEncodingType,
+ lpszStructType, pbEncoded, cbEncoded,
+ dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pvStructInfo,
+ pcbStructInfo);
+ }
+ }
+ }
+ __EXCEPT_PAGE_FAULT
+ {
+ SetLastError(STATUS_ACCESS_VIOLATION);
+ ret = FALSE;
+ }
+ __ENDTRY
+ return ret;
+}
+
static BOOL WINAPI CRYPT_AsnDecodeRdnAttr(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
@@ -1282,7 +1327,7 @@
CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE,
offsetof(CERT_RDN_ATTR, pszObjId), 0 },
{ 0, offsetof(CERT_RDN_ATTR, dwValueType),
- CRYPT_AsnDecodeNameValue, sizeof(CERT_NAME_VALUE),
+ CRYPT_AsnDecodeNameValueInternal, sizeof(CERT_NAME_VALUE),
FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
};
CERT_RDN_ATTR *attr = (CERT_RDN_ATTR *)pvStructInfo;
@@ -2940,6 +2985,9 @@
case (WORD)X509_EXTENSIONS:
decodeFunc = CRYPT_AsnDecodeExtensions;
break;
+ case (WORD)X509_NAME_VALUE:
+ decodeFunc = CRYPT_AsnDecodeNameValue;
+ break;
case (WORD)X509_NAME:
decodeFunc = CRYPT_AsnDecodeName;
break;
diff --git a/dlls/crypt32/encode.c b/dlls/crypt32/encode.c
index ee1c9cc..3fee0c9 100644
--- a/dlls/crypt32/encode.c
+++ b/dlls/crypt32/encode.c
@@ -906,58 +906,74 @@
}
static BOOL WINAPI CRYPT_AsnEncodeNameValue(DWORD dwCertEncodingType,
- CERT_NAME_VALUE *value, BYTE *pbEncoded, DWORD *pcbEncoded)
+ LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
+ PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
- BYTE tag;
- DWORD bytesNeeded, lenBytes, encodedLen;
BOOL ret = TRUE;
- switch (value->dwValueType)
+ __TRY
{
- case CERT_RDN_NUMERIC_STRING:
- tag = ASN_NUMERICSTRING;
- encodedLen = value->Value.cbData;
- break;
- case CERT_RDN_PRINTABLE_STRING:
- tag = ASN_PRINTABLESTRING;
- encodedLen = value->Value.cbData;
- break;
- case CERT_RDN_IA5_STRING:
- tag = ASN_IA5STRING;
- encodedLen = value->Value.cbData;
- break;
- case CERT_RDN_ANY_TYPE:
- /* explicitly disallowed */
- SetLastError(E_INVALIDARG);
- return FALSE;
- default:
- FIXME("String type %ld unimplemented\n", value->dwValueType);
- return FALSE;
- }
- CRYPT_EncodeLen(encodedLen, NULL, &lenBytes);
- bytesNeeded = 1 + lenBytes + encodedLen;
- if (pbEncoded)
- {
- if (*pcbEncoded < bytesNeeded)
+ BYTE tag;
+ DWORD bytesNeeded, lenBytes, encodedLen;
+ const CERT_NAME_VALUE *value = (CERT_NAME_VALUE *)pvStructInfo;
+
+ switch (value->dwValueType)
{
- SetLastError(ERROR_MORE_DATA);
- ret = FALSE;
+ case CERT_RDN_NUMERIC_STRING:
+ tag = ASN_NUMERICSTRING;
+ encodedLen = value->Value.cbData;
+ break;
+ case CERT_RDN_PRINTABLE_STRING:
+ tag = ASN_PRINTABLESTRING;
+ encodedLen = value->Value.cbData;
+ break;
+ case CERT_RDN_T61_STRING:
+ tag = ASN_T61STRING;
+ encodedLen = value->Value.cbData;
+ break;
+ case CERT_RDN_IA5_STRING:
+ tag = ASN_IA5STRING;
+ encodedLen = value->Value.cbData;
+ break;
+ case CERT_RDN_ANY_TYPE:
+ /* explicitly disallowed */
+ SetLastError(E_INVALIDARG);
+ return FALSE;
+ default:
+ FIXME("String type %ld unimplemented\n", value->dwValueType);
+ return FALSE;
}
+ CRYPT_EncodeLen(encodedLen, NULL, &lenBytes);
+ bytesNeeded = 1 + lenBytes + encodedLen;
+ if (!pbEncoded)
+ *pcbEncoded = bytesNeeded;
else
{
- *pbEncoded++ = tag;
- CRYPT_EncodeLen(encodedLen, pbEncoded, &lenBytes);
- pbEncoded += lenBytes;
- switch (value->dwValueType)
+ if ((ret = CRYPT_EncodeEnsureSpace(dwFlags, pEncodePara, pbEncoded,
+ pcbEncoded, bytesNeeded)))
{
- case CERT_RDN_NUMERIC_STRING:
- case CERT_RDN_PRINTABLE_STRING:
- case CERT_RDN_IA5_STRING:
- memcpy(pbEncoded, value->Value.pbData, value->Value.cbData);
+ if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
+ pbEncoded = *(BYTE **)pbEncoded;
+ *pbEncoded++ = tag;
+ CRYPT_EncodeLen(encodedLen, pbEncoded, &lenBytes);
+ pbEncoded += lenBytes;
+ switch (value->dwValueType)
+ {
+ case CERT_RDN_NUMERIC_STRING:
+ case CERT_RDN_PRINTABLE_STRING:
+ case CERT_RDN_T61_STRING:
+ case CERT_RDN_IA5_STRING:
+ memcpy(pbEncoded, value->Value.pbData, value->Value.cbData);
+ }
}
}
}
- *pcbEncoded = bytesNeeded;
+ __EXCEPT_PAGE_FAULT
+ {
+ SetLastError(STATUS_ACCESS_VIOLATION);
+ ret = FALSE;
+ }
+ __ENDTRY
return ret;
}
@@ -975,8 +991,8 @@
/* hack: a CERT_RDN_ATTR is identical to a CERT_NAME_VALUE beginning
* with dwValueType, so "cast" it to get its encoded size
*/
- ret = CRYPT_AsnEncodeNameValue(dwCertEncodingType,
- (CERT_NAME_VALUE *)&attr->dwValueType, NULL, &size);
+ ret = CRYPT_AsnEncodeNameValue(dwCertEncodingType, X509_NAME_VALUE,
+ (CERT_NAME_VALUE *)&attr->dwValueType, 0, NULL, NULL, &size);
if (ret)
{
bytesNeeded += size;
@@ -1003,8 +1019,8 @@
pbEncoded += size;
size = bytesNeeded - 1 - lenBytes - size;
ret = CRYPT_AsnEncodeNameValue(dwCertEncodingType,
- (CERT_NAME_VALUE *)&attr->dwValueType, pbEncoded,
- &size);
+ X509_NAME_VALUE, (CERT_NAME_VALUE *)&attr->dwValueType,
+ 0, NULL, pbEncoded, &size);
}
}
}
@@ -2264,6 +2280,9 @@
case (WORD)X509_EXTENSIONS:
encodeFunc = CRYPT_AsnEncodeExtensions;
break;
+ case (WORD)X509_NAME_VALUE:
+ encodeFunc = CRYPT_AsnEncodeNameValue;
+ break;
case (WORD)X509_NAME:
encodeFunc = CRYPT_AsnEncodeName;
break;
diff --git a/dlls/crypt32/tests/encode.c b/dlls/crypt32/tests/encode.c
index d5258c1..da5b975 100644
--- a/dlls/crypt32/tests/encode.c
+++ b/dlls/crypt32/tests/encode.c
@@ -3204,10 +3204,8 @@
test_decodeFiletime(encodings[i]);
test_encodeName(encodings[i]);
test_decodeName(encodings[i]);
- todo_wine {
test_encodeNameValue(encodings[i]);
test_decodeNameValue(encodings[i]);
- }
test_encodeAltName(encodings[i]);
test_decodeAltName(encodings[i]);
test_encodeOctets(encodings[i]);