From 53dfcd00e2aa6f69267cbde01970640cf1a296fd Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Fri, 23 Dec 2022 08:45:40 +1000 Subject: [PATCH] Ref count: change to use wolfSSL_Ref Data structures changed: WOLFSSL_CERT_MANAGER, WOLFSSL_CTX, WOLFSSL_SESSION, WOLFSSL_X509, WOLFSSL_X509, WOLFSSL_EVP_PKEY, WOLFSSL_BIO, WOLFSSL_X509_STORE --- m4/ax_atomic.m4 | 1 + src/bio.c | 44 ++++++-------------- src/internal.c | 57 +++++++------------------ src/ssl.c | 92 ++++++++++++++++------------------------- src/x509.c | 24 +++-------- src/x509_str.c | 29 ++++--------- tests/api.c | 4 +- wolfcrypt/src/evp.c | 50 +++++++--------------- wolfcrypt/src/wc_port.c | 4 +- wolfssl/internal.h | 19 ++------- wolfssl/ssl.h | 15 ++----- 11 files changed, 107 insertions(+), 232 deletions(-) diff --git a/m4/ax_atomic.m4 b/m4/ax_atomic.m4 index c4da80259..7d6dae261 100644 --- a/m4/ax_atomic.m4 +++ b/m4/ax_atomic.m4 @@ -31,5 +31,6 @@ AC_DEFUN([AC_C___ATOMIC], if test $ac_cv_c___atomic = yes; then AC_DEFINE([HAVE_C___ATOMIC], 1, [Define to 1 if __atomic operations work.]) + AM_CFLAGS="$AM_CFLAGS -DHAVE_C___ATOMIC" fi ])# AC_C___ATOMIC diff --git a/src/bio.c b/src/bio.c index f0921a2a5..2b34d529e 100644 --- a/src/bio.c +++ b/src/bio.c @@ -766,15 +766,11 @@ long wolfSSL_BIO_ctrl(WOLFSSL_BIO *bio, int cmd, long larg, void *parg) int wolfSSL_BIO_up_ref(WOLFSSL_BIO* bio) { if (bio) { - #ifndef SINGLE_THREADED - if (wc_LockMutex(&bio->refMutex) != 0) { + int ret; + wolfSSL_RefInc(&bio->ref, &ret); + if (ret != 0) { WOLFSSL_MSG("Failed to lock BIO mutex"); } - #endif - bio->refCount++; - #ifndef SINGLE_THREADED - wc_UnLockMutex(&bio->refMutex); - #endif return WOLFSSL_SUCCESS; } @@ -2495,14 +2491,15 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio) } #if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) - bio->refCount = 1; - #ifndef SINGLE_THREADED - if (wc_InitMutex(&bio->refMutex) != 0) { - wolfSSL_BIO_free(bio); - WOLFSSL_MSG("wc_InitMutex failed for WOLFSSL_BIO"); - return NULL; + { + int ret; + wolfSSL_RefInit(&bio->ref, &ret); + if (ret != 0) { + wolfSSL_BIO_free(bio); + WOLFSSL_MSG("wc_InitMutex failed for WOLFSSL_BIO"); + return NULL; + } } - #endif #endif } @@ -2567,29 +2564,14 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio) } #if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) - #ifndef SINGLE_THREADED - if (wc_LockMutex(&bio->refMutex) != 0) { - WOLFSSL_MSG("Couldn't lock BIO mutex"); - return WOLFSSL_FAILURE; - } - #endif - - /* only free if all references to it are done */ - bio->refCount--; - if (bio->refCount == 0) { - doFree = 1; - } - - #ifndef SINGLE_THREADED - wc_UnLockMutex(&bio->refMutex); - #endif + wolfSSL_RefDec(&bio->ref, &doFree, &ret); if (!doFree) { /* return success if BIO ref count is not 1 yet */ return WOLFSSL_SUCCESS; } #ifndef SINGLE_THREADED - wc_FreeMutex(&bio->refMutex); + wolfSSL_RefFree(&bio->ref); #endif #endif diff --git a/src/internal.c b/src/internal.c index 737bc34d9..b3680471e 100644 --- a/src/internal.c +++ b/src/internal.c @@ -2140,7 +2140,6 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap) XMEMSET(ctx, 0, sizeof(WOLFSSL_CTX)); ctx->method = method; - ctx->refCount = 1; /* so either CTX_free or SSL_free can release */ ctx->heap = ctx; /* defaults to self */ ctx->timeout = WOLFSSL_SESSION_TIMEOUT; @@ -2155,7 +2154,8 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap) ctx->minDowngrade = WOLFSSL_MIN_DOWNGRADE; } - if (wc_InitMutex(&ctx->countMutex) < 0) { + wolfSSL_RefInit(&ctx->ref, &ret); + if (ret < 0) { WOLFSSL_MSG("Mutex error on CTX init"); ctx->err = CTX_INIT_MUTEX_E; WOLFSSL_ERROR_VERBOSE(BAD_MUTEX_E); @@ -2610,7 +2610,8 @@ static void SSL_CtxResourceFreeStaticMem(void* heap) void FreeSSL_Ctx(WOLFSSL_CTX* ctx) { - int refCount; + int isZero; + int ret; void* heap = ctx->heap; #ifdef WOLFSSL_STATIC_MEMORY if (ctx->onHeapHint == 0) { @@ -2619,7 +2620,8 @@ void FreeSSL_Ctx(WOLFSSL_CTX* ctx) #endif /* decrement CTX reference count */ - if ((refCount = SSL_CTX_RefCount(ctx, -1)) < 0) { + wolfSSL_RefDec(&ctx->ref, &isZero, &ret); + if (ret < 0) { /* check error state, if mutex error code then mutex init failed but * CTX was still malloc'd */ if (ctx->err == CTX_INIT_MUTEX_E) { @@ -2632,7 +2634,7 @@ void FreeSSL_Ctx(WOLFSSL_CTX* ctx) return; } - if (refCount == 0) { + if (isZero) { WOLFSSL_MSG("CTX ref count down to 0, doing full free"); SSL_CtxResourceFree(ctx); @@ -2640,7 +2642,7 @@ void FreeSSL_Ctx(WOLFSSL_CTX* ctx) !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) TicketEncCbCtx_Free(&ctx->ticketKeyCtx); #endif - wc_FreeMutex(&ctx->countMutex); + wolfSSL_RefFree(&ctx->ref); XFREE(ctx, heap, DYNAMIC_TYPE_CTX); #ifdef WOLFSSL_STATIC_MEMORY SSL_CtxResourceFreeStaticMem(heap); @@ -4203,10 +4205,11 @@ void InitX509(WOLFSSL_X509* x509, int dynamicFlag, void* heap) InitX509Name(&x509->subject, 0, heap); x509->dynamicMemory = (byte)dynamicFlag; #if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA) - x509->refCount = 1; -#ifndef SINGLE_THREADED - (void)wc_InitMutex(&x509->refMutex); -#endif + { + int ret; + wolfSSL_RefInit(&x509->ref, &ret); + (void)ret; + } #endif } @@ -4301,9 +4304,7 @@ void FreeX509(WOLFSSL_X509* x509) } #if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) - #ifndef SINGLE_THREADED - wc_FreeMutex(&x509->refMutex); - #endif + wolfSSL_RefFree(&x509->ref); #endif } @@ -6151,33 +6152,6 @@ int InitSSL_Suites(WOLFSSL* ssl) return WOLFSSL_SUCCESS; } -/* returns new reference count. Arg incr positive=up or negative=down */ -int SSL_CTX_RefCount(WOLFSSL_CTX* ctx, int incr) -{ - int refCount; - - if (ctx == NULL) { - return BAD_FUNC_ARG; - } - - if (wc_LockMutex(&ctx->countMutex) != 0) { - WOLFSSL_MSG("Couldn't lock CTX count mutex"); - WOLFSSL_ERROR_VERBOSE(BAD_MUTEX_E); - return BAD_MUTEX_E; - } - - ctx->refCount += incr; - /* make sure refCount is never negative */ - if (ctx->refCount < 0) { - ctx->refCount = 0; - } - refCount = ctx->refCount; - - wc_UnLockMutex(&ctx->countMutex); - - return refCount; -} - /* This function inherits a WOLFSSL_CTX's fields into an SSL object. It is used during initialization and to switch an ssl's CTX with wolfSSL_Set_SSL_CTX. Requires ssl->suites alloc and ssl-arrays with PSK @@ -6213,7 +6187,8 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) } /* increment CTX reference count */ - if ((ret = SSL_CTX_RefCount(ctx, 1)) < 0) { + wolfSSL_RefInc(&ctx->ref, &ret); + if (ret < 0) { return ret; } ret = WOLFSSL_SUCCESS; /* set default ret */ diff --git a/src/ssl.c b/src/ssl.c index ae6ba8459..11134b129 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -1160,8 +1160,9 @@ WOLFSSL_CTX* wolfSSL_CTX_new(WOLFSSL_METHOD* method) /* increases CTX reference count to track proper time to "free" */ int wolfSSL_CTX_up_ref(WOLFSSL_CTX* ctx) { - int refCount = SSL_CTX_RefCount(ctx, 1); - return ((refCount > 1) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE); + int ret; + wolfSSL_RefInc(&ctx->ref, &ret); + return ((ret == 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE); } WOLFSSL_ABI @@ -4836,21 +4837,22 @@ WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew_ex(void* heap) cm = (WOLFSSL_CERT_MANAGER*) XMALLOC(sizeof(WOLFSSL_CERT_MANAGER), heap, DYNAMIC_TYPE_CERT_MANAGER); if (cm) { + int ret; + XMEMSET(cm, 0, sizeof(WOLFSSL_CERT_MANAGER)); - cm->refCount = 1; if (wc_InitMutex(&cm->caLock) != 0) { WOLFSSL_MSG("Bad mutex init"); wolfSSL_CertManagerFree(cm); return NULL; } - #ifndef SINGLE_THREADED - if (wc_InitMutex(&cm->refMutex) != 0) { + + wolfSSL_RefInit(&cm->ref, &ret); + if (ret != 0) { WOLFSSL_MSG("Bad mutex init"); wolfSSL_CertManagerFree(cm); return NULL; } - #endif #ifdef WOLFSSL_TRUST_PEER_CERT if (wc_InitMutex(&cm->tpLock) != 0) { @@ -4892,20 +4894,14 @@ WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew(void) void wolfSSL_CertManagerFree(WOLFSSL_CERT_MANAGER* cm) { int doFree = 0; + int ret; WOLFSSL_ENTER("wolfSSL_CertManagerFree"); if (cm) { - #ifndef SINGLE_THREADED - if (wc_LockMutex(&cm->refMutex) != 0) { + wolfSSL_RefDec(&cm->ref, &doFree, &ret); + if (ret != 0) { WOLFSSL_MSG("Couldn't lock cm mutex"); } - #endif - cm->refCount--; - if (cm->refCount == 0) - doFree = 1; - #ifndef SINGLE_THREADED - wc_UnLockMutex(&cm->refMutex); - #endif if (doFree) { #ifdef HAVE_CRL if (cm->crl) @@ -4929,11 +4925,7 @@ void wolfSSL_CertManagerFree(WOLFSSL_CERT_MANAGER* cm) FreeTrustedPeerTable(cm->tpTable, TP_TABLE_SIZE, cm->heap); wc_FreeMutex(&cm->tpLock); #endif - #ifndef SINGLE_THREADED - if (wc_FreeMutex(&cm->refMutex) != 0) { - WOLFSSL_MSG("Couldn't free refMutex mutex"); - } - #endif + wolfSSL_RefFree(&cm->ref); XFREE(cm, cm->heap, DYNAMIC_TYPE_CERT_MANAGER); } } @@ -4943,16 +4935,13 @@ void wolfSSL_CertManagerFree(WOLFSSL_CERT_MANAGER* cm) int wolfSSL_CertManager_up_ref(WOLFSSL_CERT_MANAGER* cm) { if (cm) { -#ifndef SINGLE_THREADED - if (wc_LockMutex(&cm->refMutex) != 0) { + int ret; + + wolfSSL_RefInc(&cm->ref, &ret); + if (ret != 0) { WOLFSSL_MSG("Failed to lock cm mutex"); return WOLFSSL_FAILURE; } -#endif - cm->refCount++; -#ifndef SINGLE_THREADED - wc_UnLockMutex(&cm->refMutex); -#endif return WOLFSSL_SUCCESS; } @@ -20963,15 +20952,14 @@ WOLFSSL_SESSION* wolfSSL_NewSession(void* heap) ret = (WOLFSSL_SESSION*)XMALLOC(sizeof(WOLFSSL_SESSION), heap, DYNAMIC_TYPE_SESSION); if (ret != NULL) { + int err; XMEMSET(ret, 0, sizeof(WOLFSSL_SESSION)); - #ifndef SINGLE_THREADED - if (wc_InitMutex(&ret->refMutex) != 0) { + wolfSSL_RefInit(&ret->ref, &err); + if (err != 0) { WOLFSSL_MSG("Error setting up session reference mutex"); XFREE(ret, ret->heap, DYNAMIC_TYPE_SESSION); return NULL; } - #endif - ret->refCount = 1; #ifndef NO_SESSION_CACHE ret->cacheRow = INVALID_SESSION_ROW; /* not in cache */ #endif @@ -21021,21 +21009,19 @@ WOLFSSL_SESSION* wolfSSL_SESSION_new(void) * return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on error */ int wolfSSL_SESSION_up_ref(WOLFSSL_SESSION* session) { + int ret; + session = ClientSessionToSession(session); if (session == NULL || session->type != WOLFSSL_SESSION_TYPE_HEAP) return WOLFSSL_FAILURE; -#ifndef SINGLE_THREADED - if (wc_LockMutex(&session->refMutex) != 0) { + wolfSSL_RefInc(&session->ref, &ret); + if (ret != 0) { WOLFSSL_MSG("Failed to lock session mutex"); return WOLFSSL_FAILURE; } -#endif - session->refCount++; -#ifndef SINGLE_THREADED - wc_UnLockMutex(&session->refMutex); -#endif + return WOLFSSL_SUCCESS; } @@ -21322,32 +21308,22 @@ WOLFSSL_SESSION* wolfSSL_SESSION_dup(WOLFSSL_SESSION* session) void wolfSSL_FreeSession(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* session) { + int isZero; + session = ClientSessionToSession(session); if (session == NULL) return; (void)ctx; - /* refCount will always be 1 or more if created externally. - * Internal cache sessions don't initialize a refMutex. */ - if (session->refCount > 0) { -#ifndef SINGLE_THREADED - if (wc_LockMutex(&session->refMutex) != 0) { - WOLFSSL_MSG("Failed to lock session mutex"); + if (session->ref.count > 0) { + int ret; + wolfSSL_RefDec(&session->ref, &isZero, &ret); + (void)ret; + if (!isZero) { return; } -#endif - if (session->refCount > 1) { - session->refCount--; -#ifndef SINGLE_THREADED - wc_UnLockMutex(&session->refMutex); -#endif - return; - } -#ifndef SINGLE_THREADED - wc_UnLockMutex(&session->refMutex); - wc_FreeMutex(&session->refMutex); -#endif + wolfSSL_RefFree(&session->ref); } #if defined(HAVE_EXT_CACHE) || defined(HAVE_EX_DATA) @@ -32436,6 +32412,7 @@ const char * wolfSSL_get_servername(WOLFSSL* ssl, byte type) WOLFSSL_CTX* wolfSSL_set_SSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx) { + int ret; /* This method requires some explanation. Its sibling is * int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) * which re-inits the WOLFSSL* with all settings in the new CTX. @@ -32458,7 +32435,8 @@ WOLFSSL_CTX* wolfSSL_set_SSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx) if (ssl->ctx == ctx) return ssl->ctx; - if (SSL_CTX_RefCount(ctx, 1) < 0) { + wolfSSL_RefInc(&ctx->ref, &ret); + if (ret != 0) { /* can only fail on serious stuff, like mutex not working * or ctx refcount out of whack. */ return NULL; diff --git a/src/x509.c b/src/x509.c index 11a03c32c..bd0101005 100644 --- a/src/x509.c +++ b/src/x509.c @@ -2946,18 +2946,11 @@ static void ExternalFreeX509(WOLFSSL_X509* x509) #endif if (x509->dynamicMemory) { #if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA) - #ifndef SINGLE_THREADED - if (wc_LockMutex(&x509->refMutex) != 0) { + int ret; + wolfSSL_RefDec(&x509->ref, &doFree, &ret); + if (ret != 0) { WOLFSSL_MSG("Couldn't lock x509 mutex"); } - #endif - /* only free if all references to it are done */ - x509->refCount--; - if (x509->refCount == 0) - doFree = 1; - #ifndef SINGLE_THREADED - wc_UnLockMutex(&x509->refMutex); - #endif #endif /* OPENSSL_EXTRA_X509_SMALL || OPENSSL_EXTRA */ #if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA) @@ -9038,21 +9031,16 @@ char* wolfSSL_X509_get_subjectCN(WOLFSSL_X509* x509) #endif /* KEEP_PEER_CERT */ #if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA) - /* increments ref count of WOLFSSL_X509. Return 1 on success, 0 on error */ int wolfSSL_X509_up_ref(WOLFSSL_X509* x509) { if (x509) { -#ifndef SINGLE_THREADED - if (wc_LockMutex(&x509->refMutex) != 0) { + int ret; + wolfSSL_RefInc(&x509->ref, &ret); + if (ret != 0) { WOLFSSL_MSG("Failed to lock x509 mutex"); return WOLFSSL_FAILURE; } -#endif - x509->refCount++; -#ifndef SINGLE_THREADED - wc_UnLockMutex(&x509->refMutex); -#endif return WOLFSSL_SUCCESS; } diff --git a/src/x509_str.c b/src/x509_str.c index e9703bb44..e2354df63 100644 --- a/src/x509_str.c +++ b/src/x509_str.c @@ -713,6 +713,7 @@ int wolfSSL_X509_STORE_CTX_get1_issuer(WOLFSSL_X509 **issuer, defined(WOLFSSL_WPAS_SMALL) WOLFSSL_X509_STORE* wolfSSL_X509_STORE_new(void) { + int ret; WOLFSSL_X509_STORE* store = NULL; WOLFSSL_ENTER("SSL_X509_STORE_new"); @@ -722,12 +723,10 @@ WOLFSSL_X509_STORE* wolfSSL_X509_STORE_new(void) XMEMSET(store, 0, sizeof(WOLFSSL_X509_STORE)); store->isDynamic = 1; - store->refCount = 1; -#ifndef SINGLE_THREADED - if (wc_InitMutex(&store->refMutex) != 0) + wolfSSL_RefInit(&store->ref, &ret); + if (ret != 0) goto err_exit; -#endif if ((store->cm = wolfSSL_CertManagerNew()) == NULL) goto err_exit; @@ -774,17 +773,11 @@ void wolfSSL_X509_STORE_free(WOLFSSL_X509_STORE* store) { int doFree = 0; if (store != NULL && store->isDynamic) { -#ifndef SINGLE_THREADED - if (wc_LockMutex(&store->refMutex) != 0) { + int ret; + wolfSSL_RefDec(&store->ref, &doFree, &ret); + if (ret != 0) { WOLFSSL_MSG("Couldn't lock store mutex"); } -#endif - store->refCount--; - if (store->refCount == 0) - doFree = 1; -#ifndef SINGLE_THREADED - wc_UnLockMutex(&store->refMutex); -#endif if (doFree) { #ifdef HAVE_EX_DATA_CLEANUP_HOOKS @@ -844,16 +837,12 @@ void* wolfSSL_X509_STORE_get_ex_data(WOLFSSL_X509_STORE* store, int idx) int wolfSSL_X509_STORE_up_ref(WOLFSSL_X509_STORE* store) { if (store) { -#ifndef SINGLE_THREADED - if (wc_LockMutex(&store->refMutex) != 0) { + int ret; + wolfSSL_RefInc(&store->ref, &ret); + if (ret != 0) { WOLFSSL_MSG("Failed to lock store mutex"); return WOLFSSL_FAILURE; } -#endif - store->refCount++; -#ifndef SINGLE_THREADED - wc_UnLockMutex(&store->refMutex); -#endif return WOLFSSL_SUCCESS; } diff --git a/tests/api.c b/tests/api.c index 4b4c9302c..d88fe04fd 100644 --- a/tests/api.c +++ b/tests/api.c @@ -48888,9 +48888,9 @@ static int test_wolfSSL_EVP_PKEY_encrypt(void) /* Test pkey references count is decremented. pkey shouldn't be destroyed since ctx uses it.*/ - AssertIntEQ(pkey->references, 2); + AssertIntEQ(pkey->ref.count, 2); EVP_PKEY_free(pkey); - AssertIntEQ(pkey->references, 1); + AssertIntEQ(pkey->ref.count, 1); /* Encrypt data */ /* Check that we can get the required output buffer length by passing in a diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 65673d4c8..974f5a0f6 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -9338,15 +9338,11 @@ WOLFSSL_PKCS8_PRIV_KEY_INFO* wolfSSL_EVP_PKEY2PKCS8(const WOLFSSL_EVP_PKEY* pkey int wolfSSL_EVP_PKEY_up_ref(WOLFSSL_EVP_PKEY* pkey) { if (pkey) { -#ifndef SINGLE_THREADED - if (wc_LockMutex(&pkey->refMutex) != 0) { + int ret; + wolfSSL_RefInc(&pkey->ref, &ret); + if (ret != 0) { WOLFSSL_MSG("Failed to lock pkey mutex"); } -#endif - pkey->references++; -#ifndef SINGLE_THREADED - wc_UnLockMutex(&pkey->refMutex); -#endif return WOLFSSL_SUCCESS; } @@ -9444,27 +9440,24 @@ WOLFSSL_EVP_PKEY* wolfSSL_EVP_PKEY_new_ex(void* heap) pkey->heap = heap; pkey->type = WOLFSSL_EVP_PKEY_DEFAULT; -#ifndef SINGLE_THREADED - /* init of mutex needs to come before wolfSSL_EVP_PKEY_free */ - ret = wc_InitMutex(&pkey->refMutex); - if (ret != 0){ - XFREE(pkey, heap, DYNAMIC_TYPE_PUBLIC_KEY); - WOLFSSL_MSG("Issue initializing mutex"); - return NULL; - } -#endif - #ifndef HAVE_FIPS ret = wc_InitRng_ex(&pkey->rng, heap, INVALID_DEVID); #else ret = wc_InitRng(&pkey->rng); #endif - pkey->references = 1; if (ret != 0){ wolfSSL_EVP_PKEY_free(pkey); WOLFSSL_MSG("Issue initializing RNG"); return NULL; } + + wolfSSL_RefInit(&pkey->ref, &ret); + if (ret != 0){ + wolfSSL_EVP_PKEY_free(pkey); + WOLFSSL_MSG("Issue initializing mutex"); + return NULL; + } + } else { WOLFSSL_MSG("memory failure"); @@ -9478,20 +9471,11 @@ void wolfSSL_EVP_PKEY_free(WOLFSSL_EVP_PKEY* key) int doFree = 0; WOLFSSL_ENTER("wolfSSL_EVP_PKEY_free"); if (key != NULL) { - #ifndef SINGLE_THREADED - if (wc_LockMutex(&key->refMutex) != 0) { + int ret; + wolfSSL_RefDec(&key->ref, &doFree, &ret); + if (ret != 0) { WOLFSSL_MSG("Couldn't lock pkey mutex"); } - #endif - - /* only free if all references to it are done */ - key->references--; - if (key->references == 0) { - doFree = 1; - } - #ifndef SINGLE_THREADED - wc_UnLockMutex(&key->refMutex); - #endif if (doFree) { wc_FreeRng(&key->rng); @@ -9573,11 +9557,7 @@ void wolfSSL_EVP_PKEY_free(WOLFSSL_EVP_PKEY* key) break; } - #ifndef SINGLE_THREADED - if (wc_FreeMutex(&key->refMutex) != 0) { - WOLFSSL_MSG("Couldn't free pkey mutex"); - } - #endif + wolfSSL_RefFree(&key->ref); XFREE(key, key->heap, DYNAMIC_TYPE_PUBLIC_KEY); } } diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index 55617e13a..823889ece 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -1100,7 +1100,9 @@ void wolfSSL_RefDec(wolfSSL_Ref* ref, int* isZero, int* err) WOLFSSL_MSG("Failed to lock mutex for reference decrement!"); } else { - ref->count--; + if (ref->count > 0) { + ref->count--; + } *isZero = (ref->count == 0); wc_UnLockMutex(&ref->mutex); } diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 00f7111c3..1480e7157 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2366,10 +2366,7 @@ struct WOLFSSL_CERT_MANAGER { /* CTX has ownership and free this */ /* with CTX free. */ #endif -#ifndef SINGLE_THREADED - wolfSSL_Mutex refMutex; /* reference count mutex */ -#endif - int refCount; /* reference count */ + wolfSSL_Ref ref; #ifdef HAVE_PQC short minFalconKeySz; /* minimum allowed Falcon key size */ short minDilithiumKeySz; /* minimum allowed Dilithium key size */ @@ -3179,8 +3176,7 @@ struct WOLFSSL_CTX { #ifdef SINGLE_THREADED WC_RNG* rng; /* to be shared with WOLFSSL w/o locking */ #endif - wolfSSL_Mutex countMutex; /* reference count mutex */ - int refCount; /* reference count */ + wolfSSL_Ref ref; int err; /* error code in case of mutex not created */ #ifndef NO_DH buffer serverDH_P; @@ -3895,10 +3891,7 @@ struct WOLFSSL_SESSION { #ifndef NO_SESSION_CACHE int cacheRow; /* row in session cache */ #endif - int refCount; /* reference count */ -#ifndef SINGLE_THREADED - wolfSSL_Mutex refMutex; /* ref count mutex */ -#endif + wolfSSL_Ref ref; byte altSessionID[ID_LEN]; byte haveAltSessionID:1; #ifdef HAVE_EX_DATA @@ -4575,10 +4568,7 @@ struct WOLFSSL_X509 { int certPoliciesNb; #endif /* WOLFSSL_CERT_EXT */ #if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA) -#ifndef SINGLE_THREADED - wolfSSL_Mutex refMutex; /* ref count mutex */ -#endif - int refCount; /* reference count */ + wolfSSL_Ref ref; #endif #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) #ifdef HAVE_EX_DATA @@ -5466,7 +5456,6 @@ struct WOLFSSL { #define SSL_CA_NAMES(ssl) ((ssl)->ca_names != NULL ? (ssl)->ca_names : \ (ssl)->ctx->ca_names) -WOLFSSL_LOCAL int SSL_CTX_RefCount(WOLFSSL_CTX* ctx, int incr); WOLFSSL_LOCAL int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup); WOLFSSL_LOCAL int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup); WOLFSSL_LOCAL int ReinitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup); diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 5747c0906..495d67437 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -382,10 +382,7 @@ struct WOLFSSL_EVP_PKEY { int type; /* openssh dereference */ int save_type; /* openssh dereference */ int pkey_sz; - int references; /*number of times free should be called for complete free*/ -#ifndef SINGLE_THREADED - wolfSSL_Mutex refMutex; /* ref count mutex */ -#endif + wolfSSL_Ref ref; union { char* ptr; /* der format of key */ @@ -560,10 +557,7 @@ struct WOLFSSL_BIO { WOLFSSL_CRYPTO_EX_DATA ex_data; #endif #if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) - #ifndef SINGLE_THREADED - wolfSSL_Mutex refMutex; /* ref count mutex */ - #endif - int refCount; /* reference count */ + wolfSSL_Ref ref; #endif }; @@ -614,10 +608,7 @@ struct WOLFSSL_X509_STORE { defined(WOLFSSL_WPAS_SMALL)) && defined(HAVE_CRL) WOLFSSL_X509_CRL *crl; /* points to cm->crl */ #endif -#ifndef SINGLE_THREADED - wolfSSL_Mutex refMutex; /* reference count mutex */ -#endif - int refCount; /* reference count */ + wolfSSL_Ref ref; }; #define WOLFSSL_ALWAYS_CHECK_SUBJECT 0x1