Hans Leidekker : crypt32: Add support for decoding OCSP_BASIC_REVOKED_INFO structures.
Alexandre Julliard
julliard at winehq.org
Tue May 24 15:54:59 CDT 2022
Module: wine
Branch: master
Commit: 8a463a335bff516833edf20fdfe7abb3de70fd03
URL: https://source.winehq.org/git/wine.git/?a=commit;h=8a463a335bff516833edf20fdfe7abb3de70fd03
Author: Hans Leidekker <hans at codeweavers.com>
Date: Tue May 24 09:46:20 2022 +0200
crypt32: Add support for decoding OCSP_BASIC_REVOKED_INFO structures.
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/crypt32/decode.c | 113 ++++++++++++++++++++++++++++++++++++++++++--
dlls/crypt32/tests/encode.c | 4 +-
2 files changed, 110 insertions(+), 7 deletions(-)
diff --git a/dlls/crypt32/decode.c b/dlls/crypt32/decode.c
index 762d1b54661..60f9868ed67 100644
--- a/dlls/crypt32/decode.c
+++ b/dlls/crypt32/decode.c
@@ -6351,6 +6351,112 @@ static BOOL CRYPT_AsnDecodeOCSPNextUpdate(const BYTE *pbEncoded,
return ret;
}
+static BOOL CRYPT_AsnDecodeCertStatus(const BYTE *pbEncoded,
+ DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
+ DWORD *pcbDecoded)
+{
+ BOOL ret = TRUE;
+ BYTE tag = pbEncoded[0] & ~3, status = pbEncoded[0] & 3;
+ DWORD bytesNeeded = FIELD_OFFSET(OCSP_BASIC_RESPONSE_ENTRY, ThisUpdate) -
+ FIELD_OFFSET(OCSP_BASIC_RESPONSE_ENTRY, dwCertStatus);
+
+ if (!cbEncoded)
+ {
+ SetLastError(CRYPT_E_ASN1_EOD);
+ return FALSE;
+ }
+
+ switch (status)
+ {
+ case 0:
+ if (tag != ASN_CONTEXT)
+ {
+ WARN("Unexpected tag %02x\n", tag);
+ SetLastError(CRYPT_E_ASN1_BADTAG);
+ return FALSE;
+ }
+ if (cbEncoded < 2 || pbEncoded[1])
+ {
+ SetLastError(CRYPT_E_ASN1_CORRUPT);
+ return FALSE;
+ }
+ if (!pvStructInfo)
+ *pcbStructInfo = bytesNeeded;
+ else if (*pcbStructInfo < bytesNeeded)
+ {
+ *pcbStructInfo = bytesNeeded;
+ SetLastError(ERROR_MORE_DATA);
+ return FALSE;
+ }
+ if (pvStructInfo)
+ {
+ *(DWORD *)pvStructInfo = 0;
+ *(OCSP_BASIC_REVOKED_INFO **)((char *)pvStructInfo
+ + FIELD_OFFSET(OCSP_BASIC_RESPONSE_ENTRY, u.pRevokedInfo)
+ - FIELD_OFFSET(OCSP_BASIC_RESPONSE_ENTRY, dwCertStatus)) = NULL;
+ }
+ *pcbStructInfo = bytesNeeded;
+ *pcbDecoded = 2;
+ break;
+
+ case 1:
+ {
+ DWORD dataLen;
+
+ if (tag != (ASN_CONTEXT | ASN_CONSTRUCTOR))
+ {
+ WARN("Unexpected tag %02x\n", tag);
+ SetLastError(CRYPT_E_ASN1_BADTAG);
+ return FALSE;
+ }
+ if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
+ {
+ BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
+ DWORD bytesDecoded, size;
+ FILETIME date;
+
+ if (dataLen)
+ {
+ size = sizeof(date);
+ ret = CRYPT_AsnDecodeGeneralizedTime(pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
+ dwFlags, &date, &size, &bytesDecoded);
+ if (ret)
+ {
+ OCSP_BASIC_REVOKED_INFO *info;
+
+ bytesNeeded += sizeof(*info);
+ if (!pvStructInfo)
+ *pcbStructInfo = bytesNeeded;
+ else if (*pcbStructInfo < bytesNeeded)
+ {
+ *pcbStructInfo = bytesNeeded;
+ SetLastError(ERROR_MORE_DATA);
+ return FALSE;
+ }
+ if (pvStructInfo)
+ {
+ *(DWORD *)pvStructInfo = 1;
+ info = *(OCSP_BASIC_REVOKED_INFO **)((char *)pvStructInfo
+ + FIELD_OFFSET(OCSP_BASIC_RESPONSE_ENTRY, u.pRevokedInfo)
+ - FIELD_OFFSET(OCSP_BASIC_RESPONSE_ENTRY, dwCertStatus));
+ info->RevocationDate = date;
+ }
+ *pcbStructInfo = bytesNeeded;
+ *pcbDecoded = 1 + lenBytes + bytesDecoded;
+ }
+ }
+ }
+ break;
+ }
+ default:
+ FIXME("Unhandled status %u\n", status);
+ SetLastError(CRYPT_E_ASN1_BADTAG);
+ return FALSE;
+ }
+
+ return ret;
+}
+
static BOOL CRYPT_AsnDecodeOCSPBasicResponseEntry(const BYTE *pbEncoded, DWORD cbEncoded,
DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
@@ -6367,10 +6473,9 @@ static BOOL CRYPT_AsnDecodeOCSPBasicResponseEntry(const BYTE *pbEncoded, DWORD c
{ ASN_INTEGER, offsetof(OCSP_BASIC_RESPONSE_ENTRY, CertId.SerialNumber),
CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE, TRUE,
offsetof(OCSP_BASIC_RESPONSE_ENTRY, CertId.SerialNumber.pbData), 0 },
- { ASN_CONTEXT, offsetof(OCSP_BASIC_RESPONSE_ENTRY, dwCertStatus),
- CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE,
- 0, 0 },
- /* FIXME: pRevokedInfo */
+ { 0, offsetof(OCSP_BASIC_RESPONSE_ENTRY, dwCertStatus),
+ CRYPT_AsnDecodeCertStatus, sizeof(DWORD), FALSE, TRUE,
+ offsetof(OCSP_BASIC_RESPONSE_ENTRY, u.pRevokedInfo), 0 },
{ ASN_GENERALTIME, offsetof(OCSP_BASIC_RESPONSE_ENTRY, ThisUpdate),
CRYPT_AsnDecodeGeneralizedTime, sizeof(FILETIME), FALSE, FALSE,
0, 0 },
diff --git a/dlls/crypt32/tests/encode.c b/dlls/crypt32/tests/encode.c
index b65ffde3a84..c611bb63936 100644
--- a/dlls/crypt32/tests/encode.c
+++ b/dlls/crypt32/tests/encode.c
@@ -8824,9 +8824,8 @@ static void test_decodeOCSPBasicResponseInfo(DWORD dwEncoding)
size = 0;
ret = CryptDecodeObjectEx(dwEncoding, OCSP_BASIC_RESPONSE, ocsp_basic_response_revoked,
sizeof(ocsp_basic_response_revoked), CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
- todo_wine ok(ret, "got %08lx\n", GetLastError());
+ ok(ret, "got %08lx\n", GetLastError());
- if (ret) {
ok(!info->dwVersion, "got %lu\n", info->dwVersion);
ok(info->dwResponderIdChoice == 2, "got %lu\n", info->dwResponderIdChoice);
ok(info->ByKeyResponderId.cbData == sizeof(resp_id), "got %lu\n", info->ByKeyResponderId.cbData);
@@ -8864,7 +8863,6 @@ static void test_decodeOCSPBasicResponseInfo(DWORD dwEncoding)
ok(!info->cExtension, "got %lu\n", info->cExtension);
ok(info->rgExtension == NULL, "got %p\n", info->rgExtension);
- }
LocalFree(info);
}
More information about the wine-cvs
mailing list