From 1cea09a9e2a69749a179d489be5a53d7d51f7e60 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Thu, 28 Jun 2012 16:35:51 +0300 Subject: WPS ER: Add support for building NFC configuration token WPS_ER_NFC_CONFIG_TOKEN command can now be used to build a NFC configuration token based on AP Settings learnt with WPS_ER_LEARN or set with WPS_ER_CONFIG. Signed-hostap: Jouni Malinen --- src/wps/wps.h | 1 + src/wps/wps_er.c | 40 ++++++++++++++++++++++++++++++++++++- wpa_supplicant/ctrl_iface.c | 44 ++++++++++++++++++++++++++++++++++++++++- wpa_supplicant/wpa_cli.c | 33 ++++++++++++++++++++++++++++++- wpa_supplicant/wps_supplicant.c | 28 ++++++++++++++++++++++++++ wpa_supplicant/wps_supplicant.h | 2 ++ 6 files changed, 145 insertions(+), 3 deletions(-) diff --git a/src/wps/wps.h b/src/wps/wps.h index dd84f1b..c5871af 100644 --- a/src/wps/wps.h +++ b/src/wps/wps.h @@ -835,6 +835,7 @@ int wps_er_set_config(struct wps_er *er, const u8 *uuid, const struct wps_credential *cred); int wps_er_config(struct wps_er *er, const u8 *uuid, const u8 *pin, size_t pin_len, const struct wps_credential *cred); +struct wpabuf * wps_er_nfc_config_token(struct wps_er *er, const u8 *uuid); int wps_dev_type_str2bin(const char *str, u8 dev_type[WPS_DEV_TYPE_LEN]); char * wps_dev_type_bin2str(const u8 dev_type[WPS_DEV_TYPE_LEN], char *buf, diff --git a/src/wps/wps_er.c b/src/wps/wps_er.c index 0655a3a..95a0dec 100644 --- a/src/wps/wps_er.c +++ b/src/wps/wps_er.c @@ -1,6 +1,6 @@ /* * Wi-Fi Protected Setup - External Registrar - * Copyright (c) 2009, Jouni Malinen + * Copyright (c) 2009-2012, Jouni Malinen * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -1996,3 +1996,41 @@ int wps_er_config(struct wps_er *er, const u8 *uuid, const u8 *pin, return 0; } + + +#ifdef CONFIG_WPS_NFC +struct wpabuf * wps_er_nfc_config_token(struct wps_er *er, const u8 *uuid) +{ + struct wps_er_ap *ap; + struct wpabuf *ret; + struct wps_data data; + + if (er == NULL) + return NULL; + + ap = wps_er_ap_get(er, NULL, uuid); + if (ap == NULL) + return NULL; + if (ap->ap_settings == NULL) { + wpa_printf(MSG_DEBUG, "WPS ER: No settings known for the " + "selected AP"); + return NULL; + } + + ret = wpabuf_alloc(500); + if (ret == NULL) + return NULL; + + os_memset(&data, 0, sizeof(data)); + data.wps = er->wps; + data.use_cred = ap->ap_settings; + if (wps_build_version(ret) || + wps_build_cred(&data, ret) || + wps_build_wfa_ext(ret, 0, NULL, 0)) { + wpabuf_free(ret); + return NULL; + } + + return ret; +} +#endif /* CONFIG_WPS_NFC */ diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index d4b32e3..64c805d 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -1,6 +1,6 @@ /* * WPA Supplicant / Control interface (shared code for all backends) - * Copyright (c) 2004-2010, Jouni Malinen + * Copyright (c) 2004-2012, Jouni Malinen * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -892,6 +892,43 @@ static int wpa_supplicant_ctrl_iface_wps_er_config( ap.key_hex = new_key; return wpas_wps_er_config(wpa_s, cmd, pin, &ap); } + + +#ifdef CONFIG_WPS_NFC +static int wpa_supplicant_ctrl_iface_wps_er_nfc_config_token( + struct wpa_supplicant *wpa_s, char *cmd, char *reply, size_t max_len) +{ + int ndef; + struct wpabuf *buf; + int res; + char *uuid; + + uuid = os_strchr(cmd, ' '); + if (uuid == NULL) + return -1; + *uuid++ = '\0'; + + if (os_strcmp(cmd, "WPS") == 0) + ndef = 0; + else if (os_strcmp(cmd, "NDEF") == 0) + ndef = 1; + else + return -1; + + buf = wpas_wps_er_nfc_config_token(wpa_s, ndef, uuid); + 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; +} +#endif /* CONFIG_WPS_NFC */ #endif /* CONFIG_WPS_ER */ #endif /* CONFIG_WPS */ @@ -4182,6 +4219,11 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, } else if (os_strncmp(buf, "WPS_ER_CONFIG ", 14) == 0) { if (wpa_supplicant_ctrl_iface_wps_er_config(wpa_s, buf + 14)) reply_len = -1; +#ifdef CONFIG_WPS_NFC + } else if (os_strncmp(buf, "WPS_ER_NFC_CONFIG_TOKEN ", 24) == 0) { + reply_len = wpa_supplicant_ctrl_iface_wps_er_nfc_config_token( + wpa_s, buf + 24, reply, reply_size); +#endif /* CONFIG_WPS_NFC */ #endif /* CONFIG_WPS_ER */ #endif /* CONFIG_WPS */ #ifdef CONFIG_IBSS_RSN diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c index 17d1abe..b159ad3 100644 --- a/wpa_supplicant/wpa_cli.c +++ b/wpa_supplicant/wpa_cli.c @@ -1,6 +1,6 @@ /* * WPA Supplicant - command line interface for wpa_supplicant daemon - * Copyright (c) 2004-2011, Jouni Malinen + * Copyright (c) 2004-2012, Jouni Malinen * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -1175,6 +1175,32 @@ static int wpa_cli_cmd_wps_er_config(struct wpa_ctrl *ctrl, int argc, } +#ifdef CONFIG_WPS_NFC +static int wpa_cli_cmd_wps_er_nfc_config_token(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + char cmd[256]; + int res; + + if (argc != 2) { + printf("Invalid WPS_ER_NFC_CONFIG_TOKEN command: need two " + "arguments:\n" + "- WPS/NDEF: token format\n" + "- UUID: specify which AP to use\n"); + return -1; + } + + res = os_snprintf(cmd, sizeof(cmd), "WPS_ER_NFC_CONFIG_TOKEN %s %s", + argv[0], argv[1]); + if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { + printf("Too long WPS_ER_NFC_CONFIG_TOKEN command.\n"); + return -1; + } + return wpa_ctrl_command(ctrl, cmd); +} +#endif /* CONFIG_WPS_NFC */ + + static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[]) { char cmd[256]; @@ -3152,6 +3178,11 @@ static struct wpa_cli_cmd wpa_cli_commands[] = { { "wps_er_config", wpa_cli_cmd_wps_er_config, cli_cmd_flag_sensitive, " = configure AP" }, +#ifdef CONFIG_WPS_NFC + { "wps_er_nfc_config_token", wpa_cli_cmd_wps_er_nfc_config_token, + cli_cmd_flag_none, + " = build NFC configuration token" }, +#endif /* CONFIG_WPS_NFC */ { "ibss_rsn", wpa_cli_cmd_ibss_rsn, cli_cmd_flag_none, " = request RSN authentication with in IBSS" }, diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c index 08dd998..ae0e1d1 100644 --- a/wpa_supplicant/wps_supplicant.c +++ b/wpa_supplicant/wps_supplicant.c @@ -1674,6 +1674,34 @@ int wpas_wps_er_config(struct wpa_supplicant *wpa_s, const char *uuid, } +#ifdef CONFIG_WPS_NFC +struct wpabuf * wpas_wps_er_nfc_config_token(struct wpa_supplicant *wpa_s, + int ndef, const char *uuid) +{ + struct wpabuf *ret; + u8 u[UUID_LEN]; + + if (!wpa_s->wps_er) + return NULL; + + if (uuid_str2bin(uuid, u)) + return NULL; + + ret = wps_er_nfc_config_token(wpa_s->wps_er, u); + if (ndef && ret) { + struct wpabuf *tmp; + tmp = ndef_build_wifi(ret); + wpabuf_free(ret); + if (tmp == NULL) + return NULL; + ret = tmp; + } + + return ret; +} +#endif /* CONFIG_WPS_NFC */ + + static int callbacks_pending = 0; static void wpas_wps_terminate_cb(void *ctx) diff --git a/wpa_supplicant/wps_supplicant.h b/wpa_supplicant/wps_supplicant.h index 38b3655..5a49a8f 100644 --- a/wpa_supplicant/wps_supplicant.h +++ b/wpa_supplicant/wps_supplicant.h @@ -59,6 +59,8 @@ int wpas_wps_er_set_config(struct wpa_supplicant *wpa_s, const char *uuid, int id); int wpas_wps_er_config(struct wpa_supplicant *wpa_s, const char *uuid, const char *pin, struct wps_new_ap_settings *settings); +struct wpabuf * wpas_wps_er_nfc_config_token(struct wpa_supplicant *wpa_s, + int ndef, const char *uuid); int wpas_wps_terminate_pending(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); -- cgit v1.1