forked from wolfSSL/wolfssl
dtls13: client: recompute transcript hash on downgrade
If a lower version is negotiated, the transcript hash must be recomputed using the <= v1.2 rules.
This commit is contained in:
32
src/dtls13.c
32
src/dtls13.c
@@ -716,6 +716,35 @@ static void Dtls13RtxRemoveCurAck(WOLFSSL* ssl)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void Dtls13MaybeSaveClientHello(WOLFSSL* ssl)
|
||||||
|
{
|
||||||
|
Dtls13RtxRecord *r, **prev_next;
|
||||||
|
|
||||||
|
r = ssl->dtls13Rtx.rtxRecords;
|
||||||
|
prev_next = &ssl->dtls13Rtx.rtxRecords;
|
||||||
|
|
||||||
|
if (ssl->options.side == WOLFSSL_CLIENT_END &&
|
||||||
|
ssl->options.connectState >= CLIENT_HELLO_SENT &&
|
||||||
|
ssl->options.connectState <= HELLO_AGAIN_REPLY &&
|
||||||
|
ssl->options.downgrade && ssl->options.minDowngrade >= DTLSv1_2_MINOR) {
|
||||||
|
while (r != NULL) {
|
||||||
|
if (r->handshakeType == client_hello) {
|
||||||
|
Dtls13RtxRecordUnlink(ssl, prev_next, r);
|
||||||
|
if (ssl->dtls13ClientHello != NULL)
|
||||||
|
XFREE(ssl->dtls13ClientHello, ssl->heap,
|
||||||
|
DYNAMIC_TYPE_DTLS_MSG);
|
||||||
|
ssl->dtls13ClientHello = r->data;
|
||||||
|
ssl->dtls13ClientHelloSz = r->length;
|
||||||
|
r->data = NULL;
|
||||||
|
Dtls13FreeRtxBufferRecord(ssl, r);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
prev_next = &r->next;
|
||||||
|
r = r->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int Dtls13RtxMsgRecvd(WOLFSSL* ssl, enum HandShakeType hs,
|
static int Dtls13RtxMsgRecvd(WOLFSSL* ssl, enum HandShakeType hs,
|
||||||
word32 fragOffset)
|
word32 fragOffset)
|
||||||
{
|
{
|
||||||
@@ -725,6 +754,9 @@ static int Dtls13RtxMsgRecvd(WOLFSSL* ssl, enum HandShakeType hs,
|
|||||||
ssl->keys.dtls_peer_handshake_number >=
|
ssl->keys.dtls_peer_handshake_number >=
|
||||||
ssl->keys.dtls_expected_peer_handshake_number) {
|
ssl->keys.dtls_expected_peer_handshake_number) {
|
||||||
|
|
||||||
|
if (hs == server_hello)
|
||||||
|
Dtls13MaybeSaveClientHello(ssl);
|
||||||
|
|
||||||
/* In the handshake, receiving part of the next flight, acknowledge the
|
/* In the handshake, receiving part of the next flight, acknowledge the
|
||||||
sent flight. The only exception is, on the server side, receiving the
|
sent flight. The only exception is, on the server side, receiving the
|
||||||
last client flight does not ACK any sent new_session_ticket
|
last client flight does not ACK any sent new_session_ticket
|
||||||
|
@@ -7284,6 +7284,15 @@ void SSL_ResourceFree(WOLFSSL* ssl)
|
|||||||
XFREE(ssl->buffers.dtlsCookieSecret.buffer, ssl->heap,
|
XFREE(ssl->buffers.dtlsCookieSecret.buffer, ssl->heap,
|
||||||
DYNAMIC_TYPE_COOKIE_PWD);
|
DYNAMIC_TYPE_COOKIE_PWD);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_DTLS13
|
||||||
|
if (ssl->dtls13ClientHello != NULL) {
|
||||||
|
XFREE(ssl->dtls13ClientHello, ssl->heap, DYNAMIC_TYPE_DTLS_MSG);
|
||||||
|
ssl->dtls13ClientHello = NULL;
|
||||||
|
ssl->dtls13ClientHelloSz = 0;
|
||||||
|
}
|
||||||
|
#endif /* WOLFSSL_DTLS13 */
|
||||||
|
|
||||||
#endif /* WOLFSSL_DTLS */
|
#endif /* WOLFSSL_DTLS */
|
||||||
#ifdef OPENSSL_EXTRA
|
#ifdef OPENSSL_EXTRA
|
||||||
#ifndef NO_BIO
|
#ifndef NO_BIO
|
||||||
@@ -7503,12 +7512,21 @@ void FreeHandshakeResources(WOLFSSL* ssl)
|
|||||||
WOLFSSL_ENTER("FreeHandshakeResources");
|
WOLFSSL_ENTER("FreeHandshakeResources");
|
||||||
|
|
||||||
#ifdef WOLFSSL_DTLS
|
#ifdef WOLFSSL_DTLS
|
||||||
/* DTLS_POOL (DTLSv1.3 flushes the queue autonomously) */
|
if (ssl->options.dtls) {
|
||||||
if (ssl->options.dtls && !IsAtLeastTLSv1_3(ssl->version)) {
|
/* DTLS_POOL (DTLSv1.3 flushes the queue autonomously) */
|
||||||
DtlsMsgPoolReset(ssl);
|
if(!IsAtLeastTLSv1_3(ssl->version)) {
|
||||||
DtlsMsgListDelete(ssl->dtls_rx_msg_list, ssl->heap);
|
DtlsMsgPoolReset(ssl);
|
||||||
ssl->dtls_rx_msg_list = NULL;
|
DtlsMsgListDelete(ssl->dtls_rx_msg_list, ssl->heap);
|
||||||
ssl->dtls_rx_msg_list_sz = 0;
|
ssl->dtls_rx_msg_list = NULL;
|
||||||
|
ssl->dtls_rx_msg_list_sz = 0;
|
||||||
|
}
|
||||||
|
#ifdef WOLFSSL_DTLS13
|
||||||
|
if (ssl->dtls13ClientHello != NULL) {
|
||||||
|
XFREE(ssl->dtls13ClientHello, ssl->heap, DYNAMIC_TYPE_DTLS_MSG);
|
||||||
|
ssl->dtls13ClientHello = NULL;
|
||||||
|
ssl->dtls13ClientHelloSz = 0;
|
||||||
|
}
|
||||||
|
#endif /* WOLFSSL_DTLS13 */
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
47
src/tls13.c
47
src/tls13.c
@@ -3641,6 +3641,28 @@ int SendTls13ClientHello(WOLFSSL* ssl)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(WOLFSSL_DTLS13) && !defined(WOLFSSL_NO_CLIENT)
|
||||||
|
static int Dtls13DoDowngrade(WOLFSSL* ssl)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
if (ssl->dtls13ClientHello == NULL)
|
||||||
|
return BAD_STATE_E;
|
||||||
|
|
||||||
|
/* v1.3 and v1.2 hash messages to compute the transcript hash. When we are
|
||||||
|
* using DTLSv1.3 we hash the first clientHello following v1.3 but the
|
||||||
|
* server can negotiate a lower version. So we need to re-hash the
|
||||||
|
* clientHello to adhere to DTLS <= v1.2 rules. */
|
||||||
|
ret = InitHandshakeHashes(ssl);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
ret = HashRaw(ssl, ssl->dtls13ClientHello, ssl->dtls13ClientHelloSz);
|
||||||
|
XFREE(ssl->dtls13ClientHello, ssl->heap, DYNAMIC_TYPE_DTLS_MSG);
|
||||||
|
ssl->dtls13ClientHello = NULL;
|
||||||
|
ssl->dtls13ClientHelloSz = 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif /* WOLFSSL_DTLS13 && !WOLFSSL_NO_CLIENT*/
|
||||||
|
|
||||||
/* handle processing of TLS 1.3 server_hello (2) and hello_retry_request (6) */
|
/* handle processing of TLS 1.3 server_hello (2) and hello_retry_request (6) */
|
||||||
/* Handle the ServerHello message from the server.
|
/* Handle the ServerHello message from the server.
|
||||||
* Only a client will receive this message.
|
* Only a client will receive this message.
|
||||||
@@ -3762,6 +3784,9 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
if (ssl->options.dtls) {
|
if (ssl->options.dtls) {
|
||||||
ssl->chVersion.minor = DTLSv1_2_MINOR;
|
ssl->chVersion.minor = DTLSv1_2_MINOR;
|
||||||
ssl->version.minor = DTLSv1_2_MINOR;
|
ssl->version.minor = DTLSv1_2_MINOR;
|
||||||
|
ret = Dtls13DoDowngrade(ssl);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
#endif /* WOLFSSL_DTLS13 */
|
#endif /* WOLFSSL_DTLS13 */
|
||||||
|
|
||||||
@@ -3839,6 +3864,9 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
if (ssl->options.dtls) {
|
if (ssl->options.dtls) {
|
||||||
ssl->chVersion.minor = DTLSv1_2_MINOR;
|
ssl->chVersion.minor = DTLSv1_2_MINOR;
|
||||||
ssl->version.minor = DTLSv1_2_MINOR;
|
ssl->version.minor = DTLSv1_2_MINOR;
|
||||||
|
ret = Dtls13DoDowngrade(ssl);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
#endif /* WOLFSSL_DTLS13 */
|
#endif /* WOLFSSL_DTLS13 */
|
||||||
|
|
||||||
@@ -3893,9 +3921,28 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
return VERSION_ERROR;
|
return VERSION_ERROR;
|
||||||
|
|
||||||
ssl->version.minor = args->pv.minor;
|
ssl->version.minor = args->pv.minor;
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_DTLS13
|
||||||
|
if (ssl->options.dtls) {
|
||||||
|
ret = Dtls13DoDowngrade(ssl);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif /* WOLFSSL_DTLS13 */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_DTLS13
|
||||||
|
/* we are sure that version is >= v1.3 now, we can get rid of buffered
|
||||||
|
* ClientHello that was buffered to re-compute the hash in case of
|
||||||
|
* downgrade */
|
||||||
|
if (ssl->options.dtls && ssl->dtls13ClientHello != NULL) {
|
||||||
|
XFREE(ssl->dtls13ClientHello, ssl->heap, DYNAMIC_TYPE_DTLS_MSG);
|
||||||
|
ssl->dtls13ClientHello = NULL;
|
||||||
|
ssl->dtls13ClientHelloSz = 0;
|
||||||
|
}
|
||||||
|
#endif /* WOLFSSL_DTLS13 */
|
||||||
|
|
||||||
/* Advance state and proceed */
|
/* Advance state and proceed */
|
||||||
ssl->options.asyncState = TLS_ASYNC_BUILD;
|
ssl->options.asyncState = TLS_ASYNC_BUILD;
|
||||||
} /* case TLS_ASYNC_BEGIN */
|
} /* case TLS_ASYNC_BEGIN */
|
||||||
|
@@ -4659,6 +4659,8 @@ struct WOLFSSL {
|
|||||||
word32 dtls13FragOffset;
|
word32 dtls13FragOffset;
|
||||||
byte dtls13FragHandshakeType;
|
byte dtls13FragHandshakeType;
|
||||||
Dtls13Rtx dtls13Rtx;
|
Dtls13Rtx dtls13Rtx;
|
||||||
|
byte *dtls13ClientHello;
|
||||||
|
word16 dtls13ClientHelloSz;
|
||||||
|
|
||||||
#endif /* WOLFSSL_DTLS13 */
|
#endif /* WOLFSSL_DTLS13 */
|
||||||
#endif /* WOLFSSL_DTLS */
|
#endif /* WOLFSSL_DTLS */
|
||||||
|
Reference in New Issue
Block a user