@@ -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 );
0 commit comments