EAP-TEAP peer: Allow Result TLV without Crypto-Binding TLV

If the Crypto-Binding TLV for the last EAP method has been validated
successfully in a previous message exchange with Intermediate-Result TLV
and no new EAP method has been started, Result TLV can be accepted
without an additional Crypto-Binding TLV. This allows the server to go
through additional message exchanges after inner EAP method, if needed.

Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2019-08-16 23:39:33 +03:00
parent 128d46be9f
commit 4c327146f0

View file

@ -35,6 +35,7 @@ struct eap_teap_data {
void *phase2_priv; void *phase2_priv;
int phase2_success; int phase2_success;
int inner_method_done; int inner_method_done;
int iresult_verified;
int result_success_done; int result_success_done;
int on_tx_completion; int on_tx_completion;
@ -311,6 +312,7 @@ static int eap_teap_init_phase2_method(struct eap_sm *sm,
struct eap_teap_data *data) struct eap_teap_data *data)
{ {
data->inner_method_done = 0; data->inner_method_done = 0;
data->iresult_verified = 0;
data->phase2_method = data->phase2_method =
eap_peer_get_eap_method(data->phase2_type.vendor, eap_peer_get_eap_method(data->phase2_type.vendor,
data->phase2_type.method); data->phase2_type.method);
@ -1217,14 +1219,21 @@ static int eap_teap_process_decrypted(struct eap_sm *sm,
goto send_resp; goto send_resp;
} }
if ((tlv.iresult == TEAP_STATUS_SUCCESS || if (tlv.iresult == TEAP_STATUS_SUCCESS && !tlv.crypto_binding) {
(!data->result_success_done && /* Intermediate-Result TLV indicating success, but no
tlv.result == TEAP_STATUS_SUCCESS)) && * Crypto-Binding TLV */
!tlv.crypto_binding) {
/* Result TLV or Intermediate-Result TLV indicating success,
* but no Crypto-Binding TLV */
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"EAP-TEAP: Result TLV or Intermediate-Result TLV indicating success, but no Crypto-Binding TLV"); "EAP-TEAP: Intermediate-Result TLV indicating success, but no Crypto-Binding TLV");
failed = 1;
error = TEAP_ERROR_TUNNEL_COMPROMISE_ERROR;
goto done;
}
if (!data->iresult_verified && !data->result_success_done &&
tlv.result == TEAP_STATUS_SUCCESS && !tlv.crypto_binding) {
/* Result TLV indicating success, but no Crypto-Binding TLV */
wpa_printf(MSG_DEBUG,
"EAP-TEAP: Result TLV indicating success, but no Crypto-Binding TLV");
failed = 1; failed = 1;
error = TEAP_ERROR_TUNNEL_COMPROMISE_ERROR; error = TEAP_ERROR_TUNNEL_COMPROMISE_ERROR;
goto done; goto done;
@ -1287,8 +1296,10 @@ static int eap_teap_process_decrypted(struct eap_sm *sm,
resp = wpabuf_concat(resp, tmp); resp = wpabuf_concat(resp, tmp);
if (tlv.result == TEAP_STATUS_SUCCESS && !failed) if (tlv.result == TEAP_STATUS_SUCCESS && !failed)
data->result_success_done = 1; data->result_success_done = 1;
if (tlv.iresult == TEAP_STATUS_SUCCESS && !failed) if (tlv.iresult == TEAP_STATUS_SUCCESS && !failed) {
data->inner_method_done = 0; data->inner_method_done = 0;
data->iresult_verified = 1;
}
} }
} }
@ -1359,7 +1370,8 @@ done:
} }
if (resp && tlv.result == TEAP_STATUS_SUCCESS && !failed && if (resp && tlv.result == TEAP_STATUS_SUCCESS && !failed &&
tlv.crypto_binding && data->phase2_success) { (tlv.crypto_binding || data->iresult_verified) &&
data->phase2_success) {
/* Successfully completed Phase 2 */ /* Successfully completed Phase 2 */
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"EAP-TEAP: Authentication completed successfully"); "EAP-TEAP: Authentication completed successfully");
@ -1928,6 +1940,7 @@ static void * eap_teap_init_for_reauth(struct eap_sm *sm, void *priv)
data->phase2_success = 0; data->phase2_success = 0;
data->inner_method_done = 0; data->inner_method_done = 0;
data->result_success_done = 0; data->result_success_done = 0;
data->iresult_verified = 0;
data->done_on_tx_completion = 0; data->done_on_tx_completion = 0;
data->resuming = 1; data->resuming = 1;
data->provisioning = 0; data->provisioning = 0;