BUG/MINOR: payload: fix the cipher_len bound check in smp_client_hello_parse()
smp_client_hello_parse() validates the CipherSuite length of a TLS
ClientHello with:
ext_len > hs_len
where <hs_len> is the number of ClientHello bytes remaining, counted from
<data>, which at that point still points at the 2-byte cipher_len field
itself. The CLIENTHELLO_CIPHERSUITE exit path returns that very <data>
together with *len = cipher_len, and smp_fetch_ssl_cipherlist() then
publishes <data + 2> over <cipher_len> bytes. The cipher suites therefore
have to fit *after* the length field, so the check must be:
ext_len > hs_len - 2
Without this, a ClientHello announcing a cipher_len one or two bytes
larger than what its handshake message can hold is accepted, and
req.ssl_cipherlist returns up to 2 bytes read past the end of the
ClientHello. When the ClientHello is the last thing in the buffer, those
2 bytes are leftovers of a previous connection, which then leak to
whatever logs or routes on req.ssl_cipherlist:
# 45-byte ClientHello announcing cipher_len = 10 for 8 cipher bytes
cipherlist=
130213031301009fcafe <- "cafe" sent after the TLS record
cipherlist=
130213031301009f4142 <- nothing sent after the ClientHello
The CLIENTHELLO_EXTENSIONS path was not affected; it only survived by
accident, because it re-checks "hs_len < 2" after subtracting
2 + ext_len.
A reg-test exercising both a well-formed cipher_len and an over-announced
one is added.
This must be backported as far as 3.2, where req.ssl_cipherlist was
introduced by commit
fa063a9e7 ("MINOR: sample: add 4 new sample fetches
for clienthello parsing").
Reported-by: kongr <kongr@krsecu.com>