Allow SSH keys on multiple accounts
Update validation and duplicate checks to scope key uniqueness per account, and clarify the console error message. Document cross-account key assignment and authentication testing.
This commit is contained in:
@@ -48,10 +48,12 @@ Verify all of the following fail without changing the account generation or key
|
||||
|
||||
- Unsupported RSA, certificate, or unknown key types.
|
||||
- Truncated/invalid Base64, mismatched outer and embedded types, trailing blob data, malformed Ed25519 lengths, and an invalid/off-curve ECDSA point.
|
||||
- Adding the same key again to the same account or assigning it to a different account.
|
||||
- Adding the same key again to the same account.
|
||||
- Adding a fourth key to an account that already has three.
|
||||
- Deleting an empty/out-of-range slot.
|
||||
|
||||
Assign the same public key to a second account and confirm it is accepted, receives an independent slot, and authenticates as the username selected by the SSH client.
|
||||
|
||||
Then exercise `user key delete <username> <index> --force` and `user key clear <username> --force`, reboot, and confirm the exact remaining fingerprints persist. Phase 8A stores these keys but does not yet accept SSH key login.
|
||||
|
||||
### 5. Legacy credential rotation boundary and reboot reconciliation
|
||||
|
||||
+1
-1
@@ -357,7 +357,7 @@ static int add_key(const char *username)
|
||||
secure_wipe(line, sizeof(line));
|
||||
if (error != ESP_OK) {
|
||||
if (error == USER_DATABASE_ERR_DUPLICATE_SSH_KEY) {
|
||||
printf("Could not add SSH key: that public key is already assigned to an account.\n");
|
||||
printf("Could not add SSH key: that public key is already assigned to this account.\n");
|
||||
} else if (error == ESP_ERR_NO_MEM) {
|
||||
printf("Could not add SSH key: the account already has %u keys.\n",
|
||||
USER_DATABASE_MAX_SSH_KEYS_PER_USER);
|
||||
|
||||
+8
-23
@@ -387,17 +387,11 @@ static esp_err_t validate_database(const stored_database_t *database)
|
||||
sizeof(key->blob) - key->blob_length)) {
|
||||
return ESP_ERR_INVALID_RESPONSE;
|
||||
}
|
||||
for (size_t prior_user = 0U; prior_user <= index; ++prior_user) {
|
||||
size_t prior_key_limit = prior_user == index
|
||||
? key_index
|
||||
: USER_DATABASE_MAX_SSH_KEYS_PER_USER;
|
||||
for (size_t prior_key = 0U; prior_key < prior_key_limit; ++prior_key) {
|
||||
if (stored_keys_equal(key,
|
||||
&database->users[prior_user].keys[prior_key])) {
|
||||
for (size_t prior_key = 0U; prior_key < key_index; ++prior_key) {
|
||||
if (stored_keys_equal(key, &user->keys[prior_key])) {
|
||||
return ESP_ERR_INVALID_RESPONSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
uint8_t fingerprint[USER_DATABASE_SHA256_LENGTH];
|
||||
if (mbedtls_sha256(key->blob, key->blob_length, fingerprint, 0) != 0 ||
|
||||
!constant_time_equal(fingerprint, key->fingerprint,
|
||||
@@ -1157,21 +1151,16 @@ esp_err_t user_database_add_ssh_key(
|
||||
if (error == ESP_OK) {
|
||||
stored_user_t *user = &s_candidate.users[user_index];
|
||||
int free_index = -1;
|
||||
for (size_t candidate_user_index = 0U;
|
||||
candidate_user_index < USER_DATABASE_MAX_USERS; ++candidate_user_index) {
|
||||
stored_user_t *candidate_user =
|
||||
&s_candidate.users[candidate_user_index];
|
||||
if (candidate_user->active == 0U) {
|
||||
continue;
|
||||
}
|
||||
for (size_t index = 0U;
|
||||
index < USER_DATABASE_MAX_SSH_KEYS_PER_USER; ++index) {
|
||||
stored_key_t *key = &candidate_user->keys[index];
|
||||
if (candidate_user_index == (size_t)user_index &&
|
||||
key->active == 0U && free_index < 0) {
|
||||
stored_key_t *key = &user->keys[index];
|
||||
if (key->active == 0U) {
|
||||
if (free_index < 0) {
|
||||
free_index = (int)index;
|
||||
}
|
||||
if (key->active != 0U && key->type_length == key_type_length &&
|
||||
continue;
|
||||
}
|
||||
if (key->type_length == key_type_length &&
|
||||
key->blob_length == key_blob_length &&
|
||||
memcmp(key->type, key_type, key_type_length) == 0 &&
|
||||
constant_time_equal(key->blob, key_blob, key_blob_length)) {
|
||||
@@ -1179,10 +1168,6 @@ esp_err_t user_database_add_ssh_key(
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (error != ESP_OK) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (error == ESP_OK && free_index < 0) {
|
||||
error = ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user