Merge pull request #5107 from julek-wolfssl/wpas-ex-data-leak

Call ctx->rem_sess_cb when a session is about to be invalid
pull/5148/head
David Garske 2022-05-16 13:27:08 -07:00 committed by GitHub
commit ec619e3f35
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 390 additions and 56 deletions

View File

@ -2385,7 +2385,7 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx)
wolfSSL_sk_X509_NAME_pop_free(ctx->ca_names, NULL);
ctx->ca_names = NULL;
#endif
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
#ifdef OPENSSL_EXTRA
if (ctx->x509Chain) {
wolfSSL_sk_X509_pop_free(ctx->x509Chain, NULL);
ctx->x509Chain = NULL;
@ -7229,7 +7229,7 @@ void SSL_ResourceFree(WOLFSSL* ssl)
#endif
if (ssl->session != NULL)
wolfSSL_FreeSession(ssl->session);
wolfSSL_FreeSession(ssl->ctx, ssl->session);
#ifdef HAVE_WRITE_DUP
if (ssl->dupWrite) {
FreeWriteDup(ssl);
@ -7299,7 +7299,7 @@ void SSL_ResourceFree(WOLFSSL* ssl)
#endif
}
#endif /* WOLFSSL_STATIC_MEMORY */
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
#ifdef OPENSSL_EXTRA
/* Enough to free stack structure since WOLFSSL_CIPHER
* isn't allocated separately. */
wolfSSL_sk_CIPHER_free(ssl->supportedCiphers);
@ -7531,11 +7531,11 @@ void FreeHandshakeResources(WOLFSSL* ssl)
/* heap argument is the heap hint used when creating SSL */
void FreeSSL(WOLFSSL* ssl, void* heap)
{
if (ssl->ctx) {
FreeSSL_Ctx(ssl->ctx); /* will decrement and free underlying CTX if 0 */
}
WOLFSSL_CTX* ctx = ssl->ctx;
SSL_ResourceFree(ssl);
XFREE(ssl, heap, DYNAMIC_TYPE_SSL);
if (ctx)
FreeSSL_Ctx(ctx); /* will decrement and free underlying CTX if 0 */
(void)heap;
}
@ -29344,9 +29344,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
WOLFSSL_MSG("Session lookup for resume failed");
ssl->options.resuming = 0;
} else {
#ifdef HAVE_EXT_CACHE
wolfSSL_SESSION_free(session);
#endif
if (MatchSuite(ssl, &clSuites) < 0) {
WOLFSSL_MSG("Unsupported cipher suite, OldClientHello");
return UNSUPPORTED_SUITE;

241
src/ssl.c
View File

@ -9969,7 +9969,7 @@ WOLFSSL_SESSION* wolfSSL_get_session(WOLFSSL* ssl)
id = ssl->session->altSessionID;
idSz = ID_LEN;
}
error = AddSessionToCache(ssl->session, id, idSz,
error = AddSessionToCache(ssl->ctx, ssl->session, id, idSz,
NULL, ssl->session->side,
#ifdef HAVE_SESSION_TICKET
ssl->session->ticketLen > 0,
@ -10057,7 +10057,7 @@ int wolfSSL_SetServerID(WOLFSSL* ssl, const byte* id, int len, int newSession)
if (session) {
if (wolfSSL_SetSession(ssl, session) != WOLFSSL_SUCCESS) {
#ifdef HAVE_EXT_CACHE
wolfSSL_FreeSession(session);
wolfSSL_FreeSession(ssl->ctx, session);
#endif
WOLFSSL_MSG("wolfSSL_SetSession failed");
session = NULL;
@ -10073,7 +10073,7 @@ int wolfSSL_SetServerID(WOLFSSL* ssl, const byte* id, int len, int newSession)
}
#ifdef HAVE_EXT_CACHE
else {
wolfSSL_FreeSession(session);
wolfSSL_FreeSession(ssl->ctx, session);
}
#endif
@ -12998,9 +12998,12 @@ int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output)
if (sess != NULL) {
WOLFSSL_MSG("Session found in external cache");
error = wolfSSL_DupSession(sess, output, 0);
#ifdef HAVE_EX_DATA
output->ownExData = 0; /* Session cache owns external data */
#endif
/* If copy not set then free immediately */
if (!copy)
wolfSSL_SESSION_free(sess);
wolfSSL_FreeSession(ssl->ctx, sess);
/* We want to restore the bogus ID for TLS compatibility */
if (ssl->session->haveAltSessionID &&
output == ssl->session) {
@ -13106,6 +13109,9 @@ int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output)
}
#endif
error = wolfSSL_DupSession(sess, output, 1);
#ifdef HAVE_EX_DATA
output->ownExData = 0; /* Session cache owns external data */
#endif
}
else {
error = WOLFSSL_FAILURE;
@ -13436,9 +13442,9 @@ WOLFSSL_SESSION* ClientSessionToSession(const WOLFSSL_SESSION* session)
#endif
}
int AddSessionToCache(WOLFSSL_SESSION* addSession, const byte* id, byte idSz,
int* sessionIndex, int side, word16 useTicket,
ClientSession** clientCacheEntry)
int AddSessionToCache(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* addSession,
const byte* id, byte idSz, int* sessionIndex, int side,
word16 useTicket, ClientSession** clientCacheEntry)
{
WOLFSSL_SESSION* cacheSession = NULL;
SessionRow* sessRow = NULL;
@ -13457,6 +13463,7 @@ int AddSessionToCache(WOLFSSL_SESSION* addSession, const byte* id, byte idSz,
int i;
int overwrite = 0;
(void)ctx;
(void)sessionIndex;
(void)useTicket;
(void)clientCacheEntry;
@ -13517,6 +13524,16 @@ int AddSessionToCache(WOLFSSL_SESSION* addSession, const byte* id, byte idSz,
*sessionIndex = (row << SESSIDX_ROW_SHIFT) | idx;
#endif
cacheSession = &sessRow->Sessions[idx];
#ifdef HAVE_EX_DATA
if (cacheSession->rem_sess_cb && cacheSession->ownExData) {
cacheSession->rem_sess_cb(NULL, cacheSession);
/* Make sure not to call remove functions again */
cacheSession->ownExData = 0;
cacheSession->rem_sess_cb = NULL;
}
#endif
cacheSession->type = WOLFSSL_SESSION_TYPE_CACHE;
cacheSession->cacheRow = row;
@ -13562,6 +13579,13 @@ int AddSessionToCache(WOLFSSL_SESSION* addSession, const byte* id, byte idSz,
XMEMCPY(cacheSession->sessionID, id, ID_LEN);
cacheSession->sessionIDSz = ID_LEN;
}
#ifdef HAVE_EX_DATA
if (ctx->rem_sess_cb != NULL) {
addSession->ownExData = 0;
cacheSession->ownExData = 1;
cacheSession->rem_sess_cb = ctx->rem_sess_cb;
}
#endif
}
#ifdef HAVE_SESSION_TICKET
else if (ticBuffUsed) {
@ -13576,10 +13600,10 @@ int AddSessionToCache(WOLFSSL_SESSION* addSession, const byte* id, byte idSz,
cacheSession = NULL; /* Can't access after unlocked */
#ifndef NO_CLIENT_CACHE
if (ret == 0) {
if (ret == 0 && clientCacheEntry != NULL) {
ClientSession* clientCache = AddSessionToClientCache(side, row, idx,
addSession->serverID, addSession->idLen, id, useTicket);
if (clientCache != NULL && clientCacheEntry != NULL)
if (clientCache != NULL)
*clientCacheEntry = clientCache;
}
#endif
@ -13699,12 +13723,15 @@ void AddSession(WOLFSSL* ssl)
}
/* Setup done */
if (ssl->options.side == WOLFSSL_SERVER_END /* No point in adding a
* client session */
#ifdef HAVE_EXT_CACHE
if (!ssl->options.internalCacheOff)
&& !ssl->options.internalCacheOff
#endif
)
{
/* Try to add the session to cache. Its ok if we don't succeed. */
(void)AddSessionToCache(session, id, idSz,
(void)AddSessionToCache(ssl->ctx, session, id, idSz,
#ifdef SESSION_INDEX
&ssl->sessionIndex,
#else
@ -13725,7 +13752,7 @@ void AddSession(WOLFSSL* ssl)
wolfSSL_SESSION_up_ref(session);
cbRet = ssl->ctx->new_sess_cb(ssl, session);
if (cbRet == 0)
wolfSSL_FreeSession(session);
wolfSSL_FreeSession(ssl->ctx, session);
}
#endif
@ -19317,6 +19344,9 @@ WOLFSSL_SESSION* wolfSSL_NewSession(void* heap)
XFREE(ret, NULL, DYNAMIC_TYPE_OPENSSL);
return NULL;
}
#endif
#ifdef HAVE_EX_DATA
ret->ownExData = 1;
#endif
}
return ret;
@ -19534,7 +19564,7 @@ WOLFSSL_SESSION* wolfSSL_SESSION_dup(WOLFSSL_SESSION* session)
copy = wolfSSL_NewSession(session->heap);
if (copy != NULL &&
wolfSSL_DupSession(session, copy, 0) != WOLFSSL_SUCCESS) {
wolfSSL_FreeSession(copy);
wolfSSL_FreeSession(NULL, copy);
copy = NULL;
}
return copy;
@ -19545,12 +19575,14 @@ WOLFSSL_SESSION* wolfSSL_SESSION_dup(WOLFSSL_SESSION* session)
#endif /* HAVE_EXT_CACHE */
}
void wolfSSL_FreeSession(WOLFSSL_SESSION* session)
void wolfSSL_FreeSession(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* session)
{
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) {
@ -19573,6 +19605,18 @@ void wolfSSL_FreeSession(WOLFSSL_SESSION* session)
#endif
}
#if defined(HAVE_EXT_CACHE) || defined(HAVE_EX_DATA)
if (ctx != NULL && ctx->rem_sess_cb
#ifdef HAVE_EX_DATA
&& session->ownExData /* This will be true if we are not using the
* internal cache so it will get called for
* externally cached sessions as well. */
#endif
) {
ctx->rem_sess_cb(ctx, session);
}
#endif
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
wolfSSL_CRYPTO_cleanup_ex_data(&session->ex_data);
#endif
@ -19602,7 +19646,7 @@ void wolfSSL_FreeSession(WOLFSSL_SESSION* session)
void wolfSSL_SESSION_free(WOLFSSL_SESSION* session)
{
session = ClientSessionToSession(session);
wolfSSL_FreeSession(session);
wolfSSL_FreeSession(NULL, session);
}
#ifndef NO_SESSION_CACHE
@ -19628,7 +19672,7 @@ int wolfSSL_CTX_add_session(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* session)
idSz = ID_LEN;
}
error = AddSessionToCache(session, id, idSz,
error = AddSessionToCache(ctx, session, id, idSz,
NULL, session->side,
#ifdef HAVE_SESSION_TICKET
session->ticketLen > 0,
@ -19921,30 +19965,16 @@ const WOLFSSL_CIPHER* wolfSSL_get_cipher_by_value(word16 value)
}
#if defined(OPENSSL_ALL)
#if defined(OPENSSL_EXTRA)
/* Free the structure for WOLFSSL_CIPHER stack
*
* sk stack to free nodes in
*/
void wolfSSL_sk_CIPHER_free(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk)
{
WOLFSSL_STACK* node;
WOLFSSL_STACK* tmp;
WOLFSSL_ENTER("wolfSSL_sk_CIPHER_free");
if (sk == NULL)
return;
/* parse through stack freeing each node */
node = sk->next;
while (node) {
tmp = node;
node = node->next;
XFREE(tmp, NULL, DYNAMIC_TYPE_OPENSSL);
}
/* free head of stack */
XFREE(sk, NULL, DYNAMIC_TYPE_ASN1);
wolfSSL_sk_free(sk);
}
#endif /* OPENSSL_ALL */
@ -24689,7 +24719,7 @@ void wolfSSL_CTX_sess_set_remove_cb(WOLFSSL_CTX* ctx, void (*f)(WOLFSSL_CTX*,
if (ctx == NULL)
return;
#ifdef HAVE_EXT_CACHE
#if defined(HAVE_EXT_CACHE) || defined(HAVE_EX_DATA)
ctx->rem_sess_cb = f;
#else
(void)f;
@ -30474,14 +30504,87 @@ void wolfSSL_print_all_errors_fp(XFILE fp)
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
defined(HAVE_EX_DATA)
#if defined(HAVE_EX_DATA) && !defined(NO_SESSION_CACHE)
static void SESSION_ex_data_cache_update(WOLFSSL_SESSION* session, int idx,
void* data, byte get, void** getRet, int* setRet)
{
int row;
int i;
int error = 0;
SessionRow* sessRow = NULL;
const byte* id;
byte foundCache = 0;
if (getRet != NULL)
*getRet = NULL;
if (setRet != NULL)
*setRet = WOLFSSL_FAILURE;
id = session->sessionID;
if (session->haveAltSessionID)
id = session->altSessionID;
row = (int)(HashSession(id, ID_LEN, &error) % SESSION_ROWS);
if (error != 0) {
WOLFSSL_MSG("Hash session failed");
return;
}
sessRow = &SessionCache[row];
if (SESSION_ROW_LOCK(sessRow) != 0) {
WOLFSSL_MSG("Session row lock failed");
return;
}
for (i = 0; i < SESSIONS_PER_ROW && i < sessRow->totalCount; i++) {
if (XMEMCMP(id, sessRow->Sessions[i].sessionID, ID_LEN) == 0
&& session->side == sessRow->Sessions[i].side) {
if (get) {
*getRet = wolfSSL_CRYPTO_get_ex_data(
&sessRow->Sessions[i].ex_data, idx);
}
else {
*setRet = wolfSSL_CRYPTO_set_ex_data(
&sessRow->Sessions[i].ex_data, idx, data);
}
foundCache = 1;
break;
}
}
SESSION_ROW_UNLOCK(sessRow);
/* If we don't have a session in cache then clear the ex_data and
* own it */
if (!foundCache) {
XMEMSET(&session->ex_data, 0, sizeof(WOLFSSL_CRYPTO_EX_DATA));
session->ownExData = 1;
if (!get) {
*setRet = wolfSSL_CRYPTO_set_ex_data(&session->ex_data, idx,
data);
}
}
}
#endif
int wolfSSL_SESSION_set_ex_data(WOLFSSL_SESSION* session, int idx, void* data)
{
int ret = WOLFSSL_FAILURE;
WOLFSSL_ENTER("wolfSSL_SESSION_set_ex_data");
#ifdef HAVE_EX_DATA
session = ClientSessionToSession(session);
if (session != NULL)
ret = wolfSSL_CRYPTO_set_ex_data(&session->ex_data, idx, data);
if (session != NULL) {
#ifndef NO_SESSION_CACHE
if (!session->ownExData) {
/* Need to update in cache */
SESSION_ex_data_cache_update(session, idx, data, 0, NULL, &ret);
}
else
#endif
{
ret = wolfSSL_CRYPTO_set_ex_data(&session->ex_data, idx, data);
}
}
#else
(void)session;
(void)idx;
@ -30509,17 +30612,28 @@ int wolfSSL_SESSION_set_ex_data_with_cleanup(
void* wolfSSL_SESSION_get_ex_data(const WOLFSSL_SESSION* session, int idx)
{
void* ret = NULL;
WOLFSSL_ENTER("wolfSSL_SESSION_get_ex_data");
#ifdef HAVE_EX_DATA
session = ClientSessionToSession(session);
if (session != NULL) {
return wolfSSL_CRYPTO_get_ex_data(&session->ex_data, idx);
#ifndef NO_SESSION_CACHE
if (!session->ownExData) {
/* Need to retrieve the data from the session cache */
SESSION_ex_data_cache_update((WOLFSSL_SESSION*)session, idx, NULL,
1, &ret, NULL);
}
else
#endif
{
ret = wolfSSL_CRYPTO_get_ex_data(&session->ex_data, idx);
}
}
#else
(void)session;
(void)idx;
#endif
return NULL;
return ret;
}
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL || HAVE_EX_DATA */
@ -32209,11 +32323,60 @@ int wolfSSL_SSL_CTX_remove_session(WOLFSSL_CTX *ctx, WOLFSSL_SESSION *s)
{
/* Don't remove session just timeout session. */
s->timeout = 0;
#ifndef NO_SESSION_CACHE
/* Clear the timeout in the cache */
{
int row;
int i;
SessionRow* sessRow = NULL;
WOLFSSL_SESSION *cacheSession;
const byte* id;
int ret = 0;
id = s->sessionID;
if (s->haveAltSessionID)
id = s->altSessionID;
row = (int)(HashSession(id, ID_LEN, &ret) % SESSION_ROWS);
if (ret != 0) {
WOLFSSL_MSG("Hash session failed");
return ret;
}
sessRow = &SessionCache[row];
if (SESSION_ROW_LOCK(sessRow) != 0) {
WOLFSSL_MSG("Session row lock failed");
return BAD_MUTEX_E;
}
for (i = 0; i < SESSIONS_PER_ROW && i < sessRow->totalCount; i++) {
cacheSession = &sessRow->Sessions[i];
if (XMEMCMP(id, cacheSession->sessionID, ID_LEN) == 0) {
if (ctx->method->side != cacheSession->side)
continue;
cacheSession->timeout = 0;
#ifdef HAVE_EX_DATA
if (cacheSession->ownExData) {
/* Most recent version of ex data is in cache. Copy it
* over so the user can free it. */
XMEMCPY(&s->ex_data, &cacheSession->ex_data,
sizeof(WOLFSSL_CRYPTO_EX_DATA));
}
cacheSession->ownExData = 0; /* We clear below */
s->ownExData = 1;
#endif
break;
}
}
SESSION_ROW_UNLOCK(sessRow);
}
#endif
}
#ifdef HAVE_EXT_CACHE
if (ctx->rem_sess_cb != NULL)
#if defined(HAVE_EXT_CACHE) || defined(HAVE_EX_DATA)
if (ctx->rem_sess_cb != NULL) {
ctx->rem_sess_cb(ctx, s);
}
#endif
return 0;

View File

@ -2829,13 +2829,13 @@ static int SetupPskKey(WOLFSSL* ssl, PreSharedKey* psk, int clientHello)
/* OpenSSL compatible callback that gets cached session. */
if (ssl->options.session_psk_cb(ssl, handshake_md, &id, &idlen,
&psksession) == 0) {
wolfSSL_SESSION_free(psksession);
wolfSSL_FreeSession(ssl->ctx, psksession);
WOLFSSL_MSG("psk session callback failed");
return PSK_KEY_ERROR;
}
if (psksession != NULL) {
if (idlen > MAX_PSK_KEY_LEN) {
wolfSSL_SESSION_free(psksession);
wolfSSL_FreeSession(ssl->ctx, psksession);
WOLFSSL_MSG("psk key length is too long");
return PSK_KEY_ERROR;
}
@ -2845,7 +2845,7 @@ static int SetupPskKey(WOLFSSL* ssl, PreSharedKey* psk, int clientHello)
suite[0] = psksession->cipherSuite0;
suite[1] = psksession->cipherSuite;
/* Not needed anymore. */
wolfSSL_SESSION_free(psksession);
wolfSSL_FreeSession(ssl->ctx, psksession);
/* Leave pointer not NULL to indicate success with callback. */
}
}

View File

@ -39980,6 +39980,170 @@ static void test_wolfSSL_SESSION(void)
#endif
}
#if defined(OPENSSL_EXTRA) && defined(HAVE_IO_TESTS_DEPENDENCIES) && \
defined(HAVE_EX_DATA)
static int clientSessRemCountMalloc = 0;
static int serverSessRemCountMalloc = 0;
static int clientSessRemCountFree = 0;
static int serverSessRemCountFree = 0;
static WOLFSSL_CTX* serverSessCtx = NULL;
static WOLFSSL_SESSION* serverSess = NULL;
#ifndef NO_SESSION_CACHE_REF
static WOLFSSL_CTX* clientSessCtx = NULL;
static WOLFSSL_SESSION* clientSess = NULL;
#endif
static int serverSessRemIdx = 3;
static void SessRemCtxCb(WOLFSSL_CTX *ctx, WOLFSSL_SESSION *sess)
{
int* mallocedData = (int*)SSL_SESSION_get_ex_data(sess, serverSessRemIdx);
(void)ctx;
AssertNotNull(mallocedData);
if (!*mallocedData)
clientSessRemCountFree++;
else
serverSessRemCountFree++;
XFREE(mallocedData, NULL, DYNAMIC_TYPE_SESSION);
SSL_SESSION_set_ex_data(sess, serverSessRemIdx, NULL);
}
static void SessRemCtxSetupCb(WOLFSSL_CTX* ctx)
{
SSL_CTX_sess_set_remove_cb(ctx, SessRemCtxCb);
#if defined(WOLFSSL_TLS13) && !defined(HAVE_SESSION_TICKET) && \
!defined(NO_SESSION_CACHE_REF)
/* Allow downgrade, set min version, and disable TLS 1.3.
* Do this because without NO_SESSION_CACHE_REF we will want to return a
* reference to the session cache. But with WOLFSSL_TLS13 and without
* HAVE_SESSION_TICKET we won't have a session ID to be able to place the
* session in the cache. In this case we need to downgrade to previous
* versions to just use the legacy session ID field. */
AssertIntEQ(SSL_CTX_set_min_proto_version(ctx, SSL3_VERSION), SSL_SUCCESS);
AssertIntEQ(SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION), SSL_SUCCESS);
#endif
}
static void SessRemSslSetupCb(WOLFSSL* ssl)
{
int* mallocedData = (int*)XMALLOC(sizeof(int), NULL, DYNAMIC_TYPE_SESSION);
AssertNotNull(mallocedData);
*mallocedData = SSL_is_server(ssl);
if (!*mallocedData) {
clientSessRemCountMalloc++;
#ifndef NO_SESSION_CACHE_REF
AssertNotNull(clientSess = SSL_get1_session(ssl));
AssertIntEQ(SSL_CTX_up_ref(clientSessCtx = SSL_get_SSL_CTX(ssl)),
SSL_SUCCESS);
#endif
}
else {
serverSessRemCountMalloc++;
AssertNotNull(serverSess = SSL_get1_session(ssl));
AssertIntEQ(SSL_CTX_up_ref(serverSessCtx = SSL_get_SSL_CTX(ssl)),
SSL_SUCCESS);
}
AssertIntEQ(SSL_SESSION_set_ex_data(SSL_get_session(ssl), serverSessRemIdx,
mallocedData), SSL_SUCCESS);
}
#endif
static void test_wolfSSL_CTX_sess_set_remove_cb(void)
{
#if defined(OPENSSL_EXTRA) && defined(HAVE_IO_TESTS_DEPENDENCIES) && \
defined(HAVE_EX_DATA)
/* Check that the remove callback gets called for external data in a
* session object */
callback_functions func_cb;
tcp_ready ready;
func_args client_args;
func_args server_args;
THREAD_TYPE serverThread;
printf(testingFmt, "wolfSSL_CTX_sess_set_remove_cb()");
XMEMSET(&client_args, 0, sizeof(func_args));
XMEMSET(&server_args, 0, sizeof(func_args));
XMEMSET(&func_cb, 0, sizeof(callback_functions));
#ifdef WOLFSSL_TIRTOS
fdOpenSession(Task_self());
#endif
StartTCP();
InitTcpReady(&ready);
#if defined(USE_WINDOWS_API)
/* use RNG to get random port if using windows */
ready.port = GetRandomPort();
#endif
server_args.signal = &ready;
client_args.signal = &ready;
client_args.callbacks = &func_cb;
server_args.callbacks = &func_cb;
func_cb.ctx_ready = SessRemCtxSetupCb;
func_cb.on_result = SessRemSslSetupCb;
start_thread(test_server_nofail, &server_args, &serverThread);
wait_tcp_ready(&server_args);
test_client_nofail(&client_args, NULL);
join_thread(serverThread);
AssertTrue(client_args.return_code);
AssertTrue(server_args.return_code);
FreeTcpReady(&ready);
#ifdef WOLFSSL_TIRTOS
fdOpenSession(Task_self());
#endif
/* Both should have been allocated */
AssertIntEQ(clientSessRemCountMalloc, 1);
AssertIntEQ(serverSessRemCountMalloc, 1);
#ifdef NO_SESSION_CACHE_REF
/* Client session should not be added to cache so this should be free'd when
* the SSL object was being free'd */
AssertIntEQ(clientSessRemCountFree, 1);
#else
/* Client session is in cache due to requiring a persistent reference */
AssertIntEQ(clientSessRemCountFree, 0);
/* Force a cache lookup */
AssertNotNull(SSL_SESSION_get_ex_data(clientSess, serverSessRemIdx));
/* Force a cache update */
AssertNotNull(SSL_SESSION_set_ex_data(clientSess, serverSessRemIdx - 1, 0));
/* This should set the timeout to 0 and call the remove callback from within
* the session cache. */
AssertIntEQ(SSL_CTX_remove_session(clientSessCtx, clientSess), 0);
AssertNull(SSL_SESSION_get_ex_data(clientSess, serverSessRemIdx));
AssertIntEQ(clientSessRemCountFree, 1);
#endif
/* Server session is in the cache so ex_data isn't free'd with the SSL
* object */
AssertIntEQ(serverSessRemCountFree, 0);
/* Force a cache lookup */
AssertNotNull(SSL_SESSION_get_ex_data(serverSess, serverSessRemIdx));
/* Force a cache update */
AssertNotNull(SSL_SESSION_set_ex_data(serverSess, serverSessRemIdx - 1, 0));
/* This should set the timeout to 0 and call the remove callback from within
* the session cache. */
AssertIntEQ(SSL_CTX_remove_session(serverSessCtx, serverSess), 0);
AssertNull(SSL_SESSION_get_ex_data(serverSess, serverSessRemIdx));
AssertIntEQ(serverSessRemCountFree, 1);
/* Need to free the references that we kept */
SSL_CTX_free(serverSessCtx);
SSL_SESSION_free(serverSess);
#ifndef NO_SESSION_CACHE_REF
SSL_CTX_free(clientSessCtx);
SSL_SESSION_free(clientSess);
#endif
printf(resultFmt, passed);
#endif
}
static void test_wolfSSL_ticket_keys(void)
{
#if defined(HAVE_SESSION_TICKET) && !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
@ -54115,6 +54279,7 @@ void ApiTest(void)
#endif
test_wolfSSL_cert_cb();
test_wolfSSL_SESSION();
test_wolfSSL_CTX_sess_set_remove_cb();
test_wolfSSL_ticket_keys();
test_wolfSSL_DES_ecb_encrypt();
test_wolfSSL_sk_GENERAL_NAME();

View File

@ -3080,7 +3080,9 @@ struct WOLFSSL_CTX {
#ifdef HAVE_EXT_CACHE
WOLFSSL_SESSION*(*get_sess_cb)(WOLFSSL*, const unsigned char*, int, int*);
int (*new_sess_cb)(WOLFSSL*, WOLFSSL_SESSION*);
void (*rem_sess_cb)(WOLFSSL_CTX*, WOLFSSL_SESSION*);
#endif
#if defined(HAVE_EXT_CACHE) || defined(HAVE_EX_DATA)
Rem_Sess_Cb rem_sess_cb;
#endif
#if defined(OPENSSL_EXTRA) && defined(WOLFCRYPT_HAVE_SRP) && !defined(NO_SHA256)
Srp* srp; /* TLS Secure Remote Password Protocol*/
@ -3352,6 +3354,10 @@ struct WOLFSSL_SESSION {
#endif
byte altSessionID[ID_LEN];
byte haveAltSessionID:1;
#ifdef HAVE_EX_DATA
byte ownExData:1;
Rem_Sess_Cb rem_sess_cb;
#endif
void* heap;
/* WARNING The above fields (up to and including the heap) are not copied
* in wolfSSL_DupSession. Place new fields after the heap
@ -3444,9 +3450,9 @@ WOLFSSL_LOCAL WOLFSSL_SESSION* wolfSSL_NewSession(void* heap);
WOLFSSL_LOCAL WOLFSSL_SESSION* wolfSSL_GetSession(
WOLFSSL* ssl, byte* masterSecret, byte restoreSessionCerts);
WOLFSSL_LOCAL void AddSession(WOLFSSL* ssl);
WOLFSSL_LOCAL int AddSessionToCache(WOLFSSL_SESSION* addSession, const byte* id,
byte idSz, int* sessionIndex, int side, word16 useTicket,
ClientSession** clientCacheEntry);
WOLFSSL_LOCAL int AddSessionToCache(WOLFSSL_CTX* ssl,
WOLFSSL_SESSION* addSession, const byte* id, byte idSz, int* sessionIndex,
int side, word16 useTicket, ClientSession** clientCacheEntry);
#ifndef NO_CLIENT_CACHE
WOLFSSL_LOCAL ClientSession* AddSessionToClientCache(int side, int row, int idx,
byte* serverID, word16 idLen, const byte* sessionID,
@ -3456,7 +3462,8 @@ WOLFSSL_LOCAL
WOLFSSL_SESSION* ClientSessionToSession(const WOLFSSL_SESSION* session);
WOLFSSL_LOCAL int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output);
WOLFSSL_LOCAL int wolfSSL_SetSession(WOLFSSL* ssl, WOLFSSL_SESSION* session);
WOLFSSL_LOCAL void wolfSSL_FreeSession(WOLFSSL_SESSION* session);
WOLFSSL_LOCAL void wolfSSL_FreeSession(WOLFSSL_CTX* ctx,
WOLFSSL_SESSION* session);
WOLFSSL_LOCAL int wolfSSL_DupSession(const WOLFSSL_SESSION* input,
WOLFSSL_SESSION* output, int avoidSysCalls);

View File

@ -4628,6 +4628,8 @@ WOLFSSL_API int wolfSSL_CTX_AsyncPoll(WOLFSSL_CTX* ctx, WOLF_EVENT** events, int
WOLF_EVENT_FLAG flags, int* eventCount);
#endif /* WOLFSSL_ASYNC_CRYPT */
typedef void (*Rem_Sess_Cb)(WOLFSSL_CTX*, WOLFSSL_SESSION*);
#ifdef OPENSSL_EXTRA
typedef void (*SSL_Msg_Cb)(int write_p, int version, int content_type,
const void *buf, size_t len, WOLFSSL *ssl, void *arg);