From: Frédéric Lécaille Date: Mon, 15 May 2023 16:11:21 +0000 (+0200) Subject: BUG/MINOR: quic: Missing Retry token length on receipt X-Git-Tag: v2.8-dev13~19 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=35b63964a00bb0e5f9478272b1f838d13e923b79;p=thirdparty%2Fhaproxy.git BUG/MINOR: quic: Missing Retry token length on receipt quic_retry_token_check() must decipher the token sent to and received back from clients. This token is made of the token format byte, the ODCID prefixed by its one byte length, the timestamp of its creation, and terminated by an AEAD TAG followed by the salt used to derive the secret to cipher the token. So, the length of these data must be between 2 + QUIC_ODCID_MINLEN + sizeof(uint32_t) + QUIC_TLS_TAG_LEN + QUIC_RETRY_TOKEN_SALTLEN and 2 + QUIC_CID_MAXLEN + sizeof(uint32_t) + QUIC_TLS_TAG_LEN + QUIC_RETRY_TOKEN_SALTLEN. Must be backported to 2.7 and 2.6. --- diff --git a/src/quic_conn.c b/src/quic_conn.c index eb47f340fc..a002555d57 100644 --- a/src/quic_conn.c +++ b/src/quic_conn.c @@ -6508,6 +6508,16 @@ static int quic_retry_token_check(struct quic_rx_packet *pkt, goto err; } + /* The token is made of the token format byte, the ODCID prefixed by its one byte + * length, the creation timestamp, an AEAD TAG, and finally + * the random bytes used to derive the secret to encrypt the token. + */ + if (tokenlen < 2 + QUIC_ODCID_MINLEN + sizeof(uint32_t) + QUIC_TLS_TAG_LEN + QUIC_RETRY_TOKEN_SALTLEN || + tokenlen > 2 + QUIC_CID_MAXLEN + sizeof(uint32_t) + QUIC_TLS_TAG_LEN + QUIC_RETRY_TOKEN_SALTLEN) { + TRACE_ERROR("invalid token length", QUIC_EV_CONN_LPKT, qc); + goto err; + } + aadlen = quic_generate_retry_token_aad(aad, qv->num, &pkt->scid, &dgram->saddr); salt = token + tokenlen - QUIC_RETRY_TOKEN_SALTLEN; if (!quic_tls_derive_retry_token_secret(EVP_sha256(), key, sizeof key, iv, sizeof iv, @@ -6521,7 +6531,7 @@ static int quic_retry_token_check(struct quic_rx_packet *pkt, goto err; } - /* Do not decrypt the QUIC_TOKEN_FMT_RETRY byte */ + /* The token is prefixed by a one-byte length format which is not ciphered. */ if (!quic_tls_decrypt2(buf, token + 1, tokenlen - QUIC_RETRY_TOKEN_SALTLEN - 1, aad, aadlen, ctx, aead, key, iv)) { TRACE_ERROR("Could not decrypt retry token", QUIC_EV_CONN_LPKT, qc);