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; }
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); }
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); }