diff --git a/src/internal.c b/src/internal.c index 443743a97..ac6e58d62 100644 --- a/src/internal.c +++ b/src/internal.c @@ -27456,6 +27456,20 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, /* client only parts */ #ifndef NO_WOLFSSL_CLIENT + int HaveUniqueSessionObj(WOLFSSL* ssl) + { + if (ssl->session->ref.count > 1) { + WOLFSSL_SESSION* newSession = wolfSSL_SESSION_dup(ssl->session); + if (newSession == NULL) { + WOLFSSL_MSG("Session duplicate failed"); + return 0; + } + wolfSSL_FreeSession(ssl->ctx, ssl->session); + ssl->session = newSession; + } + return 1; + } + #ifndef WOLFSSL_NO_TLS12 /* handle generation of client_hello (1) */ @@ -28295,6 +28309,11 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, else { if (DSH_CheckSessionId(ssl)) { if (SetCipherSpecs(ssl) == 0) { + if (!HaveUniqueSessionObj(ssl)) { + WOLFSSL_MSG("Unable to have unique session object"); + WOLFSSL_ERROR_VERBOSE(MEMORY_ERROR); + return MEMORY_ERROR; + } XMEMCPY(ssl->arrays->masterSecret, ssl->session->masterSecret, SECRET_LEN); @@ -31810,14 +31829,8 @@ exit_scv: #ifdef HAVE_SESSION_TICKET int SetTicket(WOLFSSL* ssl, const byte* ticket, word32 length) { - /* If the session is shared, we need to copy-on-write */ - if (ssl->session->ref.count > 1) { - WOLFSSL_SESSION* nsession = wolfSSL_SESSION_dup(ssl->session); - if (nsession == NULL) - return MEMORY_E; - wolfSSL_FreeSession(ssl->ctx, ssl->session); - ssl->session = nsession; - } + if (!HaveUniqueSessionObj(ssl)) + return MEMORY_ERROR; /* Free old dynamic ticket if we already had one */ if (ssl->session->ticketLenAlloc > 0) { diff --git a/src/ssl.c b/src/ssl.c index 78f0bad9b..94f70e35a 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -14173,11 +14173,7 @@ int wolfSSL_SetSession(WOLFSSL* ssl, WOLFSSL_SESSION* session) if (ssl->session == session) { WOLFSSL_MSG("ssl->session and session same"); } - else -#ifdef HAVE_STUNNEL - /* stunnel depends on the ex_data not being duplicated. Copy OpenSSL - * behaviour for now. */ - if (session->type != WOLFSSL_SESSION_TYPE_CACHE) { + else if (session->type != WOLFSSL_SESSION_TYPE_CACHE) { if (wolfSSL_SESSION_up_ref(session) == WOLFSSL_SUCCESS) { wolfSSL_FreeSession(ssl->ctx, ssl->session); ssl->session = session; @@ -14185,9 +14181,7 @@ int wolfSSL_SetSession(WOLFSSL* ssl, WOLFSSL_SESSION* session) else ret = WOLFSSL_FAILURE; } - else -#endif - { + else { ret = wolfSSL_DupSession(session, ssl->session, 0); if (ret != WOLFSSL_SUCCESS) WOLFSSL_MSG("Session duplicate failed"); @@ -20607,7 +20601,6 @@ int wolfSSL_DupSession(const WOLFSSL_SESSION* input, WOLFSSL_SESSION* output, WOLFSSL_SESSION* wolfSSL_SESSION_dup(WOLFSSL_SESSION* session) { -#ifdef HAVE_EXT_CACHE WOLFSSL_SESSION* copy; WOLFSSL_ENTER("wolfSSL_SESSION_dup"); @@ -20630,11 +20623,6 @@ WOLFSSL_SESSION* wolfSSL_SESSION_dup(WOLFSSL_SESSION* session) copy = NULL; } return copy; -#else - WOLFSSL_MSG("wolfSSL_SESSION_dup feature not compiled in"); - (void)session; - return NULL; -#endif /* HAVE_EXT_CACHE */ } void wolfSSL_FreeSession(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* session) diff --git a/src/tls13.c b/src/tls13.c index 19898edff..19c43fffe 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -3704,6 +3704,12 @@ static int SetupPskKey(WOLFSSL* ssl, PreSharedKey* psk, int clientHello) if (psk == NULL) return BAD_FUNC_ARG; + if (!HaveUniqueSessionObj(ssl)) { + WOLFSSL_MSG("Unable to have unique session object"); + WOLFSSL_ERROR_VERBOSE(MEMORY_ERROR); + return MEMORY_ERROR; + } + suite[0] = ssl->options.cipherSuite0; suite[1] = ssl->options.cipherSuite; diff --git a/wolfssl/internal.h b/wolfssl/internal.h index deb876ed8..4cd593185 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -6209,6 +6209,7 @@ WOLFSSL_LOCAL void DoCertFatalAlert(WOLFSSL* ssl, int ret); WOLFSSL_LOCAL int cipherExtraData(WOLFSSL* ssl); #ifndef NO_WOLFSSL_CLIENT + WOLFSSL_LOCAL int HaveUniqueSessionObj(WOLFSSL* ssl); WOLFSSL_LOCAL int SendClientHello(WOLFSSL* ssl); WOLFSSL_LOCAL int DoHelloVerifyRequest(WOLFSSL* ssl, const byte* input, word32* inOutIdx, word32 size);