• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
hostapd_dpp_qr_code(struct hostapd_data * hapd,const char * cmd)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 
hostapd_dpp_auth_resp_retry_timeout(void * eloop_ctx,void * timeout_ctx)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 
hostapd_dpp_auth_resp_retry(struct hostapd_data * hapd)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 
hostapd_dpp_tx_status(struct hostapd_data * hapd,const u8 * dst,const u8 * data,size_t data_len,int ok)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 
hostapd_dpp_reply_wait_timeout(void * eloop_ctx,void * timeout_ctx)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 
hostapd_dpp_set_testing_options(struct hostapd_data * hapd,struct dpp_authentication * auth)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 
hostapd_dpp_init_timeout(void * eloop_ctx,void * timeout_ctx)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 
hostapd_dpp_auth_init_next(struct hostapd_data * hapd)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 
hostapd_dpp_auth_init(struct hostapd_data * hapd,const char * cmd)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 
hostapd_dpp_listen(struct hostapd_data * hapd,const char * cmd)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 
hostapd_dpp_listen_stop(struct hostapd_data * hapd)516 void hostapd_dpp_listen_stop(struct hostapd_data *hapd)
517 {
518 	/* TODO: Stop listen operation on non-operating channel */
519 }
520 
521 
hostapd_dpp_rx_auth_req(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)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 
hostapd_dpp_handle_config_obj(struct hostapd_data * hapd,struct dpp_authentication * auth)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 
hostapd_dpp_gas_resp_cb(void * ctx,const u8 * addr,u8 dialog_token,enum gas_query_ap_result result,const struct wpabuf * adv_proto,const struct wpabuf * resp,u16 status_code)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 
hostapd_dpp_start_gas_client(struct hostapd_data * hapd)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 
hostapd_dpp_auth_success(struct hostapd_data * hapd,int initiator)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 
hostapd_dpp_rx_auth_resp(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)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 
hostapd_dpp_rx_auth_conf(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len)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 
hostapd_dpp_config_result_wait_timeout(void * eloop_ctx,void * timeout_ctx)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 
hostapd_dpp_rx_conf_result(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len)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 
hostapd_dpp_send_peer_disc_resp(struct hostapd_data * hapd,const u8 * src,unsigned int freq,u8 trans_id,enum dpp_status_error status)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 
hostapd_dpp_rx_peer_disc_req(struct hostapd_data * hapd,const u8 * src,const u8 * buf,size_t len,unsigned int freq)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
hostapd_dpp_rx_pkex_exchange_req(struct hostapd_data * hapd,const u8 * src,const u8 * buf,size_t len,unsigned int freq)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
hostapd_dpp_rx_pkex_exchange_resp(struct hostapd_data * hapd,const u8 * src,const u8 * buf,size_t len,unsigned int freq)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
hostapd_dpp_rx_pkex_commit_reveal_req(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)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
hostapd_dpp_rx_pkex_commit_reveal_resp(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)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 
hostapd_dpp_rx_action(struct hostapd_data * hapd,const u8 * src,const u8 * buf,size_t len,unsigned int freq)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 *
hostapd_dpp_gas_req_handler(struct hostapd_data * hapd,const u8 * sa,const u8 * query,size_t query_len)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 
hostapd_dpp_gas_status_handler(struct hostapd_data * hapd,int ok)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 
hostapd_dpp_configurator_sign(struct hostapd_data * hapd,const char * cmd)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 
hostapd_dpp_pkex_add(struct hostapd_data * hapd,const char * cmd)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 
hostapd_dpp_pkex_remove(struct hostapd_data * hapd,const char * id)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 
hostapd_dpp_stop(struct hostapd_data * hapd)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 
hostapd_dpp_init(struct hostapd_data * hapd)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 
hostapd_dpp_deinit(struct hostapd_data * hapd)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