crypt32: Add support for encoding OCSP requests.
Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
39d6ac0d9c
commit
92821ebd49
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue