Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4569,6 +4569,7 @@ include(GNUInstallDirs)

set(HEADER_EXCLUDE
"internal.h"
"ssl_sess.h"
"wolfssl/wolfcrypt/port/nrf51.h"
"wolfssl/wolfcrypt/port/arm"
"wolfssl/wolfcrypt/port/cypress"
Expand Down
221 changes: 57 additions & 164 deletions src/ssl_sess.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,85 +28,7 @@
#else

#ifndef NO_SESSION_CACHE

/* basic config gives a cache with 33 sessions, adequate for clients and
embedded servers

TITAN_SESSION_CACHE allows just over 2 million sessions, for servers
with titanic amounts of memory with long session ID timeouts and high
levels of traffic.

ENABLE_SESSION_CACHE_ROW_LOCK: Allows row level locking for increased
performance with large session caches

HUGE_SESSION_CACHE yields 65,791 sessions, for servers under heavy load,
allows over 13,000 new sessions per minute or over 200 new sessions per
second

BIG_SESSION_CACHE yields 20,027 sessions

MEDIUM_SESSION_CACHE allows 1055 sessions, adequate for servers that
aren't under heavy load, basically allows 200 new sessions per minute

SMALL_SESSION_CACHE only stores 6 sessions, good for embedded clients
or systems where the default of is too much RAM.
SessionCache takes about 2K, ClientCache takes about 3Kbytes

MICRO_SESSION_CACHE only stores 1 session, good for embedded clients
or systems where memory is at a premium.
SessionCache takes about 400 bytes, ClientCache takes 576 bytes

default SESSION_CACHE stores 33 sessions (no XXX_SESSION_CACHE defined)
SessionCache takes about 13K bytes, ClientCache takes 17K bytes
*/
#if defined(TITAN_SESSION_CACHE)
#define SESSIONS_PER_ROW 31
#define SESSION_ROWS 64937
#ifndef ENABLE_SESSION_CACHE_ROW_LOCK
#define ENABLE_SESSION_CACHE_ROW_LOCK
#endif
#elif defined(HUGE_SESSION_CACHE)
#define SESSIONS_PER_ROW 11
#define SESSION_ROWS 5981
#elif defined(BIG_SESSION_CACHE)
#define SESSIONS_PER_ROW 7
#define SESSION_ROWS 2861
#elif defined(MEDIUM_SESSION_CACHE)
#define SESSIONS_PER_ROW 5
#define SESSION_ROWS 211
#elif defined(SMALL_SESSION_CACHE)
#define SESSIONS_PER_ROW 2
#define SESSION_ROWS 3
#elif defined(MICRO_SESSION_CACHE)
#define SESSIONS_PER_ROW 1
#define SESSION_ROWS 1
#else
#define SESSIONS_PER_ROW 3
#define SESSION_ROWS 11
#endif
#define INVALID_SESSION_ROW (-1)

#ifdef NO_SESSION_CACHE_ROW_LOCK
#undef ENABLE_SESSION_CACHE_ROW_LOCK
#endif

typedef struct SessionRow {
int nextIdx; /* where to place next one */
int totalCount; /* sessions ever on this row */
#ifdef SESSION_CACHE_DYNAMIC_MEM
WOLFSSL_SESSION* Sessions[SESSIONS_PER_ROW];
void* heap;
#else
WOLFSSL_SESSION Sessions[SESSIONS_PER_ROW];
#endif

#ifdef ENABLE_SESSION_CACHE_ROW_LOCK
/* not included in import/export */
wolfSSL_RwLock row_lock;
int lock_valid;
#endif
} SessionRow;
#define SIZEOF_SESSION_ROW (sizeof(WOLFSSL_SESSION) + (sizeof(int) * 2))
#include <wolfssl/ssl_sess.h>

static WC_THREADSHARED SessionRow SessionCache[SESSION_ROWS];

Expand All @@ -127,54 +49,13 @@
#endif

#if !defined(NO_SESSION_CACHE_REF) && defined(NO_CLIENT_CACHE)
#error ClientCache is required when not using NO_SESSION_CACHE_REF
#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
* the 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

struct ClientSession {
word16 serverRow; /* SessionCache Row id */
word16 serverIdx; /* SessionCache Idx (column) */
word32 sessionIDHash;
};
#ifndef WOLFSSL_CLIENT_SESSION_DEFINED
typedef struct ClientSession ClientSession;
#define WOLFSSL_CLIENT_SESSION_DEFINED
#endif

typedef struct ClientRow {
int nextIdx; /* where to place next one */
int totalCount; /* sessions ever on this row */
ClientSession Clients[CLIENT_SESSIONS_PER_ROW];
} ClientRow;

static WC_THREADSHARED ClientRow ClientCache[CLIENT_SESSION_ROWS];
/* Client Cache */
/* uses session mutex */

/* ClientCache mutex */
static WC_THREADSHARED wolfSSL_Mutex clisession_mutex
WOLFSSL_MUTEX_INITIALIZER_CLAUSE(clisession_mutex);
Expand Down Expand Up @@ -392,28 +273,6 @@ int wolfSSL_SetServerID(WOLFSSL* ssl, const byte* id, int len, int newSession)
*/
#if defined(PERSIST_SESSION_CACHE) && !defined(SESSION_CACHE_DYNAMIC_MEM)

/* for persistence, if changes to layout need to increment and modify
save_session_cache() and restore_session_cache and memory versions too */
#define WOLFSSL_CACHE_VERSION 2

/* Session Cache Header information */
typedef struct {
int version; /* cache layout version id */
int rows; /* session rows */
int columns; /* session columns */
int sessionSz; /* sizeof WOLFSSL_SESSION */
} cache_header_t;

/* current persistence layout is:

1) cache_header_t
2) SessionCache
3) ClientCache

update WOLFSSL_CACHE_VERSION if change layout for the following
PERSISTENT_SESSION_CACHE functions
*/

/* get how big the the session cache save buffer needs to be */
int wolfSSL_get_session_cache_memsize(void)
{
Expand All @@ -424,7 +283,6 @@ int wolfSSL_get_session_cache_memsize(void)
return sz;
}


/* Persist session cache to memory */
int wolfSSL_memsave_session_cache(void* mem, int sz)
{
Expand Down Expand Up @@ -465,7 +323,7 @@ int wolfSSL_memsave_session_cache(void* mem, int sz)
}
#endif

XMEMCPY(row++, &SessionCache[i], SIZEOF_SESSION_ROW);
XMEMCPY(row++, &SessionCache[i], SIZEOF_SESSION_ROW_SAVE);
#ifdef ENABLE_SESSION_CACHE_ROW_LOCK
SESSION_ROW_UNLOCK(&SessionCache[i]);
#endif
Expand All @@ -490,36 +348,54 @@ int wolfSSL_memsave_session_cache(void* mem, int sz)


#if !defined(SESSION_CACHE_DYNAMIC_MEM) && \
(defined(HAVE_SESSION_TICKET) || \
(defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)))
(defined(PERSIST_SESSION_CACHE) || \
defined(HAVE_SESSION_TICKET) || \
(defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)) || \
defined(HAVE_EXT_CACHE) || defined(HAVE_EX_DATA))
static void SessionSanityPointerSet(SessionRow* row)
{
int j;

/* Reset pointers to safe values after raw copy */
for (j = 0; j < SESSIONS_PER_ROW; j++) {
WOLFSSL_SESSION* s = &row->Sessions[j];
#ifdef HAVE_SESSION_TICKET
s->type = WOLFSSL_SESSION_TYPE_CACHE;
#ifdef HAVE_SESSION_TICKET
s->ticket = s->staticTicket;
s->ticketLenAlloc = 0;
if (s->ticketLen > SESSION_TICKET_LEN) {
s->ticketLen = SESSION_TICKET_LEN;
}
#endif
#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET) && \
defined(WOLFSSL_TICKET_NONCE_MALLOC) && \
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
#endif /* HAVE_SESSION_TICKET */
#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET) && \
defined(WOLFSSL_TICKET_NONCE_MALLOC) && \
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && \
FIPS_VERSION_GE(5,3)))
s->ticketNonce.data = s->ticketNonce.dataStatic;
if (s->ticketNonce.len > MAX_TICKET_NONCE_STATIC_SZ) {
s->ticketNonce.len = MAX_TICKET_NONCE_STATIC_SZ;
}
#endif
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
#endif /* WOLFSSL_TLS13 && HAVE_SESSION_TICKET && etc. */
/* Sanitize the restored session: none of the following fields are
* meaningful after session restoration.
*
* We could null these instead in wolfSSL_[mem]save_session_cache(),
* but that would require an extra scratch copy (because we save from
* the live session). */
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
s->peer = NULL;
#endif
#endif /* SESSION_CERTS || OPENSSL_EXTRA */
Comment on lines +385 to +387
#if defined(HAVE_EXT_CACHE) || defined(HAVE_EX_DATA)
s->rem_sess_cb = NULL;
#endif /* HAVE_EXT_CACHE || HAVE_EX_DATA */
s->heap = NULL;
#ifdef HAVE_EX_DATA
XMEMSET(&s->ex_data, 0, sizeof(WOLFSSL_CRYPTO_EX_DATA));
s->ownExData = 0;
#endif /* HAVE_EX_DATA */
}
}
#endif
#endif /* !SESSION_CACHE_DYNAMIC_MEM && (HAVE_SESSION_TICKET || etc. ) */

/* Restore the persistent session cache from memory */
int wolfSSL_memrestore_session_cache(const void* mem, int sz)
Expand Down Expand Up @@ -565,10 +441,12 @@ int wolfSSL_memrestore_session_cache(const void* mem, int sz)
}
#endif

XMEMCPY(&SessionCache[i], row++, SIZEOF_SESSION_ROW);
XMEMCPY(&SessionCache[i], row++, SIZEOF_SESSION_ROW_RESTORE);
#if !defined(SESSION_CACHE_DYNAMIC_MEM) && \
(defined(HAVE_SESSION_TICKET) || \
(defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)))
(defined(PERSIST_SESSION_CACHE) || \
defined(HAVE_SESSION_TICKET) || \
(defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)) || \
defined(HAVE_EXT_CACHE) || defined(HAVE_EX_DATA))
SessionSanityPointerSet(&SessionCache[i]);
#endif
#ifdef ENABLE_SESSION_CACHE_ROW_LOCK
Expand Down Expand Up @@ -642,7 +520,7 @@ int wolfSSL_save_session_cache(const char *fname)
}
#endif

ret = (int)XFWRITE(&SessionCache[i], SIZEOF_SESSION_ROW, 1, file);
ret = (int)XFWRITE(&SessionCache[i], SIZEOF_SESSION_ROW_SAVE, 1, file);
#ifdef ENABLE_SESSION_CACHE_ROW_LOCK
SESSION_ROW_UNLOCK(&SessionCache[i]);
#endif
Expand Down Expand Up @@ -729,10 +607,12 @@ int wolfSSL_restore_session_cache(const char *fname)
}
#endif

ret = (int)XFREAD(&SessionCache[i], SIZEOF_SESSION_ROW, 1, file);
ret = (int)XFREAD(&SessionCache[i], SIZEOF_SESSION_ROW_RESTORE, 1, file);
#if !defined(SESSION_CACHE_DYNAMIC_MEM) && \
(defined(HAVE_SESSION_TICKET) || \
(defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)))
(defined(PERSIST_SESSION_CACHE) || \
defined(HAVE_SESSION_TICKET) || \
(defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)) || \
defined(HAVE_EXT_CACHE) || defined(HAVE_EX_DATA))
SessionSanityPointerSet(&SessionCache[i]);
#endif
#ifdef ENABLE_SESSION_CACHE_ROW_LOCK
Expand All @@ -744,6 +624,20 @@ int wolfSSL_restore_session_cache(const char *fname)
rc = FREAD_ERROR;
break;
}
#ifdef ENABLE_SESSION_CACHE_ROW_LOCK
/* the file read did not include the row lock members. seek to next
* read offset. */
if (i < cache_header.rows) {
ret = (int)XFSEEK(file, sizeof(cache_header) +
(i + 1) * sizeof(SessionRow), XSEEK_SET);
if (ret) {
WOLFSSL_MSG_EX("Session cache file seek(%d * %zu) failed",
i + 1, sizeof(SessionRow));
rc = FREAD_ERROR;
break;
}
}
#endif
}
#ifndef ENABLE_SESSION_CACHE_ROW_LOCK
SESSION_ROW_UNLOCK(&SessionCache[0]);
Expand Down Expand Up @@ -774,7 +668,6 @@ int wolfSSL_restore_session_cache(const char *fname)
#endif /* !NO_FILESYSTEM */
#endif /* PERSIST_SESSION_CACHE && !SESSION_CACHE_DYNAMIC_MEM */


/* on by default if built in but allow user to turn off */
WOLFSSL_ABI
long wolfSSL_CTX_set_session_cache_mode(WOLFSSL_CTX* ctx, long mode)
Expand Down
Loading
Loading