DPP2: Add an automatic peer_bi entry for CSR matching if needed
This allows the DPP_CA_SET command to be targeting a specific DPP-CST event in cases where the Configurator did not receive the bootstrapping information for the peer. Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
parent
b25ddfe9d3
commit
8f88dcf050
4 changed files with 82 additions and 18 deletions
|
@ -1293,9 +1293,14 @@ void dpp_auth_deinit(struct dpp_authentication *auth)
|
||||||
wpabuf_free(auth->cacert);
|
wpabuf_free(auth->cacert);
|
||||||
wpabuf_free(auth->certbag);
|
wpabuf_free(auth->certbag);
|
||||||
os_free(auth->trusted_eap_server_name);
|
os_free(auth->trusted_eap_server_name);
|
||||||
|
wpabuf_free(auth->conf_resp_tcp);
|
||||||
#endif /* CONFIG_DPP2 */
|
#endif /* CONFIG_DPP2 */
|
||||||
wpabuf_free(auth->net_access_key);
|
wpabuf_free(auth->net_access_key);
|
||||||
dpp_bootstrap_info_free(auth->tmp_own_bi);
|
dpp_bootstrap_info_free(auth->tmp_own_bi);
|
||||||
|
if (auth->tmp_peer_bi) {
|
||||||
|
dl_list_del(&auth->tmp_peer_bi->list);
|
||||||
|
dpp_bootstrap_info_free(auth->tmp_peer_bi);
|
||||||
|
}
|
||||||
#ifdef CONFIG_TESTING_OPTIONS
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
os_free(auth->config_obj_override);
|
os_free(auth->config_obj_override);
|
||||||
os_free(auth->discovery_override);
|
os_free(auth->discovery_override);
|
||||||
|
@ -2044,6 +2049,7 @@ dpp_conf_req_rx(struct dpp_authentication *auth, const u8 *attr_start,
|
||||||
cert_req = json_get_member_base64(root, "pkcs10");
|
cert_req = json_get_member_base64(root, "pkcs10");
|
||||||
if (cert_req) {
|
if (cert_req) {
|
||||||
char *txt;
|
char *txt;
|
||||||
|
int id;
|
||||||
|
|
||||||
wpa_hexdump_buf(MSG_DEBUG, "DPP: CertificateRequest", cert_req);
|
wpa_hexdump_buf(MSG_DEBUG, "DPP: CertificateRequest", cert_req);
|
||||||
if (dpp_validate_csr(auth, cert_req) < 0) {
|
if (dpp_validate_csr(auth, cert_req) < 0) {
|
||||||
|
@ -2051,13 +2057,31 @@ dpp_conf_req_rx(struct dpp_authentication *auth, const u8 *attr_start,
|
||||||
auth->force_conf_resp_status = DPP_STATUS_CSR_BAD;
|
auth->force_conf_resp_status = DPP_STATUS_CSR_BAD;
|
||||||
goto cont;
|
goto cont;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (auth->peer_bi) {
|
||||||
|
id = auth->peer_bi->id;
|
||||||
|
} else if (auth->tmp_peer_bi) {
|
||||||
|
id = auth->tmp_peer_bi->id;
|
||||||
|
} else {
|
||||||
|
struct dpp_bootstrap_info *bi;
|
||||||
|
|
||||||
|
bi = os_zalloc(sizeof(*bi));
|
||||||
|
if (!bi)
|
||||||
|
goto fail;
|
||||||
|
bi->id = dpp_next_id(auth->global);
|
||||||
|
dl_list_add(&auth->global->bootstrap, &bi->list);
|
||||||
|
auth->tmp_peer_bi = bi;
|
||||||
|
id = bi->id;
|
||||||
|
}
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "DPP: CSR is valid - forward to CA/RA");
|
wpa_printf(MSG_DEBUG, "DPP: CSR is valid - forward to CA/RA");
|
||||||
txt = base64_encode_no_lf(wpabuf_head(cert_req),
|
txt = base64_encode_no_lf(wpabuf_head(cert_req),
|
||||||
wpabuf_len(cert_req), NULL);
|
wpabuf_len(cert_req), NULL);
|
||||||
if (!txt)
|
if (!txt)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
wpa_msg(auth->msg_ctx, MSG_INFO, DPP_EVENT_CSR "peer=%d csr=%s",
|
wpa_msg(auth->msg_ctx, MSG_INFO, DPP_EVENT_CSR "peer=%d csr=%s",
|
||||||
auth->peer_bi ? (int) auth->peer_bi->id : -1, txt);
|
id, txt);
|
||||||
os_free(txt);
|
os_free(txt);
|
||||||
auth->waiting_csr = false;
|
auth->waiting_csr = false;
|
||||||
auth->waiting_cert = true;
|
auth->waiting_cert = true;
|
||||||
|
|
|
@ -244,6 +244,7 @@ struct dpp_authentication {
|
||||||
struct dpp_bootstrap_info *peer_bi;
|
struct dpp_bootstrap_info *peer_bi;
|
||||||
struct dpp_bootstrap_info *own_bi;
|
struct dpp_bootstrap_info *own_bi;
|
||||||
struct dpp_bootstrap_info *tmp_own_bi;
|
struct dpp_bootstrap_info *tmp_own_bi;
|
||||||
|
struct dpp_bootstrap_info *tmp_peer_bi;
|
||||||
u8 waiting_pubkey_hash[SHA256_MAC_LEN];
|
u8 waiting_pubkey_hash[SHA256_MAC_LEN];
|
||||||
int response_pending;
|
int response_pending;
|
||||||
int reconfig;
|
int reconfig;
|
||||||
|
@ -298,6 +299,7 @@ struct dpp_authentication {
|
||||||
bool reconfig_success;
|
bool reconfig_success;
|
||||||
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 wpabuf *conf_resp_tcp;
|
||||||
struct dpp_configuration *conf_ap;
|
struct dpp_configuration *conf_ap;
|
||||||
struct dpp_configuration *conf2_ap;
|
struct dpp_configuration *conf2_ap;
|
||||||
struct dpp_configuration *conf_sta;
|
struct dpp_configuration *conf_sta;
|
||||||
|
@ -660,6 +662,8 @@ int dpp_relay_rx_gas_req(struct dpp_global *dpp, const u8 *src, const u8 *data,
|
||||||
int dpp_controller_start(struct dpp_global *dpp,
|
int dpp_controller_start(struct dpp_global *dpp,
|
||||||
struct dpp_controller_config *config);
|
struct dpp_controller_config *config);
|
||||||
void dpp_controller_stop(struct dpp_global *dpp);
|
void dpp_controller_stop(struct dpp_global *dpp);
|
||||||
|
struct dpp_authentication * dpp_controller_get_auth(struct dpp_global *dpp,
|
||||||
|
unsigned int id);
|
||||||
int dpp_tcp_init(struct dpp_global *dpp, struct dpp_authentication *auth,
|
int dpp_tcp_init(struct dpp_global *dpp, struct dpp_authentication *auth,
|
||||||
const struct hostapd_ip_addr *addr, int port,
|
const struct hostapd_ip_addr *addr, int port,
|
||||||
const char *name);
|
const char *name);
|
||||||
|
|
|
@ -40,7 +40,6 @@ struct dpp_connection {
|
||||||
unsigned int on_tcp_tx_complete_auth_ok:1;
|
unsigned int on_tcp_tx_complete_auth_ok:1;
|
||||||
unsigned int gas_comeback_in_progress:1;
|
unsigned int gas_comeback_in_progress:1;
|
||||||
u8 gas_dialog_token;
|
u8 gas_dialog_token;
|
||||||
struct wpabuf *gas_resp;
|
|
||||||
char *name;
|
char *name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -91,7 +90,6 @@ static void dpp_connection_free(struct dpp_connection *conn)
|
||||||
eloop_cancel_timeout(dpp_tcp_gas_query_comeback, conn, NULL);
|
eloop_cancel_timeout(dpp_tcp_gas_query_comeback, conn, NULL);
|
||||||
wpabuf_free(conn->msg);
|
wpabuf_free(conn->msg);
|
||||||
wpabuf_free(conn->msg_out);
|
wpabuf_free(conn->msg_out);
|
||||||
wpabuf_free(conn->gas_resp);
|
|
||||||
dpp_auth_deinit(conn->auth);
|
dpp_auth_deinit(conn->auth);
|
||||||
os_free(conn->name);
|
os_free(conn->name);
|
||||||
os_free(conn);
|
os_free(conn);
|
||||||
|
@ -1148,7 +1146,7 @@ static int dpp_controller_rx_gas_comeback_req(struct dpp_connection *conn,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!conn->gas_resp) {
|
if (!auth->conf_resp_tcp) {
|
||||||
wpa_printf(MSG_DEBUG, "DPP: Certificate not yet ready");
|
wpa_printf(MSG_DEBUG, "DPP: Certificate not yet ready");
|
||||||
return dpp_tcp_send_comeback_delay(conn,
|
return dpp_tcp_send_comeback_delay(conn,
|
||||||
WLAN_PA_GAS_COMEBACK_RESP);
|
WLAN_PA_GAS_COMEBACK_RESP);
|
||||||
|
@ -1156,8 +1154,8 @@ static int dpp_controller_rx_gas_comeback_req(struct dpp_connection *conn,
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
"DPP: Configuration response is ready to be sent out");
|
"DPP: Configuration response is ready to be sent out");
|
||||||
resp = conn->gas_resp;
|
resp = auth->conf_resp_tcp;
|
||||||
conn->gas_resp = NULL;
|
auth->conf_resp_tcp = NULL;
|
||||||
return dpp_tcp_send_gas_resp(conn, WLAN_PA_GAS_COMEBACK_RESP, resp);
|
return dpp_tcp_send_gas_resp(conn, WLAN_PA_GAS_COMEBACK_RESP, resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1665,6 +1663,28 @@ void dpp_controller_stop(struct dpp_global *dpp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct dpp_authentication * dpp_controller_get_auth(struct dpp_global *dpp,
|
||||||
|
unsigned int id)
|
||||||
|
{
|
||||||
|
struct dpp_controller *ctrl = dpp->controller;
|
||||||
|
struct dpp_connection *conn;
|
||||||
|
|
||||||
|
if (!ctrl)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
dl_list_for_each(conn, &ctrl->conn, struct dpp_connection, list) {
|
||||||
|
struct dpp_authentication *auth = conn->auth;
|
||||||
|
|
||||||
|
if (auth &&
|
||||||
|
((auth->peer_bi && auth->peer_bi->id == id) ||
|
||||||
|
(auth->tmp_peer_bi && auth->tmp_peer_bi->id == id)))
|
||||||
|
return auth;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void dpp_tcp_init_flush(struct dpp_global *dpp)
|
void dpp_tcp_init_flush(struct dpp_global *dpp)
|
||||||
{
|
{
|
||||||
struct dpp_connection *conn, *tmp;
|
struct dpp_connection *conn, *tmp;
|
||||||
|
|
|
@ -3632,7 +3632,7 @@ int wpas_dpp_reconfig(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
|
||||||
|
|
||||||
|
|
||||||
static int wpas_dpp_build_conf_resp(struct wpa_supplicant *wpa_s,
|
static int wpas_dpp_build_conf_resp(struct wpa_supplicant *wpa_s,
|
||||||
struct dpp_authentication *auth)
|
struct dpp_authentication *auth, bool tcp)
|
||||||
{
|
{
|
||||||
struct wpabuf *resp;
|
struct wpabuf *resp;
|
||||||
|
|
||||||
|
@ -3640,6 +3640,12 @@ static int wpas_dpp_build_conf_resp(struct wpa_supplicant *wpa_s,
|
||||||
auth->e_netrole, true);
|
auth->e_netrole, true);
|
||||||
if (!resp)
|
if (!resp)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (tcp) {
|
||||||
|
auth->conf_resp_tcp = resp;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (gas_server_set_resp(wpa_s->gas_server, auth->cert_resp_ctx,
|
if (gas_server_set_resp(wpa_s->gas_server, auth->cert_resp_ctx,
|
||||||
resp) < 0) {
|
resp) < 0) {
|
||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
|
@ -3654,12 +3660,23 @@ static int wpas_dpp_build_conf_resp(struct wpa_supplicant *wpa_s,
|
||||||
|
|
||||||
int wpas_dpp_ca_set(struct wpa_supplicant *wpa_s, const char *cmd)
|
int wpas_dpp_ca_set(struct wpa_supplicant *wpa_s, const char *cmd)
|
||||||
{
|
{
|
||||||
int peer;
|
int peer = -1;
|
||||||
const char *pos, *value;
|
const char *pos, *value;
|
||||||
struct dpp_authentication *auth = wpa_s->dpp_auth;
|
struct dpp_authentication *auth = wpa_s->dpp_auth;
|
||||||
u8 *bin;
|
u8 *bin;
|
||||||
size_t bin_len;
|
size_t bin_len;
|
||||||
struct wpabuf *buf;
|
struct wpabuf *buf;
|
||||||
|
bool tcp = false;
|
||||||
|
|
||||||
|
pos = os_strstr(cmd, " peer=");
|
||||||
|
if (pos) {
|
||||||
|
peer = atoi(pos + 6);
|
||||||
|
if (!auth || !auth->waiting_cert ||
|
||||||
|
(unsigned int) peer != auth->peer_bi->id) {
|
||||||
|
auth = dpp_controller_get_auth(wpa_s->dpp, peer);
|
||||||
|
tcp = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!auth || !auth->waiting_cert) {
|
if (!auth || !auth->waiting_cert) {
|
||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
|
@ -3667,15 +3684,14 @@ int wpas_dpp_ca_set(struct wpa_supplicant *wpa_s, const char *cmd)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = os_strstr(cmd, " peer=");
|
if (peer >= 0 &&
|
||||||
if (pos) {
|
(!auth->peer_bi ||
|
||||||
peer = atoi(pos + 6);
|
(unsigned int) peer != auth->peer_bi->id) &&
|
||||||
if (!auth->peer_bi ||
|
(!auth->tmp_peer_bi ||
|
||||||
(unsigned int) peer != auth->peer_bi->id) {
|
(unsigned int) peer != auth->tmp_peer_bi->id)) {
|
||||||
wpa_printf(MSG_DEBUG, "DPP: Peer mismatch");
|
wpa_printf(MSG_DEBUG, "DPP: Peer mismatch");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pos = os_strstr(cmd, " value=");
|
pos = os_strstr(cmd, " value=");
|
||||||
if (!pos)
|
if (!pos)
|
||||||
|
@ -3689,7 +3705,7 @@ int wpas_dpp_ca_set(struct wpa_supplicant *wpa_s, const char *cmd)
|
||||||
|
|
||||||
if (os_strncmp(pos, "status ", 7) == 0) {
|
if (os_strncmp(pos, "status ", 7) == 0) {
|
||||||
auth->force_conf_resp_status = atoi(value);
|
auth->force_conf_resp_status = atoi(value);
|
||||||
return wpas_dpp_build_conf_resp(wpa_s, auth);
|
return wpas_dpp_build_conf_resp(wpa_s, auth, tcp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (os_strncmp(pos, "trustedEapServerName ", 21) == 0) {
|
if (os_strncmp(pos, "trustedEapServerName ", 21) == 0) {
|
||||||
|
@ -3713,7 +3729,7 @@ int wpas_dpp_ca_set(struct wpa_supplicant *wpa_s, const char *cmd)
|
||||||
if (os_strncmp(pos, "certBag ", 8) == 0) {
|
if (os_strncmp(pos, "certBag ", 8) == 0) {
|
||||||
wpabuf_free(auth->certbag);
|
wpabuf_free(auth->certbag);
|
||||||
auth->certbag = buf;
|
auth->certbag = buf;
|
||||||
return wpas_dpp_build_conf_resp(wpa_s, auth);
|
return wpas_dpp_build_conf_resp(wpa_s, auth, tcp);
|
||||||
}
|
}
|
||||||
|
|
||||||
wpabuf_free(buf);
|
wpabuf_free(buf);
|
||||||
|
|
Loading…
Reference in a new issue