Esempio n. 1
0
static struct wpabuf * p2p_group_build_probe_resp_ie(struct p2p_group *group)
{
	struct wpabuf *p2p_subelems, *ie;
	struct p2p_group_member *m;

	p2p_subelems = wpabuf_alloc(500);
	if (p2p_subelems == NULL)
		return NULL;

	p2p_group_add_common_ies(group, p2p_subelems);
	p2p_group_add_noa(p2p_subelems, group->noa);

	/* P2P Device Info */
	p2p_buf_add_device_info(p2p_subelems, group->p2p, NULL);

	/* P2P Group Info: Only when at least one P2P Client is connected */
	if (group->members) {
		u8 *group_info;
		group_info = wpabuf_put(p2p_subelems, 0);
		wpabuf_put_u8(p2p_subelems, P2P_ATTR_GROUP_INFO);
		wpabuf_put_le16(p2p_subelems, 0); /* Length to be filled */
		for (m = group->members; m; m = m->next)
			p2p_client_info(p2p_subelems, m);
		WPA_PUT_LE16(group_info + 1,
			     (u8 *) wpabuf_put(p2p_subelems, 0) - group_info -
			     3);
	}

	ie = p2p_group_encaps_probe_resp(p2p_subelems);
	wpabuf_free(p2p_subelems);

#ifdef CONFIG_WIFI_DISPLAY
	if (group->wfd_ie) {
		struct wpabuf *wfd = wpabuf_dup(group->wfd_ie);
		ie = wpabuf_concat(wfd, ie);
	}
#endif /* CONFIG_WIFI_DISPLAY */

	return ie;
}
Esempio n. 2
0
static struct wpabuf * eap_fast_buildReq(struct eap_sm *sm, void *priv, u8 id)
{
	struct eap_fast_data *data = priv;
	struct wpabuf *req = NULL;
	int piggyback = 0;

	if (data->ssl.state == FRAG_ACK) {
		return eap_server_tls_build_ack(id, EAP_TYPE_FAST,
						data->fast_version);
	}

	if (data->ssl.state == WAIT_FRAG_ACK) {
		return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_FAST,
						data->fast_version, id);
	}

	switch (data->state) {
	case START:
		return eap_fast_build_start(sm, data, id);
	case PHASE1:
		if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
			if (eap_fast_phase1_done(sm, data) < 0)
				return NULL;
			if (data->state == PHASE2_START) {
				/*
				 * Try to generate Phase 2 data to piggyback
				 * with the end of Phase 1 to avoid extra
				 * roundtrip.
				 */
				wpa_printf(MSG_DEBUG, "EAP-FAST: Try to start "
					   "Phase 2");
				if (eap_fast_process_phase2_start(sm, data))
					break;
				req = eap_fast_build_phase2_req(sm, data, id);
				piggyback = 1;
			}
		}
		break;
	case PHASE2_ID:
	case PHASE2_METHOD:
		req = eap_fast_build_phase2_req(sm, data, id);
		break;
	case CRYPTO_BINDING:
		req = eap_fast_build_crypto_binding(sm, data);
		if (data->phase2_method) {
			/*
			 * Include the start of the next EAP method in the
			 * sequence in the same message with Crypto-Binding to
			 * save a round-trip.
			 */
			struct wpabuf *eap;
			eap = eap_fast_build_phase2_req(sm, data, id);
			req = wpabuf_concat(req, eap);
			eap_fast_state(data, PHASE2_METHOD);
		}
		break;
	case REQUEST_PAC:
		req = eap_fast_build_pac(sm, data);
		break;
	default:
		wpa_printf(MSG_DEBUG, "EAP-FAST: %s - unexpected state %d",
			   __func__, data->state);
		return NULL;
	}

	if (req &&
	    eap_fast_encrypt_phase2(sm, data, req, piggyback) < 0)
		return NULL;

	return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_FAST,
					data->fast_version, id);
}
Esempio n. 3
0
static int eap_fast_process_decrypted(struct eap_sm *sm,
				      struct eap_fast_data *data,
				      struct eap_method_ret *ret,
				      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);
}
struct wpabuf * ndef_build_wifi_hr(void)
{
	struct wpabuf *rn, *cr, *ac_payload, *ac, *hr_payload, *hr;
	struct wpabuf *hc;

	rn = wpabuf_alloc(2);
	if (rn == NULL)
		return NULL;
	wpabuf_put_be16(rn, os_random() & 0xffff);

	cr = ndef_build_record(FLAG_MESSAGE_BEGIN | FLAG_TNF_NFC_FORUM, "cr", 2,
			       NULL, 0, rn);
	wpabuf_free(rn);

	if (cr == NULL)
		return NULL;

	ac_payload = wpabuf_alloc(4);
	if (ac_payload == NULL) {
		wpabuf_free(cr);
		return NULL;
	}
	wpabuf_put_u8(ac_payload, 0x01); /* Carrier Flags: CRS=1 "active" */
	wpabuf_put_u8(ac_payload, 0x01); /* Carrier Data Reference Length */
	wpabuf_put_u8(ac_payload, '0'); /* Carrier Data Reference: "0" */
	wpabuf_put_u8(ac_payload, 0); /* Aux Data Reference Count */

	ac = ndef_build_record(FLAG_MESSAGE_END | FLAG_TNF_NFC_FORUM, "ac", 2,
			       NULL, 0, ac_payload);
	wpabuf_free(ac_payload);
	if (ac == NULL) {
		wpabuf_free(cr);
		return NULL;
	}

	hr_payload = wpabuf_alloc(1 + wpabuf_len(cr) + wpabuf_len(ac));
	if (hr_payload == NULL) {
		wpabuf_free(cr);
		wpabuf_free(ac);
		return NULL;
	}

	wpabuf_put_u8(hr_payload, 0x12); /* Connection Handover Version 1.2 */
	wpabuf_put_buf(hr_payload, cr);
	wpabuf_put_buf(hr_payload, ac);
	wpabuf_free(cr);
	wpabuf_free(ac);

	hr = ndef_build_record(FLAG_MESSAGE_BEGIN | FLAG_TNF_NFC_FORUM, "Hr", 2,
			       NULL, 0, hr_payload);
	wpabuf_free(hr_payload);
	if (hr == NULL)
		return NULL;

	hc = ndef_build_wifi_hc(0);
	if (hc == NULL) {
		wpabuf_free(hr);
		return NULL;
	}

	return wpabuf_concat(hr, hc);
}