From 86cd3e19e9ad6712c093d97c0ce1aed3126d0d61 Mon Sep 17 00:00:00 2001 From: Jon Shallow Date: Tue, 6 Feb 2024 12:56:03 +0000 Subject: [PATCH] dtls.c: Handle DTLS1.3 ClientHello when calculating cookie Do not calculate the cookie using the Extensions as these are different between DTLS1.2 and DTLS1.3 https://datatracker.ietf.org/doc/html/rfc6347#section-4.2.1 When responding to a HelloVerifyRequest, the client MUST use the same parameter values (version, random, session_id, cipher_suites, compression_method) as it did in the original ClientHello. The server SHOULD use those values to generate its cookie and verify that they are correct upon cookie receipt. https://www.rfc-editor.org/rfc/rfc9147.html#section-5.3 The ClientHello up to, but not including the Extensions is the same for DTLS1.2 and DTLS1.3 Signed-off-by: Jon Shallow --- dtls.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/dtls.c b/dtls.c index 33b352f4..5d726949 100644 --- a/dtls.c +++ b/dtls.c @@ -464,7 +464,7 @@ dtls_create_cookie(dtls_context_t *ctx, uint8 *msg, size_t msglen, uint8 *cookie, int *clen) { unsigned char buf[DTLS_HMAC_MAX]; - size_t e, fragment_length; + size_t e, compatability_length; int len; /* create cookie with HMAC-SHA256 over: @@ -504,14 +504,23 @@ dtls_create_cookie(dtls_context_t *ctx, e += dtls_uint8_to_int(msg + DTLS_HS_LENGTH + e); e += sizeof(uint8_t); - /* read fragment length and check for consistency */ - fragment_length = dtls_get_fragment_length(DTLS_HANDSHAKE_HEADER(msg)); - if ((fragment_length < e) || (e + DTLS_HS_LENGTH) > msglen) + /* + * Read in compatablility_length length and check for consistency + * The compatability_length is because a DTLS1.3 Client Hello may come in, + * and the re-transmit of the Client Hello with cookie may be different. + */ + /* Get the Cipher Suites length + value */ + compatability_length = dtls_uint16_to_int(msg + DTLS_HS_LENGTH + e) + 2; + /* Add in the Compression length byte + value */ + compatability_length += dtls_uint8_to_int(msg + DTLS_HS_LENGTH + e + + compatability_length) + 1; + + if (e + DTLS_HS_LENGTH + compatability_length > msglen) return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); dtls_hmac_update(&hmac_context, msg + DTLS_HS_LENGTH + e, - fragment_length - e); + compatability_length); len = dtls_hmac_finalize(&hmac_context, buf);