Improve TLS client side session cache references to provide option for not returning an internal session cache pointer. Now use wolfSSL_get1_sesson for reference logic, that requires calling wolfSSL_SESSION_free. To disable this feature use NO_SESSION_CACHE_REF.

This commit is contained in:
David Garske
2021-12-22 12:51:01 -08:00
parent 57d2555ac8
commit 569c066fab
9 changed files with 495 additions and 270 deletions

View File

@ -1753,17 +1753,20 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
SOCKET_T sockfd = WOLFSSL_SOCKET_INVALID; SOCKET_T sockfd = WOLFSSL_SOCKET_INVALID;
wolfSSL_method_func method = NULL; wolfSSL_method_func method = NULL;
WOLFSSL_CTX* ctx = 0; WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = 0; WOLFSSL* ssl = NULL;
#ifdef WOLFSSL_WOLFSENTRY_HOOKS #ifdef WOLFSSL_WOLFSENTRY_HOOKS
wolfsentry_errcode_t wolfsentry_ret; wolfsentry_errcode_t wolfsentry_ret;
#endif #endif
WOLFSSL* sslResume = 0; WOLFSSL* sslResume = NULL;
WOLFSSL_SESSION* session = 0; WOLFSSL_SESSION* session = NULL;
#if !defined(NO_SESSION_CACHE) && (defined(OPENSSL_EXTRA) || \
defined(HAVE_EXT_CACHE))
byte* flatSession = NULL; byte* flatSession = NULL;
int flatSessionSz = 0; int flatSessionSz = 0;
#endif
char msg[CLI_MSG_SZ]; char msg[CLI_MSG_SZ];
int msgSz = 0; int msgSz = 0;
@ -1957,8 +1960,6 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
#endif #endif
(void)session; (void)session;
(void)flatSession;
(void)flatSessionSz;
(void)sslResume; (void)sslResume;
(void)atomicUser; (void)atomicUser;
(void)scr; (void)scr;
@ -3898,7 +3899,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
#ifndef NO_SESSION_CACHE #ifndef NO_SESSION_CACHE
if (resumeSession) { if (resumeSession) {
session = wolfSSL_get_session(ssl); session = wolfSSL_get1_session(ssl);
} }
#endif #endif
@ -3914,6 +3915,9 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
XFREE(flatSession, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(flatSession, NULL, DYNAMIC_TYPE_TMP_BUFFER);
err_sys("flat session size check failure"); err_sys("flat session size check failure");
} }
/* using heap based flat session, free original session */
wolfSSL_SESSION_free(session);
session = NULL;
} }
} }
#endif #endif
@ -4006,9 +4010,11 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
#if defined(OPENSSL_EXTRA) && defined(HAVE_EXT_CACHE) #if defined(OPENSSL_EXTRA) && defined(HAVE_EXT_CACHE)
if (flatSession) { if (flatSession) {
XFREE(flatSession, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(flatSession, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL_SESSION_free(session);
} }
#endif #endif
wolfSSL_SESSION_free(session);
session = NULL;
#ifdef HAVE_SESSION_TICKET #ifdef HAVE_SESSION_TICKET
wolfSSL_set_SessionTicket_cb(sslResume, sessionTicketCB, wolfSSL_set_SessionTicket_cb(sslResume, sessionTicketCB,
(void*)"resumed session"); (void*)"resumed session");

View File

@ -6637,9 +6637,16 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
} }
#endif /*OPENSSL_EXTRA && HAVE_SECRET_CALLBACK */ #endif /*OPENSSL_EXTRA && HAVE_SECRET_CALLBACK */
ssl->session.masterSecret = ssl->session._masterSecret;
#ifndef NO_CLIENT_CACHE
ssl->session.serverID = ssl->session._serverID;
#endif
#ifdef OPENSSL_EXTRA
ssl->session.sessionCtx = ssl->session._sessionCtx;
#endif
#ifdef HAVE_SESSION_TICKET #ifdef HAVE_SESSION_TICKET
ssl->options.noTicketTls12 = ctx->noTicketTls12; ssl->options.noTicketTls12 = ctx->noTicketTls12;
ssl->session.ticket = ssl->session.staticTicket; ssl->session.ticket = ssl->session._staticTicket;
#endif #endif
#ifdef WOLFSSL_MULTICAST #ifdef WOLFSSL_MULTICAST
@ -7215,10 +7222,10 @@ void SSL_ResourceFree(WOLFSSL* ssl)
#endif #endif
#ifdef HAVE_SESSION_TICKET #ifdef HAVE_SESSION_TICKET
if (ssl->session.isDynamic) { if (ssl->session.ticketLenAlloc > 0) {
XFREE(ssl->session.ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK); XFREE(ssl->session.ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
ssl->session.ticket = ssl->session.staticTicket; ssl->session.ticket = ssl->session._staticTicket;
ssl->session.isDynamic = 0; ssl->session.ticketLenAlloc = 0;
ssl->session.ticketLen = 0; ssl->session.ticketLen = 0;
} }
#endif #endif
@ -7492,10 +7499,10 @@ void FreeHandshakeResources(WOLFSSL* ssl)
#endif /* HAVE_PK_CALLBACKS */ #endif /* HAVE_PK_CALLBACKS */
#ifdef HAVE_SESSION_TICKET #ifdef HAVE_SESSION_TICKET
if (ssl->session.isDynamic) { if (ssl->session.ticketLenAlloc > 0) {
XFREE(ssl->session.ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK); XFREE(ssl->session.ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
ssl->session.ticket = ssl->session.staticTicket; ssl->session.ticket = ssl->session._staticTicket;
ssl->session.isDynamic = 0; ssl->session.ticketLenAlloc = 0;
ssl->session.ticketLen = 0; ssl->session.ticketLen = 0;
} }
#endif #endif
@ -26787,19 +26794,19 @@ exit_scv:
int SetTicket(WOLFSSL* ssl, const byte* ticket, word32 length) int SetTicket(WOLFSSL* ssl, const byte* ticket, word32 length)
{ {
/* Free old dynamic ticket if we already had one */ /* Free old dynamic ticket if we already had one */
if (ssl->session.isDynamic) { if (ssl->session.ticketLenAlloc > 0) {
XFREE(ssl->session.ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK); XFREE(ssl->session.ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
ssl->session.ticket = ssl->session.staticTicket; ssl->session.ticket = ssl->session._staticTicket;
ssl->session.isDynamic = 0; ssl->session.ticketLenAlloc = 0;
} }
if (length > sizeof(ssl->session.staticTicket)) { if (length > sizeof(ssl->session._staticTicket)) {
byte* sessionTicket = byte* sessionTicket =
(byte*)XMALLOC(length, ssl->heap, DYNAMIC_TYPE_SESSION_TICK); (byte*)XMALLOC(length, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
if (sessionTicket == NULL) if (sessionTicket == NULL)
return MEMORY_E; return MEMORY_E;
ssl->session.ticket = sessionTicket; ssl->session.ticket = sessionTicket;
ssl->session.isDynamic = 1; ssl->session.ticketLenAlloc = (word16)length;
} }
ssl->session.ticketLen = (word16)length; ssl->session.ticketLen = (word16)length;

532
src/ssl.c
View File

@ -3176,25 +3176,28 @@ WOLFSSL_API int wolfSSL_set_SessionTicket(WOLFSSL* ssl, const byte* buf,
if (bufSz > 0) { if (bufSz > 0) {
/* Ticket will fit into static ticket */ /* Ticket will fit into static ticket */
if(bufSz <= SESSION_TICKET_LEN) { if (bufSz <= SESSION_TICKET_LEN) {
if (ssl->session.isDynamic) { if (ssl->session.ticketLenAlloc > 0) {
XFREE(ssl->session.ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK); XFREE(ssl->session.ticket, ssl->heap,
ssl->session.isDynamic = 0; DYNAMIC_TYPE_SESSION_TICK);
ssl->session.ticket = ssl->session.staticTicket; ssl->session.ticketLenAlloc = 0;
ssl->session.ticket = ssl->session._staticTicket;
} }
} else { /* Ticket requires dynamic ticket storage */ }
else { /* Ticket requires dynamic ticket storage */
if (ssl->session.ticketLen < bufSz) { /* is dyn buffer big enough */ if (ssl->session.ticketLen < bufSz) { /* is dyn buffer big enough */
if(ssl->session.isDynamic) if (ssl->session.ticketLenAlloc > 0) {
XFREE(ssl->session.ticket, ssl->heap, XFREE(ssl->session.ticket, ssl->heap,
DYNAMIC_TYPE_SESSION_TICK); DYNAMIC_TYPE_SESSION_TICK);
}
ssl->session.ticket = (byte*)XMALLOC(bufSz, ssl->heap, ssl->session.ticket = (byte*)XMALLOC(bufSz, ssl->heap,
DYNAMIC_TYPE_SESSION_TICK); DYNAMIC_TYPE_SESSION_TICK);
if(!ssl->session.ticket) { if(ssl->session.ticket == NULL) {
ssl->session.ticket = ssl->session.staticTicket; ssl->session.ticket = ssl->session._staticTicket;
ssl->session.isDynamic = 0; ssl->session.ticketLenAlloc = 0;
return MEMORY_ERROR; return MEMORY_ERROR;
} }
ssl->session.isDynamic = 1; ssl->session.ticketLenAlloc = (word16)bufSz;
} }
} }
XMEMCPY(ssl->session.ticket, buf, bufSz); XMEMCPY(ssl->session.ticket, buf, bufSz);
@ -12224,11 +12227,32 @@ WOLFSSL_SESSION* wolfSSL_get_session(WOLFSSL* ssl)
{ {
WOLFSSL_ENTER("SSL_get_session"); WOLFSSL_ENTER("SSL_get_session");
if (ssl) if (ssl)
return GetSession(ssl, 0, 1); return GetSession(ssl, NULL, 1);
return NULL; return NULL;
} }
/* The get1 version requires caller to call SSL_SESSION_free */
WOLFSSL_SESSION* wolfSSL_get1_session(WOLFSSL* ssl)
{
WOLFSSL_SESSION* sess = NULL;
if (ssl != NULL) {
sess = GetSessionRef(ssl);
if (sess != NULL) {
/* wolfSSL_get_session returns either static cache or ref. If ref then
* increase reference counter */
/* increase reference count if allocated session */
#ifdef ENABLE_CLIENT_SESSION_REF
if (sess->type == WOLFSSL_SESSION_TYPE_REF) {
sess->refCount++;
}
#endif
}
}
return sess;
}
/* /*
* Sets the session object to use when establishing a TLS/SSL session using * Sets the session object to use when establishing a TLS/SSL session using
* the ssl object. Therefore, this function must be called before * the ssl object. Therefore, this function must be called before
@ -12276,9 +12300,9 @@ int wolfSSL_SetServerID(WOLFSSL* ssl, const byte* id, int len, int newSession)
session = GetSessionClient(ssl, id, len); session = GetSessionClient(ssl, id, len);
if (session) { if (session) {
if (SetSession(ssl, session) != WOLFSSL_SUCCESS) { if (SetSession(ssl, session) != WOLFSSL_SUCCESS) {
#ifdef HAVE_EXT_CACHE #ifdef HAVE_EXT_CACHE
FreeSession(session, 0); FreeSession(session);
#endif #endif
WOLFSSL_MSG("SetSession failed"); WOLFSSL_MSG("SetSession failed");
session = NULL; session = NULL;
} }
@ -12291,10 +12315,11 @@ int wolfSSL_SetServerID(WOLFSSL* ssl, const byte* id, int len, int newSession)
ssl->session.idLen = (word16)min(SERVER_ID_LEN, (word32)len); ssl->session.idLen = (word16)min(SERVER_ID_LEN, (word32)len);
XMEMCPY(ssl->session.serverID, id, ssl->session.idLen); XMEMCPY(ssl->session.serverID, id, ssl->session.idLen);
} }
#ifdef HAVE_EXT_CACHE #ifdef HAVE_EXT_CACHE
else else {
FreeSession(session, 0); FreeSession(session);
#endif }
#endif
return WOLFSSL_SUCCESS; return WOLFSSL_SUCCESS;
} }
@ -14898,8 +14923,17 @@ int wolfSSL_Cleanup(void)
} }
#ifndef NO_SESSION_CACHE static WC_INLINE WOLFSSL_SESSION* GetSessionPtr(const WOLFSSL_SESSION* s)
{
#ifdef ENABLE_CLIENT_SESSION_REF
if (s && s->type == WOLFSSL_SESSION_TYPE_REF) {
s = (const WOLFSSL_SESSION*)s->refPtr;
}
#endif
return (WOLFSSL_SESSION*)s;
}
#ifndef NO_SESSION_CACHE
/* some session IDs aren't random after all, let's make them random */ /* some session IDs aren't random after all, let's make them random */
static WC_INLINE word32 HashSession(const byte* sessionID, word32 len, int* error) static WC_INLINE word32 HashSession(const byte* sessionID, word32 len, int* error)
@ -15154,7 +15188,7 @@ static int SslSessionCacheOff(const WOLFSSL* ssl, const WOLFSSL_SESSION* session
WOLFSSL_SESSION* GetSession(WOLFSSL* ssl, byte* masterSecret, WOLFSSL_SESSION* GetSession(WOLFSSL* ssl, byte* masterSecret,
byte restoreSessionCerts) byte restoreSessionCerts)
{ {
WOLFSSL_SESSION* ret = 0; WOLFSSL_SESSION* ret = NULL;
const byte* id = NULL; const byte* id = NULL;
word32 row; word32 row;
int idx; int idx;
@ -15162,7 +15196,7 @@ WOLFSSL_SESSION* GetSession(WOLFSSL* ssl, byte* masterSecret,
int error = 0; int error = 0;
SessionRow* sessRow; SessionRow* sessRow;
(void) restoreSessionCerts; (void)restoreSessionCerts;
if (SslSessionCacheOff(ssl, &ssl->session)) if (SslSessionCacheOff(ssl, &ssl->session))
return NULL; return NULL;
@ -15243,140 +15277,178 @@ WOLFSSL_SESSION* GetSession(WOLFSSL* ssl, byte* masterSecret,
return ret; return ret;
} }
int SetSession(WOLFSSL* ssl, WOLFSSL_SESSION* session)
static int GetDeepCopySession(WOLFSSL* ssl, WOLFSSL_SESSION* copyFrom)
{ {
int ret = WOLFSSL_SUCCESS; int ret = WOLFSSL_SUCCESS, row = -1;
WOLFSSL_SESSION* copyInto = &ssl->session;
int lockedRow;
#ifdef HAVE_SESSION_TICKET #ifdef HAVE_SESSION_TICKET
int ticLen = 0; int ticLenAlloc;
void* ticBuff = NULL; byte *ticBuff = NULL;
int isDynamic = 0; #endif
#ifdef ENABLE_CLIENT_SESSION_REF
WOLFSSL_SESSION* ref = NULL;
#endif #endif
if (ssl == NULL || copyFrom == NULL) { if (ssl == NULL || session == NULL || SslSessionCacheOff(ssl, session)) {
return WOLFSSL_FAILURE;
}
row = session->cacheRow;
#ifdef ENABLE_CLIENT_SESSION_REF
if (session->type == WOLFSSL_SESSION_TYPE_REF) {
if (session->refPtr == NULL) {
WOLFSSL_MSG("Invalid session reference");
ret = WOLFSSL_FAILURE;
}
if (ret == WOLFSSL_SUCCESS) {
int error = 0;
ref = session; /* keep copy of ref for later */
session = (WOLFSSL_SESSION*)session->refPtr;
row = HashSession(ref->sessionID, ID_LEN, &error) % SESSION_ROWS;
if (error != 0) {
WOLFSSL_MSG("Hash session failed");
ret = WOLFSSL_FAILURE;
}
}
}
#endif
if (row < 0 || row >= SESSION_ROWS) {
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
} }
lockedRow = copyFrom->cacheRow; /* lock session cache row */
if (lockedRow >= SESSION_ROWS) { if (SESSION_ROW_LOCK(&SessionCache[row]) != 0) {
return BAD_FUNC_ARG;
}
if (lockedRow >= 0 && SESSION_ROW_LOCK(&SessionCache[lockedRow]) != 0) {
return BAD_MUTEX_E; return BAD_MUTEX_E;
} }
#ifdef HAVE_SESSION_TICKET #ifdef ENABLE_CLIENT_SESSION_REF
/* Free old dynamic ticket if we had one to avoid leak */ /* verify if ID matches session cache entry */
if (copyInto->isDynamic) { if (ref != NULL &&
XFREE(copyInto->ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK); XMEMCMP(ref->sessionID, session->sessionID, ID_LEN) != 0) {
copyInto->ticket = copyInto->staticTicket; WOLFSSL_MSG("Session cache reference not longer valid");
copyInto->isDynamic = 0; ret = WOLFSSL_FAILURE;
} }
#endif #endif
#ifdef HAVE_SESSION_TICKET #ifdef HAVE_SESSION_TICKET
/* Size of ticket to alloc if needed; Use later for alloc outside lock */ /* cache the old dynamic buffer and try to reuse or free later */
isDynamic = copyFrom->isDynamic; ticLenAlloc = ssl->session.ticketLenAlloc;
ticLen = copyFrom->ticketLen; if (ticLenAlloc > 0) {
ticBuff = ssl->session.ticket;
}
#endif #endif
/* copy ticket structure */ /* copy session structure */
XMEMCPY(copyInto, copyFrom, sizeof(WOLFSSL_SESSION)); XMEMCPY(&ssl->session, session, sizeof(WOLFSSL_SESSION));
ssl->session.type = WOLFSSL_SESSION_TYPE_SSL;
if (lockedRow >= 0) { ssl->session.masterSecret = ssl->session._masterSecret;
SESSION_ROW_UNLOCK(&SessionCache[lockedRow]); #ifndef NO_CLIENT_CACHE
} ssl->session.serverID = ssl->session._serverID;
#endif
#ifdef OPENSSL_EXTRA
ssl->session.sessionCtx = ssl->session._sessionCtx;
#endif
#ifdef HAVE_SESSION_TICKET #ifdef HAVE_SESSION_TICKET
/* Default ticket to non dynamic. This will avoid crash if we fail below */ /* try and use existing buffer */
copyInto->ticket = copyInto->staticTicket; if (ssl->session.ticketLenAlloc > 0 && ticBuff != NULL &&
copyInto->isDynamic = 0; ticLenAlloc >= ssl->session.ticketLen) {
XMEMCPY(ticBuff, session->ticket, ssl->session.ticketLen);
ssl->session.ticket = ticBuff;
ssl->session.ticketLenAlloc = ticLenAlloc;
ticBuff = NULL; /* don't free later after unlock */
}
else {
/* Default ticket to non dynamic */
ssl->session.ticket = ssl->session._staticTicket;
ssl->session.ticketLenAlloc = 0;
}
#endif
/* If doing dynamic copy, need to alloc outside lock, then inside a lock SESSION_ROW_UNLOCK(&SessionCache[row]);
* confirm the size still matches and memcpy */
if (isDynamic) { #ifdef HAVE_SESSION_TICKET
ticBuff = (byte*)XMALLOC(ticLen, ssl->heap, if (ret == WOLFSSL_SUCCESS) {
DYNAMIC_TYPE_SESSION_TICK); if (ticBuff != NULL) {
if (ticBuff == NULL) { /* free old ticket buffer */
XFREE(ticBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
}
/* allocate new one */
ticBuff = (byte*)XMALLOC(ssl->session.ticketLen, ssl->heap,
DYNAMIC_TYPE_SESSION_TICK);
if (ticBuff != NULL) {
XMEMSET(ticBuff, 0, ssl->session.ticketLen);
ssl->session.ticketLenAlloc = (word16)ssl->session.ticketLen;
ssl->session.ticket = ticBuff;
}
else {
ret = MEMORY_ERROR; ret = MEMORY_ERROR;
} }
if (ret == WOLFSSL_SUCCESS && lockedRow >= 0 && if (ret == WOLFSSL_SUCCESS && SESSION_ROW_LOCK(&SessionCache[row]) != 0) {
SESSION_ROW_LOCK(&SessionCache[lockedRow]) != 0) {
ret = BAD_MUTEX_E; ret = BAD_MUTEX_E;
} }
if (ret == WOLFSSL_SUCCESS && (word16)ticLen != copyFrom->ticketLen) { if (ret == WOLFSSL_SUCCESS && session->ticketLen != ssl->session.ticketLen) {
/* Another thread modified the ssl-> session ticket during alloc. /* Another thread modified the ssl->session ticket during alloc.
* Treat as error, since ticket different than when copy requested */ * Treat as error, since ticket different than when copy requested */
ret = VAR_STATE_CHANGE_E; ret = VAR_STATE_CHANGE_E;
} }
if (ret == WOLFSSL_SUCCESS) { if (ret == WOLFSSL_SUCCESS) {
copyInto->ticket = (byte*)ticBuff; XMEMCPY(ssl->session.ticket, session->ticket, ssl->session.ticketLen);
copyInto->isDynamic = 1;
XMEMCPY(copyInto->ticket, copyFrom->ticket, ticLen);
} }
if (ret != BAD_MUTEX_E && lockedRow >= 0) { if (ret != BAD_MUTEX_E) {
SESSION_ROW_UNLOCK(&SessionCache[lockedRow]); SESSION_ROW_UNLOCK(&SessionCache[row]);
} }
} }
#endif
if (ret != WOLFSSL_SUCCESS) { if (ret != WOLFSSL_SUCCESS) {
#ifdef HAVE_SESSION_TICKET
/* cleanup */ /* cleanup */
if (ticBuff) { if (ssl->session.ticket != ssl->session._staticTicket) {
XFREE(ticBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK); XFREE(ssl->session.ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
} }
copyInto->ticket = copyInto->staticTicket; ssl->session.ticket = ssl->session._staticTicket;
copyInto->isDynamic = 0; ssl->session.ticketLenAlloc = 0;
#endif
return ret;
} }
#endif /* HAVE_SESSION_TICKET */ session = NULL; /* invalidate the provided session, only use ssl->session */
return ret;
}
int SetSession(WOLFSSL* ssl, WOLFSSL_SESSION* session)
{
if (ssl == NULL || SslSessionCacheOff(ssl, session))
return WOLFSSL_FAILURE;
#ifdef OPENSSL_EXTRA #ifdef OPENSSL_EXTRA
/* check for application context id */ /* check for application context id */
if (ssl->sessionCtxSz > 0) { if (ssl->sessionCtxSz > 0) {
if (XMEMCMP(ssl->sessionCtx, session->sessionCtx, ssl->sessionCtxSz)) { if (XMEMCMP(ssl->sessionCtx, ssl->session.sessionCtx, ssl->sessionCtxSz)) {
/* context id did not match! */ /* context id did not match! */
WOLFSSL_MSG("Session context did not match"); WOLFSSL_MSG("Session context did not match");
return SSL_FAILURE; return WOLFSSL_FAILURE;
} }
} }
#endif /* OPENSSL_EXTRA */ #endif /* OPENSSL_EXTRA */
if (LowResTimer() < (session->bornOn + session->timeout)) { if (LowResTimer() < (ssl->session.bornOn + ssl->session.timeout)) {
int ret = GetDeepCopySession(ssl, session); ssl->options.resuming = 1;
if (ret == WOLFSSL_SUCCESS) {
ssl->options.resuming = 1;
#if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \ #if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
defined(HAVE_SESSION_TICKET)) defined(HAVE_SESSION_TICKET))
ssl->version = session->version; ssl->version = ssl->session.version;
#endif #endif
#if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \ #if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \
(defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)) (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET))
ssl->options.cipherSuite0 = session->cipherSuite0; ssl->options.cipherSuite0 = ssl->session.cipherSuite0;
ssl->options.cipherSuite = session->cipherSuite; ssl->options.cipherSuite = ssl->session.cipherSuite;
#endif #endif
} ret = WOLFSSL_SUCCESS;
return ret;
} }
else { else {
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_ERROR_CODE_OPENSSL) #if defined(OPENSSL_EXTRA) && defined(WOLFSSL_ERROR_CODE_OPENSSL)
WOLFSSL_MSG("Session is expired but return success for \ WOLFSSL_MSG("Session is expired but return success for \
OpenSSL compatibility"); OpenSSL compatibility");
return WOLFSSL_SUCCESS; ret = WOLFSSL_SUCCESS;
#else
ret = WOLFSSL_FAILURE; /* session timed out */
#endif /* OPENSSL_EXTRA && WOLFSSL_ERROR_CODE_OPENSSL */ #endif /* OPENSSL_EXTRA && WOLFSSL_ERROR_CODE_OPENSSL */
return WOLFSSL_FAILURE; /* session timed out */
} }
return ret;
} }
@ -15486,8 +15558,17 @@ int AddSession(WOLFSSL* ssl)
session = &sessRow->Sessions[idx]; session = &sessRow->Sessions[idx];
} }
session->type = WOLFSSL_SESSION_TYPE_CACHE;
session->cacheRow = row; session->cacheRow = row;
session->side = (byte)ssl->options.side; session->side = (byte)ssl->options.side;
session->heap = ssl->heap;
session->masterSecret = session->_masterSecret;
#ifndef NO_CLIENT_CACHE
session->serverID = session->_serverID;
#endif
#ifdef OPENSSL_EXTRA
session->sessionCtx = session->_sessionCtx;
#endif
#ifdef WOLFSSL_TLS13 #ifdef WOLFSSL_TLS13
if (ssl->options.tls1_3) { if (ssl->options.tls1_3) {
@ -15520,10 +15601,9 @@ int AddSession(WOLFSSL* ssl)
if ((word16)ticLen != ssl->session.ticketLen) { if ((word16)ticLen != ssl->session.ticketLen) {
error = VAR_STATE_CHANGE_E; error = VAR_STATE_CHANGE_E;
} }
if (error == 0) { if (error == 0) {
/* Cleanup cache row's old Dynamic buff if exists */ /* Cleanup cache row's old Dynamic buff if exists */
if (session->isDynamic) { if (session->ticketLenAlloc > 0) {
XFREE(session->ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK); XFREE(session->ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
session->ticket = NULL; session->ticket = NULL;
} }
@ -15531,17 +15611,19 @@ int AddSession(WOLFSSL* ssl)
/* If too large to store in static buffer, use dyn buffer */ /* If too large to store in static buffer, use dyn buffer */
if (ticLen > SESSION_TICKET_LEN) { if (ticLen > SESSION_TICKET_LEN) {
session->ticket = ticBuff; session->ticket = ticBuff;
session->isDynamic = 1; session->ticketLenAlloc = (word16)ticLen;
} else { }
session->ticket = session->staticTicket; else {
session->isDynamic = 0; session->ticket = session->_staticTicket;
session->ticketLenAlloc = 0;
} }
session->ticketLen = (word16)ticLen; session->ticketLen = (word16)ticLen;
XMEMCPY(session->ticket, ssl->session.ticket, ticLen); XMEMCPY(session->ticket, ssl->session.ticket, ticLen);
} else { /* cleanup, reset state */ }
session->ticket = session->staticTicket; else { /* cleanup, reset state */
session->isDynamic = 0; session->ticket = session->_staticTicket;
session->ticketLenAlloc = 0;
session->ticketLen = 0; session->ticketLen = 0;
if (ticBuff) { if (ticBuff) {
XFREE(ticBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK); XFREE(ticBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
@ -15665,7 +15747,7 @@ int AddSession(WOLFSSL* ssl)
cbRet = ssl->ctx->new_sess_cb(ssl, session); cbRet = ssl->ctx->new_sess_cb(ssl, session);
} }
if (ssl->options.internalCacheOff && cbRet == 0) { if (ssl->options.internalCacheOff && cbRet == 0) {
FreeSession(session, 1); FreeSession(session);
} }
#endif #endif
@ -15721,6 +15803,8 @@ WOLFSSL_X509_CHAIN* wolfSSL_SESSION_get_peer_chain(WOLFSSL_SESSION* session)
WOLFSSL_X509_CHAIN* chain = NULL; WOLFSSL_X509_CHAIN* chain = NULL;
WOLFSSL_ENTER("wolfSSL_SESSION_get_peer_chain"); WOLFSSL_ENTER("wolfSSL_SESSION_get_peer_chain");
session = GetSessionPtr(session);
if (session) if (session)
chain = &session->chain; chain = &session->chain;
@ -15735,6 +15819,8 @@ WOLFSSL_X509_CHAIN* wolfSSL_SESSION_get_peer_chain(WOLFSSL_SESSION* session)
WOLFSSL_X509* wolfSSL_SESSION_get0_peer(WOLFSSL_SESSION* session) WOLFSSL_X509* wolfSSL_SESSION_get0_peer(WOLFSSL_SESSION* session)
{ {
WOLFSSL_ENTER("wolfSSL_SESSION_get_peer_chain"); WOLFSSL_ENTER("wolfSSL_SESSION_get_peer_chain");
session = GetSessionPtr(session);
if (session) { if (session) {
int count; int count;
@ -23195,32 +23281,88 @@ int wolfSSL_session_reused(WOLFSSL* ssl)
return resuming; return resuming;
} }
WOLFSSL_SESSION* GetSessionRef(WOLFSSL* ssl)
{
WOLFSSL_SESSION* session;
#ifdef ENABLE_CLIENT_SESSION_REF
WOLFSSL_SESSION* ref = NULL;
const word32 refSize = (word32)OFFSETOF(WOLFSSL_SESSION, refPtr) +
(word32)sizeof(wc_ptr_t);
int refCount = 0;
#endif
session = GetSession(ssl, NULL, 1);
if (session == NULL) {
return session;
}
#ifdef ENABLE_CLIENT_SESSION_REF
/* if GetSessionRef has already been called then use existing pointer */
ref = (WOLFSSL_SESSION*)ssl->session.refPtr;
if (ref == NULL) {
ref = (WOLFSSL_SESSION*)XMALLOC(refSize, ssl->heap,
DYNAMIC_TYPE_SESSION);
}
else {
/* use existing ref count */
refCount = ref->refCount;
}
if (ref == NULL) {
WOLFSSL_MSG("Error allocating client session reference");
return NULL;
}
XMEMCPY(ref, session, refSize);
ref->type = WOLFSSL_SESSION_TYPE_REF;
ref->refCount = refCount;
ref->refPtr = (void*)session;
ref->heap = ssl->heap;
ssl->session.refPtr = ref;
session = ref;
#endif /* ENABLE_CLIENT_SESSION_REF */
return session;
}
#if defined(OPENSSL_EXTRA) || defined(HAVE_EXT_CACHE) #if defined(OPENSSL_EXTRA) || defined(HAVE_EXT_CACHE)
/* return a new malloc'd session with default settings on success */ /* return a new malloc'd session with default settings on success */
static WOLFSSL_SESSION* NewSession(void) WOLFSSL_SESSION* NewSession(void* heap)
{ {
WOLFSSL_SESSION* ret = NULL; WOLFSSL_SESSION* ret = NULL;
ret = (WOLFSSL_SESSION*)XMALLOC(sizeof(WOLFSSL_SESSION), NULL, ret = (WOLFSSL_SESSION*)XMALLOC(sizeof(WOLFSSL_SESSION), heap,
DYNAMIC_TYPE_OPENSSL); DYNAMIC_TYPE_SESSION);
if (ret != NULL) { if (ret != NULL) {
XMEMSET(ret, 0, sizeof(WOLFSSL_SESSION)); XMEMSET(ret, 0, sizeof(WOLFSSL_SESSION));
ret->isAlloced = 1; ret->type = WOLFSSL_SESSION_TYPE_HEAP;
ret->heap = heap;
ret->masterSecret = ret->_masterSecret;
#ifndef NO_CLIENT_CACHE
ret->serverID = ret->_serverID;
#endif
#ifdef OPENSSL_EXTRA
ret->sessionCtx = ret->_sessionCtx;
#endif
#ifdef HAVE_SESSION_TICKET
ret->ticket = ret->_staticTicket;
#endif
} }
(void)heap;
return ret; return ret;
} }
WOLFSSL_SESSION* wolfSSL_SESSION_new(void) WOLFSSL_SESSION* wolfSSL_SESSION_new_ex(void* heap)
{ {
WOLFSSL_SESSION* ret = NewSession(); WOLFSSL_SESSION* ret = NewSession(heap);
#ifdef OPENSSL_EXTRA #ifdef OPENSSL_EXTRA
if (ret != NULL) { if (ret != NULL) {
#ifndef SINGLE_THREADED #ifndef SINGLE_THREADED
if (wc_InitMutex(&ret->refMutex) != 0) { if (wc_InitMutex(&ret->refMutex) != 0) {
WOLFSSL_MSG("Error setting up session reference mutex"); WOLFSSL_MSG("Error setting up session reference mutex");
XFREE(ret, NULL, DYNAMIC_TYPE_OPENSSL); XFREE(ret, ret->heap, DYNAMIC_TYPE_SESSION);
return NULL; return NULL;
} }
#endif #endif
@ -23230,11 +23372,16 @@ WOLFSSL_SESSION* wolfSSL_SESSION_new(void)
return ret; return ret;
} }
WOLFSSL_SESSION* wolfSSL_SESSION_new(void)
{
return wolfSSL_SESSION_new_ex(NULL);
}
/* add one to session reference count /* add one to session reference count
* return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on error */ * return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on error */
int wolfSSL_SESSION_up_ref(WOLFSSL_SESSION* session) int wolfSSL_SESSION_up_ref(WOLFSSL_SESSION* session)
{ {
session = GetSessionPtr(session);
if (session == NULL) if (session == NULL)
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
@ -23260,37 +23407,46 @@ WOLFSSL_SESSION* wolfSSL_SESSION_dup(WOLFSSL_SESSION* session)
WOLFSSL_ENTER("wolfSSL_SESSION_dup"); WOLFSSL_ENTER("wolfSSL_SESSION_dup");
session = GetSessionPtr(session);
if (session == NULL) if (session == NULL)
return NULL; return NULL;
#ifdef HAVE_SESSION_TICKET #ifdef HAVE_SESSION_TICKET
if (session->isDynamic && !session->ticket) { if (session->ticketLenAlloc > 0 && !session->ticket) {
WOLFSSL_MSG("Session dynamic flag is set but ticket pointer is null"); WOLFSSL_MSG("Session dynamic flag is set but ticket pointer is null");
return NULL; return NULL;
} }
#endif #endif
copy = NewSession(); copy = NewSession(session->heap);
if (copy != NULL) { if (copy != NULL) {
XMEMCPY(copy, session, sizeof(WOLFSSL_SESSION)); XMEMCPY(copy, session, sizeof(WOLFSSL_SESSION));
copy->isAlloced = 1; copy->type = WOLFSSL_SESSION_TYPE_HEAP;
copy->cacheRow = -1; /* not in cache */ copy->cacheRow = -1; /* not in cache */
copy->masterSecret = copy->_masterSecret;
#ifndef NO_CLIENT_CACHE
copy->serverID = copy->_serverID;
#endif
#ifdef OPENSSL_EXTRA
copy->sessionCtx = copy->_sessionCtx;
#endif
#ifdef OPENSSL_EXTRA #ifdef OPENSSL_EXTRA
#ifndef SINGLE_THREADED #ifndef SINGLE_THREADED
if (wc_InitMutex(&copy->refMutex) != 0) { if (wc_InitMutex(&copy->refMutex) != 0) {
WOLFSSL_MSG("Error setting up session reference mutex"); WOLFSSL_MSG("Error setting up session reference mutex");
XFREE(copy, NULL, DYNAMIC_TYPE_OPENSSL); XFREE(copy, copy->heap, DYNAMIC_TYPE_SESSION);
return NULL; return NULL;
} }
#endif #endif
copy->refCount = 1; copy->refCount = 1;
#endif #endif
#ifdef HAVE_SESSION_TICKET #ifdef HAVE_SESSION_TICKET
if (session->isDynamic) { if (session->ticketLenAlloc > 0) {
copy->ticket = (byte*)XMALLOC(session->ticketLen, NULL, copy->ticket = (byte*)XMALLOC(session->ticketLen, copy->heap,
DYNAMIC_TYPE_SESSION_TICK); DYNAMIC_TYPE_SESSION_TICK);
XMEMCPY(copy->ticket, session->ticket, session->ticketLen); XMEMCPY(copy->ticket, session->ticket, session->ticketLen);
} else { } else {
copy->ticket = copy->staticTicket; copy->ticket = copy->_staticTicket;
} }
#endif #endif
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA) #if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
@ -23299,18 +23455,32 @@ WOLFSSL_SESSION* wolfSSL_SESSION_dup(WOLFSSL_SESSION* session)
} }
return copy; return copy;
#else #else
WOLFSSL_MSG("wolfSSL_SESSION_dup was called " WOLFSSL_MSG("wolfSSL_SESSION_dup feature not compiled in");
"but HAVE_EXT_CACHE is not defined");
(void)session; (void)session;
return NULL; return NULL;
#endif /* HAVE_EXT_CACHE */ #endif /* HAVE_EXT_CACHE */
} }
void FreeSession(WOLFSSL_SESSION* session, int isAlloced) #endif /* OPENSSL_EXTRA || HAVE_EXT_CACHE */
void FreeSession(WOLFSSL_SESSION* session)
{ {
if (session == NULL) if (session == NULL)
return; return;
#ifdef ENABLE_CLIENT_SESSION_REF
if (session->type == WOLFSSL_SESSION_TYPE_REF) {
WOLFSSL_SESSION* ref;
session->refCount--;
if (session->refCount > 0) {
return; /* don't free yet */
}
ref = session;
session = (WOLFSSL_SESSION*)session->refPtr;
XFREE(ref, ref->heap, DYNAMIC_TYPE_SESSION);
}
#endif
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS #ifdef HAVE_EX_DATA_CLEANUP_HOOKS
wolfSSL_CRYPTO_cleanup_ex_data(&session->ex_data); wolfSSL_CRYPTO_cleanup_ex_data(&session->ex_data);
#endif #endif
@ -23343,32 +23513,25 @@ void FreeSession(WOLFSSL_SESSION* session, int isAlloced)
#endif #endif
} }
#endif #endif
#if defined(HAVE_EXT_CACHE) || defined(OPENSSL_EXTRA)
if (isAlloced) { #ifdef HAVE_SESSION_TICKET
#ifdef HAVE_SESSION_TICKET if (session->ticketLenAlloc > 0) {
if (session->isDynamic) XFREE(session->ticket, heap, DYNAMIC_TYPE_SESSION_TICK);
XFREE(session->ticket, NULL, DYNAMIC_TYPE_SESSION_TICK);
#endif
XFREE(session, NULL, DYNAMIC_TYPE_OPENSSL);
} }
#else
/* No need to free since cache is static */
(void)session;
(void)isAlloced;
#endif #endif
if (session->type == WOLFSSL_SESSION_TYPE_HEAP) {
XFREE(session, session->heap, DYNAMIC_TYPE_SESSION);
}
} }
void wolfSSL_SESSION_free(WOLFSSL_SESSION* session) void wolfSSL_SESSION_free(WOLFSSL_SESSION* session)
{ {
if (session == NULL) FreeSession(session);
return;
#if defined(HAVE_EXT_CACHE) || defined(OPENSSL_EXTRA)
FreeSession(session, session->isAlloced);
#else
FreeSession(session, 0);
#endif
} }
#if defined(OPENSSL_EXTRA) || defined(HAVE_EXT_CACHE)
/** /**
* set cipher to WOLFSSL_SESSION from WOLFSSL_CIPHER * set cipher to WOLFSSL_SESSION from WOLFSSL_CIPHER
* @param session a pointer to WOLFSSL_SESSION structure * @param session a pointer to WOLFSSL_SESSION structure
@ -23381,6 +23544,7 @@ int wolfSSL_SESSION_set_cipher(WOLFSSL_SESSION* session,
WOLFSSL_ENTER("wolfSSL_SESSION_set_cipher"); WOLFSSL_ENTER("wolfSSL_SESSION_set_cipher");
/* sanity check */ /* sanity check */
session = GetSessionPtr(session);
if (session == NULL || cipher == NULL) { if (session == NULL || cipher == NULL) {
WOLFSSL_MSG("bad argument"); WOLFSSL_MSG("bad argument");
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
@ -23529,6 +23693,7 @@ const char* wolfSSL_CIPHER_get_version(const WOLFSSL_CIPHER* cipher)
const char* wolfSSL_SESSION_CIPHER_get_name(WOLFSSL_SESSION* session) const char* wolfSSL_SESSION_CIPHER_get_name(WOLFSSL_SESSION* session)
{ {
session = GetSessionPtr(session);
if (session == NULL) { if (session == NULL) {
return NULL; return NULL;
} }
@ -26023,31 +26188,6 @@ char* wolfSSL_CIPHER_description(const WOLFSSL_CIPHER* cipher, char* in,
return ret; return ret;
} }
#ifndef NO_SESSION_CACHE
WOLFSSL_SESSION* wolfSSL_get1_session(WOLFSSL* ssl)
{
if (ssl == NULL) {
return NULL;
}
/* sessions are stored statically, no need for reference count */
return wolfSSL_get_session(ssl);
}
#endif /* NO_SESSION_CACHE */
/* was do nothing */
/*
void OPENSSL_free(void* buf)
{
(void)buf;
}
*/
#ifndef NO_WOLFSSL_STUB #ifndef NO_WOLFSSL_STUB
int wolfSSL_OCSP_parse_url(char* url, char** host, char** port, char** path, int wolfSSL_OCSP_parse_url(char* url, char** host, char** port, char** path,
int* ssl) int* ssl)
@ -31266,7 +31406,6 @@ void wolfSSL_sk_pop_free(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk,
WOLFSSL_ENTER("wolfSSL_sk_pop_free"); WOLFSSL_ENTER("wolfSSL_sk_pop_free");
if (sk == NULL) { if (sk == NULL) {
WOLFSSL_MSG("Error, BAD_FUNC_ARG");
return; return;
} }
#if defined(WOLFSSL_QT) #if defined(WOLFSSL_QT)
@ -31523,6 +31662,7 @@ int wolfSSL_i2d_SSL_SESSION(WOLFSSL_SESSION* sess, unsigned char** p)
#endif #endif
unsigned char *data; unsigned char *data;
sess = GetSessionPtr(sess);
if (sess == NULL) { if (sess == NULL) {
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
} }
@ -31683,14 +31823,15 @@ WOLFSSL_SESSION* wolfSSL_d2i_SSL_SESSION(WOLFSSL_SESSION** sess,
int j; int j;
word16 length; word16 length;
#endif #endif
#endif #endif /* HAVE_EXT_CACHE */
(void)p; (void)p;
(void)i; (void)i;
(void)ret; (void)ret;
if (sess != NULL) if (sess != NULL) {
s = *sess; s = GetSessionPtr(*sess);
}
#ifdef HAVE_EXT_CACHE #ifdef HAVE_EXT_CACHE
if (p == NULL || *p == NULL) if (p == NULL || *p == NULL)
@ -31701,7 +31842,7 @@ WOLFSSL_SESSION* wolfSSL_d2i_SSL_SESSION(WOLFSSL_SESSION** sess,
if (s == NULL) if (s == NULL)
return NULL; return NULL;
#ifdef HAVE_SESSION_TICKET #ifdef HAVE_SESSION_TICKET
s->isDynamic = 0; s->ticketLenAlloc = 0;
#endif #endif
} }
@ -31857,10 +31998,11 @@ WOLFSSL_SESSION* wolfSSL_d2i_SSL_SESSION(WOLFSSL_SESSION** sess,
ato16(data + idx, &s->ticketLen); idx += OPAQUE16_LEN; ato16(data + idx, &s->ticketLen); idx += OPAQUE16_LEN;
/* Dispose of ol dynamic ticket and ensure space for new ticket. */ /* Dispose of ol dynamic ticket and ensure space for new ticket. */
if (s->isDynamic) if (s->ticketLenAlloc > 0) {
XFREE(s->ticket, NULL, DYNAMIC_TYPE_SESSION_TICK); XFREE(s->ticket, NULL, DYNAMIC_TYPE_SESSION_TICK);
}
if (s->ticketLen <= SESSION_TICKET_LEN) if (s->ticketLen <= SESSION_TICKET_LEN)
s->ticket = s->staticTicket; s->ticket = s->_staticTicket;
else { else {
s->ticket = (byte*)XMALLOC(s->ticketLen, NULL, s->ticket = (byte*)XMALLOC(s->ticketLen, NULL,
DYNAMIC_TYPE_SESSION_TICK); DYNAMIC_TYPE_SESSION_TICK);
@ -31868,7 +32010,7 @@ WOLFSSL_SESSION* wolfSSL_d2i_SSL_SESSION(WOLFSSL_SESSION** sess,
ret = MEMORY_ERROR; ret = MEMORY_ERROR;
goto end; goto end;
} }
s->isDynamic = 1; s->ticketLenAlloc = (word16)s->ticketLen;
} }
/* ticket */ /* ticket */
@ -31890,7 +32032,7 @@ end:
wolfSSL_SESSION_free(s); wolfSSL_SESSION_free(s);
s = NULL; s = NULL;
} }
#endif #endif /* HAVE_EXT_CACHE */
return s; return s;
} }
@ -31902,14 +32044,13 @@ end:
int wolfSSL_SESSION_has_ticket(const WOLFSSL_SESSION* sess) int wolfSSL_SESSION_has_ticket(const WOLFSSL_SESSION* sess)
{ {
WOLFSSL_ENTER("wolfSSL_SESSION_has_ticket"); WOLFSSL_ENTER("wolfSSL_SESSION_has_ticket");
sess = GetSessionPtr(sess);
#ifdef HAVE_SESSION_TICKET #ifdef HAVE_SESSION_TICKET
if (sess) { if (sess) {
if ((sess->ticketLen > 0) && (sess->ticket != NULL)) { if ((sess->ticketLen > 0) && (sess->ticket != NULL)) {
return WOLFSSL_SUCCESS; return WOLFSSL_SUCCESS;
} }
} }
#else
(void)sess;
#endif #endif
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
} }
@ -31918,6 +32059,7 @@ unsigned long wolfSSL_SESSION_get_ticket_lifetime_hint(
const WOLFSSL_SESSION* sess) const WOLFSSL_SESSION* sess)
{ {
WOLFSSL_ENTER("wolfSSL_SESSION_get_ticket_lifetime_hint"); WOLFSSL_ENTER("wolfSSL_SESSION_get_ticket_lifetime_hint");
sess = GetSessionPtr(sess);
if (sess) { if (sess) {
return sess->timeout; return sess->timeout;
} }
@ -31928,6 +32070,7 @@ long wolfSSL_SESSION_get_timeout(const WOLFSSL_SESSION* sess)
{ {
long timeout = 0; long timeout = 0;
WOLFSSL_ENTER("wolfSSL_SESSION_get_timeout"); WOLFSSL_ENTER("wolfSSL_SESSION_get_timeout");
sess = GetSessionPtr(sess);
if (sess) if (sess)
timeout = sess->timeout; timeout = sess->timeout;
return timeout; return timeout;
@ -31938,6 +32081,7 @@ long wolfSSL_SESSION_get_time(const WOLFSSL_SESSION* sess)
{ {
long bornOn = 0; long bornOn = 0;
WOLFSSL_ENTER("wolfSSL_SESSION_get_time"); WOLFSSL_ENTER("wolfSSL_SESSION_get_time");
sess = GetSessionPtr(sess);
if (sess) if (sess)
bornOn = sess->bornOn; bornOn = sess->bornOn;
return bornOn; return bornOn;
@ -31946,11 +32090,13 @@ long wolfSSL_SESSION_get_time(const WOLFSSL_SESSION* sess)
long wolfSSL_SSL_SESSION_set_timeout(WOLFSSL_SESSION* ses, long t) long wolfSSL_SSL_SESSION_set_timeout(WOLFSSL_SESSION* ses, long t)
{ {
word32 tmptime; word32 tmptime;
if (!ses || t < 0)
ses = GetSessionPtr(ses);
if (ses == NULL || t < 0) {
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
}
tmptime = t & 0xFFFFFFFF; tmptime = t & 0xFFFFFFFF;
ses->timeout = tmptime; ses->timeout = tmptime;
return WOLFSSL_SUCCESS; return WOLFSSL_SUCCESS;
@ -47512,7 +47658,8 @@ int wolfSSL_SESSION_set_ex_data(WOLFSSL_SESSION* session, int idx, void* data)
{ {
WOLFSSL_ENTER("wolfSSL_SESSION_set_ex_data"); WOLFSSL_ENTER("wolfSSL_SESSION_set_ex_data");
#ifdef HAVE_EX_DATA #ifdef HAVE_EX_DATA
if(session != NULL) { session = GetSessionPtr(session);
if (session != NULL) {
return wolfSSL_CRYPTO_set_ex_data(&session->ex_data, idx, data); return wolfSSL_CRYPTO_set_ex_data(&session->ex_data, idx, data);
} }
#else #else
@ -48486,7 +48633,8 @@ WOLFSSL_CTX* wolfSSL_get_SSL_CTX(WOLFSSL* ssl)
const byte* wolfSSL_SESSION_get_id(WOLFSSL_SESSION* sess, unsigned int* idLen) const byte* wolfSSL_SESSION_get_id(WOLFSSL_SESSION* sess, unsigned int* idLen)
{ {
WOLFSSL_ENTER("wolfSSL_SESSION_get_id"); WOLFSSL_ENTER("wolfSSL_SESSION_get_id");
if(!sess || !idLen) { sess = GetSessionPtr(sess);
if (sess == NULL || idLen == NULL) {
WOLFSSL_MSG("Bad func args. Please provide idLen"); WOLFSSL_MSG("Bad func args. Please provide idLen");
return NULL; return NULL;
} }
@ -48598,10 +48746,9 @@ int wolfSSL_SESSION_print(WOLFSSL_BIO *bp, const WOLFSSL_SESSION *x)
unsigned char buf[SECRET_LEN]; unsigned char buf[SECRET_LEN];
unsigned int sz = 0, i; unsigned int sz = 0, i;
int ret; int ret;
WOLFSSL_SESSION* session = (WOLFSSL_SESSION*)x; WOLFSSL_SESSION* session = GetSessionPtr(x);
if (session == NULL) { if (session == NULL) {
WOLFSSL_MSG("Bad NULL argument");
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
} }
@ -48633,7 +48780,7 @@ int wolfSSL_SESSION_print(WOLFSSL_BIO *bp, const WOLFSSL_SESSION *x)
if (wolfSSL_BIO_printf(bp, " Session-ID-ctx: \n") <= 0) if (wolfSSL_BIO_printf(bp, " Session-ID-ctx: \n") <= 0)
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
ret = wolfSSL_SESSION_get_master_key(x, buf, sizeof(buf)); ret = wolfSSL_SESSION_get_master_key(session, buf, sizeof(buf));
if (wolfSSL_BIO_printf(bp, " Master-Key: ") <= 0) if (wolfSSL_BIO_printf(bp, " Master-Key: ") <= 0)
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
@ -48653,18 +48800,18 @@ int wolfSSL_SESSION_print(WOLFSSL_BIO *bp, const WOLFSSL_SESSION *x)
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
#ifdef HAVE_SESSION_TICKET #ifdef HAVE_SESSION_TICKET
if (wolfSSL_SESSION_print_ticket(bp, x, " ") != WOLFSSL_SUCCESS) if (wolfSSL_SESSION_print_ticket(bp, session, " ") != WOLFSSL_SUCCESS)
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
#endif #endif
#if !defined(NO_SESSION_CACHE) && (defined(OPENSSL_EXTRA) || \ #if !defined(NO_SESSION_CACHE) && (defined(OPENSSL_EXTRA) || \
defined(HAVE_EXT_CACHE)) defined(HAVE_EXT_CACHE))
if (wolfSSL_BIO_printf(bp, " Start Time: %ld\n", if (wolfSSL_BIO_printf(bp, " Start Time: %ld\n",
wolfSSL_SESSION_get_time(x)) <= 0) wolfSSL_SESSION_get_time(session)) <= 0)
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
if (wolfSSL_BIO_printf(bp, " Timeout : %ld (sec)\n", if (wolfSSL_BIO_printf(bp, " Timeout : %ld (sec)\n",
wolfSSL_SESSION_get_timeout(x)) <= 0) wolfSSL_SESSION_get_timeout(session)) <= 0)
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
#endif /* !NO_SESSION_CACHE && OPENSSL_EXTRA || HAVE_EXT_CACHE */ #endif /* !NO_SESSION_CACHE && OPENSSL_EXTRA || HAVE_EXT_CACHE */
@ -56461,13 +56608,14 @@ int wolfSSL_CTX_get_security_level(const WOLFSSL_CTX* ctx)
*/ */
int wolfSSL_SESSION_is_resumable(const WOLFSSL_SESSION *s) int wolfSSL_SESSION_is_resumable(const WOLFSSL_SESSION *s)
{ {
s = GetSessionPtr(s);
if (s == NULL) if (s == NULL)
return 0; return 0;
#ifdef HAVE_SESSION_TICKET #ifdef HAVE_SESSION_TICKET
if (s->ticketLen > 0) if (s->ticketLen > 0)
return 1; return 1;
#endif #endif
if (s->sessionIDSz > 0) if (s->sessionIDSz > 0)
return 1; return 1;

View File

@ -39177,20 +39177,21 @@ static void test_wolfSSL_cert_cb(void)
static void test_wolfSSL_SESSION(void) static void test_wolfSSL_SESSION(void)
{ {
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \ #if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \
!defined(NO_RSA) && defined(HAVE_EXT_CACHE) && \ !defined(NO_RSA) && defined(HAVE_IO_TESTS_DEPENDENCIES) && \
defined(HAVE_IO_TESTS_DEPENDENCIES) && !defined(NO_SESSION_CACHE) !defined(NO_SESSION_CACHE)
WOLFSSL* ssl; WOLFSSL* ssl;
WOLFSSL_CTX* ctx; WOLFSSL_CTX* ctx;
WOLFSSL_SESSION* sess; WOLFSSL_SESSION* sess;
WOLFSSL_SESSION* sess_copy; WOLFSSL_SESSION* sess_copy;
#ifdef OPENSSL_EXTRA
unsigned char* sessDer = NULL; unsigned char* sessDer = NULL;
unsigned char* ptr = NULL; unsigned char* ptr = NULL;
#ifdef OPENSSL_EXTRA
const unsigned char context[] = "user app context"; const unsigned char context[] = "user app context";
unsigned int contextSz = (unsigned int)sizeof(context); unsigned int contextSz = (unsigned int)sizeof(context);
int sz;
#endif #endif
int ret, err, sockfd, sz; int ret, err, sockfd;
tcp_ready ready; tcp_ready ready;
func_args server_args; func_args server_args;
THREAD_TYPE serverThread; THREAD_TYPE serverThread;
@ -39208,9 +39209,12 @@ static void test_wolfSSL_SESSION(void)
AssertNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method())); AssertNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#endif #endif
AssertTrue(wolfSSL_CTX_use_certificate_file(ctx, cliCertFile, SSL_FILETYPE_PEM)); AssertTrue(wolfSSL_CTX_use_certificate_file(ctx, cliCertFile,
AssertTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, cliKeyFile, SSL_FILETYPE_PEM)); WOLFSSL_FILETYPE_PEM));
AssertIntEQ(wolfSSL_CTX_load_verify_locations(ctx, caCertFile, 0), SSL_SUCCESS); AssertTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, cliKeyFile,
WOLFSSL_FILETYPE_PEM));
AssertIntEQ(wolfSSL_CTX_load_verify_locations(ctx, caCertFile, 0),
WOLFSSL_SUCCESS);
#ifdef WOLFSSL_ENCRYPTED_KEYS #ifdef WOLFSSL_ENCRYPTED_KEYS
wolfSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack); wolfSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif #endif
@ -39239,7 +39243,7 @@ static void test_wolfSSL_SESSION(void)
/* client connection */ /* client connection */
ssl = wolfSSL_new(ctx); ssl = wolfSSL_new(ctx);
tcp_connect(&sockfd, wolfSSLIP, ready.port, 0, 0, ssl); tcp_connect(&sockfd, wolfSSLIP, ready.port, 0, 0, ssl);
AssertIntEQ(wolfSSL_set_fd(ssl, sockfd), SSL_SUCCESS); AssertIntEQ(wolfSSL_set_fd(ssl, sockfd), WOLFSSL_SUCCESS);
#ifdef WOLFSSL_ASYNC_CRYPT #ifdef WOLFSSL_ASYNC_CRYPT
err = 0; /* Reset error */ err = 0; /* Reset error */
@ -39286,15 +39290,17 @@ static void test_wolfSSL_SESSION(void)
} while (err == WC_PENDING_E); } while (err == WC_PENDING_E);
AssertIntEQ(ret, 23); AssertIntEQ(ret, 23);
AssertPtrNE((sess = wolfSSL_get1_session(ssl)), NULL); /* ref count 1 */
AssertPtrNE((sess_copy = wolfSSL_get1_session(ssl)), NULL); /* ref count 2 */
AssertPtrEq(sess, sess_copy); /* they should be the same pointer */
wolfSSL_SESSION_free(sess_copy); sess_copy = NULL;
wolfSSL_SESSION_free(sess); sess = NULL; /* free session ref */
sess = wolfSSL_get_session(ssl); sess = wolfSSL_get_session(ssl);
#if defined(OPENSSL_EXTRA) #ifdef OPENSSL_EXTRA
AssertIntEQ(SSL_SESSION_is_resumable(NULL), 0); AssertIntEQ(SSL_SESSION_is_resumable(NULL), 0);
AssertIntEQ(SSL_SESSION_is_resumable(sess), 1); AssertIntEQ(SSL_SESSION_is_resumable(sess), 1);
#else
AssertIntEQ(wolfSSL_SESSION_is_resumable(NULL), 0);
AssertIntEQ(wolfSSL_SESSION_is_resumable(sess), 1);
#endif
AssertIntEQ(wolfSSL_SESSION_has_ticket(NULL), 0); AssertIntEQ(wolfSSL_SESSION_has_ticket(NULL), 0);
AssertIntEQ(wolfSSL_SESSION_get_ticket_lifetime_hint(NULL), 0); AssertIntEQ(wolfSSL_SESSION_get_ticket_lifetime_hint(NULL), 0);
@ -39305,6 +39311,7 @@ static void test_wolfSSL_SESSION(void)
#else #else
AssertIntEQ(wolfSSL_SESSION_has_ticket(sess), 0); AssertIntEQ(wolfSSL_SESSION_has_ticket(sess), 0);
#endif #endif
#endif /* OPENSSL_EXTRA */
wolfSSL_shutdown(ssl); wolfSSL_shutdown(ssl);
wolfSSL_free(ssl); wolfSSL_free(ssl);
@ -39337,24 +39344,32 @@ static void test_wolfSSL_SESSION(void)
} }
#endif #endif
#ifdef HAVE_EXT_CACHE
AssertNotNull(sess_copy = wolfSSL_SESSION_dup(sess)); AssertNotNull(sess_copy = wolfSSL_SESSION_dup(sess));
wolfSSL_SESSION_free(sess_copy); wolfSSL_SESSION_free(sess_copy);
sess_copy = NULL;
#endif
#ifdef OPENSSL_EXTRA
/* get session from DER and update the timeout */ /* get session from DER and update the timeout */
AssertIntEQ(wolfSSL_i2d_SSL_SESSION(NULL, &sessDer), BAD_FUNC_ARG); AssertIntEQ(wolfSSL_i2d_SSL_SESSION(NULL, &sessDer), BAD_FUNC_ARG);
AssertIntGT((sz = wolfSSL_i2d_SSL_SESSION(sess, &sessDer)), 0); AssertIntGT((sz = wolfSSL_i2d_SSL_SESSION(sess, &sessDer)), 0);
wolfSSL_SESSION_free(sess); wolfSSL_SESSION_free(sess);
sess = NULL;
ptr = sessDer; ptr = sessDer;
AssertNull(sess = wolfSSL_d2i_SSL_SESSION(NULL, NULL, sz)); AssertNull(sess = wolfSSL_d2i_SSL_SESSION(NULL, NULL, sz));
AssertNotNull(sess = wolfSSL_d2i_SSL_SESSION(NULL, AssertNotNull(sess = wolfSSL_d2i_SSL_SESSION(NULL,
(const unsigned char**)&ptr, sz)); (const unsigned char**)&ptr, sz));
XFREE(sessDer, NULL, DYNAMIC_TYPE_OPENSSL); XFREE(sessDer, NULL, DYNAMIC_TYPE_OPENSSL);
sessDer = NULL;
AssertIntGT(wolfSSL_SESSION_get_time(sess), 0); AssertIntGT(wolfSSL_SESSION_get_time(sess), 0);
AssertIntEQ(wolfSSL_SSL_SESSION_set_timeout(sess, 500), SSL_SUCCESS); AssertIntEQ(wolfSSL_SSL_SESSION_set_timeout(sess, 500), SSL_SUCCESS);
#endif
/* successful set session test */ /* successful set session test */
AssertNotNull(ssl = wolfSSL_new(ctx)); AssertNotNull(ssl = wolfSSL_new(ctx));
AssertIntEQ(wolfSSL_set_session(ssl, sess), SSL_SUCCESS); AssertIntEQ(wolfSSL_set_session(ssl, sess), WOLFSSL_SUCCESS);
#ifdef HAVE_SESSION_TICKET #ifdef HAVE_SESSION_TICKET
/* Test set/get session ticket */ /* Test set/get session ticket */
@ -39364,7 +39379,8 @@ static void test_wolfSSL_SESSION(void)
word32 bufSz = (word32)sizeof(buf); word32 bufSz = (word32)sizeof(buf);
AssertIntEQ(SSL_SUCCESS, AssertIntEQ(SSL_SUCCESS,
wolfSSL_set_SessionTicket(ssl, (byte *)ticket, (word32)XSTRLEN(ticket))); wolfSSL_set_SessionTicket(ssl, (byte *)ticket,
(word32)XSTRLEN(ticket)));
AssertIntEQ(SSL_SUCCESS, AssertIntEQ(SSL_SUCCESS,
wolfSSL_get_SessionTicket(ssl, (byte *)buf, &bufSz)); wolfSSL_get_SessionTicket(ssl, (byte *)buf, &bufSz));
AssertStrEQ(ticket, buf); AssertStrEQ(ticket, buf);
@ -39372,7 +39388,6 @@ static void test_wolfSSL_SESSION(void)
#endif #endif
#ifdef OPENSSL_EXTRA #ifdef OPENSSL_EXTRA
/* session timeout case */ /* session timeout case */
/* make the session to be expired */ /* make the session to be expired */
AssertIntEQ(SSL_SESSION_set_timeout(sess,1), SSL_SUCCESS); AssertIntEQ(SSL_SESSION_set_timeout(sess,1), SSL_SUCCESS);
@ -39393,16 +39408,17 @@ static void test_wolfSSL_SESSION(void)
SSL_SUCCESS); SSL_SUCCESS);
AssertIntEQ(wolfSSL_set_session(ssl, sess), SSL_FAILURE); AssertIntEQ(wolfSSL_set_session(ssl, sess), SSL_FAILURE);
wolfSSL_free(ssl); wolfSSL_free(ssl);
AssertIntEQ(SSL_CTX_set_session_id_context(NULL, context, contextSz), AssertIntEQ(SSL_CTX_set_session_id_context(NULL, context, contextSz),
SSL_FAILURE); SSL_FAILURE);
AssertIntEQ(SSL_CTX_set_session_id_context(ctx, context, contextSz), AssertIntEQ(SSL_CTX_set_session_id_context(ctx, context, contextSz),
SSL_SUCCESS); SSL_SUCCESS);
AssertNotNull(ssl = wolfSSL_new(ctx)); AssertNotNull(ssl = wolfSSL_new(ctx));
AssertIntEQ(wolfSSL_set_session(ssl, sess), SSL_FAILURE); AssertIntEQ(wolfSSL_set_session(ssl, sess), SSL_FAILURE);
#endif #endif /* OPENSSL_EXTRA */
wolfSSL_free(ssl);
SSL_SESSION_free(sess); wolfSSL_free(ssl);
wolfSSL_SESSION_free(sess);
wolfSSL_CTX_free(ctx); wolfSSL_CTX_free(ctx);
printf(resultFmt, passed); printf(resultFmt, passed);
#endif #endif

View File

@ -3340,57 +3340,68 @@ struct WOLFSSL_X509_CHAIN {
x509_buffer certs[MAX_CHAIN_DEPTH]; /* only allow max depth 4 for now */ x509_buffer certs[MAX_CHAIN_DEPTH]; /* only allow max depth 4 for now */
}; };
#if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_SESSION_CACHE_REF)
/* enable allocation of a smaller reference for the internal cache,
* to prevent client from using internal cache reference. */
#define ENABLE_CLIENT_SESSION_REF
#endif
typedef enum WOLFSSL_SESSION_TYPE {
WOLFSSL_SESSION_TYPE_UNKNOWN,
WOLFSSL_SESSION_TYPE_SSL, /* in ssl->session */
WOLFSSL_SESSION_TYPE_CACHE, /* pointer to internal cache */
WOLFSSL_SESSION_TYPE_HEAP /* allocated from heap SESSION_new */
#ifdef ENABLE_CLIENT_SESSION_REF
,WOLFSSL_SESSION_TYPE_REF /* smaller allocation with reference to internal cache */
#endif
} WOLFSSL_SESSION_TYPE;
/* wolfSSL session type */ /* wolfSSL session type */
struct WOLFSSL_SESSION { struct WOLFSSL_SESSION {
int cacheRow; /* row in session cache */ WOLFSSL_SESSION_TYPE type;
word32 bornOn; /* create time in seconds */ byte side; /* Either WOLFSSL_CLIENT_END or
word32 timeout; /* timeout in seconds */ WOLFSSL_SERVER_END */
byte sessionID[ID_LEN]; /* id for protocol */
int cacheRow; /* row in session cache */
word32 bornOn; /* create time in seconds */
word32 timeout; /* timeout in seconds */
byte sessionID[ID_LEN]; /* id for protocol */
byte sessionIDSz; byte sessionIDSz;
byte masterSecret[SECRET_LEN]; /* stored secret */
word16 haveEMS; /* ext master secret flag */ byte* masterSecret; /* stored secret */
#ifdef SESSION_CERTS word16 haveEMS; /* ext master secret flag */
#ifdef OPENSSL_EXTRA #if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
WOLFSSL_X509* peer; /* peer cert */ WOLFSSL_X509* peer; /* peer cert */
#endif
WOLFSSL_X509_CHAIN chain; /* peer cert chain, static */
#ifdef WOLFSSL_ALT_CERT_CHAINS
WOLFSSL_X509_CHAIN altChain; /* peer alt cert chain, static */
#endif
#endif #endif
#if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \ #if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
defined(HAVE_SESSION_TICKET)) defined(HAVE_SESSION_TICKET))
ProtocolVersion version; /* which version was used */ ProtocolVersion version; /* which version was used */
#endif #endif
#if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \ #if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \
(defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)) (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET))
byte cipherSuite0; /* first byte, normally 0 */ byte cipherSuite0; /* first byte, normally 0 */
byte cipherSuite; /* 2nd byte, actual suite */ byte cipherSuite; /* 2nd byte, actual suite */
#endif #endif
#ifndef NO_CLIENT_CACHE #ifndef NO_CLIENT_CACHE
word16 idLen; /* serverID length */ word16 idLen; /* serverID length */
byte serverID[SERVER_ID_LEN]; /* for easier client lookup */ byte* serverID; /* for easier client lookup */
#endif #endif
#ifdef OPENSSL_EXTRA #ifdef OPENSSL_EXTRA
byte sessionCtxSz; /* sessionCtx length */ byte sessionCtxSz; /* sessionCtx length */
byte sessionCtx[ID_LEN]; /* app specific context id */ byte* sessionCtx; /* app specific context id */
#ifndef SINGLE_THREADED
wolfSSL_Mutex refMutex; /* ref count mutex */
#endif
int refCount; /* reference count */
#endif /* OPENSSL_EXTRA */ #endif /* OPENSSL_EXTRA */
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
byte peerVerifyRet; /* cert verify error */ byte peerVerifyRet; /* cert verify error */
#endif #endif
#ifdef WOLFSSL_TLS13 #ifdef WOLFSSL_TLS13
word16 namedGroup; word16 namedGroup;
#endif #endif
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
#ifdef WOLFSSL_TLS13 #ifdef WOLFSSL_TLS13
word32 ticketSeen; /* Time ticket seen (ms) */ word32 ticketSeen; /* Time ticket seen (ms) */
word32 ticketAdd; /* Added by client */ word32 ticketAdd; /* Added by client */
TicketNonce ticketNonce; /* Nonce used to derive PSK */ TicketNonce ticketNonce; /* Nonce used to derive PSK */
#endif #endif
#ifdef WOLFSSL_EARLY_DATA #ifdef WOLFSSL_EARLY_DATA
word32 maxEarlyDataSz; word32 maxEarlyDataSz;
@ -3399,23 +3410,53 @@ struct WOLFSSL_SESSION {
#ifdef HAVE_SESSION_TICKET #ifdef HAVE_SESSION_TICKET
byte* ticket; byte* ticket;
word16 ticketLen; word16 ticketLen;
byte staticTicket[SESSION_TICKET_LEN]; word16 ticketLenAlloc; /* is dynamic */
byte isDynamic;
#endif #endif
#if defined(HAVE_EXT_CACHE) || defined(OPENSSL_EXTRA) int refCount; /* reference count */
byte isAlloced; void* heap;
#ifdef ENABLE_CLIENT_SESSION_REF
/* pointer to WOLFSSL_SESSION in internal cache (for WOLFSSL_SESSION_TYPE_REF) */
void* refPtr;
#endif
/* Below buffers are not allocated for the WOLFSSL_SESSION_TYPE_REF, instead
* the above pointers reference the session cache for backwards
* compatibility. For all other session types the above pointers reference
* these buffers directly */
byte _masterSecret[SECRET_LEN];
#ifndef NO_CLIENT_CACHE
byte _serverID[SERVER_ID_LEN];
#endif
#ifdef HAVE_SESSION_TICKET
byte _staticTicket[SESSION_TICKET_LEN];
#endif
#ifdef OPENSSL_EXTRA
byte _sessionCtx[ID_LEN];
#endif
#ifdef SESSION_CERTS
WOLFSSL_X509_CHAIN chain; /* peer cert chain, static */
#ifdef WOLFSSL_ALT_CERT_CHAINS
WOLFSSL_X509_CHAIN altChain; /* peer alt cert chain, static */
#endif
#endif #endif
#ifdef HAVE_EX_DATA #ifdef HAVE_EX_DATA
WOLFSSL_CRYPTO_EX_DATA ex_data; WOLFSSL_CRYPTO_EX_DATA ex_data;
#endif #endif
byte side; /* Either WOLFSSL_CLIENT_END or #ifdef OPENSSL_EXTRA
WOLFSSL_SERVER_END */ #ifndef SINGLE_THREADED
wolfSSL_Mutex refMutex; /* ref count mutex */
#endif
#endif
}; };
WOLFSSL_LOCAL WOLFSSL_SESSION* NewSession(void* heap);
WOLFSSL_LOCAL WOLFSSL_SESSION* GetSession(WOLFSSL*, byte*, byte); WOLFSSL_LOCAL WOLFSSL_SESSION* GetSession(WOLFSSL*, byte*, byte);
WOLFSSL_LOCAL WOLFSSL_SESSION* GetSessionRef(WOLFSSL*);
WOLFSSL_LOCAL int SetSession(WOLFSSL*, WOLFSSL_SESSION*); WOLFSSL_LOCAL int SetSession(WOLFSSL*, WOLFSSL_SESSION*);
WOLFSSL_LOCAL void FreeSession(WOLFSSL_SESSION*, int); WOLFSSL_LOCAL void FreeSession(WOLFSSL_SESSION*);
typedef int (*hmacfp) (WOLFSSL*, byte*, const byte*, word32, int, int, int, int); typedef int (*hmacfp) (WOLFSSL*, byte*, const byte*, word32, int, int, int, int);

View File

@ -354,6 +354,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS;
#define SSL_set_session_id_context wolfSSL_set_session_id_context #define SSL_set_session_id_context wolfSSL_set_session_id_context
#define SSL_set_connect_state wolfSSL_set_connect_state #define SSL_set_connect_state wolfSSL_set_connect_state
#define SSL_set_accept_state wolfSSL_set_accept_state #define SSL_set_accept_state wolfSSL_set_accept_state
#define SSL_SESSION_new wolfSSL_SESSION_new
#define SSL_session_reused wolfSSL_session_reused #define SSL_session_reused wolfSSL_session_reused
#define SSL_SESSION_up_ref wolfSSL_SESSION_up_ref #define SSL_SESSION_up_ref wolfSSL_SESSION_up_ref
#define SSL_SESSION_dup wolfSSL_SESSION_dup #define SSL_SESSION_dup wolfSSL_SESSION_dup

View File

@ -1446,6 +1446,7 @@ WOLFSSL_API int wolfSSL_session_reused(WOLFSSL*);
WOLFSSL_API int wolfSSL_SESSION_up_ref(WOLFSSL_SESSION* session); 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_dup(WOLFSSL_SESSION* session);
WOLFSSL_API WOLFSSL_SESSION* wolfSSL_SESSION_new(void); WOLFSSL_API WOLFSSL_SESSION* wolfSSL_SESSION_new(void);
WOLFSSL_API WOLFSSL_SESSION* wolfSSL_SESSION_new_ex(void* heap);
WOLFSSL_API void wolfSSL_SESSION_free(WOLFSSL_SESSION* session); WOLFSSL_API void wolfSSL_SESSION_free(WOLFSSL_SESSION* session);
WOLFSSL_API int wolfSSL_SESSION_set_cipher(WOLFSSL_SESSION* session, WOLFSSL_API int wolfSSL_SESSION_set_cipher(WOLFSSL_SESSION* session,
const WOLFSSL_CIPHER* cipher); const WOLFSSL_CIPHER* cipher);
@ -1468,7 +1469,6 @@ WOLFSSL_API const char* wolfSSL_SESSION_CIPHER_get_name(WOLFSSL_SESSION* sessio
WOLFSSL_API const char* wolfSSL_get_cipher(WOLFSSL*); WOLFSSL_API const char* wolfSSL_get_cipher(WOLFSSL*);
WOLFSSL_API void wolfSSL_sk_CIPHER_free(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk); WOLFSSL_API void wolfSSL_sk_CIPHER_free(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk);
WOLFSSL_API WOLFSSL_SESSION* wolfSSL_get1_session(WOLFSSL* ssl); WOLFSSL_API WOLFSSL_SESSION* wolfSSL_get1_session(WOLFSSL* ssl);
/* what's ref count */
WOLFSSL_API WOLFSSL_X509* wolfSSL_X509_new(void); WOLFSSL_API WOLFSSL_X509* wolfSSL_X509_new(void);
#if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA) #if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA)

View File

@ -2269,7 +2269,7 @@ static WC_INLINE int my_psk_use_session_cb(WOLFSSL* ssl,
printf("use psk session callback \n"); printf("use psk session callback \n");
lsess = wolfSSL_SESSION_new(); lsess = SSL_SESSION_new();
if (lsess == NULL) { if (lsess == NULL) {
return 0; return 0;
} }
@ -2305,6 +2305,7 @@ static WC_INLINE int my_psk_use_session_cb(WOLFSSL* ssl,
*id = NULL; *id = NULL;
*idlen = 0; *idlen = 0;
*sess = NULL; *sess = NULL;
SSL_SESSION_free(lsess);
return 0; return 0;
} }
#else #else

View File

@ -751,7 +751,11 @@ decouple library dependencies with standard string, memory and so on.
#endif #endif
#ifndef OFFSETOF #ifndef OFFSETOF
#define OFFSETOF(type, field) ((size_t)&(((type *)0)->field)) #if defined(__clang__) || defined(__GNUC__)
#define OFFSETOF(type, field) __builtin_offsetof(type, field)
#else
#define OFFSETOF(type, field) ((size_t)&(((type *)0)->field))
#endif
#endif #endif
@ -851,6 +855,7 @@ decouple library dependencies with standard string, memory and so on.
DYNAMIC_TYPE_AES = 93, DYNAMIC_TYPE_AES = 93,
DYNAMIC_TYPE_CMAC = 94, DYNAMIC_TYPE_CMAC = 94,
DYNAMIC_TYPE_FALCON = 95, DYNAMIC_TYPE_FALCON = 95,
DYNAMIC_TYPE_SESSION = 96,
DYNAMIC_TYPE_SNIFFER_SERVER = 1000, DYNAMIC_TYPE_SNIFFER_SERVER = 1000,
DYNAMIC_TYPE_SNIFFER_SESSION = 1001, DYNAMIC_TYPE_SNIFFER_SESSION = 1001,
DYNAMIC_TYPE_SNIFFER_PB = 1002, DYNAMIC_TYPE_SNIFFER_PB = 1002,