HTTPS trust: use the public CA bundle + one missing root, not a pinned cert
Build and push server image / build-and-push (push) Successful in 33s

Root-caused the earlier "No matching trusted root certificate found"
failure properly this time by reading ESP-IDF's actual bundle-matching
code (esp_crt_bundle.c): it looks up a trusted root by the ISSUER name
of whatever certificate it can't otherwise validate, not by matching
the presented certificate itself. The live server's chain ends in a
GTS Root R4 certificate cross-signed by the old GlobalSign Root CA R1
(common Cloudflare/Google Trust Services practice, for compatibility
with older/embedded clients) -- and ESP-IDF's current bundle snapshot
has dropped that old GlobalSign root entirely, so the lookup came up
empty. This was a general gap, not something specific to this one
deployment's cert.

Fix: keep the standard public CA bundle (esp_crt_bundle_attach) as the
trust mechanism -- so any normal reverse-proxy cert (Let's Encrypt,
etc.) works out of the box -- and add the one missing root on top via
ESP-IDF's CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE mechanism
(sdkconfig.defaults), which appends a project-supplied cert file to the
bundle at build time. Fetched GlobalSign's official Root CA R1 cert and
cryptographically verified (openssl verify) it actually validates the
live server's certificate before embedding it -- see
firmware/main/certs/additional_root_ca.pem (replaces the old
tools_server_ca.pem, which pinned one exact certificate directly and
would've broken for anyone else's reverse proxy). Confirmed working
against the real deployment on hardware.
This commit is contained in:
2026-07-19 17:38:39 -04:00
parent 4ffd9e852c
commit 5588ce3e1b
6 changed files with 69 additions and 58 deletions
+15
View File
@@ -1,5 +1,20 @@
CONFIG_LWIP_MAX_SOCKETS=16
# HTTPS trust for the tools server: the standard public CA bundle (works
# for any normal reverse-proxy cert -- Let's Encrypt, a typical
# Cloudflare-issued edge cert, etc.) PLUS one specific root ESP-IDF's
# current bundle snapshot is missing: GlobalSign Root CA R1, which
# Cloudflare (via Google Trust Services) cross-signs its GTS Root R4
# chain with for backward compatibility with older/embedded clients --
# extremely common, not unique to this deployment. Without it, ESP-IDF's
# own chain-validation lookup (by issuer name, not a literal cert match)
# comes up empty and the handshake fails with "No matching trusted root
# certificate found", confirmed on hardware. See
# main/certs/additional_root_ca.pem and firmware/README.md's HTTPS
# section for how this was diagnosed/verified.
CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE=y
CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE_PATH="main/certs/additional_root_ca.pem"
# ESP32-C6 dev board has 8MB flash. A 2MB app partition (vs. the ~1MB
# "single app" default) gives headroom for the HTTP client, TLS, and image
# buffers still to come, without needing to fight for space on every build.