forked from wolfSSL/wolfssl
Initial support for deep copying of session
This commit is contained in:
@ -2652,6 +2652,7 @@ void SSL_ResourceFree(WOLFSSL* ssl)
|
||||
#if defined(KEEP_PEER_CERT) || defined(GOAHEAD_WS)
|
||||
FreeX509(&ssl->peerCert);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SESSION_TICKET
|
||||
if (ssl->session.isDynamic) {
|
||||
XFREE(ssl->session.ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
|
||||
@ -2797,6 +2798,7 @@ void FreeHandshakeResources(WOLFSSL* ssl)
|
||||
#ifdef HAVE_QSH
|
||||
QSH_FreeAll(ssl);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SESSION_TICKET
|
||||
if (ssl->session.isDynamic) {
|
||||
XFREE(ssl->session.ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
|
||||
@ -15966,7 +15968,7 @@ int DoSessionTicket(WOLFSSL* ssl,
|
||||
if (ssl->options.resuming) { /* let's try */
|
||||
int ret = -1;
|
||||
WOLFSSL_SESSION* session = GetSession(ssl,
|
||||
ssl->arrays->masterSecret);
|
||||
ssl->arrays->masterSecret, 1);
|
||||
#ifdef HAVE_SESSION_TICKET
|
||||
if (ssl->options.useTicket == 1) {
|
||||
session = &ssl->session;
|
||||
@ -15981,9 +15983,6 @@ int DoSessionTicket(WOLFSSL* ssl,
|
||||
WOLFSSL_MSG("Unsupported cipher suite, OldClientHello");
|
||||
return UNSUPPORTED_SUITE;
|
||||
}
|
||||
#ifdef SESSION_CERTS
|
||||
ssl->session = *session; /* restore session certs. */
|
||||
#endif
|
||||
|
||||
ret = wc_RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom,
|
||||
RAN_LEN);
|
||||
@ -16361,7 +16360,7 @@ int DoSessionTicket(WOLFSSL* ssl,
|
||||
if (ssl->options.resuming) {
|
||||
int ret = -1;
|
||||
WOLFSSL_SESSION* session = GetSession(ssl,
|
||||
ssl->arrays->masterSecret);
|
||||
ssl->arrays->masterSecret, 1);
|
||||
#ifdef HAVE_SESSION_TICKET
|
||||
if (ssl->options.useTicket == 1) {
|
||||
session = &ssl->session;
|
||||
@ -16377,9 +16376,6 @@ int DoSessionTicket(WOLFSSL* ssl,
|
||||
WOLFSSL_MSG("Unsupported cipher suite, ClientHello");
|
||||
return UNSUPPORTED_SUITE;
|
||||
}
|
||||
#ifdef SESSION_CERTS
|
||||
ssl->session = *session; /* restore session certs. */
|
||||
#endif
|
||||
|
||||
ret = wc_RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom,
|
||||
RAN_LEN);
|
||||
|
@ -1560,7 +1560,7 @@ static int ProcessServerHello(const byte* input, int* sslBytes,
|
||||
if (doResume ) {
|
||||
int ret = 0;
|
||||
SSL_SESSION* resume = GetSession(session->sslServer,
|
||||
session->sslServer->arrays->masterSecret);
|
||||
session->sslServer->arrays->masterSecret, 0);
|
||||
if (resume == NULL) {
|
||||
SetError(BAD_SESSION_RESUME_STR, error, session, FATAL_ERROR_STATE);
|
||||
return -1;
|
||||
@ -1825,7 +1825,7 @@ static int ProcessFinished(const byte* input, int size, int* sslBytes,
|
||||
|
||||
if (ret == 0 && session->flags.cached == 0) {
|
||||
if (session->sslServer->options.haveSessionId) {
|
||||
WOLFSSL_SESSION* sess = GetSession(session->sslServer, NULL);
|
||||
WOLFSSL_SESSION* sess = GetSession(session->sslServer, NULL, 0);
|
||||
if (sess == NULL)
|
||||
AddSession(session->sslServer); /* don't re add */
|
||||
session->flags.cached = 1;
|
||||
|
149
src/ssl.c
149
src/ssl.c
@ -1265,29 +1265,34 @@ WOLFSSL_API int wolfSSL_set_SessionTicket(WOLFSSL* ssl, byte* buf, word32 bufSz)
|
||||
if (ssl == NULL || (buf == NULL && bufSz > 0))
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
/* Ticket will fit into static ticket */
|
||||
if(bufSz <= SESSION_TICKET_LEN) {
|
||||
if (ssl->session.isDynamic) {
|
||||
XFREE(ssl->session.ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
|
||||
ssl->session.isDynamic = 0;
|
||||
}
|
||||
if (bufSz > 0) {
|
||||
/* Ticket will fit into static ticket */
|
||||
if(bufSz <= SESSION_TICKET_LEN) {
|
||||
if (ssl->session.isDynamic) {
|
||||
XFREE(ssl->session.ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
|
||||
ssl->session.isDynamic = 0;
|
||||
}
|
||||
|
||||
ssl->session.ticket = ssl->session.staticTicket;
|
||||
ssl->session.ticketLen = (word16)bufSz;
|
||||
XMEMCPY(ssl->session.ticket, buf, bufSz);
|
||||
} else { /* Ticket requires dynamic ticket storage */
|
||||
/*Not big enough space, need to alloc */
|
||||
if (!(ssl->session.ticketLen >= bufSz)) {
|
||||
if(ssl->session.isDynamic)
|
||||
XFREE(ssl->session.ticket);
|
||||
ssl->session.ticket = XMALLOC(bufSz, ssl->heap, DYNAMIC_TYPE_TICK);
|
||||
if(!ssl->session.ticket)
|
||||
return MEMORY_ERROR;
|
||||
ssl->session.isDynamic = 1;
|
||||
ssl->session.ticket = ssl->session.staticTicket;
|
||||
ssl->session.ticketLen = (word16)bufSz;
|
||||
XMEMCPY(ssl->session.ticket, buf, bufSz);
|
||||
} else { /* Ticket requires dynamic ticket storage */
|
||||
/*Not big enough space, need to alloc */
|
||||
if (!(ssl->session.ticketLen >= bufSz)) {
|
||||
if(ssl->session.isDynamic)
|
||||
XFREE(ssl->session.ticket, ssl->heap,
|
||||
DYNAMIC_TYPE_SESSION_TICK);
|
||||
ssl->session.ticket = XMALLOC(bufSz, ssl->heap,
|
||||
DYNAMIC_TYPE_SESSION_TICK);
|
||||
if(!ssl->session.ticket)
|
||||
return MEMORY_ERROR;
|
||||
ssl->session.isDynamic = 1;
|
||||
}
|
||||
XMEMCPY(ssl->session.ticket, buf, bufSz);
|
||||
}
|
||||
XMEMCPY(ssl->session.ticket, buf, bufSz);
|
||||
ssl->session.ticketLen = bufSz;
|
||||
}
|
||||
ssl->session.ticketLen = (word16)bufSz;
|
||||
|
||||
return SSL_SUCCESS;
|
||||
}
|
||||
|
||||
@ -5201,7 +5206,7 @@ WOLFSSL_SESSION* wolfSSL_get_session(WOLFSSL* ssl)
|
||||
{
|
||||
WOLFSSL_ENTER("SSL_get_session");
|
||||
if (ssl)
|
||||
return GetSession(ssl, 0);
|
||||
return GetSession(ssl, 0, 0);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -6949,7 +6954,8 @@ WOLFSSL_SESSION* GetSessionClient(WOLFSSL* ssl, const byte* id, int len)
|
||||
#endif /* NO_CLIENT_CACHE */
|
||||
|
||||
|
||||
WOLFSSL_SESSION* GetSession(WOLFSSL* ssl, byte* masterSecret)
|
||||
WOLFSSL_SESSION* GetSession(WOLFSSL* ssl, byte* masterSecret,
|
||||
byte restoreSessionCerts)
|
||||
{
|
||||
WOLFSSL_SESSION* ret = 0;
|
||||
const byte* id = NULL;
|
||||
@ -6958,6 +6964,8 @@ WOLFSSL_SESSION* GetSession(WOLFSSL* ssl, byte* masterSecret)
|
||||
int count;
|
||||
int error = 0;
|
||||
|
||||
(void) restoreSessionCerts;
|
||||
|
||||
if (ssl->options.sessionCacheOff)
|
||||
return NULL;
|
||||
|
||||
@ -7005,6 +7013,17 @@ WOLFSSL_SESSION* GetSession(WOLFSSL* ssl, byte* masterSecret)
|
||||
ret = current;
|
||||
if (masterSecret)
|
||||
XMEMCPY(masterSecret, current->masterSecret, SECRET_LEN);
|
||||
#ifdef SESSION_CERTS
|
||||
/* If set, we should copy the session certs from the ssl object
|
||||
* to the session we are returning so we can resume */
|
||||
if (restoreSessionCerts) {
|
||||
ret->chain = ssl->session.chain;
|
||||
ret->version = ssl->session.version;
|
||||
ret->cipherSuite0 = ssl->session.cipherSuite0;
|
||||
ret->cipherSuite = ssl->session.cipherSuite;
|
||||
}
|
||||
#endif /* SESSION_CERTS */
|
||||
|
||||
} else {
|
||||
WOLFSSL_MSG("Session timed out");
|
||||
}
|
||||
@ -7020,13 +7039,92 @@ WOLFSSL_SESSION* GetSession(WOLFSSL* ssl, byte* masterSecret)
|
||||
}
|
||||
|
||||
|
||||
int GetDeepCopySession(WOLFSSL* ssl, WOLFSSL_SESSION* copyFrom)
|
||||
{
|
||||
int ticketLen;
|
||||
int doDynamicCopy;
|
||||
WOLFSSL_SESSION* copyInto = &ssl->session;
|
||||
void* tmpBuff = NULL;
|
||||
int ret = SSL_SUCCESS;
|
||||
|
||||
(void)ticketLen;
|
||||
(void)doDynamicCopy;
|
||||
(void)tmpBuff;
|
||||
|
||||
if (!ssl || !copyFrom)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
if (LockMutex(&session_mutex) != 0)
|
||||
return BAD_MUTEX_E;
|
||||
|
||||
#ifdef HAVE_SESSION_TICKET
|
||||
/* Free old dynamic ticket if we had one to avoid leak */
|
||||
if (copyInto->isDynamic) {
|
||||
XFREE(copyInto->ticket, ssl->heap, DYNAMIC_TYPE_SESS_TICK);
|
||||
copyInto->ticket = copyInto->staticTicket;
|
||||
copyInto->isDynamic = 0;
|
||||
}
|
||||
/* Size of ticket to alloc if needed; Use later for alloc outside lock */
|
||||
if (copyFrom) {
|
||||
doDynamicCopy = 1;
|
||||
ticketLen = copyFrom->ticketLen;
|
||||
}
|
||||
#endif
|
||||
|
||||
*copyInto = *copyFrom;
|
||||
if (UnLockMutex(&session_mutex) != 0) {
|
||||
return BAD_MUTEX_E;
|
||||
}
|
||||
|
||||
#ifdef HAVE_SESSION_TICKET
|
||||
/* If doing dynamic copy, need to alloc outside lock, then inside a lock
|
||||
* confirm the size still matches and memcpy */
|
||||
if (doDynamicCopy) {
|
||||
tmpBuff = XMALLOC(ticketLen, ssl->heap, DYNAMIC_TYPE_SESSION_TICK);
|
||||
if (!tmpBuff)
|
||||
return MEMORY_ERROR;
|
||||
|
||||
if (LockMutex(&session_mutex) != 0) {
|
||||
XFREE(tmpBuff, ssl->heap, DYNAMIC_TYPE_SESS_TICK);
|
||||
return BAD_MUTEX_E;
|
||||
}
|
||||
|
||||
if (ticketLen != copyFrom->ticketLen) {
|
||||
/* Another thread modified the ssl-> session ticket during alloc.
|
||||
* Treat as error, as ticket different than when copy requested */
|
||||
ret = VAR_STATE_CHANGE_E;
|
||||
}
|
||||
|
||||
if (ret == SSL_SUCCESS) {
|
||||
copyInto->ticket = tmpBuff;
|
||||
XMEMCPY(copyInto->ticket, copyFrom->ticket, ticketLen);
|
||||
}
|
||||
}
|
||||
|
||||
if (UnLockMutex(&session_mutex) != 0) {
|
||||
if (ret == SSL_SUCCESS)
|
||||
ret = BAD_MUTEX_E;
|
||||
}
|
||||
|
||||
if (ret != SSL_SUCCESS) {
|
||||
/* cleanup */
|
||||
if (tmpBuff)
|
||||
XFREE(tmpBuff, ssl->heap, DYNAMIC_TYPE_SESS_TICK);
|
||||
copyInto->ticket = copyInto->staticTicket;
|
||||
copyInto->isDynamic = 0;
|
||||
}
|
||||
#endif /* HAVE_SESSION_TICKET */
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int SetSession(WOLFSSL* ssl, WOLFSSL_SESSION* session)
|
||||
{
|
||||
if (ssl->options.sessionCacheOff)
|
||||
return SSL_FAILURE;
|
||||
|
||||
if (LowResTimer() < (session->bornOn + session->timeout)) {
|
||||
ssl->session = *session;
|
||||
GetDeepCopySession(ssl, session);
|
||||
ssl->options.resuming = 1;
|
||||
|
||||
#ifdef SESSION_CERTS
|
||||
@ -7034,7 +7132,6 @@ int SetSession(WOLFSSL* ssl, WOLFSSL_SESSION* session)
|
||||
ssl->options.cipherSuite0 = session->cipherSuite0;
|
||||
ssl->options.cipherSuite = session->cipherSuite;
|
||||
#endif
|
||||
|
||||
return SSL_SUCCESS;
|
||||
}
|
||||
return SSL_FAILURE; /* session timed out */
|
||||
@ -7397,10 +7494,12 @@ int wolfSSL_get_session_stats(word32* active, word32* total, word32* peak,
|
||||
#else /* NO_SESSION_CACHE */
|
||||
|
||||
/* No session cache version */
|
||||
WOLFSSL_SESSION* GetSession(WOLFSSL* ssl, byte* masterSecret)
|
||||
WOLFSSL_SESSION* GetSession(WOLFSSL* ssl, byte* masterSecret,
|
||||
byte restoreSessionCerts)
|
||||
{
|
||||
(void)ssl;
|
||||
(void)masterSecret;
|
||||
(void)restoreSessionCerts;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -101,6 +101,9 @@ const char* wc_GetErrorString(int error)
|
||||
case MEMORY_E :
|
||||
return "out of memory error";
|
||||
|
||||
case VAR_STATE_CHANGE_E :
|
||||
return "Variable state modified by different thread";
|
||||
|
||||
case RSA_WRONG_TYPE_E :
|
||||
return "RSA wrong block type for RSA function";
|
||||
|
||||
|
@ -2164,11 +2164,11 @@ struct WOLFSSL_X509_CHAIN {
|
||||
|
||||
/* wolfSSL session type */
|
||||
struct WOLFSSL_SESSION {
|
||||
word32 bornOn; /* create time in seconds */
|
||||
word32 timeout; /* timeout in seconds */
|
||||
byte sessionID[ID_LEN]; /* id for protocol */
|
||||
byte sessionIDSz;
|
||||
byte masterSecret[SECRET_LEN]; /* stored secret */
|
||||
word32 bornOn; /* create time in seconds */
|
||||
word32 timeout; /* timeout in seconds */
|
||||
byte sessionID[ID_LEN]; /* id for protocol */
|
||||
byte sessionIDSz;
|
||||
byte masterSecret[SECRET_LEN]; /* stored secret */
|
||||
#ifdef SESSION_CERTS
|
||||
WOLFSSL_X509_CHAIN chain; /* peer cert chain, static */
|
||||
ProtocolVersion version; /* which version was used */
|
||||
@ -2176,23 +2176,23 @@ struct WOLFSSL_SESSION {
|
||||
byte cipherSuite; /* 2nd byte, actual suite */
|
||||
#endif
|
||||
#ifndef NO_CLIENT_CACHE
|
||||
word16 idLen; /* serverID length */
|
||||
byte serverID[SERVER_ID_LEN]; /* for easier client lookup */
|
||||
word16 idLen; /* serverID length */
|
||||
byte serverID[SERVER_ID_LEN]; /* for easier client lookup */
|
||||
#endif
|
||||
#ifdef HAVE_SESSION_TICKET
|
||||
byte* ticket;
|
||||
word16 ticketLen;
|
||||
byte staticTicket[SESSION_TICKET_LEN];
|
||||
byte isDynamic;
|
||||
byte* ticket;
|
||||
word16 ticketLen;
|
||||
byte staticTicket[SESSION_TICKET_LEN];
|
||||
byte isDynamic;
|
||||
#endif
|
||||
#ifdef HAVE_STUNNEL
|
||||
void* ex_data[MAX_EX_DATA];
|
||||
void* ex_data[MAX_EX_DATA];
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
WOLFSSL_LOCAL
|
||||
WOLFSSL_SESSION* GetSession(WOLFSSL*, byte*);
|
||||
WOLFSSL_SESSION* GetSession(WOLFSSL*, byte*, byte);
|
||||
WOLFSSL_LOCAL
|
||||
int SetSession(WOLFSSL*, WOLFSSL_SESSION*);
|
||||
|
||||
|
@ -287,6 +287,7 @@ WOLFSSL_API void wolfSSL_set_quiet_shutdown(WOLFSSL*, int);
|
||||
WOLFSSL_API int wolfSSL_get_error(WOLFSSL*, int);
|
||||
WOLFSSL_API int wolfSSL_get_alert_history(WOLFSSL*, WOLFSSL_ALERT_HISTORY *);
|
||||
|
||||
WOLFSSL_API int GetDeepCopySession(WOLFSSL*, WOLFSSL_SESSION*);
|
||||
WOLFSSL_API int wolfSSL_set_session(WOLFSSL* ssl,WOLFSSL_SESSION* session);
|
||||
WOLFSSL_API long wolfSSL_SSL_SESSION_set_timeout(WOLFSSL_SESSION* session, long t);
|
||||
WOLFSSL_API WOLFSSL_SESSION* wolfSSL_get_session(WOLFSSL* ssl);
|
||||
|
@ -59,6 +59,8 @@ enum {
|
||||
MP_ZERO_E = -121, /* got a mp zero result, not expected */
|
||||
|
||||
MEMORY_E = -125, /* out of memory error */
|
||||
VAR_STATE_CHANGE_E = -126, /* var state modified by different thread */
|
||||
|
||||
|
||||
RSA_WRONG_TYPE_E = -130, /* RSA wrong block type for RSA function */
|
||||
RSA_BUFFER_E = -131, /* RSA buffer error, output too small or
|
||||
|
Reference in New Issue
Block a user