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,
|
||||
word32 fragOffset)
|
||||
{
|
||||
@@ -725,6 +754,9 @@ static int Dtls13RtxMsgRecvd(WOLFSSL* ssl, enum HandShakeType hs,
|
||||
ssl->keys.dtls_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
|
||||
sent flight. The only exception is, on the server side, receiving the
|
||||
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,
|
||||
DYNAMIC_TYPE_COOKIE_PWD);
|
||||
#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 */
|
||||
#ifdef OPENSSL_EXTRA
|
||||
#ifndef NO_BIO
|
||||
@@ -7503,13 +7512,22 @@ void FreeHandshakeResources(WOLFSSL* ssl)
|
||||
WOLFSSL_ENTER("FreeHandshakeResources");
|
||||
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
/* DTLS_POOL (DTLSv1.3 flushes the queue autonomously) */
|
||||
if (ssl->options.dtls && !IsAtLeastTLSv1_3(ssl->version)) {
|
||||
if(!IsAtLeastTLSv1_3(ssl->version)) {
|
||||
DtlsMsgPoolReset(ssl);
|
||||
DtlsMsgListDelete(ssl->dtls_rx_msg_list, ssl->heap);
|
||||
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
|
||||
|
||||
#ifdef HAVE_SECURE_RENEGOTIATION
|
||||
|
47
src/tls13.c
47
src/tls13.c
@@ -3641,6 +3641,28 @@ int SendTls13ClientHello(WOLFSSL* ssl)
|
||||
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 the ServerHello message from the server.
|
||||
* Only a client will receive this message.
|
||||
@@ -3762,6 +3784,9 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
if (ssl->options.dtls) {
|
||||
ssl->chVersion.minor = DTLSv1_2_MINOR;
|
||||
ssl->version.minor = DTLSv1_2_MINOR;
|
||||
ret = Dtls13DoDowngrade(ssl);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
#endif /* WOLFSSL_DTLS13 */
|
||||
|
||||
@@ -3839,6 +3864,9 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
if (ssl->options.dtls) {
|
||||
ssl->chVersion.minor = DTLSv1_2_MINOR;
|
||||
ssl->version.minor = DTLSv1_2_MINOR;
|
||||
ret = Dtls13DoDowngrade(ssl);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
#endif /* WOLFSSL_DTLS13 */
|
||||
|
||||
@@ -3893,9 +3921,28 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
return VERSION_ERROR;
|
||||
|
||||
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 */
|
||||
ssl->options.asyncState = TLS_ASYNC_BUILD;
|
||||
} /* case TLS_ASYNC_BEGIN */
|
||||
|
@@ -4659,6 +4659,8 @@ struct WOLFSSL {
|
||||
word32 dtls13FragOffset;
|
||||
byte dtls13FragHandshakeType;
|
||||
Dtls13Rtx dtls13Rtx;
|
||||
byte *dtls13ClientHello;
|
||||
word16 dtls13ClientHelloSz;
|
||||
|
||||
#endif /* WOLFSSL_DTLS13 */
|
||||
#endif /* WOLFSSL_DTLS */
|
||||
|
Reference in New Issue
Block a user