DPP: Use JSON token builder helpers

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
Jouni Malinen 2019-11-27 16:07:49 +02:00 committed by Jouni Malinen
parent e75ab53222
commit 590bc64d65

View file

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