Browse Source

EAP-SIM server: Add support for AT_COUNTER_TOO_SMALL

If the peer rejects re-authentication with AT_COUNTER_TOO_SMALL, fall
back to full authentication to allow the authentication session to be
completed.

Signed-hostap: Jouni Malinen <j@w1.fi>
Jouni Malinen 12 years ago
parent
commit
31a3de8af3
1 changed files with 26 additions and 0 deletions
  1. 26 0
      src/eap_server/eap_server_sim.c

+ 26 - 0
src/eap_server/eap_server_sim.c

@@ -118,6 +118,13 @@ static struct wpabuf * eap_sim_build_start(struct eap_sm *sm,
 	} else if (data->start_round > 3) {
 		/* Cannot use more than three rounds of Start messages */
 		return NULL;
+	} else if (data->start_round == 0) {
+		/*
+		 * This is a special case that is used to recover from
+		 * AT_COUNTER_TOO_SMALL during re-authentication. Since we
+		 * already know the identity of the peer, there is no need to
+		 * request any identity in this case.
+		 */
 	} else if (sm->identity && sm->identity_len > 0 &&
 		   sm->identity[0] == EAP_SIM_REAUTH_ID_PREFIX) {
 		/* Reauth id may have expired - try fullauth */
@@ -410,6 +417,14 @@ static void eap_sim_process_start(struct eap_sm *sm,
 
 	wpa_printf(MSG_DEBUG, "EAP-SIM: Receive start response");
 
+	if (data->start_round == 0) {
+		/*
+		 * Special case for AT_COUNTER_TOO_SMALL recovery - no identity
+		 * was requested since we already know it.
+		 */
+		goto skip_id_update;
+	}
+
 	/*
 	 * We always request identity in SIM/Start, so the peer is required to
 	 * have replied with one.
@@ -488,6 +503,7 @@ static void eap_sim_process_start(struct eap_sm *sm,
 		return;
 	}
 
+skip_id_update:
 	/* Full authentication */
 
 	if (attr->nonce_mt == NULL || attr->selected_version < 0) {
@@ -624,6 +640,16 @@ static void eap_sim_process_reauth(struct eap_sm *sm,
 
 	wpa_printf(MSG_DEBUG, "EAP-SIM: Re-authentication response includes "
 		   "the correct AT_MAC");
+
+	if (eattr.counter_too_small) {
+		wpa_printf(MSG_DEBUG, "EAP-AKA: Re-authentication response "
+			   "included AT_COUNTER_TOO_SMALL - starting full "
+			   "authentication");
+		data->start_round = -1;
+		eap_sim_state(data, START);
+		return;
+	}
+
 	if (sm->eap_sim_aka_result_ind && attr->result_ind) {
 		data->use_result_ind = 1;
 		data->notification = EAP_SIM_SUCCESS;