Skip to content

Commit 99ee724

Browse files
committed
Fix bugs found in crl.c, keys.c, and ssl_certman.c review
crl.c: - wolfSSL_X509_CRL_dup: add NULL check on input before dereferencing crl->cm - DupX509_CRL: distinguish empty source CRL list from allocation failure so duplicating a CRL with no entries no longer returns MEMORY_E - wolfSSL_X509_STORE_add_crl: free newly-allocated CRL when wc_LockRwLock_Rd fails to avoid leaking it - InitCRL: propagate wolfSSL_RefInit failure in OPENSSL_ALL + WOLFSSL_REFCNT_ERROR_RETURN builds, freeing crlLock (and cond when HAVE_CRL_MONITOR is enabled) on the error path keys.c: - GetCipherSpec: remove duplicate usingPSK_cipher assignment in BUILD_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 case - GetCipherSpec: return UNSUPPORTED_SUITE for unknown cipher suite bytes in the TLS13_BYTE, ECDHE_PSK_BYTE, and SM_BYTE switch blocks, matching the behavior of the ECC_BYTE, CHACHA_BYTE, and normal suite switches - SetKeys: fix misleading indentation on the AESCCM and SM4-CCM dec->aes NULL-check return statements ssl_certman.c: - AddTrustedPeer: remove dead code that checked peerCert->permittedNames and peerCert->excludedNames immediately after XMEMSET zeroed the struct - AddTrustedPeer: use cm->heap (matching allocation) instead of NULL when freeing cert on the ParseCert failure path - Extract the body of wolfSSL_CertManagerFree into a new static helper DoCertManagerFree that unconditionally disposes of the certificate manager, bypassing the reference count check. wolfSSL_CertManagerFree now delegates to it after the RefDec check. - wolfSSL_CertManagerNew_ex: on init failure, call DoCertManagerFree directly to avoid leaking cm when the reference count was never initialized or failed to initialize. Set cm->heap immediately after XMEMSET so the forceful free path can use it.
1 parent 9176185 commit 99ee724

3 files changed

Lines changed: 87 additions & 63 deletions

File tree

src/crl.c

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,20 @@ int InitCRL(WOLFSSL_CRL* crl, WOLFSSL_CERT_MANAGER* cm)
9191
}
9292
#ifdef OPENSSL_ALL
9393
{
94-
int ret;
95-
wolfSSL_RefInit(&crl->ref, &ret);
96-
(void)ret;
94+
int refErr;
95+
wolfSSL_RefInit(&crl->ref, &refErr);
96+
#ifdef WOLFSSL_REFCNT_ERROR_RETURN
97+
if (refErr != 0) {
98+
WOLFSSL_MSG("wolfSSL_RefInit failed");
99+
wc_FreeRwLock(&crl->crlLock);
100+
#ifdef HAVE_CRL_MONITOR
101+
wolfSSL_CondFree(&crl->cond);
102+
#endif
103+
return refErr;
104+
}
105+
#else
106+
(void)refErr;
107+
#endif
97108
}
98109
#endif
99110
#if defined(OPENSSL_EXTRA)
@@ -1451,7 +1462,7 @@ static int DupX509_CRL(WOLFSSL_X509_CRL *dupl, const WOLFSSL_X509_CRL* crl)
14511462
#endif
14521463

14531464
dupl->crlList = DupCRL_list(crl->crlList, dupl->heap);
1454-
if (dupl->crlList == NULL)
1465+
if (crl->crlList != NULL && dupl->crlList == NULL)
14551466
return MEMORY_E;
14561467
#ifdef HAVE_CRL_IO
14571468
dupl->crlIOCb = crl->crlIOCb;
@@ -1466,6 +1477,9 @@ WOLFSSL_X509_CRL* wolfSSL_X509_CRL_dup(const WOLFSSL_X509_CRL* crl)
14661477

14671478
WOLFSSL_ENTER("wolfSSL_X509_CRL_dup");
14681479

1480+
if (crl == NULL)
1481+
return NULL;
1482+
14691483
ret = wolfSSL_X509_crl_new(crl->cm);
14701484
if (ret != NULL && DupX509_CRL(ret, crl) != 0) {
14711485
FreeCRL(ret, 1);
@@ -1514,6 +1528,7 @@ int wolfSSL_X509_STORE_add_crl(WOLFSSL_X509_STORE *store, WOLFSSL_X509_CRL *newc
15141528
}
15151529
if (wc_LockRwLock_Rd(&newcrl->crlLock) != 0) {
15161530
WOLFSSL_MSG("wc_LockRwLock_Rd failed");
1531+
FreeCRL(crl, 1);
15171532
return BAD_MUTEX_E;
15181533
}
15191534
ret = DupX509_CRL(crl, newcrl);

src/keys.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -525,8 +525,6 @@ int GetCipherSpec(word16 side, byte cipherSuite0, byte cipherSuite,
525525
specs->block_size = WC_AES_BLOCK_SIZE;
526526
specs->iv_size = AES_IV_SIZE;
527527

528-
if (opts != NULL)
529-
opts->usingPSK_cipher = 1;
530528
if (opts != NULL)
531529
opts->usingPSK_cipher = 1;
532530
break;
@@ -1374,7 +1372,8 @@ int GetCipherSpec(word16 side, byte cipherSuite0, byte cipherSuite,
13741372
#endif
13751373
#endif /* WOLFSSL_TLS13 */
13761374
default:
1377-
break;
1375+
WOLFSSL_MSG("Unsupported cipher suite, SetCipherSpecs TLS 1.3");
1376+
return UNSUPPORTED_SUITE;
13781377
}
13791378
}
13801379

@@ -1405,7 +1404,8 @@ int GetCipherSpec(word16 side, byte cipherSuite0, byte cipherSuite,
14051404
#endif
14061405

14071406
default:
1408-
break;
1407+
WOLFSSL_MSG("Unsupported cipher suite, SetCipherSpecs ECDHE_PSK");
1408+
return UNSUPPORTED_SUITE;
14091409
}
14101410
}
14111411

@@ -1466,7 +1466,8 @@ int GetCipherSpec(word16 side, byte cipherSuite0, byte cipherSuite,
14661466
#endif
14671467

14681468
default:
1469-
break;
1469+
WOLFSSL_MSG("Unsupported cipher suite, SetCipherSpecs SM");
1470+
return UNSUPPORTED_SUITE;
14701471
}
14711472
}
14721473

@@ -2799,7 +2800,7 @@ int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs,
27992800
if (dec->aes == NULL) {
28002801
dec->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER);
28012802
if (dec->aes == NULL)
2802-
return MEMORY_E;
2803+
return MEMORY_E;
28032804
} else {
28042805
wc_AesFree(dec->aes);
28052806
}
@@ -3247,7 +3248,7 @@ int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs,
32473248
dec->sm4 = (wc_Sm4*)XMALLOC(sizeof(wc_Sm4), heap,
32483249
DYNAMIC_TYPE_CIPHER);
32493250
if (dec->sm4 == NULL)
3250-
return MEMORY_E;
3251+
return MEMORY_E;
32513252
} else {
32523253
wc_Sm4Free(dec->sm4);
32533254
}

src/ssl_certman.c

Lines changed: 60 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ static WC_INLINE WOLFSSL_METHOD* cm_pick_method(void* heap)
7474
#endif
7575
}
7676

77+
static void DoCertManagerFree(WOLFSSL_CERT_MANAGER* cm);
78+
7779
/* Create a new certificate manager with a heap hint.
7880
*
7981
* @param [in] heap Heap hint.
@@ -107,6 +109,8 @@ WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew_ex(void* heap)
107109
if (!err) {
108110
/* Reset all fields. */
109111
XMEMSET(cm, 0, sizeof(WOLFSSL_CERT_MANAGER));
112+
/* Set heap hint early so cleanup can use it. */
113+
cm->heap = heap;
110114

111115
/* Create a mutex for use when modify table of stored CAs. */
112116
if (wc_InitMutex(&cm->caLock) != 0) {
@@ -144,14 +148,12 @@ WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew_ex(void* heap)
144148
#ifdef HAVE_DILITHIUM
145149
cm->minDilithiumKeySz = MIN_DILITHIUMKEY_SZ;
146150
#endif /* HAVE_DILITHIUM */
147-
148-
/* Set heap hint to use in certificate manager operations. */
149-
cm->heap = heap;
150151
}
151152

152-
/* Dispose of certificate manager on error. */
153+
/* Dispose of certificate manager on error. The reference count may not
154+
* have been initialized, so bypass the ref check and free directly. */
153155
if (err && (cm != NULL)) {
154-
wolfSSL_CertManagerFree(cm);
156+
DoCertManagerFree(cm);
155157
cm = NULL;
156158
}
157159
return cm;
@@ -168,6 +170,57 @@ WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew(void)
168170
return wolfSSL_CertManagerNew_ex(NULL);
169171
}
170172

173+
/* Unconditionally dispose of all resources owned by the certificate manager
174+
* and free cm itself, bypassing any reference count check. Safe to call on
175+
* a cm that has been XMEMSET but only partially initialized - NULL-pointer
176+
* members are handled, and wc_FreeMutex / wolfSSL_RefFree on zeroed storage
177+
* are benign on supported platforms.
178+
*
179+
* @param [in, out] cm Certificate manager (must be non-NULL).
180+
*/
181+
static void DoCertManagerFree(WOLFSSL_CERT_MANAGER* cm)
182+
{
183+
#ifdef HAVE_CRL
184+
/* Dispose of CRL handler. */
185+
if (cm->crl != NULL) {
186+
/* Dispose of CRL object - indicating dynamically allocated. */
187+
FreeCRL(cm->crl, 1);
188+
}
189+
#endif
190+
191+
#ifdef HAVE_OCSP
192+
/* Dispose of OCSP handler. */
193+
if (cm->ocsp != NULL) {
194+
FreeOCSP(cm->ocsp, 1);
195+
}
196+
/* Dispose of URL. */
197+
XFREE(cm->ocspOverrideURL, cm->heap, DYNAMIC_TYPE_URL);
198+
#if !defined(NO_WOLFSSL_SERVER) && \
199+
(defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \
200+
defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2))
201+
/* Dispose of OCSP stapling handler. */
202+
if (cm->ocsp_stapling) {
203+
FreeOCSP(cm->ocsp_stapling, 1);
204+
}
205+
#endif
206+
#endif /* HAVE_OCSP */
207+
208+
/* Dispose of CA table and mutex. */
209+
FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap);
210+
wc_FreeMutex(&cm->caLock);
211+
212+
#ifdef WOLFSSL_TRUST_PEER_CERT
213+
/* Dispose of trusted peer table and mutex. */
214+
FreeTrustedPeerTable(cm->tpTable, TP_TABLE_SIZE, cm->heap);
215+
wc_FreeMutex(&cm->tpLock);
216+
#endif
217+
218+
/* Dispose of reference count. */
219+
wolfSSL_RefFree(&cm->ref);
220+
/* Dispose of certificate manager memory. */
221+
XFREE(cm, cm->heap, DYNAMIC_TYPE_CERT_MANAGER);
222+
}
223+
171224
/* Dispose of certificate manager.
172225
*
173226
* @param [in, out] cm Certificate manager.
@@ -191,45 +244,7 @@ void wolfSSL_CertManagerFree(WOLFSSL_CERT_MANAGER* cm)
191244
(void)ret;
192245
#endif
193246
if (doFree) {
194-
#ifdef HAVE_CRL
195-
/* Dispose of CRL handler. */
196-
if (cm->crl != NULL) {
197-
/* Dispose of CRL object - indicating dynamically allocated. */
198-
FreeCRL(cm->crl, 1);
199-
}
200-
#endif
201-
202-
#ifdef HAVE_OCSP
203-
/* Dispose of OCSP handler. */
204-
if (cm->ocsp != NULL) {
205-
FreeOCSP(cm->ocsp, 1);
206-
}
207-
/* Dispose of URL. */
208-
XFREE(cm->ocspOverrideURL, cm->heap, DYNAMIC_TYPE_URL);
209-
#if !defined(NO_WOLFSSL_SERVER) && \
210-
(defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \
211-
defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2))
212-
/* Dispose of OCSP stapling handler. */
213-
if (cm->ocsp_stapling) {
214-
FreeOCSP(cm->ocsp_stapling, 1);
215-
}
216-
#endif
217-
#endif /* HAVE_OCSP */
218-
219-
/* Dispose of CA table and mutex. */
220-
FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap);
221-
wc_FreeMutex(&cm->caLock);
222-
223-
#ifdef WOLFSSL_TRUST_PEER_CERT
224-
/* Dispose of trusted peer table and mutex. */
225-
FreeTrustedPeerTable(cm->tpTable, TP_TABLE_SIZE, cm->heap);
226-
wc_FreeMutex(&cm->tpLock);
227-
#endif
228-
229-
/* Dispose of reference count. */
230-
wolfSSL_RefFree(&cm->ref);
231-
/* Dispose of certificate manager memory. */
232-
XFREE(cm, cm->heap, DYNAMIC_TYPE_CERT_MANAGER);
247+
DoCertManagerFree(cm);
233248
}
234249
}
235250
}
@@ -2859,7 +2874,7 @@ int AddTrustedPeer(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int verify)
28592874
InitDecodedCert(cert, der->buffer, der->length, cm->heap);
28602875
if ((ret = ParseCert(cert, TRUSTED_PEER_TYPE, verify, cm)) != 0) {
28612876
FreeDecodedCert(cert);
2862-
XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
2877+
XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
28632878
FreeDer(&der);
28642879
return ret;
28652880
}
@@ -2875,13 +2890,6 @@ int AddTrustedPeer(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int verify)
28752890
}
28762891
XMEMSET(peerCert, 0, sizeof(TrustedPeerCert));
28772892

2878-
#ifndef IGNORE_NAME_CONSTRAINTS
2879-
if (peerCert->permittedNames)
2880-
FreeNameSubtrees(peerCert->permittedNames, cm->heap);
2881-
if (peerCert->excludedNames)
2882-
FreeNameSubtrees(peerCert->excludedNames, cm->heap);
2883-
#endif
2884-
28852893
if (AlreadyTrustedPeer(cm, cert)) {
28862894
WOLFSSL_MSG("\tAlready have this CA, not adding again");
28872895
FreeTrustedPeer(peerCert, cm->heap);

0 commit comments

Comments
 (0)