From 9305c2332bd4dc2070b26b212949cac29eaa5e42 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sat, 16 Mar 2019 12:19:10 +0200 Subject: [PATCH] DPP: Clean up configuration parsing Share a single parsing implementation for both hostapd and wpa_supplicant to avoid code duplication. In addition, clean up the implementation to be more easily extensible. Signed-off-by: Jouni Malinen --- src/ap/dpp_hostapd.c | 160 ++---------------------------- src/common/dpp.c | 171 ++++++++++++++++++++++++++++++++ src/common/dpp.h | 4 + wpa_supplicant/dpp_supplicant.c | 159 ++--------------------------- 4 files changed, 195 insertions(+), 299 deletions(-) diff --git a/src/ap/dpp_hostapd.c b/src/ap/dpp_hostapd.c index 7184f7204..0305283b6 100644 --- a/src/ap/dpp_hostapd.c +++ b/src/ap/dpp_hostapd.c @@ -519,171 +519,31 @@ static int hostapd_dpp_set_configurator(struct hostapd_data *hapd, struct dpp_authentication *auth, const char *cmd) { - const char *pos, *end; - struct dpp_configuration *conf_sta = NULL, *conf_ap = NULL; - struct dpp_configurator *conf = NULL; - u8 ssid[32] = { "test" }; - size_t ssid_len = 4; - char pass[64] = { }; - size_t pass_len = 0; - u8 psk[PMK_LEN]; - int psk_set = 0; - char *group_id = NULL; + const char *pos; if (!cmd) return 0; wpa_printf(MSG_DEBUG, "DPP: Set configurator parameters: %s", cmd); - pos = os_strstr(cmd, " ssid="); - if (pos) { - pos += 6; - end = os_strchr(pos, ' '); - ssid_len = end ? (size_t) (end - pos) : os_strlen(pos); - ssid_len /= 2; - if (ssid_len > sizeof(ssid) || - hexstr2bin(pos, ssid, ssid_len) < 0) - goto fail; - } - - pos = os_strstr(cmd, " pass="); - if (pos) { - pos += 6; - end = os_strchr(pos, ' '); - pass_len = end ? (size_t) (end - pos) : os_strlen(pos); - pass_len /= 2; - if (pass_len > sizeof(pass) - 1 || pass_len < 8 || - hexstr2bin(pos, (u8 *) pass, pass_len) < 0) - goto fail; - } - - pos = os_strstr(cmd, " psk="); - if (pos) { - pos += 5; - if (hexstr2bin(pos, psk, PMK_LEN) < 0) - goto fail; - psk_set = 1; - } - - pos = os_strstr(cmd, " group_id="); - if (pos) { - size_t group_id_len; - - pos += 10; - end = os_strchr(pos, ' '); - group_id_len = end ? (size_t) (end - pos) : os_strlen(pos); - group_id = os_malloc(group_id_len + 1); - if (!group_id) - goto fail; - os_memcpy(group_id, pos, group_id_len); - group_id[group_id_len] = '\0'; - } - - if (os_strstr(cmd, " conf=sta-")) { - conf_sta = os_zalloc(sizeof(struct dpp_configuration)); - if (!conf_sta) - goto fail; - os_memcpy(conf_sta->ssid, ssid, ssid_len); - conf_sta->ssid_len = ssid_len; - if (os_strstr(cmd, " conf=sta-psk") || - os_strstr(cmd, " conf=sta-sae") || - os_strstr(cmd, " conf=sta-psk-sae")) { - if (os_strstr(cmd, " conf=sta-psk-sae")) - conf_sta->akm = DPP_AKM_PSK_SAE; - else if (os_strstr(cmd, " conf=sta-sae")) - conf_sta->akm = DPP_AKM_SAE; - else - conf_sta->akm = DPP_AKM_PSK; - if (psk_set) { - os_memcpy(conf_sta->psk, psk, PMK_LEN); - } else { - conf_sta->passphrase = os_strdup(pass); - if (!conf_sta->passphrase) - goto fail; - } - } else if (os_strstr(cmd, " conf=sta-dpp")) { - conf_sta->akm = DPP_AKM_DPP; - } else { - goto fail; - } - if (os_strstr(cmd, " group_id=")) { - conf_sta->group_id = group_id; - group_id = NULL; - } - } - - if (os_strstr(cmd, " conf=ap-")) { - conf_ap = os_zalloc(sizeof(struct dpp_configuration)); - if (!conf_ap) - goto fail; - os_memcpy(conf_ap->ssid, ssid, ssid_len); - conf_ap->ssid_len = ssid_len; - if (os_strstr(cmd, " conf=ap-psk") || - os_strstr(cmd, " conf=ap-sae") || - os_strstr(cmd, " conf=ap-psk-sae")) { - if (os_strstr(cmd, " conf=ap-psk-sae")) - conf_ap->akm = DPP_AKM_PSK_SAE; - else if (os_strstr(cmd, " conf=ap-sae")) - conf_ap->akm = DPP_AKM_SAE; - else - conf_ap->akm = DPP_AKM_PSK; - if (psk_set) { - os_memcpy(conf_ap->psk, psk, PMK_LEN); - } else if (pass_len > 0) { - conf_ap->passphrase = os_strdup(pass); - if (!conf_ap->passphrase) - goto fail; - } else { - goto fail; - } - } else if (os_strstr(cmd, " conf=ap-dpp")) { - conf_ap->akm = DPP_AKM_DPP; - } else { - goto fail; - } - if (os_strstr(cmd, " group_id=")) { - conf_ap->group_id = group_id; - group_id = NULL; - } - } - - pos = os_strstr(cmd, " expiry="); - if (pos) { - long int val; - - pos += 8; - val = strtol(pos, NULL, 0); - if (val <= 0) - goto fail; - if (conf_sta) - conf_sta->netaccesskey_expiry = val; - if (conf_ap) - conf_ap->netaccesskey_expiry = val; - } pos = os_strstr(cmd, " configurator="); if (pos) { auth->configurator = 1; pos += 14; - conf = hostapd_dpp_configurator_get_id(hapd, atoi(pos)); - if (!conf) { + auth->conf = hostapd_dpp_configurator_get_id(hapd, atoi(pos)); + if (!auth->conf) { wpa_printf(MSG_INFO, "DPP: Could not find the specified configurator"); - goto fail; + return -1; } } - auth->conf_sta = conf_sta; - auth->conf_ap = conf_ap; - auth->conf = conf; - os_free(group_id); - return 0; -fail: - wpa_msg(hapd->msg_ctx, MSG_INFO, - "DPP: Failed to set configurator parameters"); - dpp_configuration_free(conf_sta); - dpp_configuration_free(conf_ap); - os_free(group_id); - return -1; + if (dpp_configuration_parse(auth, cmd) < 0) { + wpa_msg(hapd->msg_ctx, MSG_INFO, + "DPP: Failed to set configurator parameters"); + return -1; + } + return 0; } diff --git a/src/common/dpp.c b/src/common/dpp.c index c7a200780..fe097c5c4 100644 --- a/src/common/dpp.c +++ b/src/common/dpp.c @@ -4048,6 +4048,70 @@ fail: } +static int bin_str_eq(const char *val, size_t len, const char *cmp) +{ + return os_strlen(cmp) == len && os_memcmp(val, cmp, len) == 0; +} + + +struct dpp_configuration * dpp_configuration_alloc(const char *type) +{ + struct dpp_configuration *conf; + const char *end; + size_t len; + + conf = os_zalloc(sizeof(*conf)); + if (!conf) + goto fail; + + end = os_strchr(type, ' '); + if (end) + len = end - type; + else + len = os_strlen(type); + + if (bin_str_eq(type, len, "psk")) + conf->akm = DPP_AKM_PSK; + else if (bin_str_eq(type, len, "sae")) + conf->akm = DPP_AKM_SAE; + else if (bin_str_eq(type, len, "psk-sae")) + conf->akm = DPP_AKM_PSK_SAE; + else if (bin_str_eq(type, len, "dpp")) + conf->akm = DPP_AKM_DPP; + else + goto fail; + + return conf; +fail: + dpp_configuration_free(conf); + return NULL; +} + + +static int dpp_akm_psk(enum dpp_akm akm) +{ + return akm == DPP_AKM_PSK || akm == DPP_AKM_PSK_SAE; +} + + +static int dpp_akm_sae(enum dpp_akm akm) +{ + return akm == DPP_AKM_SAE || akm == DPP_AKM_PSK_SAE; +} + + +int dpp_configuration_valid(const struct dpp_configuration *conf) +{ + if (conf->ssid_len == 0) + return 0; + if (dpp_akm_psk(conf->akm) && !conf->passphrase && !conf->psk_set) + return 0; + if (dpp_akm_sae(conf->akm) && !conf->passphrase) + return 0; + return 1; +} + + void dpp_configuration_free(struct dpp_configuration *conf) { if (!conf) @@ -4058,6 +4122,113 @@ void dpp_configuration_free(struct dpp_configuration *conf) } +int dpp_configuration_parse(struct dpp_authentication *auth, const char *cmd) +{ + const char *pos, *end; + struct dpp_configuration *conf_sta = NULL, *conf_ap = NULL; + struct dpp_configuration *conf = NULL; + + pos = os_strstr(cmd, " conf=sta-"); + if (pos) { + conf_sta = dpp_configuration_alloc(pos + 10); + if (!conf_sta) + goto fail; + conf = conf_sta; + } + + pos = os_strstr(cmd, " conf=ap-"); + if (pos) { + conf_ap = dpp_configuration_alloc(pos + 9); + if (!conf_ap) + goto fail; + conf = conf_ap; + } + + if (!conf) + return 0; + + pos = os_strstr(cmd, " ssid="); + if (pos) { + pos += 6; + end = os_strchr(pos, ' '); + conf->ssid_len = end ? (size_t) (end - pos) : os_strlen(pos); + conf->ssid_len /= 2; + if (conf->ssid_len > sizeof(conf->ssid) || + hexstr2bin(pos, conf->ssid, conf->ssid_len) < 0) + goto fail; + } else { +#ifdef CONFIG_TESTING_OPTIONS + /* use a default SSID for legacy testing reasons */ + os_memcpy(conf->ssid, "test", 4); + conf->ssid_len = 4; +#else /* CONFIG_TESTING_OPTIONS */ + goto fail; +#endif /* CONFIG_TESTING_OPTIONS */ + } + + pos = os_strstr(cmd, " pass="); + if (pos) { + size_t pass_len; + + pos += 6; + end = os_strchr(pos, ' '); + pass_len = end ? (size_t) (end - pos) : os_strlen(pos); + pass_len /= 2; + if (pass_len > 63 || pass_len < 8) + goto fail; + conf->passphrase = os_zalloc(pass_len + 1); + if (!conf->passphrase || + hexstr2bin(pos, (u8 *) conf->passphrase, pass_len) < 0) + goto fail; + } + + pos = os_strstr(cmd, " psk="); + if (pos) { + pos += 5; + if (hexstr2bin(pos, conf->psk, PMK_LEN) < 0) + goto fail; + conf->psk_set = 1; + } + + pos = os_strstr(cmd, " group_id="); + if (pos) { + size_t group_id_len; + + pos += 10; + end = os_strchr(pos, ' '); + group_id_len = end ? (size_t) (end - pos) : os_strlen(pos); + conf->group_id = os_malloc(group_id_len + 1); + if (!conf->group_id) + goto fail; + os_memcpy(conf->group_id, pos, group_id_len); + conf->group_id[group_id_len] = '\0'; + } + + pos = os_strstr(cmd, " expiry="); + if (pos) { + long int val; + + pos += 8; + val = strtol(pos, NULL, 0); + if (val <= 0) + goto fail; + conf->netaccesskey_expiry = val; + } + + if (!dpp_configuration_valid(conf)) + goto fail; + + auth->conf_sta = conf_sta; + auth->conf_ap = conf_ap; + return 0; + +fail: + dpp_configuration_free(conf_sta); + dpp_configuration_free(conf_ap); + return -1; +} + + void dpp_auth_deinit(struct dpp_authentication *auth) { if (!auth) diff --git a/src/common/dpp.h b/src/common/dpp.h index fe4b7f3a2..03eabef43 100644 --- a/src/common/dpp.h +++ b/src/common/dpp.h @@ -163,6 +163,7 @@ struct dpp_configuration { /* For legacy configuration */ char *passphrase; u8 psk[32]; + int psk_set; }; struct dpp_authentication { @@ -392,7 +393,10 @@ int dpp_auth_conf_rx(struct dpp_authentication *auth, const u8 *hdr, const u8 *attr_start, size_t attr_len); int dpp_notify_new_qr_code(struct dpp_authentication *auth, struct dpp_bootstrap_info *peer_bi); +struct dpp_configuration * dpp_configuration_alloc(const char *type); +int dpp_configuration_valid(const struct dpp_configuration *conf); void dpp_configuration_free(struct dpp_configuration *conf); +int dpp_configuration_parse(struct dpp_authentication *auth, const char *cmd); void dpp_auth_deinit(struct dpp_authentication *auth); struct wpabuf * dpp_conf_req_rx(struct dpp_authentication *auth, const u8 *attr_start, diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c index 411bfff83..71ba667ad 100644 --- a/wpa_supplicant/dpp_supplicant.c +++ b/wpa_supplicant/dpp_supplicant.c @@ -554,169 +554,30 @@ static int wpas_dpp_set_configurator(struct wpa_supplicant *wpa_s, struct dpp_authentication *auth, const char *cmd) { - const char *pos, *end; - struct dpp_configuration *conf_sta = NULL, *conf_ap = NULL; - struct dpp_configurator *conf = NULL; - u8 ssid[32] = { "test" }; - size_t ssid_len = 4; - char pass[64] = { }; - size_t pass_len = 0; - u8 psk[PMK_LEN]; - int psk_set = 0; - char *group_id = NULL; + const char *pos; if (!cmd) return 0; wpa_printf(MSG_DEBUG, "DPP: Set configurator parameters: %s", cmd); - pos = os_strstr(cmd, " ssid="); - if (pos) { - pos += 6; - end = os_strchr(pos, ' '); - ssid_len = end ? (size_t) (end - pos) : os_strlen(pos); - ssid_len /= 2; - if (ssid_len > sizeof(ssid) || - hexstr2bin(pos, ssid, ssid_len) < 0) - goto fail; - } - - pos = os_strstr(cmd, " pass="); - if (pos) { - pos += 6; - end = os_strchr(pos, ' '); - pass_len = end ? (size_t) (end - pos) : os_strlen(pos); - pass_len /= 2; - if (pass_len > sizeof(pass) - 1 || pass_len < 8 || - hexstr2bin(pos, (u8 *) pass, pass_len) < 0) - goto fail; - } - - pos = os_strstr(cmd, " psk="); - if (pos) { - pos += 5; - if (hexstr2bin(pos, psk, PMK_LEN) < 0) - goto fail; - psk_set = 1; - } - - pos = os_strstr(cmd, " group_id="); - if (pos) { - size_t group_id_len; - - pos += 10; - end = os_strchr(pos, ' '); - group_id_len = end ? (size_t) (end - pos) : os_strlen(pos); - group_id = os_malloc(group_id_len + 1); - if (!group_id) - goto fail; - os_memcpy(group_id, pos, group_id_len); - group_id[group_id_len] = '\0'; - } - - if (os_strstr(cmd, " conf=sta-")) { - conf_sta = os_zalloc(sizeof(struct dpp_configuration)); - if (!conf_sta) - goto fail; - os_memcpy(conf_sta->ssid, ssid, ssid_len); - conf_sta->ssid_len = ssid_len; - if (os_strstr(cmd, " conf=sta-psk") || - os_strstr(cmd, " conf=sta-sae") || - os_strstr(cmd, " conf=sta-psk-sae")) { - if (os_strstr(cmd, " conf=sta-psk-sae")) - conf_sta->akm = DPP_AKM_PSK_SAE; - else if (os_strstr(cmd, " conf=sta-sae")) - conf_sta->akm = DPP_AKM_SAE; - else - conf_sta->akm = DPP_AKM_PSK; - if (psk_set) { - os_memcpy(conf_sta->psk, psk, PMK_LEN); - } else if (pass_len > 0) { - conf_sta->passphrase = os_strdup(pass); - if (!conf_sta->passphrase) - goto fail; - } else { - goto fail; - } - } else if (os_strstr(cmd, " conf=sta-dpp")) { - conf_sta->akm = DPP_AKM_DPP; - } else { - goto fail; - } - if (os_strstr(cmd, " group_id=")) { - conf_sta->group_id = group_id; - group_id = NULL; - } - } - - if (os_strstr(cmd, " conf=ap-")) { - conf_ap = os_zalloc(sizeof(struct dpp_configuration)); - if (!conf_ap) - goto fail; - os_memcpy(conf_ap->ssid, ssid, ssid_len); - conf_ap->ssid_len = ssid_len; - if (os_strstr(cmd, " conf=ap-psk") || - os_strstr(cmd, " conf=ap-sae") || - os_strstr(cmd, " conf=ap-psk-sae")) { - if (os_strstr(cmd, " conf=ap-psk-sae")) - conf_ap->akm = DPP_AKM_PSK_SAE; - else if (os_strstr(cmd, " conf=ap-sae")) - conf_ap->akm = DPP_AKM_SAE; - else - conf_ap->akm = DPP_AKM_PSK; - if (psk_set) { - os_memcpy(conf_ap->psk, psk, PMK_LEN); - } else { - conf_ap->passphrase = os_strdup(pass); - if (!conf_ap->passphrase) - goto fail; - } - } else if (os_strstr(cmd, " conf=ap-dpp")) { - conf_ap->akm = DPP_AKM_DPP; - } else { - goto fail; - } - if (os_strstr(cmd, " group_id=")) { - conf_ap->group_id = group_id; - group_id = NULL; - } - } - - pos = os_strstr(cmd, " expiry="); - if (pos) { - long int val; - - pos += 8; - val = strtol(pos, NULL, 0); - if (val <= 0) - goto fail; - if (conf_sta) - conf_sta->netaccesskey_expiry = val; - if (conf_ap) - conf_ap->netaccesskey_expiry = val; - } pos = os_strstr(cmd, " configurator="); if (pos) { pos += 14; - conf = dpp_configurator_get_id(wpa_s, atoi(pos)); - if (!conf) { + auth->conf = dpp_configurator_get_id(wpa_s, atoi(pos)); + if (!auth->conf) { wpa_printf(MSG_INFO, "DPP: Could not find the specified configurator"); - goto fail; + return -1; } } - auth->conf_sta = conf_sta; - auth->conf_ap = conf_ap; - auth->conf = conf; - os_free(group_id); - return 0; -fail: - wpa_msg(wpa_s, MSG_INFO, "DPP: Failed to set configurator parameters"); - dpp_configuration_free(conf_sta); - dpp_configuration_free(conf_ap); - os_free(group_id); - return -1; + if (dpp_configuration_parse(auth, cmd) < 0) { + wpa_msg(wpa_s, MSG_INFO, + "DPP: Failed to set configurator parameters"); + return -1; + } + return 0; }