DPP: Allowed initiator to indicate either role

The new role=either parameter can now be used with DPP_AUTH_INIT to
indicate that the initiator can take either the Configurator or Enrollee
role.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
Jouni Malinen 2017-11-13 11:29:45 +02:00 committed by Jouni Malinen
parent 751f7f7c42
commit d1f082644c
4 changed files with 49 additions and 17 deletions

View file

@ -458,7 +458,7 @@ int hostapd_dpp_auth_init(struct hostapd_data *hapd, const char *cmd)
struct dpp_bootstrap_info *peer_bi, *own_bi = NULL;
const u8 *dst;
int res;
int configurator = 1;
u8 allowed_roles = DPP_CAPAB_CONFIGURATOR;
struct dpp_configuration *conf_sta = NULL, *conf_ap = NULL;
pos = os_strstr(cmd, " peer=");
@ -494,9 +494,12 @@ int hostapd_dpp_auth_init(struct hostapd_data *hapd, const char *cmd)
if (pos) {
pos += 6;
if (os_strncmp(pos, "configurator", 12) == 0)
configurator = 1;
allowed_roles = DPP_CAPAB_CONFIGURATOR;
else if (os_strncmp(pos, "enrollee", 8) == 0)
configurator = 0;
allowed_roles = DPP_CAPAB_ENROLLEE;
else if (os_strncmp(pos, "either", 6) == 0)
allowed_roles = DPP_CAPAB_CONFIGURATOR |
DPP_CAPAB_ENROLLEE;
else
goto fail;
}
@ -505,7 +508,7 @@ int hostapd_dpp_auth_init(struct hostapd_data *hapd, const char *cmd)
dpp_auth_deinit(hapd->dpp_auth);
/* TODO: hw_modes */
hapd->dpp_auth = dpp_auth_init(hapd->msg_ctx, peer_bi, own_bi,
configurator, 0, NULL, 0);
allowed_roles, 0, NULL, 0);
if (!hapd->dpp_auth)
goto fail;
hostapd_dpp_set_testing_options(hapd, hapd->dpp_auth);

View file

@ -1468,8 +1468,7 @@ skip_i_nonce:
pos += 2;
WPA_PUT_LE16(pos, 1);
pos += 2;
auth->i_capab = auth->configurator ? DPP_CAPAB_CONFIGURATOR :
DPP_CAPAB_ENROLLEE;
auth->i_capab = auth->allowed_roles;
*pos++ = auth->i_capab;
#ifdef CONFIG_TESTING_OPTIONS
if (dpp_test == DPP_TEST_ZERO_I_CAPAB) {
@ -1646,6 +1645,10 @@ static struct wpabuf * dpp_auth_build_resp(struct dpp_authentication *auth,
} else if (dpp_test == DPP_TEST_INCOMPATIBLE_R_CAPAB_AUTH_RESP) {
wpa_printf(MSG_INFO,
"DPP: TESTING - incompatible R-capabilities");
if ((auth->i_capab & DPP_CAPAB_ROLE_MASK) ==
(DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE))
pos[-1] = 0;
else
pos[-1] = auth->configurator ? DPP_CAPAB_ENROLLEE :
DPP_CAPAB_CONFIGURATOR;
}
@ -1863,7 +1866,7 @@ static int dpp_prepare_channel_list(struct dpp_authentication *auth,
struct dpp_authentication * dpp_auth_init(void *msg_ctx,
struct dpp_bootstrap_info *peer_bi,
struct dpp_bootstrap_info *own_bi,
int configurator,
u8 dpp_allowed_roles,
unsigned int neg_freq,
struct hostapd_hw_modes *own_modes,
u16 num_modes)
@ -1882,7 +1885,8 @@ struct dpp_authentication * dpp_auth_init(void *msg_ctx,
auth->msg_ctx = msg_ctx;
auth->initiator = 1;
auth->waiting_auth_resp = 1;
auth->configurator = configurator;
auth->allowed_roles = dpp_allowed_roles;
auth->configurator = !!(dpp_allowed_roles & DPP_CAPAB_CONFIGURATOR);
auth->peer_bi = peer_bi;
auth->own_bi = own_bi;
auth->curve = peer_bi->curve;
@ -2720,6 +2724,19 @@ dpp_auth_req_rx(void *msg_ctx, u8 dpp_allowed_roles, int qr_mutual,
wpa_printf(MSG_DEBUG, "DPP: Acting as Enrollee");
auth->configurator = 0;
break;
case DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE:
if (dpp_allowed_roles & DPP_CAPAB_ENROLLEE) {
wpa_printf(MSG_DEBUG, "DPP: Acting as Enrollee");
auth->configurator = 0;
} else if (dpp_allowed_roles & DPP_CAPAB_CONFIGURATOR) {
wpa_printf(MSG_DEBUG, "DPP: Acting as Configurator");
auth->configurator = 1;
} else {
wpa_printf(MSG_DEBUG,
"DPP: Local policy does not allow Configurator/Enrollee role");
goto not_compatible;
}
break;
default:
wpa_printf(MSG_DEBUG, "DPP: Unexpected role in I-capabilities");
wpa_msg(auth->msg_ctx, MSG_INFO,
@ -3263,7 +3280,15 @@ dpp_auth_resp_rx(struct dpp_authentication *auth, const u8 *hdr,
auth->r_capab = r_capab[0];
wpa_printf(MSG_DEBUG, "DPP: R-capabilities: 0x%02x", auth->r_capab);
role = auth->r_capab & DPP_CAPAB_ROLE_MASK;
if ((auth->configurator && role != DPP_CAPAB_ENROLLEE) ||
if ((auth->allowed_roles ==
(DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE)) &&
(role == DPP_CAPAB_CONFIGURATOR || role == DPP_CAPAB_ENROLLEE)) {
/* Peer selected its role, so move from "either role" to the
* role that is compatible with peer's selection. */
auth->configurator = role == DPP_CAPAB_ENROLLEE;
wpa_printf(MSG_DEBUG, "DPP: Acting as %s",
auth->configurator ? "Configurator" : "Enrollee");
} else if ((auth->configurator && role != DPP_CAPAB_ENROLLEE) ||
(!auth->configurator && role != DPP_CAPAB_CONFIGURATOR)) {
wpa_printf(MSG_DEBUG, "DPP: Incompatible role selection");
wpa_msg(auth->msg_ctx, MSG_INFO, DPP_EVENT_FAIL

View file

@ -183,6 +183,7 @@ struct dpp_authentication {
u8 ke[DPP_MAX_HASH_LEN];
int initiator;
int waiting_auth_resp;
u8 allowed_roles;
int configurator;
int remove_on_tx_status;
int auth_success;
@ -308,7 +309,7 @@ struct hostapd_hw_modes;
struct dpp_authentication * dpp_auth_init(void *msg_ctx,
struct dpp_bootstrap_info *peer_bi,
struct dpp_bootstrap_info *own_bi,
int configurator,
u8 dpp_allowed_roles,
unsigned int neg_freq,
struct hostapd_hw_modes *own_modes,
u16 num_modes);

View file

@ -624,7 +624,7 @@ int wpas_dpp_auth_init(struct wpa_supplicant *wpa_s, const char *cmd)
{
const char *pos;
struct dpp_bootstrap_info *peer_bi, *own_bi = NULL;
int configurator = 1;
u8 allowed_roles = DPP_CAPAB_CONFIGURATOR;
unsigned int neg_freq = 0;
wpa_s->dpp_gas_client = 0;
@ -662,9 +662,12 @@ int wpas_dpp_auth_init(struct wpa_supplicant *wpa_s, const char *cmd)
if (pos) {
pos += 6;
if (os_strncmp(pos, "configurator", 12) == 0)
configurator = 1;
allowed_roles = DPP_CAPAB_CONFIGURATOR;
else if (os_strncmp(pos, "enrollee", 8) == 0)
configurator = 0;
allowed_roles = DPP_CAPAB_ENROLLEE;
else if (os_strncmp(pos, "either", 6) == 0)
allowed_roles = DPP_CAPAB_CONFIGURATOR |
DPP_CAPAB_ENROLLEE;
else
goto fail;
}
@ -685,7 +688,7 @@ int wpas_dpp_auth_init(struct wpa_supplicant *wpa_s, const char *cmd)
offchannel_send_action_done(wpa_s);
dpp_auth_deinit(wpa_s->dpp_auth);
}
wpa_s->dpp_auth = dpp_auth_init(wpa_s, peer_bi, own_bi, configurator,
wpa_s->dpp_auth = dpp_auth_init(wpa_s, peer_bi, own_bi, allowed_roles,
neg_freq,
wpa_s->hw.modes, wpa_s->hw.num_modes);
if (!wpa_s->dpp_auth)