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

📄 eap_fast.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
	switch (hdr->code) {	case EAP_CODE_RESPONSE:		eap_fast_process_phase2_response(sm, data, (u8 *) hdr, len);		break;	default:		wpa_printf(MSG_INFO, "EAP-FAST: Unexpected code=%d in "			   "Phase 2 EAP header", hdr->code);		break;	}}static int eap_fast_parse_tlvs(u8 *data, size_t data_len,			       struct eap_fast_tlv_parse *tlv){	int mandatory, tlv_type, len, res;	u8 *pos, *end;	os_memset(tlv, 0, sizeof(*tlv));	pos = data;	end = data + data_len;	while (pos + 4 < end) {		mandatory = pos[0] & 0x80;		tlv_type = WPA_GET_BE16(pos) & 0x3fff;		pos += 2;		len = WPA_GET_BE16(pos);		pos += 2;		if (pos + len > end) {			wpa_printf(MSG_INFO, "EAP-FAST: TLV overflow");			return -1;		}		wpa_printf(MSG_DEBUG, "EAP-FAST: Received Phase 2: "			   "TLV type %d length %d%s",			   tlv_type, len, mandatory ? " (mandatory)" : "");		res = eap_fast_parse_tlv(tlv, tlv_type, pos, len);		if (res == -2)			break;		if (res < 0) {			if (mandatory) {				wpa_printf(MSG_DEBUG, "EAP-FAST: Nak unknown "					   "mandatory TLV type %d", tlv_type);				/* TODO: generate Nak TLV */				break;			} else {				wpa_printf(MSG_DEBUG, "EAP-FAST: Ignored "					   "unknown optional TLV type %d",					   tlv_type);			}		}		pos += len;	}	return 0;}static int eap_fast_validate_crypto_binding(	struct eap_fast_data *data, struct eap_tlv_crypto_binding_tlv *b,	size_t bind_len){	u8 cmac[SHA1_MAC_LEN];	wpa_printf(MSG_DEBUG, "EAP-FAST: Reply Crypto-Binding TLV: "		   "Version %d Received Version %d SubType %d",		   b->version, b->received_version, b->subtype);	wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: NONCE",		    b->nonce, sizeof(b->nonce));	wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Compound MAC",		    b->compound_mac, sizeof(b->compound_mac));	if (b->version != EAP_FAST_VERSION ||	    b->received_version != EAP_FAST_VERSION) {		wpa_printf(MSG_DEBUG, "EAP-FAST: Unexpected version "			   "in Crypto-Binding: version %d "			   "received_version %d", b->version,			   b->received_version);		return -1;	}	if (b->subtype != EAP_TLV_CRYPTO_BINDING_SUBTYPE_RESPONSE) {		wpa_printf(MSG_DEBUG, "EAP-FAST: Unexpected subtype in "			   "Crypto-Binding: %d", b->subtype);		return -1;	}	if (os_memcmp(data->crypto_binding_nonce, b->nonce, 31) != 0 ||	    (data->crypto_binding_nonce[31] | 1) != b->nonce[31]) {		wpa_printf(MSG_DEBUG, "EAP-FAST: Invalid nonce in "			   "Crypto-Binding");		return -1;	}	os_memcpy(cmac, b->compound_mac, sizeof(cmac));	os_memset(b->compound_mac, 0, sizeof(cmac));	wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Crypto-Binding TLV for "		    "Compound MAC calculation",		    (u8 *) b, bind_len);	hmac_sha1(data->cmk, EAP_FAST_CMK_LEN, (u8 *) b, bind_len,		  b->compound_mac);	if (os_memcmp(cmac, b->compound_mac, sizeof(cmac)) != 0) {		wpa_hexdump(MSG_MSGDUMP,			    "EAP-FAST: Calculated Compound MAC",			    b->compound_mac, sizeof(cmac));		wpa_printf(MSG_INFO, "EAP-FAST: Compound MAC did not "			   "match");		return -1;	}	return 0;}static int eap_fast_pac_type(u8 *pac, size_t len, u16 type){	struct eap_tlv_pac_type_tlv *tlv;	if (pac == NULL || len != sizeof(*tlv))		return 0;	tlv = (struct eap_tlv_pac_type_tlv *) pac;	return be_to_host16(tlv->tlv_type) == PAC_TYPE_PAC_TYPE &&		be_to_host16(tlv->length) == 2 &&		be_to_host16(tlv->pac_type) == type;}static void eap_fast_process_phase2_tlvs(struct eap_sm *sm,					 struct eap_fast_data *data,					 u8 *in_data, size_t in_len){	struct eap_fast_tlv_parse tlv;	int check_crypto_binding = data->state == CRYPTO_BINDING;	if (eap_fast_parse_tlvs(in_data, in_len, &tlv) < 0) {		wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to parse received "			   "Phase 2 TLVs");		return;	}	if (tlv.result == EAP_TLV_RESULT_FAILURE) {		wpa_printf(MSG_DEBUG, "EAP-FAST: Result TLV indicated "			   "failure");		eap_fast_state(data, FAILURE);		return;	}	if (data->state == REQUEST_PAC) {		u16 type, len, res;		if (tlv.pac == NULL || tlv.pac_len < 6) {			wpa_printf(MSG_DEBUG, "EAP-FAST: No PAC "				   "Acknowledgement received");			eap_fast_state(data, FAILURE);			return;		}		type = WPA_GET_BE16(tlv.pac);		len = WPA_GET_BE16(tlv.pac + 2);		res = WPA_GET_BE16(tlv.pac + 4);		if (type != PAC_TYPE_PAC_ACKNOWLEDGEMENT || len != 2 ||		    res != EAP_TLV_RESULT_SUCCESS) {			wpa_printf(MSG_DEBUG, "EAP-FAST: PAC TLV did not "				   "contain acknowledgement");			eap_fast_state(data, FAILURE);			return;		}		wpa_printf(MSG_DEBUG, "EAP-FAST: PAC-Acknowledgement received "			   "- PAC provisioning succeeded");		eap_fast_state(data, (data->anon_provisioning ||				      data->send_new_pac == 2) ?			       FAILURE : SUCCESS);		return;	}	if (check_crypto_binding) {		if (tlv.crypto_binding == NULL) {			wpa_printf(MSG_DEBUG, "EAP-FAST: No Crypto-Binding "				   "TLV received");			eap_fast_state(data, FAILURE);			return;		}		if (data->final_result &&		    tlv.result != EAP_TLV_RESULT_SUCCESS) {			wpa_printf(MSG_DEBUG, "EAP-FAST: Crypto-Binding TLV "				   "without Success Result");			eap_fast_state(data, FAILURE);			return;		}		if (!data->final_result &&		    tlv.iresult != EAP_TLV_RESULT_SUCCESS) {			wpa_printf(MSG_DEBUG, "EAP-FAST: Crypto-Binding TLV "				   "without intermediate Success Result");			eap_fast_state(data, FAILURE);			return;		}		if (eap_fast_validate_crypto_binding(data, tlv.crypto_binding,						     tlv.crypto_binding_len)) {			eap_fast_state(data, FAILURE);			return;		}		wpa_printf(MSG_DEBUG, "EAP-FAST: Valid Crypto-Binding TLV "			   "received");		if (data->final_result) {			wpa_printf(MSG_DEBUG, "EAP-FAST: Authentication "				   "completed successfully");		}		if (data->anon_provisioning &&		    sm->eap_fast_prov != ANON_PROV &&		    sm->eap_fast_prov != BOTH_PROV) {			wpa_printf(MSG_DEBUG, "EAP-FAST: Client is trying to "				   "use unauthenticated provisioning which is "				   "disabled");			eap_fast_state(data, FAILURE);			return;		}		if (sm->eap_fast_prov != AUTH_PROV &&		    sm->eap_fast_prov != BOTH_PROV &&		    tlv.request_action == EAP_TLV_ACTION_PROCESS_TLV &&		    eap_fast_pac_type(tlv.pac, tlv.pac_len,				      PAC_TYPE_TUNNEL_PAC)) {			wpa_printf(MSG_DEBUG, "EAP-FAST: Client is trying to "				   "use authenticated provisioning which is "				   "disabled");			eap_fast_state(data, FAILURE);			return;		}		if (data->anon_provisioning ||		    (tlv.request_action == EAP_TLV_ACTION_PROCESS_TLV &&		     eap_fast_pac_type(tlv.pac, tlv.pac_len,				       PAC_TYPE_TUNNEL_PAC))) {			wpa_printf(MSG_DEBUG, "EAP-FAST: Requested a new "				   "Tunnel PAC");			eap_fast_state(data, REQUEST_PAC);		} else if (data->send_new_pac) {			wpa_printf(MSG_DEBUG, "EAP-FAST: Server triggered "				   "re-keying of Tunnel PAC");			eap_fast_state(data, REQUEST_PAC);		} else if (data->final_result)			eap_fast_state(data, SUCCESS);	}	if (tlv.eap_payload_tlv) {		eap_fast_process_phase2_eap(sm, data, tlv.eap_payload_tlv,					    tlv.eap_payload_tlv_len);	}}static void eap_fast_process_phase2(struct eap_sm *sm,				    struct eap_fast_data *data,				    struct wpabuf *in_buf){	u8 *in_decrypted;	int len_decrypted;	size_t buf_len;	u8 *in_data;	size_t in_len;	in_data = wpabuf_mhead(in_buf);	in_len = wpabuf_len(in_buf);	wpa_printf(MSG_DEBUG, "EAP-FAST: Received %lu bytes encrypted data for"		   " Phase 2", (unsigned long) in_len);	if (data->pending_phase2_resp) {		wpa_printf(MSG_DEBUG, "EAP-PEAP: Pending Phase 2 response - "			   "skip decryption and use old data");		eap_fast_process_phase2_tlvs(			sm, data, wpabuf_mhead(data->pending_phase2_resp),			wpabuf_len(data->pending_phase2_resp));		wpabuf_free(data->pending_phase2_resp);		data->pending_phase2_resp = NULL;		return;	}	buf_len = in_len;	/*	 * Even though we try to disable TLS compression, it is possible that	 * this cannot be done with all TLS libraries. Add extra buffer space	 * to handle the possibility of the decrypted data being longer than	 * input data.	 */	buf_len += 500;	buf_len *= 3;	in_decrypted = os_malloc(buf_len);	if (in_decrypted == NULL) {		wpa_printf(MSG_WARNING, "EAP-FAST: Failed to allocate memory "			   "for decryption");		return;	}	len_decrypted = tls_connection_decrypt(sm->ssl_ctx, data->ssl.conn,					       in_data, in_len,					       in_decrypted, buf_len);	if (len_decrypted < 0) {		wpa_printf(MSG_INFO, "EAP-FAST: Failed to decrypt Phase 2 "			   "data");		os_free(in_decrypted);		eap_fast_state(data, FAILURE);		return;	}	wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: Decrypted Phase 2 TLVs",			in_decrypted, len_decrypted);	eap_fast_process_phase2_tlvs(sm, data, in_decrypted, len_decrypted);	if (sm->method_pending == METHOD_PENDING_WAIT) {		wpa_printf(MSG_DEBUG, "EAP-FAST: Phase2 method is in "			   "pending wait state - save decrypted response");		wpabuf_free(data->pending_phase2_resp);		data->pending_phase2_resp = wpabuf_alloc_copy(in_decrypted,							      len_decrypted);	}	os_free(in_decrypted);}static int eap_fast_process_version(struct eap_sm *sm, void *priv,				    int peer_version){	struct eap_fast_data *data = priv;	data->peer_version = peer_version;	if (data->force_version >= 0 && peer_version != data->force_version) {		wpa_printf(MSG_INFO, "EAP-FAST: peer did not select the forced"			   " version (forced=%d peer=%d) - reject",			   data->force_version, peer_version);		return -1;	}	if (peer_version < data->fast_version) {		wpa_printf(MSG_DEBUG, "EAP-FAST: peer ver=%d, own ver=%d; "			   "use version %d",			   peer_version, data->fast_version, peer_version);		data->fast_version = peer_version;	}	return 0;}static int eap_fast_process_phase1(struct eap_sm *sm,				   struct eap_fast_data *data){	if (eap_server_tls_phase1(sm, &data->ssl) < 0) {		wpa_printf(MSG_INFO, "EAP-FAST: TLS processing failed");		eap_fast_state(data, FAILURE);		return -1;	}	if (!tls_connection_established(sm->ssl_ctx, data->ssl.conn) ||	    wpabuf_len(data->ssl.out_buf) > 0)		return 1;	/*	 * Phase 1 was completed with the received message (e.g., when using	 * abbreviated handshake), so Phase 2 can be started immediately	 * without having to send through an empty message to the peer.	 */	return eap_fast_phase1_done(sm, data);}static void eap_fast_process_phase2_start(struct eap_sm *sm,					  struct eap_fast_data *data){	u8 next_type;	if (data->identity) {		os_free(sm->identity);		sm->identity = data->identity;		data->identity = NULL;		sm->identity_len = data->identity_len;		data->identity_len = 0;		sm->require_identity_match = 1;		if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) {			wpa_hexdump_ascii(MSG_DEBUG, "EAP-FAST: "					  "Phase2 Identity not found "					  "in the user database",					  sm->identity, sm->identity_len);			next_type = eap_fast_req_failure(sm, data);		} else {			wpa_printf(MSG_DEBUG, "EAP-FAST: Identity already "				   "known - skip Phase 2 Identity Request");			next_type = sm->user->methods[0].method;			sm->user_eap_method_index = 1;		}		eap_fast_state(data, PHASE2_METHOD);	} else {		eap_fast_state(data, PHASE2_ID);		next_type = EAP_TYPE_IDENTITY;	}	eap_fast_phase2_init(sm, data, next_type);}static void eap_fast_process_msg(struct eap_sm *sm, void *priv,				 const struct wpabuf *respData){	struct eap_fast_data *data = priv;	switch (data->state) {	case PHASE1:		if (eap_fast_process_phase1(sm, data))			break;		/* fall through to PHASE2_START */	case PHASE2_START:		eap_fast_process_phase2_start(sm, data);		break;	case PHASE2_ID:	case PHASE2_METHOD:	case CRYPTO_BINDING:	case REQUEST_PAC:		eap_fast_process_phase2(sm, data, data->ssl.in_buf);		break;	default:		wpa_printf(MSG_DEBUG, "EAP-FAST: Unexpected state %d in %s",			   data->state, __func__);		break;	}}static void eap_fast_process(struct eap_sm *sm, void *priv,			     struct wpabuf *respData){	struct eap_fast_data *data = priv;	if (eap_server_tls_process(sm, &data->ssl, respData, data,				   EAP_TYPE_FAST, eap_fast_process_version,				   eap_fast_process_msg) < 0)		eap_fast_state(data, FAILURE);}static Boolean eap_fast_isDone(struct eap_sm *sm, void *priv){	struct eap_fast_data *data = priv;	return data->state == SUCCESS || data->state == FAILURE;}static u8 * eap_fast_getKey(struct eap_sm *sm, void *priv, size_t *len){	struct eap_fast_data *data = priv;	u8 *eapKeyData;	if (data->state != SUCCESS)		return NULL;	eapKeyData = os_malloc(EAP_FAST_KEY_LEN);	if (eapKeyData == NULL)		return NULL;	eap_fast_derive_eap_msk(data->simck, eapKeyData);	*len = EAP_FAST_KEY_LEN;	return eapKeyData;}static u8 * eap_fast_get_emsk(struct eap_sm *sm, void *priv, size_t *len){	struct eap_fast_data *data = priv;	u8 *eapKeyData;	if (data->state != SUCCESS)		return NULL;	eapKeyData = os_malloc(EAP_EMSK_LEN);	if (eapKeyData == NULL)		return NULL;	eap_fast_derive_eap_emsk(data->simck, eapKeyData);	*len = EAP_EMSK_LEN;	return eapKeyData;}static Boolean eap_fast_isSuccess(struct eap_sm *sm, void *priv){	struct eap_fast_data *data = priv;	return data->state == SUCCESS;}int eap_server_fast_register(void){	struct eap_method *eap;	int ret;	eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,				      EAP_VENDOR_IETF, EAP_TYPE_FAST, "FAST");	if (eap == NULL)		return -1;	eap->init = eap_fast_init;	eap->reset = eap_fast_reset;	eap->buildReq = eap_fast_buildReq;	eap->check = eap_fast_check;	eap->process = eap_fast_process;	eap->isDone = eap_fast_isDone;	eap->getKey = eap_fast_getKey;	eap->get_emsk = eap_fast_get_emsk;	eap->isSuccess = eap_fast_isSuccess;	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 + -