dpp-util: add dpp_parse_configuration_object

This parses the configuration JSON object from the configuration
response. Only a minimal configuration object is supported for
now.
This commit is contained in:
James Prestwood 2021-12-16 10:08:51 -08:00 committed by Denis Kenzior
parent 683d3a3f04
commit 992deb36d4
3 changed files with 123 additions and 1 deletions

View File

@ -552,7 +552,8 @@ unit_test_p2p_LDADD = $(ell_ldadd)
unit_test_dpp_SOURCES = unit/test-dpp.c src/dpp-util.h src/dpp-util.c \
src/band.h src/band.c \
src/util.h src/util.c src/crypto.h src/crypto.c
src/util.h src/util.c src/crypto.h \
src/crypto.c src/json.h src/json.c
unit_test_dpp_LDADD = $(ell_ldadd)
unit_test_json_SOURCES = unit/test-json.c src/json.h src/json.c shared/jsmn.h

View File

@ -34,6 +34,9 @@
#include "src/util.h"
#include "src/band.h"
#include "src/crypto.h"
#include "src/json.h"
#include "ell/useful.h"
#include "src/ie.h"
static void append_freqs(struct l_string *uri,
const uint32_t *freqs, size_t len)
@ -95,6 +98,112 @@ char *dpp_generate_uri(const uint8_t *asn1, size_t asn1_len, uint8_t version,
return l_string_unwrap(uri);
}
static uint32_t dpp_parse_akm(char *akms)
{
_auto_(l_strv_free) char **split = l_strsplit(akms, '+');
char **i = split;
uint32_t akm_out = 0;
while (*i) {
if (!strncmp(*i, "psk", 3))
akm_out |= IE_RSN_AKM_SUITE_PSK;
else if (!strncmp(*i, "sae", 3))
akm_out |= IE_RSN_AKM_SUITE_SAE_SHA256;
i++;
}
return akm_out;
}
/*
* TODO: This handles the most basic configuration. i.e. a configuration object
* with ssid/passphrase/akm.
*/
struct dpp_configuration *dpp_parse_configuration_object(const char *json,
size_t json_len)
{
struct dpp_configuration *config;
struct json_contents *c;
struct json_iter iter;
struct json_iter discovery;
struct json_iter cred;
_auto_(l_free) char *tech = NULL;
_auto_(l_free) char *ssid = NULL;
_auto_(l_free) char *akm = NULL;
_auto_(l_free) char *pass = NULL;
_auto_(l_free) char *psk = NULL;
c = json_contents_new(json, json_len);
if (!c)
return NULL;
json_iter_init(&iter, c);
if (!json_iter_parse(&iter,
JSON_MANDATORY("wi-fi_tech", JSON_STRING, &tech),
JSON_MANDATORY("discovery", JSON_OBJECT, &discovery),
JSON_MANDATORY("cred", JSON_OBJECT, &cred),
JSON_UNDEFINED))
goto free_contents;
if (!tech || strncmp(tech, "infra", 5))
goto free_contents;
if (!json_iter_parse(&discovery,
JSON_MANDATORY("ssid", JSON_STRING, &ssid),
JSON_UNDEFINED))
goto free_contents;
if (!ssid || !util_ssid_is_utf8(strlen(ssid),(const uint8_t *)ssid))
goto free_contents;
if (!json_iter_parse(&cred,
JSON_MANDATORY("akm", JSON_STRING, &akm),
JSON_OPTIONAL("pass", JSON_STRING, &pass),
JSON_OPTIONAL("psk", JSON_STRING, &psk),
JSON_UNDEFINED))
goto free_contents;
if (!pass && (!psk || strlen(psk) != 64))
goto free_contents;
config = l_new(struct dpp_configuration, 1);
if (pass)
config->passphrase = l_steal_ptr(pass);
else
config->psk = l_steal_ptr(psk);
memcpy(config->ssid, ssid, strlen(ssid));
config->ssid_len = strlen(ssid);
config->akm_suites = dpp_parse_akm(akm);
if (!config->akm_suites)
goto free_config;
json_contents_free(c);
return config;
free_config:
dpp_configuration_free(config);
free_contents:
json_contents_free(c);
return NULL;
}
void dpp_configuration_free(struct dpp_configuration *config)
{
if (config->passphrase)
l_free(config->passphrase);
if (config->psk)
l_free(config->psk);
l_free(config);
}
void dpp_attr_iter_init(struct dpp_attr_iter *iter, const uint8_t *pdu,
size_t len)
{

View File

@ -100,6 +100,18 @@ enum dpp_attribute_type {
DPP_ATTR_CONFIGURATOR_NONCE = 0x1022,
};
struct dpp_configuration {
uint8_t ssid[32];
size_t ssid_len;
uint32_t akm_suites;
char *passphrase;
char *psk; /* hex string */
};
struct dpp_configuration *dpp_parse_configuration_object(const char *json,
size_t json_len);
void dpp_configuration_free(struct dpp_configuration *conf);
struct dpp_attr_iter {
const uint8_t *pos;
const uint8_t *end;