@@ -30844,6 +30844,53 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t pwdbased_test(void)
3084430844 if (ret != 0)
3084530845 return ret;
3084630846#endif
30847+ #if defined(HAVE_PKCS12) && !defined(NO_ASN) && !defined(NO_PWDBASED) && \
30848+ !defined(NO_HMAC) && !defined(NO_CERTS)
30849+ /* Test that a crafted PKCS#12 with INT_MAX MAC iterations is rejected
30850+ * immediately rather than hanging in DoPKCS12Hash(). */
30851+ {
30852+ static const byte evil_p12[] = {
30853+ 0x30, 0x58, 0x02, 0x01, 0x03, 0x30, 0x1e, 0x06,
30854+ 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
30855+ 0x07, 0x01, 0xa0, 0x11, 0x04, 0x0f, 0x30, 0x0d,
30856+ 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
30857+ 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30, 0x33, 0x30,
30858+ 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
30859+ 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x00, 0x00,
30860+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
30861+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
30862+ 0x00, 0x00, 0x04, 0x08, 0x41, 0x41, 0x41, 0x41,
30863+ 0x41, 0x41, 0x41, 0x41, 0x02, 0x04, 0x7f, 0xff,
30864+ 0xff, 0xff
30865+ };
30866+ WC_PKCS12* evilPkcs12 = wc_PKCS12_new_ex(HEAP_HINT);
30867+ if (evilPkcs12 == NULL)
30868+ return WC_TEST_RET_ENC_EC(MEMORY_E);
30869+
30870+ ret = wc_d2i_PKCS12(evil_p12, (word32)sizeof(evil_p12), evilPkcs12);
30871+ if (ret == 0) {
30872+ byte* evilKey = NULL;
30873+ byte* evilCert = NULL;
30874+ word32 evilKeySz = 0, evilCertSz = 0;
30875+ WC_DerCertList* evilCa = NULL;
30876+
30877+ ret = wc_PKCS12_parse(evilPkcs12, "test", &evilKey, &evilKeySz,
30878+ &evilCert, &evilCertSz, &evilCa);
30879+ XFREE(evilKey, HEAP_HINT, DYNAMIC_TYPE_PKCS);
30880+ XFREE(evilCert, HEAP_HINT, DYNAMIC_TYPE_PKCS);
30881+ if (evilCa)
30882+ wc_FreeCertList(evilCa, HEAP_HINT);
30883+ wc_PKCS12_free(evilPkcs12);
30884+ /* Parse must fail (iteration cap), not succeed or hang */
30885+ if (ret == 0)
30886+ return WC_TEST_RET_ENC_NC;
30887+ }
30888+ else {
30889+ wc_PKCS12_free(evilPkcs12);
30890+ }
30891+ ret = 0;
30892+ }
30893+ #endif /* HAVE_PKCS12 && !NO_ASN && !NO_PWDBASED && !NO_HMAC && !NO_CERTS */
3084730894#ifdef HAVE_SCRYPT
3084830895 ret = scrypt_test();
3084930896 if (ret != 0)
@@ -30943,6 +30990,56 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t pkcs12_test(void)
3094330990 goto out;
3094430991 }
3094530992
30993+ /* Test that a crafted PKCS#12 with INT_MAX MAC iterations is rejected
30994+ * immediately rather than hanging in DoPKCS12Hash(). This is a 90-byte
30995+ * minimal PKCS#12 with mac->itt = 0x7FFFFFFF (2,147,483,647). */
30996+ {
30997+ static const byte evil_p12[] = {
30998+ 0x30, 0x58, 0x02, 0x01, 0x03, 0x30, 0x1e, 0x06,
30999+ 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
31000+ 0x07, 0x01, 0xa0, 0x11, 0x04, 0x0f, 0x30, 0x0d,
31001+ 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
31002+ 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30, 0x33, 0x30,
31003+ 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
31004+ 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x00, 0x00,
31005+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
31006+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
31007+ 0x00, 0x00, 0x04, 0x08, 0x41, 0x41, 0x41, 0x41,
31008+ 0x41, 0x41, 0x41, 0x41, 0x02, 0x04, 0x7f, 0xff,
31009+ 0xff, 0xff
31010+ };
31011+ WC_PKCS12* evilPkcs12 = wc_PKCS12_new_ex(HEAP_HINT);
31012+ if (evilPkcs12 == NULL) {
31013+ ret = WC_TEST_RET_ENC_EC(MEMORY_E);
31014+ goto out;
31015+ }
31016+ ret = wc_d2i_PKCS12(evil_p12, (word32)sizeof(evil_p12), evilPkcs12);
31017+ if (ret != 0) {
31018+ wc_PKCS12_free(evilPkcs12);
31019+ ret = WC_TEST_RET_ENC_EC(ret);
31020+ goto out;
31021+ }
31022+ {
31023+ byte* evilKey = NULL;
31024+ byte* evilCert = NULL;
31025+ word32 evilKeySz = 0, evilCertSz = 0;
31026+ WC_DerCertList* evilCa = NULL;
31027+ ret = wc_PKCS12_parse(evilPkcs12, "test", &evilKey, &evilKeySz,
31028+ &evilCert, &evilCertSz, &evilCa);
31029+ XFREE(evilKey, HEAP_HINT, DYNAMIC_TYPE_PKCS);
31030+ XFREE(evilCert, HEAP_HINT, DYNAMIC_TYPE_PKCS);
31031+ if (evilCa)
31032+ wc_FreeCertList(evilCa, HEAP_HINT);
31033+ }
31034+ wc_PKCS12_free(evilPkcs12);
31035+ /* Must have been rejected (not hung) */
31036+ if (ret == 0) {
31037+ ret = WC_TEST_RET_ENC_NC;
31038+ goto out;
31039+ }
31040+ ret = 0; /* rejection is the expected outcome */
31041+ }
31042+
3094631043out:
3094731044
3094831045 if (derCaListOut)
0 commit comments