mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-30 18:57:27 +02:00
Merge pull request #5593 from rizlik/ticket_nonce_size
tls13: support ticketNonce with size bigger than MAX_TICKET_NONCE_SZ
This commit is contained in:
@ -1340,6 +1340,15 @@ if(WOLFSSL_SESSION_TICKET)
|
|||||||
"-DHAVE_SESSION_TICKET")
|
"-DHAVE_SESSION_TICKET")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
add_option("WOLFSSL_TICKET_NONCE_MALLOC"
|
||||||
|
"Enable dynamic allocation of ticket nonces (default: disabled)"
|
||||||
|
"no" "yes;no")
|
||||||
|
|
||||||
|
if(WOLFSSL_TICKET_NONCE_MALLOC)
|
||||||
|
list(APPEND WOLFSSL_DEFINITIONS
|
||||||
|
"-DWOLFSSL_TICKET_NONCE_MALLOC")
|
||||||
|
endif()
|
||||||
|
|
||||||
# Extended master secret extension
|
# Extended master secret extension
|
||||||
add_option("WOLFSSL_EXTENDED_MASTER"
|
add_option("WOLFSSL_EXTENDED_MASTER"
|
||||||
"Enable Extended Master Secret (default: enabled)"
|
"Enable Extended Master Secret (default: enabled)"
|
||||||
|
11
configure.ac
11
configure.ac
@ -4913,6 +4913,17 @@ then
|
|||||||
AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_SESSION_TICKET"
|
AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_SESSION_TICKET"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
AC_ARG_ENABLE([ticket-nonce-malloc],
|
||||||
|
[AS_HELP_STRING([--enable-ticket-nonce-malloc], [Enable dynamic allocation of ticket nonces (default: disabled)])],
|
||||||
|
[ ENABLED_TICKET_NONCE_MALLOC=$enableval ],
|
||||||
|
[ ENABLED_TICKET_NONCE_MALLOC=no ]
|
||||||
|
)
|
||||||
|
|
||||||
|
if test "$ENABLED_TICKET_NONCE_MALLOC" = "yes"
|
||||||
|
then
|
||||||
|
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_TICKET_NONCE_MALLOC"
|
||||||
|
fi
|
||||||
|
|
||||||
# Extended Master Secret Extension
|
# Extended Master Secret Extension
|
||||||
AC_ARG_ENABLE([extended-master],
|
AC_ARG_ENABLE([extended-master],
|
||||||
[AS_HELP_STRING([--enable-extended-master],[Enable Extended Master Secret (default: enabled)])],
|
[AS_HELP_STRING([--enable-extended-master],[Enable Extended Master Secret (default: enabled)])],
|
||||||
|
@ -33982,8 +33982,14 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
#endif
|
#endif
|
||||||
/* Resumption master secret. */
|
/* Resumption master secret. */
|
||||||
XMEMCPY(it->msecret, ssl->session->masterSecret, SECRET_LEN);
|
XMEMCPY(it->msecret, ssl->session->masterSecret, SECRET_LEN);
|
||||||
XMEMCPY(&it->ticketNonce, &ssl->session->ticketNonce,
|
if (ssl->session->ticketNonce.len > MAX_TICKET_NONCE_STATIC_SZ) {
|
||||||
sizeof(TicketNonce));
|
WOLFSSL_MSG("Bad ticket nonce value");
|
||||||
|
ret = BAD_TICKET_MSG_SZ;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
XMEMCPY(it->ticketNonce, ssl->session->ticketNonce.data,
|
||||||
|
ssl->session->ticketNonce.len);
|
||||||
|
it->ticketNonceLen = ssl->session->ticketNonce.len;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34259,8 +34265,23 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
#endif
|
#endif
|
||||||
/* Resumption master secret. */
|
/* Resumption master secret. */
|
||||||
XMEMCPY(ssl->session->masterSecret, it->msecret, SECRET_LEN);
|
XMEMCPY(ssl->session->masterSecret, it->msecret, SECRET_LEN);
|
||||||
XMEMCPY(&ssl->session->ticketNonce, &it->ticketNonce,
|
if (it->ticketNonceLen > MAX_TICKET_NONCE_STATIC_SZ) {
|
||||||
sizeof(TicketNonce));
|
WOLFSSL_MSG("Unsupported ticketNonce len in ticket");
|
||||||
|
return BAD_TICKET_ENCRYPT;
|
||||||
|
}
|
||||||
|
#if defined(WOLFSSL_TICKET_NONCE_MALLOC) && \
|
||||||
|
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
|
||||||
|
if (ssl->session->ticketNonce.data
|
||||||
|
!= ssl->session->ticketNonce.dataStatic) {
|
||||||
|
XFREE(ssl->session->ticketNonce.data, ssl->heap,
|
||||||
|
DYNAMIC_TYPE_SESSION_TICK);
|
||||||
|
ssl->session->ticketNonce.data =
|
||||||
|
ssl->session->ticketNonce.dataStatic;
|
||||||
|
}
|
||||||
|
#endif /* defined(WOLFSSL_TICKET_NONCE_MALLOC) && FIPS_VERSION_GE(5,3) */
|
||||||
|
XMEMCPY(ssl->session->ticketNonce.data, it->ticketNonce,
|
||||||
|
it->ticketNonceLen);
|
||||||
|
ssl->session->ticketNonce.len = it->ticketNonceLen;
|
||||||
ato16(it->namedGroup, &ssl->session->namedGroup);
|
ato16(it->namedGroup, &ssl->session->namedGroup);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -3292,7 +3292,7 @@ static int ProcessSessionTicket(const byte* input, int* sslBytes,
|
|||||||
|
|
||||||
/* ticket nonce */
|
/* ticket nonce */
|
||||||
len = input[0];
|
len = input[0];
|
||||||
if (len > MAX_TICKET_NONCE_SZ) {
|
if (len > MAX_TICKET_NONCE_STATIC_SZ) {
|
||||||
SetError(BAD_INPUT_STR, error, session, FATAL_ERROR_STATE);
|
SetError(BAD_INPUT_STR, error, session, FATAL_ERROR_STATE);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -3302,7 +3302,7 @@ static int ProcessSessionTicket(const byte* input, int* sslBytes,
|
|||||||
/* store nonce in server for DeriveResumptionPSK */
|
/* store nonce in server for DeriveResumptionPSK */
|
||||||
session->sslServer->session->ticketNonce.len = len;
|
session->sslServer->session->ticketNonce.len = len;
|
||||||
if (len > 0)
|
if (len > 0)
|
||||||
XMEMCPY(&session->sslServer->session->ticketNonce.data, input, len);
|
XMEMCPY(session->sslServer->session->ticketNonce.data, input, len);
|
||||||
#endif
|
#endif
|
||||||
input += len;
|
input += len;
|
||||||
*sslBytes -= len;
|
*sslBytes -= len;
|
||||||
|
316
src/ssl.c
316
src/ssl.c
@ -13555,6 +13555,40 @@ static int SslSessionCacheOff(const WOLFSSL* ssl, const WOLFSSL_SESSION* session
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_TLS13) && \
|
||||||
|
defined(WOLFSSL_TICKET_NONCE_MALLOC) && \
|
||||||
|
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
|
||||||
|
/**
|
||||||
|
* SessionTicketNoncePrealloc() - prealloc a buffer for ticket nonces
|
||||||
|
* @output: [in] pointer to WOLFSSL_SESSION object that will soon be a
|
||||||
|
* destination of a session duplication
|
||||||
|
* @buf: [out] address of the preallocated buf
|
||||||
|
* @len: [out] len of the preallocated buf
|
||||||
|
*
|
||||||
|
* prealloc a buffer that will likely suffice to contain a ticket nonce. It's
|
||||||
|
* used when copying session under lock, when syscalls need to be avoided. If
|
||||||
|
* output already has a dynamic buffer, it's reused.
|
||||||
|
*/
|
||||||
|
static int SessionTicketNoncePrealloc(byte** buf, byte* len, void *heap)
|
||||||
|
{
|
||||||
|
(void)heap;
|
||||||
|
|
||||||
|
*buf = (byte*)XMALLOC(PREALLOC_SESSION_TICKET_NONCE_LEN, heap,
|
||||||
|
DYNAMIC_TYPE_SESSION_TICK);
|
||||||
|
if (*buf == NULL) {
|
||||||
|
WOLFSSL_MSG("Failed to preallocate ticket nonce buffer");
|
||||||
|
*len = 0;
|
||||||
|
return WOLFSSL_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*len = PREALLOC_SESSION_TICKET_NONCE_LEN;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_SESSION_TICKET && WOLFSSL_TLS13 */
|
||||||
|
|
||||||
|
static int wolfSSL_DupSessionEx(const WOLFSSL_SESSION* input,
|
||||||
|
WOLFSSL_SESSION* output, int avoidSysCalls, byte* ticketNonceBuf,
|
||||||
|
byte* ticketNonceLen, byte* preallocUsed);
|
||||||
|
|
||||||
int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output)
|
int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output)
|
||||||
{
|
{
|
||||||
@ -13571,6 +13605,11 @@ int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output)
|
|||||||
#else
|
#else
|
||||||
byte* tmpTicket = NULL;
|
byte* tmpTicket = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef WOLFSSL_TLS13
|
||||||
|
byte *preallocNonce = NULL;
|
||||||
|
byte preallocNonceLen = 0;
|
||||||
|
byte preallocNonceUsed = 0;
|
||||||
|
#endif /* WOLFSSL_TLS13 */
|
||||||
byte tmpBufSet = 0;
|
byte tmpBufSet = 0;
|
||||||
#endif
|
#endif
|
||||||
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
|
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
|
||||||
@ -13678,6 +13717,30 @@ int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET) && \
|
||||||
|
defined(WOLFSSL_TICKET_NONCE_MALLOC) && \
|
||||||
|
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
|
||||||
|
if (output->ticketNonce.data != output->ticketNonce.dataStatic) {
|
||||||
|
XFREE(output->ticketNonce.data, output->heap,
|
||||||
|
DYNAMIC_TYPE_SESSION_TICK);
|
||||||
|
output->ticketNonce.data = output->ticketNonce.dataStatic;
|
||||||
|
output->ticketNonce.len = 0;
|
||||||
|
}
|
||||||
|
error = SessionTicketNoncePrealloc(&preallocNonce, &preallocNonceLen,
|
||||||
|
output->heap);
|
||||||
|
if (error != 0) {
|
||||||
|
if (tmpBufSet) {
|
||||||
|
output->ticket = output->staticTicket;
|
||||||
|
output->ticketLenAlloc = 0;
|
||||||
|
}
|
||||||
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
|
if (tmpTicket != NULL)
|
||||||
|
XFREE(tmpTicket, output->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
|
return WOLFSSL_FAILURE;
|
||||||
|
}
|
||||||
|
#endif /* WOLFSSL_TLS13 && HAVE_SESSION_TICKET*/
|
||||||
|
|
||||||
/* lock row */
|
/* lock row */
|
||||||
sessRow = &SessionCache[row];
|
sessRow = &SessionCache[row];
|
||||||
if (SESSION_ROW_LOCK(sessRow) != 0) {
|
if (SESSION_ROW_LOCK(sessRow) != 0) {
|
||||||
@ -13687,6 +13750,10 @@ int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output)
|
|||||||
output->ticket = output->staticTicket;
|
output->ticket = output->staticTicket;
|
||||||
output->ticketLenAlloc = 0;
|
output->ticketLenAlloc = 0;
|
||||||
}
|
}
|
||||||
|
#ifdef WOLFSSL_TLS13
|
||||||
|
if (preallocNonce != NULL)
|
||||||
|
XFREE(preallocNonce, output->heap, DYNAMIC_TYPE_SESSION_TICK);
|
||||||
|
#endif /* WOLFSSL_TLS13 */
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
if (tmpTicket != NULL)
|
if (tmpTicket != NULL)
|
||||||
XFREE(tmpTicket, output->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
XFREE(tmpTicket, output->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
@ -13731,7 +13798,13 @@ int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output)
|
|||||||
sess->peer = NULL;
|
sess->peer = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_TLS13)
|
||||||
|
error = wolfSSL_DupSessionEx(sess, output, 1,
|
||||||
|
preallocNonce, &preallocNonceLen, &preallocNonceUsed);
|
||||||
|
#else
|
||||||
error = wolfSSL_DupSession(sess, output, 1);
|
error = wolfSSL_DupSession(sess, output, 1);
|
||||||
|
#endif /* WOLFSSL_TSL */
|
||||||
|
|
||||||
#ifdef HAVE_EX_DATA
|
#ifdef HAVE_EX_DATA
|
||||||
output->ownExData = 0; /* Session cache owns external data */
|
output->ownExData = 0; /* Session cache owns external data */
|
||||||
#endif
|
#endif
|
||||||
@ -13780,6 +13853,45 @@ int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output)
|
|||||||
if (tmpTicket != NULL)
|
if (tmpTicket != NULL)
|
||||||
XFREE(tmpTicket, output->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
XFREE(tmpTicket, output->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_TICKET_NONCE_MALLOC) && \
|
||||||
|
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
|
||||||
|
if (error == WOLFSSL_SUCCESS && preallocNonceUsed) {
|
||||||
|
if (preallocNonceLen < PREALLOC_SESSION_TICKET_NONCE_LEN) {
|
||||||
|
/* buffer bigger than needed */
|
||||||
|
#ifndef XREALLOC
|
||||||
|
output->ticketNonce.data = (byte*)XMALLOC(preallocNonceLen,
|
||||||
|
output->heap, DYNAMIC_TYPE_SESSION_TICK);
|
||||||
|
if (output->ticketNonce.data != NULL)
|
||||||
|
XMEMCPY(output->ticketNonce.data, preallocNonce,
|
||||||
|
preallocNonceLen);
|
||||||
|
XFREE(preallocNonce, output->heap, DYNAMIC_TYPE_SESSION_TICK);
|
||||||
|
preallocNonce = NULL;
|
||||||
|
#else
|
||||||
|
output->ticketNonce.data = XREALLOC(preallocNonce,
|
||||||
|
preallocNonceLen, output->heap, DYNAMIC_TYPE_SESSION_TICK);
|
||||||
|
if (output->ticketNonce.data != NULL) {
|
||||||
|
/* don't free the reallocated pointer */
|
||||||
|
preallocNonce = NULL;
|
||||||
|
}
|
||||||
|
#endif /* !XREALLOC */
|
||||||
|
if (output->ticketNonce.data == NULL) {
|
||||||
|
output->ticketNonce.data = output->ticketNonce.dataStatic;
|
||||||
|
output->ticketNonce.len = 0;
|
||||||
|
error = WOLFSSL_FAILURE;
|
||||||
|
/* preallocNonce will be free'd after the if */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
output->ticketNonce.data = preallocNonce;
|
||||||
|
output->ticketNonce.len = preallocNonceLen;
|
||||||
|
preallocNonce = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (preallocNonce != NULL)
|
||||||
|
XFREE(preallocNonce, output->heap, DYNAMIC_TYPE_SESSION_TICK);
|
||||||
|
#endif /* WOLFSSL_TLS13 && WOLFSSL_TICKET_NONCE_MALLOC && FIPS_VERSION_GE(5,3)*/
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
|
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
|
||||||
@ -14091,7 +14203,14 @@ int AddSessionToCache(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* addSession,
|
|||||||
byte ticBuffUsed = 0;
|
byte ticBuffUsed = 0;
|
||||||
byte* ticBuff = NULL;
|
byte* ticBuff = NULL;
|
||||||
int ticLen = 0;
|
int ticLen = 0;
|
||||||
#endif
|
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_TICKET_NONCE_MALLOC) && \
|
||||||
|
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
|
||||||
|
byte *preallocNonce = NULL;
|
||||||
|
byte preallocNonceLen = 0;
|
||||||
|
byte preallocNonceUsed = 0;
|
||||||
|
byte *toFree = NULL;
|
||||||
|
#endif /* WOLFSSL_TLS13 && WOLFSSL_TICKET_NONCE_MALLOC */
|
||||||
|
#endif /* HAVE_SESSION_TICKET */
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int row;
|
int row;
|
||||||
int i;
|
int i;
|
||||||
@ -14113,7 +14232,6 @@ int AddSessionToCache(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* addSession,
|
|||||||
return MEMORY_E;
|
return MEMORY_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find a position for the new session in cache and use that */
|
|
||||||
#ifdef HAVE_SESSION_TICKET
|
#ifdef HAVE_SESSION_TICKET
|
||||||
ticLen = addSession->ticketLen;
|
ticLen = addSession->ticketLen;
|
||||||
/* Alloc Memory here to avoid syscalls during lock */
|
/* Alloc Memory here to avoid syscalls during lock */
|
||||||
@ -14124,13 +14242,35 @@ int AddSessionToCache(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* addSession,
|
|||||||
return MEMORY_E;
|
return MEMORY_E;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_TICKET_NONCE_MALLOC) && \
|
||||||
|
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
|
||||||
|
if (addSession->ticketNonce.data != addSession->ticketNonce.dataStatic) {
|
||||||
|
/* use the AddSession->heap even if the buffer maybe saved in
|
||||||
|
* CachedSession objects. CachedSession heap and AddSession heap should
|
||||||
|
* be the same */
|
||||||
|
preallocNonce = (byte*)XMALLOC(addSession->ticketNonce.len,
|
||||||
|
addSession->heap, DYNAMIC_TYPE_SESSION_TICK);
|
||||||
|
if (preallocNonce == NULL) {
|
||||||
|
if (ticBuff != NULL)
|
||||||
|
XFREE(ticBuff, addSession->heap, DYNAMIC_TYPE_SESSION_TICK);
|
||||||
|
return MEMORY_E;
|
||||||
|
}
|
||||||
|
preallocNonceLen = addSession->ticketNonce.len;
|
||||||
|
}
|
||||||
|
#endif /* WOLFSSL_TLS13 && WOLFSL_TICKET_NONCE_MALLOC && FIPS_VERSION_GE(5,3) */
|
||||||
|
#endif /* HAVE_SESSION_TICKET */
|
||||||
|
|
||||||
|
/* Find a position for the new session in cache and use that */
|
||||||
/* Use the session object in the cache for external cache if required */
|
/* Use the session object in the cache for external cache if required */
|
||||||
row = (int)(HashObject(id, ID_LEN, &ret) % SESSION_ROWS);
|
row = (int)(HashObject(id, ID_LEN, &ret) % SESSION_ROWS);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
WOLFSSL_MSG("Hash session failed");
|
WOLFSSL_MSG("Hash session failed");
|
||||||
#ifdef HAVE_SESSION_TICKET
|
#ifdef HAVE_SESSION_TICKET
|
||||||
XFREE(ticBuff, NULL, DYNAMIC_TYPE_SESSION_TICK);
|
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
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -14139,6 +14279,10 @@ int AddSessionToCache(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* addSession,
|
|||||||
if (SESSION_ROW_LOCK(sessRow) != 0) {
|
if (SESSION_ROW_LOCK(sessRow) != 0) {
|
||||||
#ifdef HAVE_SESSION_TICKET
|
#ifdef HAVE_SESSION_TICKET
|
||||||
XFREE(ticBuff, NULL, DYNAMIC_TYPE_SESSION_TICK);
|
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
|
#endif
|
||||||
WOLFSSL_MSG("Session row lock failed");
|
WOLFSSL_MSG("Session row lock failed");
|
||||||
return BAD_MUTEX_E;
|
return BAD_MUTEX_E;
|
||||||
@ -14193,6 +14337,19 @@ int AddSessionToCache(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* addSession,
|
|||||||
cacheSession->ticket = ticBuff;
|
cacheSession->ticket = ticBuff;
|
||||||
cacheSession->ticketLenAlloc = (word16) ticLen;
|
cacheSession->ticketLenAlloc = (word16) ticLen;
|
||||||
}
|
}
|
||||||
|
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_TICKET_NONCE_MALLOC) && \
|
||||||
|
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
|
||||||
|
/* cache entry never used */
|
||||||
|
if (cacheSession->ticketNonce.data == NULL)
|
||||||
|
cacheSession->ticketNonce.data = cacheSession->ticketNonce.dataStatic;
|
||||||
|
|
||||||
|
if (cacheSession->ticketNonce.data !=
|
||||||
|
cacheSession->ticketNonce.dataStatic) {
|
||||||
|
toFree = cacheSession->ticketNonce.data;
|
||||||
|
cacheSession->ticketNonce.data = cacheSession->ticketNonce.dataStatic;
|
||||||
|
cacheSession->ticketNonce.len = 0;
|
||||||
|
}
|
||||||
|
#endif /* WOFLSSL_TLS13 && WOLFSSL_TICKET_NONCE_MALLOC && FIPS_VERSION_GE(5,3)*/
|
||||||
#endif
|
#endif
|
||||||
#ifdef SESSION_CERTS
|
#ifdef SESSION_CERTS
|
||||||
if (overwrite &&
|
if (overwrite &&
|
||||||
@ -14206,7 +14363,15 @@ int AddSessionToCache(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* addSession,
|
|||||||
#endif /* SESSION_CERTS */
|
#endif /* SESSION_CERTS */
|
||||||
cacheSession->heap = NULL;
|
cacheSession->heap = NULL;
|
||||||
/* Copy data into the cache object */
|
/* Copy data into the cache object */
|
||||||
|
#if defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_TLS13) && \
|
||||||
|
defined(WOLFSSL_TICKET_NONCE_MALLOC) && \
|
||||||
|
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
|
||||||
|
ret = wolfSSL_DupSessionEx(addSession, cacheSession, 1, preallocNonce,
|
||||||
|
&preallocNonceLen, &preallocNonceUsed) == WOLFSSL_FAILURE;
|
||||||
|
#else
|
||||||
ret = wolfSSL_DupSession(addSession, cacheSession, 1) == WOLFSSL_FAILURE;
|
ret = wolfSSL_DupSession(addSession, cacheSession, 1) == WOLFSSL_FAILURE;
|
||||||
|
#endif /* HAVE_SESSION_TICKET && WOLFSSL_TLS13 && WOLFSSL_TICKET_NONCE_MALLOC
|
||||||
|
&& FIPS_VERSION_GE(5,3)*/
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
/* Increment the totalCount and the nextIdx */
|
/* Increment the totalCount and the nextIdx */
|
||||||
@ -14226,6 +14391,17 @@ int AddSessionToCache(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* addSession,
|
|||||||
cacheSession->rem_sess_cb = ctx->rem_sess_cb;
|
cacheSession->rem_sess_cb = ctx->rem_sess_cb;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_TLS13) && \
|
||||||
|
defined(WOLFSSL_TICKET_NONCE_MALLOC) && \
|
||||||
|
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
|
||||||
|
if (preallocNonce != NULL && preallocNonceUsed) {
|
||||||
|
cacheSession->ticketNonce.data = preallocNonce;
|
||||||
|
cacheSession->ticketNonce.len = preallocNonceLen;
|
||||||
|
preallocNonce = NULL;
|
||||||
|
preallocNonceLen = 0;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_SESSION_TICKET && WOLFSSL_TLS13 && WOLFSSL_TICKET_NONCE_MALLOC
|
||||||
|
* && FIPS_VERSION_GE(5,3)*/
|
||||||
}
|
}
|
||||||
#ifdef HAVE_SESSION_TICKET
|
#ifdef HAVE_SESSION_TICKET
|
||||||
else if (ticBuffUsed) {
|
else if (ticBuffUsed) {
|
||||||
@ -14253,6 +14429,13 @@ int AddSessionToCache(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* addSession,
|
|||||||
XFREE(ticBuff, NULL, DYNAMIC_TYPE_SESSION_TICK);
|
XFREE(ticBuff, NULL, DYNAMIC_TYPE_SESSION_TICK);
|
||||||
if (cacheTicBuff != NULL)
|
if (cacheTicBuff != NULL)
|
||||||
XFREE(cacheTicBuff, NULL, DYNAMIC_TYPE_SESSION_TICK);
|
XFREE(cacheTicBuff, NULL, DYNAMIC_TYPE_SESSION_TICK);
|
||||||
|
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_TICKET_NONCE_MALLOC) && \
|
||||||
|
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
|
||||||
|
if (preallocNonce != NULL)
|
||||||
|
XFREE(preallocNonce, addSession->heap, DYNAMIC_TYPE_SESSION_TICK);
|
||||||
|
if (toFree != NULL)
|
||||||
|
XFREE(toFree, addSession->heap, DYNAMIC_TYPE_SESSION_TICK);
|
||||||
|
#endif /* WOLFSSL_TLS13 && WOLFSSL_TICKET_NONCE_MALLOC && FIPS_VERSION_GE(5,3)*/
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
|
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
|
||||||
@ -20026,6 +20209,10 @@ WOLFSSL_SESSION* wolfSSL_NewSession(void* heap)
|
|||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_SESSION_TICKET
|
#ifdef HAVE_SESSION_TICKET
|
||||||
ret->ticket = ret->staticTicket;
|
ret->ticket = ret->staticTicket;
|
||||||
|
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_TICKET_NONCE_MALLOC) && \
|
||||||
|
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
|
||||||
|
ret->ticketNonce.data = ret->ticketNonce.dataStatic;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_STUNNEL
|
#ifdef HAVE_STUNNEL
|
||||||
/* stunnel has this funny mechanism of storing the "is_authenticated"
|
/* stunnel has this funny mechanism of storing the "is_authenticated"
|
||||||
@ -20088,11 +20275,16 @@ int wolfSSL_SESSION_up_ref(WOLFSSL_SESSION* session)
|
|||||||
* sessions from cache. When a cache row is locked, we
|
* sessions from cache. When a cache row is locked, we
|
||||||
* don't want to block other threads with long running
|
* don't want to block other threads with long running
|
||||||
* system calls.
|
* system calls.
|
||||||
|
* @param ticketNonceBuf If not null and @avoidSysCalls is true, the copy of the
|
||||||
|
* ticketNonce will happen in this pre allocated buffer
|
||||||
|
* @param ticketNonceLen @ticketNonceBuf len as input, used length on output
|
||||||
|
* @param ticketNonceUsed if @ticketNonceBuf was used to copy the ticket noncet
|
||||||
* @return WOLFSSL_SUCCESS on success
|
* @return WOLFSSL_SUCCESS on success
|
||||||
* WOLFSSL_FAILURE on failure
|
* WOLFSSL_FAILURE on failure
|
||||||
*/
|
*/
|
||||||
int wolfSSL_DupSession(const WOLFSSL_SESSION* input, WOLFSSL_SESSION* output,
|
static int wolfSSL_DupSessionEx(const WOLFSSL_SESSION* input,
|
||||||
int avoidSysCalls)
|
WOLFSSL_SESSION* output, int avoidSysCalls, byte* ticketNonceBuf,
|
||||||
|
byte* ticketNonceLen, byte* preallocUsed)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_SESSION_TICKET
|
#ifdef HAVE_SESSION_TICKET
|
||||||
int ticLenAlloc = 0;
|
int ticLenAlloc = 0;
|
||||||
@ -20102,6 +20294,9 @@ int wolfSSL_DupSession(const WOLFSSL_SESSION* input, WOLFSSL_SESSION* output,
|
|||||||
int ret = WOLFSSL_SUCCESS;
|
int ret = WOLFSSL_SUCCESS;
|
||||||
|
|
||||||
(void)avoidSysCalls;
|
(void)avoidSysCalls;
|
||||||
|
(void)ticketNonceBuf;
|
||||||
|
(void)ticketNonceLen;
|
||||||
|
(void)preallocUsed;
|
||||||
|
|
||||||
input = ClientSessionToSession(input);
|
input = ClientSessionToSession(input);
|
||||||
output = ClientSessionToSession(output);
|
output = ClientSessionToSession(output);
|
||||||
@ -20116,7 +20311,27 @@ int wolfSSL_DupSession(const WOLFSSL_SESSION* input, WOLFSSL_SESSION* output,
|
|||||||
ticBuff = output->ticket;
|
ticBuff = output->ticket;
|
||||||
ticLenAlloc = output->ticketLenAlloc;
|
ticLenAlloc = output->ticketLenAlloc;
|
||||||
}
|
}
|
||||||
#endif
|
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_TICKET_NONCE_MALLOC) && \
|
||||||
|
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
|
||||||
|
/* free the data, it would be better to re-use the buffer but this
|
||||||
|
* maintain the code simpler. A smart allocator should re-use the free'd
|
||||||
|
* buffer in the next malloc without much performance penalties. */
|
||||||
|
if (output->ticketNonce.data != output->ticketNonce.dataStatic) {
|
||||||
|
|
||||||
|
/* Callers that avoid syscall should never calls this with
|
||||||
|
* output->tickeNonce.data being a dynamic buffer.*/
|
||||||
|
if (avoidSysCalls) {
|
||||||
|
WOLFSSL_MSG("can't avoid syscalls with dynamic TicketNonce buffer");
|
||||||
|
return WOLFSSL_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
XFREE(output->ticketNonce.data,
|
||||||
|
output->heap, DYNAMIC_TYPE_SESSION_TICK);
|
||||||
|
output->ticketNonce.data = output->ticketNonce.dataStatic;
|
||||||
|
output->ticketNonce.len = 0;
|
||||||
|
}
|
||||||
|
#endif /* WOLFSSL_TLS13 && WOLFSSL_TICKET_NONCE_MALLOC && FIPS_VERSION_GE(5,3)*/
|
||||||
|
#endif /* HAVE_SESSION_TICKET */
|
||||||
|
|
||||||
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
|
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
|
||||||
if (output->peer != NULL) {
|
if (output->peer != NULL) {
|
||||||
@ -20132,6 +20347,12 @@ int wolfSSL_DupSession(const WOLFSSL_SESSION* input, WOLFSSL_SESSION* output,
|
|||||||
XMEMCPY((byte*)output + copyOffset, (byte*)input + copyOffset,
|
XMEMCPY((byte*)output + copyOffset, (byte*)input + copyOffset,
|
||||||
sizeof(WOLFSSL_SESSION) - copyOffset);
|
sizeof(WOLFSSL_SESSION) - copyOffset);
|
||||||
|
|
||||||
|
#if defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_TLS13) && \
|
||||||
|
defined(WOLFSSL_TICKET_NONCE_MALLOC) && \
|
||||||
|
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
|
||||||
|
/* fix pointer to static after the copy */
|
||||||
|
output->ticketNonce.data = output->ticketNonce.dataStatic;
|
||||||
|
#endif
|
||||||
/* Set sane values for copy */
|
/* Set sane values for copy */
|
||||||
#ifndef NO_SESSION_CACHE
|
#ifndef NO_SESSION_CACHE
|
||||||
if (output->type != WOLFSSL_SESSION_TYPE_CACHE)
|
if (output->type != WOLFSSL_SESSION_TYPE_CACHE)
|
||||||
@ -20225,10 +20446,74 @@ int wolfSSL_DupSession(const WOLFSSL_SESSION* input, WOLFSSL_SESSION* output,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ticBuff = NULL;
|
ticBuff = NULL;
|
||||||
|
|
||||||
|
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_TICKET_NONCE_MALLOC) && \
|
||||||
|
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
|
||||||
|
if (preallocUsed != NULL)
|
||||||
|
*preallocUsed = 0;
|
||||||
|
|
||||||
|
if (input->ticketNonce.len > MAX_TICKET_NONCE_STATIC_SZ &&
|
||||||
|
ret == WOLFSSL_SUCCESS) {
|
||||||
|
/* TicketNonce does not fit in the static buffer */
|
||||||
|
if (!avoidSysCalls) {
|
||||||
|
output->ticketNonce.data = (byte*)XMALLOC(input->ticketNonce.len,
|
||||||
|
output->heap, DYNAMIC_TYPE_SESSION_TICK);
|
||||||
|
|
||||||
|
if (output->ticketNonce.data == NULL) {
|
||||||
|
WOLFSSL_MSG("Failed to allocate space for ticket nonce");
|
||||||
|
output->ticketNonce.data = output->ticketNonce.dataStatic;
|
||||||
|
output->ticketNonce.len = 0;
|
||||||
|
ret = WOLFSSL_FAILURE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
output->ticketNonce.len = input->ticketNonce.len;
|
||||||
|
XMEMCPY(output->ticketNonce.data, input->ticketNonce.data,
|
||||||
|
input->ticketNonce.len);
|
||||||
|
ret = WOLFSSL_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* we can't do syscalls. Use prealloc buffers if provided from the
|
||||||
|
* caller. */
|
||||||
|
else if (ticketNonceBuf != NULL &&
|
||||||
|
*ticketNonceLen >= input->ticketNonce.len) {
|
||||||
|
XMEMCPY(ticketNonceBuf, input->ticketNonce.data,
|
||||||
|
input->ticketNonce.len);
|
||||||
|
*ticketNonceLen = input->ticketNonce.len;
|
||||||
|
if (preallocUsed != NULL)
|
||||||
|
*preallocUsed = 1;
|
||||||
|
ret = WOLFSSL_SUCCESS;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
WOLFSSL_MSG("TicketNonce bigger than static buffer, and we can't "
|
||||||
|
"do syscalls");
|
||||||
|
ret = WOLFSSL_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* WOLFSSL_TLS13 && WOLFSSL_TICKET_NONCE_MALLOC && FIPS_VERSION_GE(5,3)*/
|
||||||
|
|
||||||
#endif /* HAVE_SESSION_TICKET */
|
#endif /* HAVE_SESSION_TICKET */
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deep copy the contents from input to output.
|
||||||
|
* @param input The source of the copy.
|
||||||
|
* @param output The destination of the copy.
|
||||||
|
* @param avoidSysCalls If true, then system calls will be avoided or an error
|
||||||
|
* will be returned if it is not possible to proceed
|
||||||
|
* without a system call. This is useful for fetching
|
||||||
|
* sessions from cache. When a cache row is locked, we
|
||||||
|
* don't want to block other threads with long running
|
||||||
|
* system calls.
|
||||||
|
* @return WOLFSSL_SUCCESS on success
|
||||||
|
* WOLFSSL_FAILURE on failure
|
||||||
|
*/
|
||||||
|
int wolfSSL_DupSession(const WOLFSSL_SESSION* input, WOLFSSL_SESSION* output,
|
||||||
|
int avoidSysCalls)
|
||||||
|
{
|
||||||
|
return wolfSSL_DupSessionEx(input, output, avoidSysCalls, NULL, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
WOLFSSL_SESSION* wolfSSL_SESSION_dup(WOLFSSL_SESSION* session)
|
WOLFSSL_SESSION* wolfSSL_SESSION_dup(WOLFSSL_SESSION* session)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_EXT_CACHE
|
#ifdef HAVE_EXT_CACHE
|
||||||
@ -20318,6 +20603,13 @@ void wolfSSL_FreeSession(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* session)
|
|||||||
if (session->ticketLenAlloc > 0) {
|
if (session->ticketLenAlloc > 0) {
|
||||||
XFREE(session->ticket, session->heap, DYNAMIC_TYPE_SESSION_TICK);
|
XFREE(session->ticket, session->heap, DYNAMIC_TYPE_SESSION_TICK);
|
||||||
}
|
}
|
||||||
|
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_TICKET_NONCE_MALLOC) && \
|
||||||
|
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
|
||||||
|
if (session->ticketNonce.data != session->ticketNonce.dataStatic) {
|
||||||
|
XFREE(session->ticketNonce.data, session->heap,
|
||||||
|
DYNAMIC_TYPE_SESSION_TICK);
|
||||||
|
}
|
||||||
|
#endif /* WOLFSSL_TLS13 && WOLFSSL_TICKET_NONCE_MALLOC && FIPS_VERSION_GE(5,3)*/
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
|
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
|
||||||
@ -25766,7 +26058,19 @@ WOLFSSL_SESSION* wolfSSL_d2i_SSL_SESSION(WOLFSSL_SESSION** sess,
|
|||||||
ret = BUFFER_ERROR;
|
ret = BUFFER_ERROR;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
#if defined(WOLFSSL_TICKET_NONCE_MALLOC) && \
|
||||||
|
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
|
||||||
|
ret = SessionTicketNoncePopulate(s, data + idx, s->ticketNonce.len);
|
||||||
|
if (ret != 0)
|
||||||
|
goto end;
|
||||||
|
#else
|
||||||
|
if (s->ticketNonce.len > MAX_TICKET_NONCE_STATIC_SZ) {
|
||||||
|
ret = BUFFER_ERROR;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
XMEMCPY(s->ticketNonce.data, data + idx, s->ticketNonce.len);
|
XMEMCPY(s->ticketNonce.data, data + idx, s->ticketNonce.len);
|
||||||
|
#endif /* defined(WOLFSSL_TICKET_NONCE_MALLOC) && FIPS_VERSION_GE(5,3) */
|
||||||
|
|
||||||
idx += s->ticketNonce.len;
|
idx += s->ticketNonce.len;
|
||||||
#endif
|
#endif
|
||||||
#ifdef WOLFSSL_EARLY_DATA
|
#ifdef WOLFSSL_EARLY_DATA
|
||||||
|
59
src/tls13.c
59
src/tls13.c
@ -1036,6 +1036,7 @@ int DeriveMasterSecret(WOLFSSL* ssl)
|
|||||||
#define RESUMPTION_LABEL_SZ 10
|
#define RESUMPTION_LABEL_SZ 10
|
||||||
/* Resumption label for generating PSK associated with the ticket. */
|
/* Resumption label for generating PSK associated with the ticket. */
|
||||||
static const byte resumptionLabel[RESUMPTION_LABEL_SZ+1] = "resumption";
|
static const byte resumptionLabel[RESUMPTION_LABEL_SZ+1] = "resumption";
|
||||||
|
|
||||||
/* Derive the PSK associated with the ticket.
|
/* Derive the PSK associated with the ticket.
|
||||||
*
|
*
|
||||||
* ssl The SSL/TLS object.
|
* ssl The SSL/TLS object.
|
||||||
@ -1078,10 +1079,17 @@ int DeriveResumptionPSK(WOLFSSL* ssl, byte* nonce, byte nonceLen, byte* secret)
|
|||||||
}
|
}
|
||||||
|
|
||||||
PRIVATE_KEY_UNLOCK();
|
PRIVATE_KEY_UNLOCK();
|
||||||
|
#if defined(WOLFSSL_TICKET_NONCE_MALLOC) && \
|
||||||
|
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
|
||||||
|
ret = wc_Tls13_HKDF_Expand_Label_Alloc(secret, ssl->specs.hash_size,
|
||||||
|
ssl->session->masterSecret, ssl->specs.hash_size, protocol, protocolLen,
|
||||||
|
resumptionLabel, RESUMPTION_LABEL_SZ, nonce, nonceLen, digestAlg,
|
||||||
|
ssl->heap);
|
||||||
|
#else
|
||||||
ret = wc_Tls13_HKDF_Expand_Label(secret, ssl->specs.hash_size,
|
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,
|
||||||
protocol, protocolLen, resumptionLabel,
|
resumptionLabel, RESUMPTION_LABEL_SZ, nonce, nonceLen, digestAlg);
|
||||||
RESUMPTION_LABEL_SZ, nonce, nonceLen, digestAlg);
|
#endif /* !defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3) */
|
||||||
PRIVATE_KEY_LOCK();
|
PRIVATE_KEY_LOCK();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -9181,6 +9189,31 @@ static int DoTls13EndOfEarlyData(WOLFSSL* ssl, const byte* input,
|
|||||||
#endif /* !NO_WOLFSSL_SERVER */
|
#endif /* !NO_WOLFSSL_SERVER */
|
||||||
#endif /* WOLFSSL_EARLY_DATA */
|
#endif /* WOLFSSL_EARLY_DATA */
|
||||||
|
|
||||||
|
#if defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_TICKET_NONCE_MALLOC) && \
|
||||||
|
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
|
||||||
|
int SessionTicketNoncePopulate(WOLFSSL_SESSION *session, const byte *nonce,
|
||||||
|
byte len)
|
||||||
|
{
|
||||||
|
if (session->ticketNonce.data
|
||||||
|
!= session->ticketNonce.dataStatic) {
|
||||||
|
XFREE(session->ticketNonce.data, heap,
|
||||||
|
DYNAMIC_TYPE_SESSION_TICK);
|
||||||
|
session->ticketNonce.data = session->ticketNonce.dataStatic;
|
||||||
|
session->ticketNonce.len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len > MAX_TICKET_NONCE_STATIC_SZ) {
|
||||||
|
WOLFSSL_MSG("Using dynamic nonce buffer");
|
||||||
|
session->ticketNonce.data = (byte*)XMALLOC(len,
|
||||||
|
session->heap, DYNAMIC_TYPE_SESSION_TICK);
|
||||||
|
if (session->ticketNonce.data == NULL)
|
||||||
|
return MEMORY_ERROR;
|
||||||
|
}
|
||||||
|
XMEMCPY(session->ticketNonce.data, nonce, len);
|
||||||
|
session->ticketNonce.len = len;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#ifndef NO_WOLFSSL_CLIENT
|
#ifndef NO_WOLFSSL_CLIENT
|
||||||
/* Handle a New Session Ticket handshake message.
|
/* Handle a New Session Ticket handshake message.
|
||||||
* Message contains the information required to perform resumption.
|
* Message contains the information required to perform resumption.
|
||||||
@ -9232,11 +9265,14 @@ static int DoTls13NewSessionTicket(WOLFSSL* ssl, const byte* input,
|
|||||||
if ((*inOutIdx - begin) + 1 > size)
|
if ((*inOutIdx - begin) + 1 > size)
|
||||||
return BUFFER_ERROR;
|
return BUFFER_ERROR;
|
||||||
nonceLength = input[*inOutIdx];
|
nonceLength = input[*inOutIdx];
|
||||||
if (nonceLength > MAX_TICKET_NONCE_SZ) {
|
#if !defined(WOLFSSL_TICKET_NONCE_MALLOC) && \
|
||||||
|
(!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3))
|
||||||
|
if (nonceLength > MAX_TICKET_NONCE_STATIC_SZ) {
|
||||||
WOLFSSL_MSG("Nonce length not supported");
|
WOLFSSL_MSG("Nonce length not supported");
|
||||||
WOLFSSL_ERROR_VERBOSE(INVALID_PARAMETER);
|
WOLFSSL_ERROR_VERBOSE(INVALID_PARAMETER);
|
||||||
return INVALID_PARAMETER;
|
return INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
#endif /* WOLFSSL_TICKET_NONCE_MALLOC && FIPS_VERSION_GE(5,3) */
|
||||||
*inOutIdx += 1;
|
*inOutIdx += 1;
|
||||||
if ((*inOutIdx - begin) + nonceLength > size)
|
if ((*inOutIdx - begin) + nonceLength > size)
|
||||||
return BUFFER_ERROR;
|
return BUFFER_ERROR;
|
||||||
@ -9268,9 +9304,22 @@ static int DoTls13NewSessionTicket(WOLFSSL* ssl, const byte* input,
|
|||||||
#ifdef WOLFSSL_EARLY_DATA
|
#ifdef WOLFSSL_EARLY_DATA
|
||||||
ssl->session->maxEarlyDataSz = ssl->options.maxEarlyDataSz;
|
ssl->session->maxEarlyDataSz = ssl->options.maxEarlyDataSz;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(WOLFSSL_TICKET_NONCE_MALLOC) && \
|
||||||
|
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
|
||||||
|
ret = SessionTicketNoncePopulate(ssl->session, nonce, nonceLength);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
#else
|
||||||
ssl->session->ticketNonce.len = nonceLength;
|
ssl->session->ticketNonce.len = nonceLength;
|
||||||
|
if (nonceLength > MAX_TICKET_NONCE_STATIC_SZ) {
|
||||||
|
ret = BUFFER_ERROR;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
if (nonceLength > 0)
|
if (nonceLength > 0)
|
||||||
XMEMCPY(&ssl->session->ticketNonce.data, nonce, nonceLength);
|
XMEMCPY(ssl->session->ticketNonce.data, nonce, nonceLength);
|
||||||
|
#endif /* defined(WOLFSSL_TICKET_NONCE_MALLOC) && FIPS_VERSION_GE(5,3) */
|
||||||
|
|
||||||
ssl->session->namedGroup = ssl->namedGroup;
|
ssl->session->namedGroup = ssl->namedGroup;
|
||||||
|
|
||||||
if ((*inOutIdx - begin) + EXTS_SZ > size)
|
if ((*inOutIdx - begin) + EXTS_SZ > size)
|
||||||
|
287
tests/api.c
287
tests/api.c
@ -58570,8 +58570,289 @@ static int test_wolfSSL_DTLS_fragment_buckets(void)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(WOLFSSL_TICKET_NONCE_MALLOC) && defined(HAVE_SESSION_TICKET) \
|
||||||
|
&& defined(WOLFSSL_TLS13) && \
|
||||||
|
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
|
||||||
|
|
||||||
|
#define TEST_NONCE_BUF_SZ 64 * 1024
|
||||||
|
struct test_nonce_ctx
|
||||||
|
{
|
||||||
|
byte c_buff[TEST_NONCE_BUF_SZ];
|
||||||
|
int c_len;
|
||||||
|
byte s_buff[TEST_NONCE_BUF_SZ];
|
||||||
|
int s_len;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int test_ticket_nonce_write_cb(WOLFSSL *ssl,
|
||||||
|
char *data, int sz, void *ctx)
|
||||||
|
{
|
||||||
|
struct test_nonce_ctx *test_ctx;
|
||||||
|
byte *buf;
|
||||||
|
int *len;
|
||||||
|
|
||||||
|
test_ctx = (struct test_nonce_ctx*)ctx;
|
||||||
|
|
||||||
|
if (ssl->options.side == WOLFSSL_SERVER_END) {
|
||||||
|
buf = test_ctx->c_buff;
|
||||||
|
len = &test_ctx->c_len;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
buf = test_ctx->s_buff;
|
||||||
|
len = &test_ctx->s_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((unsigned)(*len + sz) > TEST_NONCE_BUF_SZ)
|
||||||
|
return WOLFSSL_CBIO_ERR_WANT_READ;
|
||||||
|
|
||||||
|
XMEMCPY(buf + *len, data, sz);
|
||||||
|
*len += sz;
|
||||||
|
|
||||||
|
return sz;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_ticket_nonce_read_cb(WOLFSSL *ssl,
|
||||||
|
char *data, int sz, void *ctx)
|
||||||
|
{
|
||||||
|
struct test_nonce_ctx *test_ctx;
|
||||||
|
int read_sz;
|
||||||
|
byte *buf;
|
||||||
|
int *len;
|
||||||
|
|
||||||
|
test_ctx = (struct test_nonce_ctx*)ctx;
|
||||||
|
|
||||||
|
if (ssl->options.side == WOLFSSL_SERVER_END) {
|
||||||
|
buf = test_ctx->s_buff;
|
||||||
|
len = &test_ctx->s_len;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
buf = test_ctx->c_buff;
|
||||||
|
len = &test_ctx->c_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*len == 0)
|
||||||
|
return WOLFSSL_CBIO_ERR_WANT_READ;
|
||||||
|
|
||||||
|
read_sz = sz < *len ? sz : *len;
|
||||||
|
|
||||||
|
XMEMCPY(data, buf, read_sz);
|
||||||
|
XMEMMOVE(buf, buf + read_sz, *len - read_sz);
|
||||||
|
|
||||||
|
*len -= read_sz;
|
||||||
|
|
||||||
|
return read_sz;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int send_new_session_ticket(WOLFSSL *ssl, byte nonceLength, byte filler)
|
||||||
|
{
|
||||||
|
struct test_nonce_ctx *test_ctx;
|
||||||
|
byte buf[2048];
|
||||||
|
int idx, sz;
|
||||||
|
word32 tmp;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
idx = 5; /* space for record header */
|
||||||
|
|
||||||
|
buf[idx] = session_ticket; /* type */
|
||||||
|
idx++;
|
||||||
|
|
||||||
|
tmp = OPAQUE32_LEN +
|
||||||
|
OPAQUE32_LEN +
|
||||||
|
OPAQUE8_LEN + nonceLength +
|
||||||
|
OPAQUE16_LEN + OPAQUE8_LEN + OPAQUE16_LEN;
|
||||||
|
c32to24(tmp, buf + idx);
|
||||||
|
idx += OPAQUE24_LEN;
|
||||||
|
|
||||||
|
c32toa((word32)12345, buf+idx); /* lifetime */
|
||||||
|
idx += OPAQUE32_LEN;
|
||||||
|
c32toa((word32)12345, buf+idx); /* add */
|
||||||
|
idx += OPAQUE32_LEN;
|
||||||
|
buf[idx] = nonceLength; /* nonce length */
|
||||||
|
idx++;
|
||||||
|
XMEMSET(&buf[idx], filler, nonceLength); /* nonce */
|
||||||
|
idx += nonceLength;
|
||||||
|
tmp = 1; /* ticket len */
|
||||||
|
c16toa((word16)tmp, buf+idx);
|
||||||
|
idx += 2;
|
||||||
|
buf[idx] = 0xFF; /* ticket */
|
||||||
|
idx++;
|
||||||
|
tmp = 0; /* ext len */
|
||||||
|
c16toa((word16)tmp, buf+idx);
|
||||||
|
idx += 2;
|
||||||
|
|
||||||
|
sz = BuildTls13Message(ssl, buf, 2048, buf+5, idx - 5,
|
||||||
|
handshake, 0, 0, 0);
|
||||||
|
test_ctx = (struct test_nonce_ctx*)wolfSSL_GetIOWriteCtx(ssl);
|
||||||
|
ret = test_ticket_nonce_write_cb(ssl, (char*)buf, sz, test_ctx);
|
||||||
|
return !(ret == sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_ticket_nonce_check(WOLFSSL_SESSION *sess, byte len)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (sess == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (sess->ticketNonce.len != len)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
if (sess->ticketNonce.data[i] != len)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_ticket_nonce_malloc_do(WOLFSSL *ssl_s, WOLFSSL *ssl_c, byte len)
|
||||||
|
{
|
||||||
|
char *buf[1024];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = send_new_session_ticket(ssl_s, len, len);
|
||||||
|
if (ret != 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
ret = wolfSSL_recv(ssl_c, buf, 1024, 0);
|
||||||
|
if (ret != WOLFSSL_SUCCESS && ssl_c->error != WANT_READ)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return test_ticket_nonce_check(ssl_c->session, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_ticket_nonce_cache(WOLFSSL *ssl_s, WOLFSSL *ssl_c, byte len)
|
||||||
|
{
|
||||||
|
WOLFSSL_SESSION *sess, *cached;
|
||||||
|
WOLFSSL_CTX *ctx;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ctx = ssl_c->ctx;
|
||||||
|
|
||||||
|
ret = test_ticket_nonce_malloc_do(ssl_s, ssl_c, len);
|
||||||
|
if (ret != 0)
|
||||||
|
return -1;
|
||||||
|
sess = wolfSSL_get1_session(ssl_c);
|
||||||
|
if (sess == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
ret = AddSessionToCache(ctx, sess, sess->sessionID, sess->sessionIDSz,
|
||||||
|
NULL, ssl_c->options.side, 1,NULL);
|
||||||
|
if (ret != 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
cached = wolfSSL_SESSION_new();
|
||||||
|
if (cached == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
ret = wolfSSL_GetSessionFromCache(ssl_c, cached);
|
||||||
|
if (ret != WOLFSSL_SUCCESS)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
ret = test_ticket_nonce_check(cached, len);
|
||||||
|
if (ret != 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
wolfSSL_SESSION_free(cached);
|
||||||
|
wolfSSL_SESSION_free(sess);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_ticket_nonce_malloc(void)
|
||||||
|
{
|
||||||
|
struct test_nonce_ctx test_ctx = { 0 };
|
||||||
|
WOLFSSL_CTX *ctx_c, *ctx_s;
|
||||||
|
byte small, medium, big;
|
||||||
|
WOLFSSL *ssl_c, *ssl_s;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ctx_c = wolfSSL_CTX_new(wolfTLSv1_3_client_method());
|
||||||
|
ctx_s = wolfSSL_CTX_new(wolfTLSv1_3_server_method());
|
||||||
|
if (ctx_c == NULL || ctx_s == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* will send ticket manually */
|
||||||
|
wolfSSL_CTX_no_ticket_TLSv13(ctx_s);
|
||||||
|
|
||||||
|
wolfSSL_CTX_set_verify(ctx_s, WOLFSSL_VERIFY_NONE, 0);
|
||||||
|
wolfSSL_CTX_set_verify(ctx_c, WOLFSSL_VERIFY_NONE, 0);
|
||||||
|
|
||||||
|
ret = wolfSSL_CTX_use_PrivateKey_file(ctx_s, svrKeyFile,
|
||||||
|
WOLFSSL_FILETYPE_PEM);
|
||||||
|
if (ret != WOLFSSL_SUCCESS)
|
||||||
|
return- -1;
|
||||||
|
|
||||||
|
ret = wolfSSL_CTX_use_certificate_file(ctx_s, svrCertFile,
|
||||||
|
WOLFSSL_FILETYPE_PEM);
|
||||||
|
if (ret != WOLFSSL_SUCCESS)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
wolfSSL_SetIORecv(ctx_c, test_ticket_nonce_read_cb);
|
||||||
|
wolfSSL_SetIOSend(ctx_c, test_ticket_nonce_write_cb);
|
||||||
|
wolfSSL_SetIORecv(ctx_s, test_ticket_nonce_read_cb);
|
||||||
|
wolfSSL_SetIOSend(ctx_s, test_ticket_nonce_write_cb);
|
||||||
|
|
||||||
|
ssl_c = wolfSSL_new(ctx_c);
|
||||||
|
ssl_s = wolfSSL_new(ctx_s);
|
||||||
|
if (ssl_c == NULL || ssl_s == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
wolfSSL_SetIOWriteCtx(ssl_c, &test_ctx);
|
||||||
|
wolfSSL_SetIOReadCtx(ssl_c, &test_ctx);
|
||||||
|
wolfSSL_SetIOWriteCtx(ssl_s, &test_ctx);
|
||||||
|
wolfSSL_SetIOReadCtx(ssl_s, &test_ctx);
|
||||||
|
|
||||||
|
while (!ssl_c->options.handShakeDone && !ssl_s->options.handShakeDone) {
|
||||||
|
ret = wolfSSL_connect(ssl_c);
|
||||||
|
if (ret != WOLFSSL_SUCCESS && ssl_c->error != WANT_READ)
|
||||||
|
return -2;
|
||||||
|
|
||||||
|
ret = wolfSSL_accept(ssl_s);
|
||||||
|
if (ret != WOLFSSL_SUCCESS && ssl_s->error != WANT_READ)
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
small = TLS13_TICKET_NONCE_STATIC_SZ;
|
||||||
|
medium = small + 20 <= 255 ? small + 20 : 255;
|
||||||
|
big = medium + 20 <= 255 ? small + 20 : 255;
|
||||||
|
|
||||||
|
if (test_ticket_nonce_malloc_do(ssl_s, ssl_c, small))
|
||||||
|
return -1;
|
||||||
|
if (ssl_c->session->ticketNonce.data !=
|
||||||
|
ssl_c->session->ticketNonce.dataStatic)
|
||||||
|
return -1;
|
||||||
|
if (test_ticket_nonce_malloc_do(ssl_s, ssl_c, medium))
|
||||||
|
return -1;
|
||||||
|
if (test_ticket_nonce_malloc_do(ssl_s, ssl_c, big))
|
||||||
|
return -1;
|
||||||
|
if (test_ticket_nonce_malloc_do(ssl_s, ssl_c, medium))
|
||||||
|
return -5;
|
||||||
|
if (test_ticket_nonce_malloc_do(ssl_s, ssl_c, small))
|
||||||
|
return -6;
|
||||||
|
|
||||||
|
if (test_ticket_nonce_cache(ssl_s, ssl_c, small))
|
||||||
|
return -1;
|
||||||
|
if (test_ticket_nonce_cache(ssl_s, ssl_c, medium))
|
||||||
|
return -1;
|
||||||
|
if (test_ticket_nonce_cache(ssl_s, ssl_c, big))
|
||||||
|
return -1;
|
||||||
|
if (test_ticket_nonce_cache(ssl_s, ssl_c, medium))
|
||||||
|
return -1;
|
||||||
|
if (test_ticket_nonce_cache(ssl_s, ssl_c, small))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
wolfSSL_free(ssl_c);
|
||||||
|
wolfSSL_free(ssl_s);
|
||||||
|
wolfSSL_CTX_free(ctx_c);
|
||||||
|
wolfSSL_CTX_free(ctx_s);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* WOLFSSL_TICKET_NONCE_MALLOC */
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*
|
/*----------------------------------------------------------------------------*
|
||||||
| Main
|
| Main
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
@ -59479,7 +59760,11 @@ TEST_CASE testCases[] = {
|
|||||||
TEST_DECL(test_ForceZero),
|
TEST_DECL(test_ForceZero),
|
||||||
|
|
||||||
TEST_DECL(test_wolfSSL_Cleanup),
|
TEST_DECL(test_wolfSSL_Cleanup),
|
||||||
|
#if defined(WOLFSSL_TICKET_NONCE_MALLOC) && defined(HAVE_SESSION_TICKET) \
|
||||||
|
&& defined(WOLFSSL_TLS13) && \
|
||||||
|
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
|
||||||
|
TEST_DECL(test_ticket_nonce_malloc),
|
||||||
|
#endif
|
||||||
#if !defined(NO_RSA) && !defined(NO_SHA) && !defined(NO_FILESYSTEM) && \
|
#if !defined(NO_RSA) && !defined(NO_SHA) && !defined(NO_FILESYSTEM) && \
|
||||||
!defined(NO_CERTS) && (!defined(NO_WOLFSSL_CLIENT) || \
|
!defined(NO_CERTS) && (!defined(NO_WOLFSSL_CLIENT) || \
|
||||||
!defined(WOLFSSL_NO_CLIENT_AUTH))
|
!defined(WOLFSSL_NO_CLIENT_AUTH))
|
||||||
|
@ -437,6 +437,13 @@ int wc_PRF_TLS(byte* digest, word32 digLen, const byte* secret, word32 secLen,
|
|||||||
int idx = 0;
|
int idx = 0;
|
||||||
byte data[MAX_TLS13_HKDF_LABEL_SZ];
|
byte data[MAX_TLS13_HKDF_LABEL_SZ];
|
||||||
|
|
||||||
|
/* okmLen (2) + protocol|label len (1) + info len(1) + protocollen +
|
||||||
|
* labellen + infolen */
|
||||||
|
idx = 4 + protocolLen + labelLen + infoLen;
|
||||||
|
if (idx > MAX_TLS13_HKDF_LABEL_SZ)
|
||||||
|
return BUFFER_E;
|
||||||
|
idx = 0;
|
||||||
|
|
||||||
/* Output length. */
|
/* Output length. */
|
||||||
data[idx++] = (byte)(okmLen >> 8);
|
data[idx++] = (byte)(okmLen >> 8);
|
||||||
data[idx++] = (byte)okmLen;
|
data[idx++] = (byte)okmLen;
|
||||||
@ -481,6 +488,95 @@ int wc_PRF_TLS(byte* digest, word32 digLen, const byte* secret, word32 secLen,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(WOLFSSL_TICKET_NONCE_MALLOC) && \
|
||||||
|
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
|
||||||
|
/* Expand data using HMAC, salt and label and info.
|
||||||
|
* TLS v1.3 defines this function.
|
||||||
|
*
|
||||||
|
* okm The generated pseudorandom key - output key material.
|
||||||
|
* okmLen The length of generated pseudorandom key -
|
||||||
|
* output key material.
|
||||||
|
* prk The salt - pseudo-random key.
|
||||||
|
* prkLen The length of the salt - pseudo-random key.
|
||||||
|
* protocol The TLS protocol label.
|
||||||
|
* protocolLen The length of the TLS protocol label.
|
||||||
|
* info The information to expand.
|
||||||
|
* infoLen The length of the information.
|
||||||
|
* digest The type of digest to use.
|
||||||
|
*
|
||||||
|
* This functions is very similar to wc_Tls13_HKDF_Expand_Label() but it
|
||||||
|
* allocate memory if the stack space usually used isn't enough.
|
||||||
|
*
|
||||||
|
* returns 0 on success, otherwise failure.
|
||||||
|
*/
|
||||||
|
int wc_Tls13_HKDF_Expand_Label_Alloc(byte* okm, word32 okmLen,
|
||||||
|
const byte* prk, word32 prkLen, const byte* protocol,
|
||||||
|
word32 protocolLen, const byte* label, word32 labelLen,
|
||||||
|
const byte* info, word32 infoLen, int digest, void* heap)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
int idx = 0;
|
||||||
|
int len;
|
||||||
|
byte *data;
|
||||||
|
|
||||||
|
(void)heap;
|
||||||
|
/* okmLen (2) + protocol|label len (1) + info len(1) + protocollen +
|
||||||
|
* labellen + infolen */
|
||||||
|
len = 4 + protocolLen + labelLen + infoLen;
|
||||||
|
|
||||||
|
data = (byte*)XMALLOC(len, heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
if (data == NULL)
|
||||||
|
return BUFFER_E;
|
||||||
|
|
||||||
|
/* Output length. */
|
||||||
|
data[idx++] = (byte)(okmLen >> 8);
|
||||||
|
data[idx++] = (byte)okmLen;
|
||||||
|
/* Length of protocol | label. */
|
||||||
|
data[idx++] = (byte)(protocolLen + labelLen);
|
||||||
|
/* Protocol */
|
||||||
|
XMEMCPY(&data[idx], protocol, protocolLen);
|
||||||
|
idx += protocolLen;
|
||||||
|
/* Label */
|
||||||
|
XMEMCPY(&data[idx], label, labelLen);
|
||||||
|
idx += labelLen;
|
||||||
|
/* Length of hash of messages */
|
||||||
|
data[idx++] = (byte)infoLen;
|
||||||
|
/* Hash of messages */
|
||||||
|
XMEMCPY(&data[idx], info, infoLen);
|
||||||
|
idx += infoLen;
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_CHECK_MEM_ZERO
|
||||||
|
wc_MemZero_Add("wc_Tls13_HKDF_Expand_Label data", data, idx);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_DEBUG_TLS
|
||||||
|
WOLFSSL_MSG(" PRK");
|
||||||
|
WOLFSSL_BUFFER(prk, prkLen);
|
||||||
|
WOLFSSL_MSG(" Info");
|
||||||
|
WOLFSSL_BUFFER(data, idx);
|
||||||
|
WOLFSSL_MSG_EX(" Digest %d", digest);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ret = wc_HKDF_Expand(digest, prk, prkLen, data, idx, okm, okmLen);
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_DEBUG_TLS
|
||||||
|
WOLFSSL_MSG(" OKM");
|
||||||
|
WOLFSSL_BUFFER(okm, okmLen);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ForceZero(data, idx);
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_CHECK_MEM_ZERO
|
||||||
|
wc_MemZero_Check(data, len);
|
||||||
|
#endif
|
||||||
|
XFREE(data, heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/* defined(WOLFSSL_TICKET_NONCE_MALLOC) && (!defined(HAVE_FIPS) ||
|
||||||
|
* FIPS_VERSION_GE(5,3)) */
|
||||||
|
|
||||||
#endif /* HAVE_HKDF && !NO_HMAC */
|
#endif /* HAVE_HKDF && !NO_HMAC */
|
||||||
|
|
||||||
|
|
||||||
|
@ -1298,6 +1298,22 @@ enum {
|
|||||||
#define DTLS_AEAD_AES_CCM_FAIL_LIMIT w64From32(0x00B5, 0x04F3)
|
#define DTLS_AEAD_AES_CCM_FAIL_LIMIT w64From32(0x00B5, 0x04F3)
|
||||||
#define DTLS_AEAD_AES_CCM_FAIL_KU_LIMIT w64From32(0x005A, 0x8279)
|
#define DTLS_AEAD_AES_CCM_FAIL_KU_LIMIT w64From32(0x005A, 0x8279)
|
||||||
|
|
||||||
|
#define TLS13_TICKET_NONCE_MAX_SZ 255
|
||||||
|
|
||||||
|
#if (defined(HAVE_FIPS) && \
|
||||||
|
!(defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3))) && \
|
||||||
|
defined(TLS13_TICKET_NONCE_STATIC_SZ)
|
||||||
|
#error "TLS13_TICKET_NONCE_STATIC_SZ is not supported in this FIPS version"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TLS13_TICKET_NONCE_STATIC_SZ
|
||||||
|
#define TLS13_TICKET_NONCE_STATIC_SZ 8
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if TLS13_TICKET_NONCE_STATIC_SZ > TLS13_TICKET_NONCE_MAX_SZ
|
||||||
|
#error "Max size for ticket nonce is 255 bytes"
|
||||||
|
#endif
|
||||||
|
|
||||||
enum Misc {
|
enum Misc {
|
||||||
CIPHER_BYTE = 0x00, /* Default ciphers */
|
CIPHER_BYTE = 0x00, /* Default ciphers */
|
||||||
ECC_BYTE = 0xC0, /* ECC first cipher suite byte */
|
ECC_BYTE = 0xC0, /* ECC first cipher suite byte */
|
||||||
@ -1388,7 +1404,8 @@ enum Misc {
|
|||||||
SESSION_ADD_SZ = 4, /* session age add */
|
SESSION_ADD_SZ = 4, /* session age add */
|
||||||
TICKET_NONCE_LEN_SZ = 1, /* Ticket nonce length size */
|
TICKET_NONCE_LEN_SZ = 1, /* Ticket nonce length size */
|
||||||
DEF_TICKET_NONCE_SZ = 1, /* Default ticket nonce size */
|
DEF_TICKET_NONCE_SZ = 1, /* Default ticket nonce size */
|
||||||
MAX_TICKET_NONCE_SZ = 8, /* maximum ticket nonce size */
|
MAX_TICKET_NONCE_STATIC_SZ = TLS13_TICKET_NONCE_STATIC_SZ,
|
||||||
|
/* maximum ticket nonce static size */
|
||||||
MAX_LIFETIME = 604800, /* maximum ticket lifetime */
|
MAX_LIFETIME = 604800, /* maximum ticket lifetime */
|
||||||
|
|
||||||
RAN_LEN = 32, /* random length */
|
RAN_LEN = 32, /* random length */
|
||||||
@ -1754,6 +1771,10 @@ enum Misc {
|
|||||||
#define PREALLOC_SESSION_TICKET_LEN 512
|
#define PREALLOC_SESSION_TICKET_LEN 512
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef PREALLOC_SESSION_TICKET_NONCE_LEN
|
||||||
|
#define PREALLOC_SESSION_TICKET_NONCE_LEN 32
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef SESSION_TICKET_HINT_DEFAULT
|
#ifndef SESSION_TICKET_HINT_DEFAULT
|
||||||
#define SESSION_TICKET_HINT_DEFAULT 300
|
#define SESSION_TICKET_HINT_DEFAULT 300
|
||||||
#endif
|
#endif
|
||||||
@ -2776,18 +2797,6 @@ WOLFSSL_LOCAL int TLSX_AddEmptyRenegotiationInfo(TLSX** extensions, void* heap);
|
|||||||
|
|
||||||
#endif /* HAVE_SECURE_RENEGOTIATION */
|
#endif /* HAVE_SECURE_RENEGOTIATION */
|
||||||
|
|
||||||
/** Session Ticket - RFC 5077 (session 3.2) */
|
|
||||||
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
|
||||||
/* Ticket nonce - for deriving PSK.
|
|
||||||
* Length allowed to be: 1..255. Only support 4 bytes.
|
|
||||||
* Defined here so that it can be included in InternalTicket.
|
|
||||||
*/
|
|
||||||
typedef struct TicketNonce {
|
|
||||||
byte len;
|
|
||||||
byte data[MAX_TICKET_NONCE_SZ];
|
|
||||||
} TicketNonce;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SESSION_TICKET
|
#ifdef HAVE_SESSION_TICKET
|
||||||
/* Our ticket format. All members need to be a byte or array of byte to
|
/* Our ticket format. All members need to be a byte or array of byte to
|
||||||
* avoid alignment issues */
|
* avoid alignment issues */
|
||||||
@ -2800,7 +2809,8 @@ typedef struct InternalTicket {
|
|||||||
#ifdef WOLFSSL_TLS13
|
#ifdef WOLFSSL_TLS13
|
||||||
byte ageAdd[AGEADD_LEN]; /* Obfuscation of age */
|
byte ageAdd[AGEADD_LEN]; /* Obfuscation of age */
|
||||||
byte namedGroup[NAMEDGROUP_LEN]; /* Named group used */
|
byte namedGroup[NAMEDGROUP_LEN]; /* Named group used */
|
||||||
TicketNonce ticketNonce; /* Ticket nonce */
|
byte ticketNonceLen;
|
||||||
|
byte ticketNonce[MAX_TICKET_NONCE_STATIC_SZ];
|
||||||
#ifdef WOLFSSL_EARLY_DATA
|
#ifdef WOLFSSL_EARLY_DATA
|
||||||
byte maxEarlyDataSz[MAXEARLYDATASZ_LEN]; /* Max size of
|
byte maxEarlyDataSz[MAXEARLYDATASZ_LEN]; /* Max size of
|
||||||
* early data */
|
* early data */
|
||||||
@ -3696,6 +3706,25 @@ WOLFSSL_LOCAL int wolfSSL_quic_add_transport_extensions(WOLFSSL *ssl, int msg_ty
|
|||||||
|
|
||||||
#endif /* WOLFSSL_QUIC */
|
#endif /* WOLFSSL_QUIC */
|
||||||
|
|
||||||
|
/** Session Ticket - RFC 5077 (session 3.2) */
|
||||||
|
#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
||||||
|
/* Ticket nonce - for deriving PSK.
|
||||||
|
Length allowed to be: 1..255. Only support
|
||||||
|
* TLS13_TICKET_NONCE_STATIC_SZ length bytes.
|
||||||
|
*/
|
||||||
|
typedef struct TicketNonce {
|
||||||
|
byte len;
|
||||||
|
#if defined(WOLFSSL_TICKET_NONCE_MALLOC) && \
|
||||||
|
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
|
||||||
|
byte *data;
|
||||||
|
byte dataStatic[MAX_TICKET_NONCE_STATIC_SZ];
|
||||||
|
#else
|
||||||
|
byte data[MAX_TICKET_NONCE_STATIC_SZ];
|
||||||
|
#endif /* WOLFSSL_TICKET_NONCE_MALLOC && FIPS_VERSION_GE(5,3) */
|
||||||
|
} TicketNonce;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/* wolfSSL session type */
|
/* wolfSSL session type */
|
||||||
struct WOLFSSL_SESSION {
|
struct WOLFSSL_SESSION {
|
||||||
/* WARNING Do not add fields here. They will be ignored in
|
/* WARNING Do not add fields here. They will be ignored in
|
||||||
@ -3789,13 +3818,21 @@ struct WOLFSSL_SESSION {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET) && \
|
||||||
|
defined(WOLFSSL_TICKET_NONCE_MALLOC) && \
|
||||||
|
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
|
||||||
|
WOLFSSL_LOCAL int SessionTicketNoncePopulate(WOLFSSL_SESSION *session,
|
||||||
|
const byte* nonce, byte len);
|
||||||
|
#endif /* WOLFSSL_TLS13 && */
|
||||||
|
|
||||||
WOLFSSL_LOCAL int wolfSSL_RAND_Init(void);
|
WOLFSSL_LOCAL int wolfSSL_RAND_Init(void);
|
||||||
|
|
||||||
WOLFSSL_LOCAL WOLFSSL_SESSION* wolfSSL_NewSession(void* heap);
|
WOLFSSL_LOCAL WOLFSSL_SESSION* wolfSSL_NewSession(void* heap);
|
||||||
WOLFSSL_LOCAL WOLFSSL_SESSION* wolfSSL_GetSession(
|
WOLFSSL_LOCAL WOLFSSL_SESSION* wolfSSL_GetSession(
|
||||||
WOLFSSL* ssl, byte* masterSecret, byte restoreSessionCerts);
|
WOLFSSL* ssl, byte* masterSecret, byte restoreSessionCerts);
|
||||||
WOLFSSL_LOCAL void AddSession(WOLFSSL* ssl);
|
WOLFSSL_LOCAL void AddSession(WOLFSSL* ssl);
|
||||||
WOLFSSL_LOCAL int AddSessionToCache(WOLFSSL_CTX* ssl,
|
/* use wolfSSL_API visibility to be able to test in tests/api.c */
|
||||||
|
WOLFSSL_API int AddSessionToCache(WOLFSSL_CTX* ssl,
|
||||||
WOLFSSL_SESSION* addSession, const byte* id, byte idSz, int* sessionIndex,
|
WOLFSSL_SESSION* addSession, const byte* id, byte idSz, int* sessionIndex,
|
||||||
int side, word16 useTicket, ClientSession** clientCacheEntry);
|
int side, word16 useTicket, ClientSession** clientCacheEntry);
|
||||||
#ifndef NO_CLIENT_CACHE
|
#ifndef NO_CLIENT_CACHE
|
||||||
@ -3805,7 +3842,8 @@ WOLFSSL_LOCAL ClientSession* AddSessionToClientCache(int side, int row, int idx,
|
|||||||
#endif
|
#endif
|
||||||
WOLFSSL_LOCAL
|
WOLFSSL_LOCAL
|
||||||
WOLFSSL_SESSION* ClientSessionToSession(const WOLFSSL_SESSION* session);
|
WOLFSSL_SESSION* ClientSessionToSession(const WOLFSSL_SESSION* session);
|
||||||
WOLFSSL_LOCAL int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output);
|
/* 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);
|
WOLFSSL_LOCAL int wolfSSL_SetSession(WOLFSSL* ssl, WOLFSSL_SESSION* session);
|
||||||
WOLFSSL_LOCAL void wolfSSL_FreeSession(WOLFSSL_CTX* ctx,
|
WOLFSSL_LOCAL void wolfSSL_FreeSession(WOLFSSL_CTX* ctx,
|
||||||
WOLFSSL_SESSION* session);
|
WOLFSSL_SESSION* session);
|
||||||
|
@ -85,6 +85,13 @@ WOLFSSL_API int wc_Tls13_HKDF_Expand_Label(byte* okm, word32 okmLen,
|
|||||||
const byte* label, word32 labelLen,
|
const byte* label, word32 labelLen,
|
||||||
const byte* info, word32 infoLen,
|
const byte* info, word32 infoLen,
|
||||||
int digest);
|
int digest);
|
||||||
|
#if defined(WOLFSSL_TICKET_NONCE_MALLOC) && \
|
||||||
|
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
|
||||||
|
WOLFSSL_API int wc_Tls13_HKDF_Expand_Label_Alloc(byte* okm, word32 okmLen,
|
||||||
|
const byte* prk, word32 prkLen, const byte* protocol, word32 protocolLen,
|
||||||
|
const byte* label, word32 labelLen, const byte* info, word32 infoLen,
|
||||||
|
int digest, void* heap);
|
||||||
|
#endif /* !defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3) */
|
||||||
|
|
||||||
#endif /* HAVE_HKDF */
|
#endif /* HAVE_HKDF */
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user