@@ -824,6 +824,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t scrypt_test(void);
824824#if !defined(NO_ASN_TIME) && !defined(NO_RSA) && defined(WOLFSSL_TEST_CERT) && \
825825 !defined(NO_FILESYSTEM)
826826WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cert_test(void);
827+ static wc_test_ret_t fill_signer_twice_test(void);
827828#endif
828829#if defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_TEST_CERT) && \
829830 !defined(NO_FILESYSTEM) && !defined(NO_RSA) && defined(WOLFSSL_GEN_CERT)
@@ -2737,6 +2738,11 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\
27372738 TEST_FAIL("CERT test failed!\n", ret);
27382739 else
27392740 TEST_PASS("CERT test passed!\n");
2741+
2742+ if ( (ret = fill_signer_twice_test()) != 0)
2743+ TEST_FAIL("FILL SIGNER test failed!\n", ret);
2744+ else
2745+ TEST_PASS("FILL SIGNER test passed!\n");
27402746#endif
27412747
27422748#if defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_TEST_CERT) && \
@@ -22267,6 +22273,111 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cert_test(void)
2226722273}
2226822274#endif /* WOLFSSL_TEST_CERT */
2226922275
22276+ #if !defined(NO_ASN_TIME) && !defined(NO_RSA) && defined(WOLFSSL_TEST_CERT) && \
22277+ !defined(NO_FILESYSTEM)
22278+ /* Test that FillSigner clears pubKeyStored/subjectCNStored after transferring
22279+ * ownership, so a second call doesn't copy stale NULL pointers. */
22280+ static wc_test_ret_t fill_signer_twice_test(void)
22281+ {
22282+ DecodedCert cert;
22283+ Signer* signer1 = NULL;
22284+ Signer* signer2 = NULL;
22285+ DerBuffer* der = NULL;
22286+ byte* tmp = NULL;
22287+ size_t bytes;
22288+ XFILE file;
22289+ wc_test_ret_t ret;
22290+
22291+ WOLFSSL_ENTER("fill_signer_twice_test");
22292+
22293+ tmp = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
22294+ if (tmp == NULL)
22295+ return WC_TEST_RET_ENC_ERRNO;
22296+
22297+ /* Load a DER certificate. */
22298+ file = XFOPEN(certExtNc, "rb");
22299+ if (!file) {
22300+ ERROR_OUT(WC_TEST_RET_ENC_ERRNO, done);
22301+ }
22302+ bytes = XFREAD(tmp, 1, FOURK_BUF, file);
22303+ XFCLOSE(file);
22304+ if (bytes == 0)
22305+ ERROR_OUT(WC_TEST_RET_ENC_ERRNO, done);
22306+
22307+ /* Create a DerBuffer for FillSigner (needed when WOLFSSL_SIGNER_DER_CERT
22308+ * is defined). */
22309+ ret = AllocDer(&der, (word32)bytes, CERT_TYPE, HEAP_HINT);
22310+ if (ret != 0)
22311+ ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done);
22312+ XMEMCPY(der->buffer, tmp, bytes);
22313+
22314+ InitDecodedCert(&cert, tmp, (word32)bytes, 0);
22315+ ret = ParseCert(&cert, CERT_TYPE, NO_VERIFY, NULL);
22316+ if (ret != 0)
22317+ ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done);
22318+
22319+ /* After parsing, pubKeyStored should be set and publicKey non-NULL. */
22320+ if (!cert.pubKeyStored || cert.publicKey == NULL) {
22321+ ERROR_OUT(WC_TEST_RET_ENC_NC, done);
22322+ }
22323+
22324+ /* First FillSigner: transfers publicKey and subjectCN ownership. */
22325+ signer1 = MakeSigner(HEAP_HINT);
22326+ if (signer1 == NULL)
22327+ ERROR_OUT(WC_TEST_RET_ENC_ERRNO, done);
22328+
22329+ ret = FillSigner(signer1, &cert, CA_TYPE, der);
22330+ if (ret != 0)
22331+ ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done);
22332+
22333+ /* signer1 should have received the publicKey. */
22334+ if (signer1->publicKey == NULL) {
22335+ ERROR_OUT(WC_TEST_RET_ENC_NC, done);
22336+ }
22337+
22338+ /* After FillSigner, cert->publicKey should be NULL. */
22339+ if (cert.publicKey != NULL) {
22340+ ERROR_OUT(WC_TEST_RET_ENC_NC, done);
22341+ }
22342+
22343+ /* BUG CHECK: pubKeyStored should have been cleared to 0.
22344+ * If it is still set, a second FillSigner would copy a NULL pointer. */
22345+ if (cert.pubKeyStored != 0) {
22346+ ERROR_OUT(WC_TEST_RET_ENC_NC, done);
22347+ }
22348+
22349+ /* Also check subjectCNStored is cleared. */
22350+ if (cert.subjectCNStored != 0) {
22351+ ERROR_OUT(WC_TEST_RET_ENC_NC, done);
22352+ }
22353+
22354+ /* Second FillSigner on the same cert should not copy NULL pointers. */
22355+ signer2 = MakeSigner(HEAP_HINT);
22356+ if (signer2 == NULL)
22357+ ERROR_OUT(WC_TEST_RET_ENC_ERRNO, done);
22358+
22359+ ret = FillSigner(signer2, &cert, CA_TYPE, der);
22360+ if (ret != 0)
22361+ ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done);
22362+
22363+ /* signer2 should NOT have a publicKey (since cert no longer owns one). */
22364+ if (signer2->publicKey != NULL) {
22365+ ERROR_OUT(WC_TEST_RET_ENC_NC, done);
22366+ }
22367+
22368+ done:
22369+ FreeDecodedCert(&cert);
22370+ if (signer1 != NULL)
22371+ FreeSigner(signer1, HEAP_HINT);
22372+ if (signer2 != NULL)
22373+ FreeSigner(signer2, HEAP_HINT);
22374+ FreeDer(&der);
22375+ XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
22376+
22377+ return ret;
22378+ }
22379+ #endif /* !NO_ASN_TIME && !NO_RSA && WOLFSSL_TEST_CERT && !NO_FILESYSTEM */
22380+
2227022381#if defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_TEST_CERT) && \
2227122382 !defined(NO_FILESYSTEM) && !defined(NO_RSA) && defined(WOLFSSL_GEN_CERT)
2227222383WOLFSSL_TEST_SUBROUTINE wc_test_ret_t certext_test(void)
0 commit comments