WPS NFC: Build new style carrier record for connection handover request
It is more useful to be able to build a single NFC carrier record instead of the full connection handover request message to allow external components to decide whether to negotiate which alternative carrier is used. This updates the carrier record contents to the new design to include Enrollee public key hash and provides this as a carrier record instead of full message. An external program is expected to be used to build the full NFC connection handover message with potentially other alternative carrier records included. Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
3f1639da57
commit
41f9ffb635
6 changed files with 40 additions and 100 deletions
|
@ -168,87 +168,3 @@ struct wpabuf * ndef_build_wifi(const struct wpabuf *buf)
|
||||||
FLAG_TNF_RFC2046, wifi_handover_type,
|
FLAG_TNF_RFC2046, wifi_handover_type,
|
||||||
os_strlen(wifi_handover_type), NULL, 0, buf);
|
os_strlen(wifi_handover_type), NULL, 0, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct wpabuf * ndef_build_wifi_hc(int begin)
|
|
||||||
{
|
|
||||||
struct wpabuf *hc, *carrier;
|
|
||||||
|
|
||||||
carrier = wpabuf_alloc(2 + os_strlen(wifi_handover_type));
|
|
||||||
if (carrier == NULL)
|
|
||||||
return NULL;
|
|
||||||
wpabuf_put_u8(carrier, 0x02); /* Carrier Type Format */
|
|
||||||
wpabuf_put_u8(carrier, os_strlen(wifi_handover_type));
|
|
||||||
wpabuf_put_str(carrier, wifi_handover_type);
|
|
||||||
|
|
||||||
hc = ndef_build_record((begin ? FLAG_MESSAGE_BEGIN : 0) |
|
|
||||||
FLAG_MESSAGE_END | FLAG_TNF_NFC_FORUM, "Hc", 2,
|
|
||||||
"0", 1, carrier);
|
|
||||||
wpabuf_free(carrier);
|
|
||||||
|
|
||||||
return hc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
|
@ -868,8 +868,6 @@ struct wpabuf * wps_build_nfc_handover_sel(struct wps_context *ctx,
|
||||||
/* ndef.c */
|
/* ndef.c */
|
||||||
struct wpabuf * ndef_parse_wifi(const struct wpabuf *buf);
|
struct wpabuf * ndef_parse_wifi(const struct wpabuf *buf);
|
||||||
struct wpabuf * ndef_build_wifi(const struct wpabuf *buf);
|
struct wpabuf * ndef_build_wifi(const struct wpabuf *buf);
|
||||||
struct wpabuf * ndef_build_wifi_hc(int begin);
|
|
||||||
struct wpabuf * ndef_build_wifi_hr(void);
|
|
||||||
|
|
||||||
#ifdef CONFIG_WPS_STRICT
|
#ifdef CONFIG_WPS_STRICT
|
||||||
int wps_validate_beacon(const struct wpabuf *wps_ie);
|
int wps_validate_beacon(const struct wpabuf *wps_ie);
|
||||||
|
|
|
@ -366,11 +366,11 @@ the ER functionality has been started (wps_er_start), the NFC password
|
||||||
token is used to enable enrollment of a new station (that was the source
|
token is used to enable enrollment of a new station (that was the source
|
||||||
of the NFC password token).
|
of the NFC password token).
|
||||||
|
|
||||||
"nfc_get_handover_req <NDEF> <WPS>" command can be used to build the
|
"nfc_get_handover_req <NDEF> <WPS-CR>" command can be used to build the
|
||||||
contents of a Handover Request Message for connection handover. The
|
WPS carrier record for a Handover Request Message for connection
|
||||||
first argument selects the format of the output data and the second
|
handover. The first argument selects the format of the output data and
|
||||||
argument selects which type of connection handover is requested (WPS =
|
the second argument selects which type of connection handover is
|
||||||
Wi-Fi handover as specified in WSC 2.0).
|
requested (WPS-CR = Wi-Fi handover as specified in WSC 2.0).
|
||||||
|
|
||||||
"nfc_get_handover_sel <NDEF> <WPS> [UUID|BSSID]" command can be used to
|
"nfc_get_handover_sel <NDEF> <WPS> [UUID|BSSID]" command can be used to
|
||||||
build the contents of a Handover Select Message for connection handover
|
build the contents of a Handover Select Message for connection handover
|
||||||
|
|
|
@ -908,12 +908,12 @@ static int wpa_supplicant_ctrl_iface_wps_nfc_tag_read(
|
||||||
|
|
||||||
static int wpas_ctrl_nfc_get_handover_req_wps(struct wpa_supplicant *wpa_s,
|
static int wpas_ctrl_nfc_get_handover_req_wps(struct wpa_supplicant *wpa_s,
|
||||||
char *reply, size_t max_len,
|
char *reply, size_t max_len,
|
||||||
int cr)
|
int ndef)
|
||||||
{
|
{
|
||||||
struct wpabuf *buf;
|
struct wpabuf *buf;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
buf = wpas_wps_nfc_handover_req(wpa_s, cr);
|
buf = wpas_wps_nfc_handover_req(wpa_s, ndef);
|
||||||
if (buf == NULL)
|
if (buf == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -933,18 +933,25 @@ static int wpas_ctrl_nfc_get_handover_req(struct wpa_supplicant *wpa_s,
|
||||||
size_t max_len)
|
size_t max_len)
|
||||||
{
|
{
|
||||||
char *pos;
|
char *pos;
|
||||||
|
int ndef;
|
||||||
|
|
||||||
pos = os_strchr(cmd, ' ');
|
pos = os_strchr(cmd, ' ');
|
||||||
if (pos == NULL)
|
if (pos == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
*pos++ = '\0';
|
*pos++ = '\0';
|
||||||
|
|
||||||
if (os_strcmp(cmd, "NDEF") != 0)
|
if (os_strcmp(cmd, "WPS") == 0)
|
||||||
|
ndef = 0;
|
||||||
|
else if (os_strcmp(cmd, "NDEF") == 0)
|
||||||
|
ndef = 1;
|
||||||
|
else
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (os_strcmp(pos, "WPS") == 0 || os_strcmp(pos, "WPS-CR") == 0) {
|
if (os_strcmp(pos, "WPS") == 0 || os_strcmp(pos, "WPS-CR") == 0) {
|
||||||
|
if (!ndef)
|
||||||
|
return -1;
|
||||||
return wpas_ctrl_nfc_get_handover_req_wps(
|
return wpas_ctrl_nfc_get_handover_req_wps(
|
||||||
wpa_s, reply, max_len, os_strcmp(pos, "WPS-CR") == 0);
|
wpa_s, reply, max_len, ndef);
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -2259,11 +2259,29 @@ int wpas_wps_nfc_tag_read(struct wpa_supplicant *wpa_s,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct wpabuf * wpas_wps_nfc_handover_req(struct wpa_supplicant *wpa_s, int cr)
|
struct wpabuf * wpas_wps_nfc_handover_req(struct wpa_supplicant *wpa_s,
|
||||||
|
int ndef)
|
||||||
{
|
{
|
||||||
if (cr)
|
struct wpabuf *ret;
|
||||||
return ndef_build_wifi_hc(1);
|
|
||||||
return ndef_build_wifi_hr();
|
if (wpa_s->conf->wps_nfc_dh_pubkey == NULL &&
|
||||||
|
wps_nfc_gen_dh(&wpa_s->conf->wps_nfc_dh_pubkey,
|
||||||
|
&wpa_s->conf->wps_nfc_dh_privkey) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ret = wps_build_nfc_handover_req(wpa_s->wps,
|
||||||
|
wpa_s->conf->wps_nfc_dh_pubkey);
|
||||||
|
|
||||||
|
if (ndef && ret) {
|
||||||
|
struct wpabuf *tmp;
|
||||||
|
tmp = ndef_build_wifi(ret);
|
||||||
|
wpabuf_free(ret);
|
||||||
|
if (tmp == NULL)
|
||||||
|
return NULL;
|
||||||
|
ret = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,8 @@ int wpas_wps_start_nfc(struct wpa_supplicant *wpa_s, const u8 *bssid,
|
||||||
const u8 *ssid, size_t ssid_len);
|
const u8 *ssid, size_t ssid_len);
|
||||||
int wpas_wps_nfc_tag_read(struct wpa_supplicant *wpa_s,
|
int wpas_wps_nfc_tag_read(struct wpa_supplicant *wpa_s,
|
||||||
const struct wpabuf *data);
|
const struct wpabuf *data);
|
||||||
struct wpabuf * wpas_wps_nfc_handover_req(struct wpa_supplicant *wpa_s, int cr);
|
struct wpabuf * wpas_wps_nfc_handover_req(struct wpa_supplicant *wpa_s,
|
||||||
|
int ndef);
|
||||||
struct wpabuf * wpas_wps_nfc_handover_sel(struct wpa_supplicant *wpa_s,
|
struct wpabuf * wpas_wps_nfc_handover_sel(struct wpa_supplicant *wpa_s,
|
||||||
int ndef, int cr, const char *uuid);
|
int ndef, int cr, const char *uuid);
|
||||||
int wpas_wps_nfc_rx_handover_req(struct wpa_supplicant *wpa_s,
|
int wpas_wps_nfc_rx_handover_req(struct wpa_supplicant *wpa_s,
|
||||||
|
|
Loading…
Reference in a new issue