WPS: Add support for config token generation with wpa_supplicant

When wpa_supplicant is controlling an AP mode interface, it can generate
the NFC configuration token similarly to the way this is done in
hostapd.

Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
Jouni Malinen 2013-02-15 11:45:29 +02:00 committed by Jouni Malinen
parent 23ffcaf172
commit bbf41865c9
8 changed files with 112 additions and 0 deletions

View file

@ -336,6 +336,16 @@ wps_nfc_dh_privkey, wps_nfc_dev_pw) or generated dynamically with
tokens during manufacturing (each station needs to have its own random tokens during manufacturing (each station needs to have its own random
keys). keys).
The "wps_nfc_config_token <WPS/NDEF>" command can be used to build an
NFC configuration token when wpa_supplicant is controlling an AP
interface (AP or P2P GO). The output value from this command is a
hexdump of the current AP configuration (WPS parameter requests this to
include only the WPS attributes; NDEF parameter requests additional NDEF
encapsulation to be included). This data needs to be written to an NFC
tag with an external program. Once written, the NFC configuration token
can be used to touch an NFC interface on a station to provision the
credentials needed to access the network.
If the station includes NFC interface and reads an NFC tag with a MIME If the station includes NFC interface and reads an NFC tag with a MIME
media type "application/vnd.wfa.wsc", the NDEF message payload (with or media type "application/vnd.wfa.wsc", the NDEF message payload (with or
without NDEF encapsulation) can be delivered to wpa_supplicant using the without NDEF encapsulation) can be delivered to wpa_supplicant using the

View file

@ -848,6 +848,18 @@ void wpa_supplicant_ap_pwd_auth_fail(struct wpa_supplicant *wpa_s)
hapd->conf->ap_pin = NULL; hapd->conf->ap_pin = NULL;
} }
struct wpabuf * wpas_ap_wps_nfc_config_token(struct wpa_supplicant *wpa_s,
int ndef)
{
struct hostapd_data *hapd;
if (wpa_s->ap_iface == NULL)
return NULL;
hapd = wpa_s->ap_iface->bss[0];
return hostapd_wps_nfc_config_token(hapd, ndef);
}
#endif /* CONFIG_WPS */ #endif /* CONFIG_WPS */

View file

@ -52,5 +52,7 @@ int wpa_supplicant_ap_mac_addr_filter(struct wpa_supplicant *wpa_s,
void wpa_supplicant_ap_pwd_auth_fail(struct wpa_supplicant *wpa_s); void wpa_supplicant_ap_pwd_auth_fail(struct wpa_supplicant *wpa_s);
void wpas_ap_ch_switch(struct wpa_supplicant *wpa_s, int freq, int ht, void wpas_ap_ch_switch(struct wpa_supplicant *wpa_s, int freq, int ht,
int offset); int offset);
struct wpabuf * wpas_ap_wps_nfc_config_token(struct wpa_supplicant *wpa_s,
int ndef);
#endif /* AP_H */ #endif /* AP_H */

View file

@ -778,6 +778,35 @@ static int wpa_supplicant_ctrl_iface_wps_nfc(struct wpa_supplicant *wpa_s,
} }
static int wpa_supplicant_ctrl_iface_wps_nfc_config_token(
struct wpa_supplicant *wpa_s, char *cmd, char *reply, size_t max_len)
{
int ndef;
struct wpabuf *buf;
int res;
if (os_strcmp(cmd, "WPS") == 0)
ndef = 0;
else if (os_strcmp(cmd, "NDEF") == 0)
ndef = 1;
else
return -1;
buf = wpas_wps_nfc_config_token(wpa_s, ndef);
if (buf == NULL)
return -1;
res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf),
wpabuf_len(buf));
reply[res++] = '\n';
reply[res] = '\0';
wpabuf_free(buf);
return res;
}
static int wpa_supplicant_ctrl_iface_wps_nfc_token( static int wpa_supplicant_ctrl_iface_wps_nfc_token(
struct wpa_supplicant *wpa_s, char *cmd, char *reply, size_t max_len) struct wpa_supplicant *wpa_s, char *cmd, char *reply, size_t max_len)
{ {
@ -4958,6 +4987,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
} else if (os_strncmp(buf, "WPS_NFC ", 8) == 0) { } else if (os_strncmp(buf, "WPS_NFC ", 8) == 0) {
if (wpa_supplicant_ctrl_iface_wps_nfc(wpa_s, buf + 8)) if (wpa_supplicant_ctrl_iface_wps_nfc(wpa_s, buf + 8))
reply_len = -1; reply_len = -1;
} else if (os_strncmp(buf, "WPS_NFC_CONFIG_TOKEN ", 21) == 0) {
reply_len = wpa_supplicant_ctrl_iface_wps_nfc_config_token(
wpa_s, buf + 21, reply, reply_size);
} else if (os_strncmp(buf, "WPS_NFC_TOKEN ", 14) == 0) { } else if (os_strncmp(buf, "WPS_NFC_TOKEN ", 14) == 0) {
reply_len = wpa_supplicant_ctrl_iface_wps_nfc_token( reply_len = wpa_supplicant_ctrl_iface_wps_nfc_token(
wpa_s, buf + 14, reply, reply_size); wpa_s, buf + 14, reply, reply_size);

View file

@ -54,6 +54,13 @@ def wpas_tag_read(message):
print wpas.request("WPS_NFC_TAG_READ " + message.encode("hex")) print wpas.request("WPS_NFC_TAG_READ " + message.encode("hex"))
def wpas_get_config_token():
wpas = wpas_connect()
if (wpas == None):
return None
return wpas.request("WPS_NFC_CONFIG_TOKEN NDEF").rstrip().decode("hex")
def wpas_get_password_token(): def wpas_get_password_token():
wpas = wpas_connect() wpas = wpas_connect()
if (wpas == None): if (wpas == None):
@ -169,6 +176,28 @@ def wps_tag_read(tag):
time.sleep(0.1) time.sleep(0.1)
def wps_write_config_tag(clf):
print "Write WPS config token"
data = wpas_get_config_token()
if (data == None):
print "Could not get WPS config token from wpa_supplicant"
return
print "Touch an NFC tag"
while True:
tag = clf.poll()
if tag == None:
time.sleep(0.1)
continue
break
print "Tag found - writing"
tag.ndef.message = data
print "Done - remove tag"
while tag.is_present:
time.sleep(0.1)
def wps_write_password_tag(clf): def wps_write_password_tag(clf):
print "Write WPS password token" print "Write WPS password token"
data = wpas_get_password_token() data = wpas_get_password_token()
@ -223,6 +252,10 @@ def main():
clf = nfc.ContactlessFrontend() clf = nfc.ContactlessFrontend()
try: try:
if len(sys.argv) > 1 and sys.argv[1] == "write-config":
wps_write_config_tag(clf)
raise SystemExit
if len(sys.argv) > 1 and sys.argv[1] == "write-password": if len(sys.argv) > 1 and sys.argv[1] == "write-password":
wps_write_password_tag(clf) wps_write_password_tag(clf)
raise SystemExit raise SystemExit

View file

@ -744,6 +744,13 @@ static int wpa_cli_cmd_wps_nfc(struct wpa_ctrl *ctrl, int argc, char *argv[])
} }
static int wpa_cli_cmd_wps_nfc_config_token(struct wpa_ctrl *ctrl, int argc,
char *argv[])
{
return wpa_cli_cmd(ctrl, "WPS_NFC_CONFIG_TOKEN", 1, argc, argv);
}
static int wpa_cli_cmd_wps_nfc_token(struct wpa_ctrl *ctrl, int argc, static int wpa_cli_cmd_wps_nfc_token(struct wpa_ctrl *ctrl, int argc,
char *argv[]) char *argv[])
{ {
@ -2488,6 +2495,9 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
{ "wps_nfc", wpa_cli_cmd_wps_nfc, wpa_cli_complete_bss, { "wps_nfc", wpa_cli_cmd_wps_nfc, wpa_cli_complete_bss,
cli_cmd_flag_none, cli_cmd_flag_none,
"[BSSID] = start Wi-Fi Protected Setup: NFC" }, "[BSSID] = start Wi-Fi Protected Setup: NFC" },
{ "wps_nfc_config_token", wpa_cli_cmd_wps_nfc_config_token, NULL,
cli_cmd_flag_none,
"<WPS|NDEF> = build configuration token" },
{ "wps_nfc_token", wpa_cli_cmd_wps_nfc_token, NULL, { "wps_nfc_token", wpa_cli_cmd_wps_nfc_token, NULL,
cli_cmd_flag_none, cli_cmd_flag_none,
"<WPS|NDEF> = create password token" }, "<WPS|NDEF> = create password token" },

View file

@ -1830,6 +1830,17 @@ void wpas_wps_update_config(struct wpa_supplicant *wpa_s)
#ifdef CONFIG_WPS_NFC #ifdef CONFIG_WPS_NFC
struct wpabuf * wpas_wps_nfc_config_token(struct wpa_supplicant *wpa_s,
int ndef)
{
#ifdef CONFIG_AP
if (wpa_s->ap_iface)
return wpas_ap_wps_nfc_config_token(wpa_s, ndef);
#endif /* CONFIG_AP */
return NULL;
}
struct wpabuf * wpas_wps_nfc_token(struct wpa_supplicant *wpa_s, int ndef) struct wpabuf * wpas_wps_nfc_token(struct wpa_supplicant *wpa_s, int ndef)
{ {
if (wpa_s->conf->wps_nfc_pw_from_config) { if (wpa_s->conf->wps_nfc_pw_from_config) {

View file

@ -62,6 +62,8 @@ struct wpabuf * wpas_wps_er_nfc_config_token(struct wpa_supplicant *wpa_s,
int wpas_wps_terminate_pending(struct wpa_supplicant *wpa_s); int wpas_wps_terminate_pending(struct wpa_supplicant *wpa_s);
int wpas_wps_in_progress(struct wpa_supplicant *wpa_s); int wpas_wps_in_progress(struct wpa_supplicant *wpa_s);
void wpas_wps_update_config(struct wpa_supplicant *wpa_s); void wpas_wps_update_config(struct wpa_supplicant *wpa_s);
struct wpabuf * wpas_wps_nfc_config_token(struct wpa_supplicant *wpa_s,
int ndef);
struct wpabuf * wpas_wps_nfc_token(struct wpa_supplicant *wpa_s, int ndef); struct wpabuf * wpas_wps_nfc_token(struct wpa_supplicant *wpa_s, int ndef);
int wpas_wps_start_nfc(struct wpa_supplicant *wpa_s, const u8 *bssid); int wpas_wps_start_nfc(struct wpa_supplicant *wpa_s, const u8 *bssid);
int wpas_wps_nfc_tag_read(struct wpa_supplicant *wpa_s, int wpas_wps_nfc_tag_read(struct wpa_supplicant *wpa_s,