Skip to content

Fix TLS 1.3 negotiation with newer MbedTLS - #2460

Open
petermm wants to merge 2 commits into
atomvm:release-0.7from
petermm:tls1.3-verify_none
Open

petermm wants to merge 2 commits into
atomvm:release-0.7from
petermm:tls1.3-verify_none

Conversation

@petermm

@petermm petermm commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

AtomVM capped the maximum TLS version to 1.2 for every connection that did not
use verified peer certificates, because Mbed TLS could not complete a TLS 1.3
handshake with optional or disabled certificate verification
(Mbed-TLS/mbedtls#7075). Mbed TLS 3.6.1 fixed that upstream, but the cap still
applied, so ssl:connect/3 with {verify, verify_none} negotiated TLS 1.2 even
when the linked library supports TLS 1.3.

Keep the workaround only for the affected versions, so Mbed TLS 3.6.1 and later
can negotiate TLS 1.3. The mbedtls_ssl_conf_max_version call is still used for
libraries older than 3.2.

The Erlang SSL tests now assert the version the server reports, accounting for
the Mbed TLS version and the protocol support compiled into it. They bound the
request with a monitored worker, since AtomVM's SSL API has no timeout, and
reject incomplete responses and unexpected receive errors.

TLS 1.3 stays opt-in on ESP32, so normal ESP32 defaults are unchanged. One
ESP32-S3, ESP-IDF v5.5.5, non-JIT CI variant runs with TLS 1.3 enabled through
the full memory-check suite. It sets CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 and a
6144-byte main/scheduler stack, which TLS 1.3 needed in those builds, and keeps
the certificate retention setting at its SDK default. Build instructions and the
network programming guide document the requirement and the security limitation
of verify_none.

Verified on generic UNIX with Mbed TLS 3.6.7: the estdlib suite passes and the
new SSL test reports TLS negotiated tls1.3; expected tls1.3.

The estdlib suite is a little longer with the added TLS request, which showed
that the 20-minute timeout on that step is too tight: the xtensa JIT+DWARF job
compiles every test module under QEMU, takes about 18.5 minutes, and needed
over 21 minutes on a slower runner. The step timeout is raised to 30 minutes so
it reports real test failures instead of a timeout.

These changes are made under both the "Apache 2.0" and the "GNU Lesser General
Public License 2.1 or later" license terms (dual license).

SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later

MbedTLS 3.6.1 fixes TLS 1.3 handshakes with optional or disabled
certificate verification. Keep the TLS 1.2 workaround only for affected
versions so newer builds can negotiate TLS 1.3.

Extend the existing Erlang SSL tests to assert Akamai's reported
negotiated version, accounting for the MbedTLS version and compiled
protocol support. Reject incomplete responses and unexpected receive
errors, and use a monitored worker to bound the regression request.

Keep normal ESP32 defaults unchanged. Exercise optional TLS 1.3 in one
ESP32-S3, IDF v5.5.5, non-JIT CI variant with a 6144-byte main/scheduler
stack, verified by the full memory-check suite. Leave certificate
retention at its SDK default and distinguish the variant's artifacts.

Signed-off-by: Peter M <petermm@gmail.com>
@github-advanced-security

Copy link
Copy Markdown

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

The step runs the whole estdlib suite, and on the slowest matrix entries
every test module is JIT compiled under QEMU. The xtensa JIT+DWARF job
takes about 18.5 minutes and needed over 21 minutes on a slower runner,
so the 20-minute timeout fails on timing alone: the failing run compiled
each module at the same speed as the passing one, about 13% slower
overall, and reached the last test when it was killed.

Raise the timeout to 30 minutes so the step reports real test failures
instead of a timeout.

Signed-off-by: Peter Madsen-Mygdal <petermm@gmail.com>
Signed-off-by: Peter M <petermm@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants