dtls13: support stateless cookie exchange on blocking socket

This commit is contained in:
Marco Oliverio
2022-09-20 11:00:45 +02:00
parent 0b525a52c4
commit b3ecdd2ecb
2 changed files with 191 additions and 40 deletions

View File

@@ -11574,6 +11574,81 @@ const char* wolfSSL_get_cipher_name_by_hash(WOLFSSL* ssl, const char* hash)
#ifndef NO_WOLFSSL_SERVER
#if defined(WOLFSSL_DTLS13) && defined(WOLFSSL_SEND_HRR_COOKIE)
static void DtlsResetState(WOLFSSL *ssl)
{
/* Reset the state so that we can statelessly await the
* ClientHello that contains the cookie. */
/* Reset DTLS window */
w64Zero(&ssl->dtls13Epochs[0].nextSeqNumber);
w64Zero(&ssl->dtls13Epochs[0].nextPeerSeqNumber);
XMEMSET(ssl->dtls13Epochs[0].window, 0,
sizeof(ssl->dtls13Epochs[0].window));
ssl->keys.dtls_expected_peer_handshake_number = 0;
ssl->keys.dtls_handshake_number = 0;
ssl->msgsReceived.got_client_hello = 0;
#ifdef WOLFSSL_SEND_HRR_COOKIE
/* Remove cookie so that it will get computed again */
TLSX_Remove(&ssl->extensions, TLSX_COOKIE, ssl->heap);
#endif
/* Reset states */
ssl->options.serverState = NULL_STATE;
ssl->options.clientState = NULL_STATE;
ssl->options.connectState = CONNECT_BEGIN;
ssl->options.acceptState = ACCEPT_BEGIN;
ssl->options.handShakeState = NULL_STATE;
Dtls13FreeFsmResources(ssl);
}
static int DtlsAcceptStateless(WOLFSSL *ssl)
{
int ret;
if (!ssl->options.dtls)
return 0;
switch (ssl->options.acceptState) {
case TLS13_ACCEPT_BEGIN:
while (ssl->options.clientState < CLIENT_HELLO_COMPLETE) {
ret = ProcessReply(ssl);
if (ret != 0)
return ret;
}
if (!IsAtLeastTLSv1_3(ssl->version))
return wolfSSL_accept(ssl);
ssl->options.acceptState = TLS13_ACCEPT_CLIENT_HELLO_DONE;
WOLFSSL_MSG("accept state ACCEPT_CLIENT_HELLO_DONE");
FALL_THROUGH;
case TLS13_ACCEPT_CLIENT_HELLO_DONE:
if (ssl->options.serverState ==
SERVER_HELLO_RETRY_REQUEST_COMPLETE) {
ret = SendTls13ServerHello(ssl, hello_retry_request);
if (ret == 0 || ret == WANT_WRITE)
DtlsResetState(ssl);
return ret;
}
ssl->options.acceptState = TLS13_ACCEPT_HELLO_RETRY_REQUEST_DONE;
WOLFSSL_MSG("accept state ACCEPT_HELLO_RETRY_REQUEST_DONE");
FALL_THROUGH;
default:
return 0;
}
return 0;
}
#endif /* WOLFSSL_DTLS13 */
/* The server accepting a connection from a client.
* The protocol version is expecting to be TLS v1.3.
* If the client downgrades, and older versions of the protocol are compiled
@@ -11761,6 +11836,19 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
}
#endif /* WOLFSSL_DTLS13 */
#if defined(WOLFSSL_DTLS13) && defined(WOLFSSL_SEND_HRR_COOKIE)
if (ssl->options.dtls && ssl->options.sendCookie) {
while (ssl->options.serverState < SERVER_HELLO_COMPLETE) {
ret = DtlsAcceptStateless(ssl);
if (ret != 0) {
ssl->error = ret;
WOLFSSL_ERROR(ssl->error);
return WOLFSSL_FATAL_ERROR;
}
}
}
#endif /* defined(WOLFSSL_DTLS13) && defined(WOLFSSL_SEND_HRR_COOKIE) */
switch (ssl->options.acceptState) {
#ifdef HAVE_SECURE_RENEGOTIATION
@@ -11800,40 +11888,6 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
WOLFSSL_ERROR(ssl->error);
return WOLFSSL_FATAL_ERROR;
}
#ifdef WOLFSSL_DTLS13
if (ssl->options.dtls && wolfSSL_dtls_get_using_nonblock(ssl)) {
/* Reset the state so that we can statelessly await the
* ClientHello that contains the cookie. Return a WANT_READ
* to the user so that we don't drop UDP messages in the
* network callbacks. */
/* Reset DTLS window */
w64Zero(&ssl->dtls13Epochs[0].nextSeqNumber);
w64Zero(&ssl->dtls13Epochs[0].nextPeerSeqNumber);
XMEMSET(ssl->dtls13Epochs[0].window, 0,
sizeof(ssl->dtls13Epochs[0].window));
ssl->keys.dtls_expected_peer_handshake_number = 0;
ssl->keys.dtls_handshake_number = 0;
ssl->msgsReceived.got_client_hello = 0;
#ifdef WOLFSSL_SEND_HRR_COOKIE
/* Remove cookie so that it will get computed again */
TLSX_Remove(&ssl->extensions, TLSX_COOKIE, ssl->heap);
#endif
/* Reset states */
ssl->options.serverState = NULL_STATE;
ssl->options.clientState = NULL_STATE;
ssl->options.connectState = CONNECT_BEGIN;
ssl->options.acceptState = ACCEPT_BEGIN;
ssl->options.handShakeState = NULL_STATE;
ssl->error = WANT_READ;
WOLFSSL_ERROR(ssl->error);
return WOLFSSL_FATAL_ERROR;
}
#endif /* WOLFSSL_DTLS13 */
}
ssl->options.acceptState = TLS13_ACCEPT_HELLO_RETRY_REQUEST_DONE;
@@ -11879,6 +11933,12 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
}
}
ssl->options.acceptState = TLS13_ACCEPT_SECOND_REPLY_DONE;
WOLFSSL_MSG("accept state ACCEPT_SECOND_REPLY_DONE");
FALL_THROUGH;
case TLS13_ACCEPT_SECOND_REPLY_DONE :
#ifdef WOLFSSL_DTLS
if (ssl->chGoodCb != NULL) {
int cbret = ssl->chGoodCb(ssl, ssl->chGoodCtx);
@@ -11890,11 +11950,6 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
}
#endif
ssl->options.acceptState = TLS13_ACCEPT_SECOND_REPLY_DONE;
WOLFSSL_MSG("accept state ACCEPT_SECOND_REPLY_DONE");
FALL_THROUGH;
case TLS13_ACCEPT_SECOND_REPLY_DONE :
if ((ssl->error = SendTls13ServerHello(ssl, server_hello)) != 0) {
WOLFSSL_ERROR(ssl->error);
return WOLFSSL_FATAL_ERROR;