diff --git a/hostapd/config_file.c b/hostapd/config_file.c index 7b22dfd0e..e29ae2fbb 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -2627,15 +2627,19 @@ static int hostapd_config_fill(struct hostapd_config *conf, "wps_nfc_dev_pw_id value", line); errors++; } + bss->wps_nfc_pw_from_config = 1; } 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); + bss->wps_nfc_pw_from_config = 1; } 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); + bss->wps_nfc_pw_from_config = 1; } 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); + bss->wps_nfc_pw_from_config = 1; #endif /* CONFIG_WPS_NFC */ #endif /* CONFIG_WPS */ #ifdef CONFIG_P2P_MANAGER diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index 4742107d4..6606f72d7 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -365,6 +365,7 @@ struct hostapd_bss_config { char *model_url; char *upc; struct wpabuf *wps_vendor_ext[MAX_WPS_VENDOR_EXTENSIONS]; + int wps_nfc_pw_from_config; int wps_nfc_dev_pw_id; struct wpabuf *wps_nfc_dh_pubkey; struct wpabuf *wps_nfc_dh_privkey; diff --git a/src/ap/wps_hostapd.c b/src/ap/wps_hostapd.c index c9f628932..dfe77ad37 100644 --- a/src/ap/wps_hostapd.c +++ b/src/ap/wps_hostapd.c @@ -1595,6 +1595,13 @@ struct wpabuf * hostapd_wps_nfc_hs_cr(struct hostapd_data *hapd, int ndef) struct wpabuf * hostapd_wps_nfc_token_gen(struct hostapd_data *hapd, int ndef) { + if (hapd->conf->wps_nfc_pw_from_config) { + return wps_nfc_token_build(ndef, + hapd->conf->wps_nfc_dev_pw_id, + hapd->conf->wps_nfc_dh_pubkey, + hapd->conf->wps_nfc_dev_pw); + } + return wps_nfc_token_gen(ndef, &hapd->conf->wps_nfc_dev_pw_id, &hapd->conf->wps_nfc_dh_pubkey, &hapd->conf->wps_nfc_dh_privkey, diff --git a/src/wps/wps.h b/src/wps/wps.h index 4227f3c7d..39fce56fb 100644 --- a/src/wps/wps.h +++ b/src/wps/wps.h @@ -810,6 +810,8 @@ u16 wps_config_methods_str2bin(const char *str); struct wpabuf * wps_build_nfc_pw_token(u16 dev_pw_id, const struct wpabuf *pubkey, const struct wpabuf *dev_pw); +struct wpabuf * wps_nfc_token_build(int ndef, int id, struct wpabuf *pubkey, + struct wpabuf *dev_pw); struct wpabuf * wps_nfc_token_gen(int ndef, int *id, struct wpabuf **pubkey, struct wpabuf **privkey, struct wpabuf **dev_pw); diff --git a/src/wps/wps_common.c b/src/wps/wps_common.c index 68d9f0a09..0897b7ba3 100644 --- a/src/wps/wps_common.c +++ b/src/wps/wps_common.c @@ -562,11 +562,34 @@ struct wpabuf * wps_build_wsc_nack(struct wps_data *wps) #ifdef CONFIG_WPS_NFC + +struct wpabuf * wps_nfc_token_build(int ndef, int id, struct wpabuf *pubkey, + struct wpabuf *dev_pw) +{ + struct wpabuf *ret; + + if (pubkey == NULL || dev_pw == NULL) + return NULL; + + ret = wps_build_nfc_pw_token(id, pubkey, dev_pw); + if (ndef && ret) { + struct wpabuf *tmp; + tmp = ndef_build_wifi(ret); + wpabuf_free(ret); + if (tmp == NULL) + return NULL; + ret = tmp; + } + + return ret; +} + + struct wpabuf * wps_nfc_token_gen(int ndef, int *id, struct wpabuf **pubkey, struct wpabuf **privkey, struct wpabuf **dev_pw) { - struct wpabuf *priv = NULL, *pub = NULL, *pw, *ret; + struct wpabuf *priv = NULL, *pub = NULL, *pw; void *dh_ctx; u16 val; @@ -596,16 +619,7 @@ struct wpabuf * wps_nfc_token_gen(int ndef, int *id, struct wpabuf **pubkey, wpabuf_free(*dev_pw); *dev_pw = pw; - ret = wps_build_nfc_pw_token(*id, *pubkey, *dev_pw); - if (ndef && ret) { - struct wpabuf *tmp; - tmp = ndef_build_wifi(ret); - wpabuf_free(ret); - if (tmp == NULL) - return NULL; - ret = tmp; - } - - return ret; + return wps_nfc_token_build(ndef, *id, *pubkey, *dev_pw); } + #endif /* CONFIG_WPS_NFC */ diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index 2c52c682e..ee634a5c1 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -2980,10 +2980,11 @@ static const struct global_parse_data global_fields[] = { { INT_RANGE(access_network_type, 0, 15), 0 }, { INT_RANGE(pbc_in_m1, 0, 1), 0 }, { STR(autoscan), 0 }, - { INT_RANGE(wps_nfc_dev_pw_id, 0x10, 0xffff), 0 }, - { BIN(wps_nfc_dh_pubkey), 0 }, - { BIN(wps_nfc_dh_privkey), 0 }, - { BIN(wps_nfc_dev_pw), 0 }, + { INT_RANGE(wps_nfc_dev_pw_id, 0x10, 0xffff), + CFG_CHANGED_NFC_PASSWORD_TOKEN }, + { BIN(wps_nfc_dh_pubkey), CFG_CHANGED_NFC_PASSWORD_TOKEN }, + { BIN(wps_nfc_dh_privkey), CFG_CHANGED_NFC_PASSWORD_TOKEN }, + { BIN(wps_nfc_dev_pw), CFG_CHANGED_NFC_PASSWORD_TOKEN }, { STR(ext_password_backend), CFG_CHANGED_EXT_PW_BACKEND }, { INT(p2p_go_max_inactivity), 0 }, { INT_RANGE(auto_interworking, 0, 1), 0 }, @@ -3020,6 +3021,8 @@ int wpa_config_process_global(struct wpa_config *config, char *pos, int line) "parse '%s'.", line, pos); ret = -1; } + if (field->changed_flag == CFG_CHANGED_NFC_PASSWORD_TOKEN) + config->wps_nfc_pw_from_config = 1; config->changed_parameters |= field->changed_flag; break; } diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h index 0c3cb9a93..2b88bb51f 100644 --- a/wpa_supplicant/config.h +++ b/wpa_supplicant/config.h @@ -220,6 +220,7 @@ struct wpa_cred { #define CFG_CHANGED_P2P_OPER_CHANNEL BIT(12) #define CFG_CHANGED_P2P_PREF_CHAN BIT(13) #define CFG_CHANGED_EXT_PW_BACKEND BIT(14) +#define CFG_CHANGED_NFC_PASSWORD_TOKEN BIT(15) /** * struct wpa_config - wpa_supplicant configuration data @@ -705,6 +706,15 @@ struct wpa_config { */ char *autoscan; + /** + * wps_nfc_pw_from_config - NFC Device Password was read from config + * + * This parameter can be determined whether the NFC Device Password was + * included in the configuration (1) or generated dynamically (0). Only + * the former case is re-written back to the configuration file. + */ + int wps_nfc_pw_from_config; + /** * wps_nfc_dev_pw_id - NFC Device Password ID for password token */ diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index 50c35333e..f29f7a6b9 100644 --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c @@ -950,12 +950,16 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config) #endif /* CONFIG_INTERWORKING */ if (config->pbc_in_m1) fprintf(f, "pbc_in_m1=%u\n", config->pbc_in_m1); - if (config->wps_nfc_dev_pw_id) - fprintf(f, "wps_nfc_dev_pw_id=%d\n", - config->wps_nfc_dev_pw_id); - write_global_bin(f, "wps_nfc_dh_pubkey", config->wps_nfc_dh_pubkey); - write_global_bin(f, "wps_nfc_dh_privkey", config->wps_nfc_dh_privkey); - write_global_bin(f, "wps_nfc_dev_pw", config->wps_nfc_dev_pw); + if (config->wps_nfc_pw_from_config) { + if (config->wps_nfc_dev_pw_id) + fprintf(f, "wps_nfc_dev_pw_id=%d\n", + config->wps_nfc_dev_pw_id); + write_global_bin(f, "wps_nfc_dh_pubkey", + config->wps_nfc_dh_pubkey); + write_global_bin(f, "wps_nfc_dh_privkey", + config->wps_nfc_dh_privkey); + write_global_bin(f, "wps_nfc_dev_pw", config->wps_nfc_dev_pw); + } if (config->ext_password_backend) fprintf(f, "ext_password_backend=%s\n", diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c index 3fd8274b5..281fef707 100644 --- a/wpa_supplicant/wps_supplicant.c +++ b/wpa_supplicant/wps_supplicant.c @@ -1832,6 +1832,13 @@ void wpas_wps_update_config(struct wpa_supplicant *wpa_s) struct wpabuf * wpas_wps_nfc_token(struct wpa_supplicant *wpa_s, int ndef) { + if (wpa_s->conf->wps_nfc_pw_from_config) { + return wps_nfc_token_build(ndef, + wpa_s->conf->wps_nfc_dev_pw_id, + wpa_s->conf->wps_nfc_dh_pubkey, + wpa_s->conf->wps_nfc_dev_pw); + } + return wps_nfc_token_gen(ndef, &wpa_s->conf->wps_nfc_dev_pw_id, &wpa_s->conf->wps_nfc_dh_pubkey, &wpa_s->conf->wps_nfc_dh_privkey,