Files
meshtastic/.agents/skills/meshtastic/references/tls-ca-provisioning.md
T

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:

  1. taskCreateCert opens ESP32 Preferences/NVS under the namespace MeshtasticHTTPS.
  2. It checks for two binary keys:
    • PK: DER-encoded RSA private key.
    • cert: DER-encoded x509 leaf certificate.
  3. If both keys exist and are non-empty, stock firmware loads them directly:
    cert = new SSLCert(certBuffer, certLen, pkBuffer, pkLen);
    
  4. 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:

  1. Generate a certificate from the private local root CA (ericxliu.local):
    • Subject: CN=meshtastic.local
    • SAN: DNS:meshtastic.local, DNS:*.meshtastic.local
  2. 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
    
  3. Generate a C header (MeshtasticTlsCertificate.h) containing both DER byte arrays using xxd -i.
  4. 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));
    
  5. 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.local
  • issuer: CN=ericxliu.local
  • HTTP/1.1 200 OK with CORS headers enabled.