Skip to content

TLS: IDF certificate bundle by default on WebSocket + MQTT transports (v0.5.1-dev) - #22

Merged
genmon merged 3 commits into
mainfrom
genmon/hawthorn-upgrade
Jul 22, 2026
Merged

genmon merged 3 commits into
mainfrom
genmon/hawthorn-upgrade

Conversation

@genmon

@genmon genmon commented Jul 22, 2026 •

Copy link
Copy Markdown
Contributor

Extends the cert-bundle default that HttpTransport shipped with in 0.5.0 to the other two TLS transports, so consumers no longer need to pin (and track rotations of) a root CA just to get TLS working.

Changes

  • use_cert_bundle (default true) on WebSocketTransport::Config and MqttTransport::Config, wiring esp_crt_bundle_attach into the IDF client. The bundle is already always linked since 0.5.0, so this adds no binary size. TLS precedence per transport: cert_pem (pin) → cert bundle → WS-only embedded GTS Root R4 (use_default_certs, now the fallback for builds without MBEDTLS_CERTIFICATE_BUNDLE) → nothing.
  • Old WS clients degrade gracefully. The bundled esp_websocket_client inside IDF 4.x Arduino cores predates the crt_bundle_attach config field; the member is detected at compile time (expression SFINAE) and such builds fall back to the embedded GTS Root R4 — the pre-0.5.1 behavior — instead of failing to compile. (Found building a core-2.x project downstream.)
  • WebSocketTransport::useDefaultCerts() now expresses explicit intent: disables the bundle and selects the embedded root (previously it set an already-default flag).

Behavior change: with no cert_pem, WS validates against the bundle instead of only the embedded GTS Root R4 (strictly more permissive), and MQTT validates against the bundle instead of having no verification option configured. use_cert_bundle = false restores the old behavior.

Docs

  • docs/changelog.md: new v0.5.1-dev entry (New + Upgrading notes).
  • docs/api.md: documented use_cert_bundle on the WS and MQTT Config tables and corrected use_default_certs to read as the bundle-disabled fallback, with the precedence chain spelled out. Also filled a pre-existing gap — added a full HttpTransport reference section (Config, methods, Response, FetchOptions; shipped in 0.5.0 with no api.md coverage), the missing header-include row, a HttpTransport column in the SendOptions table, and bumped the stale "0.4.0 API" header.

Testing

159/159 native unit tests (mocks gain the crt_bundle_attach field; new cases cover pin-overrides-bundle, bundle-by-default, and the no-bundle fallbacks). Hardware-validated downstream in hawthorn-firmware (inanimate-tech/hawthorn-firmware#109): fan-p1 and m5sticks3 running WS + MQTT against a Cloudflare-fronted host on bundle TLS with no pinned roots, plus a core-2.x device (face-p1) exercising the SFINAE fallback.

🤖 Generated with Claude Code

genmon and others added 3 commits July 21, 2026 15:56
…(v0.5.1-dev)

WebSocketTransport::Config and MqttTransport::Config gain use_cert_bundle
(default true), wiring esp_crt_bundle_attach into the IDF client — matching
HttpTransport's existing default; the bundle is already always linked since
0.5.0. Precedence: cert_pem pin > bundle > WS-only embedded GTS Root R4
(use_default_certs, now the no-bundle fallback) > nothing. Consumers that
pinned a root only to get TLS working can drop the pin and stop tracking CA
rotations. useDefaultCerts() now expresses explicit intent (disables the
bundle, selects the embedded root).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…undle_attach

The bundled esp_websocket_client inside IDF 4.x Arduino cores predates the
crt_bundle_attach config hook. Detect the member at compile time (expression
SFINAE); when absent, fall back to the embedded GTS Root R4 — the pre-0.5.1
behavior — instead of failing to compile.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ference

The v0.5.1-dev TLS change adds `use_cert_bundle` to the WebSocket and MQTT
Config structs and reorders TLS precedence, but docs/api.md still described
the old cert surface. Update both Config tables (new field + corrected
`use_default_certs` meaning as the bundle-disabled fallback) and spell out
the precedence chain.

Also fill a pre-existing gap: HttpTransport (shipped 0.5.0) had no api.md
section at all. Add a full reference — Config, methods, Response, and
FetchOptions — plus the missing header-include row and a HttpTransport
column in the SendOptions table. Bump the stale "0.4.0 API" header to 0.5.x.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@genmon
genmon merged commit 7a5966c into main Jul 22, 2026
4 checks passed
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.

1 participant