Add HTTPS identity rotation support

This commit is contained in:
2026-09-13 18:21:37 +02:00
parent 36e80811e8
commit aa4bbc2c8c
24 changed files with 826 additions and 170 deletions
+2
View File
@@ -110,6 +110,8 @@ TinyUSB callbacks enqueue/copy data and state; the transport task owns broker li
### HTTPS, WebSocket, and web serial
**8D.21 HTTPS identity extension:** The existing 8D.20 lifecycle routes/slot/controller additionally expose public stored SHA-256 fingerprint/identity generation and confirmed `rotate` with both expected generations. `web_server_replace_identity()` reserves the canonical service transition before acquiring the security identity reservation, then retains it across generation/commit and reserved stop/start. CLI rotate/reset and the deferred browser-shell owner use this same composition; direct security mutations acquire the same nonreused identity reservation. `web_security` holds its normal mutex only for admission/copies/publication during replacement, never over crypto/NVS; the reservation remains live while start copies the committed TLS pair. Generation/storage failure leaves identity and HTTPD unchanged; committed identity is never rolled back on lifecycle failure, so stored and served fingerprints can differ. Reset remains canonical CLI TLS-only recovery and starts a stopped service; ordinary stopped rotation stays stopped. No new browser reset, secrets, SSH identity action, route, task, timer or queue. Seven-field lifecycle snapshot is bounded to320 bytes; existing256-byte input/96-byte result and ACK deadlines remain. UI confirmation names the old public fingerprint and both generations, demands UART0 `web certificate info` verification of changed trust and fresh login, and shares the pending/no-replay gate with ordinary lifecycle controls. Full contracts/tests/target limits: `docs/phase8d21_implementation.md`. This extends, rather than replaces,8D.20 below.
**8D.20 integrated lifecycle (supersedes prerequisite-only status below):** `web_lifecycle_settings` admits strict current-admin cookie/Origin/CSRF stop/restart/reboot through three optional routes. One original-login operation slot and nonreused ID,256-byte/four-receive request,128-byte snapshot/96-byte result. Only after synchronous response send succeeds does HTTPD queue an ID callback; it hands that ID without waiting to the existing four-entry dispatcher. No request/fd/socket/operation pointer escapes the handler. Two-second ACK and30-second post-validation dequeue deadlines precede owner admission, not lifecycle completion. Lost HTTPD work retains one reservation until callback or successful destruction, avoiding late-work accumulation; failed destruction preserves it. Dispatcher reserves execution, revalidates original session/current admin and calls canonical generation-conditional owner APIs outside locks. Restart invalidates logins but retains its owner reservation through start; later revocation is not cancellation. Conditional reboot reserves the HTTPS generation then invokes the shared canonical `esp_restart()` primitive outside locks, with no console self-cleanup or HTTPD stop wait. UI explicit confirmation/manual results/15-second whole request fences and no replay/restore; existing Network reused.39 handlers/six sockets and unchanged tasks/stacks/timers/queue depth. Full API, uncertainty, SDK/reset audit and resource limits: `docs/phase8d20_implementation.md`.
**Historical 8D.20 internal owner prerequisite (superseded above):** `web_server` exposes a zero-wait scalar management snapshot and off-HTTPD generation-conditional stop/restart APIs. A firmware-lifetime saturated generation advances under the existing lifecycle mutex on every admitted canonical start/stop, including failed attempts; counter clear and repeated init do not restore old tokens. Conditional admission rejects failed cleanup, transition, absent server or exhausted generation. Reserved restart keeps `s_transitioning` true across successful stop into private start, with no unreserved stopped gap; external lifecycle calls remain outside the mutex. Stop failure skips start, partial-start cleanup failure retains ownership, and canonical stop/start remain recovery after saturation/failure. Repeated init preserves retained lifecycle errors. These APIs have no production caller yet and perform no authorization or ACK handoff; HTTP routes/UI/typed reboot are unimplemented. A future dispatcher must validate the original login and bound ACK handling before admission, never call shutdown from HTTPD or describe admitted work as cancelled by later revocation. Contract and incomplete scope: `docs/phase8d20_implementation.md`.