Modelled after the config-checking header from session s11n.
The list of relevant config flags was established by manually checking the
fields serialized in the format, and which config.h flags they depend on.
This probably deserves double-checking by reviewers.
Since the type of cid_len is unsigned but shorter than int, it gets
"promoted" to int (which is also the type of the result), unless we make the
other operand an unsigned int which then forces the expression to unsigned int
as well.
The code wants timer callbacks to be set (checked in fetch_input()), and can't
easily check whether we're using nbio, so it seems easier to require the
callbacks to be always set rather than only with nbio as was previously done.
context_buf was never free()d. Moreover, since we want to free it on error
paths as well, and even properly zeroize it in order to demonstrate good
memory hygiene, we need to make it and its length main()-scoped.
Previously it was missing reset in case 1, and in case 2 the code was never
executed as the option value was reset to 0.
Tighten checking of return values of save(NULL, 0) now that it works.
Also, improve the printed output as well as the comments.
I checked manually that everything now works and fail in the expected way:
save, reset-or-reinit and load all succeed, but the subsequent read or write
fails.
The number of meaning of the flags will be determined later, when handling the
relevant struct members. For now three bytes are reserved as an example, but
this number may change later.
This mainly follows the design document (saving all fields marked "saved" in
the main structure and the transform sub-structure) with two exceptions:
- things related to renegotiation are excluded here (there weren't quite in
the design document as the possibility of allowing renegotiation was still
on the table, which is no longer is) - also, ssl.secure_renegotiation (which
is not guarded by MBEDTLS_SSL_RENEGOTIATION because it's used in initial
handshakes even with renegotiation disabled) is still excluded, as we don't
need it after the handshake.
- things related to Connection ID are added, as they weren't present at the
time the design document was written.
The exact format of the header (value of the bitflag indicating compile-time
options, whether and how to merge it with the serialized session header) will
be determined later.
Enforce restrictions indicated in the documentation.
This allows to make some simplifying assumptions (no need to worry about
saving IVs for CBC in TLS < 1.1, nor about saving handshake data) and
guarantees that all values marked as "forced" in the design document have the
intended values and can be skipped when serialising.
Some of the "forced" values are not checked because their value is a
consequence of other checks (for example, session_negotiated == NULL outside
handshakes). We do however check that session and transform are not NULL (even
if that's also a consequence of the initial handshake being over) as we're
going to dereference them and static analyzers may appreciate the info.
The previous code writes the content (the EC curve list) of the extension
before writing the extension length field at the beginning, which is common
in the library in places where we don't know the length upfront. Here,
however, we do traverse the EC curve list upfront to infer its length
and do the bounds check, so we can reorder the code to write the extension
linearly and hence improve readability.
This commit introduces the option MBEDTLS_SSL_CONF_SINGLE_EC
which can be used to register a single supported elliptic curve
at compile time. It replaces the runtime configuration API
mbedtls_ssl_conf_curves() which allows to register a _list_
of supported elliptic curves.
In contrast to other options used to hardcode configuration options,
MBEDTLS_SSL_CONF_SINGLE_EC isn't a numeric option, but instead it's
only relevant if it's defined or not. To actually set the single
elliptic curve that should be supported, numeric options
MBEDTLS_SSL_CONF_SINGLE_EC_TLS_ID
MBEDTLS_SSL_CONF_SINGLE_EC_GRP_ID
must both be defined and provide the TLS ID and the Mbed TLS internal
ID and the chosen curve, respectively.
For both client/server the EC curve list is assumed not to be NULL:
- On the client-side, it's assumed when writing the
supported elliptic curve extension:
c54ee936d7/library/ssl_cli.c (L316)
- On the server, it is assumed when searching for a
suitable curve for the ECDHE exchange:
c54ee936d7/library/ssl_srv.c (L3200)
It is therefore not necessary to check this in mbedtls_ssl_check_curve().
ssl_write_supported_elliptic_curves_ext() is guarded by
```
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
```
each of which implies (by check_config.h) that MBEDTLS_ECP_C
is enabled.
The fields
- mbedtls_ssl_handshake_params::max_major_ver,
- mbedtls_ssl_handshake_params::max_minor_ver
are used only for server-side RSA-based key exchanges
can be removed otherwise.
Reasons:
- If the transport type is fixed at compile-time,
mbedtls_ssl_read_version() and mbedtls_ssl_write_version()
are called with a compile-time determined `transport`
parameter, so the transport-type branch in their body
can be eliminated at compile-time.
- mbedtls_ssl_read_version() is called with addresses of
local variables, which so far need to be put on the stack
to be addressable. Inlining the call allows to read directly
into the registers holding these local variables.
This saves 60 bytes w.r.t. the measurement performed by
> ./scripts/baremetal.sh --rom --gcc
If the minor/major version is enforced at compile-time, the `major_ver`
and `minor_ver` fields in `mbedtls_ssl_context` are redundant and can
be removed.