Home | History | Annotate | Download | only in ap
      1 /*
      2  * hostapd / DPP integration
      3  * Copyright (c) 2017, Qualcomm Atheros, Inc.
      4  *
      5  * This software may be distributed under the terms of the BSD license.
      6  * See README for more details.
      7  */
      8 
      9 #include "utils/includes.h"
     10 
     11 #include "utils/common.h"
     12 #include "utils/eloop.h"
     13 #include "common/dpp.h"
     14 #include "common/gas.h"
     15 #include "common/wpa_ctrl.h"
     16 #include "hostapd.h"
     17 #include "ap_drv_ops.h"
     18 #include "gas_query_ap.h"
     19 #include "wpa_auth.h"
     20 #include "dpp_hostapd.h"
     21 
     22 
     23 static void hostapd_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx);
     24 static void hostapd_dpp_auth_success(struct hostapd_data *hapd, int initiator);
     25 static void hostapd_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx);
     26 static int hostapd_dpp_auth_init_next(struct hostapd_data *hapd);
     27 
     28 static const u8 broadcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
     29 
     30 
     31 /**
     32  * hostapd_dpp_qr_code - Parse and add DPP bootstrapping info from a QR Code
     33  * @hapd: Pointer to hostapd_data
     34  * @cmd: DPP URI read from a QR Code
     35  * Returns: Identifier of the stored info or -1 on failure
     36  */
     37 int hostapd_dpp_qr_code(struct hostapd_data *hapd, const char *cmd)
     38 {
     39 	struct dpp_bootstrap_info *bi;
     40 	struct dpp_authentication *auth = hapd->dpp_auth;
     41 
     42 	bi = dpp_add_qr_code(hapd->iface->interfaces->dpp, cmd);
     43 	if (!bi)
     44 		return -1;
     45 
     46 	if (auth && auth->response_pending &&
     47 	    dpp_notify_new_qr_code(auth, bi) == 1) {
     48 		wpa_printf(MSG_DEBUG,
     49 			   "DPP: Sending out pending authentication response");
     50 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
     51 			" freq=%u type=%d",
     52 			MAC2STR(auth->peer_mac_addr), auth->curr_freq,
     53 			DPP_PA_AUTHENTICATION_RESP);
     54 		hostapd_drv_send_action(hapd, auth->curr_freq, 0,
     55 					auth->peer_mac_addr,
     56 					wpabuf_head(hapd->dpp_auth->resp_msg),
     57 					wpabuf_len(hapd->dpp_auth->resp_msg));
     58 	}
     59 
     60 	return bi->id;
     61 }
     62 
     63 
     64 static void hostapd_dpp_auth_resp_retry_timeout(void *eloop_ctx,
     65 						void *timeout_ctx)
     66 {
     67 	struct hostapd_data *hapd = eloop_ctx;
     68 	struct dpp_authentication *auth = hapd->dpp_auth;
     69 
     70 	if (!auth || !auth->resp_msg)
     71 		return;
     72 
     73 	wpa_printf(MSG_DEBUG,
     74 		   "DPP: Retry Authentication Response after timeout");
     75 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
     76 		" freq=%u type=%d",
     77 		MAC2STR(auth->peer_mac_addr), auth->curr_freq,
     78 		DPP_PA_AUTHENTICATION_RESP);
     79 	hostapd_drv_send_action(hapd, auth->curr_freq, 500, auth->peer_mac_addr,
     80 				wpabuf_head(auth->resp_msg),
     81 				wpabuf_len(auth->resp_msg));
     82 }
     83 
     84 
     85 static void hostapd_dpp_auth_resp_retry(struct hostapd_data *hapd)
     86 {
     87 	struct dpp_authentication *auth = hapd->dpp_auth;
     88 	unsigned int wait_time, max_tries;
     89 
     90 	if (!auth || !auth->resp_msg)
     91 		return;
     92 
     93 	if (hapd->dpp_resp_max_tries)
     94 		max_tries = hapd->dpp_resp_max_tries;
     95 	else
     96 		max_tries = 5;
     97 	auth->auth_resp_tries++;
     98 	if (auth->auth_resp_tries >= max_tries) {
     99 		wpa_printf(MSG_INFO,
    100 			   "DPP: No confirm received from initiator - stopping exchange");
    101 		hostapd_drv_send_action_cancel_wait(hapd);
    102 		dpp_auth_deinit(hapd->dpp_auth);
    103 		hapd->dpp_auth = NULL;
    104 		return;
    105 	}
    106 
    107 	if (hapd->dpp_resp_retry_time)
    108 		wait_time = hapd->dpp_resp_retry_time;
    109 	else
    110 		wait_time = 1000;
    111 	wpa_printf(MSG_DEBUG,
    112 		   "DPP: Schedule retransmission of Authentication Response frame in %u ms",
    113 		wait_time);
    114 	eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
    115 	eloop_register_timeout(wait_time / 1000,
    116 			       (wait_time % 1000) * 1000,
    117 			       hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
    118 }
    119 
    120 
    121 void hostapd_dpp_tx_status(struct hostapd_data *hapd, const u8 *dst,
    122 			   const u8 *data, size_t data_len, int ok)
    123 {
    124 	struct dpp_authentication *auth = hapd->dpp_auth;
    125 
    126 	wpa_printf(MSG_DEBUG, "DPP: TX status: dst=" MACSTR " ok=%d",
    127 		   MAC2STR(dst), ok);
    128 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX_STATUS "dst=" MACSTR
    129 		" result=%s", MAC2STR(dst), ok ? "SUCCESS" : "FAILED");
    130 
    131 	if (!hapd->dpp_auth) {
    132 		wpa_printf(MSG_DEBUG,
    133 			   "DPP: Ignore TX status since there is no ongoing authentication exchange");
    134 		return;
    135 	}
    136 
    137 #ifdef CONFIG_DPP2
    138 	if (auth->connect_on_tx_status) {
    139 		wpa_printf(MSG_DEBUG,
    140 			   "DPP: Complete exchange on configuration result");
    141 		dpp_auth_deinit(hapd->dpp_auth);
    142 		hapd->dpp_auth = NULL;
    143 		return;
    144 	}
    145 #endif /* CONFIG_DPP2 */
    146 
    147 	if (hapd->dpp_auth->remove_on_tx_status) {
    148 		wpa_printf(MSG_DEBUG,
    149 			   "DPP: Terminate authentication exchange due to an earlier error");
    150 		eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
    151 		eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
    152 				     hapd, NULL);
    153 		eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd,
    154 				     NULL);
    155 		hostapd_drv_send_action_cancel_wait(hapd);
    156 		dpp_auth_deinit(hapd->dpp_auth);
    157 		hapd->dpp_auth = NULL;
    158 		return;
    159 	}
    160 
    161 	if (hapd->dpp_auth_ok_on_ack)
    162 		hostapd_dpp_auth_success(hapd, 1);
    163 
    164 	if (!is_broadcast_ether_addr(dst) && !ok) {
    165 		wpa_printf(MSG_DEBUG,
    166 			   "DPP: Unicast DPP Action frame was not ACKed");
    167 		if (auth->waiting_auth_resp) {
    168 			/* In case of DPP Authentication Request frame, move to
    169 			 * the next channel immediately. */
    170 			hostapd_drv_send_action_cancel_wait(hapd);
    171 			hostapd_dpp_auth_init_next(hapd);
    172 			return;
    173 		}
    174 		if (auth->waiting_auth_conf) {
    175 			hostapd_dpp_auth_resp_retry(hapd);
    176 			return;
    177 		}
    178 	}
    179 
    180 	if (!is_broadcast_ether_addr(dst) && auth->waiting_auth_resp && ok) {
    181 		/* Allow timeout handling to stop iteration if no response is
    182 		 * received from a peer that has ACKed a request. */
    183 		auth->auth_req_ack = 1;
    184 	}
    185 
    186 	if (!hapd->dpp_auth_ok_on_ack && hapd->dpp_auth->neg_freq > 0 &&
    187 	    hapd->dpp_auth->curr_freq != hapd->dpp_auth->neg_freq) {
    188 		wpa_printf(MSG_DEBUG,
    189 			   "DPP: Move from curr_freq %u MHz to neg_freq %u MHz for response",
    190 			   hapd->dpp_auth->curr_freq,
    191 			   hapd->dpp_auth->neg_freq);
    192 		hostapd_drv_send_action_cancel_wait(hapd);
    193 
    194 		if (hapd->dpp_auth->neg_freq !=
    195 		    (unsigned int) hapd->iface->freq && hapd->iface->freq > 0) {
    196 			/* TODO: Listen operation on non-operating channel */
    197 			wpa_printf(MSG_INFO,
    198 				   "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)",
    199 				   hapd->dpp_auth->neg_freq, hapd->iface->freq);
    200 		}
    201 	}
    202 
    203 	if (hapd->dpp_auth_ok_on_ack)
    204 		hapd->dpp_auth_ok_on_ack = 0;
    205 }
    206 
    207 
    208 static void hostapd_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx)
    209 {
    210 	struct hostapd_data *hapd = eloop_ctx;
    211 	struct dpp_authentication *auth = hapd->dpp_auth;
    212 	unsigned int freq;
    213 	struct os_reltime now, diff;
    214 	unsigned int wait_time, diff_ms;
    215 
    216 	if (!auth || !auth->waiting_auth_resp)
    217 		return;
    218 
    219 	wait_time = hapd->dpp_resp_wait_time ?
    220 		hapd->dpp_resp_wait_time : 2000;
    221 	os_get_reltime(&now);
    222 	os_reltime_sub(&now, &hapd->dpp_last_init, &diff);
    223 	diff_ms = diff.sec * 1000 + diff.usec / 1000;
    224 	wpa_printf(MSG_DEBUG,
    225 		   "DPP: Reply wait timeout - wait_time=%u diff_ms=%u",
    226 		   wait_time, diff_ms);
    227 
    228 	if (auth->auth_req_ack && diff_ms >= wait_time) {
    229 		/* Peer ACK'ed Authentication Request frame, but did not reply
    230 		 * with Authentication Response frame within two seconds. */
    231 		wpa_printf(MSG_INFO,
    232 			   "DPP: No response received from responder - stopping initiation attempt");
    233 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_AUTH_INIT_FAILED);
    234 		hostapd_drv_send_action_cancel_wait(hapd);
    235 		hostapd_dpp_listen_stop(hapd);
    236 		dpp_auth_deinit(auth);
    237 		hapd->dpp_auth = NULL;
    238 		return;
    239 	}
    240 
    241 	if (diff_ms >= wait_time) {
    242 		/* Authentication Request frame was not ACK'ed and no reply
    243 		 * was receiving within two seconds. */
    244 		wpa_printf(MSG_DEBUG,
    245 			   "DPP: Continue Initiator channel iteration");
    246 		hostapd_drv_send_action_cancel_wait(hapd);
    247 		hostapd_dpp_listen_stop(hapd);
    248 		hostapd_dpp_auth_init_next(hapd);
    249 		return;
    250 	}
    251 
    252 	/* Driver did not support 2000 ms long wait_time with TX command, so
    253 	 * schedule listen operation to continue waiting for the response.
    254 	 *
    255 	 * DPP listen operations continue until stopped, so simply schedule a
    256 	 * new call to this function at the point when the two second reply
    257 	 * wait has expired. */
    258 	wait_time -= diff_ms;
    259 
    260 	freq = auth->curr_freq;
    261 	if (auth->neg_freq > 0)
    262 		freq = auth->neg_freq;
    263 	wpa_printf(MSG_DEBUG,
    264 		   "DPP: Continue reply wait on channel %u MHz for %u ms",
    265 		   freq, wait_time);
    266 	hapd->dpp_in_response_listen = 1;
    267 
    268 	if (freq != (unsigned int) hapd->iface->freq && hapd->iface->freq > 0) {
    269 		/* TODO: Listen operation on non-operating channel */
    270 		wpa_printf(MSG_INFO,
    271 			   "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)",
    272 			   freq, hapd->iface->freq);
    273 	}
    274 
    275 	eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
    276 			       hostapd_dpp_reply_wait_timeout, hapd, NULL);
    277 }
    278 
    279 
    280 static void hostapd_dpp_set_testing_options(struct hostapd_data *hapd,
    281 					    struct dpp_authentication *auth)
    282 {
    283 #ifdef CONFIG_TESTING_OPTIONS
    284 	if (hapd->dpp_config_obj_override)
    285 		auth->config_obj_override =
    286 			os_strdup(hapd->dpp_config_obj_override);
    287 	if (hapd->dpp_discovery_override)
    288 		auth->discovery_override =
    289 			os_strdup(hapd->dpp_discovery_override);
    290 	if (hapd->dpp_groups_override)
    291 		auth->groups_override = os_strdup(hapd->dpp_groups_override);
    292 	auth->ignore_netaccesskey_mismatch =
    293 		hapd->dpp_ignore_netaccesskey_mismatch;
    294 #endif /* CONFIG_TESTING_OPTIONS */
    295 }
    296 
    297 
    298 static void hostapd_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx)
    299 {
    300 	struct hostapd_data *hapd = eloop_ctx;
    301 
    302 	if (!hapd->dpp_auth)
    303 		return;
    304 	wpa_printf(MSG_DEBUG, "DPP: Retry initiation after timeout");
    305 	hostapd_dpp_auth_init_next(hapd);
    306 }
    307 
    308 
    309 static int hostapd_dpp_auth_init_next(struct hostapd_data *hapd)
    310 {
    311 	struct dpp_authentication *auth = hapd->dpp_auth;
    312 	const u8 *dst;
    313 	unsigned int wait_time, max_wait_time, freq, max_tries, used;
    314 	struct os_reltime now, diff;
    315 
    316 	if (!auth)
    317 		return -1;
    318 
    319 	if (auth->freq_idx == 0)
    320 		os_get_reltime(&hapd->dpp_init_iter_start);
    321 
    322 	if (auth->freq_idx >= auth->num_freq) {
    323 		auth->num_freq_iters++;
    324 		if (hapd->dpp_init_max_tries)
    325 			max_tries = hapd->dpp_init_max_tries;
    326 		else
    327 			max_tries = 5;
    328 		if (auth->num_freq_iters >= max_tries || auth->auth_req_ack) {
    329 			wpa_printf(MSG_INFO,
    330 				   "DPP: No response received from responder - stopping initiation attempt");
    331 			wpa_msg(hapd->msg_ctx, MSG_INFO,
    332 				DPP_EVENT_AUTH_INIT_FAILED);
    333 			eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
    334 					     hapd, NULL);
    335 			hostapd_drv_send_action_cancel_wait(hapd);
    336 			dpp_auth_deinit(hapd->dpp_auth);
    337 			hapd->dpp_auth = NULL;
    338 			return -1;
    339 		}
    340 		auth->freq_idx = 0;
    341 		eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
    342 		if (hapd->dpp_init_retry_time)
    343 			wait_time = hapd->dpp_init_retry_time;
    344 		else
    345 			wait_time = 10000;
    346 		os_get_reltime(&now);
    347 		os_reltime_sub(&now, &hapd->dpp_init_iter_start, &diff);
    348 		used = diff.sec * 1000 + diff.usec / 1000;
    349 		if (used > wait_time)
    350 			wait_time = 0;
    351 		else
    352 			wait_time -= used;
    353 		wpa_printf(MSG_DEBUG, "DPP: Next init attempt in %u ms",
    354 			   wait_time);
    355 		eloop_register_timeout(wait_time / 1000,
    356 				       (wait_time % 1000) * 1000,
    357 				       hostapd_dpp_init_timeout, hapd,
    358 				       NULL);
    359 		return 0;
    360 	}
    361 	freq = auth->freq[auth->freq_idx++];
    362 	auth->curr_freq = freq;
    363 
    364 	if (is_zero_ether_addr(auth->peer_bi->mac_addr))
    365 		dst = broadcast;
    366 	else
    367 		dst = auth->peer_bi->mac_addr;
    368 	hapd->dpp_auth_ok_on_ack = 0;
    369 	eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
    370 	wait_time = 2000; /* TODO: hapd->max_remain_on_chan; */
    371 	max_wait_time = hapd->dpp_resp_wait_time ?
    372 		hapd->dpp_resp_wait_time : 2000;
    373 	if (wait_time > max_wait_time)
    374 		wait_time = max_wait_time;
    375 	wait_time += 10; /* give the driver some extra time to complete */
    376 	eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
    377 			       hostapd_dpp_reply_wait_timeout, hapd, NULL);
    378 	wait_time -= 10;
    379 	if (auth->neg_freq > 0 && freq != auth->neg_freq) {
    380 		wpa_printf(MSG_DEBUG,
    381 			   "DPP: Initiate on %u MHz and move to neg_freq %u MHz for response",
    382 			   freq, auth->neg_freq);
    383 	}
    384 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
    385 		" freq=%u type=%d",
    386 		MAC2STR(dst), freq, DPP_PA_AUTHENTICATION_REQ);
    387 	auth->auth_req_ack = 0;
    388 	os_get_reltime(&hapd->dpp_last_init);
    389 	return hostapd_drv_send_action(hapd, freq, wait_time,
    390 				       dst,
    391 				       wpabuf_head(hapd->dpp_auth->req_msg),
    392 				       wpabuf_len(hapd->dpp_auth->req_msg));
    393 }
    394 
    395 
    396 int hostapd_dpp_auth_init(struct hostapd_data *hapd, const char *cmd)
    397 {
    398 	const char *pos;
    399 	struct dpp_bootstrap_info *peer_bi, *own_bi = NULL;
    400 	u8 allowed_roles = DPP_CAPAB_CONFIGURATOR;
    401 	unsigned int neg_freq = 0;
    402 
    403 	pos = os_strstr(cmd, " peer=");
    404 	if (!pos)
    405 		return -1;
    406 	pos += 6;
    407 	peer_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
    408 	if (!peer_bi) {
    409 		wpa_printf(MSG_INFO,
    410 			   "DPP: Could not find bootstrapping info for the identified peer");
    411 		return -1;
    412 	}
    413 
    414 	pos = os_strstr(cmd, " own=");
    415 	if (pos) {
    416 		pos += 5;
    417 		own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp,
    418 					      atoi(pos));
    419 		if (!own_bi) {
    420 			wpa_printf(MSG_INFO,
    421 				   "DPP: Could not find bootstrapping info for the identified local entry");
    422 			return -1;
    423 		}
    424 
    425 		if (peer_bi->curve != own_bi->curve) {
    426 			wpa_printf(MSG_INFO,
    427 				   "DPP: Mismatching curves in bootstrapping info (peer=%s own=%s)",
    428 				   peer_bi->curve->name, own_bi->curve->name);
    429 			return -1;
    430 		}
    431 	}
    432 
    433 	pos = os_strstr(cmd, " role=");
    434 	if (pos) {
    435 		pos += 6;
    436 		if (os_strncmp(pos, "configurator", 12) == 0)
    437 			allowed_roles = DPP_CAPAB_CONFIGURATOR;
    438 		else if (os_strncmp(pos, "enrollee", 8) == 0)
    439 			allowed_roles = DPP_CAPAB_ENROLLEE;
    440 		else if (os_strncmp(pos, "either", 6) == 0)
    441 			allowed_roles = DPP_CAPAB_CONFIGURATOR |
    442 				DPP_CAPAB_ENROLLEE;
    443 		else
    444 			goto fail;
    445 	}
    446 
    447 	pos = os_strstr(cmd, " neg_freq=");
    448 	if (pos)
    449 		neg_freq = atoi(pos + 10);
    450 
    451 	if (hapd->dpp_auth) {
    452 		eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
    453 		eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
    454 				     hapd, NULL);
    455 		eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd,
    456 				     NULL);
    457 		hostapd_drv_send_action_cancel_wait(hapd);
    458 		dpp_auth_deinit(hapd->dpp_auth);
    459 	}
    460 
    461 	hapd->dpp_auth = dpp_auth_init(hapd->msg_ctx, peer_bi, own_bi,
    462 				       allowed_roles, neg_freq,
    463 				       hapd->iface->hw_features,
    464 				       hapd->iface->num_hw_features);
    465 	if (!hapd->dpp_auth)
    466 		goto fail;
    467 	hostapd_dpp_set_testing_options(hapd, hapd->dpp_auth);
    468 	if (dpp_set_configurator(hapd->iface->interfaces->dpp, hapd->msg_ctx,
    469 				 hapd->dpp_auth, cmd) < 0) {
    470 		dpp_auth_deinit(hapd->dpp_auth);
    471 		hapd->dpp_auth = NULL;
    472 		goto fail;
    473 	}
    474 
    475 	hapd->dpp_auth->neg_freq = neg_freq;
    476 
    477 	if (!is_zero_ether_addr(peer_bi->mac_addr))
    478 		os_memcpy(hapd->dpp_auth->peer_mac_addr, peer_bi->mac_addr,
    479 			  ETH_ALEN);
    480 
    481 	return hostapd_dpp_auth_init_next(hapd);
    482 fail:
    483 	return -1;
    484 }
    485 
    486 
    487 int hostapd_dpp_listen(struct hostapd_data *hapd, const char *cmd)
    488 {
    489 	int freq;
    490 
    491 	freq = atoi(cmd);
    492 	if (freq <= 0)
    493 		return -1;
    494 
    495 	if (os_strstr(cmd, " role=configurator"))
    496 		hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR;
    497 	else if (os_strstr(cmd, " role=enrollee"))
    498 		hapd->dpp_allowed_roles = DPP_CAPAB_ENROLLEE;
    499 	else
    500 		hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR |
    501 			DPP_CAPAB_ENROLLEE;
    502 	hapd->dpp_qr_mutual = os_strstr(cmd, " qr=mutual") != NULL;
    503 
    504 	if (freq != hapd->iface->freq && hapd->iface->freq > 0) {
    505 		/* TODO: Listen operation on non-operating channel */
    506 		wpa_printf(MSG_INFO,
    507 			   "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)",
    508 			   freq, hapd->iface->freq);
    509 		return -1;
    510 	}
    511 
    512 	return 0;
    513 }
    514 
    515 
    516 void hostapd_dpp_listen_stop(struct hostapd_data *hapd)
    517 {
    518 	/* TODO: Stop listen operation on non-operating channel */
    519 }
    520 
    521 
    522 static void hostapd_dpp_rx_auth_req(struct hostapd_data *hapd, const u8 *src,
    523 				    const u8 *hdr, const u8 *buf, size_t len,
    524 				    unsigned int freq)
    525 {
    526 	const u8 *r_bootstrap, *i_bootstrap;
    527 	u16 r_bootstrap_len, i_bootstrap_len;
    528 	struct dpp_bootstrap_info *own_bi = NULL, *peer_bi = NULL;
    529 
    530 	if (!hapd->iface->interfaces->dpp)
    531 		return;
    532 
    533 	wpa_printf(MSG_DEBUG, "DPP: Authentication Request from " MACSTR,
    534 		   MAC2STR(src));
    535 
    536 	r_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
    537 				   &r_bootstrap_len);
    538 	if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) {
    539 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
    540 			"Missing or invalid required Responder Bootstrapping Key Hash attribute");
    541 		return;
    542 	}
    543 	wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash",
    544 		    r_bootstrap, r_bootstrap_len);
    545 
    546 	i_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_I_BOOTSTRAP_KEY_HASH,
    547 				   &i_bootstrap_len);
    548 	if (!i_bootstrap || i_bootstrap_len != SHA256_MAC_LEN) {
    549 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
    550 			"Missing or invalid required Initiator Bootstrapping Key Hash attribute");
    551 		return;
    552 	}
    553 	wpa_hexdump(MSG_MSGDUMP, "DPP: Initiator Bootstrapping Key Hash",
    554 		    i_bootstrap, i_bootstrap_len);
    555 
    556 	/* Try to find own and peer bootstrapping key matches based on the
    557 	 * received hash values */
    558 	dpp_bootstrap_find_pair(hapd->iface->interfaces->dpp, i_bootstrap,
    559 				r_bootstrap, &own_bi, &peer_bi);
    560 	if (!own_bi) {
    561 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
    562 			"No matching own bootstrapping key found - ignore message");
    563 		return;
    564 	}
    565 
    566 	if (hapd->dpp_auth) {
    567 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
    568 			"Already in DPP authentication exchange - ignore new one");
    569 		return;
    570 	}
    571 
    572 	hapd->dpp_auth_ok_on_ack = 0;
    573 	hapd->dpp_auth = dpp_auth_req_rx(hapd->msg_ctx, hapd->dpp_allowed_roles,
    574 					 hapd->dpp_qr_mutual,
    575 					 peer_bi, own_bi, freq, hdr, buf, len);
    576 	if (!hapd->dpp_auth) {
    577 		wpa_printf(MSG_DEBUG, "DPP: No response generated");
    578 		return;
    579 	}
    580 	hostapd_dpp_set_testing_options(hapd, hapd->dpp_auth);
    581 	if (dpp_set_configurator(hapd->iface->interfaces->dpp, hapd->msg_ctx,
    582 				 hapd->dpp_auth,
    583 				 hapd->dpp_configurator_params) < 0) {
    584 		dpp_auth_deinit(hapd->dpp_auth);
    585 		hapd->dpp_auth = NULL;
    586 		return;
    587 	}
    588 	os_memcpy(hapd->dpp_auth->peer_mac_addr, src, ETH_ALEN);
    589 
    590 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
    591 		" freq=%u type=%d",
    592 		MAC2STR(src), hapd->dpp_auth->curr_freq,
    593 		DPP_PA_AUTHENTICATION_RESP);
    594 	hostapd_drv_send_action(hapd, hapd->dpp_auth->curr_freq, 0,
    595 				src, wpabuf_head(hapd->dpp_auth->resp_msg),
    596 				wpabuf_len(hapd->dpp_auth->resp_msg));
    597 }
    598 
    599 
    600 static void hostapd_dpp_handle_config_obj(struct hostapd_data *hapd,
    601 					  struct dpp_authentication *auth)
    602 {
    603 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_RECEIVED);
    604 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_AKM "%s",
    605 		dpp_akm_str(auth->akm));
    606 	if (auth->ssid_len)
    607 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_SSID "%s",
    608 			wpa_ssid_txt(auth->ssid, auth->ssid_len));
    609 	if (auth->connector) {
    610 		/* TODO: Save the Connector and consider using a command
    611 		 * to fetch the value instead of sending an event with
    612 		 * it. The Connector could end up being larger than what
    613 		 * most clients are ready to receive as an event
    614 		 * message. */
    615 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONNECTOR "%s",
    616 			auth->connector);
    617 	} else if (auth->passphrase[0]) {
    618 		char hex[64 * 2 + 1];
    619 
    620 		wpa_snprintf_hex(hex, sizeof(hex),
    621 				 (const u8 *) auth->passphrase,
    622 				 os_strlen(auth->passphrase));
    623 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_PASS "%s",
    624 			hex);
    625 	} else if (auth->psk_set) {
    626 		char hex[PMK_LEN * 2 + 1];
    627 
    628 		wpa_snprintf_hex(hex, sizeof(hex), auth->psk, PMK_LEN);
    629 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_PSK "%s",
    630 			hex);
    631 	}
    632 	if (auth->c_sign_key) {
    633 		char *hex;
    634 		size_t hexlen;
    635 
    636 		hexlen = 2 * wpabuf_len(auth->c_sign_key) + 1;
    637 		hex = os_malloc(hexlen);
    638 		if (hex) {
    639 			wpa_snprintf_hex(hex, hexlen,
    640 					 wpabuf_head(auth->c_sign_key),
    641 					 wpabuf_len(auth->c_sign_key));
    642 			wpa_msg(hapd->msg_ctx, MSG_INFO,
    643 				DPP_EVENT_C_SIGN_KEY "%s", hex);
    644 			os_free(hex);
    645 		}
    646 	}
    647 	if (auth->net_access_key) {
    648 		char *hex;
    649 		size_t hexlen;
    650 
    651 		hexlen = 2 * wpabuf_len(auth->net_access_key) + 1;
    652 		hex = os_malloc(hexlen);
    653 		if (hex) {
    654 			wpa_snprintf_hex(hex, hexlen,
    655 					 wpabuf_head(auth->net_access_key),
    656 					 wpabuf_len(auth->net_access_key));
    657 			if (auth->net_access_key_expiry)
    658 				wpa_msg(hapd->msg_ctx, MSG_INFO,
    659 					DPP_EVENT_NET_ACCESS_KEY "%s %lu", hex,
    660 					(unsigned long)
    661 					auth->net_access_key_expiry);
    662 			else
    663 				wpa_msg(hapd->msg_ctx, MSG_INFO,
    664 					DPP_EVENT_NET_ACCESS_KEY "%s", hex);
    665 			os_free(hex);
    666 		}
    667 	}
    668 }
    669 
    670 
    671 static void hostapd_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token,
    672 				    enum gas_query_ap_result result,
    673 				    const struct wpabuf *adv_proto,
    674 				    const struct wpabuf *resp, u16 status_code)
    675 {
    676 	struct hostapd_data *hapd = ctx;
    677 	const u8 *pos;
    678 	struct dpp_authentication *auth = hapd->dpp_auth;
    679 	enum dpp_status_error status = DPP_STATUS_CONFIG_REJECTED;
    680 
    681 	if (!auth || !auth->auth_success) {
    682 		wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
    683 		return;
    684 	}
    685 	if (!resp || status_code != WLAN_STATUS_SUCCESS) {
    686 		wpa_printf(MSG_DEBUG, "DPP: GAS query did not succeed");
    687 		goto fail;
    688 	}
    689 
    690 	wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response adv_proto",
    691 			adv_proto);
    692 	wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response (GAS response)",
    693 			resp);
    694 
    695 	if (wpabuf_len(adv_proto) != 10 ||
    696 	    !(pos = wpabuf_head(adv_proto)) ||
    697 	    pos[0] != WLAN_EID_ADV_PROTO ||
    698 	    pos[1] != 8 ||
    699 	    pos[3] != WLAN_EID_VENDOR_SPECIFIC ||
    700 	    pos[4] != 5 ||
    701 	    WPA_GET_BE24(&pos[5]) != OUI_WFA ||
    702 	    pos[8] != 0x1a ||
    703 	    pos[9] != 1) {
    704 		wpa_printf(MSG_DEBUG,
    705 			   "DPP: Not a DPP Advertisement Protocol ID");
    706 		goto fail;
    707 	}
    708 
    709 	if (dpp_conf_resp_rx(auth, resp) < 0) {
    710 		wpa_printf(MSG_DEBUG, "DPP: Configuration attempt failed");
    711 		goto fail;
    712 	}
    713 
    714 	hostapd_dpp_handle_config_obj(hapd, auth);
    715 	status = DPP_STATUS_OK;
    716 #ifdef CONFIG_TESTING_OPTIONS
    717 	if (dpp_test == DPP_TEST_REJECT_CONFIG) {
    718 		wpa_printf(MSG_INFO, "DPP: TESTING - Reject Config Object");
    719 		status = DPP_STATUS_CONFIG_REJECTED;
    720 	}
    721 #endif /* CONFIG_TESTING_OPTIONS */
    722 fail:
    723 	if (status != DPP_STATUS_OK)
    724 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
    725 #ifdef CONFIG_DPP2
    726 	if (auth->peer_version >= 2 &&
    727 	    auth->conf_resp_status == DPP_STATUS_OK) {
    728 		struct wpabuf *msg;
    729 
    730 		wpa_printf(MSG_DEBUG, "DPP: Send DPP Configuration Result");
    731 		msg = dpp_build_conf_result(auth, status);
    732 		if (!msg)
    733 			goto fail2;
    734 
    735 		wpa_msg(hapd->msg_ctx, MSG_INFO,
    736 			DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
    737 			MAC2STR(addr), auth->curr_freq,
    738 			DPP_PA_CONFIGURATION_RESULT);
    739 		hostapd_drv_send_action(hapd, auth->curr_freq, 0,
    740 					addr, wpabuf_head(msg),
    741 					wpabuf_len(msg));
    742 		wpabuf_free(msg);
    743 
    744 		/* This exchange will be terminated in the TX status handler */
    745 		auth->connect_on_tx_status = 1;
    746 		return;
    747 	}
    748 fail2:
    749 #endif /* CONFIG_DPP2 */
    750 	dpp_auth_deinit(hapd->dpp_auth);
    751 	hapd->dpp_auth = NULL;
    752 }
    753 
    754 
    755 static void hostapd_dpp_start_gas_client(struct hostapd_data *hapd)
    756 {
    757 	struct dpp_authentication *auth = hapd->dpp_auth;
    758 	struct wpabuf *buf;
    759 	char json[100];
    760 	int res;
    761 	int netrole_ap = 1;
    762 
    763 	os_snprintf(json, sizeof(json),
    764 		    "{\"name\":\"Test\","
    765 		    "\"wi-fi_tech\":\"infra\","
    766 		    "\"netRole\":\"%s\"}",
    767 		    netrole_ap ? "ap" : "sta");
    768 	wpa_printf(MSG_DEBUG, "DPP: GAS Config Attributes: %s", json);
    769 
    770 	buf = dpp_build_conf_req(auth, json);
    771 	if (!buf) {
    772 		wpa_printf(MSG_DEBUG,
    773 			   "DPP: No configuration request data available");
    774 		return;
    775 	}
    776 
    777 	wpa_printf(MSG_DEBUG, "DPP: GAS request to " MACSTR " (freq %u MHz)",
    778 		   MAC2STR(auth->peer_mac_addr), auth->curr_freq);
    779 
    780 	res = gas_query_ap_req(hapd->gas, auth->peer_mac_addr, auth->curr_freq,
    781 			       buf, hostapd_dpp_gas_resp_cb, hapd);
    782 	if (res < 0) {
    783 		wpa_msg(hapd->msg_ctx, MSG_DEBUG,
    784 			"GAS: Failed to send Query Request");
    785 		wpabuf_free(buf);
    786 	} else {
    787 		wpa_printf(MSG_DEBUG,
    788 			   "DPP: GAS query started with dialog token %u", res);
    789 	}
    790 }
    791 
    792 
    793 static void hostapd_dpp_auth_success(struct hostapd_data *hapd, int initiator)
    794 {
    795 	wpa_printf(MSG_DEBUG, "DPP: Authentication succeeded");
    796 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_AUTH_SUCCESS "init=%d",
    797 		initiator);
    798 #ifdef CONFIG_TESTING_OPTIONS
    799 	if (dpp_test == DPP_TEST_STOP_AT_AUTH_CONF) {
    800 		wpa_printf(MSG_INFO,
    801 			   "DPP: TESTING - stop at Authentication Confirm");
    802 		if (hapd->dpp_auth->configurator) {
    803 			/* Prevent GAS response */
    804 			hapd->dpp_auth->auth_success = 0;
    805 		}
    806 		return;
    807 	}
    808 #endif /* CONFIG_TESTING_OPTIONS */
    809 
    810 	if (!hapd->dpp_auth->configurator)
    811 		hostapd_dpp_start_gas_client(hapd);
    812 }
    813 
    814 
    815 static void hostapd_dpp_rx_auth_resp(struct hostapd_data *hapd, const u8 *src,
    816 				     const u8 *hdr, const u8 *buf, size_t len,
    817 				     unsigned int freq)
    818 {
    819 	struct dpp_authentication *auth = hapd->dpp_auth;
    820 	struct wpabuf *msg;
    821 
    822 	wpa_printf(MSG_DEBUG, "DPP: Authentication Response from " MACSTR,
    823 		   MAC2STR(src));
    824 
    825 	if (!auth) {
    826 		wpa_printf(MSG_DEBUG,
    827 			   "DPP: No DPP Authentication in progress - drop");
    828 		return;
    829 	}
    830 
    831 	if (!is_zero_ether_addr(auth->peer_mac_addr) &&
    832 	    os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
    833 		wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
    834 			   MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
    835 		return;
    836 	}
    837 
    838 	eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
    839 
    840 	if (auth->curr_freq != freq && auth->neg_freq == freq) {
    841 		wpa_printf(MSG_DEBUG,
    842 			   "DPP: Responder accepted request for different negotiation channel");
    843 		auth->curr_freq = freq;
    844 	}
    845 
    846 	eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
    847 	msg = dpp_auth_resp_rx(auth, hdr, buf, len);
    848 	if (!msg) {
    849 		if (auth->auth_resp_status == DPP_STATUS_RESPONSE_PENDING) {
    850 			wpa_printf(MSG_DEBUG, "DPP: Wait for full response");
    851 			return;
    852 		}
    853 		wpa_printf(MSG_DEBUG, "DPP: No confirm generated");
    854 		return;
    855 	}
    856 	os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
    857 
    858 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
    859 		" freq=%u type=%d", MAC2STR(src), auth->curr_freq,
    860 		DPP_PA_AUTHENTICATION_CONF);
    861 	hostapd_drv_send_action(hapd, auth->curr_freq, 0, src,
    862 				wpabuf_head(msg), wpabuf_len(msg));
    863 	wpabuf_free(msg);
    864 	hapd->dpp_auth_ok_on_ack = 1;
    865 }
    866 
    867 
    868 static void hostapd_dpp_rx_auth_conf(struct hostapd_data *hapd, const u8 *src,
    869 				     const u8 *hdr, const u8 *buf, size_t len)
    870 {
    871 	struct dpp_authentication *auth = hapd->dpp_auth;
    872 
    873 	wpa_printf(MSG_DEBUG, "DPP: Authentication Confirmation from " MACSTR,
    874 		   MAC2STR(src));
    875 
    876 	if (!auth) {
    877 		wpa_printf(MSG_DEBUG,
    878 			   "DPP: No DPP Authentication in progress - drop");
    879 		return;
    880 	}
    881 
    882 	if (os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
    883 		wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
    884 			   MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
    885 		return;
    886 	}
    887 
    888 	if (dpp_auth_conf_rx(auth, hdr, buf, len) < 0) {
    889 		wpa_printf(MSG_DEBUG, "DPP: Authentication failed");
    890 		return;
    891 	}
    892 
    893 	hostapd_dpp_auth_success(hapd, 0);
    894 }
    895 
    896 
    897 #ifdef CONFIG_DPP2
    898 
    899 static void hostapd_dpp_config_result_wait_timeout(void *eloop_ctx,
    900 						   void *timeout_ctx)
    901 {
    902 	struct hostapd_data *hapd = eloop_ctx;
    903 	struct dpp_authentication *auth = hapd->dpp_auth;
    904 
    905 	if (!auth || !auth->waiting_conf_result)
    906 		return;
    907 
    908 	wpa_printf(MSG_DEBUG,
    909 		   "DPP: Timeout while waiting for Configuration Result");
    910 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
    911 	dpp_auth_deinit(auth);
    912 	hapd->dpp_auth = NULL;
    913 }
    914 
    915 
    916 static void hostapd_dpp_rx_conf_result(struct hostapd_data *hapd, const u8 *src,
    917 				       const u8 *hdr, const u8 *buf, size_t len)
    918 {
    919 	struct dpp_authentication *auth = hapd->dpp_auth;
    920 	enum dpp_status_error status;
    921 
    922 	wpa_printf(MSG_DEBUG, "DPP: Configuration Result from " MACSTR,
    923 		   MAC2STR(src));
    924 
    925 	if (!auth || !auth->waiting_conf_result) {
    926 		wpa_printf(MSG_DEBUG,
    927 			   "DPP: No DPP Configuration waiting for result - drop");
    928 		return;
    929 	}
    930 
    931 	if (os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
    932 		wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
    933 			   MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
    934 		return;
    935 	}
    936 
    937 	status = dpp_conf_result_rx(auth, hdr, buf, len);
    938 
    939 	hostapd_drv_send_action_cancel_wait(hapd);
    940 	hostapd_dpp_listen_stop(hapd);
    941 	if (status == DPP_STATUS_OK)
    942 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_SENT);
    943 	else
    944 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
    945 	dpp_auth_deinit(auth);
    946 	hapd->dpp_auth = NULL;
    947 	eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout, hapd,
    948 			     NULL);
    949 }
    950 
    951 #endif /* CONFIG_DPP2 */
    952 
    953 
    954 static void hostapd_dpp_send_peer_disc_resp(struct hostapd_data *hapd,
    955 					    const u8 *src, unsigned int freq,
    956 					    u8 trans_id,
    957 					    enum dpp_status_error status)
    958 {
    959 	struct wpabuf *msg;
    960 
    961 	msg = dpp_alloc_msg(DPP_PA_PEER_DISCOVERY_RESP,
    962 			    5 + 5 + 4 + os_strlen(hapd->conf->dpp_connector));
    963 	if (!msg)
    964 		return;
    965 
    966 #ifdef CONFIG_TESTING_OPTIONS
    967 	if (dpp_test == DPP_TEST_NO_TRANSACTION_ID_PEER_DISC_RESP) {
    968 		wpa_printf(MSG_INFO, "DPP: TESTING - no Transaction ID");
    969 		goto skip_trans_id;
    970 	}
    971 	if (dpp_test == DPP_TEST_INVALID_TRANSACTION_ID_PEER_DISC_RESP) {
    972 		wpa_printf(MSG_INFO, "DPP: TESTING - invalid Transaction ID");
    973 		trans_id ^= 0x01;
    974 	}
    975 #endif /* CONFIG_TESTING_OPTIONS */
    976 
    977 	/* Transaction ID */
    978 	wpabuf_put_le16(msg, DPP_ATTR_TRANSACTION_ID);
    979 	wpabuf_put_le16(msg, 1);
    980 	wpabuf_put_u8(msg, trans_id);
    981 
    982 #ifdef CONFIG_TESTING_OPTIONS
    983 skip_trans_id:
    984 	if (dpp_test == DPP_TEST_NO_STATUS_PEER_DISC_RESP) {
    985 		wpa_printf(MSG_INFO, "DPP: TESTING - no Status");
    986 		goto skip_status;
    987 	}
    988 	if (dpp_test == DPP_TEST_INVALID_STATUS_PEER_DISC_RESP) {
    989 		wpa_printf(MSG_INFO, "DPP: TESTING - invalid Status");
    990 		status = 254;
    991 	}
    992 #endif /* CONFIG_TESTING_OPTIONS */
    993 
    994 	/* DPP Status */
    995 	wpabuf_put_le16(msg, DPP_ATTR_STATUS);
    996 	wpabuf_put_le16(msg, 1);
    997 	wpabuf_put_u8(msg, status);
    998 
    999 #ifdef CONFIG_TESTING_OPTIONS
   1000 skip_status:
   1001 	if (dpp_test == DPP_TEST_NO_CONNECTOR_PEER_DISC_RESP) {
   1002 		wpa_printf(MSG_INFO, "DPP: TESTING - no Connector");
   1003 		goto skip_connector;
   1004 	}
   1005 	if (status == DPP_STATUS_OK &&
   1006 	    dpp_test == DPP_TEST_INVALID_CONNECTOR_PEER_DISC_RESP) {
   1007 		char *connector;
   1008 
   1009 		wpa_printf(MSG_INFO, "DPP: TESTING - invalid Connector");
   1010 		connector = dpp_corrupt_connector_signature(
   1011 			hapd->conf->dpp_connector);
   1012 		if (!connector) {
   1013 			wpabuf_free(msg);
   1014 			return;
   1015 		}
   1016 		wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
   1017 		wpabuf_put_le16(msg, os_strlen(connector));
   1018 		wpabuf_put_str(msg, connector);
   1019 		os_free(connector);
   1020 		goto skip_connector;
   1021 	}
   1022 #endif /* CONFIG_TESTING_OPTIONS */
   1023 
   1024 	/* DPP Connector */
   1025 	if (status == DPP_STATUS_OK) {
   1026 		wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
   1027 		wpabuf_put_le16(msg, os_strlen(hapd->conf->dpp_connector));
   1028 		wpabuf_put_str(msg, hapd->conf->dpp_connector);
   1029 	}
   1030 
   1031 #ifdef CONFIG_TESTING_OPTIONS
   1032 skip_connector:
   1033 #endif /* CONFIG_TESTING_OPTIONS */
   1034 
   1035 	wpa_printf(MSG_DEBUG, "DPP: Send Peer Discovery Response to " MACSTR
   1036 		   " status=%d", MAC2STR(src), status);
   1037 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
   1038 		" freq=%u type=%d status=%d", MAC2STR(src), freq,
   1039 		DPP_PA_PEER_DISCOVERY_RESP, status);
   1040 	hostapd_drv_send_action(hapd, freq, 0, src,
   1041 				wpabuf_head(msg), wpabuf_len(msg));
   1042 	wpabuf_free(msg);
   1043 }
   1044 
   1045 
   1046 static void hostapd_dpp_rx_peer_disc_req(struct hostapd_data *hapd,
   1047 					 const u8 *src,
   1048 					 const u8 *buf, size_t len,
   1049 					 unsigned int freq)
   1050 {
   1051 	const u8 *connector, *trans_id;
   1052 	u16 connector_len, trans_id_len;
   1053 	struct os_time now;
   1054 	struct dpp_introduction intro;
   1055 	os_time_t expire;
   1056 	int expiration;
   1057 	enum dpp_status_error res;
   1058 
   1059 	wpa_printf(MSG_DEBUG, "DPP: Peer Discovery Request from " MACSTR,
   1060 		   MAC2STR(src));
   1061 	if (!hapd->wpa_auth ||
   1062 	    !(hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) ||
   1063 	    !(hapd->conf->wpa & WPA_PROTO_RSN)) {
   1064 		wpa_printf(MSG_DEBUG, "DPP: DPP AKM not in use");
   1065 		return;
   1066 	}
   1067 
   1068 	if (!hapd->conf->dpp_connector || !hapd->conf->dpp_netaccesskey ||
   1069 	    !hapd->conf->dpp_csign) {
   1070 		wpa_printf(MSG_DEBUG, "DPP: No own Connector/keys set");
   1071 		return;
   1072 	}
   1073 
   1074 	os_get_time(&now);
   1075 
   1076 	if (hapd->conf->dpp_netaccesskey_expiry &&
   1077 	    (os_time_t) hapd->conf->dpp_netaccesskey_expiry < now.sec) {
   1078 		wpa_printf(MSG_INFO, "DPP: Own netAccessKey expired");
   1079 		return;
   1080 	}
   1081 
   1082 	trans_id = dpp_get_attr(buf, len, DPP_ATTR_TRANSACTION_ID,
   1083 			       &trans_id_len);
   1084 	if (!trans_id || trans_id_len != 1) {
   1085 		wpa_printf(MSG_DEBUG,
   1086 			   "DPP: Peer did not include Transaction ID");
   1087 		return;
   1088 	}
   1089 
   1090 	connector = dpp_get_attr(buf, len, DPP_ATTR_CONNECTOR, &connector_len);
   1091 	if (!connector) {
   1092 		wpa_printf(MSG_DEBUG,
   1093 			   "DPP: Peer did not include its Connector");
   1094 		return;
   1095 	}
   1096 
   1097 	res = dpp_peer_intro(&intro, hapd->conf->dpp_connector,
   1098 			     wpabuf_head(hapd->conf->dpp_netaccesskey),
   1099 			     wpabuf_len(hapd->conf->dpp_netaccesskey),
   1100 			     wpabuf_head(hapd->conf->dpp_csign),
   1101 			     wpabuf_len(hapd->conf->dpp_csign),
   1102 			     connector, connector_len, &expire);
   1103 	if (res == 255) {
   1104 		wpa_printf(MSG_INFO,
   1105 			   "DPP: Network Introduction protocol resulted in internal failure (peer "
   1106 			   MACSTR ")", MAC2STR(src));
   1107 		return;
   1108 	}
   1109 	if (res != DPP_STATUS_OK) {
   1110 		wpa_printf(MSG_INFO,
   1111 			   "DPP: Network Introduction protocol resulted in failure (peer "
   1112 			   MACSTR " status %d)", MAC2STR(src), res);
   1113 		hostapd_dpp_send_peer_disc_resp(hapd, src, freq, trans_id[0],
   1114 						res);
   1115 		return;
   1116 	}
   1117 
   1118 	if (!expire || (os_time_t) hapd->conf->dpp_netaccesskey_expiry < expire)
   1119 		expire = hapd->conf->dpp_netaccesskey_expiry;
   1120 	if (expire)
   1121 		expiration = expire - now.sec;
   1122 	else
   1123 		expiration = 0;
   1124 
   1125 	if (wpa_auth_pmksa_add2(hapd->wpa_auth, src, intro.pmk, intro.pmk_len,
   1126 				intro.pmkid, expiration,
   1127 				WPA_KEY_MGMT_DPP) < 0) {
   1128 		wpa_printf(MSG_ERROR, "DPP: Failed to add PMKSA cache entry");
   1129 		return;
   1130 	}
   1131 
   1132 	hostapd_dpp_send_peer_disc_resp(hapd, src, freq, trans_id[0],
   1133 					DPP_STATUS_OK);
   1134 }
   1135 
   1136 
   1137 static void
   1138 hostapd_dpp_rx_pkex_exchange_req(struct hostapd_data *hapd, const u8 *src,
   1139 				 const u8 *buf, size_t len,
   1140 				 unsigned int freq)
   1141 {
   1142 	struct wpabuf *msg;
   1143 
   1144 	wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Request from " MACSTR,
   1145 		   MAC2STR(src));
   1146 
   1147 	/* TODO: Support multiple PKEX codes by iterating over all the enabled
   1148 	 * values here */
   1149 
   1150 	if (!hapd->dpp_pkex_code || !hapd->dpp_pkex_bi) {
   1151 		wpa_printf(MSG_DEBUG,
   1152 			   "DPP: No PKEX code configured - ignore request");
   1153 		return;
   1154 	}
   1155 
   1156 	if (hapd->dpp_pkex) {
   1157 		/* TODO: Support parallel operations */
   1158 		wpa_printf(MSG_DEBUG,
   1159 			   "DPP: Already in PKEX session - ignore new request");
   1160 		return;
   1161 	}
   1162 
   1163 	hapd->dpp_pkex = dpp_pkex_rx_exchange_req(hapd->msg_ctx,
   1164 						  hapd->dpp_pkex_bi,
   1165 						  hapd->own_addr, src,
   1166 						  hapd->dpp_pkex_identifier,
   1167 						  hapd->dpp_pkex_code,
   1168 						  buf, len);
   1169 	if (!hapd->dpp_pkex) {
   1170 		wpa_printf(MSG_DEBUG,
   1171 			   "DPP: Failed to process the request - ignore it");
   1172 		return;
   1173 	}
   1174 
   1175 	msg = hapd->dpp_pkex->exchange_resp;
   1176 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
   1177 		" freq=%u type=%d", MAC2STR(src), freq,
   1178 		DPP_PA_PKEX_EXCHANGE_RESP);
   1179 	hostapd_drv_send_action(hapd, freq, 0, src,
   1180 				wpabuf_head(msg), wpabuf_len(msg));
   1181 	if (hapd->dpp_pkex->failed) {
   1182 		wpa_printf(MSG_DEBUG,
   1183 			   "DPP: Terminate PKEX exchange due to an earlier error");
   1184 		if (hapd->dpp_pkex->t > hapd->dpp_pkex->own_bi->pkex_t)
   1185 			hapd->dpp_pkex->own_bi->pkex_t = hapd->dpp_pkex->t;
   1186 		dpp_pkex_free(hapd->dpp_pkex);
   1187 		hapd->dpp_pkex = NULL;
   1188 	}
   1189 }
   1190 
   1191 
   1192 static void
   1193 hostapd_dpp_rx_pkex_exchange_resp(struct hostapd_data *hapd, const u8 *src,
   1194 				  const u8 *buf, size_t len, unsigned int freq)
   1195 {
   1196 	struct wpabuf *msg;
   1197 
   1198 	wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Response from " MACSTR,
   1199 		   MAC2STR(src));
   1200 
   1201 	/* TODO: Support multiple PKEX codes by iterating over all the enabled
   1202 	 * values here */
   1203 
   1204 	if (!hapd->dpp_pkex || !hapd->dpp_pkex->initiator ||
   1205 	    hapd->dpp_pkex->exchange_done) {
   1206 		wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
   1207 		return;
   1208 	}
   1209 
   1210 	msg = dpp_pkex_rx_exchange_resp(hapd->dpp_pkex, src, buf, len);
   1211 	if (!msg) {
   1212 		wpa_printf(MSG_DEBUG, "DPP: Failed to process the response");
   1213 		return;
   1214 	}
   1215 
   1216 	wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Request to " MACSTR,
   1217 		   MAC2STR(src));
   1218 
   1219 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
   1220 		" freq=%u type=%d", MAC2STR(src), freq,
   1221 		DPP_PA_PKEX_COMMIT_REVEAL_REQ);
   1222 	hostapd_drv_send_action(hapd, freq, 0, src,
   1223 				wpabuf_head(msg), wpabuf_len(msg));
   1224 	wpabuf_free(msg);
   1225 }
   1226 
   1227 
   1228 static void
   1229 hostapd_dpp_rx_pkex_commit_reveal_req(struct hostapd_data *hapd, const u8 *src,
   1230 				      const u8 *hdr, const u8 *buf, size_t len,
   1231 				      unsigned int freq)
   1232 {
   1233 	struct wpabuf *msg;
   1234 	struct dpp_pkex *pkex = hapd->dpp_pkex;
   1235 	struct dpp_bootstrap_info *bi;
   1236 
   1237 	wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Request from " MACSTR,
   1238 		   MAC2STR(src));
   1239 
   1240 	if (!pkex || pkex->initiator || !pkex->exchange_done) {
   1241 		wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
   1242 		return;
   1243 	}
   1244 
   1245 	msg = dpp_pkex_rx_commit_reveal_req(pkex, hdr, buf, len);
   1246 	if (!msg) {
   1247 		wpa_printf(MSG_DEBUG, "DPP: Failed to process the request");
   1248 		if (hapd->dpp_pkex->failed) {
   1249 			wpa_printf(MSG_DEBUG, "DPP: Terminate PKEX exchange");
   1250 			if (hapd->dpp_pkex->t > hapd->dpp_pkex->own_bi->pkex_t)
   1251 				hapd->dpp_pkex->own_bi->pkex_t =
   1252 					hapd->dpp_pkex->t;
   1253 			dpp_pkex_free(hapd->dpp_pkex);
   1254 			hapd->dpp_pkex = NULL;
   1255 		}
   1256 		return;
   1257 	}
   1258 
   1259 	wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Response to "
   1260 		   MACSTR, MAC2STR(src));
   1261 
   1262 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
   1263 		" freq=%u type=%d", MAC2STR(src), freq,
   1264 		DPP_PA_PKEX_COMMIT_REVEAL_RESP);
   1265 	hostapd_drv_send_action(hapd, freq, 0, src,
   1266 				wpabuf_head(msg), wpabuf_len(msg));
   1267 	wpabuf_free(msg);
   1268 
   1269 	bi = dpp_pkex_finish(hapd->iface->interfaces->dpp, pkex, src, freq);
   1270 	if (!bi)
   1271 		return;
   1272 	hapd->dpp_pkex = NULL;
   1273 }
   1274 
   1275 
   1276 static void
   1277 hostapd_dpp_rx_pkex_commit_reveal_resp(struct hostapd_data *hapd, const u8 *src,
   1278 				       const u8 *hdr, const u8 *buf, size_t len,
   1279 				       unsigned int freq)
   1280 {
   1281 	int res;
   1282 	struct dpp_bootstrap_info *bi;
   1283 	struct dpp_pkex *pkex = hapd->dpp_pkex;
   1284 	char cmd[500];
   1285 
   1286 	wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Response from " MACSTR,
   1287 		   MAC2STR(src));
   1288 
   1289 	if (!pkex || !pkex->initiator || !pkex->exchange_done) {
   1290 		wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
   1291 		return;
   1292 	}
   1293 
   1294 	res = dpp_pkex_rx_commit_reveal_resp(pkex, hdr, buf, len);
   1295 	if (res < 0) {
   1296 		wpa_printf(MSG_DEBUG, "DPP: Failed to process the response");
   1297 		return;
   1298 	}
   1299 
   1300 	bi = dpp_pkex_finish(hapd->iface->interfaces->dpp, pkex, src, freq);
   1301 	if (!bi)
   1302 		return;
   1303 	hapd->dpp_pkex = NULL;
   1304 
   1305 	os_snprintf(cmd, sizeof(cmd), " peer=%u %s",
   1306 		    bi->id,
   1307 		    hapd->dpp_pkex_auth_cmd ? hapd->dpp_pkex_auth_cmd : "");
   1308 	wpa_printf(MSG_DEBUG,
   1309 		   "DPP: Start authentication after PKEX with parameters: %s",
   1310 		   cmd);
   1311 	if (hostapd_dpp_auth_init(hapd, cmd) < 0) {
   1312 		wpa_printf(MSG_DEBUG,
   1313 			   "DPP: Authentication initialization failed");
   1314 		return;
   1315 	}
   1316 }
   1317 
   1318 
   1319 void hostapd_dpp_rx_action(struct hostapd_data *hapd, const u8 *src,
   1320 			   const u8 *buf, size_t len, unsigned int freq)
   1321 {
   1322 	u8 crypto_suite;
   1323 	enum dpp_public_action_frame_type type;
   1324 	const u8 *hdr;
   1325 	unsigned int pkex_t;
   1326 
   1327 	if (len < DPP_HDR_LEN)
   1328 		return;
   1329 	if (WPA_GET_BE24(buf) != OUI_WFA || buf[3] != DPP_OUI_TYPE)
   1330 		return;
   1331 	hdr = buf;
   1332 	buf += 4;
   1333 	len -= 4;
   1334 	crypto_suite = *buf++;
   1335 	type = *buf++;
   1336 	len -= 2;
   1337 
   1338 	wpa_printf(MSG_DEBUG,
   1339 		   "DPP: Received DPP Public Action frame crypto suite %u type %d from "
   1340 		   MACSTR " freq=%u",
   1341 		   crypto_suite, type, MAC2STR(src), freq);
   1342 	if (crypto_suite != 1) {
   1343 		wpa_printf(MSG_DEBUG, "DPP: Unsupported crypto suite %u",
   1344 			   crypto_suite);
   1345 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
   1346 			" freq=%u type=%d ignore=unsupported-crypto-suite",
   1347 			MAC2STR(src), freq, type);
   1348 		return;
   1349 	}
   1350 	wpa_hexdump(MSG_MSGDUMP, "DPP: Received message attributes", buf, len);
   1351 	if (dpp_check_attrs(buf, len) < 0) {
   1352 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
   1353 			" freq=%u type=%d ignore=invalid-attributes",
   1354 			MAC2STR(src), freq, type);
   1355 		return;
   1356 	}
   1357 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
   1358 		" freq=%u type=%d", MAC2STR(src), freq, type);
   1359 
   1360 	switch (type) {
   1361 	case DPP_PA_AUTHENTICATION_REQ:
   1362 		hostapd_dpp_rx_auth_req(hapd, src, hdr, buf, len, freq);
   1363 		break;
   1364 	case DPP_PA_AUTHENTICATION_RESP:
   1365 		hostapd_dpp_rx_auth_resp(hapd, src, hdr, buf, len, freq);
   1366 		break;
   1367 	case DPP_PA_AUTHENTICATION_CONF:
   1368 		hostapd_dpp_rx_auth_conf(hapd, src, hdr, buf, len);
   1369 		break;
   1370 	case DPP_PA_PEER_DISCOVERY_REQ:
   1371 		hostapd_dpp_rx_peer_disc_req(hapd, src, buf, len, freq);
   1372 		break;
   1373 	case DPP_PA_PKEX_EXCHANGE_REQ:
   1374 		hostapd_dpp_rx_pkex_exchange_req(hapd, src, buf, len, freq);
   1375 		break;
   1376 	case DPP_PA_PKEX_EXCHANGE_RESP:
   1377 		hostapd_dpp_rx_pkex_exchange_resp(hapd, src, buf, len, freq);
   1378 		break;
   1379 	case DPP_PA_PKEX_COMMIT_REVEAL_REQ:
   1380 		hostapd_dpp_rx_pkex_commit_reveal_req(hapd, src, hdr, buf, len,
   1381 						      freq);
   1382 		break;
   1383 	case DPP_PA_PKEX_COMMIT_REVEAL_RESP:
   1384 		hostapd_dpp_rx_pkex_commit_reveal_resp(hapd, src, hdr, buf, len,
   1385 						       freq);
   1386 		break;
   1387 #ifdef CONFIG_DPP2
   1388 	case DPP_PA_CONFIGURATION_RESULT:
   1389 		hostapd_dpp_rx_conf_result(hapd, src, hdr, buf, len);
   1390 		break;
   1391 #endif /* CONFIG_DPP2 */
   1392 	default:
   1393 		wpa_printf(MSG_DEBUG,
   1394 			   "DPP: Ignored unsupported frame subtype %d", type);
   1395 		break;
   1396 	}
   1397 
   1398 	if (hapd->dpp_pkex)
   1399 		pkex_t = hapd->dpp_pkex->t;
   1400 	else if (hapd->dpp_pkex_bi)
   1401 		pkex_t = hapd->dpp_pkex_bi->pkex_t;
   1402 	else
   1403 		pkex_t = 0;
   1404 	if (pkex_t >= PKEX_COUNTER_T_LIMIT) {
   1405 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PKEX_T_LIMIT "id=0");
   1406 		hostapd_dpp_pkex_remove(hapd, "*");
   1407 	}
   1408 }
   1409 
   1410 
   1411 struct wpabuf *
   1412 hostapd_dpp_gas_req_handler(struct hostapd_data *hapd, const u8 *sa,
   1413 			    const u8 *query, size_t query_len)
   1414 {
   1415 	struct dpp_authentication *auth = hapd->dpp_auth;
   1416 	struct wpabuf *resp;
   1417 
   1418 	wpa_printf(MSG_DEBUG, "DPP: GAS request from " MACSTR, MAC2STR(sa));
   1419 	if (!auth || !auth->auth_success ||
   1420 	    os_memcmp(sa, auth->peer_mac_addr, ETH_ALEN) != 0) {
   1421 		wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
   1422 		return NULL;
   1423 	}
   1424 	wpa_hexdump(MSG_DEBUG,
   1425 		    "DPP: Received Configuration Request (GAS Query Request)",
   1426 		    query, query_len);
   1427 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_REQ_RX "src=" MACSTR,
   1428 		MAC2STR(sa));
   1429 	resp = dpp_conf_req_rx(auth, query, query_len);
   1430 	if (!resp)
   1431 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
   1432 	return resp;
   1433 }
   1434 
   1435 
   1436 void hostapd_dpp_gas_status_handler(struct hostapd_data *hapd, int ok)
   1437 {
   1438 	struct dpp_authentication *auth = hapd->dpp_auth;
   1439 
   1440 	if (!auth)
   1441 		return;
   1442 
   1443 	wpa_printf(MSG_DEBUG, "DPP: Configuration exchange completed (ok=%d)",
   1444 		   ok);
   1445 	eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
   1446 	eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
   1447 #ifdef CONFIG_DPP2
   1448 	if (ok && auth->peer_version >= 2 &&
   1449 	    auth->conf_resp_status == DPP_STATUS_OK) {
   1450 		wpa_printf(MSG_DEBUG, "DPP: Wait for Configuration Result");
   1451 		auth->waiting_conf_result = 1;
   1452 		eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout,
   1453 				     hapd, NULL);
   1454 		eloop_register_timeout(2, 0,
   1455 				       hostapd_dpp_config_result_wait_timeout,
   1456 				       hapd, NULL);
   1457 		return;
   1458 	}
   1459 #endif /* CONFIG_DPP2 */
   1460 	hostapd_drv_send_action_cancel_wait(hapd);
   1461 
   1462 	if (ok)
   1463 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_SENT);
   1464 	else
   1465 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
   1466 	dpp_auth_deinit(hapd->dpp_auth);
   1467 	hapd->dpp_auth = NULL;
   1468 }
   1469 
   1470 
   1471 int hostapd_dpp_configurator_sign(struct hostapd_data *hapd, const char *cmd)
   1472 {
   1473 	struct dpp_authentication *auth;
   1474 	int ret = -1;
   1475 	char *curve = NULL;
   1476 
   1477 	auth = os_zalloc(sizeof(*auth));
   1478 	if (!auth)
   1479 		return -1;
   1480 
   1481 	curve = get_param(cmd, " curve=");
   1482 	hostapd_dpp_set_testing_options(hapd, auth);
   1483 	if (dpp_set_configurator(hapd->iface->interfaces->dpp, hapd->msg_ctx,
   1484 				 auth, cmd) == 0 &&
   1485 	    dpp_configurator_own_config(auth, curve, 1) == 0) {
   1486 		hostapd_dpp_handle_config_obj(hapd, auth);
   1487 		ret = 0;
   1488 	}
   1489 
   1490 	dpp_auth_deinit(auth);
   1491 	os_free(curve);
   1492 
   1493 	return ret;
   1494 }
   1495 
   1496 
   1497 int hostapd_dpp_pkex_add(struct hostapd_data *hapd, const char *cmd)
   1498 {
   1499 	struct dpp_bootstrap_info *own_bi;
   1500 	const char *pos, *end;
   1501 
   1502 	pos = os_strstr(cmd, " own=");
   1503 	if (!pos)
   1504 		return -1;
   1505 	pos += 5;
   1506 	own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
   1507 	if (!own_bi) {
   1508 		wpa_printf(MSG_DEBUG,
   1509 			   "DPP: Identified bootstrap info not found");
   1510 		return -1;
   1511 	}
   1512 	if (own_bi->type != DPP_BOOTSTRAP_PKEX) {
   1513 		wpa_printf(MSG_DEBUG,
   1514 			   "DPP: Identified bootstrap info not for PKEX");
   1515 		return -1;
   1516 	}
   1517 	hapd->dpp_pkex_bi = own_bi;
   1518 	own_bi->pkex_t = 0; /* clear pending errors on new code */
   1519 
   1520 	os_free(hapd->dpp_pkex_identifier);
   1521 	hapd->dpp_pkex_identifier = NULL;
   1522 	pos = os_strstr(cmd, " identifier=");
   1523 	if (pos) {
   1524 		pos += 12;
   1525 		end = os_strchr(pos, ' ');
   1526 		if (!end)
   1527 			return -1;
   1528 		hapd->dpp_pkex_identifier = os_malloc(end - pos + 1);
   1529 		if (!hapd->dpp_pkex_identifier)
   1530 			return -1;
   1531 		os_memcpy(hapd->dpp_pkex_identifier, pos, end - pos);
   1532 		hapd->dpp_pkex_identifier[end - pos] = '\0';
   1533 	}
   1534 
   1535 	pos = os_strstr(cmd, " code=");
   1536 	if (!pos)
   1537 		return -1;
   1538 	os_free(hapd->dpp_pkex_code);
   1539 	hapd->dpp_pkex_code = os_strdup(pos + 6);
   1540 	if (!hapd->dpp_pkex_code)
   1541 		return -1;
   1542 
   1543 	if (os_strstr(cmd, " init=1")) {
   1544 		struct wpabuf *msg;
   1545 
   1546 		wpa_printf(MSG_DEBUG, "DPP: Initiating PKEX");
   1547 		dpp_pkex_free(hapd->dpp_pkex);
   1548 		hapd->dpp_pkex = dpp_pkex_init(hapd->msg_ctx, own_bi,
   1549 					       hapd->own_addr,
   1550 					       hapd->dpp_pkex_identifier,
   1551 					       hapd->dpp_pkex_code);
   1552 		if (!hapd->dpp_pkex)
   1553 			return -1;
   1554 
   1555 		msg = hapd->dpp_pkex->exchange_req;
   1556 		/* TODO: Which channel to use? */
   1557 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
   1558 			" freq=%u type=%d", MAC2STR(broadcast), 2437,
   1559 			DPP_PA_PKEX_EXCHANGE_REQ);
   1560 		hostapd_drv_send_action(hapd, 2437, 0, broadcast,
   1561 					wpabuf_head(msg), wpabuf_len(msg));
   1562 	}
   1563 
   1564 	/* TODO: Support multiple PKEX info entries */
   1565 
   1566 	os_free(hapd->dpp_pkex_auth_cmd);
   1567 	hapd->dpp_pkex_auth_cmd = os_strdup(cmd);
   1568 
   1569 	return 1;
   1570 }
   1571 
   1572 
   1573 int hostapd_dpp_pkex_remove(struct hostapd_data *hapd, const char *id)
   1574 {
   1575 	unsigned int id_val;
   1576 
   1577 	if (os_strcmp(id, "*") == 0) {
   1578 		id_val = 0;
   1579 	} else {
   1580 		id_val = atoi(id);
   1581 		if (id_val == 0)
   1582 			return -1;
   1583 	}
   1584 
   1585 	if ((id_val != 0 && id_val != 1) || !hapd->dpp_pkex_code)
   1586 		return -1;
   1587 
   1588 	/* TODO: Support multiple PKEX entries */
   1589 	os_free(hapd->dpp_pkex_code);
   1590 	hapd->dpp_pkex_code = NULL;
   1591 	os_free(hapd->dpp_pkex_identifier);
   1592 	hapd->dpp_pkex_identifier = NULL;
   1593 	os_free(hapd->dpp_pkex_auth_cmd);
   1594 	hapd->dpp_pkex_auth_cmd = NULL;
   1595 	hapd->dpp_pkex_bi = NULL;
   1596 	/* TODO: Remove dpp_pkex only if it is for the identified PKEX code */
   1597 	dpp_pkex_free(hapd->dpp_pkex);
   1598 	hapd->dpp_pkex = NULL;
   1599 	return 0;
   1600 }
   1601 
   1602 
   1603 void hostapd_dpp_stop(struct hostapd_data *hapd)
   1604 {
   1605 	dpp_auth_deinit(hapd->dpp_auth);
   1606 	hapd->dpp_auth = NULL;
   1607 	dpp_pkex_free(hapd->dpp_pkex);
   1608 	hapd->dpp_pkex = NULL;
   1609 }
   1610 
   1611 
   1612 int hostapd_dpp_init(struct hostapd_data *hapd)
   1613 {
   1614 	hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE;
   1615 	hapd->dpp_init_done = 1;
   1616 	return 0;
   1617 }
   1618 
   1619 
   1620 void hostapd_dpp_deinit(struct hostapd_data *hapd)
   1621 {
   1622 #ifdef CONFIG_TESTING_OPTIONS
   1623 	os_free(hapd->dpp_config_obj_override);
   1624 	hapd->dpp_config_obj_override = NULL;
   1625 	os_free(hapd->dpp_discovery_override);
   1626 	hapd->dpp_discovery_override = NULL;
   1627 	os_free(hapd->dpp_groups_override);
   1628 	hapd->dpp_groups_override = NULL;
   1629 	hapd->dpp_ignore_netaccesskey_mismatch = 0;
   1630 #endif /* CONFIG_TESTING_OPTIONS */
   1631 	if (!hapd->dpp_init_done)
   1632 		return;
   1633 	eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
   1634 	eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
   1635 	eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
   1636 #ifdef CONFIG_DPP2
   1637 	eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout, hapd,
   1638 			     NULL);
   1639 #endif /* CONFIG_DPP2 */
   1640 	dpp_auth_deinit(hapd->dpp_auth);
   1641 	hapd->dpp_auth = NULL;
   1642 	hostapd_dpp_pkex_remove(hapd, "*");
   1643 	hapd->dpp_pkex = NULL;
   1644 	os_free(hapd->dpp_configurator_params);
   1645 	hapd->dpp_configurator_params = NULL;
   1646 }
   1647