Skip to content

Commit 03beeae

Browse files
authored
Merge pull request #10033 from embhorn/gh10028
Fix FillSigner to clear pubkeystored
2 parents d36ddf4 + 1d1d8ff commit 03beeae

4 files changed

Lines changed: 142 additions & 16 deletions

File tree

examples/ocsp_responder/ocsp_responder.c

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -199,23 +199,29 @@ static int ConvertPemToDer(const byte* pem, word32 pemSz,
199199
byte** der, word32* derSz, int type)
200200
{
201201
int ret;
202-
DerBuffer* derBuf = NULL;
203202

204-
ret = wc_PemToDer(pem, pemSz, type, &derBuf, NULL, NULL, NULL);
205-
if (ret != 0 || derBuf == NULL) {
206-
return ret;
207-
}
208-
209-
*der = (byte*)XMALLOC(derBuf->length, NULL, DYNAMIC_TYPE_TMP_BUFFER);
203+
/* Allocate buffer large enough for DER (always smaller than PEM) */
204+
*der = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
210205
if (*der == NULL) {
211-
wc_FreeDer(&derBuf);
212206
return MEMORY_E;
213207
}
214208

215-
XMEMCPY(*der, derBuf->buffer, derBuf->length);
216-
*derSz = derBuf->length;
217-
wc_FreeDer(&derBuf);
209+
if (type == PRIVATEKEY_TYPE) {
210+
ret = wc_KeyPemToDer(pem, (int)pemSz, *der, (int)pemSz, NULL);
211+
}
212+
else {
213+
ret = wc_CertPemToDer(pem, (int)pemSz, *der, (int)pemSz, type);
214+
}
215+
216+
if (ret <= 0) {
217+
XFREE(*der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
218+
*der = NULL;
219+
if (ret == 0)
220+
ret = BAD_FUNC_ARG;
221+
return ret;
222+
}
218223

224+
*derSz = (word32)ret;
219225
return 0;
220226
}
221227

wolfcrypt/src/asn.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22499,7 +22499,9 @@ int FillSigner(Signer* signer, DecodedCert* cert, int type, DerBuffer *der)
2249922499
signer->extKeyUsage = cert->extExtKeyUsage;
2250022500
signer->next = NULL; /* If Key Usage not set, all uses valid. */
2250122501
cert->publicKey = 0; /* in case lock fails don't free here. */
22502+
cert->pubKeyStored = 0;
2250222503
cert->subjectCN = 0;
22504+
cert->subjectCNStored = 0;
2250322505
#ifndef IGNORE_NAME_CONSTRAINTS
2250422506
cert->permittedNames = NULL;
2250522507
cert->excludedNames = NULL;
@@ -22794,6 +22796,7 @@ void FreeDer(DerBuffer** pDer)
2279422796
}
2279522797
}
2279622798

22799+
#ifndef WOLFSSL_API_PREFIX_MAP
2279722800
int wc_AllocDer(DerBuffer** pDer, word32 length, int type, void* heap)
2279822801
{
2279922802
return AllocDer(pDer, length, type, heap);
@@ -22802,6 +22805,7 @@ void wc_FreeDer(DerBuffer** pDer)
2280222805
{
2280322806
FreeDer(pDer);
2280422807
}
22808+
#endif
2280522809

2280622810

2280722811
#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)

wolfcrypt/test/test.c

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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)
826826
WOLFSSL_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)
2227222383
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t certext_test(void)

wolfssl/wolfcrypt/asn.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2254,6 +2254,11 @@ typedef enum MimeStatus
22542254
*/
22552255
#define GetCAByAKID wolfSSL_GetCAByAKID
22562256
#endif
2257+
#define FillSigner wc_FillSigner
2258+
#define MakeSigner wc_MakeSigner
2259+
#define FreeSigner wc_FreeSigner
2260+
#define AllocDer wc_AllocDer
2261+
#define FreeDer wc_FreeDer
22572262
#endif /* WOLFSSL_API_PREFIX_MAP */
22582263

22592264
WOLFSSL_LOCAL int HashIdAlg(word32 oidSum);
@@ -2363,9 +2368,9 @@ WOLFSSL_LOCAL int wc_GetPubX509(DecodedCert* cert, int verify, int* badDate);
23632368
WOLFSSL_LOCAL const byte* OidFromId(word32 id, word32 type, word32* oidSz);
23642369
WOLFSSL_LOCAL Signer* findSignerByKeyHash(Signer *list, byte *hash);
23652370
WOLFSSL_LOCAL Signer* findSignerByName(Signer *list, byte *hash);
2366-
WOLFSSL_LOCAL int FillSigner(Signer* signer, DecodedCert* cert, int type, DerBuffer *der);
2367-
WOLFSSL_LOCAL Signer* MakeSigner(void* heap);
2368-
WOLFSSL_LOCAL void FreeSigner(Signer* signer, void* heap);
2371+
WOLFSSL_TEST_VIS int FillSigner(Signer* signer, DecodedCert* cert, int type, DerBuffer *der);
2372+
WOLFSSL_TEST_VIS Signer* MakeSigner(void* heap);
2373+
WOLFSSL_TEST_VIS void FreeSigner(Signer* signer, void* heap);
23692374
WOLFSSL_LOCAL void FreeSignerTable(Signer** table, int rows, void* heap);
23702375
WOLFSSL_LOCAL void FreeSignerTableType(Signer** table, int rows, byte type,
23712376
void* heap);
@@ -2608,11 +2613,11 @@ WOLFSSL_LOCAL int wc_EncryptedInfoParse(EncryptedInfo* info,
26082613
WOLFSSL_LOCAL int PemToDer(const unsigned char* buff, long longSz, int type,
26092614
DerBuffer** pDer, void* heap, EncryptedInfo* info,
26102615
int* keyFormat);
2611-
WOLFSSL_LOCAL int AllocDer(DerBuffer** der, word32 length, int type,
2616+
WOLFSSL_API int AllocDer(DerBuffer** der, word32 length, int type,
26122617
void* heap);
26132618
WOLFSSL_LOCAL int AllocCopyDer(DerBuffer** der, const unsigned char* buff,
26142619
word32 length, int type, void* heap);
2615-
WOLFSSL_LOCAL void FreeDer(DerBuffer** der);
2620+
WOLFSSL_API void FreeDer(DerBuffer** der);
26162621

26172622
#ifdef WOLFSSL_ASN_PARSE_KEYUSAGE
26182623
WOLFSSL_LOCAL int ParseKeyUsageStr(const char* value, word16* keyUsage,

0 commit comments

Comments
 (0)