esp32FOTA
repository·master·Indexed 19 days ago
https://github.com/chrisjoyce911/esp32fotaAn Arduino library for ESP32 devices that enables Over-The-Air (OTA) firmware updates by polling a remote JSON configuration file. It supports HTTP and HTTPS, semantic versioning, RSA signature verification for security, and compressed firmware via Zlib or gzip. The library also allows for simultaneous updates of firmware and filesystem partitions such as SPIFFS, LittleFS, and SD.
What's inside esp32fota
- esp32FOTA is an Arduino library designed to add Over-The-Air (OTA) update capabilities to ESP32 projects. It allows devices to check a remote webserver for new firmware versions via a JSON file and perform seamless updates.
Key features of esp32FOTA
masterThe library provides several advanced OTA features, including:
- Compression Support: Handles Zlib or gzip compressed firmware.
- Filesystem Support: Supports SPIFFS, LittleFS, and SD for storing certificates and signatures.
- Protocol Support: Seamlessly handles both HTTP and HTTPS.
- Security: Includes signature verification and signature checking of downloaded firmware images.
- Update Logic: Supports semantic versioning, batch firmware sync, force updates, and web-based updates (when a web server is present).
- Partition Updates: Supports updating SPIFFS/LittleFS partitions.
Configure the Hosted JSON Manifest
masterThe
esp32FOTAlibrary uses a JSON manifest hosted on a webserver to determine if an update is available. You can define firmware updates using two different strategies. You cannot mix these strategies in a single manifest entry.1. Complete URL (Firmware Only)
Use the
urlfield to provide a direct link to the.binfile. This method does not support filesystem updates (SPIFFS, LittleFS, etc.).2. Component-based URLs (Firmware + Filesystem)
Use
host,port, andbinto construct the firmware URL, and optionalspiffs,littlefs, orfatfskeys for filesystem updates. This method allows updating both the firmware and the filesystem in one cycle.Important: If the
urlfield is present, all other URL-related fields (likehost,port,bin, or filesystem keys) will be ignored.{ "type": "esp32-fota-http", "version": "1.0.0", "host": "example.com", "port": 443, "bin": "/firmware.bin", "littlefs": "/filesystem.bin" }Handle Multiple Firmware Types or Versions in JSON
masterA single JSON manifest can contain an array of objects to support multiple hardware types or multiple version entries for the same type. The library selects the entry where the
typematches the string passed to theesp32FOTAconstructor.Multiple Hardware Types
[ { "type":"esp32-fota-http", "version":"0.0.2", "url":"http://192.168.0.100/fota/esp32-fota-http-2.bin" }, { "type":"esp32-other-hardware", "version":"0.0.3", "url":"http://192.168.0.100/fota/esp32-other-hardware.bin" } ]Multiple Versions for One Type
[ { "type":"esp32-fota-http", "version":"0.0.2", "url":"http://192.168.0.100/fota/esp32-fota-0.0.2.bin" }, { "type":"esp32-fota-http", "version":"0.0.3", "url":"http://192.168.0.100/fota/esp32-fota-0.0.3.bin", "spiffs":"http://192.168.0.100/fota/esp32-fota-0.0.3.spiffs.bin" } ]How esp32FOTA works
masterThe update process follows this workflow:
- JSON Check: The library accesses a JSON file hosted on your webserver.
- Decision Logic: It reviews the JSON content to determine if a newer firmware version is available.
- Download & Install: If an update is required, the library downloads the firmware and installs it to the device.
Requirements for successful updates:
- Webserver: Must host a JSON file containing firmware metadata.
- JSON Metadata: Must include
Firmware version,Firmware type, and theFirmware binURL (the bin can optionally be compressed with zlib or gzip). - HTTPS/Security Requirements: If using HTTPS or signature verification, you must store
root_ca.pem(for HTTPS) andrsa_key.pem(for signature checking) in your SPIFFS partition.
Configure HTTP vs HTTPS in esp32FOTA
masterThe library determines whether to use plain HTTP or HTTPS based on the port specified in the URL:
- HTTPS: Use port
443or4433. Note that for HTTPS to work, you must have theroot_ca.pemfile stored in your SPIFFS partition. - HTTP: Use any other port (defaulting to plain HTTP).
- HTTPS: Use port
Secure firmware updates with RSA signatures
masterTo ensure firmware integrity, you can sign your firmware binary using a private key. The ESP32 will verify the signature using a public key stored in a dedicated SPIFFS partition before applying the update.
1. Generate the signature
Use OpenSSL to create a signature file from your firmware binary and private key:
openssl dgst -sign priv_key.pem -keyform PEM -sha256 -out firmware.sign -binary firmware.bin2. Create the signed image
Concatenate the signature and the firmware binary into a single
.imgfile. The library expects the signature to be the first 512 bytes of the file:cat firmware.sign firmware.bin > firmware.img3. Deploy and Verify
- Upload
firmware.imgto your OTA server. - Update your
firmware.jsonto point to the newfirmware.imgURL. - Ensure your ESP32 has a SPIFFS partition containing your
rsa_key.pub. This partition is only distributed once and is not touched during subsequent OTA updates.
During the update check, the ESP32 downloads
firmware.img, extracts the first 512 bytes (the signature), and validates it against the remaining image using the public key. If valid, the device resets into the new firmware.openssl dgst -sign priv_key.pem -keyform PEM -sha256 -out firmware.sign -binary firmware.bin cat firmware.sign firmware.bin > firmware.img- Upload
Initialize esp32FOTA with Early or Late Configuration
masterYou can initialize the library using a simple constructor for basic use cases, or use
FOTAConfig_tfor advanced configurations like signature verification and custom certificates.Early Initialization (Simple)
Best for standard HTTP updates with a known name and version.
Late Initialization (Advanced)
Use
getConfig()andsetConfig()to set parameters like semantic versioning, signature checking, and custom root certificates.Note: If you are using a filesystem (like SPIFFS) to store certificates, include the filesystem header (e.g.,
#include <SPIFFS.h>) before includingesp32FOTA.hpp.### Early Init ```cpp #include <esp32FOTA.hpp> esp32FOTA esp32FOTA("esp32-fota-http", "1.0.0"); void setup() { // ... esp32FOTA.setManifestURL("http://server/fota/fota.json"); }Late Init
#include <SPIFFS.h> #include <esp32FOTA.hpp> esp32FOTA FOTA; void setup() { auto cfg = FOTA.getConfig(); cfg.name = "esp32-fota-http"; cfg.manifest_url = "http://server/fota/fota.json"; cfg.sem = SemverClass(1, 0, 0); cfg.check_sig = false; cfg.unsafe = true; // Disable cert check for TLS FOTA.setConfig(cfg); }Use Zlib/Gzip Compressed Firmware
masterYou can use compressed firmware images to save bandwidth. Note: This feature cannot be used with signature verification.
Gzip (.gz)
Requires the
ESP32-targzlibrary. The file extension in the JSON manifest must be.gz.Zlib/Pigz (.zz)
Requires the
flashzlibrary. The file extension in the JSON manifest must be.zz.Compression Commands:
# For .zz $ pigz -9kzc esp32-fota-http-2.bin > esp32-fota-http-2.bin.zz # For .gz $ gzip -c esp32-fota-http-2.bin > esp32-fota-http-2.bin.gz{ "type": "esp32-fota-http", "version": "2.5.1", "url": "http://192.168.0.100/fota/esp32-fota-http-2.bin.gz" }Install semver.c
masterYou can install
semver.cby cloning the repository or usingclib.$ git clone https://github.com/h2non/semver.c # Or using clib $ clib install h2non/semver.cVerify Firmware via RSA Signature
masterTo ensure firmware integrity, you can sign your
.binfiles with an RSA private key and have the ESP32 verify them using a public key before applying the update.1. Generate Key Pair
openssl genrsa -out priv_key.pem 4096 openssl rsa -in priv_key.pem -pubout > rsa_key.pub2. Enable Verification in Code
Set
check_sig = truein yourFOTAConfig_tand provide the public key usingsetPubKey().3. Sign the Firmware
(Note: The specific command to sign the binary is implied to follow the key generation step in the documentation).
auto cfg = FOTA.getConfig(); cfg.check_sig = true; FOTA.setConfig(cfg); // Load public key from SD CryptoFileAsset *MyPubKey = new CryptoFileAsset("/rsa_key.pub", &SD); esp32FOTA.setPubKey(MyPubKey);Manage Root Certificates and TLS
masterTo use HTTPS, you must provide root certificates.
Bundled Certificates (Arduino 3.x)
If using Arduino 3.x, you can use built-in certificates by calling:
esp32FOTA.useBundledCerts();If using PlatformIO, you must manually embed the
ca_cert_bundlefile in yourplatformio.ini:board_build.embed_txtfiles=ca_cert_bundleCustom Certificates
Certificates can be loaded from a filesystem (SPIFFS, LittleFS, SD) using
CryptoFileAssetor from memory usingCryptoMemAsset.Example: Loading from SD and Memory
CryptoFileAsset *MyRootCA = new CryptoFileAsset("/root_ca.pem", &SD); const char* root_ca = "-----BEGIN CERTIFICATE-----\n..."; CryptoMemAsset *MyRootCA_Mem = new CryptoMemAsset("Root CA", root_ca, strlen(root_ca)+1); // Apply in setup() esp32FOTA.setRootCA(MyRootCA);