Add backwards compatibility for wolfSSL_get_session

Before this pull request, `wolfSSL_get_session` always returned a pointer to the internal session cache. The user can't tell if the underlying session hasn't changed before it calls `wolfSSL_set_session` on it. This PR adds a define `NO_SESSION_CACHE_REF` (for now only defined with `OPENSSL_COMPATIBLE_DEFAULTS`) that makes wolfSSL only return a pointer to `ssl->session`. The issue is that this makes the pointer returned non-persistent ie: it gets free'd with the `WOLFSSL` object. This commit leverages the lightweight `ClientCache` to "increase" the size of the session cache. The hash of the session ID is checked to make sure that the underlying session hasn't changed.
This commit is contained in:
Juliusz Sosinowicz
2022-02-11 19:05:12 +01:00
parent ceff401269
commit b402102e58
5 changed files with 368 additions and 106 deletions

View File

@ -6830,6 +6830,7 @@ AS_CASE(["$CFLAGS $CPPFLAGS $AM_CFLAGS"],[*'OPENSSL_COMPATIBLE_DEFAULTS'*],
if test "x$ENABLED_OPENSSL_COMPATIBLE_DEFAULTS" = "xyes"
then
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_TRUST_PEER_CERT -DWOLFSSL_TLS13_MIDDLEBOX_COMPAT"
AM_CFLAGS="$AM_CFLAGS -DNO_SESSION_CACHE_REF"
ENABLED_TRUSTED_PEER_CERT=yes
fi

430
src/ssl.c
View File

@ -164,6 +164,11 @@
* should make porting to new projects easier.
* WOLFSSL_CHECK_ALERT_ON_ERR:
* Check for alerts during the handshake in the event of an error.
* NO_SESSION_CACHE_REF:
* wolfSSL_get_session on a client will return a reference to the internal
* ClientCache by default for backwards compatibility. This define will
* make wolfSSL_get_session return a reference to ssl->session. The returned
* pointer will be freed with the related WOLFSSL object.
*/
#define WOLFSSL_EVP_INCLUDED
@ -3341,7 +3346,7 @@ WOLFSSL_API int wolfSSL_set_SessionTicket(WOLFSSL* ssl, const byte* buf,
/* Ticket will fit into static ticket */
if (bufSz <= SESSION_TICKET_LEN) {
if (ssl->session->ticketLenAlloc > 0) {
XFREE(ssl->session->ticket, ssl->heap,
XFREE(ssl->session->ticket, ssl->session->heap,
DYNAMIC_TYPE_SESSION_TICK);
ssl->session->ticketLenAlloc = 0;
ssl->session->ticket = ssl->session->_staticTicket;
@ -3350,7 +3355,7 @@ WOLFSSL_API int wolfSSL_set_SessionTicket(WOLFSSL* ssl, const byte* buf,
else { /* Ticket requires dynamic ticket storage */
if (ssl->session->ticketLen < bufSz) { /* is dyn buffer big enough */
if (ssl->session->ticketLenAlloc > 0) {
XFREE(ssl->session->ticket, ssl->heap,
XFREE(ssl->session->ticket, ssl->session->heap,
DYNAMIC_TYPE_SESSION_TICK);
}
ssl->session->ticket = (byte*)XMALLOC(bufSz, ssl->session->heap,
@ -5298,20 +5303,48 @@ int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify)
#define SESSION_ROW_UNLOCK(row) wc_UnLockMutex(&session_mutex);
#endif
#if !defined(NO_SESSION_CACHE_REF) && defined(NO_CLIENT_CACHE)
#error ClientCache is required when not using NO_SESSION_CACHE_REF
#endif
#ifndef NO_CLIENT_CACHE
#ifndef CLIENT_SESSIONS_MULTIPLIER
#ifdef NO_SESSION_CACHE_REF
#define CLIENT_SESSIONS_MULTIPLIER 1
#else
/* ClientSession objects are lightweight (compared to
* WOLFSSL_SESSION) so to decrease chance that user will reuse
* thse wrong session, increase the ClientCache size. This will
* make the entire ClientCache about the size of one
* WOLFSSL_SESSION object. */
#define CLIENT_SESSIONS_MULTIPLIER 8
#endif
#endif
#define CLIENT_SESSIONS_PER_ROW \
(SESSIONS_PER_ROW * CLIENT_SESSIONS_MULTIPLIER)
#define CLIENT_SESSION_ROWS (SESSION_ROWS * CLIENT_SESSIONS_MULTIPLIER)
#if CLIENT_SESSIONS_PER_ROW > 65535
#error CLIENT_SESSIONS_PER_ROW too big
#endif
#if CLIENT_SESSION_ROWS > 65535
#error CLIENT_SESSION_ROWS too big
#endif
typedef struct ClientSession {
word16 serverRow; /* SessionCache Row id */
word16 serverIdx; /* SessionCache Idx (column) */
word32 sessionIDHash;
} ClientSession;
typedef struct ClientRow {
int nextIdx; /* where to place next one */
int totalCount; /* sessions ever on this row */
ClientSession Clients[SESSIONS_PER_ROW];
ClientSession Clients[CLIENT_SESSIONS_PER_ROW];
} ClientRow;
static WOLFSSL_GLOBAL ClientRow ClientCache[SESSION_ROWS];
static WOLFSSL_GLOBAL ClientRow ClientCache[CLIENT_SESSION_ROWS];
/* Client Cache */
/* uses session mutex */
@ -12239,6 +12272,8 @@ int wolfSSL_SESSION_get_master_key(const WOLFSSL_SESSION* ses,
{
int size;
ses = ClientSessionToSession(ses);
if (outSz == 0) {
return SECRET_LEN;
}
@ -12501,8 +12536,45 @@ WOLFSSL_ABI
WOLFSSL_SESSION* wolfSSL_get_session(WOLFSSL* ssl)
{
WOLFSSL_ENTER("SSL_get_session");
if (ssl)
if (ssl) {
#ifdef NO_SESSION_CACHE_REF
return ssl->session;
#else
if (ssl->options.side == WOLFSSL_CLIENT_END) {
/* On the client side we want to return a persistant reference for
* backwards compatibility. */
#ifndef NO_CLIENT_CACHE
if (ssl->clientSession)
return (WOLFSSL_SESSION*)ssl->clientSession;
else {
/* Try to add a ClientCache entry to associate with the current
* session. Ignore any session cache options. */
int error;
const byte* id = NULL;
byte idSz = 0;
id = ssl->session->sessionID;
idSz = ssl->session->sessionIDSz;
if (ssl->session->haveAltSessionID) {
id = ssl->session->altSessionID;
idSz = ID_LEN;
}
error = AddSessionToCache(ssl->session, id, idSz,
NULL, ssl->session->side,
#ifdef HAVE_SESSION_TICKET
ssl->session->ticketLen > 0,
#else
0,
#endif
&ssl->clientSession);
if (error == 0)
return (WOLFSSL_SESSION*)ssl->clientSession;
}
#endif
}
else
return ssl->session;
#endif
}
return NULL;
}
@ -12641,9 +12713,6 @@ int wolfSSL_memsave_session_cache(void* mem, int sz)
int i;
cache_header_t cache_header;
SessionRow* row = (SessionRow*)((byte*)mem + sizeof(cache_header));
#ifndef NO_CLIENT_CACHE
ClientRow* clRow;
#endif
WOLFSSL_ENTER("wolfSSL_memsave_session_cache");
@ -12686,11 +12755,7 @@ int wolfSSL_memsave_session_cache(void* mem, int sz)
WOLFSSL_MSG("Client cache mutex lock failed");
return BAD_MUTEX_E;
}
clRow = (ClientRow*)row;
for (i = 0; i < cache_header.rows; ++i) {
XMEMCPY(clRow++, ClientCache + i, sizeof(ClientRow));
}
XMEMCPY(row, ClientCache, sizeof(ClientCache));
wc_UnLockMutex(&clisession_mutex);
#endif
@ -12706,9 +12771,6 @@ int wolfSSL_memrestore_session_cache(const void* mem, int sz)
int i;
cache_header_t cache_header;
SessionRow* row = (SessionRow*)((byte*)mem + sizeof(cache_header));
#ifndef NO_CLIENT_CACHE
ClientRow* clRow;
#endif
WOLFSSL_ENTER("wolfSSL_memrestore_session_cache");
@ -12755,11 +12817,7 @@ int wolfSSL_memrestore_session_cache(const void* mem, int sz)
WOLFSSL_MSG("Client cache mutex lock failed");
return BAD_MUTEX_E;
}
clRow = (ClientRow*)row;
for (i = 0; i < cache_header.rows; ++i) {
XMEMCPY(ClientCache + i, clRow++, sizeof(ClientRow));
}
XMEMCPY(ClientCache, row, sizeof(ClientCache));
wc_UnLockMutex(&clisession_mutex);
#endif
@ -12838,14 +12896,10 @@ int wolfSSL_save_session_cache(const char *fname)
XFCLOSE(file);
return BAD_MUTEX_E;
}
for (i = 0; i < cache_header.rows; ++i) {
ret = (int)XFWRITE(ClientCache + i, sizeof(ClientRow), 1, file);
if (ret != 1) {
WOLFSSL_MSG("Client cache member file write failed");
rc = FWRITE_ERROR;
break;
}
ret = (int)XFWRITE(ClientCache, sizeof(ClientCache), 1, file);
if (ret != 1) {
WOLFSSL_MSG("Client cache member file write failed");
rc = FWRITE_ERROR;
}
wc_UnLockMutex(&clisession_mutex);
#endif /* !NO_CLIENT_CACHE */
@ -12930,14 +12984,11 @@ int wolfSSL_restore_session_cache(const char *fname)
XFCLOSE(file);
return BAD_MUTEX_E;
}
for (i = 0; i < cache_header.rows; ++i) {
ret = (int)XFREAD(ClientCache + i, sizeof(ClientRow), 1, file);
if (ret != 1) {
WOLFSSL_MSG("Client cache member file read failed");
XMEMSET(ClientCache, 0, sizeof ClientCache);
rc = FREAD_ERROR;
break;
}
ret = (int)XFREAD(ClientCache, sizeof(ClientCache), 1, file);
if (ret != 1) {
WOLFSSL_MSG("Client cache member file read failed");
XMEMSET(ClientCache, 0, sizeof ClientCache);
rc = FREAD_ERROR;
}
wc_UnLockMutex(&clisession_mutex);
#endif /* !NO_CLIENT_CACHE */
@ -15342,7 +15393,7 @@ WOLFSSL_SESSION* wolfSSL_GetSessionClient(WOLFSSL* ssl, const byte* id, int len)
}
#endif
row = HashSession(id, len, &error) % SESSION_ROWS;
row = HashSession(id, len, &error) % CLIENT_SESSION_ROWS;
if (error != 0) {
WOLFSSL_MSG("Hash session failed");
return NULL;
@ -15354,10 +15405,10 @@ WOLFSSL_SESSION* wolfSSL_GetSessionClient(WOLFSSL* ssl, const byte* id, int len)
}
/* start from most recently used */
count = min((word32)ClientCache[row].totalCount, SESSIONS_PER_ROW);
count = min((word32)ClientCache[row].totalCount, CLIENT_SESSIONS_PER_ROW);
idx = ClientCache[row].nextIdx - 1;
if (idx < 0 || idx >= SESSIONS_PER_ROW) {
idx = SESSIONS_PER_ROW - 1; /* if back to front, the previous was end */
if (idx < 0 || idx >= CLIENT_SESSIONS_PER_ROW) {
idx = CLIENT_SESSIONS_PER_ROW - 1; /* if back to front, the previous was end */
}
clSess = ClientCache[row].Clients;
@ -15393,7 +15444,7 @@ WOLFSSL_SESSION* wolfSSL_GetSessionClient(WOLFSSL* ssl, const byte* id, int len)
}
SESSION_ROW_UNLOCK(sessRow);
idx = idx > 0 ? idx - 1 : SESSIONS_PER_ROW - 1;
idx = idx > 0 ? idx - 1 : CLIENT_SESSIONS_PER_ROW - 1;
}
wc_UnLockMutex(&clisession_mutex);
@ -15667,36 +15718,59 @@ WOLFSSL_SESSION* wolfSSL_GetSession(WOLFSSL* ssl, byte* masterSecret,
int wolfSSL_SetSession(WOLFSSL* ssl, WOLFSSL_SESSION* session)
{
SessionRow* sessRow = NULL;
int ret = WOLFSSL_SUCCESS;
if (ssl == NULL || session == NULL || SslSessionCacheOff(ssl, session)) {
session = ClientSessionToSession(session);
if (ssl == NULL || session == NULL) {
return WOLFSSL_FAILURE;
}
if (session->type == WOLFSSL_SESSION_TYPE_CACHE) {
WOLFSSL_MSG("Can't call wolfSSL_SetSession on a session in the cache. "
"This may cause issues when the cache entry is modified "
"before it gets used.");
return WOLFSSL_FAILURE;
if (session->cacheRow < SESSION_ROWS) {
sessRow = &SessionCache[session->cacheRow];
if (SESSION_ROW_LOCK(sessRow) != 0) {
WOLFSSL_MSG("Session row lock failed");
return WOLFSSL_FAILURE;
}
}
}
if (ssl->options.side != WOLFSSL_NEITHER_END &&
if (ret == WOLFSSL_SUCCESS && SslSessionCacheOff(ssl, session)) {
WOLFSSL_MSG("Session cache off");
ret = WOLFSSL_FAILURE;
}
if (ret == WOLFSSL_SUCCESS && ssl->options.side != WOLFSSL_NEITHER_END &&
(byte)ssl->options.side != session->side) {
WOLFSSL_MSG("Setting session for wrong role");
return WOLFSSL_FAILURE;
ret = WOLFSSL_FAILURE;
}
if (wolfSSL_DupSession(session, ssl->session, 0) != WOLFSSL_SUCCESS) {
if (ret == WOLFSSL_SUCCESS &&
wolfSSL_DupSession(session, ssl->session, 0) != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("Session duplicate failed");
return WOLFSSL_FAILURE;
ret = WOLFSSL_FAILURE;
}
/* Let's copy over the altSessionID for local cache purposes */
if (session->haveAltSessionID) {
if (ret == WOLFSSL_SUCCESS && session->haveAltSessionID) {
ssl->session->haveAltSessionID = 1;
XMEMCPY(ssl->session->altSessionID, session->altSessionID, ID_LEN);
}
if (sessRow != NULL) {
SESSION_ROW_UNLOCK(sessRow);
sessRow = NULL;
}
/* Make sure we don't access this anymore */
session = NULL;
if (ret != WOLFSSL_SUCCESS)
return ret;
#ifdef OPENSSL_EXTRA
/* check for application context id */
if (ssl->sessionCtxSz > 0) {
@ -15747,10 +15821,12 @@ static int get_locked_session_stats(word32* active, word32* total,
#endif
#ifndef NO_CLIENT_CACHE
int AddSessionToClientCache(int side, int row, int idx, byte* serverID,
word16 idLen, word16 useTicket)
ClientSession* AddSessionToClientCache(int side, int row, int idx, byte* serverID,
word16 idLen, const byte* sessionID,
word16 useTicket)
{
int error = 0;
int error = -1;
word32 clientRow = 0, clientIdx = 0, sessionIDHash = 0;
(void)useTicket;
if (side == WOLFSSL_CLIENT_END
&& row != INVALID_SESSION_ROW
@ -15758,22 +15834,40 @@ int AddSessionToClientCache(int side, int row, int idx, byte* serverID,
#ifdef HAVE_SESSION_TICKET
|| useTicket == 1
#endif
|| serverID != NULL
)) {
word32 clientRow, clientIdx;
WOLFSSL_MSG("Adding client cache entry");
WOLFSSL_MSG("Trying to add client cache entry");
clientRow = HashSession(serverID,
idLen, &error) % SESSION_ROWS;
if (idLen) {
clientRow = HashSession(serverID,
idLen, &error) % CLIENT_SESSION_ROWS;
}
else if (serverID != NULL) {
clientRow = HashSession(sessionID,
ID_LEN, &error) % CLIENT_SESSION_ROWS;
}
else
error = -1;
if (error == 0 && wc_LockMutex(&clisession_mutex) == 0) {
clientIdx = ClientCache[clientRow].nextIdx++;
ClientCache[clientRow].Clients[clientIdx].serverRow =
(word16)row;
ClientCache[clientRow].Clients[clientIdx].serverIdx =
(word16)idx;
if (ClientCache[clientRow].totalCount < SESSIONS_PER_ROW)
ClientCache[clientRow].totalCount++;
ClientCache[clientRow].nextIdx %= SESSIONS_PER_ROW;
if (sessionID != NULL) {
sessionIDHash = HashSession(sessionID, ID_LEN, &error);
if (error == 0) {
ClientCache[clientRow].Clients[clientIdx].sessionIDHash
= sessionIDHash;
}
}
if (error == 0) {
WOLFSSL_MSG("Adding client cache entry");
if (ClientCache[clientRow].totalCount < CLIENT_SESSIONS_PER_ROW)
ClientCache[clientRow].totalCount++;
ClientCache[clientRow].nextIdx %= CLIENT_SESSIONS_PER_ROW;
}
wc_UnLockMutex(&clisession_mutex);
}
@ -15784,12 +15878,100 @@ int AddSessionToClientCache(int side, int row, int idx, byte* serverID,
else {
WOLFSSL_MSG("Skipping client cache");
}
return error;
if (error == 0)
return &ClientCache[clientRow].Clients[clientIdx];
else
return NULL;
}
#endif
/**
* For backwards compatibility, this API needs to be used in *ALL* functions
* that access the WOLFSSL_SESSION members directly.
*
* This API checks if the passed in session is actually a ClientSession object
* and returns the matching session cache object. Otherwise just return the
* input. ClientSession objects only occur in the ClientCache. They are not
* allocated anywhere else.
*/
WOLFSSL_SESSION* ClientSessionToSession(const WOLFSSL_SESSION* session)
{
WOLFSSL_ENTER("ClientSessionToSession");
#ifdef NO_SESSION_CACHE_REF
return (WOLFSSL_SESSION*)session;
#else
#ifndef NO_CLIENT_CACHE
if (session == NULL)
return NULL;
/* Check if session points into ClientCache */
if ((byte*)session >= (byte*)ClientCache &&
/* Cast to byte* to make pointer arithmetic work per byte */
(byte*)session < ((byte*)ClientCache) + sizeof(ClientCache)) {
ClientSession* clientSession = (ClientSession*)session;
SessionRow* sessRow = NULL;
WOLFSSL_SESSION* cacheSession = NULL;
word32 sessionIDHash = 0;
int error = 0;
session = NULL; /* Default to NULL for failure case */
if (wc_LockMutex(&clisession_mutex) != 0) {
WOLFSSL_MSG("Client cache mutex lock failed");
return NULL;
}
if (clientSession->serverRow >= SESSION_ROWS ||
clientSession->serverIdx >= SESSIONS_PER_ROW) {
WOLFSSL_MSG("Client cache serverRow or serverIdx invalid");
error = -1;
}
if (error == 0) {
/* Lock row */
sessRow = &SessionCache[clientSession->serverRow];
error = SESSION_ROW_LOCK(sessRow);
if (error != 0) {
WOLFSSL_MSG("Session cache row lock failure");
sessRow = NULL;
}
}
if (error == 0) {
cacheSession = &sessRow->Sessions[clientSession->serverIdx];
if (cacheSession->sessionIDSz == 0) {
cacheSession = NULL;
WOLFSSL_MSG("Session cache entry not set");
error = -1;
}
}
if (error == 0) {
/* Calculate the hash of the session ID */
sessionIDHash = HashSession(cacheSession->sessionID, ID_LEN,
&error);
}
if (error == 0) {
/* Check the session ID hash matches */
error = clientSession->sessionIDHash != sessionIDHash;
}
if (error == 0) {
/* Hashes match */
session = cacheSession;
WOLFSSL_MSG("Found session cache matching client session object");
}
if (sessRow != NULL) {
SESSION_ROW_UNLOCK(sessRow);
}
wc_UnLockMutex(&clisession_mutex);
return (WOLFSSL_SESSION*)session;
}
else {
/* Plain WOLFSSL_SESSION object */
return (WOLFSSL_SESSION*)session;
}
#else
return (WOLFSSL_SESSION*)session;
#endif
#endif
}
int AddSessionToCache(WOLFSSL_SESSION* addSession, const byte* id, byte idSz,
int* sessionIndex, int side, word16 useTicket)
int* sessionIndex, int side, word16 useTicket,
ClientSession** clientCacheEntry)
{
WOLFSSL_SESSION* cacheSession = NULL;
SessionRow* sessRow = NULL;
@ -15808,6 +15990,9 @@ int AddSessionToCache(WOLFSSL_SESSION* addSession, const byte* id, byte idSz,
(void)sessionIndex;
(void)useTicket;
(void)clientCacheEntry;
addSession = ClientSessionToSession(addSession);
if (addSession == NULL || idSz == 0) {
WOLFSSL_MSG("addSession NULL or idSz == 0");
@ -15841,6 +16026,7 @@ int AddSessionToCache(WOLFSSL_SESSION* addSession, const byte* id, byte idSz,
#ifdef HAVE_SESSION_TICKET
XFREE(ticBuff, addSession->heap, DYNAMIC_TYPE_SESSION_TICK);
#endif
WOLFSSL_MSG("Session row lock failed");
return BAD_MUTEX_E;
}
@ -15915,9 +16101,12 @@ int AddSessionToCache(WOLFSSL_SESSION* addSession, const byte* id, byte idSz,
cacheSession = NULL; /* Can't access after unlocked */
#ifndef NO_CLIENT_CACHE
if (ret == 0)
ret = AddSessionToClientCache(side, row, idx, addSession->serverID,
addSession->idLen, useTicket);
if (ret == 0) {
ClientSession* clientCache = AddSessionToClientCache(side, row, idx,
addSession->serverID, addSession->idLen, id, useTicket);
if (clientCache != NULL && clientCacheEntry != NULL)
*clientCacheEntry = clientCache;
}
#endif
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
@ -15933,7 +16122,7 @@ int AddSessionToCache(WOLFSSL_SESSION* addSession, const byte* id, byte idSz,
#ifndef NO_CLIENT_CACHE
#endif
int AddSession(WOLFSSL* ssl)
void AddSession(WOLFSSL* ssl)
{
int error = 0;
const byte* id = NULL;
@ -15943,23 +16132,25 @@ int AddSession(WOLFSSL* ssl)
int cbRet = 0;
#endif
(void)error;
WOLFSSL_ENTER("AddSession");
if (SslSessionCacheOff(ssl, session)) {
WOLFSSL_MSG("Cache off");
return 0;
return;
}
if (ssl->options.haveSessionId == 0) {
WOLFSSL_MSG("Don't have session id");
return 0;
return;
}
#if defined(HAVE_SESSION_TICKET) && !defined(OPENSSL_EXTRA)
/* For the compat layer generate a session object to use */
if (ssl->options.side == WOLFSSL_SERVER_END && ssl->options.useTicket == 1) {
WOLFSSL_MSG("Using tickets instead of cache");
return 0;
return;
}
#endif
@ -16005,13 +16196,33 @@ int AddSession(WOLFSSL* ssl)
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
session->peerVerifyRet = (byte)ssl->peerVerifyRet;
#endif
/* Do this last so that if it fails, the rest of the session is setup. Do
* this only for the client because if the server doesn't have an ID at
* this point, it won't on resumption. */
if (idSz == 0 && ssl->options.side == WOLFSSL_CLIENT_END) {
WC_RNG* rng = NULL;
if (ssl->rng != NULL)
rng = ssl->rng;
#ifdef HAVE_GLOBAL_RNG
else if (initGlobalRNG == 1 || wolfSSL_RAND_Init() == WOLFSSL_SUCCESS) {
rng = &globalRNG;
}
#endif
if (wc_RNG_GenerateBlock(rng, ssl->session->altSessionID,
ID_LEN) != 0)
return;
ssl->session->haveAltSessionID = 1;
id = ssl->session->altSessionID;
idSz = ID_LEN;
}
/* Setup done */
#ifdef HAVE_EXT_CACHE
if (!ssl->options.internalCacheOff)
#endif
{
error = AddSessionToCache(session, id, idSz,
/* Try to add the session to cache. Its ok if we don't succeed. */
(void)AddSessionToCache(session, id, idSz,
#ifdef SESSION_INDEX
&ssl->sessionIndex,
#else
@ -16019,10 +16230,11 @@ int AddSession(WOLFSSL* ssl)
#endif
ssl->options.side,
#ifdef HAVE_SESSION_TICKET
ssl->options.useTicket
ssl->options.useTicket,
#else
0
0,
#endif
NULL
);
}
@ -16049,8 +16261,6 @@ int AddSession(WOLFSSL* ssl)
}
}
#endif /* WOLFSSL_SESSION_STATS && WOLFSSL_PEAK_SESSIONS */
return error;
}
@ -16071,6 +16281,8 @@ int wolfSSL_GetSessionAtIndex(int idx, WOLFSSL_SESSION* session)
WOLFSSL_ENTER("wolfSSL_GetSessionAtIndex");
session = ClientSessionToSession(session);
row = idx >> SESSIDX_ROW_SHIFT;
col = idx & SESSIDX_IDX_MASK;
@ -16103,6 +16315,8 @@ WOLFSSL_X509_CHAIN* wolfSSL_SESSION_get_peer_chain(WOLFSSL_SESSION* session)
WOLFSSL_ENTER("wolfSSL_SESSION_get_peer_chain");
session = ClientSessionToSession(session);
if (session)
chain = &session->chain;
@ -16118,6 +16332,7 @@ WOLFSSL_X509* wolfSSL_SESSION_get0_peer(WOLFSSL_SESSION* session)
{
WOLFSSL_ENTER("wolfSSL_SESSION_get_peer_chain");
session = ClientSessionToSession(session);
if (session) {
int count;
@ -16301,6 +16516,11 @@ int wolfSSL_get_session_stats(word32* active, word32* total, word32* peak,
#else /* NO_SESSION_CACHE */
WOLFSSL_SESSION* ClientSessionToSession(const WOLFSSL_SESSION* session)
{
return (WOLFSSL_SESSION*)session;
}
/* No session cache version */
WOLFSSL_SESSION* wolfSSL_GetSession(WOLFSSL* ssl, byte* masterSecret,
byte restoreSessionCerts)
@ -23745,7 +23965,9 @@ WOLFSSL_SESSION* wolfSSL_SESSION_new(void)
* return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on error */
int wolfSSL_SESSION_up_ref(WOLFSSL_SESSION* session)
{
if (session == NULL)
session = ClientSessionToSession(session);
if (session == NULL || session->type != WOLFSSL_SESSION_TYPE_HEAP)
return WOLFSSL_FAILURE;
#ifndef SINGLE_THREADED
@ -23786,6 +24008,9 @@ int wolfSSL_DupSession(const WOLFSSL_SESSION* input, WOLFSSL_SESSION* output,
(void)avoidSysCalls;
input = ClientSessionToSession(input);
output = ClientSessionToSession(output);
if (input == NULL || output == NULL || input == output) {
WOLFSSL_MSG("input or output are null or same");
return WOLFSSL_FAILURE;
@ -23923,6 +24148,7 @@ WOLFSSL_SESSION* wolfSSL_SESSION_dup(WOLFSSL_SESSION* session)
WOLFSSL_ENTER("wolfSSL_SESSION_dup");
session = ClientSessionToSession(session);
if (session == NULL)
return NULL;
@ -23949,6 +24175,7 @@ WOLFSSL_SESSION* wolfSSL_SESSION_dup(WOLFSSL_SESSION* session)
void wolfSSL_FreeSession(WOLFSSL_SESSION* session)
{
session = ClientSessionToSession(session);
if (session == NULL)
return;
@ -24002,6 +24229,7 @@ void wolfSSL_FreeSession(WOLFSSL_SESSION* session)
void wolfSSL_SESSION_free(WOLFSSL_SESSION* session)
{
session = ClientSessionToSession(session);
wolfSSL_FreeSession(session);
}
@ -24014,6 +24242,7 @@ int wolfSSL_CTX_add_session(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* session)
WOLFSSL_ENTER("wolfSSL_CTX_add_session");
session = ClientSessionToSession(session);
if (session == NULL)
return WOLFSSL_FAILURE;
@ -24030,11 +24259,11 @@ int wolfSSL_CTX_add_session(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* session)
error = AddSessionToCache(session, id, idSz,
NULL, session->side,
#ifdef HAVE_SESSION_TICKET
session->ticketLen > 0
session->ticketLen > 0,
#else
0
0,
#endif
);
NULL);
return error == 0 ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
}
@ -24053,6 +24282,7 @@ int wolfSSL_SESSION_set_cipher(WOLFSSL_SESSION* session,
{
WOLFSSL_ENTER("wolfSSL_SESSION_set_cipher");
session = ClientSessionToSession(session);
/* sanity check */
if (session == NULL || cipher == NULL) {
WOLFSSL_MSG("bad argument");
@ -24202,6 +24432,7 @@ const char* wolfSSL_CIPHER_get_version(const WOLFSSL_CIPHER* cipher)
const char* wolfSSL_SESSION_CIPHER_get_name(const WOLFSSL_SESSION* session)
{
session = ClientSessionToSession(session);
if (session == NULL) {
return NULL;
}
@ -29760,8 +29991,8 @@ long wolfSSL_set_tlsext_debug_arg(WOLFSSL* ssl, void *arg)
#if defined(OPENSSL_ALL) || defined(WOLFSSL_HAPROXY)
const unsigned char *SSL_SESSION_get0_id_context(const WOLFSSL_SESSION *sess, unsigned int *sid_ctx_length)
{
const byte *c = wolfSSL_SESSION_get_id((WOLFSSL_SESSION *)sess, sid_ctx_length);
return c;
sess = ClientSessionToSession(sess);
return wolfSSL_SESSION_get_id((WOLFSSL_SESSION *)sess, sid_ctx_length);
}
#endif
@ -32352,6 +32583,7 @@ int wolfSSL_i2d_SSL_SESSION(WOLFSSL_SESSION* sess, unsigned char** p)
WOLFSSL_ENTER("wolfSSL_i2d_SSL_SESSION");
sess = ClientSessionToSession(sess);
if (sess == NULL) {
return BAD_FUNC_ARG;
}
@ -32530,11 +32762,9 @@ WOLFSSL_SESSION* wolfSSL_d2i_SSL_SESSION(WOLFSSL_SESSION** sess,
if (p == NULL || *p == NULL)
return NULL;
if (s == NULL) {
s = wolfSSL_SESSION_new();
if (s == NULL)
return NULL;
}
s = wolfSSL_SESSION_new();
if (s == NULL)
return NULL;
idx = 0;
data = (byte*)*p;
@ -32726,8 +32956,9 @@ WOLFSSL_SESSION* wolfSSL_d2i_SSL_SESSION(WOLFSSL_SESSION** sess,
#endif
(void)idx;
if (sess != NULL)
if (sess != NULL) {
*sess = s;
}
*p += idx;
@ -32749,6 +32980,7 @@ int wolfSSL_SESSION_has_ticket(const WOLFSSL_SESSION* sess)
{
WOLFSSL_ENTER("wolfSSL_SESSION_has_ticket");
#ifdef HAVE_SESSION_TICKET
sess = ClientSessionToSession(sess);
if (sess) {
if ((sess->ticketLen > 0) && (sess->ticket != NULL)) {
return WOLFSSL_SUCCESS;
@ -32764,6 +32996,7 @@ unsigned long wolfSSL_SESSION_get_ticket_lifetime_hint(
const WOLFSSL_SESSION* sess)
{
WOLFSSL_ENTER("wolfSSL_SESSION_get_ticket_lifetime_hint");
sess = ClientSessionToSession(sess);
if (sess) {
return sess->timeout;
}
@ -32774,6 +33007,7 @@ long wolfSSL_SESSION_get_timeout(const WOLFSSL_SESSION* sess)
{
long timeout = 0;
WOLFSSL_ENTER("wolfSSL_SESSION_get_timeout");
sess = ClientSessionToSession(sess);
if (sess)
timeout = sess->timeout;
return timeout;
@ -32784,6 +33018,7 @@ long wolfSSL_SESSION_get_time(const WOLFSSL_SESSION* sess)
{
long bornOn = 0;
WOLFSSL_ENTER("wolfSSL_SESSION_get_time");
sess = ClientSessionToSession(sess);
if (sess)
bornOn = sess->bornOn;
return bornOn;
@ -32793,6 +33028,7 @@ long wolfSSL_SSL_SESSION_set_timeout(WOLFSSL_SESSION* ses, long t)
{
word32 tmptime;
ses = ClientSessionToSession(ses);
if (ses == NULL || t < 0) {
return BAD_FUNC_ARG;
}
@ -40544,9 +40780,6 @@ int wolfSSL_i2d_ECDSA_SIG(const WOLFSSL_ECDSA_SIG *sig, unsigned char **pp)
}
/* End ECDSA_SIG */
/* Remove this prototype when code is reorganized. */
static int wolfSSL_RAND_Init(void);
/* Start ECDH */
/* return code compliant with OpenSSL :
* length of computed key if success, -1 if error
@ -42953,6 +43186,7 @@ WOLFSSL_ABI
const byte* wolfSSL_get_sessionID(const WOLFSSL_SESSION* session)
{
WOLFSSL_ENTER("wolfSSL_get_sessionID");
session = ClientSessionToSession(session);
if (session)
return session->sessionID;
@ -48550,6 +48784,7 @@ 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);
#else
@ -48568,6 +48803,7 @@ int wolfSSL_SESSION_set_ex_data_with_cleanup(
wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
{
WOLFSSL_ENTER("wolfSSL_SESSION_set_ex_data_with_cleanup");
session = ClientSessionToSession(session);
if(session != NULL) {
return wolfSSL_CRYPTO_set_ex_data_with_cleanup(&session->ex_data, idx,
data, cleanup_routine);
@ -48580,6 +48816,7 @@ void* wolfSSL_SESSION_get_ex_data(const WOLFSSL_SESSION* session, int idx)
{
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);
}
@ -49596,6 +49833,7 @@ const byte* wolfSSL_SESSION_get_id(const WOLFSSL_SESSION* sess,
unsigned int* idLen)
{
WOLFSSL_ENTER("wolfSSL_SESSION_get_id");
sess = ClientSessionToSession(sess);
if (sess == NULL || idLen == NULL) {
WOLFSSL_MSG("Bad func args. Please provide idLen");
return NULL;
@ -49614,6 +49852,7 @@ const byte* wolfSSL_SESSION_get_id(const WOLFSSL_SESSION* sess,
/* returns a pointer to the protocol used by the session */
static const char* wolfSSL_SESSION_get_protocol(const WOLFSSL_SESSION* in)
{
in = ClientSessionToSession(in);
return wolfSSL_internal_get_version((ProtocolVersion*)&in->version);
}
#endif
@ -49621,6 +49860,7 @@ static const char* wolfSSL_SESSION_get_protocol(const WOLFSSL_SESSION* in)
/* returns true (non 0) if the session has EMS (extended master secret) */
static int wolfSSL_SESSION_haveEMS(const WOLFSSL_SESSION* in)
{
in = ClientSessionToSession(in);
if (in == NULL)
return 0;
return in->haveEMS;
@ -49638,6 +49878,7 @@ static int wolfSSL_SESSION_print_ticket(WOLFSSL_BIO* bio,
byte* pt;
in = ClientSessionToSession(in);
if (in == NULL || bio == NULL) {
return BAD_FUNC_ARG;
}
@ -49709,6 +49950,7 @@ int wolfSSL_SESSION_print(WOLFSSL_BIO *bp, const WOLFSSL_SESSION *session)
unsigned int sz = 0, i;
int ret;
session = ClientSessionToSession(session);
if (session == NULL) {
return WOLFSSL_FAILURE;
}
@ -51129,6 +51371,7 @@ int wolfSSL_SSL_CTX_remove_session(WOLFSSL_CTX *ctx, WOLFSSL_SESSION *s)
{
WOLFSSL_ENTER("wolfSSL_SSL_CTX_remove_session");
s = ClientSessionToSession(s);
if (ctx == NULL || s == NULL)
return BAD_FUNC_ARG;
@ -51237,7 +51480,7 @@ WOLFSSL_SESSION *wolfSSL_SSL_get0_session(const WOLFSSL *ssl)
{
WOLFSSL_ENTER("wolfSSL_SSL_get0_session");
return wolfSSL_get_session((WOLFSSL*)ssl);
return ssl->session;
}
#endif /* NO_SESSION_CACHE */
@ -57569,6 +57812,7 @@ int wolfSSL_CTX_get_security_level(const WOLFSSL_CTX* ctx)
*/
int wolfSSL_SESSION_is_resumable(const WOLFSSL_SESSION *s)
{
s = ClientSessionToSession(s);
if (s == NULL)
return 0;
@ -60743,7 +60987,7 @@ static int wolfSSL_RAND_InitMutex(void)
*
* Returns WOLFSSL_SUCCESS when no error is encountered.
*/
static int wolfSSL_RAND_Init(void)
int wolfSSL_RAND_Init(void)
{
int ret = WOLFSSL_FAILURE;
#ifdef HAVE_GLOBAL_RNG

View File

@ -3255,7 +3255,7 @@ int SendTls13ClientHello(WOLFSSL* ssl)
#endif
ret = SendBuffered(ssl);
break;
break;
}
default:
ret = INPUT_CASE_ERROR;

View File

@ -6255,7 +6255,17 @@ static void test_wolfSSL_CTX_add_session_on_result(WOLFSSL* ssl)
else
sess = &test_wolfSSL_CTX_add_session_client_sess;
if (*sess == NULL) {
#ifdef NO_SESSION_CACHE_REF
AssertNotNull(*sess = wolfSSL_get1_session(ssl));
#else
/* Test for backwards compatibility */
if (wolfSSL_is_server(ssl)) {
AssertNotNull(*sess = wolfSSL_get1_session(ssl));
}
else {
AssertNotNull(*sess = wolfSSL_get_session(ssl));
}
#endif
/* Now save the session in the internal store to make it available
* for lookup. For TLS 1.3, we can't save the session without
* WOLFSSL_TICKET_HAVE_ID because there is no way to retrieve the
@ -6294,6 +6304,8 @@ static void test_wolfSSL_CTX_add_session_on_result(WOLFSSL* ssl)
WOLFSSL_X509* peer = wolfSSL_get_peer_certificate(ssl);
AssertNotNull(peer);
wolfSSL_X509_free(peer);
AssertNotNull(wolfSSL_SESSION_get_peer_chain(*sess));
AssertNotNull(wolfSSL_SESSION_get0_peer(*sess));
}
#endif
}

View File

@ -1682,6 +1682,8 @@ typedef WOLFSSL_BUFFER_INFO buffer;
typedef struct Suites Suites;
/* Declare opaque struct for API to use */
typedef struct ClientSession ClientSession;
/* defaults to client */
WOLFSSL_LOCAL void InitSSL_Method(WOLFSSL_METHOD* method, ProtocolVersion pv);
@ -3296,12 +3298,6 @@ struct WOLFSSL_X509_CHAIN {
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 */
@ -3409,12 +3405,23 @@ struct WOLFSSL_SESSION {
#endif
};
WOLFSSL_LOCAL int wolfSSL_RAND_Init(void);
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);
#ifndef NO_CLIENT_CACHE
WOLFSSL_LOCAL ClientSession* AddSessionToClientCache(int side, int row, int idx,
byte* serverID, word16 idLen, const byte* sessionID,
word16 useTicket);
#endif
WOLFSSL_LOCAL
WOLFSSL_SESSION* ClientSessionToSession(const WOLFSSL_SESSION* session);
WOLFSSL_LOCAL int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output);
WOLFSSL_LOCAL WOLFSSL_SESSION* wolfSSL_GetSessionRef(WOLFSSL* ssl);
WOLFSSL_LOCAL int wolfSSL_SetSession(WOLFSSL* ssl, WOLFSSL_SESSION* session);
WOLFSSL_LOCAL void wolfSSL_FreeSession(WOLFSSL_SESSION* session);
WOLFSSL_LOCAL int wolfSSL_DupSession(const WOLFSSL_SESSION* input,
@ -4244,6 +4251,9 @@ struct WOLFSSL {
Ciphers decrypt;
Buffers buffers;
WOLFSSL_SESSION* session;
#ifndef NO_CLIENT_CACHE
ClientSession* clientSession;
#endif
WOLFSSL_ALERT_HISTORY alert_history;
int error;
int rfd; /* read file descriptor */
@ -4767,11 +4777,6 @@ WOLFSSL_LOCAL const char* AlertTypeToString(int type);
WOLFSSL_LOCAL int SetCipherSpecs(WOLFSSL* ssl);
WOLFSSL_LOCAL int MakeMasterSecret(WOLFSSL* ssl);
WOLFSSL_LOCAL int AddSession(WOLFSSL* ssl);
WOLFSSL_LOCAL int AddSessionToCache(WOLFSSL_SESSION* addSession, const byte* id,
byte idSz, int* sessionIndex, int side, word16 useTicket);
WOLFSSL_LOCAL int AddSessionToClientCache(int side, int row, int idx,
byte* serverID, word16 idLen, word16 useTicket);
WOLFSSL_LOCAL int DeriveKeys(WOLFSSL* ssl);
WOLFSSL_LOCAL int StoreKeys(WOLFSSL* ssl, const byte* keyData, int side);