diff --git a/src/ssl.c b/src/ssl.c index f95ec4f1b..a27b09d16 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -12744,16 +12744,13 @@ int AddSession(WOLFSSL* ssl) #ifdef HAVE_EXT_CACHE if (ssl->options.internalCacheOff) { /* Create a new session object to be stored. */ - session = (WOLFSSL_SESSION*)XMALLOC(sizeof(WOLFSSL_SESSION), NULL, - DYNAMIC_TYPE_OPENSSL); + session = wolfSSL_SESSION_new(); if (session == NULL) { #ifdef HAVE_SESSION_TICKET XFREE(tmpBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK); #endif return MEMORY_E; } - XMEMSET(session, 0, sizeof(WOLFSSL_SESSION)); - session->isAlloced = 1; } else #endif @@ -17332,6 +17329,12 @@ WOLFSSL_X509* wolfSSL_d2i_X509(WOLFSSL_X509** x509, const unsigned char** in, int len) { WOLFSSL_X509* newX509 = NULL; + WOLFSSL_ENTER("wolfSSL_d2i_X509"); + + if (in == NULL) { + WOLFSSL_MSG("NULL input for wolfSSL_d2i_X509"); + return NULL; + } newX509 = wolfSSL_X509_d2i(x509, *in, len); if (newX509 != NULL) { @@ -19277,6 +19280,44 @@ int wolfSSL_session_reused(WOLFSSL* ssl) } #if defined(OPENSSL_EXTRA) || defined(HAVE_EXT_CACHE) +/* return a new malloc'd session with default settings on success */ +WOLFSSL_SESSION* wolfSSL_SESSION_new() +{ + WOLFSSL_SESSION* ret = NULL; + + ret = (WOLFSSL_SESSION*)XMALLOC(sizeof(WOLFSSL_SESSION), NULL, + DYNAMIC_TYPE_OPENSSL); + if (ret != NULL) { + XMEMSET(ret, 0, sizeof(WOLFSSL_SESSION)); + #ifdef OPENSSL_EXTRA + if (wc_InitMutex(&ret->refMutex) != 0) { + WOLFSSL_MSG("Error setting up session reference mutex"); + XFREE(ret, NULL, DYNAMIC_TYPE_OPENSSL); + return NULL; + } + #endif + ret->isAlloced = 1; + } + return ret; +} + + +/* add one to session reference count + * return WOFLSSL_SUCCESS on success and WOLFSSL_FAILURE on error */ +int wolfSSL_SESSION_up_ref(WOLFSSL_SESSION* session) +{ + if (session == NULL) + return WOLFSSL_FAILURE; + + if (wc_LockMutex(&session->refMutex) != 0) { + WOLFSSL_MSG("Failed to lock session mutex"); + } + session->refCount++; + wc_UnLockMutex(&session->refMutex); + return WOLFSSL_SUCCESS; +} + + WOLFSSL_SESSION* wolfSSL_SESSION_dup(WOLFSSL_SESSION* session) { #ifdef HAVE_EXT_CACHE @@ -19293,8 +19334,7 @@ WOLFSSL_SESSION* wolfSSL_SESSION_dup(WOLFSSL_SESSION* session) } #endif - copy = (WOLFSSL_SESSION*)XMALLOC(sizeof(WOLFSSL_SESSION), NULL, - DYNAMIC_TYPE_OPENSSL); + copy = wolfSSL_SESSION_new(); if (copy != NULL) { XMEMCPY(copy, session, sizeof(WOLFSSL_SESSION)); copy->isAlloced = 1; @@ -19331,7 +19371,18 @@ void wolfSSL_SESSION_free(WOLFSSL_SESSION* session) } #endif -#ifdef HAVE_EXT_CACHE +#ifdef OPENSSL_EXTRA + if (wc_LockMutex(&session->refMutex) != 0) { + WOLFSSL_MSG("Failed to lock session mutex"); + } + if (session->refCount > 0) { + session->refCount--; + wc_UnLockMutex(&session->refMutex); + return; + } + wc_UnLockMutex(&session->refMutex); +#endif +#if defined(HAVE_EXT_CACHE) || defined(OPENSSL_EXTRA) if (session->isAlloced) { #ifdef HAVE_SESSION_TICKET if (session->isDynamic) @@ -23939,7 +23990,10 @@ unsigned long wolfSSL_ERR_peek_error(void) int wolfSSL_ERR_GET_LIB(unsigned long err) { - switch (err) { + unsigned long value; + + value = (err & 0xFFFFFFL); + switch (value) { case PEM_R_NO_START_LINE: case PEM_R_PROBLEMS_GETTING_PASSWORD: case PEM_R_BAD_PASSWORD_READ: @@ -27220,12 +27274,9 @@ WOLFSSL_SESSION* wolfSSL_d2i_SSL_SESSION(WOLFSSL_SESSION** sess, return NULL; if (s == NULL) { - s = (WOLFSSL_SESSION*)XMALLOC(sizeof(WOLFSSL_SESSION), NULL, - DYNAMIC_TYPE_OPENSSL); + s = wolfSSL_SESSION_new(); if (s == NULL) return NULL; - XMEMSET(s, 0, sizeof(WOLFSSL_SESSION)); - s->isAlloced = 1; #ifdef HAVE_SESSION_TICKET s->isDynamic = 0; #endif @@ -42999,9 +43050,9 @@ unsigned long wolfSSL_ERR_peek_error_line_data(const char **file, int *line, if (ret == -ASN_NO_PEM_HEADER) return (ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE; - if (ret != WANT_READ && ret != WANT_WRITE && - ret != ZERO_RETURN && ret != WOLFSSL_ERROR_ZERO_RETURN && - ret != SOCKET_PEER_CLOSED_E && ret != SOCKET_ERROR_E) + if (ret != -WANT_READ && ret != -WANT_WRITE && + ret != -ZERO_RETURN && ret != -WOLFSSL_ERROR_ZERO_RETURN && + ret != -SOCKET_PEER_CLOSED_E && ret != -SOCKET_ERROR_E) break; wc_RemoveErrorNode(-1); @@ -43823,6 +43874,13 @@ int wolfSSL_X509_check_issued(WOLFSSL_X509 *issuer, WOLFSSL_X509 *subject) WOLFSSL_X509* wolfSSL_X509_dup(WOLFSSL_X509 *x) { + WOLFSSL_ENTER("wolfSSL_X509_dup"); + + if (x == NULL) { + WOLFSSL_MSG("Error: NULL certificate passed in"); + return NULL; + } + return wolfSSL_X509_d2i(NULL, x->derCert->buffer, x->derCert->length); } diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 1aeec5125..ad9524fc6 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -3154,6 +3154,8 @@ struct WOLFSSL_SESSION { #ifdef OPENSSL_EXTRA byte sessionCtxSz; /* sessionCtx length */ byte sessionCtx[ID_LEN]; /* app specific context id */ + wolfSSL_Mutex refMutex; /* ref count mutex */ + int refCount; /* reference count */ #endif #ifdef WOLFSSL_TLS13 word16 namedGroup; @@ -3174,7 +3176,7 @@ struct WOLFSSL_SESSION { byte staticTicket[SESSION_TICKET_LEN]; byte isDynamic; #endif -#ifdef HAVE_EXT_CACHE +#if defined(HAVE_EXT_CACHE) || defined(OPENSSL_EXTRA) byte isAlloced; #endif #ifdef HAVE_EX_DATA diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 1e97d4550..5f0e3c12c 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -302,6 +302,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define SSL_set_connect_state wolfSSL_set_connect_state #define SSL_set_accept_state wolfSSL_set_accept_state #define SSL_session_reused wolfSSL_session_reused +#define SSL_SESSION_up_ref wolfSSL_SESSION_up_ref #define SSL_SESSION_dup wolfSSL_SESSION_dup #define SSL_SESSION_free wolfSSL_SESSION_free #define SSL_is_init_finished wolfSSL_is_init_finished diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 551b68aa1..d02deb24c 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1153,7 +1153,9 @@ WOLFSSL_API int wolfSSL_set_session_id_context(WOLFSSL*, const unsigned char*, WOLFSSL_API void wolfSSL_set_connect_state(WOLFSSL*); WOLFSSL_API void wolfSSL_set_accept_state(WOLFSSL*); WOLFSSL_API int wolfSSL_session_reused(WOLFSSL*); +WOLFSSL_API int wolfSSL_SESSION_up_ref(WOLFSSL_SESSION* session); WOLFSSL_API WOLFSSL_SESSION* wolfSSL_SESSION_dup(WOLFSSL_SESSION* session); +WOLFSSL_API WOLFSSL_SESSION* wolfSSL_SESSION_new(void); WOLFSSL_API void wolfSSL_SESSION_free(WOLFSSL_SESSION* session); WOLFSSL_API int wolfSSL_is_init_finished(WOLFSSL*);