Implement role-aware HTTPS and SSH authentication
This commit is contained in:
+1
-112
@@ -1,5 +1,5 @@
|
||||
/* SPDX-License-Identifier: GPL-3.0-only */
|
||||
/* Canonical NVS storage for HTTPS identity and shared admin credentials. */
|
||||
/* Canonical NVS storage for HTTPS identity and legacy recovery credentials. */
|
||||
|
||||
#include "web_security.h"
|
||||
|
||||
@@ -699,117 +699,6 @@ esp_err_t web_security_copy_tls_material(
|
||||
return error;
|
||||
}
|
||||
|
||||
esp_err_t web_security_copy_username(char *output, size_t capacity,
|
||||
size_t *output_length)
|
||||
{
|
||||
if (s_security_mutex == NULL) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
xSemaphoreTake(s_security_mutex, portMAX_DELAY);
|
||||
esp_err_t error = ESP_ERR_INVALID_STATE;
|
||||
if (s_material_ready) {
|
||||
if (output_length == NULL || (output == NULL && capacity != 0U)) {
|
||||
error = ESP_ERR_INVALID_ARG;
|
||||
} else {
|
||||
*output_length = s_material.username_length;
|
||||
if (output == NULL) {
|
||||
error = capacity == 0U ? ESP_OK : ESP_ERR_INVALID_ARG;
|
||||
} else if (capacity <= s_material.username_length) {
|
||||
error = ESP_ERR_INVALID_SIZE;
|
||||
} else {
|
||||
memcpy(output, s_material.username, s_material.username_length);
|
||||
output[s_material.username_length] = '\0';
|
||||
error = ESP_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
xSemaphoreGive(s_security_mutex);
|
||||
return error;
|
||||
}
|
||||
|
||||
static esp_err_t credential_digest(const uint8_t *username, size_t username_length,
|
||||
const uint8_t *password, size_t password_length,
|
||||
uint8_t digest[WEB_SECURITY_SHA256_LENGTH])
|
||||
{
|
||||
uint8_t canonical[4U + WEB_SECURITY_USERNAME_CAPACITY +
|
||||
WEB_SECURITY_PASSWORD_CAPACITY] = {0};
|
||||
size_t offset = 0U;
|
||||
|
||||
canonical[offset++] = (uint8_t)(username_length >> 8U);
|
||||
canonical[offset++] = (uint8_t)username_length;
|
||||
if (username_length > 0U) {
|
||||
memcpy(canonical + offset, username, username_length);
|
||||
offset += username_length;
|
||||
}
|
||||
canonical[offset++] = (uint8_t)(password_length >> 8U);
|
||||
canonical[offset++] = (uint8_t)password_length;
|
||||
if (password_length > 0U) {
|
||||
memcpy(canonical + offset, password, password_length);
|
||||
offset += password_length;
|
||||
}
|
||||
|
||||
int result = mbedtls_sha256(canonical, offset, digest, 0);
|
||||
secure_wipe(canonical, sizeof(canonical));
|
||||
return result == 0 ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t web_security_authenticate_admin(const uint8_t *username,
|
||||
size_t username_length,
|
||||
const uint8_t *password,
|
||||
size_t password_length,
|
||||
bool *authenticated)
|
||||
{
|
||||
if (authenticated == NULL ||
|
||||
(username == NULL && username_length != 0U) ||
|
||||
(password == NULL && password_length != 0U)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
*authenticated = false;
|
||||
if (s_security_mutex == NULL) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
if (username_length > WEB_SECURITY_USERNAME_CAPACITY ||
|
||||
password_length > WEB_SECURITY_PASSWORD_CAPACITY) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
uint8_t supplied_digest[WEB_SECURITY_SHA256_LENGTH] = {0};
|
||||
uint8_t expected_digest[WEB_SECURITY_SHA256_LENGTH] = {0};
|
||||
xSemaphoreTake(s_security_mutex, portMAX_DELAY);
|
||||
esp_err_t error = ESP_ERR_INVALID_STATE;
|
||||
if (s_material_ready) {
|
||||
error = credential_digest(username, username_length,
|
||||
password, password_length,
|
||||
supplied_digest);
|
||||
if (error == ESP_OK) {
|
||||
error = credential_digest(s_material.username,
|
||||
s_material.username_length,
|
||||
s_material.password,
|
||||
s_material.password_length,
|
||||
expected_digest);
|
||||
}
|
||||
if (error == ESP_OK) {
|
||||
*authenticated = constant_time_equal(supplied_digest,
|
||||
expected_digest,
|
||||
sizeof(expected_digest));
|
||||
}
|
||||
}
|
||||
xSemaphoreGive(s_security_mutex);
|
||||
secure_wipe(supplied_digest, sizeof(supplied_digest));
|
||||
secure_wipe(expected_digest, sizeof(expected_digest));
|
||||
return error;
|
||||
}
|
||||
|
||||
esp_err_t web_security_authenticate_basic(const uint8_t *username,
|
||||
size_t username_length,
|
||||
const uint8_t *password,
|
||||
size_t password_length,
|
||||
bool *authenticated)
|
||||
{
|
||||
return web_security_authenticate_admin(username, username_length,
|
||||
password, password_length,
|
||||
authenticated);
|
||||
}
|
||||
|
||||
static void copy_credentials_locked(web_security_credentials_t *credentials,
|
||||
const web_security_blob_t *blob)
|
||||
|
||||
Reference in New Issue
Block a user