wpabuf_free(auth->cacert);
wpabuf_free(auth->certbag);
os_free(auth->trusted_eap_server_name);
+ wpabuf_free(auth->conf_resp_tcp);
#endif /* CONFIG_DPP2 */
wpabuf_free(auth->net_access_key);
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
os_free(auth->config_obj_override);
os_free(auth->discovery_override);
cert_req = json_get_member_base64(root, "pkcs10");
if (cert_req) {
char *txt;
+ int id;
wpa_hexdump_buf(MSG_DEBUG, "DPP: CertificateRequest", cert_req);
if (dpp_validate_csr(auth, cert_req) < 0) {
auth->force_conf_resp_status = DPP_STATUS_CSR_BAD;
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");
txt = base64_encode_no_lf(wpabuf_head(cert_req),
wpabuf_len(cert_req), NULL);
if (!txt)
goto fail;
+
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);
auth->waiting_csr = false;
auth->waiting_cert = true;
struct dpp_bootstrap_info *peer_bi;
struct dpp_bootstrap_info *own_bi;
struct dpp_bootstrap_info *tmp_own_bi;
+ struct dpp_bootstrap_info *tmp_peer_bi;
u8 waiting_pubkey_hash[SHA256_MAC_LEN];
int response_pending;
int reconfig;
bool reconfig_success;
struct wpabuf *conf_req;
const struct wpabuf *conf_resp; /* owned by GAS server */
+ struct wpabuf *conf_resp_tcp;
struct dpp_configuration *conf_ap;
struct dpp_configuration *conf2_ap;
struct dpp_configuration *conf_sta;
int dpp_controller_start(struct dpp_global *dpp,
struct dpp_controller_config *config);
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,
const struct hostapd_ip_addr *addr, int port,
const char *name);
unsigned int on_tcp_tx_complete_auth_ok:1;
unsigned int gas_comeback_in_progress:1;
u8 gas_dialog_token;
- struct wpabuf *gas_resp;
char *name;
};
eloop_cancel_timeout(dpp_tcp_gas_query_comeback, conn, NULL);
wpabuf_free(conn->msg);
wpabuf_free(conn->msg_out);
- wpabuf_free(conn->gas_resp);
dpp_auth_deinit(conn->auth);
os_free(conn->name);
os_free(conn);
return -1;
}
- if (!conn->gas_resp) {
+ if (!auth->conf_resp_tcp) {
wpa_printf(MSG_DEBUG, "DPP: Certificate not yet ready");
return dpp_tcp_send_comeback_delay(conn,
WLAN_PA_GAS_COMEBACK_RESP);
wpa_printf(MSG_DEBUG,
"DPP: Configuration response is ready to be sent out");
- resp = conn->gas_resp;
- conn->gas_resp = NULL;
+ resp = auth->conf_resp_tcp;
+ auth->conf_resp_tcp = NULL;
return dpp_tcp_send_gas_resp(conn, WLAN_PA_GAS_COMEBACK_RESP, resp);
}
}
+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)
{
struct dpp_connection *conn, *tmp;
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;
auth->e_netrole, true);
if (!resp)
return -1;
+
+ if (tcp) {
+ auth->conf_resp_tcp = resp;
+ return 0;
+ }
+
if (gas_server_set_resp(wpa_s->gas_server, auth->cert_resp_ctx,
resp) < 0) {
wpa_printf(MSG_DEBUG,
int wpas_dpp_ca_set(struct wpa_supplicant *wpa_s, const char *cmd)
{
- int peer;
+ int peer = -1;
const char *pos, *value;
struct dpp_authentication *auth = wpa_s->dpp_auth;
u8 *bin;
size_t bin_len;
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) {
wpa_printf(MSG_DEBUG,
return -1;
}
- pos = os_strstr(cmd, " peer=");
- if (pos) {
- peer = atoi(pos + 6);
- if (!auth->peer_bi ||
- (unsigned int) peer != auth->peer_bi->id) {
- wpa_printf(MSG_DEBUG, "DPP: Peer mismatch");
- return -1;
- }
+ if (peer >= 0 &&
+ (!auth->peer_bi ||
+ (unsigned int) peer != auth->peer_bi->id) &&
+ (!auth->tmp_peer_bi ||
+ (unsigned int) peer != auth->tmp_peer_bi->id)) {
+ wpa_printf(MSG_DEBUG, "DPP: Peer mismatch");
+ return -1;
}
pos = os_strstr(cmd, " value=");
if (os_strncmp(pos, "status ", 7) == 0) {
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, "certBag ", 8) == 0) {
wpabuf_free(auth->certbag);
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);