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