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

📄 eap_fast.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
				      const struct eap_hdr *req,				      struct wpabuf *decrypted,				      struct wpabuf **out_data){	struct wpabuf *resp = NULL, *tmp;	struct eap_fast_tlv_parse tlv;	int failed = 0;	if (eap_fast_parse_decrypted(decrypted, &tlv, &resp) < 0)		return 0;	if (resp)		return eap_fast_encrypt_response(sm, data, resp,						 req->identifier, out_data);	if (tlv.result == EAP_TLV_RESULT_FAILURE) {		resp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 0);		return eap_fast_encrypt_response(sm, data, resp,						 req->identifier, out_data);	}	if (tlv.iresult == EAP_TLV_RESULT_FAILURE) {		resp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 1);		return eap_fast_encrypt_response(sm, data, resp,						 req->identifier, out_data);	}	if (tlv.crypto_binding) {		tmp = eap_fast_process_crypto_binding(sm, data, ret,						      tlv.crypto_binding,						      tlv.crypto_binding_len);		if (tmp == NULL)			failed = 1;		else			resp = wpabuf_concat(resp, tmp);	}	if (tlv.iresult == EAP_TLV_RESULT_SUCCESS) {		tmp = eap_fast_tlv_result(failed ? EAP_TLV_RESULT_FAILURE :					  EAP_TLV_RESULT_SUCCESS, 1);		resp = wpabuf_concat(resp, tmp);	}	if (tlv.eap_payload_tlv) {		tmp = eap_fast_process_eap_payload_tlv(			sm, data, ret, req, tlv.eap_payload_tlv,			tlv.eap_payload_tlv_len);		resp = wpabuf_concat(resp, tmp);	}	if (tlv.pac && tlv.result != EAP_TLV_RESULT_SUCCESS) {		wpa_printf(MSG_DEBUG, "EAP-FAST: PAC TLV without Result TLV "			   "acknowledging success");		failed = 1;	} else if (tlv.pac && tlv.result == EAP_TLV_RESULT_SUCCESS) {		tmp = eap_fast_process_pac(sm, data, ret, tlv.pac,					   tlv.pac_len);		resp = wpabuf_concat(resp, tmp);	}	if (data->current_pac == NULL && data->provisioning &&	    !data->anon_provisioning && !tlv.pac &&	    (tlv.iresult == EAP_TLV_RESULT_SUCCESS ||	     tlv.result == EAP_TLV_RESULT_SUCCESS)) {		/*		 * Need to request Tunnel PAC when using authenticated		 * provisioning.		 */		wpa_printf(MSG_DEBUG, "EAP-FAST: Request Tunnel PAC");		tmp = eap_fast_pac_request();		resp = wpabuf_concat(resp, tmp);	}	if (tlv.result == EAP_TLV_RESULT_SUCCESS && !failed) {		tmp = eap_fast_tlv_result(EAP_TLV_RESULT_SUCCESS, 0);		resp = wpabuf_concat(tmp, resp);	} else if (failed) {		tmp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 0);		resp = wpabuf_concat(tmp, resp);	}	if (resp && tlv.result == EAP_TLV_RESULT_SUCCESS && !failed &&	    tlv.crypto_binding && data->phase2_success) {		if (data->anon_provisioning) {			wpa_printf(MSG_DEBUG, "EAP-FAST: Unauthenticated "				   "provisioning completed successfully.");			ret->methodState = METHOD_DONE;			ret->decision = DECISION_FAIL;		} else {			wpa_printf(MSG_DEBUG, "EAP-FAST: Authentication "				   "completed successfully.");			if (data->provisioning)				ret->methodState = METHOD_MAY_CONT;			else				ret->methodState = METHOD_DONE;			ret->decision = DECISION_UNCOND_SUCC;		}	}	if (resp == NULL) {		wpa_printf(MSG_DEBUG, "EAP-FAST: No recognized TLVs - send "			   "empty response packet");		resp = wpabuf_alloc(1);	}	return eap_fast_encrypt_response(sm, data, resp, req->identifier,					 out_data);}static int eap_fast_decrypt(struct eap_sm *sm, struct eap_fast_data *data,			    struct eap_method_ret *ret,			    const struct eap_hdr *req,			    const struct wpabuf *in_data,			    struct wpabuf **out_data){	struct wpabuf *in_decrypted;	int res;	wpa_printf(MSG_DEBUG, "EAP-FAST: Received %lu bytes encrypted data for"		   " Phase 2", (unsigned long) wpabuf_len(in_data));	if (data->pending_phase2_req) {		wpa_printf(MSG_DEBUG, "EAP-FAST: Pending Phase 2 request - "			   "skip decryption and use old data");		/* Clear TLS reassembly state. */		eap_peer_tls_reset_input(&data->ssl);		in_decrypted = data->pending_phase2_req;		data->pending_phase2_req = NULL;		goto continue_req;	}	if (wpabuf_len(in_data) == 0) {		/* Received TLS ACK - requesting more fragments */		return eap_peer_tls_encrypt(sm, &data->ssl, EAP_TYPE_FAST,					    data->fast_version,					    req->identifier, NULL, out_data);	}	res = eap_peer_tls_decrypt(sm, &data->ssl, in_data, &in_decrypted);	if (res)		return res;continue_req:	wpa_hexdump_buf(MSG_MSGDUMP, "EAP-FAST: Decrypted Phase 2 TLV(s)",			in_decrypted);	if (wpabuf_len(in_decrypted) < 4) {		wpa_printf(MSG_INFO, "EAP-FAST: Too short Phase 2 "			   "TLV frame (len=%lu)",			   (unsigned long) wpabuf_len(in_decrypted));		wpabuf_free(in_decrypted);		return -1;	}	res = eap_fast_process_decrypted(sm, data, ret, req,					 in_decrypted, out_data);	wpabuf_free(in_decrypted);	return res;}static const u8 * eap_fast_get_a_id(const u8 *buf, size_t len, size_t *id_len){	const u8 *a_id;	struct pac_tlv_hdr *hdr;	/*	 * Parse authority identity (A-ID) from the EAP-FAST/Start. This	 * supports both raw A-ID and one inside an A-ID TLV.	 */	a_id = buf;	*id_len = len;	if (len > sizeof(*hdr)) {		int tlen;		hdr = (struct pac_tlv_hdr *) buf;		tlen = be_to_host16(hdr->len);		if (be_to_host16(hdr->type) == PAC_TYPE_A_ID &&		    sizeof(*hdr) + tlen <= len) {			wpa_printf(MSG_DEBUG, "EAP-FAST: A-ID was in TLV "				   "(Start)");			a_id = (u8 *) (hdr + 1);			*id_len = tlen;		}	}	wpa_hexdump_ascii(MSG_DEBUG, "EAP-FAST: A-ID", a_id, *id_len);	return a_id;}static void eap_fast_select_pac(struct eap_fast_data *data,				const u8 *a_id, size_t a_id_len){	data->current_pac = eap_fast_get_pac(data->pac, a_id, a_id_len,					     PAC_TYPE_TUNNEL_PAC);	if (data->current_pac == NULL) {		/*		 * Tunnel PAC was not available for this A-ID. Try to use		 * Machine Authentication PAC, if one is available.		 */		data->current_pac = eap_fast_get_pac(			data->pac, a_id, a_id_len,			PAC_TYPE_MACHINE_AUTHENTICATION);	}	if (data->current_pac) {		wpa_printf(MSG_DEBUG, "EAP-FAST: PAC found for this A-ID "			   "(PAC-Type %d)", data->current_pac->pac_type);		wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-FAST: A-ID-Info",				  data->current_pac->a_id_info,				  data->current_pac->a_id_info_len);	}}static int eap_fast_use_pac_opaque(struct eap_sm *sm,				   struct eap_fast_data *data,				   struct eap_fast_pac *pac){	u8 *tlv;	size_t tlv_len, olen;	struct eap_tlv_hdr *ehdr;	olen = pac->pac_opaque_len;	tlv_len = sizeof(*ehdr) + olen;	tlv = os_malloc(tlv_len);	if (tlv) {		ehdr = (struct eap_tlv_hdr *) tlv;		ehdr->tlv_type = host_to_be16(PAC_TYPE_PAC_OPAQUE);		ehdr->length = host_to_be16(olen);		os_memcpy(ehdr + 1, pac->pac_opaque, olen);	}	if (tlv == NULL ||	    tls_connection_client_hello_ext(sm->ssl_ctx, data->ssl.conn,					    TLS_EXT_PAC_OPAQUE,					    tlv, tlv_len) < 0) {		wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to add PAC-Opaque TLS "			   "extension");		os_free(tlv);		return -1;	}	os_free(tlv);	return 0;}static int eap_fast_clear_pac_opaque_ext(struct eap_sm *sm,					 struct eap_fast_data *data){	if (tls_connection_client_hello_ext(sm->ssl_ctx, data->ssl.conn,					    TLS_EXT_PAC_OPAQUE, NULL, 0) < 0) {		wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to remove PAC-Opaque "			   "TLS extension");		return -1;	}	return 0;}static int eap_fast_set_provisioning_ciphers(struct eap_sm *sm,					     struct eap_fast_data *data){	u8 ciphers[5];	int count = 0;	if (data->provisioning_allowed & EAP_FAST_PROV_UNAUTH) {		wpa_printf(MSG_DEBUG, "EAP-FAST: Enabling unauthenticated "			   "provisioning TLS cipher suites");		ciphers[count++] = TLS_CIPHER_ANON_DH_AES128_SHA;	}	if (data->provisioning_allowed & EAP_FAST_PROV_AUTH) {		wpa_printf(MSG_DEBUG, "EAP-FAST: Enabling authenticated "			   "provisioning TLS cipher suites");		ciphers[count++] = TLS_CIPHER_RSA_DHE_AES128_SHA;		ciphers[count++] = TLS_CIPHER_AES128_SHA;		ciphers[count++] = TLS_CIPHER_RC4_SHA;	}	ciphers[count++] = TLS_CIPHER_NONE;	if (tls_connection_set_cipher_list(sm->ssl_ctx, data->ssl.conn,					   ciphers)) {		wpa_printf(MSG_INFO, "EAP-FAST: Could not configure TLS "			   "cipher suites for provisioning");		return -1;	}	return 0;}static int eap_fast_process_start(struct eap_sm *sm,				  struct eap_fast_data *data, u8 flags,				  const u8 *pos, size_t left){	const u8 *a_id;	size_t a_id_len;	/* EAP-FAST Version negotiation (section 3.1) */	wpa_printf(MSG_DEBUG, "EAP-FAST: Start (server ver=%d, own ver=%d)",		   flags & EAP_PEAP_VERSION_MASK, data->fast_version);	if ((flags & EAP_PEAP_VERSION_MASK) < data->fast_version)		data->fast_version = flags & EAP_PEAP_VERSION_MASK;	wpa_printf(MSG_DEBUG, "EAP-FAST: Using FAST version %d",		   data->fast_version);	a_id = eap_fast_get_a_id(pos, left, &a_id_len);	eap_fast_select_pac(data, a_id, a_id_len);	if (data->resuming && data->current_pac) {		wpa_printf(MSG_DEBUG, "EAP-FAST: Trying to resume session - "			   "do not add PAC-Opaque to TLS ClientHello");		if (eap_fast_clear_pac_opaque_ext(sm, data) < 0)			return -1;	} else if (data->current_pac) {		/*		 * PAC found for the A-ID and we are not resuming an old		 * session, so add PAC-Opaque extension to ClientHello.		 */		if (eap_fast_use_pac_opaque(sm, data, data->current_pac) < 0)			return -1;	} else {		/* No PAC found, so we must provision one. */		if (!data->provisioning_allowed) {			wpa_printf(MSG_DEBUG, "EAP-FAST: No PAC found and "				   "provisioning disabled");			return -1;		}		wpa_printf(MSG_DEBUG, "EAP-FAST: No PAC found - "			   "starting provisioning");		if (eap_fast_set_provisioning_ciphers(sm, data) < 0 ||		    eap_fast_clear_pac_opaque_ext(sm, data) < 0)			return -1;		data->provisioning = 1;	}	return 0;}static struct wpabuf * eap_fast_process(struct eap_sm *sm, void *priv,					struct eap_method_ret *ret,					const struct wpabuf *reqData){	const struct eap_hdr *req;	size_t left;	int res;	u8 flags, id;	struct wpabuf *resp;	const u8 *pos;	struct eap_fast_data *data = priv;	pos = eap_peer_tls_process_init(sm, &data->ssl, EAP_TYPE_FAST, ret,					reqData, &left, &flags);	if (pos == NULL)		return NULL;	req = wpabuf_head(reqData);	id = req->identifier;	if (flags & EAP_TLS_FLAGS_START) {		if (eap_fast_process_start(sm, data, flags, pos, left) < 0)			return NULL;		left = 0; /* A-ID is not used in further packet processing */	}	resp = NULL;	if (tls_connection_established(sm->ssl_ctx, data->ssl.conn) &&	    !data->resuming) {		/* Process tunneled (encrypted) phase 2 data. */		struct wpabuf msg;		wpabuf_set(&msg, pos, left);		res = eap_fast_decrypt(sm, data, ret, req, &msg, &resp);		if (res < 0) {			ret->methodState = METHOD_DONE;			ret->decision = DECISION_FAIL;			/*			 * Ack possible Alert that may have caused failure in			 * decryption.			 */			res = 1;		}	} else {		/* Continue processing TLS handshake (phase 1). */		res = eap_peer_tls_process_helper(sm, &data->ssl,						  EAP_TYPE_FAST,						  data->fast_version, id, pos,						  left, &resp);		if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {			char cipher[80];			wpa_printf(MSG_DEBUG,				   "EAP-FAST: TLS done, proceed to Phase 2");			if (data->provisioning &&			    (!(data->provisioning_allowed &			       EAP_FAST_PROV_AUTH) ||			     tls_get_cipher(sm->ssl_ctx, data->ssl.conn,					    cipher, sizeof(cipher)) < 0 ||			     os_strstr(cipher, "ADH-") ||			     os_strstr(cipher, "anon"))) {				wpa_printf(MSG_DEBUG, "EAP-FAST: Using "					   "anonymous (unauthenticated) "					   "provisioning");				data->anon_provisioning = 1;			} else				data->anon_provisioning = 0;			data->resuming = 0;			eap_fast_derive_keys(sm, data);		}		if (res == 2) {			struct wpabuf msg;			/*			 * Application data included in the handshake message.			 */			wpabuf_free(data->pending_phase2_req);			data->pending_phase2_req = resp;			resp = NULL;			wpabuf_set(&msg, pos, left);			res = eap_fast_decrypt(sm, data, ret, req, &msg,					       &resp);		}	}	if (res == 1) {		wpabuf_free(resp);		return eap_peer_tls_build_ack(id, EAP_TYPE_FAST,					      data->fast_version);	}	return resp;}#if 0 /* FIX */static Boolean eap_fast_has_reauth_data(struct eap_sm *sm, void *priv){	struct eap_fast_data *data = priv;	return tls_connection_established(sm->ssl_ctx, data->ssl.conn);}static void eap_fast_deinit_for_reauth(struct eap_sm *sm, void *priv){	struct eap_fast_data *data = priv;	os_free(data->key_block_p);	data->key_block_p = NULL;	wpabuf_free(data->pending_phase2_req);	data->pending_phase2_req = NULL;}static void * eap_fast_init_for_reauth(struct eap_sm *sm, void *priv){	struct eap_fast_data *data = priv;	if (eap_peer_tls_reauth_init(sm, &data->ssl)) {		os_free(data);		return NULL;	}	if (data->phase2_priv && data->phase2_method &&	    data->phase2_method->init_for_reauth)		data->phase2_method->init_for_reauth(sm, data->phase2_priv);	data->phase2_success = 0;	data->resuming = 1;	data->provisioning = 0;	data->anon_provisioning = 0;	data->simck_idx = 0;	return priv;}#endifstatic int eap_fast_get_status(struct eap_sm *sm, void *priv, char *buf,			       size_t buflen, int verbose){	struct eap_fast_data *data = priv;	int len, ret;	len = eap_peer_tls_status(sm, &data->ssl, buf, buflen, verbose);	if (data->phase2_method) {		ret = os_snprintf(buf + len, buflen - len,				  "EAP-FAST Phase2 method=%s\n",				  data->phase2_method->name);		if (ret < 0 || (size_t) ret >= buflen - len)			return len;		len += ret;	}	return len;}static Boolean eap_fast_isKeyAvailable(struct eap_sm *sm, void *priv){	struct eap_fast_data *data = priv;	return data->success;}static u8 * eap_fast_getKey(struct eap_sm *sm, void *priv, size_t *len){	struct eap_fast_data *data = priv;	u8 *key;	if (!data->success)		return NULL;	key = os_malloc(EAP_FAST_KEY_LEN);	if (key == NULL)		return NULL;	*len = EAP_FAST_KEY_LEN;	os_memcpy(key, data->key_data, EAP_FAST_KEY_LEN);	return key;}static u8 * eap_fast_get_emsk(struct eap_sm *sm, void *priv, size_t *len){	struct eap_fast_data *data = priv;	u8 *key;	if (!data->success)		return NULL;	key = os_malloc(EAP_EMSK_LEN);	if (key == NULL)		return NULL;	*len = EAP_EMSK_LEN;	os_memcpy(key, data->emsk, EAP_EMSK_LEN);	return key;}int eap_peer_fast_register(void){	struct eap_method *eap;	int ret;	eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,				    EAP_VENDOR_IETF, EAP_TYPE_FAST, "FAST");	if (eap == NULL)		return -1;	eap->init = eap_fast_init;	eap->deinit = eap_fast_deinit;	eap->process = eap_fast_process;	eap->isKeyAvailable = eap_fast_isKeyAvailable;	eap->getKey = eap_fast_getKey;	eap->get_status = eap_fast_get_status;#if 0	eap->has_reauth_data = eap_fast_has_reauth_data;	eap->deinit_for_reauth = eap_fast_deinit_for_reauth;	eap->init_for_reauth = eap_fast_init_for_reauth;#endif	eap->get_emsk = eap_fast_get_emsk;	ret = eap_peer_method_register(eap);	if (ret)		eap_peer_method_free(eap);	return ret;}

⌨️ 快捷键说明

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