mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
fix(protocomm): invalidate SRP session on proof-verify failure
handle_session_command1() left the session in SESSION_STATE_CMD1 with a live esp_srp handle (ephemeral b/B and derived session key intact) when the client SRP proof failed to validate. A client could therefore keep sending Command1 messages with different guessed proofs against a single handshake, turning the SRP exchange into an unlimited online dictionary attack on the proof-of-possession. Tear down the SRP context and reset the session back to SESSION_STATE_CMD0 on proof-verify failure so that every guess now requires a fresh, expensive Command0 handshake (new ephemeral). The session id is preserved so the transport session stays valid for a legitimate retry, and the credential-mismatch event still fires for application-level lockout policies. Closes SEC-620
This commit is contained in:
@@ -247,6 +247,18 @@ static esp_err_t handle_session_command1(session_t *cur_session,
|
|||||||
if (esp_srp_exchange_proofs(cur_session->srp_hd, cur_session->username, cur_session->username_len, (char * ) in->sc1->client_proof.data, device_proof) != ESP_OK) {
|
if (esp_srp_exchange_proofs(cur_session->srp_hd, cur_session->username, cur_session->username_len, (char * ) in->sc1->client_proof.data, device_proof) != ESP_OK) {
|
||||||
ESP_LOGE(TAG, "Failed to authenticate client proof!");
|
ESP_LOGE(TAG, "Failed to authenticate client proof!");
|
||||||
free(device_proof);
|
free(device_proof);
|
||||||
|
|
||||||
|
if (cur_session->srp_hd) {
|
||||||
|
esp_srp_free(cur_session->srp_hd);
|
||||||
|
cur_session->srp_hd = NULL;
|
||||||
|
}
|
||||||
|
cur_session->session_key = NULL;
|
||||||
|
cur_session->session_key_len = 0;
|
||||||
|
free(cur_session->username);
|
||||||
|
cur_session->username = NULL;
|
||||||
|
cur_session->username_len = 0;
|
||||||
|
cur_session->state = SESSION_STATE_CMD0;
|
||||||
|
|
||||||
if (esp_event_post(PROTOCOMM_SECURITY_SESSION_EVENT, PROTOCOMM_SECURITY_SESSION_CREDENTIALS_MISMATCH, NULL, 0, portMAX_DELAY) != ESP_OK) {
|
if (esp_event_post(PROTOCOMM_SECURITY_SESSION_EVENT, PROTOCOMM_SECURITY_SESSION_CREDENTIALS_MISMATCH, NULL, 0, portMAX_DELAY) != ESP_OK) {
|
||||||
ESP_LOGE(TAG, "Failed to post credential mismatch event");
|
ESP_LOGE(TAG, "Failed to post credential mismatch event");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user