forked from wolfSSL/wolfssl
Merge pull request #5716 from rizlik/dtls_cookie_stateless
dtls: allow for stateless client hello parsing
This commit is contained in:
280
src/dtls.c
280
src/dtls.c
@@ -19,6 +19,15 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* WOLFSSL_DTLS_NO_HVR_ON_RESUME
|
||||||
|
* If defined, a DTLS server will not do a cookie exchange on successful
|
||||||
|
* client resumption: the resumption will be faster (one RTT less) and
|
||||||
|
* will consume less bandwidth (one ClientHello and one HelloVerifyRequest
|
||||||
|
* less). On the other hand, if a valid SessionID is collected, forged
|
||||||
|
* clientHello messages will consume resources on the server.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -36,7 +45,7 @@
|
|||||||
|
|
||||||
#ifdef WOLFSSL_DTLS
|
#ifdef WOLFSSL_DTLS
|
||||||
|
|
||||||
void DtlsResetState(WOLFSSL *ssl)
|
void DtlsResetState(WOLFSSL* ssl)
|
||||||
{
|
{
|
||||||
/* Reset the state so that we can statelessly await the
|
/* Reset the state so that we can statelessly await the
|
||||||
* ClientHello that contains the cookie. Don't gate on IsAtLeastTLSv1_3
|
* ClientHello that contains the cookie. Don't gate on IsAtLeastTLSv1_3
|
||||||
@@ -68,8 +77,276 @@ void DtlsResetState(WOLFSSL *ssl)
|
|||||||
ssl->keys.dtls_handshake_number = 0;
|
ssl->keys.dtls_handshake_number = 0;
|
||||||
ssl->keys.dtls_expected_peer_handshake_number = 0;
|
ssl->keys.dtls_expected_peer_handshake_number = 0;
|
||||||
ssl->options.clientState = 0;
|
ssl->options.clientState = 0;
|
||||||
|
XMEMSET(ssl->keys.peerSeq->window, 0, sizeof(ssl->keys.peerSeq->window));
|
||||||
|
XMEMSET(ssl->keys.peerSeq->prevWindow, 0,
|
||||||
|
sizeof(ssl->keys.peerSeq->prevWindow));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(NO_WOLFSSL_SERVER)
|
||||||
|
|
||||||
|
#if defined(NO_SHA) && defined(NO_SHA256)
|
||||||
|
#error "DTLS needs either SHA or SHA-256"
|
||||||
|
#endif /* NO_SHA && NO_SHA256 */
|
||||||
|
|
||||||
|
#if !defined(NO_SHA) && defined(NO_SHA256)
|
||||||
|
#define DTLS_COOKIE_TYPE WC_SHA
|
||||||
|
#define DTLS_COOKIE_SZ WC_SHA_DIGEST_SIZE
|
||||||
|
#endif /* !NO_SHA && NO_SHA256 */
|
||||||
|
|
||||||
|
#ifndef NO_SHA256
|
||||||
|
#define DTLS_COOKIE_TYPE WC_SHA256
|
||||||
|
#define DTLS_COOKIE_SZ WC_SHA256_DIGEST_SIZE
|
||||||
|
#endif /* !NO_SHA256 */
|
||||||
|
|
||||||
|
typedef struct WolfSSL_ConstVector {
|
||||||
|
word32 size;
|
||||||
|
const byte* elements;
|
||||||
|
} WolfSSL_ConstVector;
|
||||||
|
|
||||||
|
typedef struct WolfSSL_CH {
|
||||||
|
ProtocolVersion* pv;
|
||||||
|
const byte* random;
|
||||||
|
WolfSSL_ConstVector sessionId;
|
||||||
|
WolfSSL_ConstVector cookie;
|
||||||
|
WolfSSL_ConstVector cipherSuite;
|
||||||
|
WolfSSL_ConstVector compression;
|
||||||
|
WolfSSL_ConstVector extension;
|
||||||
|
word32 length;
|
||||||
|
} WolfSSL_CH;
|
||||||
|
|
||||||
|
static int ReadVector8(const byte* input, WolfSSL_ConstVector* v)
|
||||||
|
{
|
||||||
|
v->size = *input;
|
||||||
|
v->elements = input + OPAQUE8_LEN;
|
||||||
|
return v->size + OPAQUE8_LEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReadVector16(const byte* input, WolfSSL_ConstVector* v)
|
||||||
|
{
|
||||||
|
word16 size16;
|
||||||
|
ato16(input, &size16);
|
||||||
|
v->size = (word32)size16;
|
||||||
|
v->elements = input + OPAQUE16_LEN;
|
||||||
|
return v->size + OPAQUE16_LEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CreateDtlsCookie(WOLFSSL* ssl, const WolfSSL_CH* ch, byte* cookie)
|
||||||
|
{
|
||||||
|
Hmac cookieHmac;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = wc_HmacInit(&cookieHmac, ssl->heap, ssl->devId);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
ret = wc_HmacSetKey(&cookieHmac, DTLS_COOKIE_TYPE,
|
||||||
|
ssl->buffers.dtlsCookieSecret.buffer,
|
||||||
|
ssl->buffers.dtlsCookieSecret.length);
|
||||||
|
if (ret != 0)
|
||||||
|
goto out;
|
||||||
|
ret = wc_HmacUpdate(&cookieHmac, (const byte*)ssl->buffers.dtlsCtx.peer.sa,
|
||||||
|
ssl->buffers.dtlsCtx.peer.sz);
|
||||||
|
if (ret != 0)
|
||||||
|
goto out;
|
||||||
|
ret = wc_HmacUpdate(&cookieHmac, (byte*)ch->pv, OPAQUE16_LEN);
|
||||||
|
if (ret != 0)
|
||||||
|
goto out;
|
||||||
|
ret = wc_HmacUpdate(&cookieHmac, (byte*)ch->random, RAN_LEN);
|
||||||
|
if (ret != 0)
|
||||||
|
goto out;
|
||||||
|
ret = wc_HmacUpdate(&cookieHmac, (byte*)ch->sessionId.elements,
|
||||||
|
ch->sessionId.size);
|
||||||
|
if (ret != 0)
|
||||||
|
goto out;
|
||||||
|
ret = wc_HmacUpdate(&cookieHmac, (byte*)ch->cipherSuite.elements,
|
||||||
|
ch->cipherSuite.size);
|
||||||
|
if (ret != 0)
|
||||||
|
goto out;
|
||||||
|
ret = wc_HmacUpdate(&cookieHmac, (byte*)ch->compression.elements,
|
||||||
|
ch->compression.size);
|
||||||
|
if (ret != 0)
|
||||||
|
goto out;
|
||||||
|
ret = wc_HmacFinal(&cookieHmac, cookie);
|
||||||
|
|
||||||
|
out:
|
||||||
|
wc_HmacFree(&cookieHmac);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ParseClientHello(const byte* input, word32 helloSz, WolfSSL_CH* ch)
|
||||||
|
{
|
||||||
|
word32 idx = 0;
|
||||||
|
|
||||||
|
/* protocol version, random and session id length check */
|
||||||
|
if (OPAQUE16_LEN + RAN_LEN + OPAQUE8_LEN > helloSz)
|
||||||
|
return BUFFER_ERROR;
|
||||||
|
|
||||||
|
ch->pv = (ProtocolVersion*)(input + idx);
|
||||||
|
idx += OPAQUE16_LEN;
|
||||||
|
ch->random = (byte*)(input + idx);
|
||||||
|
idx += RAN_LEN;
|
||||||
|
idx += ReadVector8(input + idx, &ch->sessionId);
|
||||||
|
if (idx > helloSz - OPAQUE8_LEN)
|
||||||
|
return BUFFER_ERROR;
|
||||||
|
idx += ReadVector8(input + idx, &ch->cookie);
|
||||||
|
if (idx > helloSz - OPAQUE16_LEN)
|
||||||
|
return BUFFER_ERROR;
|
||||||
|
idx += ReadVector16(input + idx, &ch->cipherSuite);
|
||||||
|
if (idx > helloSz - OPAQUE8_LEN)
|
||||||
|
return BUFFER_ERROR;
|
||||||
|
idx += ReadVector8(input + idx, &ch->compression);
|
||||||
|
if (idx > helloSz - OPAQUE16_LEN)
|
||||||
|
return BUFFER_ERROR;
|
||||||
|
idx += ReadVector16(input + idx, &ch->extension);
|
||||||
|
if (idx > helloSz)
|
||||||
|
return BUFFER_ERROR;
|
||||||
|
ch->length = idx;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_DTLS_NO_HVR_ON_RESUME
|
||||||
|
#ifdef HAVE_SESSION_TICKET
|
||||||
|
static int TlsxFindByType(WolfSSL_ConstVector* ret, word16 extType,
|
||||||
|
WolfSSL_ConstVector exts)
|
||||||
|
{
|
||||||
|
word32 len, idx = 0;
|
||||||
|
word16 type;
|
||||||
|
WolfSSL_ConstVector ext;
|
||||||
|
|
||||||
|
XMEMSET(ret, 0, sizeof(*ret));
|
||||||
|
len = exts.size;
|
||||||
|
/* type + len */
|
||||||
|
while (len >= OPAQUE16_LEN + OPAQUE16_LEN) {
|
||||||
|
ato16(exts.elements + idx, &type);
|
||||||
|
idx += OPAQUE16_LEN;
|
||||||
|
idx += ReadVector16(exts.elements + idx, &ext);
|
||||||
|
if (idx > exts.size)
|
||||||
|
return BUFFER_ERROR;
|
||||||
|
if (type == extType) {
|
||||||
|
XMEMCPY(ret, &ext, sizeof(ext));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
len = exts.size - idx;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int TlsTicketIsValid(WOLFSSL* ssl, WolfSSL_ConstVector exts,
|
||||||
|
byte* isValid)
|
||||||
|
{
|
||||||
|
WolfSSL_ConstVector tlsxSessionTicket;
|
||||||
|
byte tempTicket[SESSION_TICKET_LEN];
|
||||||
|
InternalTicket* it;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
*isValid = 0;
|
||||||
|
ret = TlsxFindByType(&tlsxSessionTicket, TLSX_SESSION_TICKET, exts);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
if (tlsxSessionTicket.size == 0)
|
||||||
|
return 0;
|
||||||
|
if (tlsxSessionTicket.size > SESSION_TICKET_LEN)
|
||||||
|
return 0;
|
||||||
|
XMEMCPY(tempTicket, tlsxSessionTicket.elements, tlsxSessionTicket.size);
|
||||||
|
ret = DoDecryptTicket(ssl, tempTicket, (word32)tlsxSessionTicket.size, &it);
|
||||||
|
if (ret != WOLFSSL_TICKET_RET_OK && ret != WOLFSSL_TICKET_RET_CREATE)
|
||||||
|
return 0;
|
||||||
|
ForceZero(it, sizeof(InternalTicket));
|
||||||
|
*isValid = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_SESSION_TICKET */
|
||||||
|
|
||||||
|
static int TlsSessionIdIsValid(WOLFSSL* ssl, WolfSSL_ConstVector sessionID,
|
||||||
|
byte* isValid)
|
||||||
|
{
|
||||||
|
WOLFSSL_SESSION* sess;
|
||||||
|
word32 sessRow;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
*isValid = 0;
|
||||||
|
if (ssl->options.sessionCacheOff)
|
||||||
|
return 0;
|
||||||
|
if (sessionID.size != ID_LEN)
|
||||||
|
return 0;
|
||||||
|
#ifdef HAVE_EXT_CACHE
|
||||||
|
{
|
||||||
|
|
||||||
|
if (ssl->ctx->get_sess_cb != NULL) {
|
||||||
|
int unused;
|
||||||
|
sess =
|
||||||
|
ssl->ctx->get_sess_cb(ssl, sessionID.elements, ID_LEN, &unused);
|
||||||
|
if (sess != NULL) {
|
||||||
|
*isValid = 1;
|
||||||
|
wolfSSL_FreeSession(ssl->ctx, sess);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ssl->ctx->internalCacheLookupOff)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
ret = TlsSessionCacheGetAndLock(sessionID.elements, &sess, &sessRow);
|
||||||
|
if (ret == 0 && sess != NULL) {
|
||||||
|
*isValid = 1;
|
||||||
|
TlsSessionCacheUnlockRow(sessRow);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int TlsResumptionIsValid(WOLFSSL* ssl, WolfSSL_CH* ch, byte* isValid)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
*isValid = 0;
|
||||||
|
#ifdef HAVE_SESSION_TICKET
|
||||||
|
ret = TlsTicketIsValid(ssl, ch->extension, isValid);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
if (*isValid)
|
||||||
|
return 0;
|
||||||
|
#endif /* HAVE_SESSION_TICKET */
|
||||||
|
ret = TlsSessionIdIsValid(ssl, ch->sessionId, isValid);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif /* WOLFSSL_DTLS_NO_HVR_ON_RESUME */
|
||||||
|
|
||||||
|
int DoClientHelloStateless(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||||
|
word32 helloSz, byte* process)
|
||||||
|
{
|
||||||
|
byte cookie[DTLS_COOKIE_SZ];
|
||||||
|
int ret;
|
||||||
|
WolfSSL_CH ch;
|
||||||
|
|
||||||
|
*process = 1;
|
||||||
|
ret = ParseClientHello(input + *inOutIdx, helloSz, &ch);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_DTLS_NO_HVR_ON_RESUME
|
||||||
|
{
|
||||||
|
byte isValid = 0;
|
||||||
|
ret = TlsResumptionIsValid(ssl, &ch, &isValid);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
if (isValid)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* WOLFSSL_DTLS_NO_HVR_ON_RESUME */
|
||||||
|
|
||||||
|
ret = CreateDtlsCookie(ssl, &ch, cookie);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
if (ch.cookie.size != DTLS_COOKIE_SZ ||
|
||||||
|
XMEMCMP(ch.cookie.elements, cookie, DTLS_COOKIE_SZ) != 0) {
|
||||||
|
*process = 0;
|
||||||
|
ret = SendHelloVerifyRequest(ssl, cookie, DTLS_COOKIE_SZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif /* !defined(NO_WOLFSSL_SERVER) */
|
||||||
|
|
||||||
#if defined(WOLFSSL_DTLS_CID)
|
#if defined(WOLFSSL_DTLS_CID)
|
||||||
|
|
||||||
typedef struct ConnectionID {
|
typedef struct ConnectionID {
|
||||||
@@ -423,5 +700,4 @@ int wolfSSL_dtls_cid_get_tx(WOLFSSL* ssl, unsigned char* buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif /* WOLFSSL_DTLS_CID */
|
#endif /* WOLFSSL_DTLS_CID */
|
||||||
|
|
||||||
#endif /* WOLFSSL_DTLS */
|
#endif /* WOLFSSL_DTLS */
|
||||||
|
182
src/internal.c
182
src/internal.c
@@ -65,13 +65,6 @@
|
|||||||
* may be received by a client. To support detecting this, peek will
|
* may be received by a client. To support detecting this, peek will
|
||||||
* return WOLFSSL_ERROR_WANT_READ.
|
* return WOLFSSL_ERROR_WANT_READ.
|
||||||
* This define turns off this behaviour.
|
* This define turns off this behaviour.
|
||||||
* WOLFSSL_DTLS_NO_HVR_ON_RESUME
|
|
||||||
* If defined, a DTLS server will not do a cookie exchange on successful
|
|
||||||
* client resumption: the resumption will be faster (one RTT less) and
|
|
||||||
* will consume less bandwidth (one ClientHello and one HelloVerifyRequest
|
|
||||||
* less). On the other hand, if a valid SessionID is collected, forged
|
|
||||||
* clientHello messages will consume resources on the server.
|
|
||||||
* This define is turned off by default.
|
|
||||||
* WOLFSSL_HOSTNAME_VERIFY_ALT_NAME_ONLY
|
* WOLFSSL_HOSTNAME_VERIFY_ALT_NAME_ONLY
|
||||||
* Verify hostname/ip address using alternate name (SAN) only and do not
|
* Verify hostname/ip address using alternate name (SAN) only and do not
|
||||||
* use the common name. Forces use of the alternate name, so certificates
|
* use the common name. Forces use of the alternate name, so certificates
|
||||||
@@ -178,11 +171,6 @@ WOLFSSL_CALLBACKS needs LARGE_STATIC_BUFFERS, please add LARGE_STATIC_BUFFERS
|
|||||||
static int DoCertificateVerify(WOLFSSL* ssl, byte* input,
|
static int DoCertificateVerify(WOLFSSL* ssl, byte* input,
|
||||||
word32* inOutIdx, word32 size);
|
word32* inOutIdx, word32 size);
|
||||||
#endif
|
#endif
|
||||||
#ifdef WOLFSSL_DTLS
|
|
||||||
static int SendHelloVerifyRequest(WOLFSSL* ssl,
|
|
||||||
const byte* cookie, byte cookieSz);
|
|
||||||
#endif /* WOLFSSL_DTLS */
|
|
||||||
|
|
||||||
#endif /* !NO_WOLFSSL_SERVER */
|
#endif /* !NO_WOLFSSL_SERVER */
|
||||||
|
|
||||||
#endif /* !WOLFSSL_NO_TLS12 */
|
#endif /* !WOLFSSL_NO_TLS12 */
|
||||||
@@ -9419,6 +9407,10 @@ static void AddRecordHeader(byte* output, word32 length, byte type, WOLFSSL* ssl
|
|||||||
#ifdef WOLFSSL_TLS13
|
#ifdef WOLFSSL_TLS13
|
||||||
if (IsAtLeastTLSv1_3(ssl->version)) {
|
if (IsAtLeastTLSv1_3(ssl->version)) {
|
||||||
rl->pvMinor = TLSv1_2_MINOR;
|
rl->pvMinor = TLSv1_2_MINOR;
|
||||||
|
#ifdef WOLFSSL_DTLS
|
||||||
|
if (ssl->options.dtls)
|
||||||
|
rl->pvMinor = DTLSv1_2_MINOR;
|
||||||
|
#endif /* WOLFSSL_DTLS */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
@@ -32782,7 +32774,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
* was created, timeout value and the current time. If the tickets are
|
* was created, timeout value and the current time. If the tickets are
|
||||||
* judged expired, falls back to full-handshake. If you want disable this
|
* judged expired, falls back to full-handshake. If you want disable this
|
||||||
* session ticket validation check in TLS1.2 and below, define
|
* session ticket validation check in TLS1.2 and below, define
|
||||||
* WOLFSSL_NO_TICKET_EXPRE.
|
* WOLFSSL_NO_TICKET_EXPIRE.
|
||||||
*/
|
*/
|
||||||
int HandleTlsResumption(WOLFSSL* ssl, int bogusID, Suites* clSuites)
|
int HandleTlsResumption(WOLFSSL* ssl, int bogusID, Suites* clSuites)
|
||||||
{
|
{
|
||||||
@@ -32917,17 +32909,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
byte lesserVersion;
|
byte lesserVersion;
|
||||||
|
|
||||||
#ifdef WOLFSSL_DTLS
|
|
||||||
Hmac cookieHmac;
|
|
||||||
byte newCookie[MAX_COOKIE_LEN];
|
|
||||||
byte peerCookie[MAX_COOKIE_LEN];
|
|
||||||
byte peerCookieSz = 0;
|
|
||||||
byte cookieType;
|
|
||||||
byte cookieSz = 0;
|
|
||||||
|
|
||||||
XMEMSET(&cookieHmac, 0, sizeof(Hmac));
|
|
||||||
#endif /* WOLFSSL_DTLS */
|
|
||||||
|
|
||||||
WOLFSSL_START(WC_FUNC_CLIENT_HELLO_DO);
|
WOLFSSL_START(WC_FUNC_CLIENT_HELLO_DO);
|
||||||
WOLFSSL_ENTER("DoClientHello");
|
WOLFSSL_ENTER("DoClientHello");
|
||||||
|
|
||||||
@@ -32935,6 +32916,21 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
if (ssl->hsInfoOn) AddPacketName(ssl, "ClientHello");
|
if (ssl->hsInfoOn) AddPacketName(ssl, "ClientHello");
|
||||||
if (ssl->toInfoOn) AddLateName("ClientHello", &ssl->timeoutInfo);
|
if (ssl->toInfoOn) AddLateName("ClientHello", &ssl->timeoutInfo);
|
||||||
#endif
|
#endif
|
||||||
|
/* do not change state in the SSL object before the next region of code
|
||||||
|
* to be able to statelessly compute a DTLS cookie */
|
||||||
|
#ifdef WOLFSSL_DTLS
|
||||||
|
if (IsDtlsNotSctpMode(ssl) && IsDtlsNotSrtpMode(ssl) && !IsSCR(ssl)) {
|
||||||
|
byte process = 0;
|
||||||
|
ret = DoClientHelloStateless(ssl, input, inOutIdx, helloSz,
|
||||||
|
&process);
|
||||||
|
if (ret != 0 || !process) {
|
||||||
|
*inOutIdx += helloSz;
|
||||||
|
DtlsResetState(ssl);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* WOLFSSL_DTLS */
|
||||||
|
|
||||||
/* protocol version, random and session id length check */
|
/* protocol version, random and session id length check */
|
||||||
if (OPAQUE16_LEN + RAN_LEN + OPAQUE8_LEN > helloSz)
|
if (OPAQUE16_LEN + RAN_LEN + OPAQUE8_LEN > helloSz)
|
||||||
return BUFFER_ERROR;
|
return BUFFER_ERROR;
|
||||||
@@ -32956,29 +32952,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
* Client Hello. */
|
* Client Hello. */
|
||||||
ssl->keys.dtls_handshake_number =
|
ssl->keys.dtls_handshake_number =
|
||||||
ssl->keys.dtls_peer_handshake_number;
|
ssl->keys.dtls_peer_handshake_number;
|
||||||
|
|
||||||
#if defined(NO_SHA) && defined(NO_SHA256)
|
|
||||||
#error "DTLS needs either SHA or SHA-256"
|
|
||||||
#endif /* NO_SHA && NO_SHA256 */
|
|
||||||
|
|
||||||
#if !defined(NO_SHA) && defined(NO_SHA256)
|
|
||||||
cookieType = WC_SHA;
|
|
||||||
cookieSz = WC_SHA_DIGEST_SIZE;
|
|
||||||
#endif /* NO_SHA */
|
|
||||||
#ifndef NO_SHA256
|
|
||||||
cookieType = WC_SHA256;
|
|
||||||
cookieSz = WC_SHA256_DIGEST_SIZE;
|
|
||||||
#endif /* NO_SHA256 */
|
|
||||||
ret = wc_HmacSetKey(&cookieHmac, cookieType,
|
|
||||||
ssl->buffers.dtlsCookieSecret.buffer,
|
|
||||||
ssl->buffers.dtlsCookieSecret.length);
|
|
||||||
if (ret != 0) goto out;
|
|
||||||
ret = wc_HmacUpdate(&cookieHmac,
|
|
||||||
(const byte*)ssl->buffers.dtlsCtx.peer.sa,
|
|
||||||
ssl->buffers.dtlsCtx.peer.sz);
|
|
||||||
if (ret != 0) goto out;
|
|
||||||
ret = wc_HmacUpdate(&cookieHmac, input + i, OPAQUE16_LEN);
|
|
||||||
if (ret != 0) goto out;
|
|
||||||
}
|
}
|
||||||
#endif /* WOLFSSL_DTLS */
|
#endif /* WOLFSSL_DTLS */
|
||||||
i += OPAQUE16_LEN;
|
i += OPAQUE16_LEN;
|
||||||
@@ -33049,15 +33022,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
WOLFSSL_MSG("\tDowngrading to DTLSv1.2");
|
WOLFSSL_MSG("\tDowngrading to DTLSv1.2");
|
||||||
ssl->options.tls1_3 = 0;
|
ssl->options.tls1_3 = 0;
|
||||||
ssl->version.minor = DTLSv1_2_MINOR;
|
ssl->version.minor = DTLSv1_2_MINOR;
|
||||||
|
|
||||||
/* reset hashes, DTLSv1.2 will take care of the hashing
|
|
||||||
later */
|
|
||||||
ret = InitHandshakeHashes(ssl);
|
|
||||||
if (ret != 0)
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
else if (pv.minor == DTLS_MINOR) {
|
else if (pv.minor == DTLS_MINOR) {
|
||||||
WOLFSSL_MSG("\tDowngrading to DTLSv1.2");
|
WOLFSSL_MSG("\tDowngrading to DTLSv1.0");
|
||||||
ssl->options.tls1_3 = 0;
|
ssl->options.tls1_3 = 0;
|
||||||
ssl->version.minor = DTLS_MINOR;
|
ssl->version.minor = DTLS_MINOR;
|
||||||
}
|
}
|
||||||
@@ -33154,12 +33121,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
|
|
||||||
/* random */
|
/* random */
|
||||||
XMEMCPY(ssl->arrays->clientRandom, input + i, RAN_LEN);
|
XMEMCPY(ssl->arrays->clientRandom, input + i, RAN_LEN);
|
||||||
#ifdef WOLFSSL_DTLS
|
|
||||||
if (IsDtlsNotSctpMode(ssl) && IsDtlsNotSrtpMode(ssl) && !IsSCR(ssl)) {
|
|
||||||
ret = wc_HmacUpdate(&cookieHmac, input + i, RAN_LEN);
|
|
||||||
if (ret != 0) goto out;
|
|
||||||
}
|
|
||||||
#endif /* WOLFSSL_DTLS */
|
|
||||||
i += RAN_LEN;
|
i += RAN_LEN;
|
||||||
|
|
||||||
#ifdef SHOW_SECRETS
|
#ifdef SHOW_SECRETS
|
||||||
@@ -33189,13 +33150,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
XMEMCPY(ssl->arrays->sessionID, input + i, b);
|
XMEMCPY(ssl->arrays->sessionID, input + i, b);
|
||||||
#ifdef WOLFSSL_DTLS
|
|
||||||
if (IsDtlsNotSctpMode(ssl) && IsDtlsNotSrtpMode(ssl) &&
|
|
||||||
!IsSCR(ssl)) {
|
|
||||||
ret = wc_HmacUpdate(&cookieHmac, input + i - 1, b + 1);
|
|
||||||
if (ret != 0) goto out;
|
|
||||||
}
|
|
||||||
#endif /* WOLFSSL_DTLS */
|
|
||||||
ssl->arrays->sessionIDSz = b;
|
ssl->arrays->sessionIDSz = b;
|
||||||
i += b;
|
i += b;
|
||||||
ssl->options.resuming = 1; /* client wants to resume */
|
ssl->options.resuming = 1; /* client wants to resume */
|
||||||
@@ -33207,10 +33161,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WOLFSSL_DTLS
|
#ifdef WOLFSSL_DTLS
|
||||||
/* cookie */
|
/* cookie */
|
||||||
if (ssl->options.dtls) {
|
if (ssl->options.dtls) {
|
||||||
|
word8 peerCookieSz;
|
||||||
if ((i - begin) + OPAQUE8_LEN > helloSz) {
|
if ((i - begin) + OPAQUE8_LEN > helloSz) {
|
||||||
ret = BUFFER_ERROR;
|
ret = BUFFER_ERROR;
|
||||||
goto out;
|
goto out;
|
||||||
@@ -33229,12 +33183,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
XMEMCPY(peerCookie, input + i, peerCookieSz);
|
|
||||||
|
|
||||||
i += peerCookieSz;
|
i += peerCookieSz;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* WOLFSSL_DTLS */
|
||||||
|
|
||||||
/* suites */
|
/* suites */
|
||||||
if ((i - begin) + OPAQUE16_LEN > helloSz) {
|
if ((i - begin) + OPAQUE16_LEN > helloSz) {
|
||||||
@@ -33304,14 +33256,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WOLFSSL_DTLS
|
|
||||||
if (IsDtlsNotSctpMode(ssl) && IsDtlsNotSrtpMode(ssl) && !IsSCR(ssl)) {
|
|
||||||
ret = wc_HmacUpdate(&cookieHmac,
|
|
||||||
input + i - OPAQUE16_LEN,
|
|
||||||
clSuites->suiteSz + OPAQUE16_LEN);
|
|
||||||
if (ret != 0) goto out;
|
|
||||||
}
|
|
||||||
#endif /* WOLFSSL_DTLS */
|
|
||||||
i += clSuites->suiteSz;
|
i += clSuites->suiteSz;
|
||||||
clSuites->hashSigAlgoSz = 0;
|
clSuites->hashSigAlgoSz = 0;
|
||||||
|
|
||||||
@@ -33332,38 +33276,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WOLFSSL_DTLS
|
|
||||||
if (IsDtlsNotSctpMode(ssl) && IsDtlsNotSrtpMode(ssl) && !IsSCR(ssl)) {
|
|
||||||
|
|
||||||
ret = wc_HmacUpdate(&cookieHmac, input + i - 1, b + 1);
|
|
||||||
if (ret != 0) goto out;
|
|
||||||
ret = wc_HmacFinal(&cookieHmac, newCookie);
|
|
||||||
if (ret != 0) goto out;
|
|
||||||
|
|
||||||
/* If a cookie callback is set, call it to overwrite the cookie.
|
|
||||||
* This should be deprecated. The code now calculates the cookie
|
|
||||||
* using an HMAC as expected. */
|
|
||||||
if (ssl->ctx->CBIOCookie != NULL &&
|
|
||||||
ssl->ctx->CBIOCookie(ssl, newCookie, cookieSz,
|
|
||||||
ssl->IOCB_CookieCtx) != cookieSz) {
|
|
||||||
ret = COOKIE_ERROR;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef WOLFSSL_DTLS_NO_HVR_ON_RESUME
|
|
||||||
if (peerCookieSz != cookieSz ||
|
|
||||||
XMEMCMP(peerCookie, newCookie, cookieSz) != 0) {
|
|
||||||
*inOutIdx += helloSz;
|
|
||||||
ret = SendHelloVerifyRequest(ssl, newCookie, cookieSz);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
#endif /* !WOLFSSL_DTLS_NO_HVR_ON_RESUME */
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif /* WOLFSSL_DTLS */
|
|
||||||
|
|
||||||
{
|
{
|
||||||
/* compression match types */
|
/* compression match types */
|
||||||
int matchNo = 0;
|
int matchNo = 0;
|
||||||
@@ -33548,20 +33460,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_DTLS_NO_HVR_ON_RESUME)
|
|
||||||
if (IsDtlsNotSctpMode(ssl) && IsDtlsNotSrtpMode(ssl) && !IsSCR(ssl)) {
|
|
||||||
|
|
||||||
if (!ssl->options.resuming) {
|
|
||||||
/* resume failed, check the cookie */
|
|
||||||
if (peerCookieSz != cookieSz ||
|
|
||||||
XMEMCMP(peerCookie, newCookie, cookieSz) != 0) {
|
|
||||||
*inOutIdx = begin + helloSz;
|
|
||||||
ret = SendHelloVerifyRequest(ssl, newCookie, cookieSz);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* WOLFSSL_DTLS && WOLFSSL_DTLS_NO_HVR_ON_RESUME */
|
|
||||||
|
|
||||||
#if defined(HAVE_TLS_EXTENSIONS) && defined(HAVE_DH_DEFAULT_PARAMS)
|
#if defined(HAVE_TLS_EXTENSIONS) && defined(HAVE_DH_DEFAULT_PARAMS)
|
||||||
#if defined(HAVE_FFDHE) && defined(HAVE_SUPPORTED_CURVES)
|
#if defined(HAVE_FFDHE) && defined(HAVE_SUPPORTED_CURVES)
|
||||||
@@ -33606,9 +33504,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
|
|
||||||
out:
|
out:
|
||||||
|
|
||||||
#ifdef WOLFSSL_DTLS
|
|
||||||
wc_HmacFree(&cookieHmac);
|
|
||||||
#endif
|
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
if (clSuites != NULL)
|
if (clSuites != NULL)
|
||||||
XFREE(clSuites, ssl->heap, DYNAMIC_TYPE_SUITES);
|
XFREE(clSuites, ssl->heap, DYNAMIC_TYPE_SUITES);
|
||||||
@@ -34386,12 +34281,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int DoDecryptTicket(WOLFSSL* ssl, const byte* input, word32 len,
|
||||||
/* Parse ticket sent by client, returns callback return value */
|
InternalTicket **it)
|
||||||
int DoClientTicket(WOLFSSL* ssl, const byte* input, word32 len)
|
|
||||||
{
|
{
|
||||||
ExternalTicket* et;
|
ExternalTicket* et;
|
||||||
InternalTicket* it;
|
|
||||||
int ret;
|
int ret;
|
||||||
int outLen;
|
int outLen;
|
||||||
word16 inLen;
|
word16 inLen;
|
||||||
@@ -34451,8 +34344,22 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
WOLFSSL_ERROR_VERBOSE(BAD_TICKET_KEY_CB_SZ);
|
WOLFSSL_ERROR_VERBOSE(BAD_TICKET_KEY_CB_SZ);
|
||||||
return BAD_TICKET_KEY_CB_SZ;
|
return BAD_TICKET_KEY_CB_SZ;
|
||||||
}
|
}
|
||||||
|
*it = (InternalTicket*)et->enc_ticket;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
it = (InternalTicket*)et->enc_ticket;
|
/* Parse ticket sent by client, returns callback return value */
|
||||||
|
int DoClientTicket(WOLFSSL* ssl, const byte* input, word32 len)
|
||||||
|
{
|
||||||
|
InternalTicket* it;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
WOLFSSL_START(WC_FUNC_TICKET_DO);
|
||||||
|
WOLFSSL_ENTER("DoClientTicket");
|
||||||
|
|
||||||
|
ret = DoDecryptTicket(ssl, input, len, &it);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
#ifdef WOLFSSL_CHECK_MEM_ZERO
|
#ifdef WOLFSSL_CHECK_MEM_ZERO
|
||||||
/* Internal ticket successfully decrypted. */
|
/* Internal ticket successfully decrypted. */
|
||||||
wc_MemZero_Add("Do Client Ticket internal", it, sizeof(InternalTicket));
|
wc_MemZero_Add("Do Client Ticket internal", it, sizeof(InternalTicket));
|
||||||
@@ -35212,7 +35119,7 @@ static int DefTicketEncCb(WOLFSSL* ssl, byte key_name[WOLFSSL_TICKET_NAME_SZ],
|
|||||||
|
|
||||||
#ifdef WOLFSSL_DTLS
|
#ifdef WOLFSSL_DTLS
|
||||||
/* handle generation of DTLS hello_verify_request (3) */
|
/* handle generation of DTLS hello_verify_request (3) */
|
||||||
static int SendHelloVerifyRequest(WOLFSSL* ssl,
|
int SendHelloVerifyRequest(WOLFSSL* ssl,
|
||||||
const byte* cookie, byte cookieSz)
|
const byte* cookie, byte cookieSz)
|
||||||
{
|
{
|
||||||
byte* output;
|
byte* output;
|
||||||
@@ -35251,13 +35158,8 @@ static int DefTicketEncCb(WOLFSSL* ssl, byte key_name[WOLFSSL_TICKET_NAME_SZ],
|
|||||||
}
|
}
|
||||||
AddHeaders(output, length, hello_verify_request, ssl);
|
AddHeaders(output, length, hello_verify_request, ssl);
|
||||||
|
|
||||||
#ifdef OPENSSL_EXTRA
|
|
||||||
output[idx++] = DTLS_MAJOR;
|
output[idx++] = DTLS_MAJOR;
|
||||||
output[idx++] = DTLS_MINOR;
|
output[idx++] = DTLS_MINOR;
|
||||||
#else
|
|
||||||
output[idx++] = ssl->version.major;
|
|
||||||
output[idx++] = ssl->version.minor;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
output[idx++] = cookieSz;
|
output[idx++] = cookieSz;
|
||||||
if (cookie == NULL || cookieSz == 0)
|
if (cookie == NULL || cookieSz == 0)
|
||||||
|
141
src/ssl.c
141
src/ssl.c
@@ -12380,7 +12380,7 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
|
|||||||
ForceZero(ssl->buffers.dtlsCookieSecret.buffer,
|
ForceZero(ssl->buffers.dtlsCookieSecret.buffer,
|
||||||
ssl->buffers.dtlsCookieSecret.length);
|
ssl->buffers.dtlsCookieSecret.length);
|
||||||
XFREE(ssl->buffers.dtlsCookieSecret.buffer,
|
XFREE(ssl->buffers.dtlsCookieSecret.buffer,
|
||||||
ssl->heap, DYNAMIC_TYPE_NONE);
|
ssl->heap, DYNAMIC_TYPE_COOKIE_PWD);
|
||||||
}
|
}
|
||||||
|
|
||||||
newSecret = (byte*)XMALLOC(secretSz, ssl->heap,DYNAMIC_TYPE_COOKIE_PWD);
|
newSecret = (byte*)XMALLOC(secretSz, ssl->heap,DYNAMIC_TYPE_COOKIE_PWD);
|
||||||
@@ -13839,15 +13839,63 @@ static int wolfSSL_DupSessionEx(const WOLFSSL_SESSION* input,
|
|||||||
WOLFSSL_SESSION* output, int avoidSysCalls, byte* ticketNonceBuf,
|
WOLFSSL_SESSION* output, int avoidSysCalls, byte* ticketNonceBuf,
|
||||||
byte* ticketNonceLen, byte* preallocUsed);
|
byte* ticketNonceLen, byte* preallocUsed);
|
||||||
|
|
||||||
|
void TlsSessionCacheUnlockRow(word32 row)
|
||||||
|
{
|
||||||
|
SessionRow* sessRow;
|
||||||
|
|
||||||
|
sessRow = &SessionCache[row];
|
||||||
|
(void)sessRow;
|
||||||
|
SESSION_ROW_UNLOCK(sessRow);
|
||||||
|
}
|
||||||
|
|
||||||
|
int TlsSessionCacheGetAndLock(const byte *id, WOLFSSL_SESSION **sess,
|
||||||
|
word32 *lockedRow)
|
||||||
|
{
|
||||||
|
SessionRow *sessRow;
|
||||||
|
WOLFSSL_SESSION *s;
|
||||||
|
word32 row;
|
||||||
|
int count;
|
||||||
|
int error;
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
*sess = NULL;
|
||||||
|
row = HashObject(id, ID_LEN, &error) % SESSION_ROWS;
|
||||||
|
if (error != 0)
|
||||||
|
return error;
|
||||||
|
sessRow = &SessionCache[row];
|
||||||
|
if (SESSION_ROW_LOCK(sessRow) != 0)
|
||||||
|
return FATAL_ERROR;
|
||||||
|
|
||||||
|
/* start from most recently used */
|
||||||
|
count = min((word32)sessRow->totalCount, SESSIONS_PER_ROW);
|
||||||
|
idx = sessRow->nextIdx - 1;
|
||||||
|
if (idx < 0 || idx >= SESSIONS_PER_ROW) {
|
||||||
|
idx = SESSIONS_PER_ROW - 1; /* if back to front, the previous was end */
|
||||||
|
}
|
||||||
|
for (; count > 0; --count) {
|
||||||
|
s = &sessRow->Sessions[idx];
|
||||||
|
if (XMEMCMP(s->sessionID, id, ID_LEN) == 0) {
|
||||||
|
*sess = s;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
idx = idx > 0 ? idx - 1 : SESSIONS_PER_ROW - 1;
|
||||||
|
}
|
||||||
|
if (*sess == NULL) {
|
||||||
|
SESSION_ROW_UNLOCK(sessRow);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*lockedRow = row;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output)
|
int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output)
|
||||||
{
|
{
|
||||||
WOLFSSL_SESSION* sess = NULL;
|
WOLFSSL_SESSION* sess = NULL;
|
||||||
const byte* id = NULL;
|
const byte* id = NULL;
|
||||||
word32 row;
|
word32 row;
|
||||||
int idx;
|
|
||||||
int count;
|
|
||||||
int error = 0;
|
int error = 0;
|
||||||
SessionRow* sessRow;
|
|
||||||
#ifdef HAVE_SESSION_TICKET
|
#ifdef HAVE_SESSION_TICKET
|
||||||
#ifndef WOLFSSL_SMALL_STACK
|
#ifndef WOLFSSL_SMALL_STACK
|
||||||
byte tmpTicket[PREALLOC_SESSION_TICKET_LEN];
|
byte tmpTicket[PREALLOC_SESSION_TICKET_LEN];
|
||||||
@@ -13937,13 +13985,6 @@ int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
row = HashObject(id, ID_LEN, &error) % SESSION_ROWS;
|
|
||||||
if (error != 0) {
|
|
||||||
WOLFSSL_MSG("Hash session failed");
|
|
||||||
return WOLFSSL_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_SESSION_TICKET
|
#ifdef HAVE_SESSION_TICKET
|
||||||
if (output->ticket == NULL ||
|
if (output->ticket == NULL ||
|
||||||
output->ticketLenAlloc < PREALLOC_SESSION_TICKET_LEN) {
|
output->ticketLenAlloc < PREALLOC_SESSION_TICKET_LEN) {
|
||||||
@@ -13995,61 +14036,48 @@ int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output)
|
|||||||
}
|
}
|
||||||
#endif /* WOLFSSL_TLS13 && HAVE_SESSION_TICKET*/
|
#endif /* WOLFSSL_TLS13 && HAVE_SESSION_TICKET*/
|
||||||
|
|
||||||
/* lock row */
|
/* init to avoid clang static analyzer false positive */
|
||||||
sessRow = &SessionCache[row];
|
row = 0;
|
||||||
if (SESSION_ROW_LOCK(sessRow) != 0) {
|
error = TlsSessionCacheGetAndLock(id, &sess, &row);
|
||||||
WOLFSSL_MSG("Session cache row lock failure");
|
error = (error == 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
|
||||||
|
if (error != WOLFSSL_SUCCESS || sess == NULL) {
|
||||||
|
WOLFSSL_MSG("Get Session from cache failed");
|
||||||
|
error = WOLFSSL_FAILURE;
|
||||||
#ifdef HAVE_SESSION_TICKET
|
#ifdef HAVE_SESSION_TICKET
|
||||||
if (tmpBufSet) {
|
if (tmpBufSet) {
|
||||||
output->ticket = output->staticTicket;
|
output->ticket = output->staticTicket;
|
||||||
output->ticketLenAlloc = 0;
|
output->ticketLenAlloc = 0;
|
||||||
}
|
}
|
||||||
#ifdef WOLFSSL_TLS13
|
#ifdef WOLFSSL_TLS13
|
||||||
if (preallocNonce != NULL)
|
if (preallocNonce != NULL) {
|
||||||
XFREE(preallocNonce, output->heap, DYNAMIC_TYPE_SESSION_TICK);
|
XFREE(preallocNonce, output->heap, DYNAMIC_TYPE_SESSION_TICK);
|
||||||
|
preallocNonce = NULL;
|
||||||
|
}
|
||||||
#endif /* WOLFSSL_TLS13 */
|
#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);
|
||||||
|
tmpTicket = NULL;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
return WOLFSSL_FAILURE;
|
}
|
||||||
|
else {
|
||||||
|
#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)
|
||||||
|
if (IsAtLeastTLSv1_3(ssl->version) != IsAtLeastTLSv1_3(sess->version)) {
|
||||||
|
WOLFSSL_MSG("Invalid session: different protocol version");
|
||||||
|
TlsSessionCacheUnlockRow(row);
|
||||||
|
error = WOLFSSL_FAILURE;
|
||||||
|
}
|
||||||
|
else if (LowResTimer() >= (sess->bornOn + sess->timeout)) {
|
||||||
|
WOLFSSL_MSG("Invalid session: timed out");
|
||||||
|
TlsSessionCacheUnlockRow(row);
|
||||||
|
error = WOLFSSL_FAILURE;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_SESSION_TICKET && WOLFSSL_TLS13 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* start from most recently used */
|
if (error == WOLFSSL_SUCCESS) {
|
||||||
count = min((word32)sessRow->totalCount, SESSIONS_PER_ROW);
|
|
||||||
idx = sessRow->nextIdx - 1;
|
|
||||||
if (idx < 0 || idx >= SESSIONS_PER_ROW) {
|
|
||||||
idx = SESSIONS_PER_ROW - 1; /* if back to front, the previous was end */
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; count > 0; --count) {
|
|
||||||
WOLFSSL_SESSION* current;
|
|
||||||
|
|
||||||
current = &sessRow->Sessions[idx];
|
|
||||||
if (XMEMCMP(current->sessionID, id, ID_LEN) == 0
|
|
||||||
&& current->side == ssl->options.side
|
|
||||||
#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)
|
|
||||||
&& (IsAtLeastTLSv1_3(ssl->version) ==
|
|
||||||
IsAtLeastTLSv1_3(current->version))
|
|
||||||
#endif
|
|
||||||
) {
|
|
||||||
WOLFSSL_MSG("Found a session match");
|
|
||||||
if (LowResTimer() < (current->bornOn + current->timeout)) {
|
|
||||||
WOLFSSL_MSG("Session valid");
|
|
||||||
sess = current;
|
|
||||||
} else {
|
|
||||||
WOLFSSL_MSG("Session timed out");
|
|
||||||
}
|
|
||||||
break; /* no more sessionIDs whether valid or not that match */
|
|
||||||
} else {
|
|
||||||
WOLFSSL_MSG("SessionID not a match at this idx");
|
|
||||||
}
|
|
||||||
|
|
||||||
idx = idx > 0 ? idx - 1 : SESSIONS_PER_ROW - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sess != NULL) {
|
|
||||||
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
|
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
|
||||||
/* We don't want the peer member. We will free it at the end. */
|
/* We don't want the peer member. We will free it at the end. */
|
||||||
if (sess->peer != NULL) {
|
if (sess->peer != NULL) {
|
||||||
@@ -14062,17 +14090,12 @@ int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output)
|
|||||||
preallocNonce, &preallocNonceLen, &preallocNonceUsed);
|
preallocNonce, &preallocNonceLen, &preallocNonceUsed);
|
||||||
#else
|
#else
|
||||||
error = wolfSSL_DupSession(sess, output, 1);
|
error = wolfSSL_DupSession(sess, output, 1);
|
||||||
#endif /* WOLFSSL_TSL */
|
#endif /* HAVE_SESSION_TICKET && WOLFSSL_TLS13 */
|
||||||
|
|
||||||
#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
|
||||||
|
TlsSessionCacheUnlockRow(row);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
error = WOLFSSL_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
SESSION_ROW_UNLOCK(sessRow);
|
|
||||||
|
|
||||||
/* We want to restore the bogus ID for TLS compatibility */
|
/* We want to restore the bogus ID for TLS compatibility */
|
||||||
if (ssl->session->haveAltSessionID &&
|
if (ssl->session->haveAltSessionID &&
|
||||||
|
@@ -5915,6 +5915,7 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
|
|
||||||
if (wantDowngrade) {
|
if (wantDowngrade) {
|
||||||
#ifndef WOLFSSL_NO_TLS12
|
#ifndef WOLFSSL_NO_TLS12
|
||||||
|
byte realMinor;
|
||||||
if (!ssl->options.downgrade) {
|
if (!ssl->options.downgrade) {
|
||||||
WOLFSSL_MSG("Client trying to connect with lesser version than "
|
WOLFSSL_MSG("Client trying to connect with lesser version than "
|
||||||
"TLS v1.3");
|
"TLS v1.3");
|
||||||
@@ -5928,7 +5929,10 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
ERROR_OUT(VERSION_ERROR, exit_dch);
|
ERROR_OUT(VERSION_ERROR, exit_dch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
realMinor = ssl->version.minor;
|
||||||
|
ssl->version.minor = args->pv.minor;
|
||||||
ret = HashInput(ssl, input + args->begin, helloSz);
|
ret = HashInput(ssl, input + args->begin, helloSz);
|
||||||
|
ssl->version.minor = realMinor;
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
ret = DoClientHello(ssl, input, inOutIdx, helloSz);
|
ret = DoClientHello(ssl, input, inOutIdx, helloSz);
|
||||||
}
|
}
|
||||||
|
271
tests/api.c
271
tests/api.c
@@ -58699,6 +58699,263 @@ static int test_wolfSSL_DTLS_fragment_buckets(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) && \
|
||||||
|
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
|
||||||
|
|
||||||
|
static int test_wolfSSL_dtls_stateless2(void)
|
||||||
|
{
|
||||||
|
WOLFSSL *ssl_c, *ssl_c2, *ssl_s;
|
||||||
|
struct test_memio_ctx test_ctx;
|
||||||
|
WOLFSSL_CTX *ctx_c, *ctx_s;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
|
||||||
|
ret = test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
|
||||||
|
wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method);
|
||||||
|
if (ret != 0)
|
||||||
|
return -1;
|
||||||
|
ssl_c2 = wolfSSL_new(ctx_c);
|
||||||
|
if (ssl_c2 == NULL)
|
||||||
|
return -2;
|
||||||
|
wolfSSL_SetIOWriteCtx(ssl_c2, &test_ctx);
|
||||||
|
wolfSSL_SetIOReadCtx(ssl_c2, &test_ctx);
|
||||||
|
/* send CH */
|
||||||
|
ret = wolfSSL_connect(ssl_c2);
|
||||||
|
if (ret == 0 || ssl_c2->error != WANT_READ)
|
||||||
|
return -3;
|
||||||
|
ret = wolfSSL_accept(ssl_s);
|
||||||
|
if (ret == 0 || ssl_s->error != WANT_READ)
|
||||||
|
return -4;
|
||||||
|
if (test_ctx.c_len == 0)
|
||||||
|
return -5;
|
||||||
|
/* consume HRR */
|
||||||
|
test_ctx.c_len = 0;
|
||||||
|
ret = test_memio_do_handshake(ssl_c, ssl_s, 10, NULL);
|
||||||
|
if (ret != 0)
|
||||||
|
return -6;
|
||||||
|
wolfSSL_free(ssl_c2);
|
||||||
|
wolfSSL_free(ssl_c);
|
||||||
|
wolfSSL_free(ssl_s);
|
||||||
|
wolfSSL_CTX_free(ctx_c);
|
||||||
|
wolfSSL_CTX_free(ctx_s);
|
||||||
|
return TEST_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_MAX_FRAGMENT
|
||||||
|
static int test_wolfSSL_dtls_stateless_maxfrag(void)
|
||||||
|
{
|
||||||
|
WOLFSSL *ssl_c, *ssl_c2, *ssl_s;
|
||||||
|
struct test_memio_ctx test_ctx;
|
||||||
|
WOLFSSL_CTX *ctx_c, *ctx_s;
|
||||||
|
word16 max_fragment;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
|
||||||
|
ret = test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
|
||||||
|
wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method);
|
||||||
|
if (ret != 0)
|
||||||
|
return -1;
|
||||||
|
ssl_c2 = wolfSSL_new(ctx_c);
|
||||||
|
if (ssl_c2 == NULL)
|
||||||
|
return -2;
|
||||||
|
ret = wolfSSL_UseMaxFragment(ssl_c2, WOLFSSL_MFL_2_8);
|
||||||
|
if (ret != WOLFSSL_SUCCESS)
|
||||||
|
return -3;
|
||||||
|
wolfSSL_SetIOWriteCtx(ssl_c2, &test_ctx);
|
||||||
|
wolfSSL_SetIOReadCtx(ssl_c2, &test_ctx);
|
||||||
|
max_fragment = ssl_s->max_fragment;
|
||||||
|
/* send CH */
|
||||||
|
ret = wolfSSL_connect(ssl_c2);
|
||||||
|
if (ret == 0 || ssl_c2->error != WANT_READ)
|
||||||
|
return -4;
|
||||||
|
ret = wolfSSL_accept(ssl_s);
|
||||||
|
if (ret == 0 || ssl_s->error != WANT_READ)
|
||||||
|
return -5;
|
||||||
|
/* CH without cookie shouldn't change state */
|
||||||
|
if (ssl_s->max_fragment != max_fragment)
|
||||||
|
return -6;
|
||||||
|
if (test_ctx.c_len == 0)
|
||||||
|
return -7;
|
||||||
|
/* consume HRR from buffer */
|
||||||
|
test_ctx.c_len = 0;
|
||||||
|
ret = test_memio_do_handshake(ssl_c, ssl_s, 10, NULL);
|
||||||
|
if (ret != 0)
|
||||||
|
return -8;
|
||||||
|
wolfSSL_free(ssl_c2);
|
||||||
|
wolfSSL_free(ssl_c);
|
||||||
|
wolfSSL_free(ssl_s);
|
||||||
|
wolfSSL_CTX_free(ctx_c);
|
||||||
|
wolfSSL_CTX_free(ctx_s);
|
||||||
|
return TEST_SUCCESS;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_MAX_FRAGMENT */
|
||||||
|
|
||||||
|
#if defined(WOLFSSL_DTLS_NO_HVR_ON_RESUME)
|
||||||
|
#define ROUNDS_WITH_HVR 4
|
||||||
|
#define ROUNDS_WITHOUT_HVR 2
|
||||||
|
#define HANDSHAKE_TYPE_OFFSET DTLS_RECORD_HEADER_SZ
|
||||||
|
static int buf_is_hvr(const byte *data, int len)
|
||||||
|
{
|
||||||
|
if (len < DTLS_RECORD_HEADER_SZ + DTLS_HANDSHAKE_HEADER_SZ)
|
||||||
|
return 0;
|
||||||
|
return data[HANDSHAKE_TYPE_OFFSET] == hello_verify_request;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _test_wolfSSL_dtls_stateless_resume(byte useticket, byte bad)
|
||||||
|
{
|
||||||
|
struct test_memio_ctx test_ctx;
|
||||||
|
WOLFSSL_CTX *ctx_c, *ctx_s;
|
||||||
|
WOLFSSL *ssl_c, *ssl_s;
|
||||||
|
WOLFSSL_SESSION *sess;
|
||||||
|
int ret, round_trips;
|
||||||
|
|
||||||
|
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
|
||||||
|
ret = test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
|
||||||
|
wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method);
|
||||||
|
if (ret != 0)
|
||||||
|
return -1;
|
||||||
|
#ifdef HAVE_SESSION_TICKET
|
||||||
|
if (useticket) {
|
||||||
|
ret = wolfSSL_UseSessionTicket(ssl_c);
|
||||||
|
if (ret != WOLFSSL_SUCCESS)
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
round_trips = ROUNDS_WITH_HVR;
|
||||||
|
ret = test_memio_do_handshake(ssl_c, ssl_s, round_trips, &round_trips);
|
||||||
|
if (ret != 0)
|
||||||
|
return -3;
|
||||||
|
if (round_trips != ROUNDS_WITH_HVR)
|
||||||
|
return -4;
|
||||||
|
sess = wolfSSL_get1_session(ssl_c);
|
||||||
|
if (sess == NULL)
|
||||||
|
return -5;
|
||||||
|
wolfSSL_shutdown(ssl_c);
|
||||||
|
wolfSSL_shutdown(ssl_s);
|
||||||
|
wolfSSL_free(ssl_c);
|
||||||
|
wolfSSL_free(ssl_s);
|
||||||
|
test_ctx.c_len = test_ctx.s_len = 0;
|
||||||
|
/* make resumption invalid */
|
||||||
|
if (bad) {
|
||||||
|
if (useticket) {
|
||||||
|
#ifdef HAVE_SESSION_TICKET
|
||||||
|
sess->ticket[0] = !sess->ticket[0];
|
||||||
|
#endif /* HAVE_SESSION_TICKET */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sess->sessionID[0] = !sess->sessionID[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ssl_c = wolfSSL_new(ctx_c);
|
||||||
|
ssl_s = wolfSSL_new(ctx_s);
|
||||||
|
wolfSSL_SetIOWriteCtx(ssl_c, &test_ctx);
|
||||||
|
wolfSSL_SetIOReadCtx(ssl_c, &test_ctx);
|
||||||
|
wolfSSL_SetIOWriteCtx(ssl_s, &test_ctx);
|
||||||
|
wolfSSL_SetIOReadCtx(ssl_s, &test_ctx);
|
||||||
|
ret = wolfSSL_set_session(ssl_c, sess);
|
||||||
|
if (ret != WOLFSSL_SUCCESS)
|
||||||
|
return -6;
|
||||||
|
ret = wolfSSL_connect(ssl_c);
|
||||||
|
if (ret == WOLFSSL_SUCCESS || ssl_c->error != WANT_READ)
|
||||||
|
return -7;
|
||||||
|
ret = wolfSSL_accept(ssl_s);
|
||||||
|
if (ret == WOLFSSL_SUCCESS || ssl_s->error != WANT_READ)
|
||||||
|
return -8;
|
||||||
|
if (bad && !buf_is_hvr(test_ctx.c_buff, test_ctx.c_len))
|
||||||
|
return -9;
|
||||||
|
if (!bad && buf_is_hvr(test_ctx.c_buff, test_ctx.c_len))
|
||||||
|
return -10;
|
||||||
|
if (!useticket) {
|
||||||
|
ret = test_memio_do_handshake(ssl_c, ssl_s, 10, &round_trips);
|
||||||
|
if (ret != 0)
|
||||||
|
return -11;
|
||||||
|
if (bad && round_trips != ROUNDS_WITH_HVR - 1)
|
||||||
|
return -12;
|
||||||
|
if (!bad && round_trips != ROUNDS_WITHOUT_HVR - 1)
|
||||||
|
return -13;
|
||||||
|
}
|
||||||
|
wolfSSL_SESSION_free(sess);
|
||||||
|
wolfSSL_free(ssl_c);
|
||||||
|
wolfSSL_free(ssl_s);
|
||||||
|
wolfSSL_CTX_free(ctx_c);
|
||||||
|
wolfSSL_CTX_free(ctx_s);
|
||||||
|
return TEST_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_wolfSSL_dtls_stateless_resume(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
#ifdef HAVE_SESSION_TICKET
|
||||||
|
ret = _test_wolfSSL_dtls_stateless_resume(1, 0);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
ret = _test_wolfSSL_dtls_stateless_resume(1, 1);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret - 100;
|
||||||
|
#endif /* HAVE_SESION_TICKET */
|
||||||
|
ret = _test_wolfSSL_dtls_stateless_resume(0, 0);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret - 200;
|
||||||
|
ret = _test_wolfSSL_dtls_stateless_resume(0, 1);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret - 300;
|
||||||
|
return TEST_SUCCESS;
|
||||||
|
}
|
||||||
|
#endif /* WOLFSSL_DTLS_NO_HVR_ON_RESUME */
|
||||||
|
|
||||||
|
#if !defined(NO_OLD_TLS)
|
||||||
|
static int test_wolfSSL_dtls_stateless_downgrade(void)
|
||||||
|
{
|
||||||
|
WOLFSSL_CTX *ctx_c, *ctx_c2, *ctx_s;
|
||||||
|
WOLFSSL *ssl_c, *ssl_c2, *ssl_s;
|
||||||
|
struct test_memio_ctx test_ctx;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
|
||||||
|
ret = test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
|
||||||
|
wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method);
|
||||||
|
if (ret != 0)
|
||||||
|
return -1;
|
||||||
|
ret = wolfSSL_CTX_SetMinVersion(ctx_s, WOLFSSL_DTLSV1);
|
||||||
|
if (ret != WOLFSSL_SUCCESS)
|
||||||
|
return -2;
|
||||||
|
ctx_c2 = wolfSSL_CTX_new(wolfDTLSv1_client_method());
|
||||||
|
if (ctx_c2 == NULL)
|
||||||
|
return -3;
|
||||||
|
wolfSSL_SetIORecv(ctx_c2, test_memio_read_cb);
|
||||||
|
wolfSSL_SetIOSend(ctx_c2, test_memio_write_cb);
|
||||||
|
ssl_c2 = wolfSSL_new(ctx_c2);
|
||||||
|
if (ssl_c2 == NULL)
|
||||||
|
return -4;
|
||||||
|
wolfSSL_SetIOWriteCtx(ssl_c2, &test_ctx);
|
||||||
|
wolfSSL_SetIOReadCtx(ssl_c2, &test_ctx);
|
||||||
|
/* send CH */
|
||||||
|
ret = wolfSSL_connect(ssl_c2);
|
||||||
|
if (ret == 0 || ssl_c2->error != WANT_READ)
|
||||||
|
return -5;
|
||||||
|
ret = wolfSSL_accept(ssl_s);
|
||||||
|
if (ret == 0 || ssl_s->error != WANT_READ)
|
||||||
|
return -6;
|
||||||
|
if (test_ctx.c_len == 0)
|
||||||
|
return -7;
|
||||||
|
/* consume HRR */
|
||||||
|
test_ctx.c_len = 0;
|
||||||
|
ret = test_memio_do_handshake(ssl_c, ssl_s, 10, NULL);
|
||||||
|
if (ret != 0)
|
||||||
|
return -8;
|
||||||
|
wolfSSL_free(ssl_c2);
|
||||||
|
wolfSSL_free(ssl_c);
|
||||||
|
wolfSSL_free(ssl_s);
|
||||||
|
wolfSSL_CTX_free(ctx_c);
|
||||||
|
wolfSSL_CTX_free(ctx_c2);
|
||||||
|
wolfSSL_CTX_free(ctx_s);
|
||||||
|
|
||||||
|
return TEST_SUCCESS;
|
||||||
|
}
|
||||||
|
#endif /* !defined(NO_OLD_TLS) */
|
||||||
|
|
||||||
|
#endif /* defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) && \
|
||||||
|
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)*/
|
||||||
|
|
||||||
#if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) && \
|
#if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) && \
|
||||||
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) && \
|
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) && \
|
||||||
@@ -59882,6 +60139,20 @@ TEST_CASE testCases[] = {
|
|||||||
TEST_DECL(test_wolfSSL_DtlsUpdateWindow),
|
TEST_DECL(test_wolfSSL_DtlsUpdateWindow),
|
||||||
TEST_DECL(test_wolfSSL_DTLS_fragment_buckets),
|
TEST_DECL(test_wolfSSL_DTLS_fragment_buckets),
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) && \
|
||||||
|
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
|
||||||
|
#ifdef WOLFSSL_DTLS_NO_HVR_ON_RESUME
|
||||||
|
TEST_DECL(test_wolfSSL_dtls_stateless_resume),
|
||||||
|
#endif /* WOLFSSL_DTLS_NO_HVR_ON_RESUME */
|
||||||
|
#ifdef HAVE_MAX_FRAGMENT
|
||||||
|
TEST_DECL(test_wolfSSL_dtls_stateless_maxfrag),
|
||||||
|
#endif /* HAVE_MAX_FRAGMENT */
|
||||||
|
TEST_DECL(test_wolfSSL_dtls_stateless2),
|
||||||
|
#if !defined(NO_OLD_TLS)
|
||||||
|
TEST_DECL(test_wolfSSL_dtls_stateless_downgrade),
|
||||||
|
#endif /* !defined(NO_OLD_TLS) */
|
||||||
|
#endif /* defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) && \
|
||||||
|
* !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) */
|
||||||
TEST_DECL(test_WOLFSSL_dtls_version_alert),
|
TEST_DECL(test_WOLFSSL_dtls_version_alert),
|
||||||
TEST_DECL(test_ForceZero),
|
TEST_DECL(test_ForceZero),
|
||||||
|
|
||||||
|
@@ -3922,6 +3922,9 @@ 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 void TlsSessionCacheUnlockRow(word32 row);
|
||||||
|
WOLFSSL_LOCAL int TlsSessionCacheGetAndLock(const byte *id,
|
||||||
|
WOLFSSL_SESSION **sess, word32 *lockedRow);
|
||||||
/* WOLFSSL_API to test it in tests/api.c */
|
/* WOLFSSL_API to test it in tests/api.c */
|
||||||
WOLFSSL_API int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output);
|
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);
|
||||||
@@ -5480,6 +5483,10 @@ extern const WOLF_EC_NIST_NAME kNistCurves[];
|
|||||||
/* internal functions */
|
/* internal functions */
|
||||||
WOLFSSL_LOCAL int SendChangeCipher(WOLFSSL* ssl);
|
WOLFSSL_LOCAL int SendChangeCipher(WOLFSSL* ssl);
|
||||||
WOLFSSL_LOCAL int SendTicket(WOLFSSL* ssl);
|
WOLFSSL_LOCAL int SendTicket(WOLFSSL* ssl);
|
||||||
|
#ifdef HAVE_SESSION_TICKET
|
||||||
|
WOLFSSL_LOCAL int DoDecryptTicket(WOLFSSL* ssl, const byte* input, word32 len,
|
||||||
|
InternalTicket **it);
|
||||||
|
#endif /* HAVE_SESSION_TICKET */
|
||||||
WOLFSSL_LOCAL int DoClientTicket(WOLFSSL* ssl, const byte* input, word32 len);
|
WOLFSSL_LOCAL int DoClientTicket(WOLFSSL* ssl, const byte* input, word32 len);
|
||||||
WOLFSSL_LOCAL int SendData(WOLFSSL* ssl, const void* data, int sz);
|
WOLFSSL_LOCAL int SendData(WOLFSSL* ssl, const void* data, int sz);
|
||||||
#ifdef WOLFSSL_TLS13
|
#ifdef WOLFSSL_TLS13
|
||||||
@@ -5683,6 +5690,13 @@ WOLFSSL_LOCAL int cipherExtraData(WOLFSSL* ssl);
|
|||||||
word32 *inOutIdx, byte *type, word32 *size, word32 *fragOffset,
|
word32 *inOutIdx, byte *type, word32 *size, word32 *fragOffset,
|
||||||
word32 *fragSz, word32 totalSz);
|
word32 *fragSz, word32 totalSz);
|
||||||
WOLFSSL_LOCAL int DtlsMsgDrain(WOLFSSL *ssl);
|
WOLFSSL_LOCAL int DtlsMsgDrain(WOLFSSL *ssl);
|
||||||
|
WOLFSSL_LOCAL int SendHelloVerifyRequest(WOLFSSL* ssl,
|
||||||
|
const byte* cookie, byte cookieSz);
|
||||||
|
|
||||||
|
#if !defined(NO_WOLFSSL_SERVER)
|
||||||
|
WOLFSSL_LOCAL int DoClientHelloStateless(WOLFSSL* ssl, const byte* input,
|
||||||
|
word32* inOutIdx, word32 helloSz, byte *process);
|
||||||
|
#endif /* !defined(NO_WOLFSSL_SERVER) */
|
||||||
#endif /* WOLFSSL_DTLS */
|
#endif /* WOLFSSL_DTLS */
|
||||||
|
|
||||||
#if defined(HAVE_SECURE_RENEGOTIATION) && defined(WOLFSSL_DTLS)
|
#if defined(HAVE_SECURE_RENEGOTIATION) && defined(WOLFSSL_DTLS)
|
||||||
|
@@ -5136,8 +5136,7 @@ void DEBUG_WRITE_DER(const byte* der, int derSz, const char* fileName);
|
|||||||
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))\
|
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))\
|
||||||
|| \
|
|| \
|
||||||
(defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) && \
|
(defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) && \
|
||||||
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) && \
|
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER))
|
||||||
!defined(NO_OLD_TLS))
|
|
||||||
#define TEST_MEMIO_BUF_SZ (64 * 1024)
|
#define TEST_MEMIO_BUF_SZ (64 * 1024)
|
||||||
struct test_memio_ctx
|
struct test_memio_ctx
|
||||||
{
|
{
|
||||||
@@ -5206,6 +5205,51 @@ static WC_INLINE int test_memio_read_cb(WOLFSSL *ssl, char *data, int sz,
|
|||||||
return read_sz;
|
return read_sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static WC_INLINE int test_memio_do_handshake(WOLFSSL *ssl_c, WOLFSSL *ssl_s,
|
||||||
|
int max_rounds, int *rounds)
|
||||||
|
{
|
||||||
|
byte handshake_complete = 0, hs_c = 0, hs_s = 0;
|
||||||
|
int ret, err;
|
||||||
|
|
||||||
|
if (rounds != NULL)
|
||||||
|
*rounds = 0;
|
||||||
|
while (!handshake_complete && max_rounds > 0) {
|
||||||
|
if (!hs_c) {
|
||||||
|
ret = wolfSSL_connect(ssl_c);
|
||||||
|
if (ret == WOLFSSL_SUCCESS) {
|
||||||
|
hs_c = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
err = wolfSSL_get_error(ssl_c, ret);
|
||||||
|
if (err != WOLFSSL_ERROR_WANT_READ &&
|
||||||
|
err != WOLFSSL_ERROR_WANT_WRITE)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!hs_s) {
|
||||||
|
ret = wolfSSL_accept(ssl_s);
|
||||||
|
if (ret == WOLFSSL_SUCCESS) {
|
||||||
|
hs_s = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
err = wolfSSL_get_error(ssl_c, ret);
|
||||||
|
if (err != WOLFSSL_ERROR_WANT_READ &&
|
||||||
|
err != WOLFSSL_ERROR_WANT_WRITE)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
handshake_complete = hs_c && hs_s;
|
||||||
|
max_rounds--;
|
||||||
|
if (rounds != NULL)
|
||||||
|
*rounds = *rounds + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!handshake_complete)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static WC_INLINE int test_memio_setup(struct test_memio_ctx *ctx,
|
static WC_INLINE int test_memio_setup(struct test_memio_ctx *ctx,
|
||||||
WOLFSSL_CTX **ctx_c, WOLFSSL_CTX **ctx_s, WOLFSSL **ssl_c, WOLFSSL **ssl_s,
|
WOLFSSL_CTX **ctx_c, WOLFSSL_CTX **ctx_s, WOLFSSL **ssl_c, WOLFSSL **ssl_s,
|
||||||
method_provider method_c, method_provider method_s)
|
method_provider method_c, method_provider method_s)
|
||||||
@@ -5224,6 +5268,9 @@ static WC_INLINE int test_memio_setup(struct test_memio_ctx *ctx,
|
|||||||
|
|
||||||
ret = wolfSSL_CTX_use_certificate_file(*ctx_s, svrCertFile,
|
ret = wolfSSL_CTX_use_certificate_file(*ctx_s, svrCertFile,
|
||||||
WOLFSSL_FILETYPE_PEM);
|
WOLFSSL_FILETYPE_PEM);
|
||||||
|
if (ret != WOLFSSL_SUCCESS)
|
||||||
|
return -1;
|
||||||
|
ret = wolfSSL_CTX_load_verify_locations(*ctx_c, caCertFile, 0);
|
||||||
if (ret != WOLFSSL_SUCCESS)
|
if (ret != WOLFSSL_SUCCESS)
|
||||||
return -1;
|
return -1;
|
||||||
wolfSSL_SetIORecv(*ctx_c, test_memio_read_cb);
|
wolfSSL_SetIORecv(*ctx_c, test_memio_read_cb);
|
||||||
|
Reference in New Issue
Block a user