DPP: Received Configurator backup processing

Add local Configurator instance for each received Configurator backup.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
Jouni Malinen 2020-01-30 23:56:31 +02:00 committed by Jouni Malinen
parent ea91ddb08a
commit 7d9e320054
5 changed files with 135 additions and 25 deletions

View File

@ -762,6 +762,33 @@ static void hostapd_dpp_handle_config_obj(struct hostapd_data *hapd,
}
static int hostapd_dpp_handle_key_pkg(struct hostapd_data *hapd,
struct dpp_asymmetric_key *key)
{
#ifdef CONFIG_DPP2
int res;
if (!key)
return 0;
wpa_printf(MSG_DEBUG, "DPP: Received Configurator backup");
wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_RECEIVED);
while (key) {
res = dpp_configurator_from_backup(
hapd->iface->interfaces->dpp, key);
if (res < 0)
return -1;
wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFIGURATOR_ID "%d",
res);
key = key->next;
}
#endif /* CONFIG_DPP2 */
return 0;
}
static void hostapd_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token,
enum gas_query_ap_result result,
const struct wpabuf *adv_proto,
@ -806,6 +833,9 @@ static void hostapd_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token,
}
hostapd_dpp_handle_config_obj(hapd, auth, &auth->conf_obj[0]);
if (hostapd_dpp_handle_key_pkg(hapd, auth->conf_key_pkg) < 0)
goto fail;
status = DPP_STATUS_OK;
#ifdef CONFIG_TESTING_OPTIONS
if (dpp_test == DPP_TEST_REJECT_CONFIG) {

View File

@ -7590,15 +7590,41 @@ int dpp_configurator_get_key(const struct dpp_configurator *conf, char *buf,
}
static int dpp_configurator_gen_kid(struct dpp_configurator *conf)
{
struct wpabuf *csign_pub = NULL;
u8 kid_hash[SHA256_MAC_LEN];
const u8 *addr[1];
size_t len[1];
int res;
csign_pub = dpp_get_pubkey_point(conf->csign, 1);
if (!csign_pub) {
wpa_printf(MSG_INFO, "DPP: Failed to extract C-sign-key");
return -1;
}
/* kid = SHA256(ANSI X9.63 uncompressed C-sign-key) */
addr[0] = wpabuf_head(csign_pub);
len[0] = wpabuf_len(csign_pub);
res = sha256_vector(1, addr, len, kid_hash);
wpabuf_free(csign_pub);
if (res < 0) {
wpa_printf(MSG_DEBUG,
"DPP: Failed to derive kid for C-sign-key");
return -1;
}
conf->kid = base64_url_encode(kid_hash, sizeof(kid_hash), NULL);
return conf->kid ? 0 : -1;
}
struct dpp_configurator *
dpp_keygen_configurator(const char *curve, const u8 *privkey,
size_t privkey_len)
{
struct dpp_configurator *conf;
struct wpabuf *csign_pub = NULL;
u8 kid_hash[SHA256_MAC_LEN];
const u8 *addr[1];
size_t len[1];
conf = os_zalloc(sizeof(*conf));
if (!conf)
@ -7624,31 +7650,12 @@ dpp_keygen_configurator(const char *curve, const u8 *privkey,
goto fail;
conf->own = 1;
csign_pub = dpp_get_pubkey_point(conf->csign, 1);
if (!csign_pub) {
wpa_printf(MSG_INFO, "DPP: Failed to extract C-sign-key");
if (dpp_configurator_gen_kid(conf) < 0)
goto fail;
}
/* kid = SHA256(ANSI X9.63 uncompressed C-sign-key) */
addr[0] = wpabuf_head(csign_pub);
len[0] = wpabuf_len(csign_pub);
if (sha256_vector(1, addr, len, kid_hash) < 0) {
wpa_printf(MSG_DEBUG,
"DPP: Failed to derive kid for C-sign-key");
goto fail;
}
conf->kid = base64_url_encode(kid_hash, sizeof(kid_hash), NULL);
if (!conf->kid)
goto fail;
out:
wpabuf_free(csign_pub);
return conf;
fail:
dpp_configurator_free(conf);
conf = NULL;
goto out;
return NULL;
}
@ -10206,6 +10213,48 @@ int dpp_configurator_get_key_id(struct dpp_global *dpp, unsigned int id,
#ifdef CONFIG_DPP2
int dpp_configurator_from_backup(struct dpp_global *dpp,
struct dpp_asymmetric_key *key)
{
struct dpp_configurator *conf;
const EC_KEY *eckey;
const EC_GROUP *group;
int nid;
const struct dpp_curve_params *curve;
if (!key->csign)
return -1;
eckey = EVP_PKEY_get0_EC_KEY(key->csign);
if (!eckey)
return -1;
group = EC_KEY_get0_group(eckey);
if (!group)
return -1;
nid = EC_GROUP_get_curve_name(group);
curve = dpp_get_curve_nid(nid);
if (!curve) {
wpa_printf(MSG_INFO, "DPP: Unsupported group in c-sign-key");
return -1;
}
conf = os_zalloc(sizeof(*conf));
if (!conf)
return -1;
conf->curve = curve;
conf->csign = key->csign;
key->csign = NULL;
conf->own = 1;
if (dpp_configurator_gen_kid(conf) < 0) {
dpp_configurator_free(conf);
return -1;
}
conf->id = dpp_next_configurator_id(dpp);
dl_list_add(&dpp->configurator, &conf->list);
return conf->id;
}
static void dpp_controller_conn_status_result_wait_timeout(void *eloop_ctx,
void *timeout_ctx);

View File

@ -566,6 +566,8 @@ int dpp_configurator_add(struct dpp_global *dpp, const char *cmd);
int dpp_configurator_remove(struct dpp_global *dpp, const char *id);
int dpp_configurator_get_key_id(struct dpp_global *dpp, unsigned int id,
char *buf, size_t buflen);
int dpp_configurator_from_backup(struct dpp_global *dpp,
struct dpp_asymmetric_key *key);
int dpp_relay_add_controller(struct dpp_global *dpp,
struct dpp_relay_config *config);
int dpp_relay_rx_action(struct dpp_global *dpp, const u8 *src, const u8 *hdr,

View File

@ -179,6 +179,7 @@ extern "C" {
#define DPP_EVENT_NET_ACCESS_KEY "DPP-NET-ACCESS-KEY "
#define DPP_EVENT_MISSING_CONNECTOR "DPP-MISSING-CONNECTOR "
#define DPP_EVENT_NETWORK_ID "DPP-NETWORK-ID "
#define DPP_EVENT_CONFIGURATOR_ID "DPP-CONFIGURATOR-ID "
#define DPP_EVENT_RX "DPP-RX "
#define DPP_EVENT_TX "DPP-TX "
#define DPP_EVENT_TX_STATUS "DPP-TX-STATUS "

View File

@ -1262,6 +1262,32 @@ static int wpas_dpp_handle_config_obj(struct wpa_supplicant *wpa_s,
}
static int wpas_dpp_handle_key_pkg(struct wpa_supplicant *wpa_s,
struct dpp_asymmetric_key *key)
{
#ifdef CONFIG_DPP2
int res;
if (!key)
return 0;
wpa_printf(MSG_DEBUG, "DPP: Received Configurator backup");
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_RECEIVED);
while (key) {
res = dpp_configurator_from_backup(wpa_s->dpp, key);
if (res < 0)
return -1;
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONFIGURATOR_ID "%d",
res);
key = key->next;
}
#endif /* CONFIG_DPP2 */
return 0;
}
static void wpas_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token,
enum gas_query_result result,
const struct wpabuf *adv_proto,
@ -1318,6 +1344,8 @@ static void wpas_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token,
}
if (auth->num_conf_obj)
wpas_dpp_post_process_config(wpa_s, auth);
if (wpas_dpp_handle_key_pkg(wpa_s, auth->conf_key_pkg) < 0)
goto fail;
status = DPP_STATUS_OK;
#ifdef CONFIG_TESTING_OPTIONS