Found by Guido Vranken.
Two possible integer overflows (during << 2 or addition in BITS_TO_LIMB())
could result in far too few memory to be allocated, then overflowing the
buffer in the subsequent for loop.
Both integer overflows happen when slen is close to or greater than
SIZE_T_MAX >> 2 (ie 2^30 on a 32 bit system).
Note: one could also avoid those overflows by changing BITS_TO_LIMB(s << 2) to
CHARS_TO_LIMB(s >> 1) but the solution implemented looks more robust with
respect to future code changes.
We've had a bit of a race between us adapting to changes in 0.3.x and the
sockets author reverting those changes in the 0.3.x line and pushing them to
0.4.0. Let's use the newest and greatest sockets :)
This extension is quite costly to generate, and we don't want to re-do it
again when the server performs a DTLS HelloVerify. So, cache the result the
first time and re-use if/when we build a new ClientHello.
Note: re-send due to timeouts are different, as the whole message is cached
already, so they don't need any special support.
This bug becomes noticeable when the extension following the "supported point
formats" extension has a number starting with 0x01, which is the case of the
EC J-PAKE extension, which explains what I noticed the bug now.
This will be immediately backported to the stable branches,
see the corresponding commits for impact analysis.
This is more consistent, as it doesn't make any sense for a user to be able to
set up an EC J-PAKE password with TLS if the corresponding key exchange is
disabled.
Arguably this is what we should de for other key exchanges as well instead of
depending on ECDH_C etc, but this is an independent issue, so let's just do
the right thing with the new key exchange and fix the other ones later. (This
is a marginal issue anyway, since people who disable all ECDH key exchange are
likely to also disable ECDH_C in order to minimize footprint.)
When we don't have a password, we want to skip the costly process of
generating the extension. So for consistency don't offer the ciphersuite
without the extension.