]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
DPP: Use JSON token builder helpers
authorJouni Malinen <jouni@codeaurora.org>
Wed, 27 Nov 2019 14:07:49 +0000 (16:07 +0200)
committerJouni Malinen <j@w1.fi>
Thu, 28 Nov 2019 14:39:09 +0000 (16:39 +0200)
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
src/common/dpp.c

index 704f55c7ae4167509ff3839b91a00827f5d1969f..c772291a8cafef27bf9f6ecf9f3e12b45848f0db 100644 (file)
@@ -2543,10 +2543,9 @@ struct wpabuf * dpp_build_conf_req_helper(struct dpp_authentication *auth,
                                          const char *name, int netrole_ap,
                                          const char *mud_url, int *opclasses)
 {
-       size_t len, nlen;
+       size_t len, name_len;
        const char *tech = "infra";
        const char *dpp_name;
-       char *nbuf;
        struct wpabuf *buf, *json;
 
 #ifdef CONFIG_TESTING_OPTIONS
@@ -2559,39 +2558,38 @@ struct wpabuf * dpp_build_conf_req_helper(struct dpp_authentication *auth,
 #endif /* CONFIG_TESTING_OPTIONS */
 
        dpp_name = name ? name : "Test";
-       len = os_strlen(dpp_name);
-       nlen = len * 6 + 1;
-       nbuf = os_malloc(nlen);
-       if (!nbuf)
-               return NULL;
-       json_escape_string(nbuf, nlen, dpp_name, len);
+       name_len = os_strlen(dpp_name);
 
-       len = 100 + os_strlen(nbuf) + int_array_len(opclasses) * 4;
+       len = 100 + name_len * 6 + 1 + int_array_len(opclasses) * 4;
        if (mud_url && mud_url[0])
                len += 10 + os_strlen(mud_url);
        json = wpabuf_alloc(len);
-       if (!json) {
-               os_free(nbuf);
+       if (!json)
                return NULL;
-       }
 
-       wpabuf_printf(json,
-                     "{\"name\":\"%s\","
-                     "\"wi-fi_tech\":\"%s\","
-                     "\"netRole\":\"%s\"",
-                     nbuf, tech, netrole_ap ? "ap" : "sta");
-       if (mud_url && mud_url[0])
-               wpabuf_printf(json, ",\"mudurl\":\"%s\"", mud_url);
+       json_start_object(json, NULL);
+       if (json_add_string_escape(json, "name", dpp_name, name_len) < 0) {
+               wpabuf_free(json);
+               return NULL;
+       }
+       json_value_sep(json);
+       json_add_string(json, "wi-fi_tech", tech);
+       json_value_sep(json);
+       json_add_string(json, "netRole", netrole_ap ? "ap" : "sta");
+       if (mud_url && mud_url[0]) {
+               json_value_sep(json);
+               json_add_string(json, "mudurl", mud_url);
+       }
        if (opclasses) {
                int i;
 
-               wpabuf_put_str(json, ",\"bandSupport\":[");
+               json_value_sep(json);
+               json_start_array(json, "bandSupport");
                for (i = 0; opclasses[i]; i++)
                        wpabuf_printf(json, "%s%u", i ? "," : "", opclasses[i]);
-               wpabuf_put_str(json, "]");
+               json_end_array(json);
        }
-       wpabuf_put_str(json, "}");
-       os_free(nbuf);
+       json_end_object(json);
 
        buf = dpp_build_conf_req(auth, wpabuf_head(json));
        wpabuf_free(json);
@@ -4636,7 +4634,6 @@ dpp_build_conf_start(struct dpp_authentication *auth,
                     struct dpp_configuration *conf, size_t tailroom)
 {
        struct wpabuf *buf;
-       char ssid[6 * sizeof(conf->ssid) + 1];
 
 #ifdef CONFIG_TESTING_OPTIONS
        if (auth->discovery_override)
@@ -4646,21 +4643,27 @@ dpp_build_conf_start(struct dpp_authentication *auth,
        buf = wpabuf_alloc(200 + tailroom);
        if (!buf)
                return NULL;
-       wpabuf_put_str(buf, "{\"wi-fi_tech\":\"infra\",\"discovery\":");
+       json_start_object(buf, NULL);
+       json_add_string(buf, "wi-fi_tech", "infra");
+       json_value_sep(buf);
 #ifdef CONFIG_TESTING_OPTIONS
        if (auth->discovery_override) {
                wpa_printf(MSG_DEBUG, "DPP: TESTING - discovery override: '%s'",
                           auth->discovery_override);
+               wpabuf_put_str(buf, "\"discovery\":");
                wpabuf_put_str(buf, auth->discovery_override);
-               wpabuf_put_u8(buf, ',');
+               json_value_sep(buf);
                return buf;
        }
 #endif /* CONFIG_TESTING_OPTIONS */
-       wpabuf_put_str(buf, "{\"ssid\":\"");
-       json_escape_string(ssid, sizeof(ssid),
-                          (const char *) conf->ssid, conf->ssid_len);
-       wpabuf_put_str(buf, ssid);
-       wpabuf_put_str(buf, "\"},");
+       json_start_object(buf, "discovery");
+       if (json_add_string_escape(buf, "ssid", conf->ssid,
+                                  conf->ssid_len) < 0) {
+               wpabuf_free(buf);
+               return NULL;
+       }
+       json_end_object(buf);
+       json_value_sep(buf);
 
        return buf;
 }
@@ -4671,37 +4674,32 @@ static int dpp_build_jwk(struct wpabuf *buf, const char *name, EVP_PKEY *key,
 {
        struct wpabuf *pub;
        const u8 *pos;
-       char *x = NULL, *y = NULL;
        int ret = -1;
 
        pub = dpp_get_pubkey_point(key, 0);
        if (!pub)
                goto fail;
+
+       json_start_object(buf, name);
+       json_add_string(buf, "kty", "EC");
+       json_value_sep(buf);
+       json_add_string(buf, "crv", curve->jwk_crv);
+       json_value_sep(buf);
        pos = wpabuf_head(pub);
-       x = base64_url_encode(pos, curve->prime_len, NULL);
+       if (json_add_base64url(buf, "x", pos, curve->prime_len) < 0)
+               goto fail;
+       json_value_sep(buf);
        pos += curve->prime_len;
-       y = base64_url_encode(pos, curve->prime_len, NULL);
-       if (!x || !y)
+       if (json_add_base64url(buf, "y", pos, curve->prime_len) < 0)
                goto fail;
-
-       wpabuf_put_str(buf, "\"");
-       wpabuf_put_str(buf, name);
-       wpabuf_put_str(buf, "\":{\"kty\":\"EC\",\"crv\":\"");
-       wpabuf_put_str(buf, curve->jwk_crv);
-       wpabuf_put_str(buf, "\",\"x\":\"");
-       wpabuf_put_str(buf, x);
-       wpabuf_put_str(buf, "\",\"y\":\"");
-       wpabuf_put_str(buf, y);
        if (kid) {
-               wpabuf_put_str(buf, "\",\"kid\":\"");
-               wpabuf_put_str(buf, kid);
+               json_value_sep(buf);
+               json_add_string(buf, "kid", kid);
        }
-       wpabuf_put_str(buf, "\"}");
+       json_end_object(buf);
        ret = 0;
 fail:
        wpabuf_free(pub);
-       os_free(x);
-       os_free(y);
        return ret;
 }
 
@@ -4710,23 +4708,15 @@ static void dpp_build_legacy_cred_params(struct wpabuf *buf,
                                         struct dpp_configuration *conf)
 {
        if (conf->passphrase && os_strlen(conf->passphrase) < 64) {
-               char pass[63 * 6 + 1];
-
-               json_escape_string(pass, sizeof(pass), conf->passphrase,
-                                  os_strlen(conf->passphrase));
-               wpabuf_put_str(buf, "\"pass\":\"");
-               wpabuf_put_str(buf, pass);
-               wpabuf_put_str(buf, "\"");
-               os_memset(pass, 0, sizeof(pass));
+               json_add_string_escape(buf, "pass", conf->passphrase,
+                                      os_strlen(conf->passphrase));
        } else if (conf->psk_set) {
                char psk[2 * sizeof(conf->psk) + 1];
 
                wpa_snprintf_hex(psk, sizeof(psk),
                                 conf->psk, sizeof(conf->psk));
-               wpabuf_put_str(buf, "\"psk_hex\":\"");
-               wpabuf_put_str(buf, psk);
-               wpabuf_put_str(buf, "\"");
-               os_memset(psk, 0, sizeof(psk));
+               json_add_string(buf, "psk_hex", psk);
+               forced_memzero(psk, sizeof(psk));
        }
 }
 
@@ -4752,7 +4742,7 @@ dpp_build_conf_obj_dpp(struct dpp_authentication *auth,
        char *signed1 = NULL, *signed2 = NULL, *signed3 = NULL;
        size_t tailroom;
        const struct dpp_curve_params *curve;
-       char jws_prot_hdr[100];
+       struct wpabuf *jws_prot_hdr;
        size_t signed1_len, signed2_len, signed3_len;
        struct wpabuf *dppcon = NULL;
        unsigned char *signature = NULL;
@@ -4813,15 +4803,21 @@ dpp_build_conf_obj_dpp(struct dpp_authentication *auth,
                                   auth->groups_override);
                        wpabuf_put_str(dppcon, "\"groups\":");
                        wpabuf_put_str(dppcon, auth->groups_override);
-                       wpabuf_put_u8(dppcon, ',');
+                       json_value_sep(dppcon);
                }
                goto skip_groups;
        }
 #endif /* CONFIG_TESTING_OPTIONS */
-       wpabuf_printf(dppcon, "{\"groups\":[{\"groupId\":\"%s\",",
-                     conf->group_id ? conf->group_id : "*");
-       wpabuf_printf(dppcon, "\"netRole\":\"%s\"}],",
-                     dpp_netrole_str(conf->netrole));
+       json_start_object(dppcon, NULL);
+       json_start_array(dppcon, "groups");
+       json_start_object(dppcon, NULL);
+       json_add_string(dppcon, "groupId",
+                       conf->group_id ? conf->group_id : "*");
+       json_value_sep(dppcon);
+       json_add_string(dppcon, "netRole", dpp_netrole_str(conf->netrole));
+       json_end_object(dppcon);
+       json_end_array(dppcon);
+       json_value_sep(dppcon);
 #ifdef CONFIG_TESTING_OPTIONS
 skip_groups:
 #endif /* CONFIG_TESTING_OPTIONS */
@@ -4832,26 +4828,38 @@ skip_groups:
        }
        if (conf->netaccesskey_expiry) {
                struct os_tm tm;
+               char expiry[30];
 
                if (os_gmtime(conf->netaccesskey_expiry, &tm) < 0) {
                        wpa_printf(MSG_DEBUG,
                                   "DPP: Failed to generate expiry string");
                        goto fail;
                }
-               wpabuf_printf(dppcon,
-                             ",\"expiry\":\"%04u-%02u-%02uT%02u:%02u:%02uZ\"",
-                             tm.year, tm.month, tm.day,
-                             tm.hour, tm.min, tm.sec);
-       }
-       wpabuf_put_u8(dppcon, '}');
+               os_snprintf(expiry, sizeof(expiry),
+                           "%04u-%02u-%02uT%02u:%02u:%02uZ",
+                           tm.year, tm.month, tm.day,
+                           tm.hour, tm.min, tm.sec);
+               json_value_sep(dppcon);
+               json_add_string(dppcon, "expiry", expiry);
+       }
+       json_end_object(dppcon);
        wpa_printf(MSG_DEBUG, "DPP: dppCon: %s",
                   (const char *) wpabuf_head(dppcon));
 
-       os_snprintf(jws_prot_hdr, sizeof(jws_prot_hdr),
-                   "{\"typ\":\"dppCon\",\"kid\":\"%s\",\"alg\":\"%s\"}",
-                   auth->conf->kid, curve->jws_alg);
-       signed1 = base64_url_encode(jws_prot_hdr, os_strlen(jws_prot_hdr),
+       jws_prot_hdr = wpabuf_alloc(100);
+       if (!jws_prot_hdr)
+               goto fail;
+       json_start_object(jws_prot_hdr, NULL);
+       json_add_string(jws_prot_hdr, "typ", "dppCon");
+       json_value_sep(jws_prot_hdr);
+       json_add_string(jws_prot_hdr, "kid", auth->conf->kid);
+       json_value_sep(jws_prot_hdr);
+       json_add_string(jws_prot_hdr, "alg", curve->jws_alg);
+       json_end_object(jws_prot_hdr);
+       signed1 = base64_url_encode(wpabuf_head(jws_prot_hdr),
+                                   wpabuf_len(jws_prot_hdr),
                                    &signed1_len);
+       wpabuf_free(jws_prot_hdr);
        signed2 = base64_url_encode(wpabuf_head(dppcon), wpabuf_len(dppcon),
                                    &signed2_len);
        if (!signed1 || !signed2)
@@ -4921,10 +4929,12 @@ skip_groups:
                akm_str = dpp_akm_selector_str(akm);
        else
                akm_str = dpp_akm_str(akm);
-       wpabuf_printf(buf, "\"cred\":{\"akm\":\"%s\",", akm_str);
+       json_start_object(buf, "cred");
+       json_add_string(buf, "akm", akm_str);
+       json_value_sep(buf);
        if (incl_legacy) {
                dpp_build_legacy_cred_params(buf, conf);
-               wpabuf_put_str(buf, ",");
+               json_value_sep(buf);
        }
        wpabuf_put_str(buf, "\"signedConnector\":\"");
        wpabuf_put_str(buf, signed1);
@@ -4932,14 +4942,16 @@ skip_groups:
        wpabuf_put_str(buf, signed2);
        wpabuf_put_u8(buf, '.');
        wpabuf_put_str(buf, signed3);
-       wpabuf_put_str(buf, "\",");
+       wpabuf_put_str(buf, "\"");
+       json_value_sep(buf);
        if (dpp_build_jwk(buf, "csign", auth->conf->csign, auth->conf->kid,
                          curve) < 0) {
                wpa_printf(MSG_DEBUG, "DPP: Failed to build csign JWK");
                goto fail;
        }
 
-       wpabuf_put_str(buf, "}}");
+       json_end_object(buf);
+       json_end_object(buf);
 
        wpa_hexdump_ascii_key(MSG_DEBUG, "DPP: Configuration Object",
                              wpabuf_head(buf), wpabuf_len(buf));
@@ -4976,9 +4988,12 @@ dpp_build_conf_obj_legacy(struct dpp_authentication *auth,
                akm_str = dpp_akm_selector_str(conf->akm);
        else
                akm_str = dpp_akm_str(conf->akm);
-       wpabuf_printf(buf, "\"cred\":{\"akm\":\"%s\",", akm_str);
+       json_start_object(buf, "cred");
+       json_add_string(buf, "akm", akm_str);
+       json_value_sep(buf);
        dpp_build_legacy_cred_params(buf, conf);
-       wpabuf_put_str(buf, "}}");
+       json_end_object(buf);
+       json_end_object(buf);
 
        wpa_hexdump_ascii_key(MSG_DEBUG, "DPP: Configuration Object (legacy)",
                              wpabuf_head(buf), wpabuf_len(buf));
@@ -6596,21 +6611,18 @@ struct wpabuf * dpp_build_conn_status_result(struct dpp_authentication *auth,
        json = wpabuf_alloc(1000);
        if (!json)
                return NULL;
-       wpabuf_printf(json, "{\"result\":%d", result);
+       json_start_object(json, NULL);
+       json_add_int(json, "result", result);
        if (ssid) {
-               char *ssid64;
-
-               ssid64 = base64_url_encode(ssid, ssid_len, NULL);
-               if (!ssid64)
+               json_value_sep(json);
+               if (json_add_base64url(json, "ssid64", ssid, ssid_len) < 0)
                        goto fail;
-               wpabuf_put_str(json, ",\"ssid64\":\"");
-               wpabuf_put_str(json, ssid64);
-               os_free(ssid64);
-               wpabuf_put_str(json, "\"");
-       }
-       if (channel_list)
-               wpabuf_printf(json, ",\"channelList\":\"%s\"", channel_list);
-       wpabuf_put_str(json, "}");
+       }
+       if (channel_list) {
+               json_value_sep(json);
+               json_add_string(json, "channelList", channel_list);
+       }
+       json_end_object(json);
        wpa_hexdump_ascii(MSG_DEBUG, "DPP: connStatus JSON",
                          wpabuf_head(json), wpabuf_len(json));