forked from wolfSSL/wolfssl
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 NO_WOLFSSL_CLIENT
|
||||
static int DoHelloVerifyRequest(WOLFSSL* ssl, const byte* input,
|
||||
word32* inOutIdx, word32 size);
|
||||
static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input,
|
||||
word32* inOutIdx, word32 size);
|
||||
#ifndef NO_CERTS
|
||||
@ -24562,8 +24560,8 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType,
|
||||
|
||||
|
||||
/* handle processing of DTLS hello_verify_request (3) */
|
||||
static int DoHelloVerifyRequest(WOLFSSL* ssl, const byte* input,
|
||||
word32* inOutIdx, word32 size)
|
||||
int DoHelloVerifyRequest(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
word32 size)
|
||||
{
|
||||
ProtocolVersion pv;
|
||||
byte cookieSz;
|
||||
@ -24605,7 +24603,18 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType,
|
||||
*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;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
73
src/tls13.c
73
src/tls13.c
@ -3411,9 +3411,14 @@ int SendTls13ClientHello(WOLFSSL* ssl)
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_DTLS13
|
||||
/* legacy_cookie_id (always 0 length) */
|
||||
if (ssl->options.dtls)
|
||||
args->length += OPAQUE8_LEN;
|
||||
if (ssl->options.dtls) {
|
||||
/* legacy_cookie_id 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 */
|
||||
|
||||
/* Advance state and proceed */
|
||||
@ -3519,9 +3524,19 @@ int SendTls13ClientHello(WOLFSSL* ssl)
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_DTLS13
|
||||
/* legacy_cookie_id. always 0 length vector */
|
||||
if (ssl->options.dtls)
|
||||
args->output[args->idx++] = 0;
|
||||
if (ssl->options.dtls) {
|
||||
args->output[args->idx++] = ssl->arrays->cookieSz;
|
||||
|
||||
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 */
|
||||
|
||||
/* Cipher suites */
|
||||
@ -9111,6 +9126,40 @@ static int SanityCheckTls13MsgReceived(WOLFSSL* ssl, byte type)
|
||||
}
|
||||
/* Multiple KeyUpdates can be sent. */
|
||||
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:
|
||||
WOLFSSL_MSG("Unknown message type");
|
||||
@ -9171,7 +9220,11 @@ int DoTls13HandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
|
||||
if (ssl->options.side == WOLFSSL_CLIENT_END &&
|
||||
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");
|
||||
SendAlert(ssl, alert_fatal, unexpected_message);
|
||||
return OUT_OF_ORDER_E;
|
||||
@ -9265,6 +9318,12 @@ int DoTls13HandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
ret = DoTls13KeyUpdate(ssl, input, inOutIdx, size);
|
||||
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:
|
||||
WOLFSSL_MSG("Unknown handshake message type");
|
||||
ret = UNKNOWN_HANDSHAKE_TYPE;
|
||||
|
@ -5175,6 +5175,8 @@ WOLFSSL_LOCAL int cipherExtraData(WOLFSSL* ssl);
|
||||
|
||||
#ifndef NO_WOLFSSL_CLIENT
|
||||
WOLFSSL_LOCAL int SendClientHello(WOLFSSL* ssl);
|
||||
WOLFSSL_LOCAL int DoHelloVerifyRequest(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
word32 size);
|
||||
#ifdef WOLFSSL_TLS13
|
||||
WOLFSSL_LOCAL int SendTls13ClientHello(WOLFSSL* ssl);
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user