mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-30 02:37:28 +02:00
TLS v1.3: Support a stateful ticket and test HAVE_EXT_CACHE (#5960)
* Add TLSv1.3 stateful support Fix internal and external session cache * session cache fixes * Refactor - implement wolfSSL_CTX_flush_sessions - use wolfSSL_CTX_flush_sessions to make test_wolfSSL_CTX_add_session_ext deterministic - add dtls to test_wolfSSL_CTX_add_session_ext - DoClientTicket_ex does not modify ssl object - only call session remove callback on: - timeout - session is being overwritten/removed from the cache * Session fixes - restore bogus ID on session duplicate - don't evict on overwrite - use memmove instead on memcpy as `ssl->session == session` is possible - ignore ClientSession parameter in AddSessionToCache on NO_SESSION_CACHE_REF - use sessionID when altSessionID not present * Session fixes - DoClientTicketFinalize: always copy in the ID as teh altSessionID - don't overwrite ex_data when overwriting cacheSession and cacheSession owns it * Callback wants to retain a copy * wolfSSL_GetSessionClient: ssl->ctx->get_sess_cb does not apply here * test_wolfSSL_CTX_add_session_ext gate expected results on WOLFSSL_DTLS_NO_HVR_ON_RESUME * TlsSessionIdIsValid: copy return can't be ignored * Silence unused parameter * test_wolfSSL_CTX_add_session_ext: handle async case * Gate wolfSSL_SSL_CTX_remove_session on NO_SESSION_CACHE * ssl.c: style fixes * Add twcase_get_sessionCb_cleanup to free external cache * Remove hard tab * Correct build error in wolfSSL_CTX_flush_sessions * Jenkins fixes: - altSessionID only available with WOLFSSL_TICKET_HAVE_ID - slim out psk_sess_free_cb_ctx * Stateful dtls case has 2 accesses. Stateless just one. * Add version numbering to hostap logs * Import internal.h for test_wolfSSL_SESSION_get_ex_new_index * wolfSSL_SetSession: don't check SslSessionCacheOff for session setting * wolfSSL_SetSession: fully set expired session for OpenSSL compatibility * wolfSSL_SetSession: check if setting same object * AddSession: always populate the session object to allow re-use * Add logging to wolfSSL_NewSession and wolfSSL_FreeSession * Always setup session object * Check if session has been setup before setting it * Print errors in async test * Make SetupSession available outside NO_SESSION_CACHE * Review comments * Fix ticBuf leak and TlsSessionIdIsValid logic * Fix unmatched curly brackets * TlsSessionIdIsValid: always need to check copy var * TlsResumptionIsValid: set resume to FALSE default * wolfSSL_SetSession: remove now variable since only used in one place * Move internalCacheLookupOff into HAVE_EXT_CACHE block --------- Co-authored-by: Juliusz Sosinowicz <juliusz@wolfssl.com>
This commit is contained in:
6
.github/workflows/async.yml
vendored
6
.github/workflows/async.yml
vendored
@ -23,3 +23,9 @@ jobs:
|
||||
./configure ${{ matrix.config }}
|
||||
make check
|
||||
|
||||
- name: Print errors
|
||||
if: ${{ failure() }}
|
||||
run: |
|
||||
if [ -f test-suite.log ] ; then
|
||||
cat test-suite.log
|
||||
fi
|
||||
|
11
.github/workflows/hostap.yml
vendored
11
.github/workflows/hostap.yml
vendored
@ -99,6 +99,15 @@ jobs:
|
||||
${{ toJSON(matrix) }}
|
||||
EOF
|
||||
|
||||
- name: Print computed job run ID
|
||||
run: |
|
||||
SHA_SUM=$(sha256sum << 'END_OF_HEREDOC' | cut -d " " -f 1
|
||||
${{ toJSON(github) }}
|
||||
END_OF_HEREDOC
|
||||
)
|
||||
echo "our_job_run_id=$SHA_SUM" >> $GITHUB_ENV
|
||||
echo Our job run ID is $SHA_SUM
|
||||
|
||||
- name: Checkout wolfSSL
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
@ -264,7 +273,7 @@ jobs:
|
||||
if: ${{ failure() && steps.testing.outcome == 'failure' }}
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: hostap-logs
|
||||
name: hostap-logs-${{ env.our_job_run_id }}
|
||||
path: hostap/tests/hwsim/logs.zip
|
||||
retention-days: 5
|
||||
|
||||
|
4
.github/workflows/os-check.yml
vendored
4
.github/workflows/os-check.yml
vendored
@ -15,6 +15,10 @@ jobs:
|
||||
'--enable-all --enable-asn=template',
|
||||
'--enable-all --enable-asn=original',
|
||||
'--enable-harden-tls',
|
||||
'--enable-tls13 --enable-session-ticket --enable-dtls --enable-dtls13
|
||||
--enable-opensslextra --enable-sessioncerts
|
||||
CPPFLAGS=''-DWOLFSSL_DTLS_NO_HVR_ON_RESUME -DHAVE_EXT_CACHE
|
||||
-DWOLFSSL_TICKET_HAVE_ID -DHAVE_EX_DATA -DSESSION_CACHE_DYNAMIC_MEM'' ',
|
||||
]
|
||||
name: make check
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
59
src/dtls.c
59
src/dtls.c
@ -335,6 +335,8 @@ static int TlsTicketIsValid(const WOLFSSL* ssl, WolfSSL_ConstVector exts,
|
||||
int ret = 0;
|
||||
int tlsxFound;
|
||||
|
||||
*resume = FALSE;
|
||||
|
||||
ret = FindExtByType(&tlsxSessionTicket, TLSX_SESSION_TICKET, exts,
|
||||
&tlsxFound);
|
||||
if (ret != 0)
|
||||
@ -359,42 +361,45 @@ static int TlsTicketIsValid(const WOLFSSL* ssl, WolfSSL_ConstVector exts,
|
||||
static int TlsSessionIdIsValid(const WOLFSSL* ssl, WolfSSL_ConstVector sessionID,
|
||||
int* resume)
|
||||
{
|
||||
WOLFSSL_SESSION* sess;
|
||||
const WOLFSSL_SESSION* sess;
|
||||
word32 sessRow;
|
||||
int ret;
|
||||
#ifdef HAVE_EXT_CACHE
|
||||
int copy;
|
||||
#endif
|
||||
*resume = FALSE;
|
||||
|
||||
if (ssl->options.sessionCacheOff)
|
||||
return 0;
|
||||
if (sessionID.size != ID_LEN)
|
||||
return 0;
|
||||
#ifdef HAVE_EXT_CACHE
|
||||
{
|
||||
|
||||
if (ssl->ctx->get_sess_cb != NULL) {
|
||||
int unused;
|
||||
sess =
|
||||
ssl->ctx->get_sess_cb((WOLFSSL*)ssl, sessionID.elements, ID_LEN,
|
||||
&unused);
|
||||
if (sess != NULL) {
|
||||
#ifdef HAVE_EXT_CACHE
|
||||
if (ssl->ctx->get_sess_cb != NULL) {
|
||||
WOLFSSL_SESSION* extSess =
|
||||
ssl->ctx->get_sess_cb((WOLFSSL*)ssl, sessionID.elements, ID_LEN,
|
||||
©);
|
||||
if (extSess != NULL) {
|
||||
#if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
|
||||
defined(HAVE_SESSION_TICKET))
|
||||
/* This logic is only for TLS <= 1.2 tickets. Don't accept
|
||||
* TLS 1.3. */
|
||||
if (IsAtLeastTLSv1_3(sess->version))
|
||||
wolfSSL_FreeSession(ssl->ctx, sess);
|
||||
else
|
||||
defined(HAVE_SESSION_TICKET))
|
||||
/* This logic is only for TLS <= 1.2 tickets. Don't accept
|
||||
* TLS 1.3. */
|
||||
if (!IsAtLeastTLSv1_3(extSess->version))
|
||||
#endif
|
||||
{
|
||||
*resume = 1;
|
||||
wolfSSL_FreeSession(ssl->ctx, sess);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
*resume = TRUE;
|
||||
if (!copy)
|
||||
wolfSSL_FreeSession(ssl->ctx, extSess);
|
||||
if (*resume)
|
||||
return 0;
|
||||
}
|
||||
if (ssl->ctx->internalCacheLookupOff)
|
||||
return 0;
|
||||
}
|
||||
if (ssl->ctx->internalCacheLookupOff)
|
||||
return 0;
|
||||
#endif
|
||||
ret = TlsSessionCacheGetAndLock(sessionID.elements, &sess, &sessRow, 1);
|
||||
|
||||
|
||||
ret = TlsSessionCacheGetAndRdLock(sessionID.elements, &sess, &sessRow,
|
||||
ssl->options.side);
|
||||
if (ret == 0 && sess != NULL) {
|
||||
#if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
|
||||
defined(HAVE_SESSION_TICKET))
|
||||
@ -402,9 +407,7 @@ static int TlsSessionIdIsValid(const WOLFSSL* ssl, WolfSSL_ConstVector sessionID
|
||||
* TLS 1.3. */
|
||||
if (!IsAtLeastTLSv1_3(sess->version))
|
||||
#endif
|
||||
{
|
||||
*resume = 1;
|
||||
}
|
||||
*resume = TRUE;
|
||||
TlsSessionCacheUnlockRow(sessRow);
|
||||
}
|
||||
|
||||
@ -480,7 +483,7 @@ static void FindPskSuiteFromExt(const WOLFSSL* ssl, TLSX* extensions,
|
||||
/* Decode the identity. */
|
||||
switch (current->decryptRet) {
|
||||
case PSK_DECRYPT_NONE:
|
||||
ret = DoClientTicket_ex(ssl, current);
|
||||
ret = DoClientTicket_ex(ssl, current, 0);
|
||||
break;
|
||||
case PSK_DECRYPT_OK:
|
||||
ret = WOLFSSL_TICKET_RET_OK;
|
||||
|
219
src/internal.c
219
src/internal.c
@ -21301,8 +21301,9 @@ int SendFinished(WOLFSSL* ssl)
|
||||
return BUILD_MSG_ERROR;
|
||||
|
||||
if (!ssl->options.resuming) {
|
||||
SetupSession(ssl);
|
||||
#ifndef NO_SESSION_CACHE
|
||||
AddSession(ssl); /* just try */
|
||||
AddSession(ssl);
|
||||
#endif
|
||||
if (ssl->options.side == WOLFSSL_SERVER_END) {
|
||||
#ifdef OPENSSL_EXTRA
|
||||
@ -30622,6 +30623,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
*inOutIdx += length;
|
||||
if (length > 0) {
|
||||
ssl->timeout = lifetime;
|
||||
SetupSession(ssl);
|
||||
#ifndef NO_SESSION_CACHE
|
||||
AddSession(ssl);
|
||||
#endif
|
||||
@ -34833,18 +34835,35 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
}
|
||||
#endif /* WOLFSSL_SLT13 */
|
||||
|
||||
void DoClientTicketFinalize(WOLFSSL* ssl, InternalTicket* it)
|
||||
void DoClientTicketFinalize(WOLFSSL* ssl, InternalTicket* it,
|
||||
const WOLFSSL_SESSION* sess)
|
||||
{
|
||||
#ifdef WOLFSSL_TICKET_HAVE_ID
|
||||
ssl->session->haveAltSessionID = 1;
|
||||
XMEMCPY(ssl->session->altSessionID, it->id, ID_LEN);
|
||||
if (wolfSSL_GetSession(ssl, NULL, 1) != NULL) {
|
||||
WOLFSSL_MSG("Found session matching the session id"
|
||||
" found in the ticket");
|
||||
#endif
|
||||
if (sess != NULL) {
|
||||
byte bogusID[ID_LEN];
|
||||
byte bogusIDSz = ssl->session->sessionIDSz;
|
||||
XMEMCPY(bogusID, ssl->session->sessionID, ID_LEN);
|
||||
/* Failure here should not interupt the resumption. We already have
|
||||
* all the cipher material we need in `it` */
|
||||
WOLFSSL_MSG("Copying in session from passed in arg");
|
||||
(void)wolfSSL_DupSession(sess, ssl->session, 1);
|
||||
/* Restore the fake ID */
|
||||
XMEMCPY(ssl->session->sessionID, bogusID, ID_LEN);
|
||||
ssl->session->sessionIDSz= bogusIDSz;
|
||||
}
|
||||
#ifdef WOLFSSL_TICKET_HAVE_ID
|
||||
else {
|
||||
WOLFSSL_MSG("Can't find session matching the session id"
|
||||
" found in the ticket");
|
||||
if (wolfSSL_GetSession(ssl, NULL, 1) != NULL) {
|
||||
WOLFSSL_MSG("Found session matching the session id"
|
||||
" found in the ticket");
|
||||
}
|
||||
else {
|
||||
WOLFSSL_MSG("Can't find session matching the session id"
|
||||
" found in the ticket");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -34907,18 +34926,139 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
}
|
||||
|
||||
#if defined(WOLFSSL_TLS13)
|
||||
static void PopulateInternalTicketFromSession(const WOLFSSL_SESSION* sess,
|
||||
InternalTicket* it)
|
||||
{
|
||||
#ifdef WOLFSSL_32BIT_MILLI_TIME
|
||||
word32 milliBornOn = sess->bornOn;
|
||||
#else
|
||||
sword64 milliBornOn = (sword64)sess->bornOn;
|
||||
#endif
|
||||
/* Convert to milliseconds */
|
||||
milliBornOn *= 1000;
|
||||
it->pv = sess->version;
|
||||
it->suite[0] = sess->cipherSuite0;
|
||||
it->suite[1] = sess->cipherSuite;
|
||||
XMEMCPY(it->msecret, sess->masterSecret, SECRET_LEN);
|
||||
#ifdef WOLFSSL_32BIT_MILLI_TIME
|
||||
c32toa(milliBornOn, it->timestamp);
|
||||
#else
|
||||
c32toa((word32)(milliBornOn >> 32), it->timestamp);
|
||||
c32toa((word32)milliBornOn , it->timestamp + OPAQUE32_LEN);
|
||||
#endif
|
||||
it->haveEMS = (byte)sess->haveEMS;
|
||||
c32toa(sess->ticketAdd, it->ageAdd);
|
||||
c16toa(sess->namedGroup, it->namedGroup);
|
||||
if (sess->ticketNonce.len <= MAX_TICKET_NONCE_STATIC_SZ) {
|
||||
it->ticketNonceLen = sess->ticketNonce.len;
|
||||
XMEMCPY(it->ticketNonce, sess->ticketNonce.data,
|
||||
sess->ticketNonce.len);
|
||||
}
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
c32toa(sess->maxEarlyDataSz, it->maxEarlyDataSz);
|
||||
#endif
|
||||
#ifdef WOLFSSL_TICKET_HAVE_ID
|
||||
if (sess->haveAltSessionID)
|
||||
XMEMCPY(it->id, sess->altSessionID, ID_LEN);
|
||||
else
|
||||
XMEMCPY(it->id, sess->sessionID, ID_LEN);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static const WOLFSSL_SESSION* GetSesionFromCacheOrExt(const WOLFSSL* ssl,
|
||||
const byte* id, psk_sess_free_cb_ctx* freeCtx)
|
||||
{
|
||||
const WOLFSSL_SESSION* sess = NULL;
|
||||
int ret;
|
||||
XMEMSET(freeCtx, 0, sizeof(*freeCtx));
|
||||
#ifdef HAVE_EXT_CACHE
|
||||
if (ssl->ctx->get_sess_cb != NULL) {
|
||||
int copy = 0;
|
||||
sess = ssl->ctx->get_sess_cb((WOLFSSL*)ssl,
|
||||
id, ID_LEN, ©);
|
||||
if (sess != NULL) {
|
||||
freeCtx->extCache = 1;
|
||||
/* If copy not set then free immediately */
|
||||
if (!copy)
|
||||
freeCtx->freeSess = 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (sess == NULL) {
|
||||
ret = TlsSessionCacheGetAndRdLock(id, &sess, &freeCtx->row,
|
||||
ssl->options.side);
|
||||
if (ret != 0)
|
||||
sess = NULL;
|
||||
}
|
||||
return sess;
|
||||
}
|
||||
|
||||
static void FreeSessionFromCacheOrExt(const WOLFSSL* ssl,
|
||||
const WOLFSSL_SESSION* sess, psk_sess_free_cb_ctx* freeCtx)
|
||||
{
|
||||
(void)ssl;
|
||||
(void)sess;
|
||||
#ifdef HAVE_EXT_CACHE
|
||||
if (freeCtx->extCache) {
|
||||
if (freeCtx->freeSess)
|
||||
/* In this case sess is not longer const and the external cache
|
||||
* wants us to free it. */
|
||||
wolfSSL_FreeSession(ssl->ctx, (WOLFSSL_SESSION*)sess);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
TlsSessionCacheUnlockRow(freeCtx->row);
|
||||
}
|
||||
|
||||
/* Parse ticket sent by client, returns callback return value. Doesn't
|
||||
* modify ssl and stores the InternalTicket inside psk */
|
||||
int DoClientTicket_ex(const WOLFSSL* ssl, PreSharedKey* psk)
|
||||
int DoClientTicket_ex(const WOLFSSL* ssl, PreSharedKey* psk, int retainSess)
|
||||
{
|
||||
int decryptRet;
|
||||
int ret;
|
||||
int decryptRet = WOLFSSL_TICKET_RET_REJECT;
|
||||
|
||||
WOLFSSL_START(WC_FUNC_TICKET_DO);
|
||||
WOLFSSL_ENTER("DoClientTicket_ex");
|
||||
|
||||
decryptRet = DoDecryptTicket(ssl, psk->identity, psk->identityLen,
|
||||
&psk->it);
|
||||
if (psk->identityLen == ID_LEN && IsAtLeastTLSv1_3(ssl->version)) {
|
||||
/* This is a stateful ticket. We can be sure about this because
|
||||
* stateless tickets are much longer. */
|
||||
const WOLFSSL_SESSION* sess = NULL;
|
||||
sess = GetSesionFromCacheOrExt(ssl, psk->identity,
|
||||
&psk->sess_free_cb_ctx);
|
||||
if (sess != NULL) {
|
||||
/* Session found in cache. Copy in relevant info to psk */
|
||||
byte* tmp;
|
||||
WOLFSSL_MSG("Found session matching the session id"
|
||||
" found in the ticket");
|
||||
/* Allocate and populate an InternalTicket */
|
||||
tmp = (byte*)XREALLOC(psk->identity, sizeof(InternalTicket),
|
||||
ssl->heap, DYNAMIC_TYPE_TLSX);
|
||||
if (tmp != NULL) {
|
||||
XMEMSET(tmp, 0, sizeof(InternalTicket));
|
||||
psk->identity = tmp;
|
||||
psk->identityLen = sizeof(InternalTicket);
|
||||
psk->it = (InternalTicket*)tmp;
|
||||
PopulateInternalTicketFromSession(sess, psk->it);
|
||||
decryptRet = WOLFSSL_TICKET_RET_OK;
|
||||
if (retainSess) {
|
||||
psk->sess = sess;
|
||||
psk->sess_free_cb = FreeSessionFromCacheOrExt;
|
||||
}
|
||||
}
|
||||
if (psk->sess == NULL) {
|
||||
FreeSessionFromCacheOrExt(ssl, sess,
|
||||
&psk->sess_free_cb_ctx);
|
||||
XMEMSET(&psk->sess_free_cb_ctx, 0,
|
||||
sizeof(psk_sess_free_cb_ctx));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
decryptRet = DoDecryptTicket(ssl, psk->identity, psk->identityLen,
|
||||
&psk->it);
|
||||
}
|
||||
switch (decryptRet) {
|
||||
case WOLFSSL_TICKET_RET_OK:
|
||||
psk->decryptRet = PSK_DECRYPT_OK;
|
||||
@ -34930,11 +35070,11 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
psk->decryptRet = PSK_DECRYPT_FAIL;
|
||||
return decryptRet;
|
||||
}
|
||||
#ifdef WOLFSSL_CHECK_MEM_ZERO
|
||||
#ifdef WOLFSSL_CHECK_MEM_ZERO
|
||||
/* Internal ticket successfully decrypted. */
|
||||
wc_MemZero_Add("Do Client Ticket internal", psk->it,
|
||||
sizeof(InternalTicket));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
ret = DoClientTicketCheckVersion(ssl, psk->it);
|
||||
if (ret != 0) {
|
||||
@ -34952,17 +35092,41 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
/* Parse ticket sent by client, returns callback return value */
|
||||
int DoClientTicket(WOLFSSL* ssl, const byte* input, word32 len)
|
||||
{
|
||||
int decryptRet;
|
||||
int decryptRet = WOLFSSL_TICKET_RET_REJECT;
|
||||
int ret;
|
||||
InternalTicket* it
|
||||
InternalTicket* it;
|
||||
#ifdef WOLFSSL_TLS13
|
||||
InternalTicket staticIt;
|
||||
const WOLFSSL_SESSION* sess = NULL;
|
||||
psk_sess_free_cb_ctx freeCtx;
|
||||
|
||||
XMEMSET(&freeCtx, 0, sizeof(psk_sess_free_cb_ctx));
|
||||
#endif
|
||||
|
||||
WOLFSSL_START(WC_FUNC_TICKET_DO);
|
||||
WOLFSSL_ENTER("DoClientTicket");
|
||||
|
||||
decryptRet = DoDecryptTicket(ssl, input, len, &it);
|
||||
#ifdef WOLFSSL_TLS13
|
||||
if (len == ID_LEN && IsAtLeastTLSv1_3(ssl->version)) {
|
||||
/* This is a stateful ticket. We can be sure about this because
|
||||
* stateless tickets are much longer. */
|
||||
sess = GetSesionFromCacheOrExt(ssl, input, &freeCtx);
|
||||
if (sess != NULL) {
|
||||
it = &staticIt;
|
||||
XMEMSET(it, 0, sizeof(InternalTicket));
|
||||
PopulateInternalTicketFromSession(sess, it);
|
||||
decryptRet = WOLFSSL_TICKET_RET_OK;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
decryptRet = DoDecryptTicket(ssl, input, len, &it);
|
||||
|
||||
if (decryptRet != WOLFSSL_TICKET_RET_OK &&
|
||||
decryptRet != WOLFSSL_TICKET_RET_CREATE)
|
||||
return decryptRet;
|
||||
decryptRet != WOLFSSL_TICKET_RET_CREATE) {
|
||||
it = NULL;
|
||||
goto cleanup;
|
||||
}
|
||||
#ifdef WOLFSSL_CHECK_MEM_ZERO
|
||||
/* Internal ticket successfully decrypted. */
|
||||
wc_MemZero_Add("Do Client Ticket internal", it, sizeof(InternalTicket));
|
||||
@ -34970,20 +35134,23 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
|
||||
ret = DoClientTicketCheckVersion(ssl, it);
|
||||
if (ret != 0) {
|
||||
decryptRet = ret;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
DoClientTicketFinalize(ssl, it, NULL);
|
||||
|
||||
cleanup:
|
||||
if (it != NULL) {
|
||||
ForceZero(it, sizeof(*it));
|
||||
#ifdef WOLFSSL_CHECK_MEM_ZERO
|
||||
wc_MemZero_Check(it, sizeof(InternalTicket));
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
DoClientTicketFinalize(ssl, it);
|
||||
|
||||
ForceZero(it, sizeof(*it));
|
||||
#ifdef WOLFSSL_CHECK_MEM_ZERO
|
||||
wc_MemZero_Check(it, sizeof(InternalTicket));
|
||||
#ifdef WOLFSSL_TLS13
|
||||
if (sess != NULL)
|
||||
FreeSessionFromCacheOrExt(ssl, sess, &freeCtx);
|
||||
#endif
|
||||
|
||||
return decryptRet;
|
||||
}
|
||||
|
||||
|
@ -3418,6 +3418,7 @@ static int ProcessSessionTicket(const byte* input, int* sslBytes,
|
||||
WOLFSSL_SESSION* sess = wolfSSL_GetSession(session->sslServer,
|
||||
NULL, 0);
|
||||
if (sess == NULL) {
|
||||
SetupSession(session->sslServer);
|
||||
AddSession(session->sslServer); /* don't re add */
|
||||
#ifdef WOLFSSL_SNIFFER_STATS
|
||||
INC_STAT(SnifferStats.sslResumptionInserts);
|
||||
@ -4345,6 +4346,7 @@ static int ProcessFinished(const byte* input, int size, int* sslBytes,
|
||||
#ifndef NO_SESSION_CACHE
|
||||
WOLFSSL_SESSION* sess = wolfSSL_GetSession(session->sslServer, NULL, 0);
|
||||
if (sess == NULL) {
|
||||
SetupSession(session->sslServer);
|
||||
AddSession(session->sslServer); /* don't re add */
|
||||
#ifdef WOLFSSL_SNIFFER_STATS
|
||||
INC_STAT(SnifferStats.sslResumptionInserts);
|
||||
|
562
src/ssl.c
562
src/ssl.c
@ -6336,6 +6336,35 @@ int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify)
|
||||
static WOLFSSL_GLOBAL int clisession_mutex_valid = 0;
|
||||
#endif /* !NO_CLIENT_CACHE */
|
||||
|
||||
void EvictSessionFromCache(WOLFSSL_SESSION* session)
|
||||
{
|
||||
#ifdef HAVE_EX_DATA
|
||||
int save_ownExData = session->ownExData;
|
||||
session->ownExData = 1; /* Make sure ex_data access doesn't lead back
|
||||
* into the cache. */
|
||||
#endif
|
||||
#if defined(HAVE_EXT_CACHE) || defined(HAVE_EX_DATA)
|
||||
if (session->rem_sess_cb != NULL) {
|
||||
session->rem_sess_cb(NULL, session);
|
||||
session->rem_sess_cb = NULL;
|
||||
}
|
||||
#endif
|
||||
ForceZero(session->masterSecret, SECRET_LEN);
|
||||
XMEMSET(session->sessionID, 0, ID_LEN);
|
||||
session->sessionIDSz = 0;
|
||||
#ifdef HAVE_SESSION_TICKET
|
||||
if (session->ticketLenAlloc > 0) {
|
||||
XFREE(session->ticket, NULL, DYNAMIC_TYPE_SESSION_TICK);
|
||||
session->ticket = session->staticTicket;
|
||||
session->ticketLen = 0;
|
||||
session->ticketLenAlloc = 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_EX_DATA
|
||||
session->ownExData = save_ownExData;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* !NO_SESSION_CACHE */
|
||||
|
||||
#if defined(OPENSSL_EXTRA) && !defined(WOLFSSL_NO_OPENSSL_RAND_CB)
|
||||
@ -14446,6 +14475,47 @@ int wolfSSL_Cleanup(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void SetupSession(WOLFSSL* ssl)
|
||||
{
|
||||
WOLFSSL_SESSION* session = ssl->session;
|
||||
|
||||
WOLFSSL_ENTER("SetupSession");
|
||||
|
||||
if (!IsAtLeastTLSv1_3(ssl->version) && ssl->arrays != NULL &&
|
||||
!session->haveAltSessionID) {
|
||||
/* Make sure the session ID is available when the user calls any
|
||||
* get_session API */
|
||||
XMEMCPY(session->sessionID, ssl->arrays->sessionID, ID_LEN);
|
||||
session->sessionIDSz = ssl->arrays->sessionIDSz;
|
||||
}
|
||||
session->side = (byte)ssl->options.side;
|
||||
if (!IsAtLeastTLSv1_3(ssl->version) && ssl->arrays != NULL)
|
||||
XMEMCPY(session->masterSecret, ssl->arrays->masterSecret, SECRET_LEN);
|
||||
session->haveEMS = ssl->options.haveEMS;
|
||||
#ifdef OPENSSL_EXTRA
|
||||
/* If using compatibility layer then check for and copy over session context
|
||||
* id. */
|
||||
if (ssl->sessionCtxSz > 0 && ssl->sessionCtxSz < ID_LEN) {
|
||||
XMEMCPY(ssl->session->sessionCtx, ssl->sessionCtx, ssl->sessionCtxSz);
|
||||
session->sessionCtxSz = ssl->sessionCtxSz;
|
||||
}
|
||||
#endif
|
||||
session->timeout = ssl->timeout;
|
||||
session->bornOn = LowResTimer();
|
||||
#if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
|
||||
defined(HAVE_SESSION_TICKET))
|
||||
session->version = ssl->version;
|
||||
#endif
|
||||
#if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \
|
||||
(defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET))
|
||||
session->cipherSuite0 = ssl->options.cipherSuite0;
|
||||
session->cipherSuite = ssl->options.cipherSuite;
|
||||
#endif
|
||||
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
|
||||
session->peerVerifyRet = (byte)ssl->peerVerifyRet;
|
||||
#endif
|
||||
session->isSetup = 1;
|
||||
}
|
||||
|
||||
#ifndef NO_SESSION_CACHE
|
||||
|
||||
@ -14457,6 +14527,44 @@ void wolfSSL_flush_sessions(WOLFSSL_CTX* ctx, long tm)
|
||||
(void)tm;
|
||||
}
|
||||
|
||||
void wolfSSL_CTX_flush_sessions(WOLFSSL_CTX* ctx, long tm)
|
||||
{
|
||||
int i, j;
|
||||
byte id[ID_LEN];
|
||||
|
||||
(void)ctx;
|
||||
XMEMSET(id, 0, ID_LEN);
|
||||
WOLFSSL_ENTER("wolfSSL_flush_sessions");
|
||||
for (i = 0; i < SESSION_ROWS; ++i) {
|
||||
if (SESSION_ROW_WR_LOCK(&SessionCache[i]) != 0) {
|
||||
WOLFSSL_MSG("Session cache mutex lock failed");
|
||||
return;
|
||||
}
|
||||
for (j = 0; j < SESSIONS_PER_ROW; j++) {
|
||||
#ifdef SESSION_CACHE_DYNAMIC_MEM
|
||||
WOLFSSL_SESSION* s = SessionCache[i].Sessions[j];
|
||||
#else
|
||||
WOLFSSL_SESSION* s = &SessionCache[i].Sessions[j];
|
||||
#endif
|
||||
if (
|
||||
#ifdef SESSION_CACHE_DYNAMIC_MEM
|
||||
s != NULL &&
|
||||
#endif
|
||||
XMEMCMP(s->sessionID, id, ID_LEN) != 0 &&
|
||||
s->bornOn + s->timeout < (word32)tm
|
||||
)
|
||||
{
|
||||
EvictSessionFromCache(s);
|
||||
#ifdef SESSION_CACHE_DYNAMIC_MEM
|
||||
XFREE(s, s->heap, DYNAMIC_TYPE_SESSION);
|
||||
SessionCache[i].Sessions[j] = NULL;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
SESSION_ROW_UNLOCK(&SessionCache[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* set ssl session timeout in seconds */
|
||||
WOLFSSL_ABI
|
||||
@ -14559,23 +14667,8 @@ WOLFSSL_SESSION* wolfSSL_GetSessionClient(WOLFSSL* ssl, const byte* id, int len)
|
||||
|
||||
len = min(SERVER_ID_LEN, (word32)len);
|
||||
|
||||
#ifdef HAVE_EXT_CACHE
|
||||
if (ssl->ctx->get_sess_cb != NULL) {
|
||||
int copy = 0;
|
||||
WOLFSSL_MSG("Calling external session cache");
|
||||
ret = ssl->ctx->get_sess_cb(ssl, (byte*)id, len, ©);
|
||||
if (ret != NULL) {
|
||||
WOLFSSL_MSG("Session found in external cache");
|
||||
return ret;
|
||||
}
|
||||
WOLFSSL_MSG("Session not found in external cache");
|
||||
}
|
||||
|
||||
if (ssl->ctx->internalCacheLookupOff) {
|
||||
WOLFSSL_MSG("Internal cache turned off");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
/* Do not access ssl->ctx->get_sess_cb from here. It is using a different
|
||||
* set of ID's */
|
||||
|
||||
row = HashObject(id, len, &error) % CLIENT_SESSION_ROWS;
|
||||
if (error != 0) {
|
||||
@ -14648,9 +14741,6 @@ static int SslSessionCacheOff(const WOLFSSL* ssl, const WOLFSSL_SESSION* session
|
||||
return ssl->options.sessionCacheOff
|
||||
#if defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_FORCE_CACHE_ON_TICKET)
|
||||
&& session->ticketLen == 0
|
||||
#endif
|
||||
#ifdef OPENSSL_EXTRA
|
||||
&& ssl->options.side != WOLFSSL_CLIENT_END
|
||||
#endif
|
||||
;
|
||||
}
|
||||
@ -14699,11 +14789,13 @@ void TlsSessionCacheUnlockRow(word32 row)
|
||||
SESSION_ROW_UNLOCK(sessRow);
|
||||
}
|
||||
|
||||
int TlsSessionCacheGetAndLock(const byte *id, WOLFSSL_SESSION **sess,
|
||||
word32 *lockedRow, byte readOnly)
|
||||
/* Don't use this function directly. Use TlsSessionCacheGetAndRdLock and
|
||||
* TlsSessionCacheGetAndWrLock to fully utilize compiler const support. */
|
||||
static int TlsSessionCacheGetAndLock(const byte *id,
|
||||
const WOLFSSL_SESSION **sess, word32 *lockedRow, byte readOnly, byte side)
|
||||
{
|
||||
SessionRow *sessRow;
|
||||
WOLFSSL_SESSION *s;
|
||||
const WOLFSSL_SESSION *s;
|
||||
word32 row;
|
||||
int count;
|
||||
int error;
|
||||
@ -14733,7 +14825,7 @@ int TlsSessionCacheGetAndLock(const byte *id, WOLFSSL_SESSION **sess,
|
||||
#else
|
||||
s = &sessRow->Sessions[idx];
|
||||
#endif
|
||||
if (s && XMEMCMP(s->sessionID, id, ID_LEN) == 0) {
|
||||
if (s && XMEMCMP(s->sessionID, id, ID_LEN) == 0 && s->side == side) {
|
||||
*sess = s;
|
||||
break;
|
||||
}
|
||||
@ -14749,9 +14841,22 @@ int TlsSessionCacheGetAndLock(const byte *id, WOLFSSL_SESSION **sess,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int TlsSessionCacheGetAndRdLock(const byte *id, const WOLFSSL_SESSION **sess,
|
||||
word32 *lockedRow, byte side)
|
||||
{
|
||||
return TlsSessionCacheGetAndLock(id, sess, lockedRow, 1, side);
|
||||
}
|
||||
|
||||
int TlsSessionCacheGetAndWrLock(const byte *id, WOLFSSL_SESSION **sess,
|
||||
word32 *lockedRow, byte side)
|
||||
{
|
||||
return TlsSessionCacheGetAndLock(id, (const WOLFSSL_SESSION**)sess,
|
||||
lockedRow, 0, side);
|
||||
}
|
||||
|
||||
int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output)
|
||||
{
|
||||
WOLFSSL_SESSION* sess = NULL;
|
||||
const WOLFSSL_SESSION* sess = NULL;
|
||||
const byte* id = NULL;
|
||||
word32 row;
|
||||
int error = 0;
|
||||
@ -14810,23 +14915,25 @@ int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output)
|
||||
#ifdef HAVE_EXT_CACHE
|
||||
if (ssl->ctx->get_sess_cb != NULL) {
|
||||
int copy = 0;
|
||||
WOLFSSL_SESSION* extSess;
|
||||
/* Attempt to retrieve the session from the external cache. */
|
||||
WOLFSSL_MSG("Calling external session cache");
|
||||
sess = ssl->ctx->get_sess_cb(ssl, (byte*)id, ID_LEN, ©);
|
||||
if ((sess != NULL)
|
||||
extSess = ssl->ctx->get_sess_cb(ssl, (byte*)id, ID_LEN, ©);
|
||||
if ((extSess != NULL)
|
||||
#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)
|
||||
&& (IsAtLeastTLSv1_3(ssl->version) ==
|
||||
IsAtLeastTLSv1_3(sess->version))
|
||||
IsAtLeastTLSv1_3(extSess->version))
|
||||
#endif
|
||||
) {
|
||||
WOLFSSL_MSG("Session found in external cache");
|
||||
error = wolfSSL_DupSession(sess, output, 0);
|
||||
error = wolfSSL_DupSession(extSess, output, 0);
|
||||
#ifdef HAVE_EX_DATA
|
||||
output->ownExData = 1;
|
||||
extSess->ownExData = 1;
|
||||
output->ownExData = 0;
|
||||
#endif
|
||||
/* If copy not set then free immediately */
|
||||
if (!copy)
|
||||
wolfSSL_FreeSession(ssl->ctx, sess);
|
||||
wolfSSL_FreeSession(ssl->ctx, extSess);
|
||||
/* We want to restore the bogus ID for TLS compatibility */
|
||||
if (ssl->session->haveAltSessionID &&
|
||||
output == ssl->session) {
|
||||
@ -14897,7 +15004,7 @@ int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output)
|
||||
|
||||
/* init to avoid clang static analyzer false positive */
|
||||
row = 0;
|
||||
error = TlsSessionCacheGetAndLock(id, &sess, &row, 1);
|
||||
error = TlsSessionCacheGetAndRdLock(id, &sess, &row, (byte)ssl->options.side);
|
||||
error = (error == 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
|
||||
if (error != WOLFSSL_SUCCESS || sess == NULL) {
|
||||
WOLFSSL_MSG("Get Session from cache failed");
|
||||
@ -14929,21 +15036,23 @@ int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output)
|
||||
error = WOLFSSL_FAILURE;
|
||||
}
|
||||
else if (LowResTimer() >= (sess->bornOn + sess->timeout)) {
|
||||
WOLFSSL_SESSION* wrSess = NULL;
|
||||
WOLFSSL_MSG("Invalid session: timed out");
|
||||
sess = NULL;
|
||||
TlsSessionCacheUnlockRow(row);
|
||||
/* Attempt to get a write lock */
|
||||
error = TlsSessionCacheGetAndWrLock(id, &wrSess, &row,
|
||||
ssl->options.side);
|
||||
if (error == 0 && wrSess != NULL) {
|
||||
EvictSessionFromCache(wrSess);
|
||||
TlsSessionCacheUnlockRow(row);
|
||||
}
|
||||
error = WOLFSSL_FAILURE;
|
||||
}
|
||||
#endif /* HAVE_SESSION_TICKET && WOLFSSL_TLS13 */
|
||||
}
|
||||
|
||||
if (error == WOLFSSL_SUCCESS) {
|
||||
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
|
||||
/* We don't want the peer member. We will free it at the end. */
|
||||
if (sess->peer != NULL) {
|
||||
peer = sess->peer;
|
||||
sess->peer = NULL;
|
||||
}
|
||||
#endif
|
||||
#if defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_TLS13)
|
||||
error = wolfSSL_DupSessionEx(sess, output, 1,
|
||||
preallocNonce, &preallocNonceLen, &preallocNonceUsed);
|
||||
@ -14951,7 +15060,7 @@ int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output)
|
||||
error = wolfSSL_DupSession(sess, output, 1);
|
||||
#endif /* HAVE_SESSION_TICKET && WOLFSSL_TLS13 */
|
||||
#ifdef HAVE_EX_DATA
|
||||
output->ownExData = 0; /* Session cache owns external data */
|
||||
output->ownExData = !sess->ownExData; /* Session may own ex_data */
|
||||
#endif
|
||||
TlsSessionCacheUnlockRow(row);
|
||||
}
|
||||
@ -15071,11 +15180,12 @@ int wolfSSL_SetSession(WOLFSSL* ssl, WOLFSSL_SESSION* session)
|
||||
|
||||
session = ClientSessionToSession(session);
|
||||
|
||||
if (ssl == NULL || session == NULL) {
|
||||
WOLFSSL_MSG("ssl or session NULL");
|
||||
if (ssl == NULL || session == NULL || !session->isSetup) {
|
||||
WOLFSSL_MSG("ssl or session NULL or not set up");
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
/* We need to lock the session as the first step if its in the cache */
|
||||
if (session->type == WOLFSSL_SESSION_TYPE_CACHE) {
|
||||
if (session->cacheRow < SESSION_ROWS) {
|
||||
sessRow = &SessionCache[session->cacheRow];
|
||||
@ -15086,11 +15196,6 @@ int wolfSSL_SetSession(WOLFSSL* ssl, WOLFSSL_SESSION* session)
|
||||
}
|
||||
}
|
||||
|
||||
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");
|
||||
@ -15098,12 +15203,16 @@ int wolfSSL_SetSession(WOLFSSL* ssl, WOLFSSL_SESSION* session)
|
||||
}
|
||||
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
if (ssl->session == session) {
|
||||
WOLFSSL_MSG("ssl->session and session same");
|
||||
}
|
||||
else
|
||||
#ifdef HAVE_STUNNEL
|
||||
/* stunnel depends on the ex_data not being duplicated. Copy OpenSSL
|
||||
* behaviour for now. */
|
||||
if (session->type != WOLFSSL_SESSION_TYPE_CACHE) {
|
||||
if (wolfSSL_SESSION_up_ref(session) == WOLFSSL_SUCCESS) {
|
||||
wolfSSL_SESSION_free(ssl->session);
|
||||
wolfSSL_FreeSession(ssl->ctx, ssl->session);
|
||||
ssl->session = session;
|
||||
}
|
||||
else
|
||||
@ -15119,7 +15228,8 @@ int wolfSSL_SetSession(WOLFSSL* ssl, WOLFSSL_SESSION* session)
|
||||
}
|
||||
|
||||
/* Let's copy over the altSessionID for local cache purposes */
|
||||
if (ret == WOLFSSL_SUCCESS && session->haveAltSessionID) {
|
||||
if (ret == WOLFSSL_SUCCESS && session->haveAltSessionID &&
|
||||
ssl->session != session) {
|
||||
ssl->session->haveAltSessionID = 1;
|
||||
XMEMCPY(ssl->session->altSessionID, session->altSessionID, ID_LEN);
|
||||
}
|
||||
@ -15146,36 +15256,33 @@ int wolfSSL_SetSession(WOLFSSL* ssl, WOLFSSL_SESSION* session)
|
||||
}
|
||||
#endif /* OPENSSL_EXTRA */
|
||||
|
||||
if (LowResTimer() < (ssl->session->bornOn + ssl->session->timeout)) {
|
||||
ssl->options.resuming = 1;
|
||||
ssl->options.haveEMS = ssl->session->haveEMS;
|
||||
|
||||
#if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
|
||||
defined(HAVE_SESSION_TICKET))
|
||||
ssl->version = ssl->session->version;
|
||||
if (IsAtLeastTLSv1_3(ssl->version))
|
||||
ssl->options.tls1_3 = 1;
|
||||
#endif
|
||||
#if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \
|
||||
(defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET))
|
||||
ssl->options.cipherSuite0 = ssl->session->cipherSuite0;
|
||||
ssl->options.cipherSuite = ssl->session->cipherSuite;
|
||||
#endif
|
||||
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
|
||||
ssl->peerVerifyRet = (unsigned long)ssl->session->peerVerifyRet;
|
||||
#endif
|
||||
ret = WOLFSSL_SUCCESS;
|
||||
}
|
||||
else {
|
||||
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_ERROR_CODE_OPENSSL)
|
||||
if (LowResTimer() >= (ssl->session->bornOn + ssl->session->timeout)) {
|
||||
#if !defined(OPENSSL_EXTRA) || !defined(WOLFSSL_ERROR_CODE_OPENSSL)
|
||||
return WOLFSSL_FAILURE; /* session timed out */
|
||||
#else /* defined(OPENSSL_EXTRA) && defined(WOLFSSL_ERROR_CODE_OPENSSL) */
|
||||
WOLFSSL_MSG("Session is expired but return success for "
|
||||
"OpenSSL compatibility");
|
||||
ret = WOLFSSL_SUCCESS;
|
||||
#else
|
||||
ret = WOLFSSL_FAILURE; /* session timed out */
|
||||
#endif /* OPENSSL_EXTRA && WOLFSSL_ERROR_CODE_OPENSSL */
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
ssl->options.resuming = 1;
|
||||
ssl->options.haveEMS = ssl->session->haveEMS;
|
||||
|
||||
#if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
|
||||
defined(HAVE_SESSION_TICKET))
|
||||
ssl->version = ssl->session->version;
|
||||
if (IsAtLeastTLSv1_3(ssl->version))
|
||||
ssl->options.tls1_3 = 1;
|
||||
#endif
|
||||
#if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \
|
||||
(defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET))
|
||||
ssl->options.cipherSuite0 = ssl->session->cipherSuite0;
|
||||
ssl->options.cipherSuite = ssl->session->cipherSuite;
|
||||
#endif
|
||||
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
|
||||
ssl->peerVerifyRet = (unsigned long)ssl->session->peerVerifyRet;
|
||||
#endif
|
||||
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@ -15379,7 +15486,6 @@ int AddSessionToCache(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* addSession,
|
||||
int row;
|
||||
int i;
|
||||
int overwrite = 0;
|
||||
|
||||
(void)ctx;
|
||||
(void)sessionIndex;
|
||||
(void)useTicket;
|
||||
@ -15479,34 +15585,47 @@ int AddSessionToCache(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* addSession,
|
||||
|
||||
#ifdef SESSION_CACHE_DYNAMIC_MEM
|
||||
cacheSession = sessRow->Sessions[idx];
|
||||
if (cacheSession) {
|
||||
XFREE(cacheSession, sessRow->heap, DYNAMIC_TYPE_SESSION);
|
||||
cacheSession = NULL;
|
||||
}
|
||||
cacheSession = (WOLFSSL_SESSION*) XMALLOC(sizeof(WOLFSSL_SESSION), sessRow->heap,
|
||||
DYNAMIC_TYPE_SESSION);
|
||||
if (cacheSession == NULL) {
|
||||
return MEMORY_E;
|
||||
cacheSession = (WOLFSSL_SESSION*) XMALLOC(sizeof(WOLFSSL_SESSION),
|
||||
sessRow->heap, DYNAMIC_TYPE_SESSION);
|
||||
if (cacheSession == NULL) {
|
||||
#ifdef HAVE_SESSION_TICKET
|
||||
XFREE(ticBuff, NULL, DYNAMIC_TYPE_SESSION_TICK);
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_TICKE_NONCE_MALLOC)
|
||||
if (preallocNonce != NULL)
|
||||
XFREE(preallocNonce, addSession->heap, DYNAMIC_TYPE_SESSION_TICK);
|
||||
#endif
|
||||
#endif
|
||||
SESSION_ROW_UNLOCK(sessRow);
|
||||
return MEMORY_E;
|
||||
}
|
||||
XMEMSET(cacheSession, 0, sizeof(WOLFSSL_SESSION));
|
||||
sessRow->Sessions[idx] = cacheSession;
|
||||
}
|
||||
XMEMSET(cacheSession, 0, sizeof(WOLFSSL_SESSION));
|
||||
sessRow->Sessions[idx] = cacheSession;
|
||||
#else
|
||||
cacheSession = &sessRow->Sessions[idx];
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_EX_DATA
|
||||
if (cacheSession->ownExData) {
|
||||
if (overwrite) {
|
||||
/* Figure out who owns the ex_data */
|
||||
if (cacheSession->ownExData) {
|
||||
/* Prioritize cacheSession copy */
|
||||
XMEMCPY(&addSession->ex_data, &cacheSession->ex_data,
|
||||
sizeof(WOLFSSL_CRYPTO_EX_DATA));
|
||||
}
|
||||
/* else will be copied in wolfSSL_DupSession call */
|
||||
}
|
||||
else if (cacheSession->ownExData) {
|
||||
crypto_ex_cb_free_data(cacheSession, crypto_ex_cb_ctx_session,
|
||||
&cacheSession->ex_data);
|
||||
if (cacheSession->rem_sess_cb) {
|
||||
cacheSession->rem_sess_cb(NULL, cacheSession);
|
||||
/* Make sure not to call remove functions again */
|
||||
cacheSession->ownExData = 0;
|
||||
cacheSession->rem_sess_cb = NULL;
|
||||
}
|
||||
cacheSession->ownExData = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!overwrite)
|
||||
EvictSessionFromCache(cacheSession);
|
||||
|
||||
cacheSession->type = WOLFSSL_SESSION_TYPE_CACHE;
|
||||
cacheSession->cacheRow = row;
|
||||
|
||||
@ -15573,22 +15692,26 @@ int AddSessionToCache(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* addSession,
|
||||
#endif
|
||||
|
||||
if (ret == 0) {
|
||||
/* Increment the totalCount and the nextIdx */
|
||||
if (sessRow->totalCount < SESSIONS_PER_ROW)
|
||||
sessRow->totalCount++;
|
||||
sessRow->nextIdx = (sessRow->nextIdx + 1) % SESSIONS_PER_ROW;
|
||||
if (!overwrite) {
|
||||
/* Increment the totalCount and the nextIdx */
|
||||
if (sessRow->totalCount < SESSIONS_PER_ROW)
|
||||
sessRow->totalCount++;
|
||||
sessRow->nextIdx = (sessRow->nextIdx + 1) % SESSIONS_PER_ROW;
|
||||
}
|
||||
if (id != addSession->sessionID) {
|
||||
/* ssl->session->sessionID may contain the bogus ID or we want the
|
||||
* ID from the arrays object */
|
||||
XMEMCPY(cacheSession->sessionID, id, ID_LEN);
|
||||
cacheSession->sessionIDSz = ID_LEN;
|
||||
}
|
||||
#ifdef HAVE_EX_DATA
|
||||
if (ctx->rem_sess_cb != NULL) {
|
||||
addSession->ownExData = 0;
|
||||
cacheSession->ownExData = 1;
|
||||
#if defined(HAVE_EXT_CACHE) || defined(HAVE_EX_DATA)
|
||||
if (ctx->rem_sess_cb != NULL)
|
||||
cacheSession->rem_sess_cb = ctx->rem_sess_cb;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_EX_DATA
|
||||
/* The session in cache now owns the ex_data */
|
||||
addSession->ownExData = 0;
|
||||
cacheSession->ownExData = 1;
|
||||
#endif
|
||||
#if defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_TLS13) && \
|
||||
defined(WOLFSSL_TICKET_NONCE_MALLOC) && \
|
||||
@ -15610,7 +15733,6 @@ int AddSessionToCache(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* addSession,
|
||||
cacheSession->ticketLen = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
SESSION_ROW_UNLOCK(sessRow);
|
||||
cacheSession = NULL; /* Can't access after unlocked */
|
||||
|
||||
@ -15647,9 +15769,6 @@ int AddSessionToCache(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* addSession,
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef NO_CLIENT_CACHE
|
||||
#endif
|
||||
|
||||
void AddSession(WOLFSSL* ssl)
|
||||
{
|
||||
int error = 0;
|
||||
@ -15666,63 +15785,16 @@ void AddSession(WOLFSSL* ssl)
|
||||
return;
|
||||
}
|
||||
|
||||
if (ssl->options.haveSessionId == 0) {
|
||||
WOLFSSL_MSG("Don't have session id");
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (session->haveAltSessionID) {
|
||||
id = session->altSessionID;
|
||||
idSz = ID_LEN;
|
||||
}
|
||||
else {
|
||||
if (!IsAtLeastTLSv1_3(ssl->version) && ssl->arrays != NULL) {
|
||||
/* Make sure the session ID is available when the user calls any
|
||||
* get_session API */
|
||||
XMEMCPY(session->sessionID, ssl->arrays->sessionID, ID_LEN);
|
||||
session->sessionIDSz = ssl->arrays->sessionIDSz;
|
||||
}
|
||||
id = session->sessionID;
|
||||
idSz = session->sessionIDSz;
|
||||
}
|
||||
|
||||
session->timeout = ssl->timeout;
|
||||
session->side = (byte)ssl->options.side;
|
||||
if (!IsAtLeastTLSv1_3(ssl->version) && ssl->arrays != NULL)
|
||||
XMEMCPY(session->masterSecret, ssl->arrays->masterSecret, SECRET_LEN);
|
||||
session->haveEMS = ssl->options.haveEMS;
|
||||
#ifdef OPENSSL_EXTRA
|
||||
/* If using compatibility layer then check for and copy over session context
|
||||
* id. */
|
||||
if (ssl->sessionCtxSz > 0 && ssl->sessionCtxSz < ID_LEN) {
|
||||
XMEMCPY(ssl->session->sessionCtx, ssl->sessionCtx, ssl->sessionCtxSz);
|
||||
session->sessionCtxSz = ssl->sessionCtxSz;
|
||||
}
|
||||
#endif
|
||||
session->timeout = ssl->timeout;
|
||||
session->bornOn = LowResTimer();
|
||||
#if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
|
||||
defined(HAVE_SESSION_TICKET))
|
||||
session->version = ssl->version;
|
||||
#endif
|
||||
#if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \
|
||||
(defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET))
|
||||
session->cipherSuite0 = ssl->options.cipherSuite0;
|
||||
session->cipherSuite = ssl->options.cipherSuite;
|
||||
#endif
|
||||
#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
|
||||
/* 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;
|
||||
@ -15740,31 +15812,28 @@ void AddSession(WOLFSSL* ssl)
|
||||
id = ssl->session->altSessionID;
|
||||
idSz = ID_LEN;
|
||||
}
|
||||
/* Setup done */
|
||||
|
||||
if (ssl->options.side == WOLFSSL_SERVER_END /* No point in adding a
|
||||
* client session */
|
||||
#ifdef HAVE_EXT_CACHE
|
||||
&& !ssl->options.internalCacheOff
|
||||
#endif
|
||||
)
|
||||
{
|
||||
/* Try to add the session to cache. Its ok if we don't succeed. */
|
||||
(void)AddSessionToCache(ssl->ctx, session, id, idSz,
|
||||
/* Try to add the session to internal cache or external cache
|
||||
if a new_sess_cb is set. Its ok if we don't succeed. */
|
||||
(void)AddSessionToCache(ssl->ctx, session, id, idSz,
|
||||
#ifdef SESSION_INDEX
|
||||
&ssl->sessionIndex,
|
||||
&ssl->sessionIndex,
|
||||
#else
|
||||
NULL,
|
||||
NULL,
|
||||
#endif
|
||||
ssl->options.side,
|
||||
ssl->options.side,
|
||||
#ifdef HAVE_SESSION_TICKET
|
||||
ssl->options.useTicket,
|
||||
ssl->options.useTicket,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif
|
||||
NULL
|
||||
);
|
||||
}
|
||||
#ifdef NO_SESSION_CACHE_REF
|
||||
NULL
|
||||
#else
|
||||
(ssl->options.side == WOLFSSL_CLIENT_END) ?
|
||||
&ssl->clientSession : NULL
|
||||
#endif
|
||||
);
|
||||
|
||||
#ifdef HAVE_EXT_CACHE
|
||||
if (error == 0 && ssl->ctx->new_sess_cb != NULL) {
|
||||
@ -17718,8 +17787,16 @@ cleanup:
|
||||
if ((ctx->mask & WOLFSSL_OP_NO_TICKET) == WOLFSSL_OP_NO_TICKET) {
|
||||
ctx->noTicketTls12 = 1;
|
||||
}
|
||||
/* This code is here for documentation purpose. You must not turn off
|
||||
* session tickets with the WOLFSSL_OP_NO_TICKET option for TLSv1.3.
|
||||
* Because we need to support both stateful and stateless tickets.
|
||||
#ifdef WOLFSSL_TLS13
|
||||
if ((ctx->mask & WOLFSSL_OP_NO_TICKET) == WOLFSSL_OP_NO_TICKET) {
|
||||
ctx->noTicketTls13 = 1;
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
#endif
|
||||
|
||||
return ctx->mask;
|
||||
}
|
||||
|
||||
@ -20101,7 +20178,7 @@ size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out,
|
||||
|
||||
if (!ssl->options.handShakeDone) {
|
||||
/* Only reset the session if we didn't complete a handshake */
|
||||
wolfSSL_SESSION_free(ssl->session);
|
||||
wolfSSL_FreeSession(ssl->ctx, ssl->session);
|
||||
ssl->session = wolfSSL_NewSession(ssl->heap);
|
||||
if (ssl->session == NULL) {
|
||||
return WOLFSSL_FAILURE;
|
||||
@ -21130,6 +21207,8 @@ WOLFSSL_SESSION* wolfSSL_NewSession(void* heap)
|
||||
{
|
||||
WOLFSSL_SESSION* ret = NULL;
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_NewSession");
|
||||
|
||||
ret = (WOLFSSL_SESSION*)XMALLOC(sizeof(WOLFSSL_SESSION), heap,
|
||||
DYNAMIC_TYPE_SESSION);
|
||||
if (ret != NULL) {
|
||||
@ -21161,12 +21240,12 @@ WOLFSSL_SESSION* wolfSSL_NewSession(void* heap)
|
||||
ret->ticketNonce.data = ret->ticketNonce.dataStatic;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef HAVE_EX_DATA
|
||||
crypto_ex_cb_setup_new_data(ret, crypto_ex_cb_ctx_session,
|
||||
&ret->ex_data);
|
||||
#endif
|
||||
#ifdef HAVE_EX_DATA
|
||||
ret->ownExData = 1;
|
||||
if (crypto_ex_cb_ctx_session != NULL) {
|
||||
crypto_ex_cb_setup_new_data(ret, crypto_ex_cb_ctx_session,
|
||||
&ret->ex_data);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
@ -21516,6 +21595,8 @@ void wolfSSL_FreeSession(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* session)
|
||||
|
||||
(void)ctx;
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_FreeSession");
|
||||
|
||||
if (session->ref.count > 0) {
|
||||
int ret;
|
||||
int isZero;
|
||||
@ -21527,23 +21608,14 @@ void wolfSSL_FreeSession(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* session)
|
||||
wolfSSL_RefFree(&session->ref);
|
||||
}
|
||||
|
||||
#if defined(HAVE_EXT_CACHE) || defined(HAVE_EX_DATA)
|
||||
WOLFSSL_MSG("wolfSSL_FreeSession full free");
|
||||
|
||||
#ifdef HAVE_EX_DATA
|
||||
if (session->ownExData) {
|
||||
crypto_ex_cb_free_data(session, crypto_ex_cb_ctx_session,
|
||||
&session->ex_data);
|
||||
}
|
||||
#endif
|
||||
if (ctx != NULL && ctx->rem_sess_cb
|
||||
#ifdef HAVE_EX_DATA
|
||||
&& session->ownExData /* This will be true if we are not using the
|
||||
* internal cache so it will get called for
|
||||
* externally cached sessions as well. */
|
||||
#endif
|
||||
) {
|
||||
ctx->rem_sess_cb(ctx, session);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
|
||||
wolfSSL_CRYPTO_cleanup_ex_data(&session->ex_data);
|
||||
@ -21583,6 +21655,8 @@ void wolfSSL_FreeSession(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* session)
|
||||
}
|
||||
}
|
||||
|
||||
/* DO NOT use this API internally. Use wolfSSL_FreeSession directly instead
|
||||
* and pass in the ctx parameter if possible (like from ssl->ctx). */
|
||||
void wolfSSL_SESSION_free(WOLFSSL_SESSION* session)
|
||||
{
|
||||
session = ClientSessionToSession(session);
|
||||
@ -21605,12 +21679,14 @@ int wolfSSL_CTX_add_session(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* session)
|
||||
/* Session cache is global */
|
||||
(void)ctx;
|
||||
|
||||
id = session->sessionID;
|
||||
idSz = session->sessionIDSz;
|
||||
if (session->haveAltSessionID) {
|
||||
id = session->altSessionID;
|
||||
idSz = ID_LEN;
|
||||
}
|
||||
else {
|
||||
id = session->sessionID;
|
||||
idSz = session->sessionIDSz;
|
||||
}
|
||||
|
||||
error = AddSessionToCache(ctx, session, id, idSz,
|
||||
NULL, session->side,
|
||||
@ -25800,11 +25876,13 @@ WOLFSSL_SESSION* wolfSSL_d2i_SSL_SESSION(WOLFSSL_SESSION** sess,
|
||||
*sess = s;
|
||||
}
|
||||
|
||||
s->isSetup = 1;
|
||||
|
||||
*p += idx;
|
||||
|
||||
end:
|
||||
if (ret != 0 && (sess == NULL || *sess != s)) {
|
||||
wolfSSL_SESSION_free(s);
|
||||
wolfSSL_FreeSession(NULL, s);
|
||||
s = NULL;
|
||||
}
|
||||
#endif /* HAVE_EXT_CACHE */
|
||||
@ -31340,6 +31418,8 @@ int wolfSSL_version(WOLFSSL* ssl)
|
||||
return DTLS1_VERSION;
|
||||
case DTLSv1_2_MINOR :
|
||||
return DTLS1_2_VERSION;
|
||||
case DTLSv1_3_MINOR:
|
||||
return DTLS1_3_VERSION;
|
||||
default:
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
@ -32639,10 +32719,13 @@ int wolfSSL_SSL_CTX_set_tmp_ecdh(WOLFSSL_CTX *ctx, WOLFSSL_EC_KEY *ecdh)
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Assumes that the session passed in is from the cache. */
|
||||
#ifndef NO_SESSION_CACHE
|
||||
int wolfSSL_SSL_CTX_remove_session(WOLFSSL_CTX *ctx, WOLFSSL_SESSION *s)
|
||||
{
|
||||
#if defined(HAVE_EXT_CACHE) || defined(HAVE_EX_DATA)
|
||||
int rem_called = FALSE;
|
||||
#endif
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_SSL_CTX_remove_session");
|
||||
|
||||
s = ClientSessionToSession(s);
|
||||
@ -32653,77 +32736,64 @@ int wolfSSL_SSL_CTX_remove_session(WOLFSSL_CTX *ctx, WOLFSSL_SESSION *s)
|
||||
if (!ctx->internalCacheOff)
|
||||
#endif
|
||||
{
|
||||
/* Don't remove session just timeout session. */
|
||||
s->timeout = 0;
|
||||
#ifndef NO_SESSION_CACHE
|
||||
/* Clear the timeout in the cache */
|
||||
{
|
||||
int row;
|
||||
int i;
|
||||
SessionRow* sessRow = NULL;
|
||||
WOLFSSL_SESSION *cacheSession;
|
||||
const byte* id;
|
||||
int ret = 0;
|
||||
const byte* id;
|
||||
WOLFSSL_SESSION *sess = NULL;
|
||||
word32 row = 0;
|
||||
int ret;
|
||||
|
||||
id = s->sessionID;
|
||||
if (s->haveAltSessionID)
|
||||
id = s->altSessionID;
|
||||
id = s->sessionID;
|
||||
if (s->haveAltSessionID)
|
||||
id = s->altSessionID;
|
||||
|
||||
row = (int)(HashObject(id, ID_LEN, &ret) % SESSION_ROWS);
|
||||
if (ret != 0) {
|
||||
WOLFSSL_MSG("Hash session failed");
|
||||
return ret;
|
||||
ret = TlsSessionCacheGetAndWrLock(id, &sess, &row, ctx->method->side);
|
||||
if (ret == 0 && sess != NULL) {
|
||||
#if defined(HAVE_EXT_CACHE) || defined(HAVE_EX_DATA)
|
||||
if (sess->rem_sess_cb != NULL) {
|
||||
rem_called = TRUE;
|
||||
}
|
||||
|
||||
sessRow = &SessionCache[row];
|
||||
if (SESSION_ROW_WR_LOCK(sessRow) != 0) {
|
||||
WOLFSSL_MSG("Session row lock failed");
|
||||
return BAD_MUTEX_E;
|
||||
}
|
||||
|
||||
for (i = 0; i < SESSIONS_PER_ROW && i < sessRow->totalCount; i++) {
|
||||
#ifdef SESSION_CACHE_DYNAMIC_MEM
|
||||
cacheSession = sessRow->Sessions[i];
|
||||
#else
|
||||
cacheSession = &sessRow->Sessions[i];
|
||||
#endif
|
||||
if (cacheSession &&
|
||||
XMEMCMP(id, cacheSession->sessionID, ID_LEN) == 0) {
|
||||
if (ctx->method->side != cacheSession->side)
|
||||
continue;
|
||||
cacheSession->timeout = 0;
|
||||
/* Call this before changing ownExData so that calls to ex_data
|
||||
* don't try to access the SessionCache again. */
|
||||
EvictSessionFromCache(sess);
|
||||
#ifdef HAVE_EX_DATA
|
||||
if (cacheSession->ownExData) {
|
||||
/* Most recent version of ex data is in cache. Copy it
|
||||
* over so the user can free it. */
|
||||
XMEMCPY(&s->ex_data, &cacheSession->ex_data,
|
||||
sizeof(WOLFSSL_CRYPTO_EX_DATA));
|
||||
}
|
||||
cacheSession->ownExData = 0; /* We clear below */
|
||||
s->ownExData = 1;
|
||||
if (sess->ownExData) {
|
||||
/* Most recent version of ex data is in cache. Copy it
|
||||
* over so the user can free it. */
|
||||
XMEMCPY(&s->ex_data, &sess->ex_data,
|
||||
sizeof(WOLFSSL_CRYPTO_EX_DATA));
|
||||
s->ownExData = 1;
|
||||
sess->ownExData = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SESSION_CACHE_DYNAMIC_MEM
|
||||
XFREE(cacheSession, sessRow->heap, DYNAMIC_TYPE_SESSION);
|
||||
sessRow->Sessions[i] = NULL;
|
||||
#endif
|
||||
break;
|
||||
{
|
||||
/* Find and clear entry. Row is locked so we are good to go. */
|
||||
int idx;
|
||||
for (idx = 0; idx < SESSIONS_PER_ROW; idx++) {
|
||||
if (sess == SessionCache[row].Sessions[idx]) {
|
||||
XFREE(sess, sess->heap, DYNAMIC_TYPE_SESSION);
|
||||
SessionCache[row].Sessions[idx] = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
SESSION_ROW_UNLOCK(sessRow);
|
||||
}
|
||||
#endif
|
||||
TlsSessionCacheUnlockRow(row);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(HAVE_EXT_CACHE) || defined(HAVE_EX_DATA)
|
||||
if (ctx->rem_sess_cb != NULL) {
|
||||
if (ctx->rem_sess_cb != NULL && !rem_called) {
|
||||
ctx->rem_sess_cb(ctx, s);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* s cannot be resumed at this point */
|
||||
s->timeout = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* !NO_SESSION_CACHE */
|
||||
#ifndef NO_BIO
|
||||
BIO *wolfSSL_SSL_get_rbio(const WOLFSSL *s)
|
||||
{
|
||||
|
72
src/tls13.c
72
src/tls13.c
@ -5667,7 +5667,8 @@ static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 inputSz,
|
||||
/* Decode the identity. */
|
||||
switch (current->decryptRet) {
|
||||
case PSK_DECRYPT_NONE:
|
||||
ret = DoClientTicket_ex(ssl, current);
|
||||
ret = DoClientTicket_ex(ssl, current, 1);
|
||||
/* psk->sess may be set. Need to clean up later. */
|
||||
break;
|
||||
case PSK_DECRYPT_OK:
|
||||
ret = WOLFSSL_TICKET_RET_OK;
|
||||
@ -5685,12 +5686,27 @@ static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 inputSz,
|
||||
return ret;
|
||||
#endif
|
||||
|
||||
if (ret != WOLFSSL_TICKET_RET_OK && current->sess_free_cb != NULL) {
|
||||
current->sess_free_cb(ssl, current->sess,
|
||||
¤t->sess_free_cb_ctx);
|
||||
current->sess = NULL;
|
||||
XMEMSET(¤t->sess_free_cb_ctx, 0,
|
||||
sizeof(psk_sess_free_cb_ctx));
|
||||
}
|
||||
if (ret == WOLFSSL_TICKET_RET_OK) {
|
||||
if (DoClientTicketCheck(ssl, current, ssl->timeout, suite) != 0)
|
||||
ret = DoClientTicketCheck(ssl, current, ssl->timeout, suite);
|
||||
if (ret == 0)
|
||||
DoClientTicketFinalize(ssl, current->it, current->sess);
|
||||
if (current->sess_free_cb != NULL) {
|
||||
current->sess_free_cb(ssl, current->sess,
|
||||
¤t->sess_free_cb_ctx);
|
||||
current->sess = NULL;
|
||||
XMEMSET(¤t->sess_free_cb_ctx, 0,
|
||||
sizeof(psk_sess_free_cb_ctx));
|
||||
}
|
||||
if (ret != 0)
|
||||
continue;
|
||||
|
||||
DoClientTicketFinalize(ssl, current->it);
|
||||
|
||||
/* SERVER: using secret in session ticket for peer auth. */
|
||||
ssl->options.peerAuthGood = 1;
|
||||
|
||||
@ -10023,10 +10039,6 @@ static int DoTls13NewSessionTicket(WOLFSSL* ssl, const byte* input,
|
||||
#endif
|
||||
const byte* nonce;
|
||||
byte nonceLength;
|
||||
#ifndef NO_SESSION_CACHE
|
||||
const byte* id;
|
||||
byte idSz;
|
||||
#endif
|
||||
|
||||
WOLFSSL_START(WC_FUNC_NEW_SESSION_TICKET_DO);
|
||||
WOLFSSL_ENTER("DoTls13NewSessionTicket");
|
||||
@ -10122,16 +10134,9 @@ static int DoTls13NewSessionTicket(WOLFSSL* ssl, const byte* input,
|
||||
#endif
|
||||
*inOutIdx += length;
|
||||
|
||||
SetupSession(ssl);
|
||||
#ifndef NO_SESSION_CACHE
|
||||
AddSession(ssl);
|
||||
id = ssl->session->sessionID;
|
||||
idSz = ssl->session->sessionIDSz;
|
||||
if (ssl->session->haveAltSessionID) {
|
||||
id = ssl->session->altSessionID;
|
||||
idSz = ID_LEN;
|
||||
}
|
||||
AddSessionToCache(ssl->ctx, ssl->session, id, idSz, NULL,
|
||||
ssl->session->side, 1, &ssl->clientSession);
|
||||
AddSession(ssl);
|
||||
#endif
|
||||
|
||||
/* Always encrypted. */
|
||||
@ -10316,12 +10321,15 @@ static int SendTls13NewSessionTicket(WOLFSSL* ssl)
|
||||
#else
|
||||
extSz = EXTS_SZ;
|
||||
#endif
|
||||
|
||||
/* Lifetime | Age Add | Ticket | Extensions */
|
||||
length = SESSION_HINT_SZ + SESSION_ADD_SZ + LENGTH_SZ +
|
||||
ssl->session->ticketLen + extSz;
|
||||
/* Lifetime | Age Add | Ticket session ID | Extensions */
|
||||
length = SESSION_HINT_SZ + SESSION_ADD_SZ + LENGTH_SZ;
|
||||
if ((ssl->options.mask & WOLFSSL_OP_NO_TICKET) != 0)
|
||||
length += ID_LEN + extSz;
|
||||
else
|
||||
length += ssl->session->ticketLen + extSz;
|
||||
/* Nonce */
|
||||
length += TICKET_NONCE_LEN_SZ + DEF_TICKET_NONCE_SZ;
|
||||
|
||||
sendSz = idx + length + MAX_MSG_EXTRA;
|
||||
|
||||
/* Check buffers are big enough and grow if needed. */
|
||||
@ -10346,11 +10354,26 @@ static int SendTls13NewSessionTicket(WOLFSSL* ssl)
|
||||
output[idx++] = ssl->session->ticketNonce.data[0];
|
||||
|
||||
/* length */
|
||||
c16toa(ssl->session->ticketLen, output + idx);
|
||||
if ((ssl->options.mask & WOLFSSL_OP_NO_TICKET) != 0) {
|
||||
c16toa(ID_LEN, output + idx);
|
||||
}
|
||||
else {
|
||||
c16toa(ssl->session->ticketLen, output + idx);
|
||||
}
|
||||
|
||||
idx += LENGTH_SZ;
|
||||
/* ticket */
|
||||
XMEMCPY(output + idx, ssl->session->ticket, ssl->session->ticketLen);
|
||||
idx += ssl->session->ticketLen;
|
||||
if ((ssl->options.mask & WOLFSSL_OP_NO_TICKET) != 0) {
|
||||
if (ssl->session->haveAltSessionID)
|
||||
XMEMCPY(output + idx, ssl->session->altSessionID, ID_LEN);
|
||||
else
|
||||
XMEMCPY(output + idx, ssl->session->sessionID, ID_LEN);
|
||||
idx += ID_LEN;
|
||||
}
|
||||
else {
|
||||
XMEMCPY(output + idx, ssl->session->ticket, ssl->session->ticketLen);
|
||||
idx += ssl->session->ticketLen;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
extSz = 0;
|
||||
@ -10366,6 +10389,7 @@ static int SendTls13NewSessionTicket(WOLFSSL* ssl)
|
||||
|
||||
ssl->options.haveSessionId = 1;
|
||||
|
||||
SetupSession(ssl);
|
||||
/* Only add to cache when support built in and when the ticket contains
|
||||
* an ID. Otherwise we have no way to actually retrieve the ticket from the
|
||||
* cache. */
|
||||
|
601
tests/api.c
601
tests/api.c
@ -342,7 +342,7 @@
|
||||
defined(HAVE_SESSION_TICKET) || (defined(OPENSSL_EXTRA) && \
|
||||
defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN)) || \
|
||||
defined(WOLFSSL_TEST_STATIC_BUILD) || defined(WOLFSSL_DTLS) || \
|
||||
defined(HAVE_ECH)
|
||||
defined(HAVE_ECH) || defined(HAVE_EX_DATA)
|
||||
/* for testing SSL_get_peer_cert_chain, or SESSION_TICKET_HINT_DEFAULT,
|
||||
* for setting authKeyIdSrc in WOLFSSL_X509, or testing DTLS sequence
|
||||
* number tracking */
|
||||
@ -7447,6 +7447,592 @@ static int test_wolfSSL_CTX_add_session(void)
|
||||
|
||||
return res;
|
||||
}
|
||||
#if defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(HAVE_EXT_CACHE) && \
|
||||
!defined(SINGLE_THREADED) && defined(WOLFSSL_TLS13) && \
|
||||
!defined(NO_SESSION_CACHE) && defined(OPENSSL_EXTRA) && \
|
||||
defined(SESSION_CERTS) && defined(HAVE_SESSION_TICKET) && \
|
||||
!defined(TITAN_SESSION_CACHE) && \
|
||||
!defined(HUGE_SESSION_CACHE) && \
|
||||
!defined(BIG_SESSION_CACHE) && \
|
||||
!defined(MEDIUM_SESSION_CACHE)
|
||||
|
||||
/* twcase - prefix for test_wolfSSL_CTX_add_session_ext */
|
||||
/* Sessions to restore/store */
|
||||
static WOLFSSL_SESSION* twcase_server_first_session_ptr;
|
||||
static WOLFSSL_SESSION* twcase_client_first_session_ptr;
|
||||
static WOLFSSL_CTX* twcase_server_current_ctx_ptr;
|
||||
static int twcase_new_session_called = 0;
|
||||
static int twcase_remove_session_called = 0;
|
||||
static int twcase_get_session_called = 0;
|
||||
|
||||
/* Test default, SESSIONS_PER_ROW*SESSION_ROWS = 3*11, see ssl.c */
|
||||
#define SESSION_CACHE_SIZE 33
|
||||
|
||||
typedef struct {
|
||||
const byte* key; /* key, altSessionID, session ID, NULL if empty */
|
||||
WOLFSSL_SESSION* value;
|
||||
} hashTable_entry;
|
||||
|
||||
typedef struct {
|
||||
hashTable_entry entries[SESSION_CACHE_SIZE]; /* hash slots */
|
||||
size_t capacity; /* size of entries */
|
||||
size_t length; /* number of items in the hash table */
|
||||
wolfSSL_Mutex htLock; /* lock */
|
||||
}hashTable;
|
||||
|
||||
static hashTable server_sessionCache;
|
||||
|
||||
static int twcase_new_sessionCb(WOLFSSL *ssl, WOLFSSL_SESSION *sess)
|
||||
{
|
||||
int i;
|
||||
(void)ssl;
|
||||
/*
|
||||
* This example uses a hash table.
|
||||
* Steps you should take for a non-demo code:
|
||||
* - acquire a lock for the file named according to the session id
|
||||
* - open the file
|
||||
* - encrypt and write the SSL_SESSION object to the file
|
||||
* - release the lock
|
||||
*
|
||||
* Return:
|
||||
* 0: The callback does not wish to hold a reference of the sess
|
||||
* 1: The callback wants to hold a reference of the sess. The callback is
|
||||
* now also responsible for calling wolfSSL_SESSION_free() on sess.
|
||||
*/
|
||||
if (sess == NULL)
|
||||
return 0;
|
||||
|
||||
if (wc_LockMutex(&server_sessionCache.htLock) != 0) {
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < SESSION_CACHE_SIZE; i++) {
|
||||
if (server_sessionCache.entries[i].value == NULL) {
|
||||
if (sess->haveAltSessionID == 1)
|
||||
server_sessionCache.entries[i].key = sess->altSessionID;
|
||||
else
|
||||
server_sessionCache.entries[i].key = sess->sessionID;
|
||||
|
||||
server_sessionCache.entries[i].value = sess;
|
||||
server_sessionCache.length++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
++twcase_new_session_called;
|
||||
wc_UnLockMutex(&server_sessionCache.htLock);
|
||||
fprintf(stderr, "\t\ttwcase_new_session_called %d\n",
|
||||
twcase_new_session_called);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void twcase_remove_sessionCb(WOLFSSL_CTX *ctx, WOLFSSL_SESSION *sess)
|
||||
{
|
||||
int i;
|
||||
(void)ctx;
|
||||
(void)sess;
|
||||
|
||||
if (sess == NULL)
|
||||
return;
|
||||
/*
|
||||
* This example uses a hash table.
|
||||
* Steps you should take for a non-demo code:
|
||||
* - acquire a lock for the file named according to the session id
|
||||
* - remove the file
|
||||
* - release the lock
|
||||
*/
|
||||
if (wc_LockMutex(&server_sessionCache.htLock) != 0) {
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < SESSION_CACHE_SIZE; i++) {
|
||||
if (server_sessionCache.entries[i].key != NULL &&
|
||||
XMEMCMP(server_sessionCache.entries[i].key,
|
||||
sess->sessionID, SSL_MAX_SSL_SESSION_ID_LENGTH) == 0) {
|
||||
wolfSSL_SESSION_free(server_sessionCache.entries[i].value);
|
||||
server_sessionCache.entries[i].value = NULL;
|
||||
server_sessionCache.entries[i].key = NULL;
|
||||
server_sessionCache.length--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
++twcase_remove_session_called;
|
||||
wc_UnLockMutex(&server_sessionCache.htLock);
|
||||
fprintf(stderr, "\t\ttwcase_remove_session_called %d\n",
|
||||
twcase_remove_session_called);
|
||||
}
|
||||
|
||||
static WOLFSSL_SESSION *twcase_get_sessionCb(WOLFSSL *ssl,
|
||||
const unsigned char *id, int len, int *ref)
|
||||
{
|
||||
int i;
|
||||
(void)ssl;
|
||||
(void)id;
|
||||
(void)len;
|
||||
|
||||
/*
|
||||
* This example uses a hash table.
|
||||
* Steps you should take for a non-demo code:
|
||||
* - acquire a lock for the file named according to the session id in the
|
||||
* 2nd arg
|
||||
* - read and decrypt contents of file and create a new SSL_SESSION
|
||||
* - object release the lock
|
||||
* - return the new session object
|
||||
*/
|
||||
fprintf(stderr, "\t\ttwcase_get_session_called %d\n",
|
||||
++twcase_get_session_called);
|
||||
/* This callback want to retain a copy of the object. If we want wolfSSL to
|
||||
* be responsible for the pointer then set to 0. */
|
||||
*ref = 1;
|
||||
|
||||
for (i = 0; i < SESSION_CACHE_SIZE; i++) {
|
||||
if (server_sessionCache.entries[i].key != NULL &&
|
||||
XMEMCMP(server_sessionCache.entries[i].key, id,
|
||||
SSL_MAX_SSL_SESSION_ID_LENGTH) == 0) {
|
||||
return server_sessionCache.entries[i].value;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
static void twcase_get_sessionCb_cleanup(void)
|
||||
{
|
||||
int i;
|
||||
int cnt = 0;
|
||||
|
||||
/* If twcase_get_sessionCb sets *ref = 1, the application is responsible
|
||||
* for freeing sessions */
|
||||
|
||||
for (i = 0; i < SESSION_CACHE_SIZE; i++) {
|
||||
if (server_sessionCache.entries[i].value != NULL) {
|
||||
wolfSSL_SESSION_free(server_sessionCache.entries[i].value);
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "\t\ttwcase_get_sessionCb_cleanup freed %d sessions\n",
|
||||
cnt);
|
||||
}
|
||||
|
||||
static void twcase_cache_intOff_extOff(WOLFSSL_CTX* ctx)
|
||||
{
|
||||
/* off - Disable internal cache */
|
||||
AssertIntEQ(wolfSSL_CTX_set_session_cache_mode(ctx,
|
||||
WOLFSSL_SESS_CACHE_NO_INTERNAL_STORE), WOLFSSL_SUCCESS);
|
||||
#ifdef OPENSSL_EXTRA
|
||||
AssertIntEQ(wolfSSL_CTX_get_session_cache_mode(ctx) &
|
||||
WOLFSSL_SESS_CACHE_NO_INTERNAL_STORE,
|
||||
WOLFSSL_SESS_CACHE_NO_INTERNAL_STORE);
|
||||
#endif
|
||||
/* off - Donot setup external cache */
|
||||
|
||||
/* Require both peers to provide certs */
|
||||
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL);
|
||||
}
|
||||
|
||||
static void twcase_cache_intOn_extOff(WOLFSSL_CTX* ctx)
|
||||
{
|
||||
/* on - internal cache is on by default*/
|
||||
/* off - Donot setup external cache */
|
||||
/* Require both peers to provide certs */
|
||||
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL);
|
||||
}
|
||||
|
||||
static void twcase_cache_intOff_extOn(WOLFSSL_CTX* ctx)
|
||||
{
|
||||
/* off - Disable internal cache */
|
||||
AssertIntEQ(wolfSSL_CTX_set_session_cache_mode(ctx,
|
||||
WOLFSSL_SESS_CACHE_NO_INTERNAL_STORE), WOLFSSL_SUCCESS);
|
||||
#ifdef OPENSSL_EXTRA
|
||||
AssertIntEQ(wolfSSL_CTX_get_session_cache_mode(ctx) &
|
||||
WOLFSSL_SESS_CACHE_NO_INTERNAL_STORE,
|
||||
WOLFSSL_SESS_CACHE_NO_INTERNAL_STORE);
|
||||
#endif
|
||||
/* on - Enable external cache */
|
||||
wolfSSL_CTX_sess_set_new_cb(ctx, twcase_new_sessionCb);
|
||||
wolfSSL_CTX_sess_set_remove_cb(ctx, twcase_remove_sessionCb);
|
||||
wolfSSL_CTX_sess_set_get_cb(ctx, twcase_get_sessionCb);
|
||||
|
||||
/* Require both peers to provide certs */
|
||||
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL);
|
||||
}
|
||||
|
||||
static void twcase_cache_intOn_extOn(WOLFSSL_CTX* ctx)
|
||||
{
|
||||
/* on - internal cache is on by default */
|
||||
/* on - Enable external cache */
|
||||
wolfSSL_CTX_sess_set_new_cb(ctx, twcase_new_sessionCb);
|
||||
wolfSSL_CTX_sess_set_remove_cb(ctx, twcase_remove_sessionCb);
|
||||
wolfSSL_CTX_sess_set_get_cb(ctx, twcase_get_sessionCb);
|
||||
|
||||
/* Require both peers to provide certs */
|
||||
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL);
|
||||
}
|
||||
static void twcase_cache_intOn_extOn_noTicket(WOLFSSL_CTX* ctx)
|
||||
{
|
||||
/* on - internal cache is on by default */
|
||||
/* on - Enable external cache */
|
||||
wolfSSL_CTX_sess_set_new_cb(ctx, twcase_new_sessionCb);
|
||||
wolfSSL_CTX_sess_set_remove_cb(ctx, twcase_remove_sessionCb);
|
||||
wolfSSL_CTX_sess_set_get_cb(ctx, twcase_get_sessionCb);
|
||||
|
||||
wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TICKET);
|
||||
/* Require both peers to provide certs */
|
||||
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL);
|
||||
}
|
||||
static void twcase_server_sess_ctx_pre_shutdown(WOLFSSL* ssl)
|
||||
{
|
||||
WOLFSSL_SESSION** sess;
|
||||
if (wolfSSL_is_server(ssl))
|
||||
sess = &twcase_server_first_session_ptr;
|
||||
else
|
||||
return;
|
||||
|
||||
if (*sess == NULL) {
|
||||
AssertNotNull(*sess = wolfSSL_get1_session(ssl));
|
||||
/* 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
|
||||
* session from cache. */
|
||||
if (wolfSSL_is_server(ssl)
|
||||
#ifndef WOLFSSL_TICKET_HAVE_ID
|
||||
&& wolfSSL_version(ssl) != TLS1_3_VERSION
|
||||
&& wolfSSL_version(ssl) != DTLS1_3_VERSION
|
||||
#endif
|
||||
) {
|
||||
AssertIntEQ(wolfSSL_CTX_add_session(wolfSSL_get_SSL_CTX(ssl),
|
||||
*sess), WOLFSSL_SUCCESS);
|
||||
}
|
||||
}
|
||||
/* Save CTX to be able to decrypt tickets */
|
||||
if (twcase_server_current_ctx_ptr == NULL) {
|
||||
AssertNotNull(twcase_server_current_ctx_ptr = wolfSSL_get_SSL_CTX(ssl));
|
||||
AssertIntEQ(wolfSSL_CTX_up_ref(wolfSSL_get_SSL_CTX(ssl)),
|
||||
WOLFSSL_SUCCESS);
|
||||
}
|
||||
#ifdef SESSION_CERTS
|
||||
#ifndef WOLFSSL_TICKET_HAVE_ID
|
||||
if (wolfSSL_version(ssl) != TLS1_3_VERSION &&
|
||||
wolfSSL_session_reused(ssl))
|
||||
#endif
|
||||
{
|
||||
/* With WOLFSSL_TICKET_HAVE_ID the peer certs should be available
|
||||
* for all connections. TLS 1.3 only has tickets so if we don't
|
||||
* include the session id in the ticket then the certificates
|
||||
* will not be available on resumption. */
|
||||
WOLFSSL_X509* peer = wolfSSL_get_peer_certificate(ssl);
|
||||
AssertNotNull(peer);
|
||||
wolfSSL_X509_free(peer);
|
||||
AssertNotNull(wolfSSL_SESSION_get_peer_chain(*sess));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void twcase_client_sess_ctx_pre_shutdown(WOLFSSL* ssl)
|
||||
{
|
||||
WOLFSSL_SESSION** sess;
|
||||
sess = &twcase_client_first_session_ptr;
|
||||
if (*sess == NULL) {
|
||||
AssertNotNull(*sess = wolfSSL_get1_session(ssl));
|
||||
}
|
||||
else {
|
||||
/* If we have a session retrieved then remaining connections should be
|
||||
* resuming on that session */
|
||||
AssertIntEQ(wolfSSL_session_reused(ssl), 1);
|
||||
}
|
||||
|
||||
#ifdef SESSION_CERTS
|
||||
#ifndef WOLFSSL_TICKET_HAVE_ID
|
||||
if (wolfSSL_version(ssl) != TLS1_3_VERSION &&
|
||||
wolfSSL_session_reused(ssl))
|
||||
#endif
|
||||
{
|
||||
|
||||
WOLFSSL_X509* peer = wolfSSL_get_peer_certificate(ssl);
|
||||
AssertNotNull(peer);
|
||||
wolfSSL_X509_free(peer);
|
||||
AssertNotNull(wolfSSL_SESSION_get_peer_chain(*sess));
|
||||
#ifdef OPENSSL_EXTRA
|
||||
AssertNotNull(wolfSSL_SESSION_get0_peer(*sess));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
static void twcase_client_set_sess_ssl_ready(WOLFSSL* ssl)
|
||||
{
|
||||
/* Set the session to reuse for the client */
|
||||
AssertNotNull(ssl);
|
||||
AssertNotNull(twcase_client_first_session_ptr);
|
||||
AssertIntEQ(wolfSSL_set_session(ssl,twcase_client_first_session_ptr),
|
||||
WOLFSSL_SUCCESS);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int test_wolfSSL_CTX_add_session_ext(void)
|
||||
{
|
||||
int res = TEST_SKIPPED;
|
||||
#if defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(HAVE_EXT_CACHE) && \
|
||||
!defined(SINGLE_THREADED) && defined(WOLFSSL_TLS13) && \
|
||||
!defined(NO_SESSION_CACHE) && defined(OPENSSL_EXTRA) && \
|
||||
defined(SESSION_CERTS) && defined(HAVE_SESSION_TICKET) && \
|
||||
!defined(TITAN_SESSION_CACHE) && \
|
||||
!defined(HUGE_SESSION_CACHE) && \
|
||||
!defined(BIG_SESSION_CACHE) && \
|
||||
!defined(MEDIUM_SESSION_CACHE)
|
||||
/* Test the default 33 sessions */
|
||||
|
||||
struct test_params {
|
||||
method_provider client_meth;
|
||||
method_provider server_meth;
|
||||
const char* tls_version;
|
||||
} params[] = {
|
||||
#if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
|
||||
defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_TICKET_HAVE_ID)
|
||||
{ wolfTLSv1_3_client_method, wolfTLSv1_3_server_method, "TLSv1_3" },
|
||||
#ifdef WOLFSSL_DTLS13
|
||||
{ wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method, "DTLSv1_3" },
|
||||
#endif
|
||||
#endif
|
||||
#ifndef WOLFSSL_NO_TLS12
|
||||
{ wolfTLSv1_2_client_method, wolfTLSv1_2_server_method, "TLSv1_2" },
|
||||
#ifdef WOLFSSL_DTLS
|
||||
{ wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method, "DTLSv1_2" },
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(NO_OLD_TLS) && ((!defined(NO_AES) && !defined(NO_AES_CBC)) || \
|
||||
!defined(NO_DES3))
|
||||
{ wolfTLSv1_1_client_method, wolfTLSv1_1_server_method, "TLSv1_1" },
|
||||
#ifdef WOLFSSL_DTLS
|
||||
{ wolfDTLSv1_client_method, wolfDTLSv1_server_method, "DTLSv1_0" },
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
const int paramsLen = sizeof(params)/sizeof(*params);
|
||||
int i, j;
|
||||
|
||||
/* Clear cache before starting */
|
||||
wolfSSL_CTX_flush_sessions(NULL, -1);
|
||||
|
||||
XMEMSET(&server_sessionCache, 0, sizeof(hashTable));
|
||||
if (wc_InitMutex(&server_sessionCache.htLock) != 0)
|
||||
return BAD_MUTEX_E;
|
||||
server_sessionCache.capacity = SESSION_CACHE_SIZE;
|
||||
|
||||
for (i = 0; i < paramsLen; i++) {
|
||||
fprintf(stderr, "\tBegin %s\n", params[i].tls_version);
|
||||
for (j = 0; j < 5; j++) {
|
||||
int tls13 = XSTRSTR(params[i].tls_version, "TLSv1_3") != NULL;
|
||||
int dtls = XSTRSTR(params[i].tls_version, "DTLS") != NULL;
|
||||
callback_functions client_cb;
|
||||
callback_functions server_cb;
|
||||
|
||||
(void)dtls;
|
||||
|
||||
/* Test five cache configurations */
|
||||
twcase_client_first_session_ptr = NULL;
|
||||
twcase_server_first_session_ptr = NULL;
|
||||
twcase_server_current_ctx_ptr = NULL;
|
||||
twcase_new_session_called = 0;
|
||||
twcase_remove_session_called = 0;
|
||||
twcase_get_session_called = 0;
|
||||
|
||||
/* connection 1 - first connection */
|
||||
fprintf(stderr, "\tconnect: %s: j=%d, methodsLen=%d\n",
|
||||
params[i].tls_version, j, paramsLen);
|
||||
|
||||
XMEMSET(&client_cb, 0, sizeof(callback_functions));
|
||||
XMEMSET(&server_cb, 0, sizeof(callback_functions));
|
||||
client_cb.method = params[i].client_meth;
|
||||
server_cb.method = params[i].server_meth;
|
||||
|
||||
if (dtls)
|
||||
client_cb.doUdp = server_cb.doUdp = 1;
|
||||
|
||||
/* Setup internal and external cache */
|
||||
switch (j) {
|
||||
case 0:
|
||||
/* SSL_OP_NO_TICKET stateful ticket case */
|
||||
server_cb.ctx_ready = twcase_cache_intOn_extOn_noTicket;
|
||||
break;
|
||||
case 1:
|
||||
server_cb.ctx_ready = twcase_cache_intOn_extOn;
|
||||
break;
|
||||
case 2:
|
||||
server_cb.ctx_ready = twcase_cache_intOff_extOn;
|
||||
break;
|
||||
case 3:
|
||||
server_cb.ctx_ready = twcase_cache_intOn_extOff;
|
||||
break;
|
||||
case 4:
|
||||
server_cb.ctx_ready = twcase_cache_intOff_extOff;
|
||||
break;
|
||||
}
|
||||
client_cb.ctx_ready = twcase_cache_intOff_extOff;
|
||||
|
||||
/* Add session to internal cache and save SSL session for testing */
|
||||
server_cb.on_result = twcase_server_sess_ctx_pre_shutdown;
|
||||
/* Save client SSL session for testing */
|
||||
client_cb.on_result = twcase_client_sess_ctx_pre_shutdown;
|
||||
server_cb.ticNoInit = 1; /* Use default builtin */
|
||||
/* Don't free/release ctx */
|
||||
server_cb.ctx = twcase_server_current_ctx_ptr;
|
||||
server_cb.isSharedCtx = 1;
|
||||
|
||||
test_wolfSSL_client_server_nofail(&client_cb, &server_cb);
|
||||
|
||||
AssertTrue(client_cb.return_code);
|
||||
AssertTrue(server_cb.return_code);
|
||||
AssertIntEQ(twcase_get_session_called, 0);
|
||||
switch (j) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
/* cache cannot be searched with out a connection */
|
||||
/* Add a new session */
|
||||
AssertIntEQ(twcase_new_session_called, 1);
|
||||
/* In twcase_server_sess_ctx_pre_shutdown
|
||||
* wolfSSL_CTX_add_session which evicts the existing session
|
||||
* in cache and adds it back in */
|
||||
AssertIntLE(twcase_remove_session_called, 1);
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
/* no external cache */
|
||||
AssertIntEQ(twcase_new_session_called, 0);
|
||||
AssertIntEQ(twcase_remove_session_called, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
/* connection 2 - session resume */
|
||||
fprintf(stderr, "\tresume: %s: j=%d, methodsLen=%d\n",
|
||||
params[i].tls_version, j, paramsLen);
|
||||
twcase_new_session_called = 0;
|
||||
twcase_remove_session_called = 0;
|
||||
twcase_get_session_called = 0;
|
||||
server_cb.on_result = 0;
|
||||
client_cb.on_result = 0;
|
||||
server_cb.ticNoInit = 1; /* Use default builtin */
|
||||
|
||||
server_cb.ctx = twcase_server_current_ctx_ptr;
|
||||
|
||||
/* try session resumption */
|
||||
client_cb.ssl_ready = twcase_client_set_sess_ssl_ready;
|
||||
|
||||
test_wolfSSL_client_server_nofail(&client_cb, &server_cb);
|
||||
|
||||
AssertTrue(client_cb.return_code);
|
||||
AssertTrue(server_cb.return_code);
|
||||
|
||||
/* Clear cache before checking */
|
||||
wolfSSL_CTX_flush_sessions(NULL, -1);
|
||||
|
||||
switch (j) {
|
||||
case 0:
|
||||
if (tls13) {
|
||||
/* (D)TLSv1.3 stateful case */
|
||||
/* cache hit */
|
||||
/* DTLS accesses cache once for stateless parsing and
|
||||
* once for stateful parsing */
|
||||
AssertIntEQ(twcase_get_session_called, !dtls ? 1 : 2);
|
||||
|
||||
/* (D)TLSv1.3 creates a new ticket,
|
||||
* updates both internal and external cache */
|
||||
AssertIntEQ(twcase_new_session_called, 1);
|
||||
AssertIntEQ(twcase_remove_session_called, 1);
|
||||
|
||||
}
|
||||
else {
|
||||
/* non (D)TLSv1.3 case, no update */
|
||||
/* DTLS accesses cache once for stateless parsing and
|
||||
* once for stateful parsing */
|
||||
#ifdef WOLFSSL_DTLS_NO_HVR_ON_RESUME
|
||||
AssertIntEQ(twcase_get_session_called, !dtls ? 1 : 2);
|
||||
#else
|
||||
AssertIntEQ(twcase_get_session_called, 1);
|
||||
#endif
|
||||
AssertIntEQ(twcase_new_session_called, 0);
|
||||
/* Called on session added in
|
||||
* twcase_server_sess_ctx_pre_shutdown */
|
||||
AssertIntEQ(twcase_remove_session_called, 1);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (tls13) {
|
||||
/* (D)TLSv1.3 case */
|
||||
/* cache hit */
|
||||
AssertIntEQ(twcase_get_session_called, 1);
|
||||
/* (D)TLSv1.3 creates a new ticket,
|
||||
* updates both internal and external cache */
|
||||
AssertIntEQ(twcase_new_session_called, 1);
|
||||
/* Called on session added in
|
||||
* twcase_server_sess_ctx_pre_shutdown and by wolfSSL */
|
||||
AssertIntEQ(twcase_remove_session_called, 1);
|
||||
}
|
||||
else {
|
||||
/* non (D)TLSv1.3 case */
|
||||
/* cache hit */
|
||||
/* DTLS accesses cache once for stateless parsing and
|
||||
* once for stateful parsing */
|
||||
#ifdef WOLFSSL_DTLS_NO_HVR_ON_RESUME
|
||||
AssertIntEQ(twcase_get_session_called, !dtls ? 1 : 2);
|
||||
#else
|
||||
AssertIntEQ(twcase_get_session_called, 1);
|
||||
#endif
|
||||
AssertIntEQ(twcase_new_session_called, 0);
|
||||
/* Called on session added in
|
||||
* twcase_server_sess_ctx_pre_shutdown */
|
||||
AssertIntEQ(twcase_remove_session_called, 1);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (tls13) {
|
||||
/* (D)TLSv1.3 case */
|
||||
/* cache hit */
|
||||
AssertIntEQ(twcase_get_session_called, 1);
|
||||
/* (D)TLSv1.3 creates a new ticket,
|
||||
* updates both internal and external cache */
|
||||
AssertIntEQ(twcase_new_session_called, 1);
|
||||
/* Called on session added in
|
||||
* twcase_server_sess_ctx_pre_shutdown and by wolfSSL */
|
||||
AssertIntEQ(twcase_remove_session_called, 1);
|
||||
}
|
||||
else {
|
||||
/* non (D)TLSv1.3 case */
|
||||
/* cache hit */
|
||||
/* DTLS accesses cache once for stateless parsing and
|
||||
* once for stateful parsing */
|
||||
#ifdef WOLFSSL_DTLS_NO_HVR_ON_RESUME
|
||||
AssertIntEQ(twcase_get_session_called, !dtls ? 1 : 2);
|
||||
#else
|
||||
AssertIntEQ(twcase_get_session_called, 1);
|
||||
#endif
|
||||
AssertIntEQ(twcase_new_session_called, 0);
|
||||
/* Called on session added in
|
||||
* twcase_server_sess_ctx_pre_shutdown */
|
||||
AssertIntEQ(twcase_remove_session_called, 1);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
/* no external cache */
|
||||
AssertIntEQ(twcase_get_session_called, 0);
|
||||
AssertIntEQ(twcase_new_session_called, 0);
|
||||
AssertIntEQ(twcase_remove_session_called, 0);
|
||||
break;
|
||||
}
|
||||
wolfSSL_SESSION_free(twcase_client_first_session_ptr);
|
||||
wolfSSL_SESSION_free(twcase_server_first_session_ptr);
|
||||
wolfSSL_CTX_free(twcase_server_current_ctx_ptr);
|
||||
}
|
||||
twcase_get_sessionCb_cleanup();
|
||||
XMEMSET(&server_sessionCache.entries, 0,
|
||||
sizeof(server_sessionCache.entries));
|
||||
fprintf(stderr, "\tEnd %s\n", params[i].tls_version);
|
||||
}
|
||||
wc_FreeMutex(&server_sessionCache.htLock);
|
||||
res = TEST_RES_CHECK(1);
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SESSION_EXPORT)
|
||||
/* canned export of a session using older version 3 */
|
||||
@ -44888,14 +45474,10 @@ static int test_wolfSSL_CTX_sess_set_remove_cb(void)
|
||||
/* Both should have been allocated */
|
||||
AssertIntEQ(clientSessRemCountMalloc, 1);
|
||||
AssertIntEQ(serverSessRemCountMalloc, 1);
|
||||
#if (!defined(WOLFSSL_TLS13) || !defined(HAVE_SESSION_TICKET)) && \
|
||||
defined(NO_SESSION_CACHE_REF)
|
||||
/* Client session should not be added to cache so this should be free'd when
|
||||
* the SSL object was being free'd */
|
||||
AssertIntEQ(clientSessRemCountFree, 1);
|
||||
#else
|
||||
/* Client session is in cache due to requiring a persistent reference */
|
||||
/* This should not be called yet. Session wasn't evicted from cache yet. */
|
||||
AssertIntEQ(clientSessRemCountFree, 0);
|
||||
#if (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)) || \
|
||||
!defined(NO_SESSION_CACHE_REF)
|
||||
/* Force a cache lookup */
|
||||
AssertNotNull(SSL_SESSION_get_ex_data(clientSess, serverSessRemIdx));
|
||||
/* Force a cache update */
|
||||
@ -62297,6 +62879,8 @@ static int test_wolfSSL_SESSION_get_ex_new_index(void)
|
||||
SSL_SESSION_free(d);
|
||||
AssertIntEQ(test_wolfSSL_SESSION_get_ex_new_index_free_cb_called, 2);
|
||||
|
||||
crypto_ex_cb_free(crypto_ex_cb_ctx_session);
|
||||
crypto_ex_cb_ctx_session = NULL;
|
||||
return TEST_RES_CHECK(1);
|
||||
}
|
||||
#else
|
||||
@ -64972,6 +65556,7 @@ TEST_CASE testCases[] = {
|
||||
#ifdef HAVE_IO_TESTS_DEPENDENCIES
|
||||
TEST_DECL(test_wolfSSL_get_finished),
|
||||
TEST_DECL(test_wolfSSL_CTX_add_session),
|
||||
TEST_DECL(test_wolfSSL_CTX_add_session_ext),
|
||||
#endif
|
||||
TEST_DECL(test_SSL_CIPHER_get_xxx),
|
||||
TEST_DECL(test_wolfSSL_ERR_strings),
|
||||
|
@ -3212,6 +3212,18 @@ enum PskDecryptReturn {
|
||||
PSK_DECRYPT_FAIL,
|
||||
};
|
||||
|
||||
#ifdef HAVE_SESSION_TICKET
|
||||
typedef struct psk_sess_free_cb_ctx {
|
||||
word32 row;
|
||||
#ifdef HAVE_EXT_CACHE
|
||||
int extCache;
|
||||
int freeSess;
|
||||
#endif
|
||||
} psk_sess_free_cb_ctx;
|
||||
typedef void (psk_sess_free_cb)(const WOLFSSL* ssl, const WOLFSSL_SESSION* sess,
|
||||
psk_sess_free_cb_ctx* freeCtx);
|
||||
#endif
|
||||
|
||||
/* The PreSharedKey extension information - entry in a linked list. */
|
||||
typedef struct PreSharedKey {
|
||||
word16 identityLen; /* Length of identity */
|
||||
@ -3224,6 +3236,11 @@ typedef struct PreSharedKey {
|
||||
byte hmac; /* HMAC algorithm */
|
||||
#ifdef HAVE_SESSION_TICKET
|
||||
InternalTicket* it; /* ptr to ticket */
|
||||
const WOLFSSL_SESSION* sess; /* ptr to session either from external cache or
|
||||
* into SessionCache. Work around so that we
|
||||
* don't call into the cache more than once */
|
||||
psk_sess_free_cb* sess_free_cb; /* callback to free sess */
|
||||
psk_sess_free_cb_ctx sess_free_cb_ctx; /* info for sess_free_cb */
|
||||
#endif
|
||||
byte resumption:1; /* Resumption PSK */
|
||||
byte chosen:1; /* Server's choice */
|
||||
@ -4063,6 +4080,8 @@ struct WOLFSSL_SESSION {
|
||||
byte haveAltSessionID:1;
|
||||
#ifdef HAVE_EX_DATA
|
||||
byte ownExData:1;
|
||||
#endif
|
||||
#if defined(HAVE_EXT_CACHE) || defined(HAVE_EX_DATA)
|
||||
Rem_Sess_Cb rem_sess_cb;
|
||||
#endif
|
||||
void* heap;
|
||||
@ -4138,6 +4157,7 @@ struct WOLFSSL_SESSION {
|
||||
#ifdef HAVE_EX_DATA
|
||||
WOLFSSL_CRYPTO_EX_DATA ex_data;
|
||||
#endif
|
||||
byte isSetup:1;
|
||||
};
|
||||
|
||||
#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET) && \
|
||||
@ -4152,9 +4172,10 @@ 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 SetupSession(WOLFSSL* ssl);
|
||||
WOLFSSL_LOCAL void AddSession(WOLFSSL* ssl);
|
||||
/* use wolfSSL_API visibility to be able to test in tests/api.c */
|
||||
WOLFSSL_API int AddSessionToCache(WOLFSSL_CTX* ssl,
|
||||
WOLFSSL_API int AddSessionToCache(WOLFSSL_CTX* ctx,
|
||||
WOLFSSL_SESSION* addSession, const byte* id, byte idSz, int* sessionIndex,
|
||||
int side, word16 useTicket, ClientSession** clientCacheEntry);
|
||||
#ifndef NO_CLIENT_CACHE
|
||||
@ -4165,8 +4186,11 @@ WOLFSSL_LOCAL ClientSession* AddSessionToClientCache(int side, int row, int idx,
|
||||
WOLFSSL_LOCAL
|
||||
WOLFSSL_SESSION* ClientSessionToSession(const WOLFSSL_SESSION* session);
|
||||
WOLFSSL_LOCAL void TlsSessionCacheUnlockRow(word32 row);
|
||||
WOLFSSL_LOCAL int TlsSessionCacheGetAndLock(const byte *id,
|
||||
WOLFSSL_SESSION **sess, word32 *lockedRow, byte readOnly);
|
||||
WOLFSSL_LOCAL int TlsSessionCacheGetAndRdLock(const byte *id,
|
||||
const WOLFSSL_SESSION **sess, word32 *lockedRow, byte side);
|
||||
WOLFSSL_LOCAL int TlsSessionCacheGetAndWrLock(const byte *id,
|
||||
WOLFSSL_SESSION **sess, word32 *lockedRow, byte side);
|
||||
WOLFSSL_LOCAL void EvictSessionFromCache(WOLFSSL_SESSION* session);
|
||||
/* WOLFSSL_API to test it in tests/api.c */
|
||||
WOLFSSL_API int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output);
|
||||
WOLFSSL_LOCAL int wolfSSL_SetSession(WOLFSSL* ssl, WOLFSSL_SESSION* session);
|
||||
@ -5767,13 +5791,15 @@ WOLFSSL_LOCAL int SendTicket(WOLFSSL* ssl);
|
||||
WOLFSSL_LOCAL int DoDecryptTicket(const WOLFSSL* ssl, const byte* input,
|
||||
word32 len, InternalTicket **it);
|
||||
/* Return 0 when check successful. <0 on failure. */
|
||||
WOLFSSL_LOCAL void DoClientTicketFinalize(WOLFSSL* ssl, InternalTicket* it);
|
||||
WOLFSSL_LOCAL void DoClientTicketFinalize(WOLFSSL* ssl, InternalTicket* it,
|
||||
const WOLFSSL_SESSION* sess);
|
||||
|
||||
#ifdef WOLFSSL_TLS13
|
||||
WOLFSSL_LOCAL int DoClientTicketCheck(const WOLFSSL* ssl,
|
||||
const PreSharedKey* psk, sword64 timeout, const byte* suite);
|
||||
WOLFSSL_LOCAL void CleanupClientTickets(PreSharedKey* psk);
|
||||
WOLFSSL_LOCAL int DoClientTicket_ex(const WOLFSSL* ssl, PreSharedKey* psk);
|
||||
WOLFSSL_LOCAL int DoClientTicket_ex(const WOLFSSL* ssl, PreSharedKey* psk,
|
||||
int retainSess);
|
||||
#endif
|
||||
|
||||
WOLFSSL_LOCAL int DoClientTicket(WOLFSSL* ssl, const byte* input, word32 len);
|
||||
@ -6292,8 +6318,9 @@ typedef struct CRYPTO_EX_cb_ctx {
|
||||
WOLFSSL_CRYPTO_EX_dup* dup_func;
|
||||
struct CRYPTO_EX_cb_ctx* next;
|
||||
} CRYPTO_EX_cb_ctx;
|
||||
extern CRYPTO_EX_cb_ctx* crypto_ex_cb_ctx_session;
|
||||
WOLFSSL_LOCAL void crypto_ex_cb_free(CRYPTO_EX_cb_ctx* cb_ctx);
|
||||
/* use wolfSSL_API visibility to be able to clear in tests/api.c */
|
||||
WOLFSSL_API extern CRYPTO_EX_cb_ctx* crypto_ex_cb_ctx_session;
|
||||
WOLFSSL_API void crypto_ex_cb_free(CRYPTO_EX_cb_ctx* cb_ctx);
|
||||
WOLFSSL_LOCAL void crypto_ex_cb_setup_new_data(void *new_obj,
|
||||
CRYPTO_EX_cb_ctx* cb_ctx, WOLFSSL_CRYPTO_EX_DATA* ex_data);
|
||||
WOLFSSL_LOCAL void crypto_ex_cb_free_data(void *obj, CRYPTO_EX_cb_ctx* cb_ctx,
|
||||
|
@ -1235,6 +1235,7 @@ WOLFSSL_ABI WOLFSSL_API int wolfSSL_set_session(WOLFSSL* ssl, WOLFSSL_SESSION*
|
||||
WOLFSSL_API long wolfSSL_SSL_SESSION_set_timeout(WOLFSSL_SESSION* ses, long t);
|
||||
WOLFSSL_ABI WOLFSSL_API WOLFSSL_SESSION* wolfSSL_get_session(WOLFSSL* ssl);
|
||||
WOLFSSL_ABI WOLFSSL_API void wolfSSL_flush_sessions(WOLFSSL_CTX* ctx, long tm);
|
||||
WOLFSSL_API void wolfSSL_CTX_flush_sessions(WOLFSSL_CTX* ctx, long tm);
|
||||
WOLFSSL_API int wolfSSL_SetServerID(WOLFSSL* ssl, const unsigned char* id, int len, int newSession);
|
||||
|
||||
#if defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO) || defined(WOLFSSL_HAPROXY) \
|
||||
@ -4881,9 +4882,6 @@ WOLFSSL_API long wolfSSL_SSL_CTX_get_timeout(const WOLFSSL_CTX *ctx);
|
||||
WOLFSSL_API long wolfSSL_get_timeout(WOLFSSL* ssl);
|
||||
WOLFSSL_API int wolfSSL_SSL_CTX_set_tmp_ecdh(WOLFSSL_CTX *ctx,
|
||||
WOLFSSL_EC_KEY *ecdh);
|
||||
WOLFSSL_API int wolfSSL_SSL_CTX_remove_session(WOLFSSL_CTX* ctx,
|
||||
WOLFSSL_SESSION *c);
|
||||
|
||||
WOLFSSL_API WOLFSSL_BIO *wolfSSL_SSL_get_rbio(const WOLFSSL *s);
|
||||
WOLFSSL_API WOLFSSL_BIO *wolfSSL_SSL_get_wbio(const WOLFSSL *s);
|
||||
WOLFSSL_API int wolfSSL_SSL_do_handshake(WOLFSSL *s);
|
||||
@ -4899,6 +4897,8 @@ WOLFSSL_API int wolfSSL_SSL_in_init(WOLFSSL* ssl);
|
||||
WOLFSSL_API int wolfSSL_SSL_in_connect_init(WOLFSSL* ssl);
|
||||
|
||||
#ifndef NO_SESSION_CACHE
|
||||
WOLFSSL_API int wolfSSL_SSL_CTX_remove_session(WOLFSSL_CTX* ctx,
|
||||
WOLFSSL_SESSION *c);
|
||||
WOLFSSL_API WOLFSSL_SESSION *wolfSSL_SSL_get0_session(const WOLFSSL *s);
|
||||
#endif
|
||||
|
||||
@ -5166,6 +5166,7 @@ WOLFSSL_API int wolfSSL_dtls_cid_get_tx(WOLFSSL* ssl, unsigned char* buffer,
|
||||
#define TLS1_3_VERSION 0x0304
|
||||
#define DTLS1_VERSION 0xFEFF
|
||||
#define DTLS1_2_VERSION 0xFEFD
|
||||
#define DTLS1_3_VERSION 0xFEFC
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
Reference in New Issue
Block a user