Remove Legacy Credential Bootstrap Paths

Decouple user provisioning from HTTPS identity storage while retaining
compatible v1 user records and migrating TLS material to the
credential-free
v2 format. Add focused security regression coverage and update operator
documentation.
This commit is contained in:
2026-09-08 19:09:26 +02:00
parent 82f21d6116
commit ac80863d80
26 changed files with 1013 additions and 583 deletions
+14 -20
View File
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-only */
/* Persistent HTTPS identity and legacy migration/recovery credentials. */
/* Persistent HTTPS identity; authentication belongs to the user database. */
#pragma once
@@ -16,9 +16,7 @@ extern "C" {
#define WEB_SECURITY_NVS_NAMESPACE "web_sec"
#define WEB_SECURITY_NVS_BLOB_KEY "material"
#define WEB_SECURITY_USERNAME_CAPACITY 16U
#define WEB_SECURITY_PASSWORD_CAPACITY 32U
#define WEB_SECURITY_PASSWORD_LENGTH 24U
#define WEB_SECURITY_PRIVATE_KEY_DER_CAPACITY 256U
#define WEB_SECURITY_CERTIFICATE_DER_CAPACITY 1024U
#define WEB_SECURITY_SHA256_LENGTH 32U
@@ -31,18 +29,9 @@ extern "C" {
typedef enum {
WEB_SECURITY_LOAD_STORED = 0,
WEB_SECURITY_LOAD_GENERATED_MISSING = 1,
WEB_SECURITY_LOAD_MIGRATED_V1 = 2,
} web_security_load_result_t;
/*
* This intentionally contains a displayable secret. UART callers should call
* secure_wipe() on it immediately after rendering the length-delimited fields.
*/
typedef struct {
size_t username_length;
size_t password_length;
char username[WEB_SECURITY_USERNAME_CAPACITY + 1U];
char password[WEB_SECURITY_PASSWORD_CAPACITY + 1U];
} web_security_credentials_t;
typedef struct {
uint32_t material_generation;
@@ -55,7 +44,11 @@ typedef struct {
} web_security_certificate_metadata_t;
/*
* NVS must already be initialized. Missing material is generated and saved;
* NVS must already be initialized. Missing TLS material is generated and saved.
* Valid v1 material is migrated to certificate-only v2 before publication,
* preserving exact TLS identity and generation. Replacement is logical NVS
* deletion of legacy fields, not secure flash erasure. Migration failure never
* triggers regeneration or fallback overwrite;
* an existing wrong-version blob returns ESP_ERR_INVALID_VERSION, while any
* malformed or cryptographically inconsistent blob returns
* ESP_ERR_INVALID_RESPONSE and is never overwritten. Call before radio startup
@@ -73,17 +66,18 @@ esp_err_t web_security_copy_tls_material(
uint8_t *private_key, size_t private_key_capacity,
size_t *private_key_length);
/* Explicit secret-bearing API intended for a physically attached UART CLI. */
esp_err_t web_security_show_credentials(web_security_credentials_t *credentials);
esp_err_t web_security_get_certificate_metadata(
web_security_certificate_metadata_t *metadata);
/* Mutations become visible only after a complete blob has committed to NVS. */
esp_err_t web_security_rotate_credentials(web_security_credentials_t *new_credentials);
esp_err_t web_security_rotate_certificate(void);
/* Explicitly replaces missing, valid, or incompatible stored material. */
esp_err_t web_security_reset_all(web_security_credentials_t *new_credentials);
/* TLS ONLY: explicitly replaces missing, valid, or incompatible material.
* Generation increments from live state, or starts at one if unavailable.
* No user database mutation. */
esp_err_t web_security_reset_all(void);
#ifdef __cplusplus
}