Skip to content

Commit 755a90b

Browse files
authored
Merge pull request #10218 from julek-wolfssl/zd/21535
Fix bugs found in crl.c, keys.c, and ssl_certman.c review
2 parents 318cd62 + 4a36d16 commit 755a90b

4 files changed

Lines changed: 115 additions & 64 deletions

File tree

src/crl.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,18 @@ int InitCRL(WOLFSSL_CRL* crl, WOLFSSL_CERT_MANAGER* cm)
9393
{
9494
int ret;
9595
wolfSSL_RefInit(&crl->ref, &ret);
96+
#ifdef WOLFSSL_REFCNT_ERROR_RETURN
97+
if (ret != 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 ret;
104+
}
105+
#else
96106
(void)ret;
107+
#endif
97108
}
98109
#endif
99110
#if defined(OPENSSL_EXTRA)
@@ -1455,7 +1466,7 @@ static int DupX509_CRL(WOLFSSL_X509_CRL *dupl, const WOLFSSL_X509_CRL* crl)
14551466
#endif
14561467

14571468
dupl->crlList = DupCRL_list(crl->crlList, dupl->heap);
1458-
if (dupl->crlList == NULL)
1469+
if (crl->crlList != NULL && dupl->crlList == NULL)
14591470
return MEMORY_E;
14601471
#ifdef HAVE_CRL_IO
14611472
dupl->crlIOCb = crl->crlIOCb;
@@ -1470,6 +1481,9 @@ WOLFSSL_X509_CRL* wolfSSL_X509_CRL_dup(const WOLFSSL_X509_CRL* crl)
14701481

14711482
WOLFSSL_ENTER("wolfSSL_X509_CRL_dup");
14721483

1484+
if (crl == NULL)
1485+
return NULL;
1486+
14731487
ret = wolfSSL_X509_crl_new(crl->cm);
14741488
if (ret != NULL && DupX509_CRL(ret, crl) != 0) {
14751489
FreeCRL(ret, 1);
@@ -1518,6 +1532,7 @@ int wolfSSL_X509_STORE_add_crl(WOLFSSL_X509_STORE *store, WOLFSSL_X509_CRL *newc
15181532
}
15191533
if (wc_LockRwLock_Rd(&newcrl->crlLock) != 0) {
15201534
WOLFSSL_MSG("wc_LockRwLock_Rd failed");
1535+
FreeCRL(crl, 1);
15211536
return BAD_MUTEX_E;
15221537
}
15231538
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: 83 additions & 56 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,12 +109,17 @@ 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) {
113117
WOLFSSL_MSG("Bad mutex init");
114118
err = 1;
115119
}
120+
else {
121+
cm->caLockInit = 1;
122+
}
116123
}
117124
if (!err) {
118125
/* Initialize reference count. */
@@ -121,13 +128,23 @@ WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew_ex(void* heap)
121128
if (err != 0) {
122129
WOLFSSL_MSG("Bad reference count init");
123130
}
131+
else {
132+
cm->refInit = 1;
133+
}
134+
#else
135+
cm->refInit = 1;
124136
#endif
125137
}
126138
#ifdef WOLFSSL_TRUST_PEER_CERT
127-
/* Create a mutex for use when modify table of trusted peers. */
128-
if ((!err) && (wc_InitMutex(&cm->tpLock) != 0)) {
129-
WOLFSSL_MSG("Bad mutex init");
130-
err = 1;
139+
if (!err) {
140+
/* Create a mutex for use when modify table of trusted peers. */
141+
if (wc_InitMutex(&cm->tpLock) != 0) {
142+
WOLFSSL_MSG("Bad mutex init");
143+
err = 1;
144+
}
145+
else {
146+
cm->tpLockInit = 1;
147+
}
131148
}
132149
#endif
133150
if (!err) {
@@ -144,14 +161,12 @@ WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew_ex(void* heap)
144161
#ifdef HAVE_DILITHIUM
145162
cm->minDilithiumKeySz = MIN_DILITHIUMKEY_SZ;
146163
#endif /* HAVE_DILITHIUM */
147-
148-
/* Set heap hint to use in certificate manager operations. */
149-
cm->heap = heap;
150164
}
151165

152-
/* Dispose of certificate manager on error. */
166+
/* Dispose of certificate manager on error. The reference count may not
167+
* have been initialized, so bypass the ref check and free directly. */
153168
if (err && (cm != NULL)) {
154-
wolfSSL_CertManagerFree(cm);
169+
DoCertManagerFree(cm);
155170
cm = NULL;
156171
}
157172
return cm;
@@ -168,6 +183,63 @@ WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew(void)
168183
return wolfSSL_CertManagerNew_ex(NULL);
169184
}
170185

186+
/* Unconditionally dispose of all resources owned by the certificate manager
187+
* and free cm itself, bypassing any reference count check. Only frees the
188+
* sub-resources that are marked as initialized in the cm bitfield, so it is
189+
* safe to call on a cm that was only partially initialized by
190+
* wolfSSL_CertManagerNew_ex.
191+
*
192+
* @param [in, out] cm Certificate manager (must be non-NULL).
193+
*/
194+
static void DoCertManagerFree(WOLFSSL_CERT_MANAGER* cm)
195+
{
196+
#ifdef HAVE_CRL
197+
/* Dispose of CRL handler. */
198+
if (cm->crl != NULL) {
199+
/* Dispose of CRL object - indicating dynamically allocated. */
200+
FreeCRL(cm->crl, 1);
201+
}
202+
#endif
203+
204+
#ifdef HAVE_OCSP
205+
/* Dispose of OCSP handler. */
206+
if (cm->ocsp != NULL) {
207+
FreeOCSP(cm->ocsp, 1);
208+
}
209+
/* Dispose of URL. */
210+
XFREE(cm->ocspOverrideURL, cm->heap, DYNAMIC_TYPE_URL);
211+
#if !defined(NO_WOLFSSL_SERVER) && \
212+
(defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \
213+
defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2))
214+
/* Dispose of OCSP stapling handler. */
215+
if (cm->ocsp_stapling) {
216+
FreeOCSP(cm->ocsp_stapling, 1);
217+
}
218+
#endif
219+
#endif /* HAVE_OCSP */
220+
221+
/* Dispose of CA table and mutex. */
222+
FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap);
223+
if (cm->caLockInit) {
224+
wc_FreeMutex(&cm->caLock);
225+
}
226+
227+
#ifdef WOLFSSL_TRUST_PEER_CERT
228+
/* Dispose of trusted peer table and mutex. */
229+
FreeTrustedPeerTable(cm->tpTable, TP_TABLE_SIZE, cm->heap);
230+
if (cm->tpLockInit) {
231+
wc_FreeMutex(&cm->tpLock);
232+
}
233+
#endif
234+
235+
/* Dispose of reference count. */
236+
if (cm->refInit) {
237+
wolfSSL_RefFree(&cm->ref);
238+
}
239+
/* Dispose of certificate manager memory. */
240+
XFREE(cm, cm->heap, DYNAMIC_TYPE_CERT_MANAGER);
241+
}
242+
171243
/* Dispose of certificate manager.
172244
*
173245
* @param [in, out] cm Certificate manager.
@@ -191,45 +263,7 @@ void wolfSSL_CertManagerFree(WOLFSSL_CERT_MANAGER* cm)
191263
(void)ret;
192264
#endif
193265
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);
266+
DoCertManagerFree(cm);
233267
}
234268
}
235269
}
@@ -2859,7 +2893,7 @@ int AddTrustedPeer(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int verify)
28592893
InitDecodedCert(cert, der->buffer, der->length, cm->heap);
28602894
if ((ret = ParseCert(cert, TRUSTED_PEER_TYPE, verify, cm)) != 0) {
28612895
FreeDecodedCert(cert);
2862-
XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
2896+
XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
28632897
FreeDer(&der);
28642898
return ret;
28652899
}
@@ -2875,13 +2909,6 @@ int AddTrustedPeer(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int verify)
28752909
}
28762910
XMEMSET(peerCert, 0, sizeof(TrustedPeerCert));
28772911

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-
28852912
if (AlreadyTrustedPeer(cm, cert)) {
28862913
WOLFSSL_MSG("\tAlready have this CA, not adding again");
28872914
FreeTrustedPeer(peerCert, cm->heap);

wolfssl/internal.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2647,6 +2647,14 @@ struct WOLFSSL_CERT_MANAGER {
26472647
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
26482648
byte ocspMustStaple:1; /* server must respond with staple */
26492649
#endif
2650+
/* Tracks which resources were successfully initialized so that
2651+
* DoCertManagerFree can dispose of them safely even when construction
2652+
* fails partway through. */
2653+
WC_BITFIELD caLockInit:1; /* caLock has been initialized */
2654+
#ifdef WOLFSSL_TRUST_PEER_CERT
2655+
WC_BITFIELD tpLockInit:1; /* tpLock has been initialized */
2656+
#endif
2657+
WC_BITFIELD refInit:1; /* ref has been initialized */
26502658

26512659
#ifndef NO_RSA
26522660
short minRsaKeySz; /* minimum allowed RSA key size */

0 commit comments

Comments
 (0)