feat: OTA TLS cert verification + CI release pipeline
Wire ESP-IDF's built-in 150-CA root bundle to the OTA HTTP client so HTTPS OTA verifies server certificates. Pin bundle config in sdkconfig.defaults. Replace dead artifact-copy step with Gitea release creation on tag push. Bump CI container to IDF v5.5.
This commit is contained in:
@@ -14,7 +14,7 @@ jobs:
|
|||||||
needs: [cppcheck, flawfinder, gitleaks]
|
needs: [cppcheck, flawfinder, gitleaks]
|
||||||
runs-on: anvil
|
runs-on: anvil
|
||||||
container:
|
container:
|
||||||
image: docker.io/espressif/idf:v5.3
|
image: docker.io/espressif/idf:v5.5
|
||||||
volumes:
|
volumes:
|
||||||
- /var/cache/ccache:/ccache
|
- /var/cache/ccache:/ccache
|
||||||
env:
|
env:
|
||||||
@@ -90,15 +90,33 @@ jobs:
|
|||||||
cd get-started/csi_recv_router
|
cd get-started/csi_recv_router
|
||||||
idf.py size-components 2>/dev/null | head -30
|
idf.py size-components 2>/dev/null | head -30
|
||||||
|
|
||||||
- name: Upload firmware artifact
|
- name: Create release
|
||||||
|
if: startsWith(github.ref, 'refs/tags/v')
|
||||||
run: |
|
run: |
|
||||||
mkdir -p /tmp/artifacts
|
BIN="get-started/csi_recv_router/build/csi_recv_router.bin"
|
||||||
cp get-started/csi_recv_router/build/csi_recv_router.bin /tmp/artifacts/
|
TAG="${{ github.ref_name }}"
|
||||||
cp get-started/csi_recv_router/build/bootloader/bootloader.bin /tmp/artifacts/
|
API="https://git.mymx.me/api/v1/repos/${{ github.repository }}"
|
||||||
cp get-started/csi_recv_router/build/partition_table/partition-table.bin /tmp/artifacts/
|
TOKEN="${{ github.token }}"
|
||||||
cp get-started/csi_recv_router/build/ota_data_initial.bin /tmp/artifacts/
|
SIZE=$(stat -c%s "$BIN")
|
||||||
echo "Artifacts ready in /tmp/artifacts"
|
|
||||||
ls -la /tmp/artifacts/
|
RELEASE_ID=$(curl -sS -f -X POST "$API/releases" \
|
||||||
|
-H "Authorization: token $TOKEN" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "{
|
||||||
|
\"tag_name\": \"$TAG\",
|
||||||
|
\"name\": \"$TAG\",
|
||||||
|
\"body\": \"Firmware $TAG — $((SIZE / 1024)) KB\"
|
||||||
|
}" | python3 -c "import json,sys; print(json.load(sys.stdin)['id'])")
|
||||||
|
|
||||||
|
echo "Release $RELEASE_ID created for $TAG"
|
||||||
|
|
||||||
|
curl -sS -f -X POST \
|
||||||
|
"$API/releases/$RELEASE_ID/assets?name=csi_recv_router.bin" \
|
||||||
|
-H "Authorization: token $TOKEN" \
|
||||||
|
-H "Content-Type: application/octet-stream" \
|
||||||
|
--data-binary @"$BIN"
|
||||||
|
|
||||||
|
echo "Uploaded csi_recv_router.bin ($((SIZE / 1024)) KB)"
|
||||||
|
|
||||||
cppcheck:
|
cppcheck:
|
||||||
name: C/C++ Static Analysis
|
name: C/C++ Static Analysis
|
||||||
|
|||||||
@@ -172,6 +172,7 @@ Note: Promiscuous mode (probe/deauth capture) disabled on original ESP32 — bre
|
|||||||
- [x] Enable WDT panic (`CONFIG_ESP_TASK_WDT_PANIC`)
|
- [x] Enable WDT panic (`CONFIG_ESP_TASK_WDT_PANIC`)
|
||||||
- [x] Remove unused `#include "esp_now.h"` (CVE-2025-52471 mitigation)
|
- [x] Remove unused `#include "esp_now.h"` (CVE-2025-52471 mitigation)
|
||||||
- [x] Remove hardcoded default IP from Kconfig (use TARGET command)
|
- [x] Remove hardcoded default IP from Kconfig (use TARGET command)
|
||||||
|
- [x] OTA TLS certificate verification (ESP-IDF 150-CA bundle, `crt_bundle_attach`)
|
||||||
- [ ] Multi-target (send data to 2+ UDP destinations)
|
- [ ] Multi-target (send data to 2+ UDP destinations)
|
||||||
|
|
||||||
## Web Backend (`~/git/esp32-web/`)
|
## Web Backend (`~/git/esp32-web/`)
|
||||||
|
|||||||
3
TASKS.md
3
TASKS.md
@@ -57,6 +57,9 @@ Tracked separately in `~/git/esp32-web/TASKS.md`. Currently at v0.1.5.
|
|||||||
- [x] Remove unused `#include "esp_now.h"` (2026-02-14)
|
- [x] Remove unused `#include "esp_now.h"` (2026-02-14)
|
||||||
- [x] Remove hardcoded default IP from Kconfig (2026-02-14)
|
- [x] Remove hardcoded default IP from Kconfig (2026-02-14)
|
||||||
|
|
||||||
|
### P1 - High
|
||||||
|
- [x] OTA TLS certificate verification via ESP-IDF CA bundle (2026-02-14)
|
||||||
|
|
||||||
### P2 - Normal
|
### P2 - Normal
|
||||||
- [ ] Tune presence threshold per room with real-world testing
|
- [ ] Tune presence threshold per room with real-world testing
|
||||||
- [ ] Power consumption measurements using POWERTEST + external meter
|
- [ ] Power consumption measurements using POWERTEST + external meter
|
||||||
|
|||||||
2
TODO.md
2
TODO.md
@@ -11,7 +11,7 @@
|
|||||||
- [ ] Flash encryption planning (irreversible eFuse burn)
|
- [ ] Flash encryption planning (irreversible eFuse burn)
|
||||||
- [ ] Secure Boot V2 planning (irreversible eFuse burn)
|
- [ ] Secure Boot V2 planning (irreversible eFuse burn)
|
||||||
- [ ] DTLS for UDP command channel (stretch goal)
|
- [ ] DTLS for UDP command channel (stretch goal)
|
||||||
- [ ] OTA certificate pinning / embedded CA cert
|
- [x] OTA TLS certificate verification (ESP-IDF CA bundle)
|
||||||
- [ ] NVS encryption for auth_secret at rest
|
- [ ] NVS encryption for auth_secret at rest
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
#include "esp_random.h"
|
#include "esp_random.h"
|
||||||
#include "esp_ota_ops.h"
|
#include "esp_ota_ops.h"
|
||||||
#include "esp_https_ota.h"
|
#include "esp_https_ota.h"
|
||||||
|
#include "esp_crt_bundle.h"
|
||||||
#include "esp_partition.h"
|
#include "esp_partition.h"
|
||||||
#include "esp_chip_info.h"
|
#include "esp_chip_info.h"
|
||||||
#include "esp_http_client.h"
|
#include "esp_http_client.h"
|
||||||
@@ -1235,6 +1236,7 @@ static void ota_task(void *arg)
|
|||||||
esp_http_client_config_t http_cfg = {
|
esp_http_client_config_t http_cfg = {
|
||||||
.url = url,
|
.url = url,
|
||||||
.timeout_ms = 30000,
|
.timeout_ms = 30000,
|
||||||
|
.crt_bundle_attach = esp_crt_bundle_attach,
|
||||||
};
|
};
|
||||||
|
|
||||||
esp_https_ota_config_t ota_cfg = {
|
esp_https_ota_config_t ota_cfg = {
|
||||||
|
|||||||
@@ -69,6 +69,12 @@ CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
|||||||
CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE=y
|
CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE=y
|
||||||
CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP=y
|
CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP=y
|
||||||
|
|
||||||
|
#
|
||||||
|
# TLS Certificate Bundle (CA root store for HTTPS OTA)
|
||||||
|
#
|
||||||
|
CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y
|
||||||
|
CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y
|
||||||
|
|
||||||
#
|
#
|
||||||
# BLE (NimBLE, scan-only, WiFi coexistence)
|
# BLE (NimBLE, scan-only, WiFi coexistence)
|
||||||
#
|
#
|
||||||
|
|||||||
Reference in New Issue
Block a user