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

crypt32: Implement encoding CTLs.

parent 26d643d3
......@@ -93,6 +93,12 @@ static BOOL WINAPI CRYPT_AsnEncodeUnsignedInteger(DWORD dwCertEncodingType,
static BOOL WINAPI CRYPT_AsnEncodeChoiceOfTime(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded);
static BOOL WINAPI CRYPT_AsnEncodeEnhancedKeyUsage(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded);
static BOOL WINAPI CRYPT_AsnEncodePKCSAttributes(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded);
BOOL CRYPT_EncodeEnsureSpace(DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara,
BYTE *pbEncoded, DWORD *pcbEncoded, DWORD bytesNeeded)
......@@ -1411,6 +1417,193 @@ static BOOL WINAPI CRYPT_AsnEncodeUnicodeName(DWORD dwCertEncodingType,
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeCTLVersion(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
const DWORD *ver = (const DWORD *)pvStructInfo;
BOOL ret;
/* CTL_V1 is not encoded */
if (*ver == CTL_V1)
{
*pcbEncoded = 0;
ret = TRUE;
}
else
ret = CRYPT_AsnEncodeInt(dwCertEncodingType, X509_INTEGER, ver,
dwFlags, pEncodePara, pbEncoded, pcbEncoded);
return ret;
}
/* Like CRYPT_AsnEncodeAlgorithmId, but encodes parameters as an asn.1 NULL
* if they are empty and the OID is not empty (otherwise omits them.)
*/
static BOOL WINAPI CRYPT_AsnEncodeCTLSubjectAlgorithm(
DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo,
DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded,
DWORD *pcbEncoded)
{
const CRYPT_ALGORITHM_IDENTIFIER *algo =
(const CRYPT_ALGORITHM_IDENTIFIER *)pvStructInfo;
BOOL ret;
struct AsnEncodeSequenceItem items[2] = {
{ algo->pszObjId, CRYPT_AsnEncodeOid, 0 },
};
DWORD cItem = 1;
if (algo->pszObjId)
{
static const BYTE asn1Null[] = { ASN_NULL, 0 };
static const CRYPT_DATA_BLOB nullBlob = { sizeof(asn1Null),
(LPBYTE)asn1Null };
if (algo->Parameters.cbData)
items[cItem].pvStructInfo = &algo->Parameters;
else
items[cItem].pvStructInfo = &nullBlob;
items[cItem].encodeFunc = CRYPT_CopyEncodedBlob;
cItem++;
}
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, cItem,
dwFlags, pEncodePara, pbEncoded, pcbEncoded);
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeCTLEntry(const CTL_ENTRY *entry,
BYTE *pbEncoded, DWORD *pcbEncoded)
{
struct AsnEncodeSequenceItem items[2] = {
{ &entry->SubjectIdentifier, CRYPT_AsnEncodeOctets, 0 },
{ &entry->cAttribute, CRYPT_AsnEncodePKCSAttributes, 0 },
};
BOOL ret;
ret = CRYPT_AsnEncodeSequence(X509_ASN_ENCODING, items,
sizeof(items) / sizeof(items[0]), 0, NULL, pbEncoded, pcbEncoded);
return ret;
}
struct CTLEntries
{
DWORD cEntry;
CTL_ENTRY *rgEntry;
};
static BOOL WINAPI CRYPT_AsnEncodeCTLEntries(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret;
DWORD bytesNeeded, dataLen, lenBytes, i;
const struct CTLEntries *entries = (const struct CTLEntries *)pvStructInfo;
ret = TRUE;
for (i = 0, dataLen = 0; ret && i < entries->cEntry; i++)
{
DWORD size;
ret = CRYPT_AsnEncodeCTLEntry(&entries->rgEntry[i], NULL, &size);
if (ret)
dataLen += size;
}
if (ret)
{
CRYPT_EncodeLen(dataLen, NULL, &lenBytes);
bytesNeeded = 1 + lenBytes + dataLen;
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(dataLen, pbEncoded, &lenBytes);
pbEncoded += lenBytes;
for (i = 0; ret && i < entries->cEntry; i++)
{
DWORD size = dataLen;
ret = CRYPT_AsnEncodeCTLEntry(&entries->rgEntry[i],
pbEncoded, &size);
pbEncoded += size;
dataLen -= size;
}
}
}
}
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeCTL(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret = FALSE;
__TRY
{
const CTL_INFO *info = (const CTL_INFO *)pvStructInfo;
struct AsnEncodeSequenceItem items[9] = {
{ &info->dwVersion, CRYPT_AsnEncodeCTLVersion, 0 },
{ &info->SubjectUsage, CRYPT_AsnEncodeEnhancedKeyUsage, 0 },
};
struct AsnConstructedItem constructed = { 0 };
DWORD cItem = 2;
if (info->ListIdentifier.cbData)
{
items[cItem].pvStructInfo = &info->ListIdentifier;
items[cItem].encodeFunc = CRYPT_AsnEncodeOctets;
cItem++;
}
if (info->SequenceNumber.cbData)
{
items[cItem].pvStructInfo = &info->SequenceNumber;
items[cItem].encodeFunc = CRYPT_AsnEncodeInteger;
cItem++;
}
items[cItem].pvStructInfo = &info->ThisUpdate;
items[cItem].encodeFunc = CRYPT_AsnEncodeChoiceOfTime;
cItem++;
if (info->NextUpdate.dwLowDateTime || info->NextUpdate.dwHighDateTime)
{
items[cItem].pvStructInfo = &info->NextUpdate;
items[cItem].encodeFunc = CRYPT_AsnEncodeChoiceOfTime;
cItem++;
}
items[cItem].pvStructInfo = &info->SubjectAlgorithm;
items[cItem].encodeFunc = CRYPT_AsnEncodeCTLSubjectAlgorithm;
cItem++;
if (info->cCTLEntry)
{
items[cItem].pvStructInfo = &info->cCTLEntry;
items[cItem].encodeFunc = CRYPT_AsnEncodeCTLEntries;
cItem++;
}
if (info->cExtension)
{
constructed.tag = 0;
constructed.pvStructInfo = &info->cExtension;
constructed.encodeFunc = CRYPT_AsnEncodeExtensions;
items[cItem].pvStructInfo = &constructed;
items[cItem].encodeFunc = CRYPT_AsnEncodeConstructed;
cItem++;
}
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, cItem,
dwFlags, pEncodePara, pbEncoded, pcbEncoded);
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
}
__ENDTRY
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeSMIMECapability(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
......@@ -3864,6 +4057,9 @@ static CryptEncodeObjectExFunc CRYPT_GetBuiltinEncoder(DWORD dwCertEncodingType,
case LOWORD(X509_ENHANCED_KEY_USAGE):
encodeFunc = CRYPT_AsnEncodeEnhancedKeyUsage;
break;
case LOWORD(PKCS_CTL):
encodeFunc = CRYPT_AsnEncodeCTL;
break;
case LOWORD(PKCS_SMIME_CAPABILITIES):
encodeFunc = CRYPT_AsnEncodeSMIMECapabilities;
break;
......@@ -3924,6 +4120,8 @@ static CryptEncodeObjectExFunc CRYPT_GetBuiltinEncoder(DWORD dwCertEncodingType,
encodeFunc = CRYPT_AsnEncodeNameConstraints;
else if (!strcmp(lpszStructType, szOID_AUTHORITY_INFO_ACCESS))
encodeFunc = CRYPT_AsnEncodeAuthorityInfoAccess;
else if (!strcmp(lpszStructType, szOID_CTL))
encodeFunc = CRYPT_AsnEncodeCTL;
return encodeFunc;
}
......
......@@ -5003,7 +5003,6 @@ static void test_encodeCTL(DWORD dwEncoding)
memset(&info, 0, sizeof(info));
ret = CryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
todo_wine
ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
if (buf)
{
......@@ -5015,7 +5014,6 @@ static void test_encodeCTL(DWORD dwEncoding)
info.dwVersion = 1;
ret = CryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
todo_wine
ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
if (buf)
{
......@@ -5029,7 +5027,6 @@ static void test_encodeCTL(DWORD dwEncoding)
info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
ret = CryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
todo_wine
ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
if (buf)
{
......@@ -5044,7 +5041,6 @@ static void test_encodeCTL(DWORD dwEncoding)
info.ListIdentifier.pbData = (LPBYTE)serialNum;
ret = CryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
todo_wine
ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
if (buf)
{
......@@ -5058,7 +5054,6 @@ static void test_encodeCTL(DWORD dwEncoding)
info.SequenceNumber.pbData = (LPBYTE)serialNum;
ret = CryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
todo_wine
ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
if (buf)
{
......@@ -5072,7 +5067,6 @@ static void test_encodeCTL(DWORD dwEncoding)
SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
ret = CryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
todo_wine
ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
if (buf)
{
......@@ -5084,7 +5078,6 @@ static void test_encodeCTL(DWORD dwEncoding)
SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
ret = CryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
todo_wine
ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
if (buf)
{
......@@ -5099,7 +5092,6 @@ static void test_encodeCTL(DWORD dwEncoding)
info.SubjectAlgorithm.pszObjId = oid2;
ret = CryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
todo_wine
ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
if (buf)
{
......@@ -5125,7 +5117,6 @@ static void test_encodeCTL(DWORD dwEncoding)
info.rgCTLEntry = ctlEntry;
ret = CryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
todo_wine
ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
if (buf)
{
......@@ -5138,7 +5129,6 @@ static void test_encodeCTL(DWORD dwEncoding)
value1.pbData = (LPBYTE)emptySequence;
ret = CryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
todo_wine
ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
if (buf)
{
......@@ -5159,7 +5149,6 @@ static void test_encodeCTL(DWORD dwEncoding)
info.cCTLEntry = 2;
ret = CryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
todo_wine
ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
if (buf)
{
......
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