Clarify Service Contracts And Security Invariants

This commit is contained in:
2026-09-21 13:39:30 +02:00
parent 6406142b21
commit 655f26a611
58 changed files with 272 additions and 25 deletions
+10
View File
@@ -41,6 +41,8 @@ typedef enum {
USER_DATABASE_LOAD_EMPTY,
} user_database_load_result_t;
/* Secret-free identity copy, not a permanent authorization grant. Recheck
* principal currentness at protected boundaries after account changes. */
typedef struct {
uint32_t user_id;
uint32_t auth_generation;
@@ -50,6 +52,8 @@ typedef struct {
char username[USER_DATABASE_USERNAME_CAPACITY + 1U];
} user_principal_t;
/* Caller-owned plaintext secret; keep out of routine status/logs and wipe
* the entire structure after the intended credential handoff. */
typedef struct {
size_t password_length;
uint8_t password[USER_DATABASE_PASSWORD_CAPACITY + 1U];
@@ -122,15 +126,21 @@ esp_err_t user_database_set_password_current(const user_database_account_t *expe
* owns/wipes successful output; failures clear it. Same generator as CLI. */
esp_err_t user_database_generate_password_value(user_database_generated_password_t *generated);
/* ESP_OK alone is not authentication: require authenticated == true before
* using principal. Credential rejection normally returns ESP_OK with false. */
esp_err_t user_database_authenticate_password(
const uint8_t *username, size_t username_length,
const uint8_t *password, size_t password_length,
user_principal_t *principal, bool *authenticated);
/* Likewise require authorized == true. This checks key membership only;
* the SSH layer must verify proof of private-key possession separately. */
esp_err_t user_database_authorize_ssh_public_key(
const uint8_t *username, size_t username_length,
const uint8_t *key_type, size_t key_type_length,
const uint8_t *key_blob, size_t key_blob_length,
user_principal_t *principal, bool *authorized);
/* Account identity/generation/role check only, not transport-session liveness.
* ESP_OK reports a completed check; inspect current for the decision. */
esp_err_t user_database_principal_is_current(const user_principal_t *principal,
bool *current);