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