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