2.1 KiB
2.1 KiB
TLS Local CA Provisioning on Meshtastic
How Meshtastic Stores Certificates
Stock Meshtastic firmware (src/mesh/http/WebServer.cpp) utilizes the esp32_https_server library with mbedTLS. During startup:
taskCreateCertopens ESP32 Preferences/NVS under the namespaceMeshtasticHTTPS.- It checks for two binary keys:
PK: DER-encoded RSA private key.cert: DER-encoded x509 leaf certificate.
- If both keys exist and are non-empty, stock firmware loads them directly:
cert = new SSLCert(certBuffer, certLen, pkBuffer, pkLen); - Only if keys are missing does it generate a self-signed certificate (
CN=meshtastic.local, O=Meshtastic, C=US) and write them to NVS.
Persistent Local CA Provisioning Strategy
Because stock Meshtastic reuses existing NVS keys, custom certificates survive subsequent OTA updates to stock firmware:
- Generate a certificate from the private local root CA (
ericxliu.local):- Subject:
CN=meshtastic.local - SAN:
DNS:meshtastic.local, DNS:*.meshtastic.local
- Subject:
- Convert PEM certificate and key to DER binaries:
openssl x509 -in meshtastic.local.crt -outform DER -out meshtastic.local.crt.der openssl rsa -in meshtastic.local.key -outform DER -out meshtastic.local.key.der - Generate a C header (
MeshtasticTlsCertificate.h) containing both DER byte arrays usingxxd -i. - In
WebServer.cpp::taskCreateCert, inject the DER bytes before the check:prefs.begin("MeshtasticHTTPS", false); prefs.putBytes("PK", meshtasticTlsPrivateKeyDer, sizeof(meshtasticTlsPrivateKeyDer)); prefs.putBytes("cert", meshtasticTlsCertificateDer, sizeof(meshtasticTlsCertificateDer)); - On the first boot, the firmware writes the CA-signed certificate into NVS. Future boots and stock builds will use the persistent NVS certificate.
Verification
Test from a machine trusting the local root CA:
# Verify TLS without -k
curl -v https://meshtastic.local/api/v1/fromradio
Expected output:
SSL certificate verify ok.subject: CN=meshtastic.localissuer: CN=ericxliu.localHTTP/1.1 200 OKwith CORS headers enabled.