@@ -822,6 +822,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t scrypt_test(void);
822822#if !defined(NO_ASN_TIME) && !defined(NO_RSA) && defined(WOLFSSL_TEST_CERT) && \
823823 !defined(NO_FILESYSTEM)
824824WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cert_test(void);
825+ static wc_test_ret_t fill_signer_twice_test(void);
825826#endif
826827#if defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_TEST_CERT) && \
827828 !defined(NO_FILESYSTEM) && !defined(NO_RSA) && defined(WOLFSSL_GEN_CERT)
@@ -2733,6 +2734,11 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\
27332734 TEST_FAIL("CERT test failed!\n", ret);
27342735 else
27352736 TEST_PASS("CERT test passed!\n");
2737+
2738+ if ( (ret = fill_signer_twice_test()) != 0)
2739+ TEST_FAIL("FILL SIGNER test failed!\n", ret);
2740+ else
2741+ TEST_PASS("FILL SIGNER test passed!\n");
27362742#endif
27372743
27382744#if defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_TEST_CERT) && \
@@ -22252,6 +22258,111 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cert_test(void)
2225222258}
2225322259#endif /* WOLFSSL_TEST_CERT */
2225422260
22261+ #if !defined(NO_ASN_TIME) && !defined(NO_RSA) && defined(WOLFSSL_TEST_CERT) && \
22262+ !defined(NO_FILESYSTEM)
22263+ /* Test that FillSigner clears pubKeyStored/subjectCNStored after transferring
22264+ * ownership, so a second call doesn't copy stale NULL pointers. */
22265+ static wc_test_ret_t fill_signer_twice_test(void)
22266+ {
22267+ DecodedCert cert;
22268+ Signer* signer1 = NULL;
22269+ Signer* signer2 = NULL;
22270+ DerBuffer* der = NULL;
22271+ byte* tmp = NULL;
22272+ size_t bytes;
22273+ XFILE file;
22274+ wc_test_ret_t ret;
22275+
22276+ WOLFSSL_ENTER("fill_signer_twice_test");
22277+
22278+ tmp = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
22279+ if (tmp == NULL)
22280+ return WC_TEST_RET_ENC_ERRNO;
22281+
22282+ /* Load a DER certificate. */
22283+ file = XFOPEN(certExtNc, "rb");
22284+ if (!file) {
22285+ ERROR_OUT(WC_TEST_RET_ENC_ERRNO, done);
22286+ }
22287+ bytes = XFREAD(tmp, 1, FOURK_BUF, file);
22288+ XFCLOSE(file);
22289+ if (bytes == 0)
22290+ ERROR_OUT(WC_TEST_RET_ENC_ERRNO, done);
22291+
22292+ /* Create a DerBuffer for FillSigner (needed when WOLFSSL_SIGNER_DER_CERT
22293+ * is defined). */
22294+ ret = AllocDer(&der, (word32)bytes, CERT_TYPE, HEAP_HINT);
22295+ if (ret != 0)
22296+ ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done);
22297+ XMEMCPY(der->buffer, tmp, bytes);
22298+
22299+ InitDecodedCert(&cert, tmp, (word32)bytes, 0);
22300+ ret = ParseCert(&cert, CERT_TYPE, NO_VERIFY, NULL);
22301+ if (ret != 0)
22302+ ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done);
22303+
22304+ /* After parsing, pubKeyStored should be set and publicKey non-NULL. */
22305+ if (!cert.pubKeyStored || cert.publicKey == NULL) {
22306+ ERROR_OUT(WC_TEST_RET_ENC_NC, done);
22307+ }
22308+
22309+ /* First FillSigner: transfers publicKey and subjectCN ownership. */
22310+ signer1 = MakeSigner(HEAP_HINT);
22311+ if (signer1 == NULL)
22312+ ERROR_OUT(WC_TEST_RET_ENC_ERRNO, done);
22313+
22314+ ret = FillSigner(signer1, &cert, CA_TYPE, der);
22315+ if (ret != 0)
22316+ ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done);
22317+
22318+ /* signer1 should have received the publicKey. */
22319+ if (signer1->publicKey == NULL) {
22320+ ERROR_OUT(WC_TEST_RET_ENC_NC, done);
22321+ }
22322+
22323+ /* After FillSigner, cert->publicKey should be NULL. */
22324+ if (cert.publicKey != NULL) {
22325+ ERROR_OUT(WC_TEST_RET_ENC_NC, done);
22326+ }
22327+
22328+ /* BUG CHECK: pubKeyStored should have been cleared to 0.
22329+ * If it is still set, a second FillSigner would copy a NULL pointer. */
22330+ if (cert.pubKeyStored != 0) {
22331+ ERROR_OUT(WC_TEST_RET_ENC_NC, done);
22332+ }
22333+
22334+ /* Also check subjectCNStored is cleared. */
22335+ if (cert.subjectCNStored != 0) {
22336+ ERROR_OUT(WC_TEST_RET_ENC_NC, done);
22337+ }
22338+
22339+ /* Second FillSigner on the same cert should not copy NULL pointers. */
22340+ signer2 = MakeSigner(HEAP_HINT);
22341+ if (signer2 == NULL)
22342+ ERROR_OUT(WC_TEST_RET_ENC_ERRNO, done);
22343+
22344+ ret = FillSigner(signer2, &cert, CA_TYPE, der);
22345+ if (ret != 0)
22346+ ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done);
22347+
22348+ /* signer2 should NOT have a publicKey (since cert no longer owns one). */
22349+ if (signer2->publicKey != NULL) {
22350+ ERROR_OUT(WC_TEST_RET_ENC_NC, done);
22351+ }
22352+
22353+ done:
22354+ FreeDecodedCert(&cert);
22355+ if (signer1 != NULL)
22356+ FreeSigner(signer1, HEAP_HINT);
22357+ if (signer2 != NULL)
22358+ FreeSigner(signer2, HEAP_HINT);
22359+ FreeDer(&der);
22360+ XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
22361+
22362+ return ret;
22363+ }
22364+ #endif /* !NO_ASN_TIME && !NO_RSA && WOLFSSL_TEST_CERT && !NO_FILESYSTEM */
22365+
2225522366#if defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_TEST_CERT) && \
2225622367 !defined(NO_FILESYSTEM) && !defined(NO_RSA) && defined(WOLFSSL_GEN_CERT)
2225722368WOLFSSL_TEST_SUBROUTINE wc_test_ret_t certext_test(void)
0 commit comments