DPP2: Allow multiple Config Objects to be build on Configurator

Special @CONF-OBJ-SEP@ string can now be used as a DPP configuration
string value to split the string into two different components to
configure two Config Objects for an Enrollee.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
Jouni Malinen 2019-09-25 03:49:41 +03:00 committed by Jouni Malinen
parent 99918e069a
commit 7eb06a3369
2 changed files with 78 additions and 12 deletions

View file

@ -4360,8 +4360,8 @@ void dpp_configuration_free(struct dpp_configuration *conf)
} }
static int dpp_configuration_parse(struct dpp_authentication *auth, static int dpp_configuration_parse_helper(struct dpp_authentication *auth,
const char *cmd) const char *cmd, int idx)
{ {
const char *pos, *end; const char *pos, *end;
struct dpp_configuration *conf_sta = NULL, *conf_ap = NULL; struct dpp_configuration *conf_sta = NULL, *conf_ap = NULL;
@ -4459,8 +4459,15 @@ static int dpp_configuration_parse(struct dpp_authentication *auth,
if (!dpp_configuration_valid(conf)) if (!dpp_configuration_valid(conf))
goto fail; goto fail;
if (idx == 0) {
auth->conf_sta = conf_sta; auth->conf_sta = conf_sta;
auth->conf_ap = conf_ap; auth->conf_ap = conf_ap;
} else if (idx == 1) {
auth->conf2_sta = conf_sta;
auth->conf2_ap = conf_ap;
} else {
goto fail;
}
return 0; return 0;
fail: fail:
@ -4470,6 +4477,41 @@ fail:
} }
static int dpp_configuration_parse(struct dpp_authentication *auth,
const char *cmd)
{
const char *pos;
char *tmp;
size_t len;
int res;
pos = os_strstr(cmd, " @CONF-OBJ-SEP@ ");
if (!pos)
return dpp_configuration_parse_helper(auth, cmd, 0);
len = pos - cmd;
tmp = os_malloc(len + 1);
if (!tmp)
goto fail;
os_memcpy(tmp, cmd, len);
tmp[len] = '\0';
res = dpp_configuration_parse_helper(auth, cmd, 0);
str_clear_free(tmp);
if (res)
goto fail;
res = dpp_configuration_parse_helper(auth, cmd + len, 1);
if (res)
goto fail;
return 0;
fail:
dpp_configuration_free(auth->conf_sta);
dpp_configuration_free(auth->conf2_sta);
dpp_configuration_free(auth->conf_ap);
dpp_configuration_free(auth->conf2_ap);
return -1;
}
static struct dpp_configurator * static struct dpp_configurator *
dpp_configurator_get_id(struct dpp_global *dpp, unsigned int id) dpp_configurator_get_id(struct dpp_global *dpp, unsigned int id)
{ {
@ -4529,7 +4571,9 @@ void dpp_auth_deinit(struct dpp_authentication *auth)
if (!auth) if (!auth)
return; return;
dpp_configuration_free(auth->conf_ap); dpp_configuration_free(auth->conf_ap);
dpp_configuration_free(auth->conf2_ap);
dpp_configuration_free(auth->conf_sta); dpp_configuration_free(auth->conf_sta);
dpp_configuration_free(auth->conf2_sta);
EVP_PKEY_free(auth->own_protocol_key); EVP_PKEY_free(auth->own_protocol_key);
EVP_PKEY_free(auth->peer_protocol_key); EVP_PKEY_free(auth->peer_protocol_key);
wpabuf_free(auth->req_msg); wpabuf_free(auth->req_msg);
@ -4898,20 +4942,28 @@ dpp_build_conf_obj_legacy(struct dpp_authentication *auth,
static struct wpabuf * static struct wpabuf *
dpp_build_conf_obj(struct dpp_authentication *auth, int ap) dpp_build_conf_obj(struct dpp_authentication *auth, int ap, int idx)
{ {
struct dpp_configuration *conf; struct dpp_configuration *conf;
#ifdef CONFIG_TESTING_OPTIONS #ifdef CONFIG_TESTING_OPTIONS
if (auth->config_obj_override) { if (auth->config_obj_override) {
if (idx != 0)
return NULL;
wpa_printf(MSG_DEBUG, "DPP: Testing - Config Object override"); wpa_printf(MSG_DEBUG, "DPP: Testing - Config Object override");
return wpabuf_alloc_copy(auth->config_obj_override, return wpabuf_alloc_copy(auth->config_obj_override,
os_strlen(auth->config_obj_override)); os_strlen(auth->config_obj_override));
} }
#endif /* CONFIG_TESTING_OPTIONS */ #endif /* CONFIG_TESTING_OPTIONS */
if (idx == 0)
conf = ap ? auth->conf_ap : auth->conf_sta; conf = ap ? auth->conf_ap : auth->conf_sta;
else if (idx == 1)
conf = ap ? auth->conf2_ap : auth->conf2_sta;
else
conf = NULL;
if (!conf) { if (!conf) {
if (idx != 0)
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"DPP: No configuration available for Enrollee(%s) - reject configuration request", "DPP: No configuration available for Enrollee(%s) - reject configuration request",
ap ? "ap" : "sta"); ap ? "ap" : "sta");
@ -4928,7 +4980,7 @@ static struct wpabuf *
dpp_build_conf_resp(struct dpp_authentication *auth, const u8 *e_nonce, dpp_build_conf_resp(struct dpp_authentication *auth, const u8 *e_nonce,
u16 e_nonce_len, int ap) u16 e_nonce_len, int ap)
{ {
struct wpabuf *conf; struct wpabuf *conf, *conf2 = NULL;
size_t clear_len, attr_len; size_t clear_len, attr_len;
struct wpabuf *clear = NULL, *msg = NULL; struct wpabuf *clear = NULL, *msg = NULL;
u8 *wrapped; u8 *wrapped;
@ -4936,10 +4988,11 @@ dpp_build_conf_resp(struct dpp_authentication *auth, const u8 *e_nonce,
size_t len[1]; size_t len[1];
enum dpp_status_error status; enum dpp_status_error status;
conf = dpp_build_conf_obj(auth, ap); conf = dpp_build_conf_obj(auth, ap, 0);
if (conf) { if (conf) {
wpa_hexdump_ascii(MSG_DEBUG, "DPP: configurationObject JSON", wpa_hexdump_ascii(MSG_DEBUG, "DPP: configurationObject JSON",
wpabuf_head(conf), wpabuf_len(conf)); wpabuf_head(conf), wpabuf_len(conf));
conf2 = dpp_build_conf_obj(auth, ap, 1);
} }
status = conf ? DPP_STATUS_OK : DPP_STATUS_CONFIGURE_FAILURE; status = conf ? DPP_STATUS_OK : DPP_STATUS_CONFIGURE_FAILURE;
auth->conf_resp_status = status; auth->conf_resp_status = status;
@ -4948,6 +5001,8 @@ dpp_build_conf_resp(struct dpp_authentication *auth, const u8 *e_nonce,
clear_len = 4 + e_nonce_len; clear_len = 4 + e_nonce_len;
if (conf) if (conf)
clear_len += 4 + wpabuf_len(conf); clear_len += 4 + wpabuf_len(conf);
if (conf2)
clear_len += 4 + wpabuf_len(conf2);
if (auth->peer_version >= 2 && auth->send_conn_status && !ap) if (auth->peer_version >= 2 && auth->send_conn_status && !ap)
clear_len += 4; clear_len += 4;
clear = wpabuf_alloc(clear_len); clear = wpabuf_alloc(clear_len);
@ -4997,6 +5052,14 @@ skip_e_nonce:
wpabuf_put_le16(clear, wpabuf_len(conf)); wpabuf_put_le16(clear, wpabuf_len(conf));
wpabuf_put_buf(clear, conf); wpabuf_put_buf(clear, conf);
} }
if (auth->peer_version >= 2 && conf2) {
wpabuf_put_le16(clear, DPP_ATTR_CONFIG_OBJ);
wpabuf_put_le16(clear, wpabuf_len(conf2));
wpabuf_put_buf(clear, conf2);
} else if (conf2) {
wpa_printf(MSG_DEBUG,
"DPP: Second Config Object available, but peer does not support more than one");
}
if (auth->peer_version >= 2 && auth->send_conn_status && !ap) { if (auth->peer_version >= 2 && auth->send_conn_status && !ap) {
wpa_printf(MSG_DEBUG, "DPP: sendConnStatus"); wpa_printf(MSG_DEBUG, "DPP: sendConnStatus");
@ -5051,6 +5114,7 @@ skip_wrapped_data:
"DPP: Configuration Response attributes", msg); "DPP: Configuration Response attributes", msg);
out: out:
wpabuf_free(conf); wpabuf_free(conf);
wpabuf_free(conf2);
wpabuf_free(clear); wpabuf_free(clear);
return msg; return msg;
@ -6612,7 +6676,7 @@ int dpp_configurator_own_config(struct dpp_authentication *auth,
auth->peer_protocol_key = auth->own_protocol_key; auth->peer_protocol_key = auth->own_protocol_key;
dpp_copy_csign(auth, auth->conf->csign); dpp_copy_csign(auth, auth->conf->csign);
conf_obj = dpp_build_conf_obj(auth, ap); conf_obj = dpp_build_conf_obj(auth, ap, 0);
if (!conf_obj) if (!conf_obj)
goto fail; goto fail;
ret = dpp_parse_conf_obj(auth, wpabuf_head(conf_obj), ret = dpp_parse_conf_obj(auth, wpabuf_head(conf_obj),

View file

@ -237,7 +237,9 @@ struct dpp_authentication {
struct wpabuf *conf_req; struct wpabuf *conf_req;
const struct wpabuf *conf_resp; /* owned by GAS server */ const struct wpabuf *conf_resp; /* owned by GAS server */
struct dpp_configuration *conf_ap; struct dpp_configuration *conf_ap;
struct dpp_configuration *conf2_ap;
struct dpp_configuration *conf_sta; struct dpp_configuration *conf_sta;
struct dpp_configuration *conf2_sta;
struct dpp_configurator *conf; struct dpp_configurator *conf;
char *connector; /* received signedConnector */ char *connector; /* received signedConnector */
u8 ssid[SSID_MAX_LEN]; u8 ssid[SSID_MAX_LEN];