1 /*
2 * hostapd / DPP integration
3 * Copyright (c) 2017, Qualcomm Atheros, Inc.
4 * Copyright (c) 2018-2020, The Linux Foundation
5 *
6 * This software may be distributed under the terms of the BSD license.
7 * See README for more details.
8 */
9
10 #include "utils/includes.h"
11
12 #include "utils/common.h"
13 #include "utils/eloop.h"
14 #include "common/dpp.h"
15 #include "common/gas.h"
16 #include "common/wpa_ctrl.h"
17 #include "hostapd.h"
18 #include "ap_drv_ops.h"
19 #include "gas_query_ap.h"
20 #include "gas_serv.h"
21 #include "wpa_auth.h"
22 #include "dpp_hostapd.h"
23
24
25 static void hostapd_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx);
26 static void hostapd_dpp_auth_conf_wait_timeout(void *eloop_ctx,
27 void *timeout_ctx);
28 static void hostapd_dpp_auth_success(struct hostapd_data *hapd, int initiator);
29 static void hostapd_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx);
30 static int hostapd_dpp_auth_init_next(struct hostapd_data *hapd);
31 #ifdef CONFIG_DPP2
32 static void hostapd_dpp_reconfig_reply_wait_timeout(void *eloop_ctx,
33 void *timeout_ctx);
34 static void hostapd_dpp_handle_config_obj(struct hostapd_data *hapd,
35 struct dpp_authentication *auth,
36 struct dpp_config_obj *conf);
37 #endif /* CONFIG_DPP2 */
38
39 static const u8 broadcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
40
41
42 /**
43 * hostapd_dpp_qr_code - Parse and add DPP bootstrapping info from a QR Code
44 * @hapd: Pointer to hostapd_data
45 * @cmd: DPP URI read from a QR Code
46 * Returns: Identifier of the stored info or -1 on failure
47 */
hostapd_dpp_qr_code(struct hostapd_data * hapd,const char * cmd)48 int hostapd_dpp_qr_code(struct hostapd_data *hapd, const char *cmd)
49 {
50 struct dpp_bootstrap_info *bi;
51 struct dpp_authentication *auth = hapd->dpp_auth;
52
53 bi = dpp_add_qr_code(hapd->iface->interfaces->dpp, cmd);
54 if (!bi)
55 return -1;
56
57 if (auth && auth->response_pending &&
58 dpp_notify_new_qr_code(auth, bi) == 1) {
59 wpa_printf(MSG_DEBUG,
60 "DPP: Sending out pending authentication response");
61 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
62 " freq=%u type=%d",
63 MAC2STR(auth->peer_mac_addr), auth->curr_freq,
64 DPP_PA_AUTHENTICATION_RESP);
65 hostapd_drv_send_action(hapd, auth->curr_freq, 0,
66 auth->peer_mac_addr,
67 wpabuf_head(hapd->dpp_auth->resp_msg),
68 wpabuf_len(hapd->dpp_auth->resp_msg));
69 }
70
71 #ifdef CONFIG_DPP2
72 dpp_controller_new_qr_code(hapd->iface->interfaces->dpp, bi);
73 #endif /* CONFIG_DPP2 */
74
75 return bi->id;
76 }
77
78
79 /**
80 * hostapd_dpp_nfc_uri - Parse and add DPP bootstrapping info from NFC Tag (URI)
81 * @hapd: Pointer to hostapd_data
82 * @cmd: DPP URI read from a NFC Tag (URI NDEF message)
83 * Returns: Identifier of the stored info or -1 on failure
84 */
hostapd_dpp_nfc_uri(struct hostapd_data * hapd,const char * cmd)85 int hostapd_dpp_nfc_uri(struct hostapd_data *hapd, const char *cmd)
86 {
87 struct dpp_bootstrap_info *bi;
88
89 bi = dpp_add_nfc_uri(hapd->iface->interfaces->dpp, cmd);
90 if (!bi)
91 return -1;
92
93 return bi->id;
94 }
95
96
hostapd_dpp_nfc_handover_req(struct hostapd_data * hapd,const char * cmd)97 int hostapd_dpp_nfc_handover_req(struct hostapd_data *hapd, const char *cmd)
98 {
99 const char *pos;
100 struct dpp_bootstrap_info *peer_bi, *own_bi;
101
102 pos = os_strstr(cmd, " own=");
103 if (!pos)
104 return -1;
105 pos += 5;
106 own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
107 if (!own_bi)
108 return -1;
109
110 pos = os_strstr(cmd, " uri=");
111 if (!pos)
112 return -1;
113 pos += 5;
114 peer_bi = dpp_add_nfc_uri(hapd->iface->interfaces->dpp, pos);
115 if (!peer_bi) {
116 wpa_printf(MSG_INFO,
117 "DPP: Failed to parse URI from NFC Handover Request");
118 return -1;
119 }
120
121 if (dpp_nfc_update_bi(own_bi, peer_bi) < 0)
122 return -1;
123
124 return peer_bi->id;
125 }
126
127
hostapd_dpp_nfc_handover_sel(struct hostapd_data * hapd,const char * cmd)128 int hostapd_dpp_nfc_handover_sel(struct hostapd_data *hapd, const char *cmd)
129 {
130 const char *pos;
131 struct dpp_bootstrap_info *peer_bi, *own_bi;
132
133 pos = os_strstr(cmd, " own=");
134 if (!pos)
135 return -1;
136 pos += 5;
137 own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
138 if (!own_bi)
139 return -1;
140
141 pos = os_strstr(cmd, " uri=");
142 if (!pos)
143 return -1;
144 pos += 5;
145 peer_bi = dpp_add_nfc_uri(hapd->iface->interfaces->dpp, pos);
146 if (!peer_bi) {
147 wpa_printf(MSG_INFO,
148 "DPP: Failed to parse URI from NFC Handover Select");
149 return -1;
150 }
151
152 if (peer_bi->curve != own_bi->curve) {
153 wpa_printf(MSG_INFO,
154 "DPP: Peer (NFC Handover Selector) used different curve");
155 return -1;
156 }
157
158 return peer_bi->id;
159 }
160
161
hostapd_dpp_auth_resp_retry_timeout(void * eloop_ctx,void * timeout_ctx)162 static void hostapd_dpp_auth_resp_retry_timeout(void *eloop_ctx,
163 void *timeout_ctx)
164 {
165 struct hostapd_data *hapd = eloop_ctx;
166 struct dpp_authentication *auth = hapd->dpp_auth;
167
168 if (!auth || !auth->resp_msg)
169 return;
170
171 wpa_printf(MSG_DEBUG,
172 "DPP: Retry Authentication Response after timeout");
173 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
174 " freq=%u type=%d",
175 MAC2STR(auth->peer_mac_addr), auth->curr_freq,
176 DPP_PA_AUTHENTICATION_RESP);
177 hostapd_drv_send_action(hapd, auth->curr_freq, 500, auth->peer_mac_addr,
178 wpabuf_head(auth->resp_msg),
179 wpabuf_len(auth->resp_msg));
180 }
181
182
hostapd_dpp_auth_resp_retry(struct hostapd_data * hapd)183 static void hostapd_dpp_auth_resp_retry(struct hostapd_data *hapd)
184 {
185 struct dpp_authentication *auth = hapd->dpp_auth;
186 unsigned int wait_time, max_tries;
187
188 if (!auth || !auth->resp_msg)
189 return;
190
191 if (hapd->dpp_resp_max_tries)
192 max_tries = hapd->dpp_resp_max_tries;
193 else
194 max_tries = 5;
195 auth->auth_resp_tries++;
196 if (auth->auth_resp_tries >= max_tries) {
197 wpa_printf(MSG_INFO,
198 "DPP: No confirm received from initiator - stopping exchange");
199 hostapd_drv_send_action_cancel_wait(hapd);
200 dpp_auth_deinit(hapd->dpp_auth);
201 hapd->dpp_auth = NULL;
202 return;
203 }
204
205 if (hapd->dpp_resp_retry_time)
206 wait_time = hapd->dpp_resp_retry_time;
207 else
208 wait_time = 1000;
209 wpa_printf(MSG_DEBUG,
210 "DPP: Schedule retransmission of Authentication Response frame in %u ms",
211 wait_time);
212 eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
213 eloop_register_timeout(wait_time / 1000,
214 (wait_time % 1000) * 1000,
215 hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
216 }
217
218
hostapd_dpp_tx_status(struct hostapd_data * hapd,const u8 * dst,const u8 * data,size_t data_len,int ok)219 void hostapd_dpp_tx_status(struct hostapd_data *hapd, const u8 *dst,
220 const u8 *data, size_t data_len, int ok)
221 {
222 struct dpp_authentication *auth = hapd->dpp_auth;
223
224 wpa_printf(MSG_DEBUG, "DPP: TX status: dst=" MACSTR_SEC " ok=%d",
225 MAC2STR_SEC(dst), ok);
226 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX_STATUS "dst=" MACSTR
227 " result=%s", MAC2STR(dst), ok ? "SUCCESS" : "FAILED");
228
229 if (!hapd->dpp_auth) {
230 wpa_printf(MSG_DEBUG,
231 "DPP: Ignore TX status since there is no ongoing authentication exchange");
232 return;
233 }
234
235 #ifdef CONFIG_DPP2
236 if (auth->connect_on_tx_status) {
237 wpa_printf(MSG_DEBUG,
238 "DPP: Complete exchange on configuration result");
239 dpp_auth_deinit(hapd->dpp_auth);
240 hapd->dpp_auth = NULL;
241 return;
242 }
243 #endif /* CONFIG_DPP2 */
244
245 if (hapd->dpp_auth->remove_on_tx_status) {
246 wpa_printf(MSG_DEBUG,
247 "DPP: Terminate authentication exchange due to an earlier error");
248 eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
249 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
250 hapd, NULL);
251 eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout,
252 hapd, NULL);
253 eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd,
254 NULL);
255 #ifdef CONFIG_DPP2
256 eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
257 hapd, NULL);
258 #endif /* CONFIG_DPP2 */
259 hostapd_drv_send_action_cancel_wait(hapd);
260 dpp_auth_deinit(hapd->dpp_auth);
261 hapd->dpp_auth = NULL;
262 return;
263 }
264
265 if (hapd->dpp_auth_ok_on_ack)
266 hostapd_dpp_auth_success(hapd, 1);
267
268 if (!is_broadcast_ether_addr(dst) && !ok) {
269 wpa_printf(MSG_DEBUG,
270 "DPP: Unicast DPP Action frame was not ACKed");
271 if (auth->waiting_auth_resp) {
272 /* In case of DPP Authentication Request frame, move to
273 * the next channel immediately. */
274 hostapd_drv_send_action_cancel_wait(hapd);
275 hostapd_dpp_auth_init_next(hapd);
276 return;
277 }
278 if (auth->waiting_auth_conf) {
279 hostapd_dpp_auth_resp_retry(hapd);
280 return;
281 }
282 }
283
284 if (auth->waiting_auth_conf &&
285 auth->auth_resp_status == DPP_STATUS_OK) {
286 /* Make sure we do not get stuck waiting for Auth Confirm
287 * indefinitely after successfully transmitted Auth Response to
288 * allow new authentication exchanges to be started. */
289 eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout, hapd,
290 NULL);
291 eloop_register_timeout(1, 0, hostapd_dpp_auth_conf_wait_timeout,
292 hapd, NULL);
293 }
294
295 if (!is_broadcast_ether_addr(dst) && auth->waiting_auth_resp && ok) {
296 /* Allow timeout handling to stop iteration if no response is
297 * received from a peer that has ACKed a request. */
298 auth->auth_req_ack = 1;
299 }
300
301 if (!hapd->dpp_auth_ok_on_ack && hapd->dpp_auth->neg_freq > 0 &&
302 hapd->dpp_auth->curr_freq != hapd->dpp_auth->neg_freq) {
303 wpa_printf(MSG_DEBUG,
304 "DPP: Move from curr_freq %u MHz to neg_freq %u MHz for response",
305 hapd->dpp_auth->curr_freq,
306 hapd->dpp_auth->neg_freq);
307 hostapd_drv_send_action_cancel_wait(hapd);
308
309 if (hapd->dpp_auth->neg_freq !=
310 (unsigned int) hapd->iface->freq && hapd->iface->freq > 0) {
311 /* TODO: Listen operation on non-operating channel */
312 wpa_printf(MSG_INFO,
313 "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)",
314 hapd->dpp_auth->neg_freq, hapd->iface->freq);
315 }
316 }
317
318 if (hapd->dpp_auth_ok_on_ack)
319 hapd->dpp_auth_ok_on_ack = 0;
320 }
321
322
hostapd_dpp_reply_wait_timeout(void * eloop_ctx,void * timeout_ctx)323 static void hostapd_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx)
324 {
325 struct hostapd_data *hapd = eloop_ctx;
326 struct dpp_authentication *auth = hapd->dpp_auth;
327 unsigned int freq;
328 struct os_reltime now, diff;
329 unsigned int wait_time, diff_ms;
330
331 if (!auth || !auth->waiting_auth_resp)
332 return;
333
334 wait_time = hapd->dpp_resp_wait_time ?
335 hapd->dpp_resp_wait_time : 2000;
336 os_get_reltime(&now);
337 os_reltime_sub(&now, &hapd->dpp_last_init, &diff);
338 diff_ms = diff.sec * 1000 + diff.usec / 1000;
339 wpa_printf(MSG_DEBUG,
340 "DPP: Reply wait timeout - wait_time=%u diff_ms=%u",
341 wait_time, diff_ms);
342
343 if (auth->auth_req_ack && diff_ms >= wait_time) {
344 /* Peer ACK'ed Authentication Request frame, but did not reply
345 * with Authentication Response frame within two seconds. */
346 wpa_printf(MSG_INFO,
347 "DPP: No response received from responder - stopping initiation attempt");
348 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_AUTH_INIT_FAILED);
349 hostapd_drv_send_action_cancel_wait(hapd);
350 hostapd_dpp_listen_stop(hapd);
351 dpp_auth_deinit(auth);
352 hapd->dpp_auth = NULL;
353 return;
354 }
355
356 if (diff_ms >= wait_time) {
357 /* Authentication Request frame was not ACK'ed and no reply
358 * was receiving within two seconds. */
359 wpa_printf(MSG_DEBUG,
360 "DPP: Continue Initiator channel iteration");
361 hostapd_drv_send_action_cancel_wait(hapd);
362 hostapd_dpp_listen_stop(hapd);
363 hostapd_dpp_auth_init_next(hapd);
364 return;
365 }
366
367 /* Driver did not support 2000 ms long wait_time with TX command, so
368 * schedule listen operation to continue waiting for the response.
369 *
370 * DPP listen operations continue until stopped, so simply schedule a
371 * new call to this function at the point when the two second reply
372 * wait has expired. */
373 wait_time -= diff_ms;
374
375 freq = auth->curr_freq;
376 if (auth->neg_freq > 0)
377 freq = auth->neg_freq;
378 wpa_printf(MSG_DEBUG,
379 "DPP: Continue reply wait on channel %u MHz for %u ms",
380 freq, wait_time);
381 hapd->dpp_in_response_listen = 1;
382
383 if (freq != (unsigned int) hapd->iface->freq && hapd->iface->freq > 0) {
384 /* TODO: Listen operation on non-operating channel */
385 wpa_printf(MSG_INFO,
386 "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)",
387 freq, hapd->iface->freq);
388 }
389
390 eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
391 hostapd_dpp_reply_wait_timeout, hapd, NULL);
392 }
393
394
hostapd_dpp_auth_conf_wait_timeout(void * eloop_ctx,void * timeout_ctx)395 static void hostapd_dpp_auth_conf_wait_timeout(void *eloop_ctx,
396 void *timeout_ctx)
397 {
398 struct hostapd_data *hapd = eloop_ctx;
399 struct dpp_authentication *auth = hapd->dpp_auth;
400
401 if (!auth || !auth->waiting_auth_conf)
402 return;
403
404 wpa_printf(MSG_DEBUG,
405 "DPP: Terminate authentication exchange due to Auth Confirm timeout");
406 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
407 "No Auth Confirm received");
408 hostapd_drv_send_action_cancel_wait(hapd);
409 dpp_auth_deinit(auth);
410 hapd->dpp_auth = NULL;
411 }
412
413
hostapd_dpp_set_testing_options(struct hostapd_data * hapd,struct dpp_authentication * auth)414 static void hostapd_dpp_set_testing_options(struct hostapd_data *hapd,
415 struct dpp_authentication *auth)
416 {
417 #ifdef CONFIG_TESTING_OPTIONS
418 if (hapd->dpp_config_obj_override)
419 auth->config_obj_override =
420 os_strdup(hapd->dpp_config_obj_override);
421 if (hapd->dpp_discovery_override)
422 auth->discovery_override =
423 os_strdup(hapd->dpp_discovery_override);
424 if (hapd->dpp_groups_override)
425 auth->groups_override = os_strdup(hapd->dpp_groups_override);
426 auth->ignore_netaccesskey_mismatch =
427 hapd->dpp_ignore_netaccesskey_mismatch;
428 #endif /* CONFIG_TESTING_OPTIONS */
429 }
430
431
hostapd_dpp_init_timeout(void * eloop_ctx,void * timeout_ctx)432 static void hostapd_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx)
433 {
434 struct hostapd_data *hapd = eloop_ctx;
435
436 if (!hapd->dpp_auth)
437 return;
438 wpa_printf(MSG_DEBUG, "DPP: Retry initiation after timeout");
439 hostapd_dpp_auth_init_next(hapd);
440 }
441
442
hostapd_dpp_auth_init_next(struct hostapd_data * hapd)443 static int hostapd_dpp_auth_init_next(struct hostapd_data *hapd)
444 {
445 struct dpp_authentication *auth = hapd->dpp_auth;
446 const u8 *dst;
447 unsigned int wait_time, max_wait_time, freq, max_tries, used;
448 struct os_reltime now, diff;
449
450 if (!auth)
451 return -1;
452
453 if (auth->freq_idx == 0)
454 os_get_reltime(&hapd->dpp_init_iter_start);
455
456 if (auth->freq_idx >= auth->num_freq) {
457 auth->num_freq_iters++;
458 if (hapd->dpp_init_max_tries)
459 max_tries = hapd->dpp_init_max_tries;
460 else
461 max_tries = 5;
462 if (auth->num_freq_iters >= max_tries || auth->auth_req_ack) {
463 wpa_printf(MSG_INFO,
464 "DPP: No response received from responder - stopping initiation attempt");
465 wpa_msg(hapd->msg_ctx, MSG_INFO,
466 DPP_EVENT_AUTH_INIT_FAILED);
467 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
468 hapd, NULL);
469 hostapd_drv_send_action_cancel_wait(hapd);
470 dpp_auth_deinit(hapd->dpp_auth);
471 hapd->dpp_auth = NULL;
472 return -1;
473 }
474 auth->freq_idx = 0;
475 eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
476 if (hapd->dpp_init_retry_time)
477 wait_time = hapd->dpp_init_retry_time;
478 else
479 wait_time = 10000;
480 os_get_reltime(&now);
481 os_reltime_sub(&now, &hapd->dpp_init_iter_start, &diff);
482 used = diff.sec * 1000 + diff.usec / 1000;
483 if (used > wait_time)
484 wait_time = 0;
485 else
486 wait_time -= used;
487 wpa_printf(MSG_DEBUG, "DPP: Next init attempt in %u ms",
488 wait_time);
489 eloop_register_timeout(wait_time / 1000,
490 (wait_time % 1000) * 1000,
491 hostapd_dpp_init_timeout, hapd,
492 NULL);
493 return 0;
494 }
495 freq = auth->freq[auth->freq_idx++];
496 auth->curr_freq = freq;
497
498 if (!is_zero_ether_addr(auth->peer_mac_addr))
499 dst = auth->peer_mac_addr;
500 else if (is_zero_ether_addr(auth->peer_bi->mac_addr))
501 dst = broadcast;
502 else
503 dst = auth->peer_bi->mac_addr;
504 hapd->dpp_auth_ok_on_ack = 0;
505 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
506 wait_time = 2000; /* TODO: hapd->max_remain_on_chan; */
507 max_wait_time = hapd->dpp_resp_wait_time ?
508 hapd->dpp_resp_wait_time : 2000;
509 if (wait_time > max_wait_time)
510 wait_time = max_wait_time;
511 wait_time += 10; /* give the driver some extra time to complete */
512 eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
513 hostapd_dpp_reply_wait_timeout, hapd, NULL);
514 wait_time -= 10;
515 if (auth->neg_freq > 0 && freq != auth->neg_freq) {
516 wpa_printf(MSG_DEBUG,
517 "DPP: Initiate on %u MHz and move to neg_freq %u MHz for response",
518 freq, auth->neg_freq);
519 }
520 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
521 " freq=%u type=%d",
522 MAC2STR(dst), freq, DPP_PA_AUTHENTICATION_REQ);
523 auth->auth_req_ack = 0;
524 os_get_reltime(&hapd->dpp_last_init);
525 return hostapd_drv_send_action(hapd, freq, wait_time,
526 dst,
527 wpabuf_head(hapd->dpp_auth->req_msg),
528 wpabuf_len(hapd->dpp_auth->req_msg));
529 }
530
531
532 #ifdef CONFIG_DPP2
hostapd_dpp_process_conf_obj(void * ctx,struct dpp_authentication * auth)533 static int hostapd_dpp_process_conf_obj(void *ctx,
534 struct dpp_authentication *auth)
535 {
536 struct hostapd_data *hapd = ctx;
537 unsigned int i;
538
539 for (i = 0; i < auth->num_conf_obj; i++)
540 hostapd_dpp_handle_config_obj(hapd, auth,
541 &auth->conf_obj[i]);
542
543 return 0;
544 }
545 #endif /* CONFIG_DPP2 */
546
547
hostapd_dpp_auth_init(struct hostapd_data * hapd,const char * cmd)548 int hostapd_dpp_auth_init(struct hostapd_data *hapd, const char *cmd)
549 {
550 const char *pos;
551 struct dpp_bootstrap_info *peer_bi, *own_bi = NULL;
552 struct dpp_authentication *auth;
553 u8 allowed_roles = DPP_CAPAB_CONFIGURATOR;
554 unsigned int neg_freq = 0;
555 int tcp = 0;
556 #ifdef CONFIG_DPP2
557 int tcp_port = DPP_TCP_PORT;
558 struct hostapd_ip_addr ipaddr;
559 char *addr;
560 #endif /* CONFIG_DPP2 */
561
562 pos = os_strstr(cmd, " peer=");
563 if (!pos)
564 return -1;
565 pos += 6;
566 peer_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
567 if (!peer_bi) {
568 wpa_printf(MSG_INFO,
569 "DPP: Could not find bootstrapping info for the identified peer");
570 return -1;
571 }
572
573 #ifdef CONFIG_DPP2
574 pos = os_strstr(cmd, " tcp_port=");
575 if (pos) {
576 pos += 10;
577 tcp_port = atoi(pos);
578 }
579
580 addr = get_param(cmd, " tcp_addr=");
581 if (addr) {
582 int res;
583
584 res = hostapd_parse_ip_addr(addr, &ipaddr);
585 os_free(addr);
586 if (res)
587 return -1;
588 tcp = 1;
589 }
590 #endif /* CONFIG_DPP2 */
591
592 pos = os_strstr(cmd, " own=");
593 if (pos) {
594 pos += 5;
595 own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp,
596 atoi(pos));
597 if (!own_bi) {
598 wpa_printf(MSG_INFO,
599 "DPP: Could not find bootstrapping info for the identified local entry");
600 return -1;
601 }
602
603 if (peer_bi->curve != own_bi->curve) {
604 wpa_printf(MSG_INFO,
605 "DPP: Mismatching curves in bootstrapping info (peer=%s own=%s)",
606 peer_bi->curve->name, own_bi->curve->name);
607 return -1;
608 }
609 }
610
611 pos = os_strstr(cmd, " role=");
612 if (pos) {
613 pos += 6;
614 if (os_strncmp(pos, "configurator", 12) == 0)
615 allowed_roles = DPP_CAPAB_CONFIGURATOR;
616 else if (os_strncmp(pos, "enrollee", 8) == 0)
617 allowed_roles = DPP_CAPAB_ENROLLEE;
618 else if (os_strncmp(pos, "either", 6) == 0)
619 allowed_roles = DPP_CAPAB_CONFIGURATOR |
620 DPP_CAPAB_ENROLLEE;
621 else
622 goto fail;
623 }
624
625 pos = os_strstr(cmd, " neg_freq=");
626 if (pos)
627 neg_freq = atoi(pos + 10);
628
629 if (!tcp && hapd->dpp_auth) {
630 eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
631 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
632 hapd, NULL);
633 eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout,
634 hapd, NULL);
635 eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd,
636 NULL);
637 #ifdef CONFIG_DPP2
638 eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
639 hapd, NULL);
640 #endif /* CONFIG_DPP2 */
641 hostapd_drv_send_action_cancel_wait(hapd);
642 dpp_auth_deinit(hapd->dpp_auth);
643 }
644
645 auth = dpp_auth_init(hapd->iface->interfaces->dpp, hapd->msg_ctx,
646 peer_bi, own_bi, allowed_roles, neg_freq,
647 hapd->iface->hw_features,
648 hapd->iface->num_hw_features);
649 if (!auth)
650 goto fail;
651 hostapd_dpp_set_testing_options(hapd, auth);
652 if (dpp_set_configurator(auth, cmd) < 0) {
653 dpp_auth_deinit(auth);
654 goto fail;
655 }
656
657 auth->neg_freq = neg_freq;
658
659 if (!is_zero_ether_addr(peer_bi->mac_addr))
660 os_memcpy(auth->peer_mac_addr, peer_bi->mac_addr, ETH_ALEN);
661
662 #ifdef CONFIG_DPP2
663 if (tcp)
664 return dpp_tcp_init(hapd->iface->interfaces->dpp, auth,
665 &ipaddr, tcp_port, hapd->conf->dpp_name,
666 DPP_NETROLE_AP, hapd->msg_ctx, hapd,
667 hostapd_dpp_process_conf_obj);
668 #endif /* CONFIG_DPP2 */
669
670 hapd->dpp_auth = auth;
671 return hostapd_dpp_auth_init_next(hapd);
672 fail:
673 return -1;
674 }
675
676
hostapd_dpp_listen(struct hostapd_data * hapd,const char * cmd)677 int hostapd_dpp_listen(struct hostapd_data *hapd, const char *cmd)
678 {
679 int freq;
680
681 freq = atoi(cmd);
682 if (freq <= 0)
683 return -1;
684
685 if (os_strstr(cmd, " role=configurator"))
686 hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR;
687 else if (os_strstr(cmd, " role=enrollee"))
688 hapd->dpp_allowed_roles = DPP_CAPAB_ENROLLEE;
689 else
690 hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR |
691 DPP_CAPAB_ENROLLEE;
692 hapd->dpp_qr_mutual = os_strstr(cmd, " qr=mutual") != NULL;
693
694 if (freq != hapd->iface->freq && hapd->iface->freq > 0) {
695 /* TODO: Listen operation on non-operating channel */
696 wpa_printf(MSG_INFO,
697 "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)",
698 freq, hapd->iface->freq);
699 return -1;
700 }
701
702 hostapd_drv_dpp_listen(hapd, true);
703 return 0;
704 }
705
706
hostapd_dpp_listen_stop(struct hostapd_data * hapd)707 void hostapd_dpp_listen_stop(struct hostapd_data *hapd)
708 {
709 hostapd_drv_dpp_listen(hapd, false);
710 /* TODO: Stop listen operation on non-operating channel */
711 }
712
713
hostapd_dpp_rx_auth_req(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)714 static void hostapd_dpp_rx_auth_req(struct hostapd_data *hapd, const u8 *src,
715 const u8 *hdr, const u8 *buf, size_t len,
716 unsigned int freq)
717 {
718 const u8 *r_bootstrap, *i_bootstrap;
719 u16 r_bootstrap_len, i_bootstrap_len;
720 struct dpp_bootstrap_info *own_bi = NULL, *peer_bi = NULL;
721
722 if (!hapd->iface->interfaces->dpp)
723 return;
724
725 wpa_printf(MSG_DEBUG, "DPP: Authentication Request from " MACSTR_SEC,
726 MAC2STR_SEC(src));
727
728 #ifdef CONFIG_DPP2
729 hostapd_dpp_chirp_stop(hapd);
730 #endif /* CONFIG_DPP2 */
731
732 r_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
733 &r_bootstrap_len);
734 if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) {
735 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
736 "Missing or invalid required Responder Bootstrapping Key Hash attribute");
737 return;
738 }
739 wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash",
740 r_bootstrap, r_bootstrap_len);
741
742 i_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_I_BOOTSTRAP_KEY_HASH,
743 &i_bootstrap_len);
744 if (!i_bootstrap || i_bootstrap_len != SHA256_MAC_LEN) {
745 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
746 "Missing or invalid required Initiator Bootstrapping Key Hash attribute");
747 return;
748 }
749 wpa_hexdump(MSG_MSGDUMP, "DPP: Initiator Bootstrapping Key Hash",
750 i_bootstrap, i_bootstrap_len);
751
752 /* Try to find own and peer bootstrapping key matches based on the
753 * received hash values */
754 dpp_bootstrap_find_pair(hapd->iface->interfaces->dpp, i_bootstrap,
755 r_bootstrap, &own_bi, &peer_bi);
756 #ifdef CONFIG_DPP2
757 if (!own_bi) {
758 if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
759 src, hdr, buf, len, freq, i_bootstrap,
760 r_bootstrap, hapd) == 0)
761 return;
762 }
763 #endif /* CONFIG_DPP2 */
764 if (!own_bi) {
765 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
766 "No matching own bootstrapping key found - ignore message");
767 return;
768 }
769
770 if (hapd->dpp_auth) {
771 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
772 "Already in DPP authentication exchange - ignore new one");
773 return;
774 }
775
776 hapd->dpp_auth_ok_on_ack = 0;
777 hapd->dpp_auth = dpp_auth_req_rx(hapd->iface->interfaces->dpp,
778 hapd->msg_ctx, hapd->dpp_allowed_roles,
779 hapd->dpp_qr_mutual,
780 peer_bi, own_bi, freq, hdr, buf, len);
781 if (!hapd->dpp_auth) {
782 wpa_printf(MSG_DEBUG, "DPP: No response generated");
783 return;
784 }
785 hostapd_dpp_set_testing_options(hapd, hapd->dpp_auth);
786 if (dpp_set_configurator(hapd->dpp_auth,
787 hapd->dpp_configurator_params) < 0) {
788 dpp_auth_deinit(hapd->dpp_auth);
789 hapd->dpp_auth = NULL;
790 return;
791 }
792 os_memcpy(hapd->dpp_auth->peer_mac_addr, src, ETH_ALEN);
793
794 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
795 " freq=%u type=%d",
796 MAC2STR(src), hapd->dpp_auth->curr_freq,
797 DPP_PA_AUTHENTICATION_RESP);
798 hostapd_drv_send_action(hapd, hapd->dpp_auth->curr_freq, 0,
799 src, wpabuf_head(hapd->dpp_auth->resp_msg),
800 wpabuf_len(hapd->dpp_auth->resp_msg));
801 }
802
803
hostapd_dpp_handle_config_obj(struct hostapd_data * hapd,struct dpp_authentication * auth,struct dpp_config_obj * conf)804 static void hostapd_dpp_handle_config_obj(struct hostapd_data *hapd,
805 struct dpp_authentication *auth,
806 struct dpp_config_obj *conf)
807 {
808 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_RECEIVED);
809 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_AKM "%s",
810 dpp_akm_str(conf->akm));
811 if (conf->ssid_len)
812 wpa_msg_only_for_cb(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_SSID "%s",
813 wpa_ssid_txt(conf->ssid, conf->ssid_len));
814 wpa_printf(MSG_INFO, "%s", DPP_EVENT_CONFOBJ_SSID "%s",
815 anonymize_ssid(wpa_ssid_txt(conf->ssid, conf->ssid_len)));
816 if (conf->connector) {
817 /* TODO: Save the Connector and consider using a command
818 * to fetch the value instead of sending an event with
819 * it. The Connector could end up being larger than what
820 * most clients are ready to receive as an event
821 * message. */
822 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONNECTOR "%s",
823 conf->connector);
824 }
825 if (conf->passphrase[0]) {
826 char hex[64 * 2 + 1];
827
828 wpa_snprintf_hex(hex, sizeof(hex),
829 (const u8 *) conf->passphrase,
830 os_strlen(conf->passphrase));
831 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_PASS "%s",
832 hex);
833 } else if (conf->psk_set) {
834 char hex[PMK_LEN * 2 + 1];
835
836 wpa_snprintf_hex(hex, sizeof(hex), conf->psk, PMK_LEN);
837 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_PSK "%s",
838 hex);
839 }
840 if (conf->c_sign_key) {
841 char *hex;
842 size_t hexlen;
843
844 hexlen = 2 * wpabuf_len(conf->c_sign_key) + 1;
845 hex = os_malloc(hexlen);
846 if (hex) {
847 wpa_snprintf_hex(hex, hexlen,
848 wpabuf_head(conf->c_sign_key),
849 wpabuf_len(conf->c_sign_key));
850 wpa_msg(hapd->msg_ctx, MSG_INFO,
851 DPP_EVENT_C_SIGN_KEY "%s", hex);
852 os_free(hex);
853 }
854 }
855 if (auth->net_access_key) {
856 char *hex;
857 size_t hexlen;
858
859 hexlen = 2 * wpabuf_len(auth->net_access_key) + 1;
860 hex = os_malloc(hexlen);
861 if (hex) {
862 wpa_snprintf_hex(hex, hexlen,
863 wpabuf_head(auth->net_access_key),
864 wpabuf_len(auth->net_access_key));
865 if (auth->net_access_key_expiry)
866 wpa_msg(hapd->msg_ctx, MSG_INFO,
867 DPP_EVENT_NET_ACCESS_KEY "%s %lu", hex,
868 (unsigned long)
869 auth->net_access_key_expiry);
870 else
871 wpa_msg(hapd->msg_ctx, MSG_INFO,
872 DPP_EVENT_NET_ACCESS_KEY "%s", hex);
873 os_free(hex);
874 }
875 }
876 }
877
878
hostapd_dpp_handle_key_pkg(struct hostapd_data * hapd,struct dpp_asymmetric_key * key)879 static int hostapd_dpp_handle_key_pkg(struct hostapd_data *hapd,
880 struct dpp_asymmetric_key *key)
881 {
882 #ifdef CONFIG_DPP2
883 int res;
884
885 if (!key)
886 return 0;
887
888 wpa_printf(MSG_DEBUG, "DPP: Received Configurator backup");
889 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_RECEIVED);
890
891 while (key) {
892 res = dpp_configurator_from_backup(
893 hapd->iface->interfaces->dpp, key);
894 if (res < 0)
895 return -1;
896 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFIGURATOR_ID "%d",
897 res);
898 key = key->next;
899 }
900 #endif /* CONFIG_DPP2 */
901
902 return 0;
903 }
904
905
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)906 static void hostapd_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token,
907 enum gas_query_ap_result result,
908 const struct wpabuf *adv_proto,
909 const struct wpabuf *resp, u16 status_code)
910 {
911 struct hostapd_data *hapd = ctx;
912 const u8 *pos;
913 struct dpp_authentication *auth = hapd->dpp_auth;
914 enum dpp_status_error status = DPP_STATUS_CONFIG_REJECTED;
915
916 if (!auth || !auth->auth_success) {
917 wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
918 return;
919 }
920 if (result != GAS_QUERY_AP_SUCCESS ||
921 !resp || status_code != WLAN_STATUS_SUCCESS) {
922 wpa_printf(MSG_DEBUG, "DPP: GAS query did not succeed");
923 goto fail;
924 }
925
926 wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response adv_proto",
927 adv_proto);
928 wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response (GAS response)",
929 resp);
930
931 if (wpabuf_len(adv_proto) != 10 ||
932 !(pos = wpabuf_head(adv_proto)) ||
933 pos[0] != WLAN_EID_ADV_PROTO ||
934 pos[1] != 8 ||
935 pos[3] != WLAN_EID_VENDOR_SPECIFIC ||
936 pos[4] != 5 ||
937 WPA_GET_BE24(&pos[5]) != OUI_WFA ||
938 pos[8] != 0x1a ||
939 pos[9] != 1) {
940 wpa_printf(MSG_DEBUG,
941 "DPP: Not a DPP Advertisement Protocol ID");
942 goto fail;
943 }
944
945 if (dpp_conf_resp_rx(auth, resp) < 0) {
946 wpa_printf(MSG_DEBUG, "DPP: Configuration attempt failed");
947 goto fail;
948 }
949
950 hostapd_dpp_handle_config_obj(hapd, auth, &auth->conf_obj[0]);
951 if (hostapd_dpp_handle_key_pkg(hapd, auth->conf_key_pkg) < 0)
952 goto fail;
953
954 status = DPP_STATUS_OK;
955 #ifdef CONFIG_TESTING_OPTIONS
956 if (dpp_test == DPP_TEST_REJECT_CONFIG) {
957 wpa_printf(MSG_INFO, "DPP: TESTING - Reject Config Object");
958 status = DPP_STATUS_CONFIG_REJECTED;
959 }
960 #endif /* CONFIG_TESTING_OPTIONS */
961 fail:
962 if (status != DPP_STATUS_OK)
963 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
964 #ifdef CONFIG_DPP2
965 if (auth->peer_version >= 2 &&
966 auth->conf_resp_status == DPP_STATUS_OK) {
967 struct wpabuf *msg;
968
969 wpa_printf(MSG_DEBUG, "DPP: Send DPP Configuration Result");
970 msg = dpp_build_conf_result(auth, status);
971 if (!msg)
972 goto fail2;
973
974 wpa_msg(hapd->msg_ctx, MSG_INFO,
975 DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
976 MAC2STR(addr), auth->curr_freq,
977 DPP_PA_CONFIGURATION_RESULT);
978 hostapd_drv_send_action(hapd, auth->curr_freq, 0,
979 addr, wpabuf_head(msg),
980 wpabuf_len(msg));
981 wpabuf_free(msg);
982
983 /* This exchange will be terminated in the TX status handler */
984 auth->connect_on_tx_status = 1;
985 return;
986 }
987 fail2:
988 #endif /* CONFIG_DPP2 */
989 dpp_auth_deinit(hapd->dpp_auth);
990 hapd->dpp_auth = NULL;
991 }
992
993
hostapd_dpp_start_gas_client(struct hostapd_data * hapd)994 static void hostapd_dpp_start_gas_client(struct hostapd_data *hapd)
995 {
996 struct dpp_authentication *auth = hapd->dpp_auth;
997 struct wpabuf *buf;
998 int res;
999
1000 buf = dpp_build_conf_req_helper(auth, hapd->conf->dpp_name,
1001 DPP_NETROLE_AP,
1002 hapd->conf->dpp_mud_url, NULL);
1003 if (!buf) {
1004 wpa_printf(MSG_DEBUG,
1005 "DPP: No configuration request data available");
1006 return;
1007 }
1008
1009 wpa_printf(MSG_DEBUG, "DPP: GAS request to " MACSTR_SEC " (freq %u MHz)",
1010 MAC2STR_SEC(auth->peer_mac_addr), auth->curr_freq);
1011
1012 res = gas_query_ap_req(hapd->gas, auth->peer_mac_addr, auth->curr_freq,
1013 buf, hostapd_dpp_gas_resp_cb, hapd);
1014 if (res < 0) {
1015 wpa_msg(hapd->msg_ctx, MSG_DEBUG,
1016 "GAS: Failed to send Query Request");
1017 wpabuf_free(buf);
1018 } else {
1019 wpa_printf(MSG_DEBUG,
1020 "DPP: GAS query started with dialog token %u", res);
1021 }
1022 }
1023
1024
hostapd_dpp_auth_success(struct hostapd_data * hapd,int initiator)1025 static void hostapd_dpp_auth_success(struct hostapd_data *hapd, int initiator)
1026 {
1027 wpa_printf(MSG_DEBUG, "DPP: Authentication succeeded");
1028 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_AUTH_SUCCESS "init=%d",
1029 initiator);
1030 #ifdef CONFIG_TESTING_OPTIONS
1031 if (dpp_test == DPP_TEST_STOP_AT_AUTH_CONF) {
1032 wpa_printf(MSG_INFO,
1033 "DPP: TESTING - stop at Authentication Confirm");
1034 if (hapd->dpp_auth->configurator) {
1035 /* Prevent GAS response */
1036 hapd->dpp_auth->auth_success = 0;
1037 }
1038 return;
1039 }
1040 #endif /* CONFIG_TESTING_OPTIONS */
1041
1042 if (!hapd->dpp_auth->configurator)
1043 hostapd_dpp_start_gas_client(hapd);
1044 }
1045
1046
hostapd_dpp_rx_auth_resp(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)1047 static void hostapd_dpp_rx_auth_resp(struct hostapd_data *hapd, const u8 *src,
1048 const u8 *hdr, const u8 *buf, size_t len,
1049 unsigned int freq)
1050 {
1051 struct dpp_authentication *auth = hapd->dpp_auth;
1052 struct wpabuf *msg;
1053
1054 wpa_printf(MSG_DEBUG, "DPP: Authentication Response from " MACSTR_SEC,
1055 MAC2STR_SEC(src));
1056
1057 if (!auth) {
1058 wpa_printf(MSG_DEBUG,
1059 "DPP: No DPP Authentication in progress - drop");
1060 return;
1061 }
1062
1063 if (!is_zero_ether_addr(auth->peer_mac_addr) &&
1064 os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
1065 wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
1066 MACSTR_SEC ") - drop", MAC2STR_SEC(auth->peer_mac_addr));
1067 return;
1068 }
1069
1070 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
1071
1072 if (auth->curr_freq != freq && auth->neg_freq == freq) {
1073 wpa_printf(MSG_DEBUG,
1074 "DPP: Responder accepted request for different negotiation channel");
1075 auth->curr_freq = freq;
1076 }
1077
1078 eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
1079 msg = dpp_auth_resp_rx(auth, hdr, buf, len);
1080 if (!msg) {
1081 if (auth->auth_resp_status == DPP_STATUS_RESPONSE_PENDING) {
1082 wpa_printf(MSG_DEBUG, "DPP: Wait for full response");
1083 return;
1084 }
1085 wpa_printf(MSG_DEBUG, "DPP: No confirm generated");
1086 return;
1087 }
1088 os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
1089
1090 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1091 " freq=%u type=%d", MAC2STR(src), auth->curr_freq,
1092 DPP_PA_AUTHENTICATION_CONF);
1093 hostapd_drv_send_action(hapd, auth->curr_freq, 0, src,
1094 wpabuf_head(msg), wpabuf_len(msg));
1095 wpabuf_free(msg);
1096 hapd->dpp_auth_ok_on_ack = 1;
1097 }
1098
1099
hostapd_dpp_rx_auth_conf(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len)1100 static void hostapd_dpp_rx_auth_conf(struct hostapd_data *hapd, const u8 *src,
1101 const u8 *hdr, const u8 *buf, size_t len)
1102 {
1103 struct dpp_authentication *auth = hapd->dpp_auth;
1104
1105 wpa_printf(MSG_DEBUG, "DPP: Authentication Confirmation from " MACSTR_SEC,
1106 MAC2STR_SEC(src));
1107
1108 if (!auth) {
1109 wpa_printf(MSG_DEBUG,
1110 "DPP: No DPP Authentication in progress - drop");
1111 return;
1112 }
1113
1114 if (os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
1115 wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
1116 MACSTR_SEC ") - drop", MAC2STR_SEC(auth->peer_mac_addr));
1117 return;
1118 }
1119
1120 if (dpp_auth_conf_rx(auth, hdr, buf, len) < 0) {
1121 wpa_printf(MSG_DEBUG, "DPP: Authentication failed");
1122 return;
1123 }
1124
1125 hostapd_dpp_auth_success(hapd, 0);
1126 }
1127
1128
1129 #ifdef CONFIG_DPP2
1130
hostapd_dpp_config_result_wait_timeout(void * eloop_ctx,void * timeout_ctx)1131 static void hostapd_dpp_config_result_wait_timeout(void *eloop_ctx,
1132 void *timeout_ctx)
1133 {
1134 struct hostapd_data *hapd = eloop_ctx;
1135 struct dpp_authentication *auth = hapd->dpp_auth;
1136
1137 if (!auth || !auth->waiting_conf_result)
1138 return;
1139
1140 wpa_printf(MSG_DEBUG,
1141 "DPP: Timeout while waiting for Configuration Result");
1142 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
1143 dpp_auth_deinit(auth);
1144 hapd->dpp_auth = NULL;
1145 }
1146
1147
hostapd_dpp_conn_status_result_wait_timeout(void * eloop_ctx,void * timeout_ctx)1148 static void hostapd_dpp_conn_status_result_wait_timeout(void *eloop_ctx,
1149 void *timeout_ctx)
1150 {
1151 struct hostapd_data *hapd = eloop_ctx;
1152 struct dpp_authentication *auth = hapd->dpp_auth;
1153
1154 if (!auth || !auth->waiting_conf_result)
1155 return;
1156
1157 wpa_printf(MSG_DEBUG,
1158 "DPP: Timeout while waiting for Connection Status Result");
1159 wpa_msg(hapd->msg_ctx, MSG_INFO,
1160 DPP_EVENT_CONN_STATUS_RESULT "timeout");
1161 dpp_auth_deinit(auth);
1162 hapd->dpp_auth = NULL;
1163 }
1164
1165
hostapd_dpp_rx_conf_result(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len)1166 static void hostapd_dpp_rx_conf_result(struct hostapd_data *hapd, const u8 *src,
1167 const u8 *hdr, const u8 *buf, size_t len)
1168 {
1169 struct dpp_authentication *auth = hapd->dpp_auth;
1170 enum dpp_status_error status;
1171
1172 wpa_printf(MSG_DEBUG, "DPP: Configuration Result from " MACSTR_SEC,
1173 MAC2STR_SEC(src));
1174
1175 if (!auth || !auth->waiting_conf_result) {
1176 wpa_printf(MSG_DEBUG,
1177 "DPP: No DPP Configuration waiting for result - drop");
1178 return;
1179 }
1180
1181 if (os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
1182 wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
1183 MACSTR_SEC ") - drop", MAC2STR_SEC(auth->peer_mac_addr));
1184 return;
1185 }
1186
1187 status = dpp_conf_result_rx(auth, hdr, buf, len);
1188
1189 if (status == DPP_STATUS_OK && auth->send_conn_status) {
1190 wpa_msg(hapd->msg_ctx, MSG_INFO,
1191 DPP_EVENT_CONF_SENT "wait_conn_status=1");
1192 wpa_printf(MSG_DEBUG, "DPP: Wait for Connection Status Result");
1193 eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout,
1194 hapd, NULL);
1195 auth->waiting_conn_status_result = 1;
1196 eloop_cancel_timeout(
1197 hostapd_dpp_conn_status_result_wait_timeout,
1198 hapd, NULL);
1199 eloop_register_timeout(
1200 16, 0, hostapd_dpp_conn_status_result_wait_timeout,
1201 hapd, NULL);
1202 return;
1203 }
1204 hostapd_drv_send_action_cancel_wait(hapd);
1205 hostapd_dpp_listen_stop(hapd);
1206 if (status == DPP_STATUS_OK)
1207 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_SENT);
1208 else
1209 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
1210 dpp_auth_deinit(auth);
1211 hapd->dpp_auth = NULL;
1212 eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout, hapd,
1213 NULL);
1214 }
1215
1216
hostapd_dpp_rx_conn_status_result(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len)1217 static void hostapd_dpp_rx_conn_status_result(struct hostapd_data *hapd,
1218 const u8 *src, const u8 *hdr,
1219 const u8 *buf, size_t len)
1220 {
1221 struct dpp_authentication *auth = hapd->dpp_auth;
1222 enum dpp_status_error status;
1223 u8 ssid[SSID_MAX_LEN];
1224 size_t ssid_len = 0;
1225 char *channel_list = NULL;
1226
1227 wpa_printf(MSG_DEBUG, "DPP: Connection Status Result");
1228
1229 if (!auth || !auth->waiting_conn_status_result) {
1230 wpa_printf(MSG_DEBUG,
1231 "DPP: No DPP Configuration waiting for connection status result - drop");
1232 return;
1233 }
1234
1235 status = dpp_conn_status_result_rx(auth, hdr, buf, len,
1236 ssid, &ssid_len, &channel_list);
1237 wpa_msg_only_for_cb(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONN_STATUS_RESULT
1238 "result=%d ssid=%s channel_list=%s",
1239 status, wpa_ssid_txt(ssid, ssid_len),
1240 channel_list ? channel_list : "N/A");
1241 wpa_printf(MSG_INFO, DPP_EVENT_CONN_STATUS_RESULT
1242 "result=%d ssid=%s channel_list=%s",
1243 status, anonymize_ssid(wpa_ssid_txt(ssid, ssid_len)),
1244 channel_list ? channel_list : "N/A");
1245 os_free(channel_list);
1246 hostapd_drv_send_action_cancel_wait(hapd);
1247 hostapd_dpp_listen_stop(hapd);
1248 dpp_auth_deinit(auth);
1249 hapd->dpp_auth = NULL;
1250 eloop_cancel_timeout(hostapd_dpp_conn_status_result_wait_timeout,
1251 hapd, NULL);
1252 }
1253
1254
1255 static void
hostapd_dpp_rx_presence_announcement(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)1256 hostapd_dpp_rx_presence_announcement(struct hostapd_data *hapd, const u8 *src,
1257 const u8 *hdr, const u8 *buf, size_t len,
1258 unsigned int freq)
1259 {
1260 const u8 *r_bootstrap;
1261 u16 r_bootstrap_len;
1262 struct dpp_bootstrap_info *peer_bi;
1263 struct dpp_authentication *auth;
1264
1265 wpa_printf(MSG_DEBUG, "DPP: Presence Announcement from " MACSTR_SEC,
1266 MAC2STR_SEC(src));
1267
1268 r_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
1269 &r_bootstrap_len);
1270 if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) {
1271 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1272 "Missing or invalid required Responder Bootstrapping Key Hash attribute");
1273 return;
1274 }
1275 wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash",
1276 r_bootstrap, r_bootstrap_len);
1277 peer_bi = dpp_bootstrap_find_chirp(hapd->iface->interfaces->dpp,
1278 r_bootstrap);
1279 dpp_notify_chirp_received(hapd->msg_ctx,
1280 peer_bi ? (int) peer_bi->id : -1,
1281 src, freq, r_bootstrap);
1282 if (!peer_bi) {
1283 if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
1284 src, hdr, buf, len, freq, NULL,
1285 r_bootstrap, hapd) == 0)
1286 return;
1287 wpa_printf(MSG_DEBUG,
1288 "DPP: No matching bootstrapping information found");
1289 return;
1290 }
1291
1292 if (hapd->dpp_auth) {
1293 wpa_printf(MSG_DEBUG,
1294 "DPP: Ignore Presence Announcement during ongoing Authentication");
1295 return;
1296 }
1297
1298 auth = dpp_auth_init(hapd->iface->interfaces->dpp, hapd->msg_ctx,
1299 peer_bi, NULL, DPP_CAPAB_CONFIGURATOR, freq, NULL,
1300 0);
1301 if (!auth)
1302 return;
1303 hostapd_dpp_set_testing_options(hapd, auth);
1304 if (dpp_set_configurator(auth,
1305 hapd->dpp_configurator_params) < 0) {
1306 dpp_auth_deinit(auth);
1307 return;
1308 }
1309
1310 auth->neg_freq = freq;
1311
1312 /* The source address of the Presence Announcement frame overrides any
1313 * MAC address information from the bootstrapping information. */
1314 os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
1315
1316 hapd->dpp_auth = auth;
1317 if (hostapd_dpp_auth_init_next(hapd) < 0) {
1318 dpp_auth_deinit(hapd->dpp_auth);
1319 hapd->dpp_auth = NULL;
1320 }
1321 }
1322
1323
hostapd_dpp_reconfig_reply_wait_timeout(void * eloop_ctx,void * timeout_ctx)1324 static void hostapd_dpp_reconfig_reply_wait_timeout(void *eloop_ctx,
1325 void *timeout_ctx)
1326 {
1327 struct hostapd_data *hapd = eloop_ctx;
1328 struct dpp_authentication *auth = hapd->dpp_auth;
1329
1330 if (!auth)
1331 return;
1332
1333 wpa_printf(MSG_DEBUG, "DPP: Reconfig Reply wait timeout");
1334 hostapd_dpp_listen_stop(hapd);
1335 dpp_auth_deinit(auth);
1336 hapd->dpp_auth = NULL;
1337 }
1338
1339
1340 static void
hostapd_dpp_rx_reconfig_announcement(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)1341 hostapd_dpp_rx_reconfig_announcement(struct hostapd_data *hapd, const u8 *src,
1342 const u8 *hdr, const u8 *buf, size_t len,
1343 unsigned int freq)
1344 {
1345 const u8 *csign_hash, *fcgroup, *a_nonce, *e_id;
1346 u16 csign_hash_len, fcgroup_len, a_nonce_len, e_id_len;
1347 struct dpp_configurator *conf;
1348 struct dpp_authentication *auth;
1349 unsigned int wait_time, max_wait_time;
1350 u16 group;
1351
1352 if (hapd->dpp_auth) {
1353 wpa_printf(MSG_DEBUG,
1354 "DPP: Ignore Reconfig Announcement during ongoing Authentication");
1355 return;
1356 }
1357
1358 wpa_printf(MSG_DEBUG, "DPP: Reconfig Announcement from " MACSTR_SEC,
1359 MAC2STR_SEC(src));
1360
1361 csign_hash = dpp_get_attr(buf, len, DPP_ATTR_C_SIGN_KEY_HASH,
1362 &csign_hash_len);
1363 if (!csign_hash || csign_hash_len != SHA256_MAC_LEN) {
1364 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1365 "Missing or invalid required Configurator C-sign key Hash attribute");
1366 return;
1367 }
1368 wpa_hexdump(MSG_MSGDUMP, "DPP: Configurator C-sign key Hash (kid)",
1369 csign_hash, csign_hash_len);
1370 conf = dpp_configurator_find_kid(hapd->iface->interfaces->dpp,
1371 csign_hash);
1372 if (!conf) {
1373 if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
1374 src, hdr, buf, len, freq, NULL,
1375 NULL, hapd) == 0)
1376 return;
1377 wpa_printf(MSG_DEBUG,
1378 "DPP: No matching Configurator information found");
1379 return;
1380 }
1381
1382 fcgroup = dpp_get_attr(buf, len, DPP_ATTR_FINITE_CYCLIC_GROUP,
1383 &fcgroup_len);
1384 if (!fcgroup || fcgroup_len != 2) {
1385 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
1386 "Missing or invalid required Finite Cyclic Group attribute");
1387 return;
1388 }
1389 group = WPA_GET_LE16(fcgroup);
1390 wpa_printf(MSG_DEBUG, "DPP: Enrollee finite cyclic group: %u", group);
1391
1392 a_nonce = dpp_get_attr(buf, len, DPP_ATTR_A_NONCE, &a_nonce_len);
1393 e_id = dpp_get_attr(buf, len, DPP_ATTR_E_PRIME_ID, &e_id_len);
1394
1395 auth = dpp_reconfig_init(hapd->iface->interfaces->dpp, hapd->msg_ctx,
1396 conf, freq, group, a_nonce, a_nonce_len,
1397 e_id, e_id_len);
1398 if (!auth)
1399 return;
1400 hostapd_dpp_set_testing_options(hapd, auth);
1401 if (dpp_set_configurator(auth, hapd->dpp_configurator_params) < 0) {
1402 dpp_auth_deinit(auth);
1403 return;
1404 }
1405
1406 os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
1407 hapd->dpp_auth = auth;
1408
1409 hapd->dpp_in_response_listen = 0;
1410 hapd->dpp_auth_ok_on_ack = 0;
1411 wait_time = 2000; /* TODO: hapd->max_remain_on_chan; */
1412 max_wait_time = hapd->dpp_resp_wait_time ?
1413 hapd->dpp_resp_wait_time : 2000;
1414 if (wait_time > max_wait_time)
1415 wait_time = max_wait_time;
1416 wait_time += 10; /* give the driver some extra time to complete */
1417 eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
1418 hostapd_dpp_reconfig_reply_wait_timeout,
1419 hapd, NULL);
1420 wait_time -= 10;
1421
1422 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1423 " freq=%u type=%d",
1424 MAC2STR(src), freq, DPP_PA_RECONFIG_AUTH_REQ);
1425 if (hostapd_drv_send_action(hapd, freq, wait_time, src,
1426 wpabuf_head(auth->reconfig_req_msg),
1427 wpabuf_len(auth->reconfig_req_msg)) < 0) {
1428 dpp_auth_deinit(hapd->dpp_auth);
1429 hapd->dpp_auth = NULL;
1430 }
1431 }
1432
1433
1434 static void
hostapd_dpp_rx_reconfig_auth_resp(struct hostapd_data * hapd,const u8 * src,const u8 * hdr,const u8 * buf,size_t len,unsigned int freq)1435 hostapd_dpp_rx_reconfig_auth_resp(struct hostapd_data *hapd, const u8 *src,
1436 const u8 *hdr, const u8 *buf, size_t len,
1437 unsigned int freq)
1438 {
1439 struct dpp_authentication *auth = hapd->dpp_auth;
1440 struct wpabuf *conf;
1441
1442 wpa_printf(MSG_DEBUG, "DPP: Reconfig Authentication Response from "
1443 MACSTR_SEC, MAC2STR_SEC(src));
1444
1445 if (!auth || !auth->reconfig || !auth->configurator) {
1446 wpa_printf(MSG_DEBUG,
1447 "DPP: No DPP Reconfig Authentication in progress - drop");
1448 return;
1449 }
1450
1451 if (os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
1452 wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
1453 MACSTR_SEC ") - drop", MAC2STR_SEC(auth->peer_mac_addr));
1454 return;
1455 }
1456
1457 conf = dpp_reconfig_auth_resp_rx(auth, hdr, buf, len);
1458 if (!conf)
1459 return;
1460
1461 eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
1462 hapd, NULL);
1463
1464 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1465 " freq=%u type=%d",
1466 MAC2STR(src), freq, DPP_PA_RECONFIG_AUTH_CONF);
1467 if (hostapd_drv_send_action(hapd, freq, 500, src,
1468 wpabuf_head(conf), wpabuf_len(conf)) < 0) {
1469 wpabuf_free(conf);
1470 dpp_auth_deinit(hapd->dpp_auth);
1471 hapd->dpp_auth = NULL;
1472 return;
1473 }
1474 wpabuf_free(conf);
1475 }
1476
1477 #endif /* CONFIG_DPP2 */
1478
1479
hostapd_dpp_send_peer_disc_resp(struct hostapd_data * hapd,const u8 * src,unsigned int freq,u8 trans_id,enum dpp_status_error status)1480 static void hostapd_dpp_send_peer_disc_resp(struct hostapd_data *hapd,
1481 const u8 *src, unsigned int freq,
1482 u8 trans_id,
1483 enum dpp_status_error status)
1484 {
1485 struct wpabuf *msg;
1486 size_t len;
1487
1488 len = 5 + 5 + 4 + os_strlen(hapd->conf->dpp_connector);
1489 #ifdef CONFIG_DPP2
1490 len += 5;
1491 #endif /* CONFIG_DPP2 */
1492 msg = dpp_alloc_msg(DPP_PA_PEER_DISCOVERY_RESP, len);
1493 if (!msg)
1494 return;
1495
1496 #ifdef CONFIG_TESTING_OPTIONS
1497 if (dpp_test == DPP_TEST_NO_TRANSACTION_ID_PEER_DISC_RESP) {
1498 wpa_printf(MSG_INFO, "DPP: TESTING - no Transaction ID");
1499 goto skip_trans_id;
1500 }
1501 if (dpp_test == DPP_TEST_INVALID_TRANSACTION_ID_PEER_DISC_RESP) {
1502 wpa_printf(MSG_INFO, "DPP: TESTING - invalid Transaction ID");
1503 trans_id ^= 0x01;
1504 }
1505 #endif /* CONFIG_TESTING_OPTIONS */
1506
1507 /* Transaction ID */
1508 wpabuf_put_le16(msg, DPP_ATTR_TRANSACTION_ID);
1509 wpabuf_put_le16(msg, 1);
1510 wpabuf_put_u8(msg, trans_id);
1511
1512 #ifdef CONFIG_TESTING_OPTIONS
1513 skip_trans_id:
1514 if (dpp_test == DPP_TEST_NO_STATUS_PEER_DISC_RESP) {
1515 wpa_printf(MSG_INFO, "DPP: TESTING - no Status");
1516 goto skip_status;
1517 }
1518 if (dpp_test == DPP_TEST_INVALID_STATUS_PEER_DISC_RESP) {
1519 wpa_printf(MSG_INFO, "DPP: TESTING - invalid Status");
1520 status = 254;
1521 }
1522 #endif /* CONFIG_TESTING_OPTIONS */
1523
1524 /* DPP Status */
1525 wpabuf_put_le16(msg, DPP_ATTR_STATUS);
1526 wpabuf_put_le16(msg, 1);
1527 wpabuf_put_u8(msg, status);
1528
1529 #ifdef CONFIG_TESTING_OPTIONS
1530 skip_status:
1531 if (dpp_test == DPP_TEST_NO_CONNECTOR_PEER_DISC_RESP) {
1532 wpa_printf(MSG_INFO, "DPP: TESTING - no Connector");
1533 goto skip_connector;
1534 }
1535 if (status == DPP_STATUS_OK &&
1536 dpp_test == DPP_TEST_INVALID_CONNECTOR_PEER_DISC_RESP) {
1537 char *connector;
1538
1539 wpa_printf(MSG_INFO, "DPP: TESTING - invalid Connector");
1540 connector = dpp_corrupt_connector_signature(
1541 hapd->conf->dpp_connector);
1542 if (!connector) {
1543 wpabuf_free(msg);
1544 return;
1545 }
1546 wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
1547 wpabuf_put_le16(msg, os_strlen(connector));
1548 wpabuf_put_str(msg, connector);
1549 os_free(connector);
1550 goto skip_connector;
1551 }
1552 #endif /* CONFIG_TESTING_OPTIONS */
1553
1554 /* DPP Connector */
1555 if (status == DPP_STATUS_OK) {
1556 wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
1557 wpabuf_put_le16(msg, os_strlen(hapd->conf->dpp_connector));
1558 wpabuf_put_str(msg, hapd->conf->dpp_connector);
1559 }
1560
1561 #ifdef CONFIG_TESTING_OPTIONS
1562 skip_connector:
1563 if (dpp_test == DPP_TEST_NO_PROTOCOL_VERSION_PEER_DISC_RESP) {
1564 wpa_printf(MSG_INFO, "DPP: TESTING - no Protocol Version");
1565 goto skip_proto_ver;
1566 }
1567 #endif /* CONFIG_TESTING_OPTIONS */
1568
1569 #ifdef CONFIG_DPP2
1570 if (DPP_VERSION > 1) {
1571 u8 ver = DPP_VERSION;
1572 #ifdef CONFIG_DPP3
1573 int conn_ver;
1574
1575 conn_ver = dpp_get_connector_version(hapd->conf->dpp_connector);
1576 if (conn_ver > 0 && ver != conn_ver) {
1577 wpa_printf(MSG_DEBUG,
1578 "DPP: Use Connector version %d instead of current protocol version %d",
1579 conn_ver, ver);
1580 ver = conn_ver;
1581 }
1582 #endif /* CONFIG_DPP3 */
1583
1584 /* Protocol Version */
1585 wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION);
1586 wpabuf_put_le16(msg, 1);
1587 wpabuf_put_u8(msg, ver);
1588 }
1589 #endif /* CONFIG_DPP2 */
1590
1591 #ifdef CONFIG_TESTING_OPTIONS
1592 skip_proto_ver:
1593 #endif /* CONFIG_TESTING_OPTIONS */
1594
1595 wpa_printf(MSG_DEBUG, "DPP: Send Peer Discovery Response to " MACSTR
1596 " status=%d", MAC2STR(src), status);
1597 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1598 " freq=%u type=%d status=%d", MAC2STR(src), freq,
1599 DPP_PA_PEER_DISCOVERY_RESP, status);
1600 hostapd_drv_send_action(hapd, freq, 0, src,
1601 wpabuf_head(msg), wpabuf_len(msg));
1602 wpabuf_free(msg);
1603 }
1604
1605
hostapd_dpp_rx_peer_disc_req(struct hostapd_data * hapd,const u8 * src,const u8 * buf,size_t len,unsigned int freq)1606 static void hostapd_dpp_rx_peer_disc_req(struct hostapd_data *hapd,
1607 const u8 *src,
1608 const u8 *buf, size_t len,
1609 unsigned int freq)
1610 {
1611 const u8 *connector, *trans_id;
1612 u16 connector_len, trans_id_len;
1613 struct os_time now;
1614 struct dpp_introduction intro;
1615 os_time_t expire;
1616 int expiration;
1617 enum dpp_status_error res;
1618
1619 wpa_printf(MSG_DEBUG, "DPP: Peer Discovery Request from " MACSTR_SEC,
1620 MAC2STR_SEC(src));
1621 if (!hapd->wpa_auth ||
1622 !(hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) ||
1623 !(hapd->conf->wpa & WPA_PROTO_RSN)) {
1624 wpa_printf(MSG_DEBUG, "DPP: DPP AKM not in use");
1625 return;
1626 }
1627
1628 if (!hapd->conf->dpp_connector || !hapd->conf->dpp_netaccesskey ||
1629 !hapd->conf->dpp_csign) {
1630 wpa_printf(MSG_DEBUG, "DPP: No own Connector/keys set");
1631 return;
1632 }
1633
1634 os_get_time(&now);
1635
1636 if (hapd->conf->dpp_netaccesskey_expiry &&
1637 (os_time_t) hapd->conf->dpp_netaccesskey_expiry < now.sec) {
1638 wpa_printf(MSG_INFO, "DPP: Own netAccessKey expired");
1639 return;
1640 }
1641
1642 trans_id = dpp_get_attr(buf, len, DPP_ATTR_TRANSACTION_ID,
1643 &trans_id_len);
1644 if (!trans_id || trans_id_len != 1) {
1645 wpa_printf(MSG_DEBUG,
1646 "DPP: Peer did not include Transaction ID");
1647 return;
1648 }
1649
1650 connector = dpp_get_attr(buf, len, DPP_ATTR_CONNECTOR, &connector_len);
1651 if (!connector) {
1652 wpa_printf(MSG_DEBUG,
1653 "DPP: Peer did not include its Connector");
1654 return;
1655 }
1656
1657 res = dpp_peer_intro(&intro, hapd->conf->dpp_connector,
1658 wpabuf_head(hapd->conf->dpp_netaccesskey),
1659 wpabuf_len(hapd->conf->dpp_netaccesskey),
1660 wpabuf_head(hapd->conf->dpp_csign),
1661 wpabuf_len(hapd->conf->dpp_csign),
1662 connector, connector_len, &expire);
1663 if (res == 255) {
1664 wpa_printf(MSG_INFO,
1665 "DPP: Network Introduction protocol resulted in internal failure (peer "
1666 MACSTR_SEC ")", MAC2STR_SEC(src));
1667 return;
1668 }
1669 if (res != DPP_STATUS_OK) {
1670 wpa_printf(MSG_INFO,
1671 "DPP: Network Introduction protocol resulted in failure (peer "
1672 MACSTR_SEC " status %d)", MAC2STR_SEC(src), res);
1673 hostapd_dpp_send_peer_disc_resp(hapd, src, freq, trans_id[0],
1674 res);
1675 return;
1676 }
1677
1678 #ifdef CONFIG_DPP3
1679 if (intro.peer_version && intro.peer_version >= 2) {
1680 const u8 *version;
1681 u16 version_len;
1682 u8 attr_version = 1;
1683
1684 version = dpp_get_attr(buf, len, DPP_ATTR_PROTOCOL_VERSION,
1685 &version_len);
1686 if (version && version_len >= 1)
1687 attr_version = version[0];
1688 if (attr_version != intro.peer_version) {
1689 wpa_printf(MSG_INFO,
1690 "DPP: Protocol version mismatch (Connector: %d Attribute: %d",
1691 intro.peer_version, attr_version);
1692 hostapd_dpp_send_peer_disc_resp(hapd, src, freq,
1693 trans_id[0],
1694 DPP_STATUS_NO_MATCH);
1695 return;
1696 }
1697 }
1698 #endif /* CONFIG_DPP3 */
1699
1700 if (!expire || (os_time_t) hapd->conf->dpp_netaccesskey_expiry < expire)
1701 expire = hapd->conf->dpp_netaccesskey_expiry;
1702 if (expire)
1703 expiration = expire - now.sec;
1704 else
1705 expiration = 0;
1706
1707 if (wpa_auth_pmksa_add2(hapd->wpa_auth, src, intro.pmk, intro.pmk_len,
1708 intro.pmkid, expiration,
1709 WPA_KEY_MGMT_DPP) < 0) {
1710 wpa_printf(MSG_ERROR, "DPP: Failed to add PMKSA cache entry");
1711 return;
1712 }
1713
1714 hostapd_dpp_send_peer_disc_resp(hapd, src, freq, trans_id[0],
1715 DPP_STATUS_OK);
1716 }
1717
1718
1719 static void
hostapd_dpp_rx_pkex_exchange_req(struct hostapd_data * hapd,const u8 * src,const u8 * buf,size_t len,unsigned int freq,bool v2)1720 hostapd_dpp_rx_pkex_exchange_req(struct hostapd_data *hapd, const u8 *src,
1721 const u8 *buf, size_t len,
1722 unsigned int freq, bool v2)
1723 {
1724 struct wpabuf *msg;
1725
1726 wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Request from " MACSTR_SEC,
1727 MAC2STR_SEC(src));
1728
1729 /* TODO: Support multiple PKEX codes by iterating over all the enabled
1730 * values here */
1731
1732 if (!hapd->dpp_pkex_code || !hapd->dpp_pkex_bi) {
1733 wpa_printf(MSG_DEBUG,
1734 "DPP: No PKEX code configured - ignore request");
1735 return;
1736 }
1737
1738 if (hapd->dpp_pkex) {
1739 /* TODO: Support parallel operations */
1740 wpa_printf(MSG_DEBUG,
1741 "DPP: Already in PKEX session - ignore new request");
1742 return;
1743 }
1744
1745 hapd->dpp_pkex = dpp_pkex_rx_exchange_req(hapd->msg_ctx,
1746 hapd->dpp_pkex_bi,
1747 hapd->own_addr, src,
1748 hapd->dpp_pkex_identifier,
1749 hapd->dpp_pkex_code,
1750 buf, len, v2);
1751 if (!hapd->dpp_pkex) {
1752 wpa_printf(MSG_DEBUG,
1753 "DPP: Failed to process the request - ignore it");
1754 return;
1755 }
1756
1757 msg = hapd->dpp_pkex->exchange_resp;
1758 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1759 " freq=%u type=%d", MAC2STR(src), freq,
1760 DPP_PA_PKEX_EXCHANGE_RESP);
1761 hostapd_drv_send_action(hapd, freq, 0, src,
1762 wpabuf_head(msg), wpabuf_len(msg));
1763 if (hapd->dpp_pkex->failed) {
1764 wpa_printf(MSG_DEBUG,
1765 "DPP: Terminate PKEX exchange due to an earlier error");
1766 if (hapd->dpp_pkex->t > hapd->dpp_pkex->own_bi->pkex_t)
1767 hapd->dpp_pkex->own_bi->pkex_t = hapd->dpp_pkex->t;
1768 dpp_pkex_free(hapd->dpp_pkex);
1769 hapd->dpp_pkex = NULL;
1770 }
1771 }
1772
1773
1774 static void
hostapd_dpp_rx_pkex_exchange_resp(struct hostapd_data * hapd,const u8 * src,const u8 * buf,size_t len,unsigned int freq)1775 hostapd_dpp_rx_pkex_exchange_resp(struct hostapd_data *hapd, const u8 *src,
1776 const u8 *buf, size_t len, unsigned int freq)
1777 {
1778 struct wpabuf *msg;
1779
1780 wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Response from " MACSTR_SEC,
1781 MAC2STR_SEC(src));
1782
1783 /* TODO: Support multiple PKEX codes by iterating over all the enabled
1784 * values here */
1785
1786 if (!hapd->dpp_pkex || !hapd->dpp_pkex->initiator ||
1787 hapd->dpp_pkex->exchange_done) {
1788 wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
1789 return;
1790 }
1791
1792 msg = dpp_pkex_rx_exchange_resp(hapd->dpp_pkex, src, buf, len);
1793 if (!msg) {
1794 wpa_printf(MSG_DEBUG, "DPP: Failed to process the response");
1795 return;
1796 }
1797
1798 wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Request to " MACSTR_SEC,
1799 MAC2STR_SEC(src));
1800
1801 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1802 " freq=%u type=%d", MAC2STR(src), freq,
1803 DPP_PA_PKEX_COMMIT_REVEAL_REQ);
1804 hostapd_drv_send_action(hapd, freq, 0, src,
1805 wpabuf_head(msg), wpabuf_len(msg));
1806 wpabuf_free(msg);
1807 }
1808
1809
1810 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)1811 hostapd_dpp_rx_pkex_commit_reveal_req(struct hostapd_data *hapd, const u8 *src,
1812 const u8 *hdr, const u8 *buf, size_t len,
1813 unsigned int freq)
1814 {
1815 struct wpabuf *msg;
1816 struct dpp_pkex *pkex = hapd->dpp_pkex;
1817 struct dpp_bootstrap_info *bi;
1818
1819 wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Request from " MACSTR_SEC,
1820 MAC2STR_SEC(src));
1821
1822 if (!pkex || pkex->initiator || !pkex->exchange_done) {
1823 wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
1824 return;
1825 }
1826
1827 msg = dpp_pkex_rx_commit_reveal_req(pkex, hdr, buf, len);
1828 if (!msg) {
1829 wpa_printf(MSG_DEBUG, "DPP: Failed to process the request");
1830 if (hapd->dpp_pkex->failed) {
1831 wpa_printf(MSG_DEBUG, "DPP: Terminate PKEX exchange");
1832 if (hapd->dpp_pkex->t > hapd->dpp_pkex->own_bi->pkex_t)
1833 hapd->dpp_pkex->own_bi->pkex_t =
1834 hapd->dpp_pkex->t;
1835 dpp_pkex_free(hapd->dpp_pkex);
1836 hapd->dpp_pkex = NULL;
1837 }
1838 return;
1839 }
1840
1841 wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Response to "
1842 MACSTR_SEC, MAC2STR_SEC(src));
1843
1844 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1845 " freq=%u type=%d", MAC2STR(src), freq,
1846 DPP_PA_PKEX_COMMIT_REVEAL_RESP);
1847 hostapd_drv_send_action(hapd, freq, 0, src,
1848 wpabuf_head(msg), wpabuf_len(msg));
1849 wpabuf_free(msg);
1850
1851 bi = dpp_pkex_finish(hapd->iface->interfaces->dpp, pkex, src, freq);
1852 if (!bi)
1853 return;
1854 hapd->dpp_pkex = NULL;
1855 }
1856
1857
1858 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)1859 hostapd_dpp_rx_pkex_commit_reveal_resp(struct hostapd_data *hapd, const u8 *src,
1860 const u8 *hdr, const u8 *buf, size_t len,
1861 unsigned int freq)
1862 {
1863 int res;
1864 struct dpp_bootstrap_info *bi;
1865 struct dpp_pkex *pkex = hapd->dpp_pkex;
1866 char cmd[500];
1867
1868 wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Response from " MACSTR_SEC,
1869 MAC2STR_SEC(src));
1870
1871 if (!pkex || !pkex->initiator || !pkex->exchange_done) {
1872 wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
1873 return;
1874 }
1875
1876 res = dpp_pkex_rx_commit_reveal_resp(pkex, hdr, buf, len);
1877 if (res < 0) {
1878 wpa_printf(MSG_DEBUG, "DPP: Failed to process the response");
1879 return;
1880 }
1881
1882 bi = dpp_pkex_finish(hapd->iface->interfaces->dpp, pkex, src, freq);
1883 if (!bi)
1884 return;
1885 hapd->dpp_pkex = NULL;
1886
1887 os_snprintf(cmd, sizeof(cmd), " peer=%u %s",
1888 bi->id,
1889 hapd->dpp_pkex_auth_cmd ? hapd->dpp_pkex_auth_cmd : "");
1890 wpa_printf(MSG_DEBUG,
1891 "DPP: Start authentication after PKEX with parameters: %s",
1892 cmd);
1893 if (hostapd_dpp_auth_init(hapd, cmd) < 0) {
1894 wpa_printf(MSG_DEBUG,
1895 "DPP: Authentication initialization failed");
1896 return;
1897 }
1898 }
1899
1900
hostapd_dpp_rx_action(struct hostapd_data * hapd,const u8 * src,const u8 * buf,size_t len,unsigned int freq)1901 void hostapd_dpp_rx_action(struct hostapd_data *hapd, const u8 *src,
1902 const u8 *buf, size_t len, unsigned int freq)
1903 {
1904 u8 crypto_suite;
1905 enum dpp_public_action_frame_type type;
1906 const u8 *hdr;
1907 unsigned int pkex_t;
1908
1909 if (len < DPP_HDR_LEN)
1910 return;
1911 if (WPA_GET_BE24(buf) != OUI_WFA || buf[3] != DPP_OUI_TYPE)
1912 return;
1913 hdr = buf;
1914 buf += 4;
1915 len -= 4;
1916 crypto_suite = *buf++;
1917 type = *buf++;
1918 len -= 2;
1919
1920 wpa_printf(MSG_DEBUG,
1921 "DPP: Received DPP Public Action frame crypto suite %u type %d from "
1922 MACSTR_SEC " freq=%u",
1923 crypto_suite, type, MAC2STR_SEC(src), freq);
1924 if (crypto_suite != 1) {
1925 wpa_printf(MSG_DEBUG, "DPP: Unsupported crypto suite %u",
1926 crypto_suite);
1927 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
1928 " freq=%u type=%d ignore=unsupported-crypto-suite",
1929 MAC2STR(src), freq, type);
1930 return;
1931 }
1932 wpa_hexdump(MSG_MSGDUMP, "DPP: Received message attributes", buf, len);
1933 if (dpp_check_attrs(buf, len) < 0) {
1934 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
1935 " freq=%u type=%d ignore=invalid-attributes",
1936 MAC2STR(src), freq, type);
1937 return;
1938 }
1939 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
1940 " freq=%u type=%d", MAC2STR(src), freq, type);
1941
1942 #ifdef CONFIG_DPP2
1943 if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
1944 src, hdr, buf, len, freq, NULL, NULL,
1945 hapd) == 0)
1946 return;
1947 #endif /* CONFIG_DPP2 */
1948
1949 switch (type) {
1950 case DPP_PA_AUTHENTICATION_REQ:
1951 hostapd_dpp_rx_auth_req(hapd, src, hdr, buf, len, freq);
1952 break;
1953 case DPP_PA_AUTHENTICATION_RESP:
1954 hostapd_dpp_rx_auth_resp(hapd, src, hdr, buf, len, freq);
1955 break;
1956 case DPP_PA_AUTHENTICATION_CONF:
1957 hostapd_dpp_rx_auth_conf(hapd, src, hdr, buf, len);
1958 break;
1959 case DPP_PA_PEER_DISCOVERY_REQ:
1960 hostapd_dpp_rx_peer_disc_req(hapd, src, buf, len, freq);
1961 break;
1962 #ifdef CONFIG_DPP3
1963 case DPP_PA_PKEX_EXCHANGE_REQ:
1964 /* This is for PKEXv2, but for now, process only with
1965 * CONFIG_DPP3 to avoid issues with a capability that has not
1966 * been tested with other implementations. */
1967 hostapd_dpp_rx_pkex_exchange_req(hapd, src, buf, len, freq,
1968 true);
1969 break;
1970 #endif /* CONFIG_DPP3 */
1971 case DPP_PA_PKEX_V1_EXCHANGE_REQ:
1972 hostapd_dpp_rx_pkex_exchange_req(hapd, src, buf, len, freq,
1973 false);
1974 break;
1975 case DPP_PA_PKEX_EXCHANGE_RESP:
1976 hostapd_dpp_rx_pkex_exchange_resp(hapd, src, buf, len, freq);
1977 break;
1978 case DPP_PA_PKEX_COMMIT_REVEAL_REQ:
1979 hostapd_dpp_rx_pkex_commit_reveal_req(hapd, src, hdr, buf, len,
1980 freq);
1981 break;
1982 case DPP_PA_PKEX_COMMIT_REVEAL_RESP:
1983 hostapd_dpp_rx_pkex_commit_reveal_resp(hapd, src, hdr, buf, len,
1984 freq);
1985 break;
1986 #ifdef CONFIG_DPP2
1987 case DPP_PA_CONFIGURATION_RESULT:
1988 hostapd_dpp_rx_conf_result(hapd, src, hdr, buf, len);
1989 break;
1990 case DPP_PA_CONNECTION_STATUS_RESULT:
1991 hostapd_dpp_rx_conn_status_result(hapd, src, hdr, buf, len);
1992 break;
1993 case DPP_PA_PRESENCE_ANNOUNCEMENT:
1994 hostapd_dpp_rx_presence_announcement(hapd, src, hdr, buf, len,
1995 freq);
1996 break;
1997 case DPP_PA_RECONFIG_ANNOUNCEMENT:
1998 hostapd_dpp_rx_reconfig_announcement(hapd, src, hdr, buf, len,
1999 freq);
2000 break;
2001 case DPP_PA_RECONFIG_AUTH_RESP:
2002 hostapd_dpp_rx_reconfig_auth_resp(hapd, src, hdr, buf, len,
2003 freq);
2004 break;
2005 #endif /* CONFIG_DPP2 */
2006 default:
2007 wpa_printf(MSG_DEBUG,
2008 "DPP: Ignored unsupported frame subtype %d", type);
2009 break;
2010 }
2011
2012 if (hapd->dpp_pkex)
2013 pkex_t = hapd->dpp_pkex->t;
2014 else if (hapd->dpp_pkex_bi)
2015 pkex_t = hapd->dpp_pkex_bi->pkex_t;
2016 else
2017 pkex_t = 0;
2018 if (pkex_t >= PKEX_COUNTER_T_LIMIT) {
2019 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PKEX_T_LIMIT "id=0");
2020 hostapd_dpp_pkex_remove(hapd, "*");
2021 }
2022 }
2023
2024
2025 struct wpabuf *
hostapd_dpp_gas_req_handler(struct hostapd_data * hapd,const u8 * sa,const u8 * query,size_t query_len,const u8 * data,size_t data_len)2026 hostapd_dpp_gas_req_handler(struct hostapd_data *hapd, const u8 *sa,
2027 const u8 *query, size_t query_len,
2028 const u8 *data, size_t data_len)
2029 {
2030 struct dpp_authentication *auth = hapd->dpp_auth;
2031 struct wpabuf *resp;
2032
2033 wpa_printf(MSG_DEBUG, "DPP: GAS request from " MACSTR_SEC, MAC2STR_SEC(sa));
2034 if (!auth || (!auth->auth_success && !auth->reconfig_success) ||
2035 os_memcmp(sa, auth->peer_mac_addr, ETH_ALEN) != 0) {
2036 #ifdef CONFIG_DPP2
2037 if (dpp_relay_rx_gas_req(hapd->iface->interfaces->dpp, sa, data,
2038 data_len) == 0) {
2039 /* Response will be forwarded once received over TCP */
2040 return NULL;
2041 }
2042 #endif /* CONFIG_DPP2 */
2043 wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
2044 return NULL;
2045 }
2046
2047 if (hapd->dpp_auth_ok_on_ack && auth->configurator) {
2048 wpa_printf(MSG_DEBUG,
2049 "DPP: Have not received ACK for Auth Confirm yet - assume it was received based on this GAS request");
2050 /* hostapd_dpp_auth_success() would normally have been called
2051 * from TX status handler, but since there was no such handler
2052 * call yet, simply send out the event message and proceed with
2053 * exchange. */
2054 wpa_msg(hapd->msg_ctx, MSG_INFO,
2055 DPP_EVENT_AUTH_SUCCESS "init=1");
2056 hapd->dpp_auth_ok_on_ack = 0;
2057 }
2058
2059 wpa_hexdump(MSG_DEBUG,
2060 "DPP: Received Configuration Request (GAS Query Request)",
2061 query, query_len);
2062 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_REQ_RX "src=" MACSTR,
2063 MAC2STR(sa));
2064 resp = dpp_conf_req_rx(auth, query, query_len);
2065 if (!resp)
2066 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
2067 return resp;
2068 }
2069
2070
hostapd_dpp_gas_status_handler(struct hostapd_data * hapd,int ok)2071 void hostapd_dpp_gas_status_handler(struct hostapd_data *hapd, int ok)
2072 {
2073 struct dpp_authentication *auth = hapd->dpp_auth;
2074
2075 if (!auth)
2076 return;
2077
2078 wpa_printf(MSG_DEBUG, "DPP: Configuration exchange completed (ok=%d)",
2079 ok);
2080 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
2081 eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout, hapd, NULL);
2082 eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
2083 #ifdef CONFIG_DPP2
2084 eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
2085 hapd, NULL);
2086 if (ok && auth->peer_version >= 2 &&
2087 auth->conf_resp_status == DPP_STATUS_OK) {
2088 wpa_printf(MSG_DEBUG, "DPP: Wait for Configuration Result");
2089 auth->waiting_conf_result = 1;
2090 eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout,
2091 hapd, NULL);
2092 eloop_register_timeout(2, 0,
2093 hostapd_dpp_config_result_wait_timeout,
2094 hapd, NULL);
2095 return;
2096 }
2097 #endif /* CONFIG_DPP2 */
2098 hostapd_drv_send_action_cancel_wait(hapd);
2099
2100 if (ok)
2101 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_SENT);
2102 else
2103 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
2104 dpp_auth_deinit(hapd->dpp_auth);
2105 hapd->dpp_auth = NULL;
2106 }
2107
2108
hostapd_dpp_configurator_sign(struct hostapd_data * hapd,const char * cmd)2109 int hostapd_dpp_configurator_sign(struct hostapd_data *hapd, const char *cmd)
2110 {
2111 struct dpp_authentication *auth;
2112 int ret = -1;
2113 char *curve = NULL;
2114
2115 auth = dpp_alloc_auth(hapd->iface->interfaces->dpp, hapd->msg_ctx);
2116 if (!auth)
2117 return -1;
2118
2119 curve = get_param(cmd, " curve=");
2120 hostapd_dpp_set_testing_options(hapd, auth);
2121 if (dpp_set_configurator(auth, cmd) == 0 &&
2122 dpp_configurator_own_config(auth, curve, 1) == 0) {
2123 hostapd_dpp_handle_config_obj(hapd, auth, &auth->conf_obj[0]);
2124 ret = 0;
2125 }
2126
2127 dpp_auth_deinit(auth);
2128 os_free(curve);
2129
2130 return ret;
2131 }
2132
2133
hostapd_dpp_pkex_add(struct hostapd_data * hapd,const char * cmd)2134 int hostapd_dpp_pkex_add(struct hostapd_data *hapd, const char *cmd)
2135 {
2136 struct dpp_bootstrap_info *own_bi;
2137 const char *pos, *end;
2138
2139 pos = os_strstr(cmd, " own=");
2140 if (!pos)
2141 return -1;
2142 pos += 5;
2143 own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
2144 if (!own_bi) {
2145 wpa_printf(MSG_DEBUG,
2146 "DPP: Identified bootstrap info not found");
2147 return -1;
2148 }
2149 if (own_bi->type != DPP_BOOTSTRAP_PKEX) {
2150 wpa_printf(MSG_DEBUG,
2151 "DPP: Identified bootstrap info not for PKEX");
2152 return -1;
2153 }
2154 hapd->dpp_pkex_bi = own_bi;
2155 own_bi->pkex_t = 0; /* clear pending errors on new code */
2156
2157 os_free(hapd->dpp_pkex_identifier);
2158 hapd->dpp_pkex_identifier = NULL;
2159 pos = os_strstr(cmd, " identifier=");
2160 if (pos) {
2161 pos += 12;
2162 end = os_strchr(pos, ' ');
2163 if (!end)
2164 return -1;
2165 hapd->dpp_pkex_identifier = os_malloc(end - pos + 1);
2166 if (!hapd->dpp_pkex_identifier)
2167 return -1;
2168 os_memcpy(hapd->dpp_pkex_identifier, pos, end - pos);
2169 hapd->dpp_pkex_identifier[end - pos] = '\0';
2170 }
2171
2172 pos = os_strstr(cmd, " code=");
2173 if (!pos)
2174 return -1;
2175 os_free(hapd->dpp_pkex_code);
2176 hapd->dpp_pkex_code = os_strdup(pos + 6);
2177 if (!hapd->dpp_pkex_code)
2178 return -1;
2179
2180 if (os_strstr(cmd, " init=1") || os_strstr(cmd, " init=2")) {
2181 struct wpabuf *msg;
2182 bool v2 = os_strstr(cmd, " init=2") != NULL;
2183
2184 wpa_printf(MSG_DEBUG, "DPP: Initiating PKEX");
2185 dpp_pkex_free(hapd->dpp_pkex);
2186 hapd->dpp_pkex = dpp_pkex_init(hapd->msg_ctx, own_bi,
2187 hapd->own_addr,
2188 hapd->dpp_pkex_identifier,
2189 hapd->dpp_pkex_code, v2);
2190 if (!hapd->dpp_pkex)
2191 return -1;
2192
2193 msg = hapd->dpp_pkex->exchange_req;
2194 /* TODO: Which channel to use? */
2195 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2196 " freq=%u type=%d", MAC2STR(broadcast), 2437,
2197 v2 ? DPP_PA_PKEX_EXCHANGE_REQ :
2198 DPP_PA_PKEX_V1_EXCHANGE_REQ);
2199 hostapd_drv_send_action(hapd, 2437, 0, broadcast,
2200 wpabuf_head(msg), wpabuf_len(msg));
2201 }
2202
2203 /* TODO: Support multiple PKEX info entries */
2204
2205 os_free(hapd->dpp_pkex_auth_cmd);
2206 hapd->dpp_pkex_auth_cmd = os_strdup(cmd);
2207
2208 return 1;
2209 }
2210
2211
hostapd_dpp_pkex_remove(struct hostapd_data * hapd,const char * id)2212 int hostapd_dpp_pkex_remove(struct hostapd_data *hapd, const char *id)
2213 {
2214 unsigned int id_val;
2215
2216 if (os_strcmp(id, "*") == 0) {
2217 id_val = 0;
2218 } else {
2219 id_val = atoi(id);
2220 if (id_val == 0)
2221 return -1;
2222 }
2223
2224 if ((id_val != 0 && id_val != 1) || !hapd->dpp_pkex_code)
2225 return -1;
2226
2227 /* TODO: Support multiple PKEX entries */
2228 os_free(hapd->dpp_pkex_code);
2229 hapd->dpp_pkex_code = NULL;
2230 os_free(hapd->dpp_pkex_identifier);
2231 hapd->dpp_pkex_identifier = NULL;
2232 os_free(hapd->dpp_pkex_auth_cmd);
2233 hapd->dpp_pkex_auth_cmd = NULL;
2234 hapd->dpp_pkex_bi = NULL;
2235 /* TODO: Remove dpp_pkex only if it is for the identified PKEX code */
2236 dpp_pkex_free(hapd->dpp_pkex);
2237 hapd->dpp_pkex = NULL;
2238 return 0;
2239 }
2240
2241
hostapd_dpp_stop(struct hostapd_data * hapd)2242 void hostapd_dpp_stop(struct hostapd_data *hapd)
2243 {
2244 dpp_auth_deinit(hapd->dpp_auth);
2245 hapd->dpp_auth = NULL;
2246 dpp_pkex_free(hapd->dpp_pkex);
2247 hapd->dpp_pkex = NULL;
2248 }
2249
2250
2251 #ifdef CONFIG_DPP2
2252
hostapd_dpp_relay_tx(void * ctx,const u8 * addr,unsigned int freq,const u8 * msg,size_t len)2253 static void hostapd_dpp_relay_tx(void *ctx, const u8 *addr, unsigned int freq,
2254 const u8 *msg, size_t len)
2255 {
2256 struct hostapd_data *hapd = ctx;
2257 u8 *buf;
2258
2259 wpa_printf(MSG_DEBUG, "DPP: Send action frame dst=" MACSTR_SEC " freq=%u",
2260 MAC2STR_SEC(addr), freq);
2261 buf = os_malloc(2 + len);
2262 if (!buf)
2263 return;
2264 buf[0] = WLAN_ACTION_PUBLIC;
2265 buf[1] = WLAN_PA_VENDOR_SPECIFIC;
2266 os_memcpy(buf + 2, msg, len);
2267 hostapd_drv_send_action(hapd, freq, 0, addr, buf, 2 + len);
2268 os_free(buf);
2269 }
2270
2271
hostapd_dpp_relay_gas_resp_tx(void * ctx,const u8 * addr,u8 dialog_token,int prot,struct wpabuf * buf)2272 static void hostapd_dpp_relay_gas_resp_tx(void *ctx, const u8 *addr,
2273 u8 dialog_token, int prot,
2274 struct wpabuf *buf)
2275 {
2276 struct hostapd_data *hapd = ctx;
2277
2278 gas_serv_req_dpp_processing(hapd, addr, dialog_token, prot, buf);
2279 }
2280
2281 #endif /* CONFIG_DPP2 */
2282
2283
hostapd_dpp_add_controllers(struct hostapd_data * hapd)2284 static int hostapd_dpp_add_controllers(struct hostapd_data *hapd)
2285 {
2286 #ifdef CONFIG_DPP2
2287 struct dpp_controller_conf *ctrl;
2288 struct dpp_relay_config config;
2289
2290 os_memset(&config, 0, sizeof(config));
2291 config.cb_ctx = hapd;
2292 config.tx = hostapd_dpp_relay_tx;
2293 config.gas_resp_tx = hostapd_dpp_relay_gas_resp_tx;
2294 for (ctrl = hapd->conf->dpp_controller; ctrl; ctrl = ctrl->next) {
2295 config.ipaddr = &ctrl->ipaddr;
2296 config.pkhash = ctrl->pkhash;
2297 if (dpp_relay_add_controller(hapd->iface->interfaces->dpp,
2298 &config) < 0)
2299 return -1;
2300 }
2301 #endif /* CONFIG_DPP2 */
2302
2303 return 0;
2304 }
2305
2306
hostapd_dpp_init(struct hostapd_data * hapd)2307 int hostapd_dpp_init(struct hostapd_data *hapd)
2308 {
2309 hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE;
2310 hapd->dpp_init_done = 1;
2311 return hostapd_dpp_add_controllers(hapd);
2312 }
2313
2314
hostapd_dpp_deinit(struct hostapd_data * hapd)2315 void hostapd_dpp_deinit(struct hostapd_data *hapd)
2316 {
2317 #ifdef CONFIG_TESTING_OPTIONS
2318 os_free(hapd->dpp_config_obj_override);
2319 hapd->dpp_config_obj_override = NULL;
2320 os_free(hapd->dpp_discovery_override);
2321 hapd->dpp_discovery_override = NULL;
2322 os_free(hapd->dpp_groups_override);
2323 hapd->dpp_groups_override = NULL;
2324 hapd->dpp_ignore_netaccesskey_mismatch = 0;
2325 #endif /* CONFIG_TESTING_OPTIONS */
2326 if (!hapd->dpp_init_done)
2327 return;
2328 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
2329 eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout, hapd, NULL);
2330 eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
2331 eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
2332 #ifdef CONFIG_DPP2
2333 eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
2334 hapd, NULL);
2335 eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout, hapd,
2336 NULL);
2337 eloop_cancel_timeout(hostapd_dpp_conn_status_result_wait_timeout, hapd,
2338 NULL);
2339 hostapd_dpp_chirp_stop(hapd);
2340 if (hapd->iface->interfaces)
2341 dpp_controller_stop_for_ctx(hapd->iface->interfaces->dpp, hapd);
2342 #endif /* CONFIG_DPP2 */
2343 dpp_auth_deinit(hapd->dpp_auth);
2344 hapd->dpp_auth = NULL;
2345 hostapd_dpp_pkex_remove(hapd, "*");
2346 hapd->dpp_pkex = NULL;
2347 os_free(hapd->dpp_configurator_params);
2348 hapd->dpp_configurator_params = NULL;
2349 }
2350
2351
2352 #ifdef CONFIG_DPP2
2353
hostapd_dpp_controller_start(struct hostapd_data * hapd,const char * cmd)2354 int hostapd_dpp_controller_start(struct hostapd_data *hapd, const char *cmd)
2355 {
2356 struct dpp_controller_config config;
2357 const char *pos;
2358
2359 os_memset(&config, 0, sizeof(config));
2360 config.allowed_roles = DPP_CAPAB_ENROLLEE | DPP_CAPAB_CONFIGURATOR;
2361 config.netrole = DPP_NETROLE_AP;
2362 config.msg_ctx = hapd->msg_ctx;
2363 config.cb_ctx = hapd;
2364 config.process_conf_obj = hostapd_dpp_process_conf_obj;
2365 if (cmd) {
2366 pos = os_strstr(cmd, " tcp_port=");
2367 if (pos) {
2368 pos += 10;
2369 config.tcp_port = atoi(pos);
2370 }
2371
2372 pos = os_strstr(cmd, " role=");
2373 if (pos) {
2374 pos += 6;
2375 if (os_strncmp(pos, "configurator", 12) == 0)
2376 config.allowed_roles = DPP_CAPAB_CONFIGURATOR;
2377 else if (os_strncmp(pos, "enrollee", 8) == 0)
2378 config.allowed_roles = DPP_CAPAB_ENROLLEE;
2379 else if (os_strncmp(pos, "either", 6) == 0)
2380 config.allowed_roles = DPP_CAPAB_CONFIGURATOR |
2381 DPP_CAPAB_ENROLLEE;
2382 else
2383 return -1;
2384 }
2385
2386 config.qr_mutual = os_strstr(cmd, " qr=mutual") != NULL;
2387 }
2388 config.configurator_params = hapd->dpp_configurator_params;
2389 return dpp_controller_start(hapd->iface->interfaces->dpp, &config);
2390 }
2391
2392
2393 static void hostapd_dpp_chirp_next(void *eloop_ctx, void *timeout_ctx);
2394
hostapd_dpp_chirp_timeout(void * eloop_ctx,void * timeout_ctx)2395 static void hostapd_dpp_chirp_timeout(void *eloop_ctx, void *timeout_ctx)
2396 {
2397 struct hostapd_data *hapd = eloop_ctx;
2398
2399 wpa_printf(MSG_DEBUG, "DPP: No chirp response received");
2400 hostapd_drv_send_action_cancel_wait(hapd);
2401 hostapd_dpp_chirp_next(hapd, NULL);
2402 }
2403
2404
hostapd_dpp_chirp_start(struct hostapd_data * hapd)2405 static void hostapd_dpp_chirp_start(struct hostapd_data *hapd)
2406 {
2407 struct wpabuf *msg;
2408 int type;
2409
2410 msg = hapd->dpp_presence_announcement;
2411 type = DPP_PA_PRESENCE_ANNOUNCEMENT;
2412 wpa_printf(MSG_DEBUG, "DPP: Chirp on %d MHz", hapd->dpp_chirp_freq);
2413 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
2414 " freq=%u type=%d",
2415 MAC2STR(broadcast), hapd->dpp_chirp_freq, type);
2416 if (hostapd_drv_send_action(
2417 hapd, hapd->dpp_chirp_freq, 2000, broadcast,
2418 wpabuf_head(msg), wpabuf_len(msg)) < 0 ||
2419 eloop_register_timeout(2, 0, hostapd_dpp_chirp_timeout,
2420 hapd, NULL) < 0)
2421 hostapd_dpp_chirp_stop(hapd);
2422 }
2423
2424
2425 static struct hostapd_hw_modes *
dpp_get_mode(struct hostapd_data * hapd,enum hostapd_hw_mode mode)2426 dpp_get_mode(struct hostapd_data *hapd,
2427 enum hostapd_hw_mode mode)
2428 {
2429 struct hostapd_hw_modes *modes = hapd->iface->hw_features;
2430 u16 num_modes = hapd->iface->num_hw_features;
2431 u16 i;
2432
2433 for (i = 0; i < num_modes; i++) {
2434 if (modes[i].mode != mode ||
2435 !modes[i].num_channels || !modes[i].channels)
2436 continue;
2437 return &modes[i];
2438 }
2439
2440 return NULL;
2441 }
2442
2443
2444 static void
hostapd_dpp_chirp_scan_res_handler(struct hostapd_iface * iface)2445 hostapd_dpp_chirp_scan_res_handler(struct hostapd_iface *iface)
2446 {
2447 struct hostapd_data *hapd = iface->bss[0];
2448 struct wpa_scan_results *scan_res;
2449 struct dpp_bootstrap_info *bi = hapd->dpp_chirp_bi;
2450 unsigned int i;
2451 struct hostapd_hw_modes *mode;
2452 int c;
2453 bool chan6 = hapd->iface->hw_features == NULL;
2454
2455 if (!bi)
2456 return;
2457
2458 hapd->dpp_chirp_scan_done = 1;
2459
2460 scan_res = hostapd_driver_get_scan_results(hapd);
2461
2462 os_free(hapd->dpp_chirp_freqs);
2463 hapd->dpp_chirp_freqs = NULL;
2464
2465 /* Channels from own bootstrapping info */
2466 if (bi) {
2467 for (i = 0; i < bi->num_freq; i++)
2468 int_array_add_unique(&hapd->dpp_chirp_freqs,
2469 bi->freq[i]);
2470 }
2471
2472 /* Preferred chirping channels */
2473 mode = dpp_get_mode(hapd, HOSTAPD_MODE_IEEE80211G);
2474 if (mode) {
2475 for (c = 0; c < mode->num_channels; c++) {
2476 struct hostapd_channel_data *chan = &mode->channels[c];
2477
2478 if (chan->flag & (HOSTAPD_CHAN_DISABLED |
2479 HOSTAPD_CHAN_RADAR) ||
2480 chan->freq != 2437)
2481 continue;
2482 chan6 = true;
2483 break;
2484 }
2485 }
2486 if (chan6)
2487 int_array_add_unique(&hapd->dpp_chirp_freqs, 2437);
2488
2489 mode = dpp_get_mode(hapd, HOSTAPD_MODE_IEEE80211A);
2490 if (mode) {
2491 int chan44 = 0, chan149 = 0;
2492
2493 for (c = 0; c < mode->num_channels; c++) {
2494 struct hostapd_channel_data *chan = &mode->channels[c];
2495
2496 if (chan->flag & (HOSTAPD_CHAN_DISABLED |
2497 HOSTAPD_CHAN_RADAR))
2498 continue;
2499 if (chan->freq == 5220)
2500 chan44 = 1;
2501 if (chan->freq == 5745)
2502 chan149 = 1;
2503 }
2504 if (chan149)
2505 int_array_add_unique(&hapd->dpp_chirp_freqs, 5745);
2506 else if (chan44)
2507 int_array_add_unique(&hapd->dpp_chirp_freqs, 5220);
2508 }
2509
2510 mode = dpp_get_mode(hapd, HOSTAPD_MODE_IEEE80211AD);
2511 if (mode) {
2512 for (c = 0; c < mode->num_channels; c++) {
2513 struct hostapd_channel_data *chan = &mode->channels[c];
2514
2515 if ((chan->flag & (HOSTAPD_CHAN_DISABLED |
2516 HOSTAPD_CHAN_RADAR)) ||
2517 chan->freq != 60480)
2518 continue;
2519 int_array_add_unique(&hapd->dpp_chirp_freqs, 60480);
2520 break;
2521 }
2522 }
2523
2524 /* Add channels from scan results for APs that advertise Configurator
2525 * Connectivity element */
2526 for (i = 0; scan_res && i < scan_res->num; i++) {
2527 struct wpa_scan_res *bss = scan_res->res[i];
2528 size_t ie_len = bss->ie_len;
2529
2530 if (!ie_len)
2531 ie_len = bss->beacon_ie_len;
2532 if (get_vendor_ie((const u8 *) (bss + 1), ie_len,
2533 DPP_CC_IE_VENDOR_TYPE))
2534 int_array_add_unique(&hapd->dpp_chirp_freqs,
2535 bss->freq);
2536 }
2537
2538 if (!hapd->dpp_chirp_freqs ||
2539 eloop_register_timeout(0, 0, hostapd_dpp_chirp_next,
2540 hapd, NULL) < 0)
2541 hostapd_dpp_chirp_stop(hapd);
2542
2543 wpa_scan_results_free(scan_res);
2544 }
2545
2546
hostapd_dpp_chirp_next(void * eloop_ctx,void * timeout_ctx)2547 static void hostapd_dpp_chirp_next(void *eloop_ctx, void *timeout_ctx)
2548 {
2549 struct hostapd_data *hapd = eloop_ctx;
2550 int i;
2551
2552 if (hapd->dpp_chirp_listen)
2553 hostapd_dpp_listen_stop(hapd);
2554
2555 if (hapd->dpp_chirp_freq == 0) {
2556 if (hapd->dpp_chirp_round % 4 == 0 &&
2557 !hapd->dpp_chirp_scan_done) {
2558 struct wpa_driver_scan_params params;
2559 int ret;
2560
2561 wpa_printf(MSG_DEBUG,
2562 "DPP: Update channel list for chirping");
2563 os_memset(¶ms, 0, sizeof(params));
2564 ret = hostapd_driver_scan(hapd, ¶ms);
2565 if (ret < 0) {
2566 wpa_printf(MSG_DEBUG,
2567 "DPP: Failed to request a scan ret=%d (%s)",
2568 ret, strerror(-ret));
2569 hostapd_dpp_chirp_scan_res_handler(hapd->iface);
2570 } else {
2571 hapd->iface->scan_cb =
2572 hostapd_dpp_chirp_scan_res_handler;
2573 }
2574 return;
2575 }
2576 hapd->dpp_chirp_freq = hapd->dpp_chirp_freqs[0];
2577 hapd->dpp_chirp_round++;
2578 wpa_printf(MSG_DEBUG, "DPP: Start chirping round %d",
2579 hapd->dpp_chirp_round);
2580 } else {
2581 for (i = 0; hapd->dpp_chirp_freqs[i]; i++)
2582 if (hapd->dpp_chirp_freqs[i] == hapd->dpp_chirp_freq)
2583 break;
2584 if (!hapd->dpp_chirp_freqs[i]) {
2585 wpa_printf(MSG_DEBUG,
2586 "DPP: Previous chirp freq %d not found",
2587 hapd->dpp_chirp_freq);
2588 return;
2589 }
2590 i++;
2591 if (hapd->dpp_chirp_freqs[i]) {
2592 hapd->dpp_chirp_freq = hapd->dpp_chirp_freqs[i];
2593 } else {
2594 hapd->dpp_chirp_iter--;
2595 if (hapd->dpp_chirp_iter <= 0) {
2596 wpa_printf(MSG_DEBUG,
2597 "DPP: Chirping iterations completed");
2598 hostapd_dpp_chirp_stop(hapd);
2599 return;
2600 }
2601 hapd->dpp_chirp_freq = 0;
2602 hapd->dpp_chirp_scan_done = 0;
2603 if (eloop_register_timeout(30, 0,
2604 hostapd_dpp_chirp_next,
2605 hapd, NULL) < 0) {
2606 hostapd_dpp_chirp_stop(hapd);
2607 return;
2608 }
2609 if (hapd->dpp_chirp_listen) {
2610 wpa_printf(MSG_DEBUG,
2611 "DPP: Listen on %d MHz during chirp 30 second wait",
2612 hapd->dpp_chirp_listen);
2613 /* TODO: start listen on the channel */
2614 } else {
2615 wpa_printf(MSG_DEBUG,
2616 "DPP: Wait 30 seconds before starting the next chirping round");
2617 }
2618 return;
2619 }
2620 }
2621
2622 hostapd_dpp_chirp_start(hapd);
2623 }
2624
2625
hostapd_dpp_chirp(struct hostapd_data * hapd,const char * cmd)2626 int hostapd_dpp_chirp(struct hostapd_data *hapd, const char *cmd)
2627 {
2628 const char *pos;
2629 int iter = 1, listen_freq = 0;
2630 struct dpp_bootstrap_info *bi;
2631
2632 pos = os_strstr(cmd, " own=");
2633 if (!pos)
2634 return -1;
2635 pos += 5;
2636 bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
2637 if (!bi) {
2638 wpa_printf(MSG_DEBUG,
2639 "DPP: Identified bootstrap info not found");
2640 return -1;
2641 }
2642
2643 pos = os_strstr(cmd, " iter=");
2644 if (pos) {
2645 iter = atoi(pos + 6);
2646 if (iter <= 0)
2647 return -1;
2648 }
2649
2650 pos = os_strstr(cmd, " listen=");
2651 if (pos) {
2652 listen_freq = atoi(pos + 8);
2653 if (listen_freq <= 0)
2654 return -1;
2655 }
2656
2657 hostapd_dpp_chirp_stop(hapd);
2658 hapd->dpp_allowed_roles = DPP_CAPAB_ENROLLEE;
2659 hapd->dpp_qr_mutual = 0;
2660 hapd->dpp_chirp_bi = bi;
2661 hapd->dpp_presence_announcement = dpp_build_presence_announcement(bi);
2662 if (!hapd->dpp_presence_announcement)
2663 return -1;
2664 hapd->dpp_chirp_iter = iter;
2665 hapd->dpp_chirp_round = 0;
2666 hapd->dpp_chirp_scan_done = 0;
2667 hapd->dpp_chirp_listen = listen_freq;
2668
2669 return eloop_register_timeout(0, 0, hostapd_dpp_chirp_next, hapd, NULL);
2670 }
2671
2672
hostapd_dpp_chirp_stop(struct hostapd_data * hapd)2673 void hostapd_dpp_chirp_stop(struct hostapd_data *hapd)
2674 {
2675 if (hapd->dpp_presence_announcement) {
2676 hostapd_drv_send_action_cancel_wait(hapd);
2677 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CHIRP_STOPPED);
2678 }
2679 hapd->dpp_chirp_bi = NULL;
2680 wpabuf_free(hapd->dpp_presence_announcement);
2681 hapd->dpp_presence_announcement = NULL;
2682 if (hapd->dpp_chirp_listen)
2683 hostapd_dpp_listen_stop(hapd);
2684 hapd->dpp_chirp_listen = 0;
2685 hapd->dpp_chirp_freq = 0;
2686 os_free(hapd->dpp_chirp_freqs);
2687 hapd->dpp_chirp_freqs = NULL;
2688 eloop_cancel_timeout(hostapd_dpp_chirp_next, hapd, NULL);
2689 eloop_cancel_timeout(hostapd_dpp_chirp_timeout, hapd, NULL);
2690 if (hapd->iface->scan_cb == hostapd_dpp_chirp_scan_res_handler) {
2691 /* TODO: abort ongoing scan */
2692 hapd->iface->scan_cb = NULL;
2693 }
2694 }
2695
2696
handle_dpp_remove_bi(struct hostapd_iface * iface,void * ctx)2697 static int handle_dpp_remove_bi(struct hostapd_iface *iface, void *ctx)
2698 {
2699 struct dpp_bootstrap_info *bi = ctx;
2700 size_t i;
2701
2702 for (i = 0; i < iface->num_bss; i++) {
2703 struct hostapd_data *hapd = iface->bss[i];
2704
2705 if (bi == hapd->dpp_chirp_bi)
2706 hostapd_dpp_chirp_stop(hapd);
2707 }
2708
2709 return 0;
2710 }
2711
2712
hostapd_dpp_remove_bi(void * ctx,struct dpp_bootstrap_info * bi)2713 void hostapd_dpp_remove_bi(void *ctx, struct dpp_bootstrap_info *bi)
2714 {
2715 struct hapd_interfaces *interfaces = ctx;
2716
2717 hostapd_for_each_interface(interfaces, handle_dpp_remove_bi, bi);
2718 }
2719
2720 #endif /* CONFIG_DPP2 */
2721