@@ -2711,6 +2711,72 @@ int test_wc_PKCS7_DecodeEnvelopedData_stream(void)
27112711} /* END test_wc_PKCS7_DecodeEnvelopedData_stream() */
27122712
27132713
2714+ /*
2715+ * Regression test: a PKCS#7 EnvelopedData with a forged RecipientInfo SET
2716+ * length (parsed via GetSet_ex with NO_USER_CHECK) must not drive an
2717+ * uncapped heap allocation through wc_PKCS7_GrowStream(). The decoder
2718+ * must reject the oversized allocation rather than attempting it.
2719+ */
2720+ int test_wc_PKCS7_DecodeEnvelopedData_forgedRecipientSetLen (void )
2721+ {
2722+ EXPECT_DECLS ;
2723+ #if defined(HAVE_PKCS7 ) && !defined(NO_RSA ) && !defined(NO_PKCS7_STREAM )
2724+ /* Crafted ContentInfo/EnvelopedData header. All lengths use the
2725+ * 4-byte long form for clarity. The RecipientInfo SET length is
2726+ * forged to 0x01000001 (16 MB + 1), which exceeds the default
2727+ * WOLFSSL_PKCS7_MAX_STREAM_ALLOC cap and should be rejected before
2728+ * any allocation succeeds. The body after the SET header is never
2729+ * consumed because the decoder fails at the GrowStream() cap. */
2730+ static const byte forged [] = {
2731+ /* ContentInfo SEQUENCE, body length 0x01000021 */
2732+ 0x30 , 0x84 , 0x01 , 0x00 , 0x00 , 0x21 ,
2733+ /* OID 1.2.840.113549.1.7.3 (id-envelopedData) */
2734+ 0x06 , 0x09 , 0x2A , 0x86 , 0x48 , 0x86 , 0xF7 , 0x0D ,
2735+ 0x01 , 0x07 , 0x03 ,
2736+ /* [0] EXPLICIT content, body length 0x01000016 */
2737+ 0xA0 , 0x84 , 0x01 , 0x00 , 0x00 , 0x16 ,
2738+ /* EnvelopedData SEQUENCE, body length 0x01000010 */
2739+ 0x30 , 0x84 , 0x01 , 0x00 , 0x00 , 0x10 ,
2740+ /* version INTEGER 0 */
2741+ 0x02 , 0x01 , 0x00 ,
2742+ /* Forged RecipientInfo SET header: length = 0x01000001 */
2743+ 0x31 , 0x84 , 0x01 , 0x00 , 0x00 , 0x01 ,
2744+ /* Padding so that header-parsing states can buffer their
2745+ * required lookahead without returning WC_PKCS7_WANT_READ_E.
2746+ * These bytes are never interpreted. */
2747+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
2748+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
2749+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
2750+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
2751+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
2752+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
2753+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
2754+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF
2755+ };
2756+ PKCS7 * pkcs7 = NULL ;
2757+ byte out [32 ];
2758+ int ret ;
2759+
2760+ ExpectNotNull (pkcs7 = wc_PKCS7_New (HEAP_HINT , testDevId ));
2761+ ExpectIntEQ (wc_PKCS7_InitWithCert (pkcs7 , (byte * )client_cert_der_2048 ,
2762+ sizeof_client_cert_der_2048 ), 0 );
2763+ ExpectIntEQ (wc_PKCS7_SetKey (pkcs7 , (byte * )client_key_der_2048 ,
2764+ sizeof_client_key_der_2048 ), 0 );
2765+
2766+ ret = wc_PKCS7_DecodeEnvelopedData (pkcs7 , (byte * )forged ,
2767+ (word32 )sizeof (forged ), out , (word32 )sizeof (out ));
2768+ /* Must NOT return WC_PKCS7_WANT_READ_E (which would imply the
2769+ * oversized allocation succeeded and the decoder is waiting for
2770+ * the around 16 MB of SET body). Must NOT return 0 / positive length.
2771+ * Expected: BUFFER_E from the GrowStream cap. */
2772+ ExpectIntEQ (ret , WC_NO_ERR_TRACE (BUFFER_E ));
2773+
2774+ wc_PKCS7_Free (pkcs7 );
2775+ #endif
2776+ return EXPECT_RESULT ();
2777+ } /* END test_wc_PKCS7_DecodeEnvelopedData_forgedRecipientSetLen() */
2778+
2779+
27142780/*
27152781 * Testing wc_PKCS7_DecodeEnvelopedData with streaming
27162782 */
0 commit comments