The self-signed certificate is compiled into the ESP32 firmware and expires after OpenSSL's default 30 days. What happens on day 31, and what does pinning one certificate cost over a device's lifetime?
On day 31 curl and Node.js clients reject the server as expired, while the ESP32 keeps connecting, because ESP-IDF's mbedTLS ignores certificate dates by default (the board has no trustworthy clock). Pinning one leaf certificate means every renewal or key change requires reflashing every device.
Why the ESP32 does not notice. Checking "valid from / valid to" needs the current date. A dev board has no battery-backed clock; after reset its time starts near 1970 until something sets it. So ESP-IDF ships with CONFIG_MBEDTLS_HAVE_TIME_DATE off: certificate validity dates are simply ignored. Enabling it makes the check real but requires setting the clock first, usually with SNTP, before the first TLS connection, otherwise every certificate looks "not yet valid".
The lifecycle cost. The certificate is part of the firmware image, so:
- renewing it (new validity) or replacing the key (after a leak) means a rebuild and a reflash of every device;
- a long validity (
-days 3650) avoids renewals, but ignored or not, an expiry date is then no limit on a stolen key.
Ways to reduce the cost:
| Approach | Change at renewal |
|---|---|
| Pin the leaf certificate (this setup) | Reflash all devices |
| Pin the public key and reuse the key at renewal | Server only, as long as the key stays secret |
| Run a small private CA, embed the CA certificate, issue server certificates from it | Server only; devices trust any certificate the CA signs |
| Public domain name + public CA, ESP-IDF certificate bundle | Server only; does not work for a private IP address |
Go deeper:
ESP-IDF — Kconfig reference —
CONFIG_MBEDTLS_HAVE_TIME_DATE: expiry checks are off by default and need SNTP when enabled.ESP-IDF — System time — how the ESP32 keeps time and synchronises it with SNTP.
ESP-IDF — ESP x509 certificate bundle — trusting public CAs instead of a pinned certificate.