mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-30 10:47:28 +02:00
dtls13: allow processing of HelloVerifyRequest to support downgrade
HelloVerifyRequest is used in DTLSv1.2 to perform a return routability check, so it can be the legitim reply from a DTLSv1.2 server to a ClientHello.
This commit is contained in:
@ -147,8 +147,6 @@ WOLFSSL_CALLBACKS needs LARGE_STATIC_BUFFERS, please add LARGE_STATIC_BUFFERS
|
|||||||
#ifndef WOLFSSL_NO_TLS12
|
#ifndef WOLFSSL_NO_TLS12
|
||||||
|
|
||||||
#ifndef NO_WOLFSSL_CLIENT
|
#ifndef NO_WOLFSSL_CLIENT
|
||||||
static int DoHelloVerifyRequest(WOLFSSL* ssl, const byte* input,
|
|
||||||
word32* inOutIdx, word32 size);
|
|
||||||
static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input,
|
static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input,
|
||||||
word32* inOutIdx, word32 size);
|
word32* inOutIdx, word32 size);
|
||||||
#ifndef NO_CERTS
|
#ifndef NO_CERTS
|
||||||
@ -24562,8 +24560,8 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType,
|
|||||||
|
|
||||||
|
|
||||||
/* handle processing of DTLS hello_verify_request (3) */
|
/* handle processing of DTLS hello_verify_request (3) */
|
||||||
static int DoHelloVerifyRequest(WOLFSSL* ssl, const byte* input,
|
int DoHelloVerifyRequest(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||||
word32* inOutIdx, word32 size)
|
word32 size)
|
||||||
{
|
{
|
||||||
ProtocolVersion pv;
|
ProtocolVersion pv;
|
||||||
byte cookieSz;
|
byte cookieSz;
|
||||||
@ -24605,7 +24603,18 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType,
|
|||||||
*inOutIdx += cookieSz;
|
*inOutIdx += cookieSz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(WOLFSSL_DTLS13) && defined(WOLFSSL_TLS13)
|
||||||
|
if (IsAtLeastTLSv1_3(ssl->version) && ssl->options.dtls) {
|
||||||
|
/* we sent a TLSv1.3 ClientHello but received a
|
||||||
|
* HELLO_VERIFY_REQUEST */
|
||||||
|
if (!ssl->options.downgrade ||
|
||||||
|
ssl->options.minDowngrade < pv.minor)
|
||||||
|
return VERSION_ERROR;
|
||||||
|
}
|
||||||
|
#endif /* defined(WOLFSSL_DTLS13) && defined(WOLFSSL_TLS13) */
|
||||||
|
|
||||||
ssl->options.serverState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
|
ssl->options.serverState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
73
src/tls13.c
73
src/tls13.c
@ -3411,9 +3411,14 @@ int SendTls13ClientHello(WOLFSSL* ssl)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WOLFSSL_DTLS13
|
#ifdef WOLFSSL_DTLS13
|
||||||
/* legacy_cookie_id (always 0 length) */
|
if (ssl->options.dtls) {
|
||||||
if (ssl->options.dtls)
|
/* legacy_cookie_id len */
|
||||||
args->length += OPAQUE8_LEN;
|
args->length += ENUM_LEN;
|
||||||
|
|
||||||
|
/* server sent us an HelloVerifyRequest and we allow downgrade */
|
||||||
|
if (ssl->arrays->cookieSz > 0 && ssl->options.downgrade)
|
||||||
|
args->length += ssl->arrays->cookieSz;
|
||||||
|
}
|
||||||
#endif /* WOLFSSL_DTLS13 */
|
#endif /* WOLFSSL_DTLS13 */
|
||||||
|
|
||||||
/* Advance state and proceed */
|
/* Advance state and proceed */
|
||||||
@ -3519,9 +3524,19 @@ int SendTls13ClientHello(WOLFSSL* ssl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WOLFSSL_DTLS13
|
#ifdef WOLFSSL_DTLS13
|
||||||
/* legacy_cookie_id. always 0 length vector */
|
if (ssl->options.dtls) {
|
||||||
if (ssl->options.dtls)
|
args->output[args->idx++] = ssl->arrays->cookieSz;
|
||||||
args->output[args->idx++] = 0;
|
|
||||||
|
if (ssl->arrays->cookieSz > 0) {
|
||||||
|
/* We have a cookie saved, so the server sent us an
|
||||||
|
* HelloVerifyRequest, it means it is a v1.2 server */
|
||||||
|
if (!ssl->options.downgrade)
|
||||||
|
return VERSION_ERROR;
|
||||||
|
XMEMCPY(args->output + args->idx, ssl->arrays->cookie,
|
||||||
|
ssl->arrays->cookieSz);
|
||||||
|
args->idx += ssl->arrays->cookieSz;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif /* WOLFSSL_DTLS13 */
|
#endif /* WOLFSSL_DTLS13 */
|
||||||
|
|
||||||
/* Cipher suites */
|
/* Cipher suites */
|
||||||
@ -9111,6 +9126,40 @@ static int SanityCheckTls13MsgReceived(WOLFSSL* ssl, byte type)
|
|||||||
}
|
}
|
||||||
/* Multiple KeyUpdates can be sent. */
|
/* Multiple KeyUpdates can be sent. */
|
||||||
break;
|
break;
|
||||||
|
#if defined(WOLFSSL_DTLS13) && !defined(WOLFSSL_NO_TLS12)
|
||||||
|
case hello_verify_request:
|
||||||
|
if (!ssl->options.dtls) {
|
||||||
|
WOLFSSL_MSG("HelloVerifyRequest when not in DTLS");
|
||||||
|
return OUT_OF_ORDER_E;
|
||||||
|
}
|
||||||
|
if (ssl->msgsReceived.got_hello_verify_request) {
|
||||||
|
WOLFSSL_MSG("Duplicate HelloVerifyRequest received");
|
||||||
|
return DUPLICATE_MSG_E;
|
||||||
|
}
|
||||||
|
ssl->msgsReceived.got_hello_verify_request = 1;
|
||||||
|
if (ssl->msgsReceived.got_hello_retry_request) {
|
||||||
|
WOLFSSL_MSG(
|
||||||
|
"Both HelloVerifyRequest and HelloRetryRequest received");
|
||||||
|
return DUPLICATE_MSG_E;
|
||||||
|
}
|
||||||
|
if (ssl->options.serverState >=
|
||||||
|
SERVER_HELLO_RETRY_REQUEST_COMPLETE ||
|
||||||
|
ssl->options.connectState != CLIENT_HELLO_SENT) {
|
||||||
|
WOLFSSL_MSG("HelloVerifyRequest received out of order");
|
||||||
|
return OUT_OF_ORDER_E;
|
||||||
|
}
|
||||||
|
if (ssl->options.side == WOLFSSL_SERVER_END) {
|
||||||
|
WOLFSSL_MSG("HelloVerifyRequest recevied on the server");
|
||||||
|
return SIDE_ERROR;
|
||||||
|
}
|
||||||
|
if (!ssl->options.downgrade ||
|
||||||
|
ssl->options.minDowngrade < DTLSv1_2_MINOR) {
|
||||||
|
WOLFSSL_MSG(
|
||||||
|
"HelloVerifyRequest recevied but not DTLSv1.2 allowed");
|
||||||
|
return VERSION_ERROR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif /* WOLFSSL_DTLS13 && !WOLFSSL_NO_TLS12*/
|
||||||
|
|
||||||
default:
|
default:
|
||||||
WOLFSSL_MSG("Unknown message type");
|
WOLFSSL_MSG("Unknown message type");
|
||||||
@ -9171,7 +9220,11 @@ int DoTls13HandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
|||||||
|
|
||||||
if (ssl->options.side == WOLFSSL_CLIENT_END &&
|
if (ssl->options.side == WOLFSSL_CLIENT_END &&
|
||||||
ssl->options.serverState == NULL_STATE &&
|
ssl->options.serverState == NULL_STATE &&
|
||||||
type != server_hello && type != hello_retry_request) {
|
type != server_hello && type != hello_retry_request
|
||||||
|
#if defined(WOLFSSL_DTLS13) && !defined(WOLFSSL_NO_TLS12)
|
||||||
|
&& (!ssl->options.dtls || type != hello_verify_request)
|
||||||
|
#endif /* defined(WOLFSSL_DTLS13) && !defined(WOLFSSL_NO_TLS12) */
|
||||||
|
) {
|
||||||
WOLFSSL_MSG("First server message not server hello");
|
WOLFSSL_MSG("First server message not server hello");
|
||||||
SendAlert(ssl, alert_fatal, unexpected_message);
|
SendAlert(ssl, alert_fatal, unexpected_message);
|
||||||
return OUT_OF_ORDER_E;
|
return OUT_OF_ORDER_E;
|
||||||
@ -9265,6 +9318,12 @@ int DoTls13HandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
|||||||
ret = DoTls13KeyUpdate(ssl, input, inOutIdx, size);
|
ret = DoTls13KeyUpdate(ssl, input, inOutIdx, size);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#if defined(WOLFSSL_DTLS13) && !defined(WOLFSSL_NO_TLS12)
|
||||||
|
case hello_verify_request:
|
||||||
|
WOLFSSL_MSG("processing hello verify request");
|
||||||
|
ret = DoHelloVerifyRequest(ssl, input, inOutIdx, size);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
WOLFSSL_MSG("Unknown handshake message type");
|
WOLFSSL_MSG("Unknown handshake message type");
|
||||||
ret = UNKNOWN_HANDSHAKE_TYPE;
|
ret = UNKNOWN_HANDSHAKE_TYPE;
|
||||||
|
@ -5175,6 +5175,8 @@ WOLFSSL_LOCAL int cipherExtraData(WOLFSSL* ssl);
|
|||||||
|
|
||||||
#ifndef NO_WOLFSSL_CLIENT
|
#ifndef NO_WOLFSSL_CLIENT
|
||||||
WOLFSSL_LOCAL int SendClientHello(WOLFSSL* ssl);
|
WOLFSSL_LOCAL int SendClientHello(WOLFSSL* ssl);
|
||||||
|
WOLFSSL_LOCAL int DoHelloVerifyRequest(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||||
|
word32 size);
|
||||||
#ifdef WOLFSSL_TLS13
|
#ifdef WOLFSSL_TLS13
|
||||||
WOLFSSL_LOCAL int SendTls13ClientHello(WOLFSSL* ssl);
|
WOLFSSL_LOCAL int SendTls13ClientHello(WOLFSSL* ssl);
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user