diff --git a/doc/dox_comments/header_files/ssl.h b/doc/dox_comments/header_files/ssl.h index 59bc6ae7b..6f0ec5994 100644 --- a/doc/dox_comments/header_files/ssl.h +++ b/doc/dox_comments/header_files/ssl.h @@ -11166,7 +11166,7 @@ WOLFSSL_API int wolfSSL_CTX_UseSessionTicket(WOLFSSL_CTX* ctx); if(wolfSSL_get_SessionTicket(ssl, buf, bufSz) <= 0){ // Nothing was written to the buffer } else { - // the buffer holds the content from ssl->session.ticket + // the buffer holds the content from ssl->session->ticket } \endcode diff --git a/src/internal.c b/src/internal.c index 04cdd3589..8ba08423e 100644 --- a/src/internal.c +++ b/src/internal.c @@ -6629,18 +6629,14 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) } #endif /*OPENSSL_EXTRA && HAVE_SECRET_CALLBACK */ - ssl->session.heap = ssl->heap; - ssl->session.type = WOLFSSL_SESSION_TYPE_SSL; - ssl->session.masterSecret = ssl->session._masterSecret; -#ifndef NO_CLIENT_CACHE - ssl->session.serverID = ssl->session._serverID; -#endif -#ifdef OPENSSL_EXTRA - ssl->session.sessionCtx = ssl->session._sessionCtx; -#endif + ssl->session = wolfSSL_NewSession(ssl->heap); + if (ssl->session == NULL) { + WOLFSSL_MSG("SSL Session Memory error"); + return MEMORY_E; + } + #ifdef HAVE_SESSION_TICKET ssl->options.noTicketTls12 = ctx->noTicketTls12; - ssl->session.ticket = ssl->session._staticTicket; #endif #ifdef WOLFSSL_MULTICAST @@ -6687,10 +6683,10 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) void FreeArrays(WOLFSSL* ssl, int keep) { if (ssl->arrays) { - if (keep) { + if (keep && !IsAtLeastTLSv1_3(ssl->version)) { /* keeps session id for user retrieval */ - XMEMCPY(ssl->session.sessionID, ssl->arrays->sessionID, ID_LEN); - ssl->session.sessionIDSz = ssl->arrays->sessionIDSz; + XMEMCPY(ssl->session->sessionID, ssl->arrays->sessionID, ID_LEN); + ssl->session->sessionIDSz = ssl->arrays->sessionIDSz; } if (ssl->arrays->preMasterSecret) { XFREE(ssl->arrays->preMasterSecret, ssl->heap, DYNAMIC_TYPE_SECRET); @@ -7224,17 +7220,8 @@ void SSL_ResourceFree(WOLFSSL* ssl) FreeX509(&ssl->peerCert); #endif -#ifdef HAVE_SESSION_TICKET - if (ssl->session.ticketLenAlloc > 0) { - XFREE(ssl->session.ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK); - ssl->session.ticket = ssl->session._staticTicket; - ssl->session.ticketLenAlloc = 0; - ssl->session.ticketLen = 0; - } -#endif -#ifdef HAVE_EXT_CACHE - wolfSSL_SESSION_free(ssl->extSession); -#endif + if (ssl->session != NULL) + wolfSSL_FreeSession(ssl->session); #ifdef HAVE_WRITE_DUP if (ssl->dupWrite) { FreeWriteDup(ssl); @@ -7501,15 +7488,6 @@ void FreeHandshakeResources(WOLFSSL* ssl) } #endif /* HAVE_PK_CALLBACKS */ -#ifdef HAVE_SESSION_TICKET - if (ssl->session.ticketLenAlloc > 0) { - XFREE(ssl->session.ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK); - ssl->session.ticket = ssl->session._staticTicket; - ssl->session.ticketLenAlloc = 0; - ssl->session.ticketLen = 0; - } -#endif - #if defined(HAVE_TLS_EXTENSIONS) && !defined(HAVE_SNI) && \ !defined(HAVE_ALPN) && !defined(WOLFSSL_POST_HANDSHAKE_AUTH) /* Some extensions need to be kept for post-handshake querying. */ @@ -11369,7 +11347,7 @@ int DoVerifyCallback(WOLFSSL_CERT_MANAGER* cm, WOLFSSL* ssl, int ret, } #endif #ifdef SESSION_CERTS - store->sesChain = &ssl->session.chain; + store->sesChain = &ssl->session->chain; #endif } #ifndef NO_WOLFSSL_CM_VERIFY @@ -11439,9 +11417,9 @@ int DoVerifyCallback(WOLFSSL_CERT_MANAGER* cm, WOLFSSL* ssl, int ret, #ifdef SESSION_CERTS if ((ssl != NULL) && (store->discardSessionCerts)) { WOLFSSL_MSG("Verify callback requested discard sess certs"); - ssl->session.chain.count = 0; + ssl->session->chain.count = 0; #ifdef WOLFSSL_ALT_CERT_CHAINS - ssl->session.altChain.count = 0; + ssl->session->altChain.count = 0; #endif } #endif /* SESSION_CERTS */ @@ -12083,7 +12061,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, args->certs[args->totalCerts].buffer = input + args->idx; #ifdef SESSION_CERTS - AddSessionCertToChain(&ssl->session.chain, + AddSessionCertToChain(&ssl->session->chain, input + args->idx, certSz); #endif /* SESSION_CERTS */ @@ -12378,7 +12356,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, #if defined(SESSION_CERTS) && defined(WOLFSSL_ALT_CERT_CHAINS) /* if using alternate chain, store the cert used */ if (ssl->options.usingAltCertChain) { - AddSessionCertToChain(&ssl->session.altChain, + AddSessionCertToChain(&ssl->session->altChain, cert->buffer, cert->length); } #endif /* SESSION_CERTS && WOLFSSL_ALT_CERT_CHAINS */ @@ -12474,7 +12452,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, /* if using alternate chain, store the cert used */ if (ssl->options.usingAltCertChain) { buffer* cert = &args->certs[args->certIdx]; - AddSessionCertToChain(&ssl->session.altChain, + AddSessionCertToChain(&ssl->session->altChain, cert->buffer, cert->length); } #endif /* SESSION_CERTS && WOLFSSL_ALT_CERT_CHAINS */ @@ -13271,9 +13249,9 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, #ifdef SESSION_CERTS /* Reset the session cert chain count in case the session resume failed. */ - ssl->session.chain.count = 0; + ssl->session->chain.count = 0; #ifdef WOLFSSL_ALT_CERT_CHAINS - ssl->session.altChain.count = 0; + ssl->session->altChain.count = 0; #endif #endif /* SESSION_CERTS */ @@ -22761,7 +22739,7 @@ exit_dpk: return BAD_FUNC_ARG; } - idSz = ssl->options.resuming ? ssl->session.sessionIDSz : 0; + idSz = ssl->options.resuming ? ssl->session->sessionIDSz : 0; #ifdef WOLFSSL_TLS13 if (IsAtLeastTLSv1_3(ssl->version)) @@ -22777,11 +22755,11 @@ exit_dpk: } #ifdef HAVE_SESSION_TICKET - if (ssl->options.resuming && ssl->session.ticketLen > 0) { + if (ssl->options.resuming && ssl->session->ticketLen > 0) { SessionTicket* ticket; - ticket = TLSX_SessionTicket_Create(0, ssl->session.ticket, - ssl->session.ticketLen, ssl->heap); + ticket = TLSX_SessionTicket_Create(0, ssl->session->ticket, + ssl->session->ticketLen, ssl->heap); if (ticket == NULL) return MEMORY_E; ret = TLSX_UseSessionTicket(&ssl->extensions, ticket, ssl->heap); @@ -22870,9 +22848,9 @@ exit_dpk: /* then session id */ output[idx++] = (byte)idSz; if (idSz) { - XMEMCPY(output + idx, ssl->session.sessionID, - ssl->session.sessionIDSz); - idx += ssl->session.sessionIDSz; + XMEMCPY(output + idx, ssl->session->sessionID, + ssl->session->sessionIDSz); + idx += ssl->session->sessionIDSz; } /* then DTLS cookie */ @@ -23069,12 +23047,12 @@ exit_dpk: #ifdef HAVE_SESSION_TICKET /* server may send blank ticket which may not be expected to indicate * existing one ok but will also be sending a new one */ - ret = ret || (ssl->session.ticketLen > 0); + ret = ret || (ssl->session->ticketLen > 0); #endif ret = ret || (ssl->options.haveSessionId && XMEMCMP(ssl->arrays->sessionID, - ssl->session.sessionID, ID_LEN) == 0); + ssl->session->sessionID, ID_LEN) == 0); return ret; } @@ -23412,7 +23390,7 @@ exit_dpk: #ifdef HAVE_SECRET_CALLBACK if (ssl->sessionSecretCb != NULL) { int secretSz = SECRET_LEN; - ret = ssl->sessionSecretCb(ssl, ssl->session.masterSecret, + ret = ssl->sessionSecretCb(ssl, ssl->session->masterSecret, &secretSz, ssl->sessionSecretCtx); if (ret != 0 || secretSz != SECRET_LEN) return SESSION_SECRET_CB_E; @@ -23470,7 +23448,7 @@ exit_dpk: if (SetCipherSpecs(ssl) == 0) { XMEMCPY(ssl->arrays->masterSecret, - ssl->session.masterSecret, SECRET_LEN); + ssl->session->masterSecret, SECRET_LEN); #ifdef NO_OLD_TLS ret = DeriveTlsKeys(ssl); #else @@ -26742,27 +26720,27 @@ exit_scv: int SetTicket(WOLFSSL* ssl, const byte* ticket, word32 length) { /* Free old dynamic ticket if we already had one */ - if (ssl->session.ticketLenAlloc > 0) { - XFREE(ssl->session.ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK); - ssl->session.ticket = ssl->session._staticTicket; - ssl->session.ticketLenAlloc = 0; + if (ssl->session->ticketLenAlloc > 0) { + XFREE(ssl->session->ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK); + ssl->session->ticket = ssl->session->_staticTicket; + ssl->session->ticketLenAlloc = 0; } - if (length > sizeof(ssl->session._staticTicket)) { + if (length > sizeof(ssl->session->_staticTicket)) { byte* sessionTicket = (byte*)XMALLOC(length, ssl->heap, DYNAMIC_TYPE_SESSION_TICK); if (sessionTicket == NULL) return MEMORY_E; - ssl->session.ticket = sessionTicket; - ssl->session.ticketLenAlloc = (word16)length; + ssl->session->ticket = sessionTicket; + ssl->session->ticketLenAlloc = (word16)length; } - ssl->session.ticketLen = (word16)length; + ssl->session->ticketLen = (word16)length; if (length > 0) { - XMEMCPY(ssl->session.ticket, ticket, length); + XMEMCPY(ssl->session->ticket, ticket, length); if (ssl->session_ticket_cb != NULL) { ssl->session_ticket_cb(ssl, - ssl->session.ticket, ssl->session.ticketLen, + ssl->session->ticket, ssl->session->ticketLen, ssl->session_ticket_ctx); } /* Create a fake sessionID based on the ticket, this will @@ -26770,13 +26748,13 @@ int SetTicket(WOLFSSL* ssl, const byte* ticket, word32 length) ssl->options.haveSessionId = 1; #ifdef WOLFSSL_TLS13 if (ssl->options.tls1_3) { - XMEMCPY(ssl->session.sessionID, - ssl->session.ticket + length - ID_LEN, ID_LEN); + XMEMCPY(ssl->session->sessionID, + ssl->session->ticket + length - ID_LEN, ID_LEN); } else #endif XMEMCPY(ssl->arrays->sessionID, - ssl->session.ticket + length - ID_LEN, ID_LEN); + ssl->session->ticket + length - ID_LEN, ID_LEN); } return 0; @@ -29271,7 +29249,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, (void)bogusID; #ifdef HAVE_SESSION_TICKET if (ssl->options.useTicket == 1) { - session = &ssl->session; + session = ssl->session; } else if (bogusID == 1 && ssl->options.rejectTicket == 0) { WOLFSSL_MSG("Bogus session ID without session ticket"); return BUFFER_ERROR; @@ -30582,7 +30560,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, int CreateTicket(WOLFSSL* ssl) { InternalTicket it; - ExternalTicket* et = (ExternalTicket*)ssl->session.ticket; + ExternalTicket* et = (ExternalTicket*)ssl->session->ticket; int encLen; int ret; byte zeros[WOLFSSL_TICKET_MAC_SZ]; /* biggest cmp size */ @@ -30614,12 +30592,12 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, sizeof(it.ageAdd)); if (ret != 0) return BAD_TICKET_ENCRYPT; - ssl->session.ticketAdd = it.ageAdd; - it.namedGroup = ssl->session.namedGroup; + ssl->session->ticketAdd = it.ageAdd; + it.namedGroup = ssl->session->namedGroup; it.timestamp = TimeNowInMilliseconds(); /* Resumption master secret. */ - XMEMCPY(it.msecret, ssl->session.masterSecret, SECRET_LEN); - XMEMCPY(&it.ticketNonce, &ssl->session.ticketNonce, + XMEMCPY(it.msecret, ssl->session->masterSecret, SECRET_LEN); + XMEMCPY(&it.ticketNonce, &ssl->session->ticketNonce, sizeof(TicketNonce)); #endif } @@ -30627,12 +30605,12 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #ifdef WOLFSSL_TICKET_HAVE_ID { const byte* id = NULL; - if (ssl->options.haveTicketSessionID) - id = ssl->ticketSessionID; + if (ssl->session->haveAltSessionID) + id = ssl->session->altSessionID; else if (!IsAtLeastTLSv1_3(ssl->version) && ssl->arrays != NULL) id = ssl->arrays->sessionID; else - id = ssl->session.sessionID; + id = ssl->session->sessionID; XMEMCPY(it.id, id, ID_LEN); } #endif @@ -30702,7 +30680,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, /* set size */ c16toa((word16)encLen, et->enc_len); - ssl->session.ticketLen = (word16)(encLen + WOLFSSL_TICKET_FIXED_SZ); + ssl->session->ticketLen = (word16)(encLen + WOLFSSL_TICKET_FIXED_SZ); if (encLen < WOLFSSL_TICKET_ENC_SZ) { /* move mac up since whole enc buffer not used */ XMEMMOVE(et->enc_ticket +encLen, et->mac,WOLFSSL_TICKET_MAC_SZ); @@ -30795,8 +30773,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #ifdef WOLFSSL_TICKET_HAVE_ID { - ssl->options.haveTicketSessionID = 1; - XMEMCPY(ssl->ticketSessionID, it.id, ID_LEN); + 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"); @@ -30812,28 +30790,28 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, XMEMCPY(ssl->arrays->masterSecret, it.msecret, SECRET_LEN); /* Copy the haveExtendedMasterSecret property from the ticket to * the saved session, so the property may be checked later. */ - ssl->session.haveEMS = it.haveEMS; - ato32((const byte*)&it.timestamp, &ssl->session.bornOn); + ssl->session->haveEMS = it.haveEMS; + ato32((const byte*)&it.timestamp, &ssl->session->bornOn); #ifndef NO_RESUME_SUITE_CHECK - ssl->session.cipherSuite0 = it.suite[0]; - ssl->session.cipherSuite = it.suite[1]; + ssl->session->cipherSuite0 = it.suite[0]; + ssl->session->cipherSuite = it.suite[1]; #endif } else { #ifdef WOLFSSL_TLS13 /* Restore information to renegotiate. */ - ssl->session.ticketSeen = it.timestamp; - ssl->session.ticketAdd = it.ageAdd; - ssl->session.cipherSuite0 = it.suite[0]; - ssl->session.cipherSuite = it.suite[1]; + ssl->session->ticketSeen = it.timestamp; + ssl->session->ticketAdd = it.ageAdd; + ssl->session->cipherSuite0 = it.suite[0]; + ssl->session->cipherSuite = it.suite[1]; #ifdef WOLFSSL_EARLY_DATA - ssl->session.maxEarlyDataSz = it.maxEarlyDataSz; + ssl->session->maxEarlyDataSz = it.maxEarlyDataSz; #endif /* Resumption master secret. */ - XMEMCPY(ssl->session.masterSecret, it.msecret, SECRET_LEN); - XMEMCPY(&ssl->session.ticketNonce, &it.ticketNonce, + XMEMCPY(ssl->session->masterSecret, it.msecret, SECRET_LEN); + XMEMCPY(&ssl->session->ticketNonce, &it.ticketNonce, sizeof(TicketNonce)); - ssl->session.namedGroup = it.namedGroup; + ssl->session->namedGroup = it.namedGroup; #endif } } @@ -30864,7 +30842,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if (ret != 0) return ret; } - length += ssl->session.ticketLen; + length += ssl->session->ticketLen; sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ; if (!ssl->options.dtls) { @@ -30896,12 +30874,12 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, idx += SESSION_HINT_SZ; /* length */ - c16toa(ssl->session.ticketLen, output + idx); + c16toa(ssl->session->ticketLen, output + idx); idx += LENGTH_SZ; /* ticket */ - XMEMCPY(output + idx, ssl->session.ticket, ssl->session.ticketLen); - idx += ssl->session.ticketLen; + XMEMCPY(output + idx, ssl->session->ticket, ssl->session->ticketLen); + idx += ssl->session->ticketLen; if (IsEncryptionOn(ssl, 1) && ssl->options.handShakeDone) { byte* input; diff --git a/src/sniffer.c b/src/sniffer.c index 2e35e1487..8eae315c8 100644 --- a/src/sniffer.c +++ b/src/sniffer.c @@ -3044,9 +3044,9 @@ static int ProcessSessionTicket(const byte* input, int* sslBytes, *sslBytes -= OPAQUE8_LEN; #ifdef HAVE_SESSION_TICKET /* store nonce in server for DeriveResumptionPSK */ - session->sslServer->session.ticketNonce.len = len; + session->sslServer->session->ticketNonce.len = len; if (len > 0) - XMEMCPY(&session->sslServer->session.ticketNonce.data, input, len); + XMEMCPY(&session->sslServer->session->ticketNonce.data, input, len); #endif input += len; *sslBytes -= len; @@ -3123,7 +3123,7 @@ static int DoResume(SnifferSession* session, char* error) #ifdef WOLFSSL_TLS13 if (IsAtLeastTLSv1_3(session->sslServer->version)) { resume = wolfSSL_GetSession(session->sslServer, - session->sslServer->session.masterSecret, 0); + session->sslServer->session->masterSecret, 0); if (resume == NULL) { /* TLS v1.3 with hello_retry uses session_id even for new session, so ignore error here */ @@ -3147,8 +3147,8 @@ static int DoResume(SnifferSession* session, char* error) /* make sure client has master secret too */ #ifdef WOLFSSL_TLS13 if (IsAtLeastTLSv1_3(session->sslServer->version)) { - XMEMCPY(session->sslClient->session.masterSecret, - session->sslServer->session.masterSecret, SECRET_LEN); + XMEMCPY(session->sslClient->session->masterSecret, + session->sslServer->session->masterSecret, SECRET_LEN); } else #endif @@ -3179,8 +3179,8 @@ static int DoResume(SnifferSession* session, char* error) session->sslServer->arrays->psk_keySz = session->sslServer->specs.hash_size; session->sslClient->arrays->psk_keySz = session->sslClient->specs.hash_size; ret = DeriveResumptionPSK(session->sslServer, - session->sslServer->session.ticketNonce.data, - session->sslServer->session.ticketNonce.len, + session->sslServer->session->ticketNonce.data, + session->sslServer->session->ticketNonce.len, session->sslServer->arrays->psk_key); /* Copy resumption PSK to client */ XMEMCPY(session->sslClient->arrays->psk_key, @@ -3266,7 +3266,7 @@ static int ProcessServerHello(int msgSz, const byte* input, int* sslBytes, } if (b) { #ifdef WOLFSSL_TLS13 - XMEMCPY(session->sslServer->session.sessionID, input, ID_LEN); + XMEMCPY(session->sslServer->session->sessionID, input, ID_LEN); #endif XMEMCPY(session->sslServer->arrays->sessionID, input, ID_LEN); session->sslServer->options.haveSessionId = 1; @@ -3370,10 +3370,10 @@ static int ProcessServerHello(int msgSz, const byte* input, int* sslBytes, session->sslClient->options.resuming = 1; #ifdef WOLFSSL_TLS13 /* default nonce to len = 1, data = 0 */ - session->sslServer->session.ticketNonce.len = 1; - session->sslServer->session.ticketNonce.data[0] = 0; - session->sslClient->session.ticketNonce.len = 1; - session->sslClient->session.ticketNonce.data[0] = 0; + session->sslServer->session->ticketNonce.len = 1; + session->sslServer->session->ticketNonce.data[0] = 0; + session->sslClient->session->ticketNonce.len = 1; + session->sslClient->session->ticketNonce.data[0] = 0; #endif break; #endif @@ -3595,7 +3595,7 @@ static int ProcessClientHello(const byte* input, int* sslBytes, } Trace(CLIENT_RESUME_TRY_STR); #ifdef WOLFSSL_TLS13 - XMEMCPY(session->sslClient->session.sessionID, input, ID_LEN); + XMEMCPY(session->sslClient->session->sessionID, input, ID_LEN); #endif if (session->sslClient->arrays) XMEMCPY(session->sslClient->arrays->sessionID, input, ID_LEN); @@ -4014,14 +4014,14 @@ static int ProcessFinished(const byte* input, int size, int* sslBytes, #ifdef HAVE_SESSION_TICKET /* derive resumption secret for next session - on finished (from client) */ ret += DeriveResumptionSecret(session->sslClient, - session->sslClient->session.masterSecret); + session->sslClient->session->masterSecret); /* copy resumption secret to server */ - XMEMCPY(session->sslServer->session.masterSecret, - session->sslClient->session.masterSecret, SECRET_LEN); + XMEMCPY(session->sslServer->session->masterSecret, + session->sslClient->session->masterSecret, SECRET_LEN); #ifdef SHOW_SECRETS PrintSecret("resumption secret", - session->sslClient->session.masterSecret, SECRET_LEN); + session->sslClient->session->masterSecret, SECRET_LEN); #endif #endif } diff --git a/src/ssl.c b/src/ssl.c index 21346570f..a14e27af0 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -3321,9 +3321,9 @@ WOLFSSL_API int wolfSSL_get_SessionTicket(WOLFSSL* ssl, if (ssl == NULL || buf == NULL || bufSz == NULL || *bufSz == 0) return BAD_FUNC_ARG; - if (ssl->session.ticketLen <= *bufSz) { - XMEMCPY(buf, ssl->session.ticket, ssl->session.ticketLen); - *bufSz = ssl->session.ticketLen; + if (ssl->session->ticketLen <= *bufSz) { + XMEMCPY(buf, ssl->session->ticket, ssl->session->ticketLen); + *bufSz = ssl->session->ticketLen; } else *bufSz = 0; @@ -3340,32 +3340,32 @@ WOLFSSL_API int wolfSSL_set_SessionTicket(WOLFSSL* ssl, const byte* buf, if (bufSz > 0) { /* Ticket will fit into static ticket */ if (bufSz <= SESSION_TICKET_LEN) { - if (ssl->session.ticketLenAlloc > 0) { - XFREE(ssl->session.ticket, ssl->heap, + if (ssl->session->ticketLenAlloc > 0) { + XFREE(ssl->session->ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK); - ssl->session.ticketLenAlloc = 0; - ssl->session.ticket = ssl->session._staticTicket; + ssl->session->ticketLenAlloc = 0; + ssl->session->ticket = ssl->session->_staticTicket; } } else { /* Ticket requires dynamic ticket storage */ - if (ssl->session.ticketLen < bufSz) { /* is dyn buffer big enough */ - if (ssl->session.ticketLenAlloc > 0) { - XFREE(ssl->session.ticket, ssl->heap, + if (ssl->session->ticketLen < bufSz) { /* is dyn buffer big enough */ + if (ssl->session->ticketLenAlloc > 0) { + XFREE(ssl->session->ticket, ssl->heap, DYNAMIC_TYPE_SESSION_TICK); } - ssl->session.ticket = (byte*)XMALLOC(bufSz, ssl->session.heap, + ssl->session->ticket = (byte*)XMALLOC(bufSz, ssl->session->heap, DYNAMIC_TYPE_SESSION_TICK); - if(ssl->session.ticket == NULL) { - ssl->session.ticket = ssl->session._staticTicket; - ssl->session.ticketLenAlloc = 0; + if(ssl->session->ticket == NULL) { + ssl->session->ticket = ssl->session->_staticTicket; + ssl->session->ticketLenAlloc = 0; return MEMORY_ERROR; } - ssl->session.ticketLenAlloc = (word16)bufSz; + ssl->session->ticketLenAlloc = (word16)bufSz; } } - XMEMCPY(ssl->session.ticket, buf, bufSz); + XMEMCPY(ssl->session->ticket, buf, bufSz); } - ssl->session.ticketLen = (word16)bufSz; + ssl->session->ticketLen = (word16)bufSz; return WOLFSSL_SUCCESS; } @@ -12483,7 +12483,7 @@ WOLFSSL_SESSION* wolfSSL_get_session(WOLFSSL* ssl) { WOLFSSL_ENTER("SSL_get_session"); if (ssl) - return &ssl->session; + return ssl->session; return NULL; } @@ -12494,37 +12494,8 @@ WOLFSSL_SESSION* wolfSSL_get1_session(WOLFSSL* ssl) WOLFSSL_SESSION* sess = NULL; WOLFSSL_ENTER("SSL_get1_session"); if (ssl != NULL) { -#ifdef HAVE_EXT_CACHE - sess = &ssl->session; - if (ssl->extSession == NULL) { - ssl->extSession = sess = wolfSSL_SESSION_new(); - if (wolfSSL_DupSession(&ssl->session, sess, 0) - != WOLFSSL_SUCCESS) { - sess = NULL; - } -#ifdef WOLFSSL_TICKET_HAVE_ID - /* Set the real session ID for the independent session object */ - if (sess != NULL && ssl->options.haveTicketSessionID) { - XMEMCPY(sess->sessionID, ssl->ticketSessionID, ID_LEN); - sess->sessionIDSz = ID_LEN; - } -#endif - } - else - sess = ssl->extSession; -#else - sess = wolfSSL_SESSION_new(); + sess = ssl->session; if (sess != NULL) { - if (wolfSSL_DupSession(&ssl->session, sess, 0) - != WOLFSSL_SUCCESS) { - wolfSSL_SESSION_free(sess); - sess = NULL; - } - } -#endif - if (sess != NULL) { - /* wolfSSL_get_session returns either static cache or ref. If ref then - * increase reference counter */ /* increase reference count if allocated session */ if (sess->type == WOLFSSL_SESSION_TYPE_HEAP) { if (wolfSSL_SESSION_up_ref(sess) != WOLFSSL_SUCCESS) @@ -12595,8 +12566,8 @@ int wolfSSL_SetServerID(WOLFSSL* ssl, const byte* id, int len, int newSession) if (session == NULL) { WOLFSSL_MSG("Valid ServerID not cached already"); - ssl->session.idLen = (word16)min(SERVER_ID_LEN, (word32)len); - XMEMCPY(ssl->session.serverID, id, ssl->session.idLen); + ssl->session->idLen = (word16)min(SERVER_ID_LEN, (word32)len); + XMEMCPY(ssl->session->serverID, id, ssl->session->idLen); } #ifdef HAVE_EXT_CACHE else { @@ -12990,7 +12961,7 @@ int wolfSSL_set_session_secret_cb(WOLFSSL* ssl, SessionSecretCb cb, void* ctx) ssl->sessionSecretCb = cb; ssl->sessionSecretCtx = ctx; /* If using a pre-set key, assume session resumption. */ - ssl->session.sessionIDSz = 0; + ssl->session->sessionIDSz = 0; ssl->options.resuming = 1; return WOLFSSL_SUCCESS; @@ -15447,9 +15418,8 @@ int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output) #if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA) WOLFSSL_X509* peer = NULL; #endif -#ifdef WOLFSSL_TICKET_HAVE_ID byte bogusID[ID_LEN]; -#endif + byte bogusIDSz = 0; WOLFSSL_ENTER("wolfSSL_GetSessionFromCache"); @@ -15458,7 +15428,7 @@ int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output) return WOLFSSL_FAILURE; } - if (SslSessionCacheOff(ssl, &ssl->session)) + if (SslSessionCacheOff(ssl, ssl->session)) return WOLFSSL_FAILURE; if (ssl->options.haveSessionId == 0) @@ -15471,17 +15441,17 @@ int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output) if (!IsAtLeastTLSv1_3(ssl->version) && ssl->arrays != NULL) id = ssl->arrays->sessionID; - else - id = ssl->session.sessionID; - -#ifdef WOLFSSL_TICKET_HAVE_ID - if (ssl->options.haveTicketSessionID) { - id = ssl->ticketSessionID; + else if (ssl->session->haveAltSessionID) { + id = ssl->session->altSessionID; /* We want to restore the bogus ID for TLS compatibility */ - if (output->type == WOLFSSL_SESSION_TYPE_SSL) - XMEMCPY(bogusID, ssl->session.sessionID, ID_LEN); + if (output == ssl->session) { + XMEMCPY(bogusID, ssl->session->sessionID, ID_LEN); + bogusIDSz = ssl->session->sessionIDSz; + } } -#endif + else + id = ssl->session->sessionID; + #ifdef HAVE_EXT_CACHE if (ssl->ctx->get_sess_cb != NULL) { @@ -15495,12 +15465,12 @@ int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output) /* If copy not set then free immediately */ if (!copy) wolfSSL_SESSION_free(sess); -#ifdef WOLFSSL_TICKET_HAVE_ID /* We want to restore the bogus ID for TLS compatibility */ - if (ssl->options.haveTicketSessionID && - output->type == WOLFSSL_SESSION_TYPE_SSL) - XMEMCPY(ssl->session.sessionID, bogusID, ID_LEN); -#endif + if (ssl->session->haveAltSessionID && + output == ssl->session) { + XMEMCPY(ssl->session->sessionID, bogusID, ID_LEN); + ssl->session->sessionIDSz = bogusIDSz; + } return error; } WOLFSSL_MSG("Session not found in external cache"); @@ -15591,23 +15561,28 @@ int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output) idx = idx > 0 ? idx - 1 : SESSIONS_PER_ROW - 1; } + if (sess != NULL) { #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; - } + /* 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 - error = wolfSSL_DupSession(sess, output, 1); + error = wolfSSL_DupSession(sess, output, 1); + } + else { + error = WOLFSSL_FAILURE; + } SESSION_ROW_UNLOCK(sessRow); -#ifdef WOLFSSL_TICKET_HAVE_ID /* We want to restore the bogus ID for TLS compatibility */ - if (ssl->options.haveTicketSessionID && - output->type == WOLFSSL_SESSION_TYPE_SSL) - XMEMCPY(ssl->session.sessionID, bogusID, ID_LEN); -#endif + if (ssl->session->haveAltSessionID && + output == ssl->session) { + XMEMCPY(ssl->session->sessionID, bogusID, ID_LEN); + ssl->session->sessionIDSz = bogusIDSz; + } #ifdef HAVE_SESSION_TICKET if (tmpBufSet) { @@ -15658,19 +15633,13 @@ WOLFSSL_SESSION* wolfSSL_GetSession(WOLFSSL* ssl, byte* masterSecret, (void)restoreSessionCerts; /* Kept for compatibility */ - if (wolfSSL_GetSessionFromCache(ssl, &ssl->session) == WOLFSSL_SUCCESS) - ret = &ssl->session; + if (wolfSSL_GetSessionFromCache(ssl, ssl->session) == WOLFSSL_SUCCESS) { + ret = ssl->session; + } else { WOLFSSL_MSG("wolfSSL_GetSessionFromCache did not return a session"); } -#ifdef HAVE_EXT_CACHE - if (ret == NULL && ssl->extSession != NULL) { - WOLFSSL_MSG("Found dynamic session"); - ret = ssl->extSession; - } -#endif - if (ret != NULL && masterSecret != NULL) XMEMCPY(masterSecret, ret->masterSecret, SECRET_LEN); @@ -15698,15 +15667,21 @@ int wolfSSL_SetSession(WOLFSSL* ssl, WOLFSSL_SESSION* session) return WOLFSSL_FAILURE; } - if (wolfSSL_DupSession(session, &ssl->session, 0) != WOLFSSL_SUCCESS) { + if (wolfSSL_DupSession(session, ssl->session, 0) != WOLFSSL_SUCCESS) { WOLFSSL_MSG("Session duplicate failed"); return WOLFSSL_FAILURE; } + /* Let's copy over the altSessionID for local cache purposes */ + if (session->haveAltSessionID) { + ssl->session->haveAltSessionID = 1; + XMEMCPY(ssl->session->altSessionID, session->altSessionID, ID_LEN); + } + #ifdef OPENSSL_EXTRA /* check for application context id */ if (ssl->sessionCtxSz > 0) { - if (XMEMCMP(ssl->sessionCtx, ssl->session.sessionCtx, ssl->sessionCtxSz)) { + if (XMEMCMP(ssl->sessionCtx, ssl->session->sessionCtx, ssl->sessionCtxSz)) { /* context id did not match! */ WOLFSSL_MSG("Session context did not match"); return WOLFSSL_FAILURE; @@ -15714,23 +15689,23 @@ int wolfSSL_SetSession(WOLFSSL* ssl, WOLFSSL_SESSION* session) } #endif /* OPENSSL_EXTRA */ - if (LowResTimer() < (ssl->session.bornOn + ssl->session.timeout)) { + if (LowResTimer() < (ssl->session->bornOn + ssl->session->timeout)) { ssl->options.resuming = 1; - ssl->options.haveEMS = ssl->session.haveEMS; + ssl->options.haveEMS = ssl->session->haveEMS; #if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \ defined(HAVE_SESSION_TICKET)) - ssl->version = ssl->session.version; + 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; + 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; + ssl->peerVerifyRet = (unsigned long)ssl->session->peerVerifyRet; #endif ret = WOLFSSL_SUCCESS; } @@ -15752,31 +15727,203 @@ static int get_locked_session_stats(word32* active, word32* total, word32* peak); #endif -int AddSession(WOLFSSL* ssl) +#ifndef NO_CLIENT_CACHE +int AddSessionToClientCache(int side, int row, int idx, byte* serverID, + word16 idLen, word16 useTicket) { - int row = INVALID_SESSION_ROW; + int error = 0; + (void)useTicket; + if (side == WOLFSSL_CLIENT_END + && row != INVALID_SESSION_ROW + && (idLen +#ifdef HAVE_SESSION_TICKET + || useTicket == 1 +#endif + )) { + word32 clientRow, clientIdx; + + WOLFSSL_MSG("Adding client cache entry"); + + clientRow = HashSession(serverID, + idLen, &error) % SESSION_ROWS; + if (error == 0 && wc_LockMutex(&clisession_mutex) == 0) { + clientIdx = ClientCache[clientRow].nextIdx++; + ClientCache[clientRow].Clients[clientIdx].serverRow = + (word16)row; + ClientCache[clientRow].Clients[clientIdx].serverIdx = + (word16)idx; + if (ClientCache[clientRow].totalCount < SESSIONS_PER_ROW) + ClientCache[clientRow].totalCount++; + ClientCache[clientRow].nextIdx %= SESSIONS_PER_ROW; + + wc_UnLockMutex(&clisession_mutex); + } + else { + WOLFSSL_MSG("Hash session failed"); + } + } + else { + WOLFSSL_MSG("Skipping client cache"); + } + return error; +} +#endif + +int AddSessionToCache(WOLFSSL_SESSION* addSession, const byte* id, + int* sessionIndex, int side, word16 useTicket) +{ + WOLFSSL_SESSION* cacheSession = NULL; + SessionRow* sessRow = NULL; word32 idx = 0; - int error = 0; - const byte* id = NULL; +#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA) + WOLFSSL_X509* peer = NULL; +#endif #ifdef HAVE_SESSION_TICKET byte* ticBuff = NULL; int ticLen = 0; #endif - WOLFSSL_SESSION* session; + int ret = 0; + int row; int i; int overwrite = 0; + + (void)sessionIndex; + (void)useTicket; + + if (addSession == NULL) + return BAD_FUNC_ARG; + + /* Find a position for the new session in cache and use that */ +#ifdef HAVE_SESSION_TICKET + ticLen = addSession->ticketLen; + /* Alloc Memory here to avoid syscalls during lock */ + if (ticLen > SESSION_TICKET_LEN) { + ticBuff = (byte*)XMALLOC(ticLen, addSession->heap, + DYNAMIC_TYPE_SESSION_TICK); + if (ticBuff == NULL) { + return MEMORY_E; + } + } +#endif + /* Use the session object in the cache for external cache if required */ + row = (int)(HashSession(id, ID_LEN, &ret) % SESSION_ROWS); + if (ret != 0) { + WOLFSSL_MSG("Hash session failed"); + #ifdef HAVE_SESSION_TICKET + XFREE(ticBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK); + #endif + return ret; + } + + sessRow = &SessionCache[row]; + if (SESSION_ROW_LOCK(sessRow) != 0) { + #ifdef HAVE_SESSION_TICKET + XFREE(ticBuff, addSession->heap, DYNAMIC_TYPE_SESSION_TICK); + #endif + return BAD_MUTEX_E; + } + + for (i = 0; i < SESSIONS_PER_ROW && i < sessRow->totalCount; i++) { + if (XMEMCMP(id, + sessRow->Sessions[i].sessionID, ID_LEN) == 0 && + sessRow->Sessions[i].side == side) { + WOLFSSL_MSG("Session already exists. Overwriting."); + overwrite = 1; + idx = i; + break; + } + } + + if (!overwrite) + idx = sessRow->nextIdx; +#ifdef SESSION_INDEX + if (sessionIndex != NULL) + *sessionIndex = (row << SESSIDX_ROW_SHIFT) | idx; +#endif + cacheSession = &sessRow->Sessions[idx]; + cacheSession->type = WOLFSSL_SESSION_TYPE_CACHE; + cacheSession->cacheRow = row; + +#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA) + /* Save the peer field to free after unlocking the row */ + if (cacheSession->peer != NULL) + peer = cacheSession->peer; + cacheSession->peer = NULL; +#endif +#ifdef HAVE_SESSION_TICKET + if (ticBuff != NULL) { + cacheSession->ticket = ticBuff; + cacheSession->ticketLenAlloc = ticLen; + } +#endif +#ifdef SESSION_CERTS + if (overwrite && + addSession->chain.count == 0 && + cacheSession->chain.count > 0) { + /* Copy in the certs from the session */ + addSession->chain.count = cacheSession->chain.count; + XMEMCPY(addSession->chain.certs, cacheSession->chain.certs, + sizeof(x509_buffer) * cacheSession->chain.count); + } +#endif /* SESSION_CERTS */ + /* Copy data into the cache object */ + ret = wolfSSL_DupSession(addSession, cacheSession, 1) == WOLFSSL_FAILURE; + + 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 (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_SESSION_TICKET + else if (ticBuff != NULL) { + /* Error occured. Need to clean up the ticket buffer. */ + cacheSession->ticket = cacheSession->_staticTicket; + cacheSession->ticketLenAlloc = 0; + cacheSession->ticketLen = 0; + } +#endif + + SESSION_ROW_UNLOCK(sessRow); + cacheSession = NULL; /* Can't access after unlocked */ + +#ifndef NO_CLIENT_CACHE + if (ret == 0) + ret = AddSessionToClientCache(side, row, idx, addSession->serverID, + addSession->idLen, useTicket); +#endif + +#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA) + if (peer != NULL) { + wolfSSL_X509_free(peer); + peer = NULL; /* Make sure not use after this point */ + } +#endif + + return ret; +} + +#ifndef NO_CLIENT_CACHE +#endif + +int AddSession(WOLFSSL* ssl) +{ + int error = 0; + const byte* id = NULL; + WOLFSSL_SESSION* session = ssl->session; #ifdef HAVE_EXT_CACHE int cbRet = 0; - byte sessionAlloc = 0; -#endif - SessionRow* sessRow = NULL; -#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA) - WOLFSSL_X509* peer = NULL; #endif WOLFSSL_ENTER("AddSession"); - if (SslSessionCacheOff(ssl, &ssl->session)) { + if (SslSessionCacheOff(ssl, session)) { WOLFSSL_MSG("Cache off"); return 0; } @@ -15794,15 +15941,18 @@ int AddSession(WOLFSSL* ssl) } #endif - if (!IsAtLeastTLSv1_3(ssl->version) && ssl->arrays != NULL) - id = ssl->arrays->sessionID; - else - id = ssl->session.sessionID; + if (session->haveAltSessionID) + id = session->altSessionID; + 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; + } -#ifdef WOLFSSL_TICKET_HAVE_ID - if (ssl->options.haveTicketSessionID) - id = ssl->ticketSessionID; -#endif if (id == NULL) { WOLFSSL_MSG("No Session ID"); @@ -15810,222 +15960,63 @@ int AddSession(WOLFSSL* ssl) } /* Setup the ssl->session object */ - ssl->session.timeout = ssl->timeout; - ssl->session.side = (byte)ssl->options.side; - if (ssl->arrays != NULL -#ifdef WOLFSSL_TLS13 - && !IsAtLeastTLSv1_3(ssl->version) -#endif - ) { - XMEMCPY(ssl->session.masterSecret, ssl->arrays->masterSecret, SECRET_LEN); - ssl->session.sessionIDSz = ssl->arrays->sessionIDSz; - } - ssl->session.haveEMS = ssl->options.haveEMS; + 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); - ssl->session.sessionCtxSz = ssl->sessionCtxSz; + XMEMCPY(ssl->session->sessionCtx, ssl->sessionCtx, ssl->sessionCtxSz); + session->sessionCtxSz = ssl->sessionCtxSz; } #endif - ssl->session.timeout = ssl->timeout; - ssl->session.bornOn = LowResTimer(); + session->timeout = ssl->timeout; + session->bornOn = LowResTimer(); #if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \ defined(HAVE_SESSION_TICKET)) - ssl->session.version = ssl->version; + session->version = ssl->version; #endif #if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \ (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)) - ssl->session.cipherSuite0 = ssl->options.cipherSuite0; - ssl->session.cipherSuite = ssl->options.cipherSuite; + session->cipherSuite0 = ssl->options.cipherSuite0; + session->cipherSuite = ssl->options.cipherSuite; #endif #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) - ssl->session.peerVerifyRet = (byte)ssl->peerVerifyRet; + session->peerVerifyRet = (byte)ssl->peerVerifyRet; #endif /* Setup done */ -#ifdef HAVE_SESSION_TICKET - ticLen = ssl->session.ticketLen; - /* Alloc Memory here so if Malloc fails can exit outside of lock */ - if (ticLen > SESSION_TICKET_LEN) { - ticBuff = (byte*)XMALLOC(ticLen, ssl->heap, DYNAMIC_TYPE_SESSION_TICK); - if (ticBuff == NULL) { - return MEMORY_E; - } - } -#endif - #ifdef HAVE_EXT_CACHE - if (ssl->options.internalCacheOff) { - /* Create a new session object to be stored or use the existing - * one. */ - if (ssl->extSession != NULL) { - session = ssl->extSession; - } - else { - ssl->extSession = session = wolfSSL_SESSION_new(); - if (session == NULL) { - #ifdef HAVE_SESSION_TICKET - XFREE(ticBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK); - #endif - return MEMORY_E; - } - } - sessionAlloc = 1; - } - else + if (!ssl->options.internalCacheOff) #endif { - /* Use the session object in the cache for external cache if required */ - row = (int)(HashSession(id, ID_LEN, &error) % SESSION_ROWS); - if (error != 0) { - WOLFSSL_MSG("Hash session failed"); - #ifdef HAVE_SESSION_TICKET - XFREE(ticBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK); - #endif - return error; - } - - sessRow = &SessionCache[row]; - if (SESSION_ROW_LOCK(sessRow) != 0) { - #ifdef HAVE_SESSION_TICKET - XFREE(ticBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK); - #endif - return BAD_MUTEX_E; - } - - for (i=0; i < SESSIONS_PER_ROW && i < sessRow->totalCount; i++) { - if (XMEMCMP(id, - sessRow->Sessions[i].sessionID, ID_LEN) == 0 && - sessRow->Sessions[i].side == ssl->options.side) { - WOLFSSL_MSG("Session already exists. Overwriting."); - overwrite = 1; - idx = i; - break; - } - } - - if (!overwrite) { - idx = sessRow->nextIdx++; - if (sessRow->totalCount < SESSIONS_PER_ROW) - sessRow->totalCount++; - if (sessRow->nextIdx >= SESSIONS_PER_ROW) - sessRow->nextIdx = 0; - } + error = AddSessionToCache(session, id, #ifdef SESSION_INDEX - ssl->sessionIndex = (row << SESSIDX_ROW_SHIFT) | idx; + &ssl->sessionIndex, +#else + NULL, #endif - session = &sessRow->Sessions[idx]; - session->type = WOLFSSL_SESSION_TYPE_CACHE; - session->cacheRow = row; - } -#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA) - /* We don't care about the peer field */ - if (session->peer != NULL) - peer = session->peer; - session->peer = NULL; -#endif - -#ifdef SESSION_CERTS - if (error == 0) { - if (ssl->session.chain.count == 0 && - session->chain.count > 0) { - /* Copy in the certs from the session */ - ssl->session.chain.count = session->chain.count; - XMEMCPY(ssl->session.chain.certs, session->chain.certs, - sizeof(x509_buffer) * session->chain.count); - } - } -#endif /* SESSION_CERTS */ - - if (error == 0) { + ssl->options.side, #ifdef HAVE_SESSION_TICKET - if (ticBuff != NULL) { - session->ticket = ticBuff; - session->ticketLenAlloc = ticLen; - } + ssl->options.useTicket +#else + 0 #endif - - /* Copy data into the session object */ - error = wolfSSL_DupSession(&ssl->session, session, - session->type == WOLFSSL_SESSION_TYPE_CACHE) == WOLFSSL_FAILURE; - - /* ssl->session.sessionID may contain the bogus ID or we want the ID from - * the arrays objects */ - XMEMCPY(session->sessionID, id, ID_LEN); - session->sessionIDSz = ID_LEN; + ); } -#ifdef HAVE_SESSION_TICKET - if (error != 0 && ticBuff != NULL) { - session->ticket = session->_staticTicket; - session->ticketLenAlloc = 0; - session->ticketLen = 0; - } -#endif - #ifdef HAVE_EXT_CACHE if (error == 0 && ssl->ctx->new_sess_cb != NULL) { - if (sessionAlloc) - wolfSSL_SESSION_up_ref(session); + wolfSSL_SESSION_up_ref(session); cbRet = ssl->ctx->new_sess_cb(ssl, session); - if (sessionAlloc && cbRet == 0) + if (cbRet == 0) wolfSSL_FreeSession(session); } #endif - if (sessRow != NULL) { - SESSION_ROW_UNLOCK(sessRow); - session = NULL; /* Can't access after this point */ - } - -#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA) - if (peer != NULL) { - wolfSSL_X509_free(peer); - peer = NULL; /* Make sure not use after this point */ - } -#endif - -#ifndef NO_CLIENT_CACHE - /* Make sure to do this outside of the lock. This way we don't */ - if (error == 0) { - if (ssl->options.side == WOLFSSL_CLIENT_END - && row != INVALID_SESSION_ROW - && (ssl->session.idLen -#ifdef HAVE_SESSION_TICKET - || ssl->options.useTicket == 1 -#endif - )) { - word32 clientRow, clientIdx; - - WOLFSSL_MSG("Adding client cache entry"); - - clientRow = HashSession(ssl->session.serverID, - ssl->session.idLen, &error) % SESSION_ROWS; - if (error == 0 && wc_LockMutex(&clisession_mutex) == 0) { - clientIdx = ClientCache[clientRow].nextIdx++; - ClientCache[clientRow].Clients[clientIdx].serverRow = - (word16)row; - ClientCache[clientRow].Clients[clientIdx].serverIdx = - (word16)idx; - if (ClientCache[clientRow].totalCount < SESSIONS_PER_ROW) - ClientCache[clientRow].totalCount++; - if (ClientCache[clientRow].nextIdx >= SESSIONS_PER_ROW) - ClientCache[clientRow].nextIdx = 0; - - wc_UnLockMutex(&clisession_mutex); - } - else { - WOLFSSL_MSG("Hash session failed"); - } - } - else { - WOLFSSL_MSG("Skipping client cache"); - } - } -#endif /* !NO_CLIENT_CACHE */ - #if defined(WOLFSSL_SESSION_STATS) && defined(WOLFSSL_PEAK_SESSIONS) if (error == 0) { word32 active = 0; @@ -16041,11 +16032,6 @@ int AddSession(WOLFSSL* ssl) } #endif /* WOLFSSL_SESSION_STATS && WOLFSSL_PEAK_SESSIONS */ -#ifdef HAVE_SESSION_TICKET - if (ticBuff != NULL && error != 0) - XFREE(ticBuff, ssl->heap, DYNAMIC_TYPE_SESSION_TICK); -#endif - return error; } @@ -20357,7 +20343,7 @@ size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out, #endif } #ifdef SESSION_CERTS - ssl->session.chain.count = 0; + ssl->session->chain.count = 0; #endif #ifdef KEEP_PEER_CERT FreeX509(&ssl->peerCert); @@ -20739,9 +20725,9 @@ size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out, if (ssl->peerCert.issuer.sz) ret = wolfSSL_X509_dup(&ssl->peerCert); #ifdef SESSION_CERTS - else if (ssl->session.chain.count > 0) { - if (DecodeToX509(&ssl->peerCert, ssl->session.chain.certs[0].buffer, - ssl->session.chain.certs[0].length) == 0) { + else if (ssl->session->chain.count > 0) { + if (DecodeToX509(&ssl->peerCert, ssl->session->chain.certs[0].buffer, + ssl->session->chain.certs[0].length) == 0) { ret = wolfSSL_X509_dup(&ssl->peerCert); } } @@ -20828,11 +20814,11 @@ WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_set_peer_cert_chain(WOLFSSL* ssl) int ret; WOLFSSL_ENTER("wolfSSL_set_peer_cert_chain"); - if ((ssl == NULL) || (ssl->session.chain.count == 0)) + if ((ssl == NULL) || (ssl->session->chain.count == 0)) return NULL; sk = wolfSSL_sk_X509_new(); - i = ssl->session.chain.count-1; + i = ssl->session->chain.count-1; for (; i >= 0; i--) { x509 = wolfSSL_X509_new(); if (x509 == NULL) { @@ -20840,10 +20826,10 @@ WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_set_peer_cert_chain(WOLFSSL* ssl) wolfSSL_sk_X509_pop_free(sk, NULL); return NULL; } - ret = DecodeToX509(x509, ssl->session.chain.certs[i].buffer, - ssl->session.chain.certs[i].length); + ret = DecodeToX509(x509, ssl->session->chain.certs[i].buffer, + ssl->session->chain.certs[i].length); #if !defined(WOLFSSL_QT) - if (ret == 0 && i == ssl->session.chain.count-1) { + if (ret == 0 && i == ssl->session->chain.count-1) { /* On the last element in the chain try to add the CA chain * first if we have one for this cert */ if (PushCAx509Chain(SSL_CM(ssl), x509, sk) @@ -23676,6 +23662,14 @@ WOLFSSL_SESSION* wolfSSL_NewSession(void* heap) DYNAMIC_TYPE_SESSION); if (ret != NULL) { XMEMSET(ret, 0, sizeof(WOLFSSL_SESSION)); + #ifndef SINGLE_THREADED + if (wc_InitMutex(&ret->refMutex) != 0) { + WOLFSSL_MSG("Error setting up session reference mutex"); + XFREE(ret, ret->heap, DYNAMIC_TYPE_SESSION); + return NULL; + } + #endif + ret->refCount = 1; ret->cacheRow = INVALID_SESSION_ROW; /* not in cache */ ret->type = WOLFSSL_SESSION_TYPE_HEAP; ret->heap = heap; @@ -23689,16 +23683,6 @@ WOLFSSL_SESSION* wolfSSL_NewSession(void* heap) #ifdef HAVE_SESSION_TICKET ret->ticket = ret->_staticTicket; #endif -#ifdef OPENSSL_EXTRA -#ifndef SINGLE_THREADED - if (wc_InitMutex(&ret->refMutex) != 0) { - WOLFSSL_MSG("Error setting up session reference mutex"); - XFREE(ret, ret->heap, DYNAMIC_TYPE_SESSION); - return NULL; - } -#endif - ret->refCount = 1; -#endif #ifdef HAVE_STUNNEL /* stunnel has this funny mechanism of storing the "is_authenticated" * session info in the session ex data. This is basically their @@ -23809,6 +23793,7 @@ int wolfSSL_DupSession(const WOLFSSL_SESSION* input, WOLFSSL_SESSION* output, else if (!avoidSysCalls) output->peer = wolfSSL_X509_dup(input->peer); else + /* output->peer is not that important to copy */ output->peer = NULL; #endif output->masterSecret = output->_masterSecret; @@ -23939,6 +23924,7 @@ void wolfSSL_FreeSession(WOLFSSL_SESSION* session) #ifndef SINGLE_THREADED if (wc_LockMutex(&session->refMutex) != 0) { WOLFSSL_MSG("Failed to lock session mutex"); + return; } #endif if (session->refCount > 1) { @@ -23985,19 +23971,10 @@ void wolfSSL_SESSION_free(WOLFSSL_SESSION* session) wolfSSL_FreeSession(session); } -#ifdef HAVE_EXT_CACHE -/* HAVE_EXT_CACHE is needed for wolfSSL_SESSION_dup to work. Also without this - * define the input session will already always be in the session cache. */ int wolfSSL_CTX_add_session(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* session) { - word32 row; int error = 0; - SessionRow* sessRow = NULL; - int i; - int overwrite = 0; - word32 idx = 0; - WOLFSSL_SESSION* copy; - WOLFSSL_SESSION* cacheSess; + const byte* id = NULL; WOLFSSL_ENTER("wolfSSL_CTX_add_session"); @@ -24007,86 +23984,21 @@ int wolfSSL_CTX_add_session(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* session) /* Session cache is global */ (void)ctx; - /* Same session row selection logic as in AddSession */ + id = session->sessionID; + if (session->haveAltSessionID) + id = session->altSessionID; - row = HashSession(session->sessionID, ID_LEN, &error) % SESSION_ROWS; - if (error != 0) { - WOLFSSL_MSG("Hash session failed"); - return WOLFSSL_FAILURE; - } - - sessRow = &SessionCache[row]; - if (SESSION_ROW_LOCK(sessRow) != 0) { - WOLFSSL_MSG("Row lock failed"); - return WOLFSSL_FAILURE; - } - - for (i=0; i < SESSIONS_PER_ROW && i < sessRow->totalCount; i++) { - if (XMEMCMP(session->sessionID, - sessRow->Sessions[i].sessionID, ID_LEN) == 0 && - sessRow->Sessions[i].side == session->side) { - WOLFSSL_MSG("Session already exists. Overwriting."); - overwrite = 1; - idx = i; - break; - } - } - - if (!overwrite) { - idx = sessRow->nextIdx++; - } - else if (session == &sessRow->Sessions[idx]) { - /* Sanity check to make sure we don't do unnecessary work */ - WOLFSSL_MSG("Session already present in cache"); - SESSION_ROW_UNLOCK(sessRow); - return WOLFSSL_SUCCESS; - } - - cacheSess = &sessRow->Sessions[idx]; - - copy = wolfSSL_SESSION_dup(session); - if (copy == NULL) { - WOLFSSL_MSG("wolfSSL_SESSION_dup failed"); - SESSION_ROW_UNLOCK(sessRow); - return WOLFSSL_FAILURE; - } - - wolfSSL_FreeSession(cacheSess); - - /* Just copy the fields and free the duplicated object */ - XMEMCPY(cacheSess, copy, sizeof(*copy)); - - cacheSess->type = WOLFSSL_SESSION_TYPE_CACHE; - cacheSess->cacheRow = row; - cacheSess->masterSecret = cacheSess->_masterSecret; -#ifndef NO_CLIENT_CACHE - cacheSess->serverID = cacheSess->_serverID; -#endif -#ifdef OPENSSL_EXTRA - cacheSess->sessionCtx = cacheSess->_sessionCtx; -#endif + error = AddSessionToCache(session, id, + NULL, session->side, #ifdef HAVE_SESSION_TICKET - if (cacheSess->ticketLenAlloc == 0) - cacheSess->ticket = cacheSess->_staticTicket; + session->ticketLen > 0 +#else + 0 #endif - cacheSess->refCount = 0; -#ifndef SINGLE_THREADED - /* We can free this since we are free'ing the `copy` object directly */ - wc_FreeMutex(&cacheSess->refMutex); -#endif - cacheSess->heap = NULL; + ); - if (sessRow->totalCount < SESSIONS_PER_ROW) - sessRow->totalCount++; - if (sessRow->nextIdx == SESSIONS_PER_ROW) - sessRow->nextIdx = 0; - - XFREE(copy, NULL, DYNAMIC_TYPE_SESSION); - - SESSION_ROW_UNLOCK(sessRow); - return WOLFSSL_SUCCESS; + return error == 0 ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE; } -#endif #if defined(OPENSSL_EXTRA) || defined(HAVE_EXT_CACHE) @@ -32408,6 +32320,8 @@ int wolfSSL_i2d_SSL_SESSION(WOLFSSL_SESSION* sess, unsigned char** p) * haveEMS */ size += OPAQUE8_LEN + OPAQUE32_LEN + OPAQUE32_LEN + OPAQUE8_LEN + sess->sessionIDSz + SECRET_LEN + OPAQUE8_LEN; + /* altSessionID */ + size += OPAQUE8_LEN + (sess->haveAltSessionID ? ID_LEN : 0); #ifdef SESSION_CERTS /* Peer chain */ size += OPAQUE8_LEN; @@ -32471,6 +32385,11 @@ int wolfSSL_i2d_SSL_SESSION(WOLFSSL_SESSION* sess, unsigned char** p) idx += sess->sessionIDSz; XMEMCPY(data + idx, sess->masterSecret, SECRET_LEN); idx += SECRET_LEN; data[idx++] = (byte)sess->haveEMS; + data[idx++] = sess->haveAltSessionID ? ID_LEN : 0; + if (sess->haveAltSessionID) { + XMEMCPY(data + idx, sess->altSessionID, ID_LEN); + idx += ID_LEN; + } #ifdef SESSION_CERTS data[idx++] = (byte)sess->chain.count; for (i = 0; i < sess->chain.count; i++) { @@ -32589,8 +32508,8 @@ WOLFSSL_SESSION* wolfSSL_d2i_SSL_SESSION(WOLFSSL_SESSION** sess, ato32(data + idx, &s->timeout); idx += OPAQUE32_LEN; s->sessionIDSz = data[idx++]; - /* sessionID | secret | haveEMS */ - if (i - idx < s->sessionIDSz + SECRET_LEN + OPAQUE8_LEN) { + /* sessionID | secret | haveEMS | haveAltSessionID */ + if (i - idx < s->sessionIDSz + SECRET_LEN + OPAQUE8_LEN + OPAQUE8_LEN) { ret = BUFFER_ERROR; goto end; } @@ -32598,6 +32517,20 @@ WOLFSSL_SESSION* wolfSSL_d2i_SSL_SESSION(WOLFSSL_SESSION** sess, idx += s->sessionIDSz; XMEMCPY(s->masterSecret, data + idx, SECRET_LEN); idx += SECRET_LEN; s->haveEMS = data[idx++]; + if (data[idx] != ID_LEN && data[idx] != 0) { + ret = BUFFER_ERROR; + goto end; + } + s->haveAltSessionID = data[idx++] == ID_LEN; + + /* altSessionID */ + if (s->haveAltSessionID) { + if (i - idx < ID_LEN) { + ret = BUFFER_ERROR; + goto end; + } + XMEMCPY(s->altSessionID, data + idx, ID_LEN); idx += ID_LEN; + } #ifdef SESSION_CERTS /* Certificate chain */ @@ -42794,7 +42727,7 @@ WOLFSSL_X509_CHAIN* wolfSSL_get_peer_alt_chain(WOLFSSL* ssl) { WOLFSSL_ENTER("wolfSSL_get_peer_alt_chain"); if (ssl) - return &ssl->session.altChain; + return &ssl->session->altChain; return 0; } @@ -42806,7 +42739,7 @@ WOLFSSL_X509_CHAIN* wolfSSL_get_peer_chain(WOLFSSL* ssl) { WOLFSSL_ENTER("wolfSSL_get_peer_chain"); if (ssl) - return &ssl->session.chain; + return &ssl->session->chain; return 0; } @@ -51251,21 +51184,9 @@ int wolfSSL_SSL_in_connect_init(WOLFSSL* ssl) WOLFSSL_SESSION *wolfSSL_SSL_get0_session(const WOLFSSL *ssl) { - WOLFSSL_SESSION *session; - WOLFSSL_ENTER("wolfSSL_SSL_get0_session"); - if (ssl == NULL) { - return NULL; - } - - session = wolfSSL_get_session((WOLFSSL*)ssl); - -#ifdef HAVE_EXT_CACHE - ((WOLFSSL*)ssl)->extSession = session; -#endif - - return session; + return wolfSSL_get_session((WOLFSSL*)ssl); } #endif /* NO_SESSION_CACHE */ diff --git a/src/tls.c b/src/tls.c index d0802ff55..433605a44 100644 --- a/src/tls.c +++ b/src/tls.c @@ -7698,7 +7698,7 @@ static int TLSX_KeyShare_Process(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) int ret; #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) - ssl->session.namedGroup = (byte)keyShareEntry->group; + ssl->session->namedGroup = (byte)keyShareEntry->group; #endif /* reset the pre master secret size */ if (ssl->arrays->preMasterSz == 0) @@ -7943,7 +7943,7 @@ static int TLSX_KeyShare_Parse(WOLFSSL* ssl, const byte* input, word16 length, /* Process the entry to calculate the secret. */ ret = TLSX_KeyShare_Process(ssl, keyShareEntry); if (ret == 0) - ssl->session.namedGroup = ssl->namedGroup = group; + ssl->session->namedGroup = ssl->namedGroup = group; } else if (msgType == hello_retry_request) { if (length != OPAQUE16_LEN) @@ -9122,10 +9122,10 @@ static int TLSX_PreSharedKey_Parse(WOLFSSL* ssl, const byte* input, #ifdef HAVE_SESSION_TICKET if (list->resumption) { /* Check that the session's details are the same as the server's. */ - if (ssl->options.cipherSuite0 != ssl->session.cipherSuite0 || - ssl->options.cipherSuite != ssl->session.cipherSuite || - ssl->session.version.major != ssl->ctx->method->version.major || - ssl->session.version.minor != ssl->ctx->method->version.minor) { + if (ssl->options.cipherSuite0 != ssl->session->cipherSuite0 || + ssl->options.cipherSuite != ssl->session->cipherSuite || + ssl->session->version.major != ssl->ctx->method->version.major || + ssl->session->version.minor != ssl->ctx->method->version.minor) { return PSK_KEY_ERROR; } } @@ -9636,7 +9636,7 @@ static int TLSX_EarlyData_Parse(WOLFSSL* ssl, const byte* input, word16 length, return BUFFER_E; ato32(input, &maxSz); - ssl->session.maxEarlyDataSz = maxSz; + ssl->session->maxEarlyDataSz = maxSz; return 0; } @@ -10195,8 +10195,8 @@ static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions) int ret = WOLFSSL_SUCCESS; #ifdef WOLFSSL_TLS13 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) - if (ssl->options.resuming && ssl->session.namedGroup != 0) { - return TLSX_UseSupportedCurve(extensions, ssl->session.namedGroup, + if (ssl->options.resuming && ssl->session->namedGroup != 0) { + return TLSX_UseSupportedCurve(extensions, ssl->session->namedGroup, ssl->heap); } #endif @@ -10600,8 +10600,8 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer) extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE); if (extension == NULL) { #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) - if (ssl->options.resuming && ssl->session.namedGroup != 0) - namedGroup = ssl->session.namedGroup; + if (ssl->options.resuming && ssl->session->namedGroup != 0) + namedGroup = ssl->session->namedGroup; else #endif if (ssl->numGroups > 0) { @@ -10647,8 +10647,8 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer) TLSX_Remove(&ssl->extensions, TLSX_PRE_SHARED_KEY, ssl->heap); #endif #if defined(HAVE_SESSION_TICKET) - if (ssl->options.resuming && ssl->session.ticketLen > 0) { - WOLFSSL_SESSION* sess = &ssl->session; + if (ssl->options.resuming && ssl->session->ticketLen > 0) { + WOLFSSL_SESSION* sess = ssl->session; word32 now, milli; if (sess->ticketLen > MAX_PSK_ID_LEN) { diff --git a/src/tls13.c b/src/tls13.c index 20b9dafc9..94bf2debf 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -807,7 +807,7 @@ int DeriveResumptionSecret(WOLFSSL* ssl, byte* key) masterSecret = ssl->arrays->masterSecret; } else { - masterSecret = ssl->session.masterSecret; + masterSecret = ssl->session->masterSecret; } return DeriveKey(ssl, key, -1, masterSecret, resumeMasterLabel, RESUME_MASTER_LABEL_SZ, ssl->specs.mac_algorithm, 1); @@ -1014,7 +1014,7 @@ int DeriveResumptionPSK(WOLFSSL* ssl, byte* nonce, byte nonceLen, byte* secret) PRIVATE_KEY_UNLOCK(); ret = wc_Tls13_HKDF_Expand_Label(secret, ssl->specs.hash_size, - ssl->session.masterSecret, ssl->specs.hash_size, + ssl->session->masterSecret, ssl->specs.hash_size, protocol, protocolLen, resumptionLabel, RESUMPTION_LABEL_SZ, nonce, nonceLen, digestAlg); PRIVATE_KEY_LOCK(); @@ -2772,13 +2772,13 @@ static int SetupPskKey(WOLFSSL* ssl, PreSharedKey* psk, int clientHello) } #ifdef WOLFSSL_EARLY_DATA - if (ssl->session.maxEarlyDataSz == 0) + if (ssl->session->maxEarlyDataSz == 0) ssl->earlyData = no_early_data; #endif /* Resumption PSK is master secret. */ ssl->arrays->psk_keySz = ssl->specs.hash_size; - if ((ret = DeriveResumptionPSK(ssl, ssl->session.ticketNonce.data, - ssl->session.ticketNonce.len, ssl->arrays->psk_key)) != 0) { + if ((ret = DeriveResumptionPSK(ssl, ssl->session->ticketNonce.data, + ssl->session->ticketNonce.len, ssl->arrays->psk_key)) != 0) { return ret; } } @@ -3049,15 +3049,15 @@ int SendTls13ClientHello(WOLFSSL* ssl) #ifdef HAVE_SESSION_TICKET if (ssl->options.resuming && - (ssl->session.version.major != ssl->version.major || - ssl->session.version.minor != ssl->version.minor)) { + (ssl->session->version.major != ssl->version.major || + ssl->session->version.minor != ssl->version.minor)) { #ifndef WOLFSSL_NO_TLS12 - if (ssl->session.version.major == ssl->version.major && - ssl->session.version.minor < ssl->version.minor) { + if (ssl->session->version.major == ssl->version.major && + ssl->session->version.minor < ssl->version.minor) { /* Cannot resume with a different protocol version. */ ssl->options.resuming = 0; - ssl->version.major = ssl->session.version.major; - ssl->version.minor = ssl->session.version.minor; + ssl->version.major = ssl->session->version.major; + ssl->version.minor = ssl->session->version.minor; return SendClientHello(ssl); } else @@ -3097,8 +3097,8 @@ int SendTls13ClientHello(WOLFSSL* ssl) #if defined(WOLFSSL_TLS13_MIDDLEBOX_COMPAT) args->length += ID_LEN; #else - if (ssl->session.sessionIDSz > 0) - args->length += ssl->session.sessionIDSz; + if (ssl->session->sessionIDSz > 0) + args->length += ssl->session->sessionIDSz; #endif /* Advance state and proceed */ @@ -3179,11 +3179,11 @@ int SendTls13ClientHello(WOLFSSL* ssl) XMEMCPY(args->output + args->idx, ssl->arrays->clientRandom, RAN_LEN); args->idx += RAN_LEN; - if (ssl->session.sessionIDSz > 0) { + if (ssl->session->sessionIDSz > 0) { /* Session resumption for old versions of protocol. */ args->output[args->idx++] = ID_LEN; - XMEMCPY(args->output + args->idx, ssl->session.sessionID, - ssl->session.sessionIDSz); + XMEMCPY(args->output + args->idx, ssl->session->sessionID, + ssl->session->sessionIDSz); args->idx += ID_LEN; } else { @@ -3514,7 +3514,7 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #ifdef HAVE_SECRET_CALLBACK if (ssl->sessionSecretCb != NULL) { int secretSz = SECRET_LEN; - ret = ssl->sessionSecretCb(ssl, ssl->session.masterSecret, + ret = ssl->sessionSecretCb(ssl, ssl->session->masterSecret, &secretSz, ssl->sessionSecretCtx); if (ret != 0 || secretSz != SECRET_LEN) { return SESSION_SECRET_CB_E; @@ -3566,9 +3566,9 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, WOLFSSL_MSG("args->sessIdSz == 0"); return INVALID_PARAMETER; } - if (ssl->session.sessionIDSz != 0) { - if (ssl->session.sessionIDSz != args->sessIdSz || - XMEMCMP(ssl->session.sessionID, args->sessId, + if (ssl->session->sessionIDSz != 0) { + if (ssl->session->sessionIDSz != args->sessIdSz || + XMEMCMP(ssl->session->sessionID, args->sessId, args->sessIdSz) != 0) { WOLFSSL_MSG("session id doesn't match"); return INVALID_PARAMETER; @@ -3580,8 +3580,8 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, return INVALID_PARAMETER; } #else - if (args->sessIdSz != ssl->session.sessionIDSz || (args->sessIdSz > 0 && - XMEMCMP(ssl->session.sessionID, args->sessId, args->sessIdSz) != 0)) + if (args->sessIdSz != ssl->session->sessionIDSz || (args->sessIdSz > 0 && + XMEMCMP(ssl->session->sessionID, args->sessId, args->sessIdSz) != 0)) { WOLFSSL_MSG("Server sent different session id"); return INVALID_PARAMETER; @@ -3944,7 +3944,7 @@ static int FindPsk(WOLFSSL* ssl, PreSharedKey* psk, byte* suite, int* err) ssl->options.verifyPeer = 0; /* PSK age is always zero. */ - if (psk->ticketAge != ssl->session.ticketAdd) { + if (psk->ticketAge != ssl->session->ticketAdd) { ret = PSK_KEY_ERROR; } } @@ -4016,7 +4016,7 @@ static int DoPreSharedKeys(WOLFSSL* ssl, byte* suite, int* usingPSK, int* first) /* Difference between now and time ticket constructed * (from decrypted ticket). */ diff = now; - diff -= ssl->session.ticketSeen; + diff -= ssl->session->ticketSeen; if (diff > (sword64)ssl->timeout * 1000 || diff > (sword64)TLS13_MAX_TICKET_AGE * 1000) { current = current->next; @@ -4024,7 +4024,7 @@ static int DoPreSharedKeys(WOLFSSL* ssl, byte* suite, int* usingPSK, int* first) } /* Subtract client's ticket age and unobfuscate. */ diff -= current->ticketAge; - diff += ssl->session.ticketAdd; + diff += ssl->session->ticketAdd; /* Check session and ticket age timeout. * Allow +/- 1000 milliseconds on ticket age. */ @@ -4037,14 +4037,14 @@ static int DoPreSharedKeys(WOLFSSL* ssl, byte* suite, int* usingPSK, int* first) /* Check whether resumption is possible based on suites in SSL and * ciphersuite in ticket. */ - if ((suite[0] != ssl->session.cipherSuite0) || - (suite[1] != ssl->session.cipherSuite)) { + if ((suite[0] != ssl->session->cipherSuite0) || + (suite[1] != ssl->session->cipherSuite)) { current = current->next; continue; } #else - suite[0] = ssl->session.cipherSuite0; - suite[1] = ssl->session.cipherSuite; + suite[0] = ssl->session->cipherSuite0; + suite[1] = ssl->session->cipherSuite; if (!FindSuiteSSL(ssl, suite)) { current = current->next; continue; @@ -4052,19 +4052,19 @@ static int DoPreSharedKeys(WOLFSSL* ssl, byte* suite, int* usingPSK, int* first) #endif #ifdef WOLFSSL_EARLY_DATA - ssl->options.maxEarlyDataSz = ssl->session.maxEarlyDataSz; + ssl->options.maxEarlyDataSz = ssl->session->maxEarlyDataSz; #endif /* Use the same cipher suite as before and set up for use. */ - ssl->options.cipherSuite0 = ssl->session.cipherSuite0; - ssl->options.cipherSuite = ssl->session.cipherSuite; + ssl->options.cipherSuite0 = ssl->session->cipherSuite0; + ssl->options.cipherSuite = ssl->session->cipherSuite; ret = SetCipherSpecs(ssl); if (ret != 0) return ret; /* Resumption PSK is resumption master secret. */ ssl->arrays->psk_keySz = ssl->specs.hash_size; - if ((ret = DeriveResumptionPSK(ssl, ssl->session.ticketNonce.data, - ssl->session.ticketNonce.len, ssl->arrays->psk_key)) != 0) { + if ((ret = DeriveResumptionPSK(ssl, ssl->session->ticketNonce.data, + ssl->session->ticketNonce.len, ssl->arrays->psk_key)) != 0) { return ret; } @@ -4273,7 +4273,7 @@ static int CheckPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz, if ((modes & (1 << PSK_DHE_KE)) != 0 && !ssl->options.noPskDheKe && ext != NULL) { /* Only use named group used in last session. */ - ssl->namedGroup = ssl->session.namedGroup; + ssl->namedGroup = ssl->session->namedGroup; *usingPSK = 2; /* generate new ephemeral key */ } @@ -4404,7 +4404,7 @@ static int RestartHandshakeHashWithCookie(WOLFSSL* ssl, Cookie* cookie) return ret; /* Reconstruct the HelloRetryMessage for handshake hash. */ - length = HRR_BODY_SZ - ID_LEN + ssl->session.sessionIDSz + + length = HRR_BODY_SZ - ID_LEN + ssl->session->sessionIDSz + HRR_COOKIE_HDR_SZ + cookie->len; length += HRR_VERSIONS_SZ; if (cookieDataSz > hashSz + OPAQUE16_LEN) { @@ -4425,10 +4425,10 @@ static int RestartHandshakeHashWithCookie(WOLFSSL* ssl, Cookie* cookie) XMEMCPY(hrr + hrrIdx, helloRetryRequestRandom, RAN_LEN); hrrIdx += RAN_LEN; - hrr[hrrIdx++] = ssl->session.sessionIDSz; - if (ssl->session.sessionIDSz > 0) { - XMEMCPY(hrr + hrrIdx, ssl->session.sessionID, ssl->session.sessionIDSz); - hrrIdx += ssl->session.sessionIDSz; + hrr[hrrIdx++] = ssl->session->sessionIDSz; + if (ssl->session->sessionIDSz > 0) { + XMEMCPY(hrr + hrrIdx, ssl->session->sessionID, ssl->session->sessionIDSz); + hrrIdx += ssl->session->sessionIDSz; } /* Cipher Suite */ @@ -4439,7 +4439,7 @@ static int RestartHandshakeHashWithCookie(WOLFSSL* ssl, Cookie* cookie) hrr[hrrIdx++] = 0; /* Extensions' length */ - length -= HRR_BODY_SZ - ID_LEN + ssl->session.sessionIDSz; + length -= HRR_BODY_SZ - ID_LEN + ssl->session->sessionIDSz; c16toa(length, hrr + hrrIdx); hrrIdx += 2; @@ -4717,9 +4717,9 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ERROR_OUT(BUFFER_ERROR, exit_dch); } - ssl->session.sessionIDSz = sessIdSz; + ssl->session->sessionIDSz = sessIdSz; if (sessIdSz == ID_LEN) { - XMEMCPY(ssl->session.sessionID, input + args->idx, sessIdSz); + XMEMCPY(ssl->session->sessionID, input + args->idx, sessIdSz); args->idx += ID_LEN; } @@ -4973,7 +4973,7 @@ int SendTls13ServerHello(WOLFSSL* ssl, byte extMsgType) /* Protocol version, server random, session id, cipher suite, compression * and extensions. */ - length = VERSION_SZ + RAN_LEN + ENUM_LEN + ssl->session.sessionIDSz + + length = VERSION_SZ + RAN_LEN + ENUM_LEN + ssl->session->sessionIDSz + SUITE_LEN + COMP_LEN; ret = TLSX_GetResponseSize(ssl, extMsgType, &length); if (ret != 0) @@ -5014,10 +5014,10 @@ int SendTls13ServerHello(WOLFSSL* ssl, byte extMsgType) WOLFSSL_BUFFER(ssl->arrays->serverRandom, RAN_LEN); #endif - output[idx++] = ssl->session.sessionIDSz; - if (ssl->session.sessionIDSz > 0) { - XMEMCPY(output + idx, ssl->session.sessionID, ssl->session.sessionIDSz); - idx += ssl->session.sessionIDSz; + output[idx++] = ssl->session->sessionIDSz; + if (ssl->session->sessionIDSz > 0) { + XMEMCPY(output + idx, ssl->session->sessionID, ssl->session->sessionIDSz); + idx += ssl->session->sessionIDSz; } /* Chosen cipher suite */ @@ -7144,7 +7144,7 @@ static int SendTls13Finished(WOLFSSL* ssl) return ret; #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) - ret = DeriveResumptionSecret(ssl, ssl->session.masterSecret); + ret = DeriveResumptionSecret(ssl, ssl->session->masterSecret); if (ret != 0) return ret; #endif @@ -7476,18 +7476,18 @@ static int DoTls13NewSessionTicket(WOLFSSL* ssl, const byte* input, return now; /* Copy in ticket data (server identity). */ ssl->timeout = lifetime; - ssl->session.timeout = lifetime; - ssl->session.cipherSuite0 = ssl->options.cipherSuite0; - ssl->session.cipherSuite = ssl->options.cipherSuite; - ssl->session.ticketSeen = now; - ssl->session.ticketAdd = ageAdd; + ssl->session->timeout = lifetime; + ssl->session->cipherSuite0 = ssl->options.cipherSuite0; + ssl->session->cipherSuite = ssl->options.cipherSuite; + ssl->session->ticketSeen = now; + ssl->session->ticketAdd = ageAdd; #ifdef WOLFSSL_EARLY_DATA - ssl->session.maxEarlyDataSz = ssl->options.maxEarlyDataSz; + ssl->session->maxEarlyDataSz = ssl->options.maxEarlyDataSz; #endif - ssl->session.ticketNonce.len = nonceLength; + ssl->session->ticketNonce.len = nonceLength; if (nonceLength > 0) - XMEMCPY(&ssl->session.ticketNonce.data, nonce, nonceLength); - ssl->session.namedGroup = ssl->namedGroup; + XMEMCPY(&ssl->session->ticketNonce.data, nonce, nonceLength); + ssl->session->namedGroup = ssl->namedGroup; if ((*inOutIdx - begin) + EXTS_SZ > size) return BUFFER_ERROR; @@ -7592,7 +7592,7 @@ static int ExpectedResumptionSecret(WOLFSSL* ssl) if ((ret = HashRaw(ssl, mac, finishedSz)) != 0) return ret; - if ((ret = DeriveResumptionSecret(ssl, ssl->session.masterSecret)) != 0) + if ((ret = DeriveResumptionSecret(ssl, ssl->session->masterSecret)) != 0) return ret; /* Restore the hash inline with currently seen messages. */ @@ -7656,12 +7656,12 @@ static int SendTls13NewSessionTicket(WOLFSSL* ssl) #endif /* Start ticket nonce at 0 and go up to 255. */ - if (ssl->session.ticketNonce.len == 0) { - ssl->session.ticketNonce.len = DEF_TICKET_NONCE_SZ; - ssl->session.ticketNonce.data[0] = 0; + if (ssl->session->ticketNonce.len == 0) { + ssl->session->ticketNonce.len = DEF_TICKET_NONCE_SZ; + ssl->session->ticketNonce.data[0] = 0; } else - ssl->session.ticketNonce.data[0]++; + ssl->session->ticketNonce.data[0]++; if (!ssl->options.noTicketTls13) { if ((ret = CreateTicket(ssl)) != 0) @@ -7669,9 +7669,9 @@ static int SendTls13NewSessionTicket(WOLFSSL* ssl) } #ifdef WOLFSSL_EARLY_DATA - ssl->session.maxEarlyDataSz = ssl->options.maxEarlyDataSz; - if (ssl->session.maxEarlyDataSz > 0) - TLSX_EarlyData_Use(ssl, ssl->session.maxEarlyDataSz); + ssl->session->maxEarlyDataSz = ssl->options.maxEarlyDataSz; + if (ssl->session->maxEarlyDataSz > 0) + TLSX_EarlyData_Use(ssl, ssl->session->maxEarlyDataSz); extSz = 0; ret = TLSX_GetResponseSize(ssl, session_ticket, &extSz); if (ret != 0) @@ -7682,7 +7682,7 @@ static int SendTls13NewSessionTicket(WOLFSSL* ssl) /* Lifetime | Age Add | Ticket | Extensions */ length = SESSION_HINT_SZ + SESSION_ADD_SZ + LENGTH_SZ + - ssl->session.ticketLen + extSz; + ssl->session->ticketLen + extSz; /* Nonce */ length += TICKET_NONCE_LEN_SZ + DEF_TICKET_NONCE_SZ; sendSz = idx + length + MAX_MSG_EXTRA; @@ -7702,18 +7702,18 @@ static int SendTls13NewSessionTicket(WOLFSSL* ssl) c32toa(ssl->ctx->ticketHint, output + idx); idx += SESSION_HINT_SZ; /* Age add - obfuscator */ - c32toa(ssl->session.ticketAdd, output + idx); + c32toa(ssl->session->ticketAdd, output + idx); idx += SESSION_ADD_SZ; - output[idx++] = ssl->session.ticketNonce.len; - output[idx++] = ssl->session.ticketNonce.data[0]; + output[idx++] = ssl->session->ticketNonce.len; + output[idx++] = ssl->session->ticketNonce.data[0]; /* length */ - c16toa(ssl->session.ticketLen, output + idx); + c16toa(ssl->session->ticketLen, output + idx); idx += LENGTH_SZ; /* ticket */ - XMEMCPY(output + idx, ssl->session.ticket, ssl->session.ticketLen); - idx += ssl->session.ticketLen; + XMEMCPY(output + idx, ssl->session->ticket, ssl->session->ticketLen); + idx += ssl->session->ticketLen; #ifdef WOLFSSL_EARLY_DATA extSz = 0; @@ -8409,7 +8409,7 @@ int DoTls13HandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx, #ifndef NO_WOLFSSL_SERVER #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) if (ssl->options.side == WOLFSSL_SERVER_END && type == finished) { - ret = DeriveResumptionSecret(ssl, ssl->session.masterSecret); + ret = DeriveResumptionSecret(ssl, ssl->session->masterSecret); if (ret != 0) return ret; } @@ -9933,8 +9933,8 @@ int wolfSSL_write_early_data(WOLFSSL* ssl, const void* data, int sz, int* outSz) if (ssl->options.handShakeState == CLIENT_HELLO_COMPLETE) { #ifdef OPENSSL_EXTRA /* when processed early data exceeds max size */ - if (ssl->session.maxEarlyDataSz > 0 && - (ssl->earlyDataSz + sz > ssl->session.maxEarlyDataSz)) { + if (ssl->session->maxEarlyDataSz > 0 && + (ssl->earlyDataSz + sz > ssl->session->maxEarlyDataSz)) { ssl->error = TOO_MUCH_EARLY_DATA; return WOLFSSL_FATAL_ERROR; } diff --git a/tests/api.c b/tests/api.c index 535766b95..7053ba89f 100644 --- a/tests/api.c +++ b/tests/api.c @@ -6257,13 +6257,14 @@ static void test_wolfSSL_CTX_add_session_on_result(WOLFSSL* ssl) } #ifdef SESSION_CERTS #ifndef WOLFSSL_TICKET_HAVE_ID - if (wolfSSL_version(ssl) != TLS1_3_VERSION) + 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. */ + * will not be available on resumption. */ WOLFSSL_X509* peer = wolfSSL_get_peer_certificate(ssl); AssertNotNull(peer); wolfSSL_X509_free(peer); diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 4cfcf96ef..76f9162b3 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -3319,6 +3319,8 @@ struct WOLFSSL_SESSION { #ifndef SINGLE_THREADED wolfSSL_Mutex refMutex; /* ref count mutex */ #endif + byte altSessionID[ID_LEN]; + byte haveAltSessionID:1; void* heap; /* WARNING The above fields (up to and including the heap) are not copied * in wolfSSL_DupSession. Place new fields after the heap @@ -3711,9 +3713,6 @@ typedef struct Options { word16 startedETMRead:1; /* Doing Encrypt-Then-MAC read */ word16 startedETMWrite:1; /* Doing Encrypt-Then-MAC write */ #endif -#ifdef WOLFSSL_TICKET_HAVE_ID - word16 haveTicketSessionID:1; -#endif /* need full byte values for this section */ byte processReply; /* nonblocking resume */ @@ -4242,13 +4241,7 @@ struct WOLFSSL { Ciphers encrypt; Ciphers decrypt; Buffers buffers; - WOLFSSL_SESSION session; -#ifdef HAVE_EXT_CACHE - WOLFSSL_SESSION* extSession; -#endif -#ifdef WOLFSSL_TICKET_HAVE_ID - byte ticketSessionID[ID_LEN]; -#endif + WOLFSSL_SESSION* session; WOLFSSL_ALERT_HISTORY alert_history; int error; int rfd; /* read file descriptor */ @@ -4773,6 +4766,10 @@ WOLFSSL_LOCAL int SetCipherSpecs(WOLFSSL* ssl); WOLFSSL_LOCAL int MakeMasterSecret(WOLFSSL* ssl); WOLFSSL_LOCAL int AddSession(WOLFSSL* ssl); +WOLFSSL_LOCAL int AddSessionToCache(WOLFSSL_SESSION* addSession, const byte* id, + int* sessionIndex, int side, word16 useTicket); +WOLFSSL_LOCAL int AddSessionToClientCache(int side, int row, int idx, + byte* serverID, word16 idLen, word16 useTicket); WOLFSSL_LOCAL int DeriveKeys(WOLFSSL* ssl); WOLFSSL_LOCAL int StoreKeys(WOLFSSL* ssl, const byte* keyData, int side); diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 47a029763..bad886e80 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1484,6 +1484,8 @@ WOLFSSL_API WOLFSSL_SESSION* wolfSSL_SESSION_dup(WOLFSSL_SESSION* session); WOLFSSL_API WOLFSSL_SESSION* wolfSSL_SESSION_new(void); WOLFSSL_API WOLFSSL_SESSION* wolfSSL_SESSION_new_ex(void* heap); WOLFSSL_API void wolfSSL_SESSION_free(WOLFSSL_SESSION* session); +WOLFSSL_API int wolfSSL_CTX_add_session(WOLFSSL_CTX* ctx, + WOLFSSL_SESSION* session); WOLFSSL_API int wolfSSL_SESSION_set_cipher(WOLFSSL_SESSION* session, const WOLFSSL_CIPHER* cipher); WOLFSSL_API int wolfSSL_is_init_finished(WOLFSSL* ssl); @@ -4441,9 +4443,6 @@ WOLFSSL_API int wolfSSL_version(WOLFSSL* ssl); #if defined(OPENSSL_ALL) || defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) \ || defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) -WOLFSSL_API int wolfSSL_CTX_add_session(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* session); - - WOLFSSL_API int wolfSSL_get_state(const WOLFSSL* ssl); WOLFSSL_API WOLFSSL_X509* wolfSSL_sk_X509_value(WOLF_STACK_OF(WOLFSSL_X509)*, int i);