Juan Lang : crypt32: Test and correct decoding indefinite-length-encoded PKCS content.

Alexandre Julliard julliard at winehq.org
Tue Sep 18 05:31:33 CDT 2007


Module: wine
Branch: master
Commit: 7e475b4a774edf29d7c3ae5def5f0d0f5d159368
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=7e475b4a774edf29d7c3ae5def5f0d0f5d159368

Author: Juan Lang <juan.lang at gmail.com>
Date:   Mon Sep 17 17:29:37 2007 -0700

crypt32: Test and correct decoding indefinite-length-encoded PKCS content.

---

 dlls/crypt32/decode.c       |   38 ++++++++++++++++++++++++++++-------
 dlls/crypt32/tests/encode.c |   46 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 76 insertions(+), 8 deletions(-)

diff --git a/dlls/crypt32/decode.c b/dlls/crypt32/decode.c
index f0fab24..8da7138 100644
--- a/dlls/crypt32/decode.c
+++ b/dlls/crypt32/decode.c
@@ -2456,21 +2456,43 @@ static BOOL CRYPT_AsnDecodePKCSContent(const BYTE *pbEncoded, DWORD cbEncoded,
      pvStructInfo, *pcbStructInfo, pcbDecoded);
 
     /* The caller has already checked the tag, no need to check it again.
-     * Check the outer length is valid by calling CRYPT_GetLen:
+     * Check the outer length is valid:
      */
-    if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
+    if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
     {
         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
         DWORD innerLen;
 
         pbEncoded += 1 + lenBytes;
-        /* Check the inner length is valid by calling CRYPT_GetLen again: */
-        if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &innerLen)))
+        cbEncoded -= 1 + lenBytes;
+        if (dataLen == CMSG_INDEFINITE_LENGTH)
+            cbEncoded -= 2; /* space for 0 TLV */
+        /* Check the inner length is valid: */
+        if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &innerLen)))
         {
-            ret = CRYPT_AsnDecodeCopyBytes(pbEncoded, dataLen, dwFlags,
-             pvStructInfo, pcbStructInfo, NULL);
-            if (pcbDecoded)
-                *pcbDecoded = 1 + lenBytes + dataLen;
+            DWORD decodedLen;
+
+            ret = CRYPT_AsnDecodeCopyBytes(pbEncoded, cbEncoded, dwFlags,
+             pvStructInfo, pcbStructInfo, &decodedLen);
+            if (dataLen == CMSG_INDEFINITE_LENGTH)
+            {
+                if (*(pbEncoded + decodedLen) != 0 ||
+                 *(pbEncoded + decodedLen + 1) != 0)
+                {
+                    TRACE("expected 0 TLV, got {%02x,%02x}\n",
+                     *(pbEncoded + decodedLen),
+                     *(pbEncoded + decodedLen + 1));
+                    SetLastError(CRYPT_E_ASN1_CORRUPT);
+                    ret = FALSE;
+                }
+                else
+                    decodedLen += 2;
+            }
+            if (ret && pcbDecoded)
+            {
+                *pcbDecoded = 1 + lenBytes + decodedLen;
+                TRACE("decoded %d bytes\n", *pcbDecoded);
+            }
         }
     }
     return ret;
diff --git a/dlls/crypt32/tests/encode.c b/dlls/crypt32/tests/encode.c
index 13d288b..3e29db0 100644
--- a/dlls/crypt32/tests/encode.c
+++ b/dlls/crypt32/tests/encode.c
@@ -4799,6 +4799,36 @@ static void test_encodePKCSContentInfo(DWORD dwEncoding)
     }
 }
 
+static const BYTE indefiniteSignedPKCSContent[] = {
+0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x80,
+0x30,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
+0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
+0x0d,0x01,0x07,0x01,0xa0,0x80,0x24,0x80,0x04,0x04,0x01,0x02,0x03,0x04,0x04,
+0x04,0x01,0x02,0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x81,0xd2,0x30,
+0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
+0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
+0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
+0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
+0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
+0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
+0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
+0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,
+0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,
+0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,
+0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,
+0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,
+0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,
+0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,
+0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
+0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
+0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
+0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x57,0xba,0xe0,0xad,
+0xfe,0x36,0x8d,0xb3,0x88,0xa2,0x8d,0x84,0x82,0x52,0x09,0x09,0xd9,0xf0,0xb8,
+0x04,0xfa,0xb5,0x51,0x0b,0x2b,0x2e,0xd5,0x72,0x3e,0x3d,0x13,0x8a,0x51,0xc3,
+0x71,0x65,0x9a,0x52,0xf2,0x8f,0xb2,0x5b,0x39,0x28,0xb3,0x29,0x36,0xa5,0x8d,
+0xe3,0x55,0x71,0x91,0xf9,0x2a,0xd1,0xb8,0xaa,0x52,0xb8,0x22,0x3a,0xeb,0x61,
+0x00,0x00,0x00,0x00,0x00,0x00 };
+
 static void test_decodePKCSContentInfo(DWORD dwEncoding)
 {
     BOOL ret;
@@ -4849,6 +4879,22 @@ static void test_decodePKCSContentInfo(DWORD dwEncoding)
          "Unexpected size %d\n", info->Content.cbData);
         ok(!memcmp(info->Content.pbData, ints[0].encoded,
          info->Content.cbData), "Unexpected value\n");
+        LocalFree(buf);
+    }
+    ret = CryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
+     indefiniteSignedPKCSContent, sizeof(indefiniteSignedPKCSContent),
+     CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
+    ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
+    if (buf)
+    {
+        info = (CRYPT_CONTENT_INFO *)buf;
+
+        ok(!strcmp(info->pszObjId, szOID_RSA_signedData),
+         "Expected %s, got %s\n", szOID_RSA_signedData, info->pszObjId);
+        todo_wine
+        ok(info->Content.cbData == 392, "Expected 392, got %d\n",
+         info->Content.cbData);
+        LocalFree(buf);
     }
 }
 




More information about the wine-cvs mailing list