From 8aa97fdf854a2ec6c1e7b74871efdf131187c073 Mon Sep 17 00:00:00 2001 From: Juan Lang Date: Mon, 17 Sep 2007 17:29:37 -0700 Subject: [PATCH] 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(c 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(D } } +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(D "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); } } -- 1.4.1