Commit dd4bd4ad authored by Juan Lang's avatar Juan Lang Committed by Alexandre Julliard

crypt32: Implement X509_NAME_VALUE encoding/decoding.

parent d7043f23
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#define ASN_SETOF (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x11) #define ASN_SETOF (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x11)
#define ASN_NUMERICSTRING (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x12) #define ASN_NUMERICSTRING (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x12)
#define ASN_PRINTABLESTRING (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x13) #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_IA5STRING (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x16)
#define ASN_UTCTIME (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x17) #define ASN_UTCTIME (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x17)
#define ASN_GENERALTIME (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x18) #define ASN_GENERALTIME (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x18)
......
...@@ -1182,7 +1182,7 @@ static BOOL WINAPI CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType, ...@@ -1182,7 +1182,7 @@ static BOOL WINAPI CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType,
* order to avoid overwriting memory. (In some cases, it may change it, if it * 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! * 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, LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{ {
...@@ -1199,6 +1199,7 @@ static BOOL WINAPI CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType, ...@@ -1199,6 +1199,7 @@ static BOOL WINAPI CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType,
case ASN_NUMERICSTRING: case ASN_NUMERICSTRING:
case ASN_PRINTABLESTRING: case ASN_PRINTABLESTRING:
case ASN_IA5STRING: case ASN_IA5STRING:
case ASN_T61STRING:
break; break;
default: default:
FIXME("Unimplemented string type %02x\n", pbEncoded[0]); FIXME("Unimplemented string type %02x\n", pbEncoded[0]);
...@@ -1214,6 +1215,7 @@ static BOOL WINAPI CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType, ...@@ -1214,6 +1215,7 @@ static BOOL WINAPI CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType,
case ASN_NUMERICSTRING: case ASN_NUMERICSTRING:
case ASN_PRINTABLESTRING: case ASN_PRINTABLESTRING:
case ASN_IA5STRING: case ASN_IA5STRING:
case ASN_T61STRING:
if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG)) if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
bytesNeeded += dataLen; bytesNeeded += dataLen;
break; break;
...@@ -1240,6 +1242,9 @@ static BOOL WINAPI CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType, ...@@ -1240,6 +1242,9 @@ static BOOL WINAPI CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType,
case ASN_IA5STRING: case ASN_IA5STRING:
value->dwValueType = CERT_RDN_IA5_STRING; value->dwValueType = CERT_RDN_IA5_STRING;
break; break;
case ASN_T61STRING:
value->dwValueType = CERT_RDN_T61_STRING;
break;
} }
if (dataLen) if (dataLen)
{ {
...@@ -1248,6 +1253,7 @@ static BOOL WINAPI CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType, ...@@ -1248,6 +1253,7 @@ static BOOL WINAPI CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType,
case ASN_NUMERICSTRING: case ASN_NUMERICSTRING:
case ASN_PRINTABLESTRING: case ASN_PRINTABLESTRING:
case ASN_IA5STRING: case ASN_IA5STRING:
case ASN_T61STRING:
value->Value.cbData = dataLen; value->Value.cbData = dataLen;
if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG) if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
value->Value.pbData = (BYTE *)pbEncoded + 1 + value->Value.pbData = (BYTE *)pbEncoded + 1 +
...@@ -1272,6 +1278,45 @@ static BOOL WINAPI CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType, ...@@ -1272,6 +1278,45 @@ static BOOL WINAPI CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType,
return ret; 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, static BOOL WINAPI CRYPT_AsnDecodeRdnAttr(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
...@@ -1282,7 +1327,7 @@ static BOOL WINAPI CRYPT_AsnDecodeRdnAttr(DWORD dwCertEncodingType, ...@@ -1282,7 +1327,7 @@ static BOOL WINAPI CRYPT_AsnDecodeRdnAttr(DWORD dwCertEncodingType,
CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE, CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE,
offsetof(CERT_RDN_ATTR, pszObjId), 0 }, offsetof(CERT_RDN_ATTR, pszObjId), 0 },
{ 0, offsetof(CERT_RDN_ATTR, dwValueType), { 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 }, FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
}; };
CERT_RDN_ATTR *attr = (CERT_RDN_ATTR *)pvStructInfo; CERT_RDN_ATTR *attr = (CERT_RDN_ATTR *)pvStructInfo;
...@@ -2940,6 +2985,9 @@ BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, ...@@ -2940,6 +2985,9 @@ BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
case (WORD)X509_EXTENSIONS: case (WORD)X509_EXTENSIONS:
decodeFunc = CRYPT_AsnDecodeExtensions; decodeFunc = CRYPT_AsnDecodeExtensions;
break; break;
case (WORD)X509_NAME_VALUE:
decodeFunc = CRYPT_AsnDecodeNameValue;
break;
case (WORD)X509_NAME: case (WORD)X509_NAME:
decodeFunc = CRYPT_AsnDecodeName; decodeFunc = CRYPT_AsnDecodeName;
break; break;
......
...@@ -906,58 +906,74 @@ static BOOL WINAPI CRYPT_AsnEncodeOid(DWORD dwCertEncodingType, ...@@ -906,58 +906,74 @@ static BOOL WINAPI CRYPT_AsnEncodeOid(DWORD dwCertEncodingType,
} }
static BOOL WINAPI CRYPT_AsnEncodeNameValue(DWORD dwCertEncodingType, 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; 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); case CERT_RDN_NUMERIC_STRING:
ret = FALSE; 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 else
{ {
*pbEncoded++ = tag; if ((ret = CRYPT_EncodeEnsureSpace(dwFlags, pEncodePara, pbEncoded,
CRYPT_EncodeLen(encodedLen, pbEncoded, &lenBytes); pcbEncoded, bytesNeeded)))
pbEncoded += lenBytes;
switch (value->dwValueType)
{ {
case CERT_RDN_NUMERIC_STRING: if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
case CERT_RDN_PRINTABLE_STRING: pbEncoded = *(BYTE **)pbEncoded;
case CERT_RDN_IA5_STRING: *pbEncoded++ = tag;
memcpy(pbEncoded, value->Value.pbData, value->Value.cbData); 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; return ret;
} }
...@@ -975,8 +991,8 @@ static BOOL WINAPI CRYPT_AsnEncodeRdnAttr(DWORD dwCertEncodingType, ...@@ -975,8 +991,8 @@ static BOOL WINAPI CRYPT_AsnEncodeRdnAttr(DWORD dwCertEncodingType,
/* hack: a CERT_RDN_ATTR is identical to a CERT_NAME_VALUE beginning /* hack: a CERT_RDN_ATTR is identical to a CERT_NAME_VALUE beginning
* with dwValueType, so "cast" it to get its encoded size * with dwValueType, so "cast" it to get its encoded size
*/ */
ret = CRYPT_AsnEncodeNameValue(dwCertEncodingType, ret = CRYPT_AsnEncodeNameValue(dwCertEncodingType, X509_NAME_VALUE,
(CERT_NAME_VALUE *)&attr->dwValueType, NULL, &size); (CERT_NAME_VALUE *)&attr->dwValueType, 0, NULL, NULL, &size);
if (ret) if (ret)
{ {
bytesNeeded += size; bytesNeeded += size;
...@@ -1003,8 +1019,8 @@ static BOOL WINAPI CRYPT_AsnEncodeRdnAttr(DWORD dwCertEncodingType, ...@@ -1003,8 +1019,8 @@ static BOOL WINAPI CRYPT_AsnEncodeRdnAttr(DWORD dwCertEncodingType,
pbEncoded += size; pbEncoded += size;
size = bytesNeeded - 1 - lenBytes - size; size = bytesNeeded - 1 - lenBytes - size;
ret = CRYPT_AsnEncodeNameValue(dwCertEncodingType, ret = CRYPT_AsnEncodeNameValue(dwCertEncodingType,
(CERT_NAME_VALUE *)&attr->dwValueType, pbEncoded, X509_NAME_VALUE, (CERT_NAME_VALUE *)&attr->dwValueType,
&size); 0, NULL, pbEncoded, &size);
} }
} }
} }
...@@ -2264,6 +2280,9 @@ BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, ...@@ -2264,6 +2280,9 @@ BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
case (WORD)X509_EXTENSIONS: case (WORD)X509_EXTENSIONS:
encodeFunc = CRYPT_AsnEncodeExtensions; encodeFunc = CRYPT_AsnEncodeExtensions;
break; break;
case (WORD)X509_NAME_VALUE:
encodeFunc = CRYPT_AsnEncodeNameValue;
break;
case (WORD)X509_NAME: case (WORD)X509_NAME:
encodeFunc = CRYPT_AsnEncodeName; encodeFunc = CRYPT_AsnEncodeName;
break; break;
......
...@@ -3204,10 +3204,8 @@ START_TEST(encode) ...@@ -3204,10 +3204,8 @@ START_TEST(encode)
test_decodeFiletime(encodings[i]); test_decodeFiletime(encodings[i]);
test_encodeName(encodings[i]); test_encodeName(encodings[i]);
test_decodeName(encodings[i]); test_decodeName(encodings[i]);
todo_wine {
test_encodeNameValue(encodings[i]); test_encodeNameValue(encodings[i]);
test_decodeNameValue(encodings[i]); test_decodeNameValue(encodings[i]);
}
test_encodeAltName(encodings[i]); test_encodeAltName(encodings[i]);
test_decodeAltName(encodings[i]); test_decodeAltName(encodings[i]);
test_encodeOctets(encodings[i]); test_encodeOctets(encodings[i]);
......
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