⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eap_sim.c

📁 IEEE802.11 a/b/g 客户端应用程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (attr->identity) {		os_free(sm->identity);		sm->identity = os_malloc(attr->identity_len);		if (sm->identity) {			os_memcpy(sm->identity, attr->identity,				  attr->identity_len);			sm->identity_len = attr->identity_len;		}	}	identity = NULL;	identity_len = 0;	if (sm->identity && sm->identity_len > 0 &&	    sm->identity[0] == EAP_SIM_PERMANENT_PREFIX) {		identity = sm->identity;		identity_len = sm->identity_len;	} else {		identity = eap_sim_db_get_permanent(sm->eap_sim_db_priv,						    sm->identity,						    sm->identity_len,						    &identity_len);		if (identity == NULL) {			data->reauth = eap_sim_db_get_reauth_entry(				sm->eap_sim_db_priv, sm->identity,				sm->identity_len);			if (data->reauth) {				wpa_printf(MSG_DEBUG, "EAP-SIM: Using fast "					   "re-authentication");				identity = data->reauth->identity;				identity_len = data->reauth->identity_len;				data->counter = data->reauth->counter;				os_memcpy(data->mk, data->reauth->mk,					  EAP_SIM_MK_LEN);			}		}	}	if (identity == NULL) {		wpa_printf(MSG_DEBUG, "EAP-SIM: Could not get proper permanent"			   " user name");		eap_sim_state(data, FAILURE);		return;	}	wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM: Identity",			  identity, identity_len);	if (data->reauth) {		eap_sim_state(data, REAUTH);		return;	}	if (attr->nonce_mt == NULL || attr->selected_version < 0) {		wpa_printf(MSG_DEBUG, "EAP-SIM: Start/Response missing "			   "required attributes");		eap_sim_state(data, FAILURE);		return;	}	if (!eap_sim_supported_ver(data, attr->selected_version)) {		wpa_printf(MSG_DEBUG, "EAP-SIM: Peer selected unsupported "			   "version %d", attr->selected_version);		eap_sim_state(data, FAILURE);		return;	}	data->counter = 0; /* reset re-auth counter since this is full auth */	data->reauth = NULL;	data->num_chal = eap_sim_db_get_gsm_triplets(		sm->eap_sim_db_priv, identity, identity_len,		EAP_SIM_MAX_CHAL,		(u8 *) data->rand, (u8 *) data->kc, (u8 *) data->sres, sm);	if (data->num_chal == EAP_SIM_DB_PENDING) {		wpa_printf(MSG_DEBUG, "EAP-SIM: GSM authentication triplets "			   "not yet available - pending request");		sm->method_pending = METHOD_PENDING_WAIT;		return;	}	if (data->num_chal < 2) {		wpa_printf(MSG_INFO, "EAP-SIM: Failed to get GSM "			   "authentication triplets for the peer");		eap_sim_state(data, FAILURE);		return;	}	identity_len = sm->identity_len;	while (identity_len > 0 && sm->identity[identity_len - 1] == '\0') {		wpa_printf(MSG_DEBUG, "EAP-SIM: Workaround - drop last null "			   "character from identity");		identity_len--;	}	wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM: Identity for MK derivation",			  sm->identity, identity_len);	os_memcpy(data->nonce_mt, attr->nonce_mt, EAP_SIM_NONCE_MT_LEN);	WPA_PUT_BE16(ver_list, EAP_SIM_VERSION);	eap_sim_derive_mk(sm->identity, identity_len, attr->nonce_mt,			  attr->selected_version, ver_list, sizeof(ver_list),			  data->num_chal, (const u8 *) data->kc, data->mk);	eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut, data->msk,			    data->emsk);	eap_sim_state(data, CHALLENGE);}static void eap_sim_process_challenge(struct eap_sm *sm,				      struct eap_sim_data *data,				      struct wpabuf *respData,				      struct eap_sim_attrs *attr){	const u8 *identity;	size_t identity_len;	if (attr->mac == NULL ||	    eap_sim_verify_mac(data->k_aut, respData, attr->mac,			       (u8 *) data->sres,			       data->num_chal * EAP_SIM_SRES_LEN)) {		wpa_printf(MSG_WARNING, "EAP-SIM: Challenge message "			   "did not include valid AT_MAC");		eap_sim_state(data, FAILURE);		return;	}	wpa_printf(MSG_DEBUG, "EAP-SIM: 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_sim_state(data, NOTIFICATION);	} else		eap_sim_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) {		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_sim_process_reauth(struct eap_sm *sm,				   struct eap_sim_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;	if (attr->mac == NULL ||	    eap_sim_verify_mac(data->k_aut, respData, attr->mac, data->nonce_s,			       EAP_SIM_NONCE_S_LEN)) {		wpa_printf(MSG_WARNING, "EAP-SIM: Re-authentication message "			   "did not include valid AT_MAC");		goto fail;	}	if (attr->encr_data == NULL || attr->iv == NULL) {		wpa_printf(MSG_WARNING, "EAP-SIM: 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-SIM: Failed to parse encrypted "			   "data from reauthentication message");		goto fail;	}	if (eattr.counter != data->counter) {		wpa_printf(MSG_WARNING, "EAP-SIM: 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-SIM: Re-authentication 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_sim_state(data, NOTIFICATION);	} else		eap_sim_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) {		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:	eap_sim_state(data, FAILURE);	eap_sim_db_remove_reauth(sm->eap_sim_db_priv, data->reauth);	data->reauth = NULL;	os_free(decrypted);}static void eap_sim_process_client_error(struct eap_sm *sm,					 struct eap_sim_data *data,					 struct wpabuf *respData,					 struct eap_sim_attrs *attr){	wpa_printf(MSG_DEBUG, "EAP-SIM: Client reported error %d",		   attr->client_error_code);	if (data->notification == EAP_SIM_SUCCESS && data->use_result_ind)		eap_sim_state(data, SUCCESS);	else		eap_sim_state(data, FAILURE);}static void eap_sim_process_notification(struct eap_sm *sm,					 struct eap_sim_data *data,					 struct wpabuf *respData,					 struct eap_sim_attrs *attr){	wpa_printf(MSG_DEBUG, "EAP-SIM: Client replied to notification");	if (data->notification == EAP_SIM_SUCCESS && data->use_result_ind)		eap_sim_state(data, SUCCESS);	else		eap_sim_state(data, FAILURE);}static void eap_sim_process(struct eap_sm *sm, void *priv,			    struct wpabuf *respData){	struct eap_sim_data *data = priv;	const u8 *pos, *end;	u8 subtype;	size_t len;	struct eap_sim_attrs attr;	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_SIM, respData, &len);	if (pos == NULL || len < 3)		return;	end = pos + len;	subtype = *pos;	pos += 3;	if (eap_sim_parse_attr(pos, end, &attr, 0, 0)) {		wpa_printf(MSG_DEBUG, "EAP-SIM: Failed to parse attributes");		eap_sim_state(data, FAILURE);		return;	}	if (subtype == EAP_SIM_SUBTYPE_CLIENT_ERROR) {		eap_sim_process_client_error(sm, data, respData, &attr);		return;	}	switch (data->state) {	case START:		eap_sim_process_start(sm, data, respData, &attr);		break;	case CHALLENGE:		eap_sim_process_challenge(sm, data, respData, &attr);		break;	case REAUTH:		eap_sim_process_reauth(sm, data, respData, &attr);		break;	case NOTIFICATION:		eap_sim_process_notification(sm, data, respData, &attr);		break;	default:		wpa_printf(MSG_DEBUG, "EAP-SIM: Unknown state %d in "			   "process", data->state);		break;	}}static Boolean eap_sim_isDone(struct eap_sm *sm, void *priv){	struct eap_sim_data *data = priv;	return data->state == SUCCESS || data->state == FAILURE;}static u8 * eap_sim_getKey(struct eap_sm *sm, void *priv, size_t *len){	struct eap_sim_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_sim_get_emsk(struct eap_sm *sm, void *priv, size_t *len){	struct eap_sim_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_sim_isSuccess(struct eap_sm *sm, void *priv){	struct eap_sim_data *data = priv;	return data->state == SUCCESS;}int eap_server_sim_register(void){	struct eap_method *eap;	int ret;	eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,				      EAP_VENDOR_IETF, EAP_TYPE_SIM, "SIM");	if (eap == NULL)		return -1;	eap->init = eap_sim_init;	eap->reset = eap_sim_reset;	eap->buildReq = eap_sim_buildReq;	eap->check = eap_sim_check;	eap->process = eap_sim_process;	eap->isDone = eap_sim_isDone;	eap->getKey = eap_sim_getKey;	eap->isSuccess = eap_sim_isSuccess;	eap->get_emsk = eap_sim_get_emsk;	ret = eap_server_method_register(eap);	if (ret)		eap_server_method_free(eap);	return ret;}

⌨️ 快捷键说明

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