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