From ffdaa05a6b1b59c4b2e50f9b7fef82769fc2d3fe Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Thu, 28 Jun 2012 19:43:29 +0300 Subject: WPS: Add support for NCF password token from AP The new hostapd ctrl_iface command WPS_NFC_TOKEN can now be used to manage AP-as-Enrollee operations with NFC password token. WPS/NDEF parameters to this command can be used to generate a new NFC password token. enable/disable parameters can be used to enable/disable use of NFC password token (instead of AP PIN) for external Registrars. A preconfigured NFS password token can be used by providing its parameters with new hostapd.conf fields wps_nfc_dev_pw_id, wps_nfc_dh_pubkey, wps_nfc_dh_privkey, and wps_nfc_dev_pw. This use will also depend on WPS_NFC_TOKEN enable/disable commands, i.e., the configured NFS password token is disabled by default. Signed-hostap: Jouni Malinen --- hostapd/config_file.c | 46 +++++++++++++++++++++++++++++++++++++++++++++- hostapd/ctrl_iface.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ hostapd/hostapd_cli.c | 23 +++++++++++++++++++++++ 3 files changed, 117 insertions(+), 1 deletion(-) (limited to 'hostapd') diff --git a/hostapd/config_file.c b/hostapd/config_file.c index b00ed8f..7b15e57 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -1325,6 +1325,31 @@ fail: #endif /* CONFIG_INTERWORKING */ +#ifdef CONFIG_WPS_NFC +static struct wpabuf * hostapd_parse_bin(const char *buf) +{ + size_t len; + struct wpabuf *ret; + + len = os_strlen(buf); + if (len & 0x01) + return NULL; + len /= 2; + + ret = wpabuf_alloc(len); + if (ret == NULL) + return NULL; + + if (hexstr2bin(buf, wpabuf_put(ret, len), len)) { + wpabuf_free(ret); + return NULL; + } + + return ret; +} +#endif /* CONFIG_WPS_NFC */ + + static int hostapd_config_fill(struct hostapd_config *conf, struct hostapd_bss_config *bss, char *buf, char *pos, int line) @@ -2224,6 +2249,25 @@ static int hostapd_config_fill(struct hostapd_config *conf, bss->upc = os_strdup(pos); } else if (os_strcmp(buf, "pbc_in_m1") == 0) { bss->pbc_in_m1 = atoi(pos); +#ifdef CONFIG_WPS_NFC + } else if (os_strcmp(buf, "wps_nfc_dev_pw_id") == 0) { + bss->wps_nfc_dev_pw_id = atoi(pos); + if (bss->wps_nfc_dev_pw_id < 0x10 || + bss->wps_nfc_dev_pw_id > 0xffff) { + wpa_printf(MSG_ERROR, "Line %d: Invalid " + "wps_nfc_dev_pw_id value", line); + errors++; + } + } else if (os_strcmp(buf, "wps_nfc_dh_pubkey") == 0) { + wpabuf_free(bss->wps_nfc_dh_pubkey); + bss->wps_nfc_dh_pubkey = hostapd_parse_bin(pos); + } else if (os_strcmp(buf, "wps_nfc_dh_privkey") == 0) { + wpabuf_free(bss->wps_nfc_dh_privkey); + bss->wps_nfc_dh_privkey = hostapd_parse_bin(pos); + } else if (os_strcmp(buf, "wps_nfc_dev_pw") == 0) { + wpabuf_free(bss->wps_nfc_dev_pw); + bss->wps_nfc_dev_pw = hostapd_parse_bin(pos); +#endif /* CONFIG_WPS_NFC */ #endif /* CONFIG_WPS */ #ifdef CONFIG_P2P_MANAGER } else if (os_strcmp(buf, "manage_p2p") == 0) { @@ -2398,7 +2442,7 @@ struct hostapd_config * hostapd_config_read(const char *fname) struct hostapd_config *conf; struct hostapd_bss_config *bss; FILE *f; - char buf[256], *pos; + char buf[512], *pos; int line = 0; int errors = 0; size_t i; diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c index 0fa1764..7587e03 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -330,6 +330,52 @@ static int hostapd_ctrl_iface_wps_nfc_config_token(struct hostapd_data *hapd, return res; } + + +static int hostapd_ctrl_iface_wps_nfc_token_gen(struct hostapd_data *hapd, + char *reply, size_t max_len, + int ndef) +{ + struct wpabuf *buf; + int res; + + buf = hostapd_wps_nfc_token_gen(hapd, 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 hostapd_ctrl_iface_wps_nfc_token(struct hostapd_data *hapd, + char *cmd, char *reply, + size_t max_len) +{ + if (os_strcmp(cmd, "WPS") == 0) + return hostapd_ctrl_iface_wps_nfc_token_gen(hapd, reply, + max_len, 0); + + if (os_strcmp(cmd, "NDEF") == 0) + return hostapd_ctrl_iface_wps_nfc_token_gen(hapd, reply, + max_len, 1); + + if (os_strcmp(cmd, "enable") == 0) + return hostapd_wps_nfc_token_enable(hapd); + + if (os_strcmp(cmd, "disable") == 0) { + hostapd_wps_nfc_token_disable(hapd); + return 0; + } + + return -1; +} #endif /* CONFIG_WPS_NFC */ @@ -835,6 +881,9 @@ static void hostapd_ctrl_iface_receive(int sock, void *eloop_ctx, } else if (os_strncmp(buf, "WPS_NFC_CONFIG_TOKEN ", 21) == 0) { reply_len = hostapd_ctrl_iface_wps_nfc_config_token( hapd, buf + 21, reply, reply_size); + } else if (os_strncmp(buf, "WPS_NFC_TOKEN ", 14) == 0) { + reply_len = hostapd_ctrl_iface_wps_nfc_token( + hapd, buf + 14, reply, reply_size); #endif /* CONFIG_WPS_NFC */ #endif /* CONFIG_WPS */ } else if (os_strncmp(buf, "ESS_DISASSOC ", 13) == 0) { diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c index ed52187..0c33d5b 100644 --- a/hostapd/hostapd_cli.c +++ b/hostapd/hostapd_cli.c @@ -77,6 +77,7 @@ static const char *commands_help = #ifdef CONFIG_WPS_NFC " wps_nfc_tag_read report read NFC tag with WPS data\n" " wps_nfc_config_token build NFC configuration token\n" +" wps_nfc_token manager NFC password token\n" #endif /* CONFIG_WPS_NFC */ " wps_ap_pin [params..] enable/disable AP PIN\n" " wps_config configure AP\n" @@ -484,6 +485,27 @@ static int hostapd_cli_cmd_wps_nfc_config_token(struct wpa_ctrl *ctrl, } return wpa_ctrl_command(ctrl, cmd); } + + +static int hostapd_cli_cmd_wps_nfc_token(struct wpa_ctrl *ctrl, + int argc, char *argv[]) +{ + char cmd[64]; + int res; + + if (argc != 1) { + printf("Invalid 'wps_nfc_token' command - one argument is " + "required.\n"); + return -1; + } + + res = os_snprintf(cmd, sizeof(cmd), "WPS_NFC_TOKEN %s", argv[0]); + if (res < 0 || (size_t) res >= sizeof(cmd) - 1) { + printf("Too long WPS_NFC_TOKEN command.\n"); + return -1; + } + return wpa_ctrl_command(ctrl, cmd); +} #endif /* CONFIG_WPS_NFC */ @@ -787,6 +809,7 @@ static struct hostapd_cli_cmd hostapd_cli_commands[] = { #ifdef CONFIG_WPS_NFC { "wps_nfc_tag_read", hostapd_cli_cmd_wps_nfc_tag_read }, { "wps_nfc_config_token", hostapd_cli_cmd_wps_nfc_config_token }, + { "wps_nfc_token", hostapd_cli_cmd_wps_nfc_token }, #endif /* CONFIG_WPS_NFC */ { "wps_ap_pin", hostapd_cli_cmd_wps_ap_pin }, { "wps_config", hostapd_cli_cmd_wps_config }, -- cgit v1.1