Commit 92821ebd authored by Hans Leidekker's avatar Hans Leidekker Committed by Alexandre Julliard

crypt32: Add support for encoding OCSP requests.

parent 39d6ac0d
......@@ -4472,6 +4472,195 @@ BOOL CRYPT_AsnEncodePKCSEnvelopedData(const CRYPT_ENVELOPED_DATA *envelopedData,
ARRAY_SIZE(items), 0, NULL, pvData, pcbData);
}
static BOOL WINAPI CRYPT_AsnEncodeCertId(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret;
__TRY
{
const OCSP_CERT_ID *id = pvStructInfo;
struct AsnEncodeSequenceItem items[] = {
{ &id->HashAlgorithm, CRYPT_AsnEncodeAlgorithmIdWithNullParams, 0 },
{ &id->IssuerNameHash, CRYPT_AsnEncodeOctets, 0 },
{ &id->IssuerKeyHash, CRYPT_AsnEncodeOctets, 0 },
{ &id->SerialNumber, CRYPT_AsnEncodeInteger, 0 },
};
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
ARRAY_SIZE(items), dwFlags, pEncodePara, pbEncoded, pcbEncoded);
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
ret = FALSE;
}
__ENDTRY
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeOCSPRequestEntry(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret;
__TRY
{
const OCSP_REQUEST_ENTRY *info = pvStructInfo;
struct AsnEncodeSequenceItem items[] = {
{ &info->CertId, CRYPT_AsnEncodeCertId, 0 },
};
if (info->cExtension)
{
FIXME("extensions not supported\n");
SetLastError(E_INVALIDARG);
ret = FALSE;
}
else
{
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
ARRAY_SIZE(items), dwFlags, pEncodePara, pbEncoded, pcbEncoded);
}
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
ret = FALSE;
}
__ENDTRY
return ret;
}
struct ocsp_request_list
{
DWORD count;
OCSP_REQUEST_ENTRY *entry;
};
static BOOL WINAPI CRYPT_AsnEncodeOCSPRequestEntries(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret;
__TRY
{
DWORD bytesNeeded, dataLen, lenBytes, i;
const struct ocsp_request_list *list = pvStructInfo;
ret = TRUE;
for (i = 0, dataLen = 0; ret && i < list->count; i++)
{
DWORD size;
ret = CRYPT_AsnEncodeOCSPRequestEntry(dwCertEncodingType, lpszStructType, &list->entry[i],
dwFlags, pEncodePara, 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)))
{
BYTE *out;
if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
pbEncoded = *(BYTE **)pbEncoded;
out = pbEncoded;
*out++ = ASN_SEQUENCEOF;
CRYPT_EncodeLen(dataLen, out, &lenBytes);
out += lenBytes;
for (i = 0; i < list->count; i++)
{
DWORD size = dataLen;
ret = CRYPT_AsnEncodeOCSPRequestEntry(dwCertEncodingType, lpszStructType,
&list->entry[i], dwFlags, pEncodePara, out, &size);
out += size;
dataLen -= size;
}
if (!ret && (dwFlags & CRYPT_ENCODE_ALLOC_FLAG))
CRYPT_FreeSpace(pEncodePara, pbEncoded);
}
}
}
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
ret = FALSE;
}
__ENDTRY
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeOCSPRequest(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret;
__TRY
{
const OCSP_REQUEST_INFO *info = pvStructInfo;
if (info->dwVersion != OCSP_REQUEST_V1)
{
FIXME("version %lu not supported\n", info->dwVersion);
SetLastError(E_INVALIDARG);
ret = FALSE;
}
else
{
if (info->cExtension)
{
FIXME("extensions not supported\n");
SetLastError(E_INVALIDARG);
ret = FALSE;
}
else
{
struct AsnConstructedItem name;
struct AsnEncodeSequenceItem items[2];
DWORD count = 1;
name.tag = 1;
name.pvStructInfo = info->pRequestorName;
name.encodeFunc = CRYPT_AsnEncodeAltNameEntry;
items[0].pvStructInfo = &name;
items[0].encodeFunc = CRYPT_AsnEncodeConstructed;
if (info->cRequestEntry)
{
items[1].pvStructInfo = &info->cRequestEntry;
items[1].encodeFunc = CRYPT_AsnEncodeOCSPRequestEntries;
count++;
}
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
count, dwFlags, pEncodePara, pbEncoded, pcbEncoded);
}
}
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
ret = FALSE;
}
__ENDTRY
return ret;
}
static CryptEncodeObjectExFunc CRYPT_GetBuiltinEncoder(DWORD dwCertEncodingType,
LPCSTR lpszStructType)
{
......@@ -4612,6 +4801,9 @@ static CryptEncodeObjectExFunc CRYPT_GetBuiltinEncoder(DWORD dwCertEncodingType,
case LOWORD(CNG_RSA_PUBLIC_KEY_BLOB):
encodeFunc = CRYPT_AsnEncodeRsaPubKey_Bcrypt;
break;
case LOWORD(OCSP_REQUEST):
encodeFunc = CRYPT_AsnEncodeOCSPRequest;
break;
default:
FIXME("Unimplemented encoder for lpszStructType OID %d\n", LOWORD(lpszStructType));
}
......
......@@ -8633,6 +8633,90 @@ static void testPortPublicKeyInfo(void)
ok(ret,"CryptAcquireContextA failed\n");
}
static void test_encodeOCSPRequestInfo(DWORD dwEncoding)
{
static const BYTE expected[] =
{0x30, 0x68, 0xa1, 0x17, 0x82, 0x15, 0x2a, 0x2e, 0x63, 0x6d, 0x2e, 0x73, 0x74, 0x65, 0x61, 0x6d,
0x70, 0x6f, 0x77, 0x65, 0x72, 0x65, 0x64, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x4d, 0x30, 0x4b, 0x30,
0x49, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0xe4, 0xe3,
0x95, 0xa2, 0x29, 0xd3, 0xd4, 0xc1, 0xc3, 0x1f, 0xf0, 0x98 ,0x0c, 0x0b, 0x4e, 0xc0, 0x09, 0x8a,
0xab, 0xd8, 0x04, 0x14, 0xb7, 0x6b, 0xa2, 0xea, 0xa8, 0xaa, 0x84, 0x8c, 0x79, 0xea, 0xb4, 0xda,
0x0f, 0x98, 0xb2, 0xc5, 0x95, 0x76, 0xb9, 0xf4, 0x02, 0x10, 0xb1, 0xc1, 0x87, 0x54, 0x54, 0xac,
0x1e, 0x55, 0x40, 0xfb, 0xef, 0xd9, 0x6d, 0x8f, 0x49, 0x08};
static const BYTE expected2[] =
{0x30, 0x81, 0xb6, 0xa1, 0x17, 0x82, 0x15, 0x2a, 0x2e, 0x63, 0x6d, 0x2e, 0x73, 0x74, 0x65, 0x61,
0x6d, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x65, 0x64, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x81, 0x9a, 0x30,
0x4b, 0x30, 0x49, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14,
0xe4, 0xe3, 0x95, 0xa2, 0x29, 0xd3, 0xd4, 0xc1, 0xc3, 0x1f, 0xf0, 0x98, 0x0c, 0x0b, 0x4e, 0xc0,
0x09, 0x8a, 0xab, 0xd8, 0x04, 0x14, 0xb7, 0x6b, 0xa2, 0xea, 0xa8, 0xaa, 0x84, 0x8c, 0x79, 0xea,
0xb4, 0xda, 0x0f, 0x98, 0xb2, 0xc5, 0x95, 0x76, 0xb9, 0xf4, 0x02, 0x10, 0xb1, 0xc1, 0x87, 0x54,
0x54, 0xac, 0x1e, 0x55, 0x40, 0xfb, 0xef, 0xd9, 0x6d, 0x8f, 0x49, 0x08, 0x30, 0x4b, 0x30, 0x49,
0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0xe4, 0xe3, 0x95,
0xa2, 0x29, 0xd3, 0xd4, 0xc1, 0xc3, 0x1f, 0xf0, 0x98, 0x0c, 0x0b, 0x4e, 0xc0, 0x09, 0x8a, 0xab,
0xd8, 0x04, 0x14, 0xb7, 0x6b, 0xa2, 0xea, 0xa8, 0xaa, 0x84, 0x8c, 0x79, 0xea, 0xb4, 0xda, 0x0f,
0x98, 0xb2, 0xc5, 0x95, 0x76, 0xb9, 0xf4, 0x02, 0x10, 0xb1, 0xc1, 0x87, 0x54, 0x54, 0xac, 0x1e,
0x55, 0x40, 0xfb, 0xef, 0xd9, 0x6d, 0x8f, 0x49, 0x08};
static const BYTE issuer_name[] =
{0xe4, 0xe3 ,0x95, 0xa2, 0x29, 0xd3, 0xd4, 0xc1, 0xc3, 0x1f, 0xf0, 0x98, 0x0c, 0x0b, 0x4e, 0xc0,
0x09, 0x8a, 0xab, 0xd8};
static const BYTE issuer_key[] =
{0xb7, 0x6b, 0xa2, 0xea, 0xa8, 0xaa, 0x84, 0x8c, 0x79, 0xea, 0xb4, 0xda, 0x0f, 0x98, 0xb2, 0xc5,
0x95, 0x76, 0xb9, 0xf4};
static const BYTE serial[] =
{0x08, 0x49, 0x8f, 0x6d, 0xd9, 0xef, 0xfb, 0x40, 0x55, 0x1e, 0xac, 0x54, 0x54, 0x87, 0xc1, 0xb1};
OCSP_REQUEST_ENTRY entry[2];
CERT_ALT_NAME_ENTRY name;
OCSP_REQUEST_INFO info;
DWORD size;
BYTE *buf;
BOOL ret;
memset(&entry, 0, sizeof(entry));
entry[0].CertId.HashAlgorithm.pszObjId = (char *)szOID_OIWSEC_sha1;
entry[0].CertId.IssuerNameHash.cbData = sizeof(issuer_name);
entry[0].CertId.IssuerNameHash.pbData = (BYTE *)issuer_name;
entry[0].CertId.IssuerKeyHash.cbData = sizeof(issuer_key);
entry[0].CertId.IssuerKeyHash.pbData = (BYTE *)issuer_key;
entry[0].CertId.SerialNumber.cbData = sizeof(serial);
entry[0].CertId.SerialNumber.pbData = (BYTE *)serial;
name.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
name.pwszDNSName = (WCHAR *)L"*.cm.steampowered.com";
info.dwVersion = OCSP_REQUEST_V1;
info.pRequestorName = &name;
info.cRequestEntry = 1;
info.rgRequestEntry = entry;
info.cExtension = 0;
info.rgExtension = NULL;
size = 0;
SetLastError(0xdeadbeef);
ret = pCryptEncodeObjectEx(dwEncoding, OCSP_REQUEST, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
ok(ret, "got %08lx\n", GetLastError());
ok(size == sizeof(expected), "got %lu\n", size);
ok(!memcmp(buf, expected, sizeof(expected)), "unexpected value\n");
LocalFree(buf);
/* two entries */
entry[1].CertId.HashAlgorithm.pszObjId = (char *)szOID_OIWSEC_sha1;
entry[1].CertId.IssuerNameHash.cbData = sizeof(issuer_name);
entry[1].CertId.IssuerNameHash.pbData = (BYTE *)issuer_name;
entry[1].CertId.IssuerKeyHash.cbData = sizeof(issuer_key);
entry[1].CertId.IssuerKeyHash.pbData = (BYTE *)issuer_key;
entry[1].CertId.SerialNumber.cbData = sizeof(serial);
entry[1].CertId.SerialNumber.pbData = (BYTE *)serial;
info.cRequestEntry = 2;
size = 0;
SetLastError(0xdeadbeef);
ret = pCryptEncodeObjectEx(dwEncoding, OCSP_REQUEST, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
ok(ret, "got %08lx\n", GetLastError());
ok(size == sizeof(expected2), "got %lu\n", size);
ok(!memcmp(buf, expected2, sizeof(expected2)), "unexpected value\n");
LocalFree(buf);
}
START_TEST(encode)
{
static const DWORD encodings[] = { X509_ASN_ENCODING, PKCS_7_ASN_ENCODING,
......@@ -8726,6 +8810,7 @@ START_TEST(encode)
test_encodeCertPolicyConstraints(encodings[i]);
test_decodeCertPolicyConstraints(encodings[i]);
test_decodeRsaPrivateKey(encodings[i]);
test_encodeOCSPRequestInfo(encodings[i]);
}
testPortPublicKeyInfo();
}
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