eap_aka.c

来自「最新的Host AP 新添加了许多pcmcia 的驱动」· C语言 代码 · 共 1,279 行 · 第 1/3 页

C
1,279
字号
	 * that the RES length in bits matches with the expected RES.	 */	if (attr->res == NULL || attr->res_len < data->res_len ||	    attr->res_len_bits != data->res_len * 8 ||	    os_memcmp(attr->res, data->res, data->res_len) != 0) {		wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message did not "			   "include valid AT_RES (attr len=%lu, res len=%lu "			   "bits, expected %lu bits)",			   (unsigned long) attr->res_len,			   (unsigned long) attr->res_len_bits,			   (unsigned long) data->res_len * 8);		data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH;		eap_aka_state(data, NOTIFICATION);		return;	}	wpa_printf(MSG_DEBUG, "EAP-AKA: Challenge response includes the "		   "correct AT_MAC");	if (sm->eap_sim_aka_result_ind && attr->result_ind) {		data->use_result_ind = 1;		data->notification = EAP_SIM_SUCCESS;		eap_aka_state(data, NOTIFICATION);	} else		eap_aka_state(data, SUCCESS);	identity = eap_sim_db_get_permanent(sm->eap_sim_db_priv, sm->identity,					    sm->identity_len, &identity_len);	if (identity == NULL) {		identity = sm->identity;		identity_len = sm->identity_len;	}	if (data->next_pseudonym) {		eap_sim_db_add_pseudonym(sm->eap_sim_db_priv, identity,					 identity_len,					 data->next_pseudonym);		data->next_pseudonym = NULL;	}	if (data->next_reauth_id) {		if (data->eap_method == EAP_TYPE_AKA_PRIME) {#ifdef EAP_AKA_PRIME			eap_sim_db_add_reauth_prime(sm->eap_sim_db_priv,						    identity,						    identity_len,						    data->next_reauth_id,						    data->counter + 1,						    data->k_encr, data->k_aut,						    data->k_re);#endif /* EAP_AKA_PRIME */		} else {			eap_sim_db_add_reauth(sm->eap_sim_db_priv, identity,					      identity_len,					      data->next_reauth_id,					      data->counter + 1,					      data->mk);		}		data->next_reauth_id = NULL;	}}static void eap_aka_process_sync_failure(struct eap_sm *sm,					 struct eap_aka_data *data,					 struct wpabuf *respData,					 struct eap_sim_attrs *attr){	wpa_printf(MSG_DEBUG, "EAP-AKA: Processing Synchronization-Failure");	if (attr->auts == NULL) {		wpa_printf(MSG_WARNING, "EAP-AKA: Synchronization-Failure "			   "message did not include valid AT_AUTS");		data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH;		eap_aka_state(data, NOTIFICATION);		return;	}	/* Avoid re-reporting AUTS when processing pending EAP packet by	 * maintaining a local flag stating whether this AUTS has already been	 * reported. */	if (!data->auts_reported &&	    eap_sim_db_resynchronize(sm->eap_sim_db_priv, sm->identity,				     sm->identity_len, attr->auts,				     data->rand)) {		wpa_printf(MSG_WARNING, "EAP-AKA: Resynchronization failed");		data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH;		eap_aka_state(data, NOTIFICATION);		return;	}	data->auts_reported = 1;	/* Try again after resynchronization */	eap_aka_determine_identity(sm, data, 0, 0);}static void eap_aka_process_reauth(struct eap_sm *sm,				   struct eap_aka_data *data,				   struct wpabuf *respData,				   struct eap_sim_attrs *attr){	struct eap_sim_attrs eattr;	u8 *decrypted = NULL;	const u8 *identity, *id2;	size_t identity_len, id2_len;	wpa_printf(MSG_DEBUG, "EAP-AKA: Processing Reauthentication");	if (attr->mac == NULL ||	    eap_aka_verify_mac(data, respData, attr->mac, data->nonce_s,			       EAP_SIM_NONCE_S_LEN)) {		wpa_printf(MSG_WARNING, "EAP-AKA: Re-authentication message "			   "did not include valid AT_MAC");		goto fail;	}	if (attr->encr_data == NULL || attr->iv == NULL) {		wpa_printf(MSG_WARNING, "EAP-AKA: Reauthentication "			   "message did not include encrypted data");		goto fail;	}	decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data,				       attr->encr_data_len, attr->iv, &eattr,				       0);	if (decrypted == NULL) {		wpa_printf(MSG_WARNING, "EAP-AKA: Failed to parse encrypted "			   "data from reauthentication message");		goto fail;	}	if (eattr.counter != data->counter) {		wpa_printf(MSG_WARNING, "EAP-AKA: Re-authentication message "			   "used incorrect counter %u, expected %u",			   eattr.counter, data->counter);		goto fail;	}	os_free(decrypted);	decrypted = NULL;	wpa_printf(MSG_DEBUG, "EAP-AKA: 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");		eap_aka_determine_identity(sm, data, 0, 1);		return;	}	if (sm->eap_sim_aka_result_ind && attr->result_ind) {		data->use_result_ind = 1;		data->notification = EAP_SIM_SUCCESS;		eap_aka_state(data, NOTIFICATION);	} else		eap_aka_state(data, SUCCESS);	if (data->reauth) {		identity = data->reauth->identity;		identity_len = data->reauth->identity_len;	} else {		identity = sm->identity;		identity_len = sm->identity_len;	}	id2 = eap_sim_db_get_permanent(sm->eap_sim_db_priv, identity,				       identity_len, &id2_len);	if (id2) {		identity = id2;		identity_len = id2_len;	}	if (data->next_pseudonym) {		eap_sim_db_add_pseudonym(sm->eap_sim_db_priv, identity,					 identity_len, data->next_pseudonym);		data->next_pseudonym = NULL;	}	if (data->next_reauth_id) {		if (data->eap_method == EAP_TYPE_AKA_PRIME) {#ifdef EAP_AKA_PRIME			eap_sim_db_add_reauth_prime(sm->eap_sim_db_priv,						    identity,						    identity_len,						    data->next_reauth_id,						    data->counter + 1,						    data->k_encr, data->k_aut,						    data->k_re);#endif /* EAP_AKA_PRIME */		} else {			eap_sim_db_add_reauth(sm->eap_sim_db_priv, identity,					      identity_len,					      data->next_reauth_id,					      data->counter + 1,					      data->mk);		}		data->next_reauth_id = NULL;	} else {		eap_sim_db_remove_reauth(sm->eap_sim_db_priv, data->reauth);		data->reauth = NULL;	}	return;fail:	data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH;	eap_aka_state(data, NOTIFICATION);	eap_sim_db_remove_reauth(sm->eap_sim_db_priv, data->reauth);	data->reauth = NULL;	os_free(decrypted);}static void eap_aka_process_client_error(struct eap_sm *sm,					 struct eap_aka_data *data,					 struct wpabuf *respData,					 struct eap_sim_attrs *attr){	wpa_printf(MSG_DEBUG, "EAP-AKA: Client reported error %d",		   attr->client_error_code);	if (data->notification == EAP_SIM_SUCCESS && data->use_result_ind)		eap_aka_state(data, SUCCESS);	else		eap_aka_state(data, FAILURE);}static void eap_aka_process_authentication_reject(	struct eap_sm *sm, struct eap_aka_data *data,	struct wpabuf *respData, struct eap_sim_attrs *attr){	wpa_printf(MSG_DEBUG, "EAP-AKA: Client rejected authentication");	eap_aka_state(data, FAILURE);}static void eap_aka_process_notification(struct eap_sm *sm,					 struct eap_aka_data *data,					 struct wpabuf *respData,					 struct eap_sim_attrs *attr){	wpa_printf(MSG_DEBUG, "EAP-AKA: Client replied to notification");	if (data->notification == EAP_SIM_SUCCESS && data->use_result_ind)		eap_aka_state(data, SUCCESS);	else		eap_aka_state(data, FAILURE);}static void eap_aka_process(struct eap_sm *sm, void *priv,			    struct wpabuf *respData){	struct eap_aka_data *data = priv;	const u8 *pos, *end;	u8 subtype;	size_t len;	struct eap_sim_attrs attr;	pos = eap_hdr_validate(EAP_VENDOR_IETF, data->eap_method, respData,			       &len);	if (pos == NULL || len < 3)		return;	end = pos + len;	subtype = *pos;	pos += 3;	if (eap_aka_subtype_ok(data, subtype)) {		wpa_printf(MSG_DEBUG, "EAP-AKA: Unrecognized or unexpected "			   "EAP-AKA Subtype in EAP Response");		data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH;		eap_aka_state(data, NOTIFICATION);		return;	}	if (eap_sim_parse_attr(pos, end, &attr,			       data->eap_method == EAP_TYPE_AKA_PRIME ? 2 : 1,			       0)) {		wpa_printf(MSG_DEBUG, "EAP-AKA: Failed to parse attributes");		data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH;		eap_aka_state(data, NOTIFICATION);		return;	}	if (subtype == EAP_AKA_SUBTYPE_CLIENT_ERROR) {		eap_aka_process_client_error(sm, data, respData, &attr);		return;	}	if (subtype == EAP_AKA_SUBTYPE_AUTHENTICATION_REJECT) {		eap_aka_process_authentication_reject(sm, data, respData,						      &attr);		return;	}	switch (data->state) {	case IDENTITY:		eap_aka_process_identity(sm, data, respData, &attr);		break;	case CHALLENGE:		if (subtype == EAP_AKA_SUBTYPE_SYNCHRONIZATION_FAILURE) {			eap_aka_process_sync_failure(sm, data, respData,						     &attr);		} else {			eap_aka_process_challenge(sm, data, respData, &attr);		}		break;	case REAUTH:		eap_aka_process_reauth(sm, data, respData, &attr);		break;	case NOTIFICATION:		eap_aka_process_notification(sm, data, respData, &attr);		break;	default:		wpa_printf(MSG_DEBUG, "EAP-AKA: Unknown state %d in "			   "process", data->state);		break;	}}static Boolean eap_aka_isDone(struct eap_sm *sm, void *priv){	struct eap_aka_data *data = priv;	return data->state == SUCCESS || data->state == FAILURE;}static u8 * eap_aka_getKey(struct eap_sm *sm, void *priv, size_t *len){	struct eap_aka_data *data = priv;	u8 *key;	if (data->state != SUCCESS)		return NULL;	key = os_malloc(EAP_SIM_KEYING_DATA_LEN);	if (key == NULL)		return NULL;	os_memcpy(key, data->msk, EAP_SIM_KEYING_DATA_LEN);	*len = EAP_SIM_KEYING_DATA_LEN;	return key;}static u8 * eap_aka_get_emsk(struct eap_sm *sm, void *priv, size_t *len){	struct eap_aka_data *data = priv;	u8 *key;	if (data->state != SUCCESS)		return NULL;	key = os_malloc(EAP_EMSK_LEN);	if (key == NULL)		return NULL;	os_memcpy(key, data->emsk, EAP_EMSK_LEN);	*len = EAP_EMSK_LEN;	return key;}static Boolean eap_aka_isSuccess(struct eap_sm *sm, void *priv){	struct eap_aka_data *data = priv;	return data->state == SUCCESS;}int eap_server_aka_register(void){	struct eap_method *eap;	int ret;	eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,				      EAP_VENDOR_IETF, EAP_TYPE_AKA, "AKA");	if (eap == NULL)		return -1;	eap->init = eap_aka_init;	eap->reset = eap_aka_reset;	eap->buildReq = eap_aka_buildReq;	eap->check = eap_aka_check;	eap->process = eap_aka_process;	eap->isDone = eap_aka_isDone;	eap->getKey = eap_aka_getKey;	eap->isSuccess = eap_aka_isSuccess;	eap->get_emsk = eap_aka_get_emsk;	ret = eap_server_method_register(eap);	if (ret)		eap_server_method_free(eap);	return ret;}#ifdef EAP_AKA_PRIMEint eap_server_aka_prime_register(void){	struct eap_method *eap;	int ret;	eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,				      EAP_VENDOR_IETF, EAP_TYPE_AKA_PRIME,				      "AKA'");	if (eap == NULL)		return -1;	eap->init = eap_aka_prime_init;	eap->reset = eap_aka_reset;	eap->buildReq = eap_aka_buildReq;	eap->check = eap_aka_check;	eap->process = eap_aka_process;	eap->isDone = eap_aka_isDone;	eap->getKey = eap_aka_getKey;	eap->isSuccess = eap_aka_isSuccess;	eap->get_emsk = eap_aka_get_emsk;	ret = eap_server_method_register(eap);	if (ret)		eap_server_method_free(eap);	return ret;}#endif /* EAP_AKA_PRIME */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?