3 * Copyright (c) 2017, Qualcomm Atheros, Inc.
4 * Copyright (c) 2018, The Linux Foundation
6 * This software may be distributed under the terms of the BSD license.
7 * See README for more details.
10 #include "utils/includes.h"
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"
22 #include "offchannel.h"
23 #include "gas_query.h"
27 #include "dpp_supplicant.h"
30 static int wpas_dpp_listen_start(struct wpa_supplicant
*wpa_s
,
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
);
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
);
48 static const u8 broadcast
[ETH_ALEN
] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
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;
55 static struct dpp_configurator
*
56 dpp_configurator_get_id(struct wpa_supplicant
*wpa_s
, unsigned int id
)
58 struct dpp_configurator
*conf
;
60 dl_list_for_each(conf
, &wpa_s
->dpp_configurator
,
61 struct dpp_configurator
, list
) {
69 static unsigned int wpas_dpp_next_id(struct wpa_supplicant
*wpa_s
)
71 struct dpp_bootstrap_info
*bi
;
72 unsigned int max_id
= 0;
74 dl_list_for_each(bi
, &wpa_s
->dpp_bootstrap
, struct dpp_bootstrap_info
,
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
89 int wpas_dpp_qr_code(struct wpa_supplicant
*wpa_s
, const char *cmd
)
91 struct dpp_bootstrap_info
*bi
;
92 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
94 bi
= dpp_parse_qr_code(cmd
);
98 bi
->id
= wpas_dpp_next_id(wpa_s
);
99 dl_list_add(&wpa_s
->dpp_bootstrap
, &bi
->list
);
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
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
,
112 wpabuf_head(auth
->resp_msg
),
113 wpabuf_len(auth
->resp_msg
),
114 500, wpas_dpp_tx_status
, 0);
121 static char * get_param(const char *cmd
, const char *param
)
123 const char *pos
, *end
;
127 pos
= os_strstr(cmd
, param
);
131 pos
+= os_strlen(param
);
132 end
= os_strchr(pos
, ' ');
136 len
= os_strlen(pos
);
137 val
= os_malloc(len
+ 1);
140 os_memcpy(val
, pos
, len
);
146 int wpas_dpp_bootstrap_gen(struct wpa_supplicant
*wpa_s
, const char *cmd
)
148 char *chan
= NULL
, *mac
= NULL
, *info
= NULL
, *pk
= NULL
, *curve
= NULL
;
151 size_t privkey_len
= 0;
154 struct dpp_bootstrap_info
*bi
;
156 bi
= os_zalloc(sizeof(*bi
));
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
;
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=");
174 privkey_len
= os_strlen(key
) / 2;
175 privkey
= os_malloc(privkey_len
);
177 hexstr2bin(key
, privkey
, privkey_len
) < 0)
181 pk
= dpp_keygen(bi
, curve
, privkey
, privkey_len
);
185 len
= 4; /* "DPP:" */
187 if (dpp_parse_uri_chan_list(bi
, chan
) < 0)
189 len
+= 3 + os_strlen(chan
); /* C:...; */
192 if (dpp_parse_uri_mac(bi
, mac
) < 0)
194 len
+= 3 + os_strlen(mac
); /* M:...; */
197 if (dpp_parse_uri_info(bi
, info
) < 0)
199 len
+= 3 + os_strlen(info
); /* I:...; */
201 len
+= 4 + os_strlen(pk
);
202 bi
->uri
= os_malloc(len
+ 1);
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
? ";" : "",
210 bi
->id
= wpas_dpp_next_id(wpa_s
);
211 dl_list_add(&wpa_s
->dpp_bootstrap
, &bi
->list
);
221 bin_clear_free(privkey
, privkey_len
);
222 dpp_bootstrap_info_free(bi
);
227 static struct dpp_bootstrap_info
*
228 dpp_bootstrap_get_id(struct wpa_supplicant
*wpa_s
, unsigned int id
)
230 struct dpp_bootstrap_info
*bi
;
232 dl_list_for_each(bi
, &wpa_s
->dpp_bootstrap
, struct dpp_bootstrap_info
,
241 static int dpp_bootstrap_del(struct wpa_supplicant
*wpa_s
, unsigned int id
)
243 struct dpp_bootstrap_info
*bi
, *tmp
;
246 dl_list_for_each_safe(bi
, tmp
, &wpa_s
->dpp_bootstrap
,
247 struct dpp_bootstrap_info
, list
) {
248 if (id
&& bi
->id
!= id
)
251 dl_list_del(&bi
->list
);
252 dpp_bootstrap_info_free(bi
);
256 return 0; /* flush succeeds regardless of entries found */
257 return found
? 0 : -1;
261 int wpas_dpp_bootstrap_remove(struct wpa_supplicant
*wpa_s
, const char *id
)
265 if (os_strcmp(id
, "*") == 0) {
273 return dpp_bootstrap_del(wpa_s
, id_val
);
277 const char * wpas_dpp_bootstrap_get_uri(struct wpa_supplicant
*wpa_s
,
280 struct dpp_bootstrap_info
*bi
;
282 bi
= dpp_bootstrap_get_id(wpa_s
, id
);
289 int wpas_dpp_bootstrap_info(struct wpa_supplicant
*wpa_s
, int id
,
290 char *reply
, int reply_size
)
292 struct dpp_bootstrap_info
*bi
;
294 bi
= dpp_bootstrap_get_id(wpa_s
, id
);
297 return os_snprintf(reply
, reply_size
, "type=%s\n"
298 "mac_addr=" MACSTR
"\n"
302 dpp_bootstrap_type_txt(bi
->type
),
303 MAC2STR(bi
->mac_addr
),
304 bi
->info
? bi
->info
: "",
310 static void wpas_dpp_auth_resp_retry_timeout(void *eloop_ctx
, void *timeout_ctx
)
312 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
313 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
315 if (!auth
|| !auth
->resp_msg
)
318 wpa_printf(MSG_DEBUG
,
319 "DPP: Retry Authentication Response after timeout");
320 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
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);
332 static void wpas_dpp_auth_resp_retry(struct wpa_supplicant
*wpa_s
)
334 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
335 unsigned int wait_time
, max_tries
;
337 if (!auth
|| !auth
->resp_msg
)
340 if (wpa_s
->dpp_resp_max_tries
)
341 max_tries
= wpa_s
->dpp_resp_max_tries
;
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
;
353 if (wpa_s
->dpp_resp_retry_time
)
354 wait_time
= wpa_s
->dpp_resp_retry_time
;
357 wpa_printf(MSG_DEBUG
,
358 "DPP: Schedule retransmission of Authentication Response frame in %u ms",
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
);
367 static void wpas_dpp_try_to_connect(struct wpa_supplicant
*wpa_s
)
369 wpa_printf(MSG_DEBUG
, "DPP: Trying to connect to the new network");
370 wpa_s
->disconnected
= 0;
371 wpa_s
->reassociate
= 1;
372 wpa_s
->scan_runs
= 0;
373 wpa_s
->normal_scans
= 0;
374 wpa_supplicant_cancel_sched_scan(wpa_s
);
375 wpa_supplicant_req_scan(wpa_s
, 0, 0);
379 static void wpas_dpp_tx_status(struct wpa_supplicant
*wpa_s
,
380 unsigned int freq
, const u8
*dst
,
381 const u8
*src
, const u8
*bssid
,
382 const u8
*data
, size_t data_len
,
383 enum offchannel_send_action_result result
)
386 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
388 res_txt
= result
== OFFCHANNEL_SEND_ACTION_SUCCESS
? "SUCCESS" :
389 (result
== OFFCHANNEL_SEND_ACTION_NO_ACK
? "no-ACK" :
391 wpa_printf(MSG_DEBUG
, "DPP: TX status: freq=%u dst=" MACSTR
392 " result=%s", freq
, MAC2STR(dst
), res_txt
);
393 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX_STATUS
"dst=" MACSTR
394 " freq=%u result=%s", MAC2STR(dst
), freq
, res_txt
);
396 if (!wpa_s
->dpp_auth
) {
397 wpa_printf(MSG_DEBUG
,
398 "DPP: Ignore TX status since there is no ongoing authentication exchange");
403 if (auth
->connect_on_tx_status
) {
404 wpa_printf(MSG_DEBUG
,
405 "DPP: Try to connect after completed configuration result");
406 wpas_dpp_try_to_connect(wpa_s
);
407 dpp_auth_deinit(wpa_s
->dpp_auth
);
408 wpa_s
->dpp_auth
= NULL
;
411 #endif /* CONFIG_DPP2 */
413 if (wpa_s
->dpp_auth
->remove_on_tx_status
) {
414 wpa_printf(MSG_DEBUG
,
415 "DPP: Terminate authentication exchange due to an earlier error");
416 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
417 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
418 eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout
, wpa_s
,
420 offchannel_send_action_done(wpa_s
);
421 dpp_auth_deinit(wpa_s
->dpp_auth
);
422 wpa_s
->dpp_auth
= NULL
;
426 if (wpa_s
->dpp_auth_ok_on_ack
)
427 wpas_dpp_auth_success(wpa_s
, 1);
429 if (!is_broadcast_ether_addr(dst
) &&
430 result
!= OFFCHANNEL_SEND_ACTION_SUCCESS
) {
431 wpa_printf(MSG_DEBUG
,
432 "DPP: Unicast DPP Action frame was not ACKed");
433 if (auth
->waiting_auth_resp
) {
434 /* In case of DPP Authentication Request frame, move to
435 * the next channel immediately. */
436 offchannel_send_action_done(wpa_s
);
437 wpas_dpp_auth_init_next(wpa_s
);
440 if (auth
->waiting_auth_conf
) {
441 wpas_dpp_auth_resp_retry(wpa_s
);
446 if (!is_broadcast_ether_addr(dst
) && auth
->waiting_auth_resp
&&
447 result
== OFFCHANNEL_SEND_ACTION_SUCCESS
) {
448 /* Allow timeout handling to stop iteration if no response is
449 * received from a peer that has ACKed a request. */
450 auth
->auth_req_ack
= 1;
453 if (!wpa_s
->dpp_auth_ok_on_ack
&& wpa_s
->dpp_auth
->neg_freq
> 0 &&
454 wpa_s
->dpp_auth
->curr_freq
!= wpa_s
->dpp_auth
->neg_freq
) {
455 wpa_printf(MSG_DEBUG
,
456 "DPP: Move from curr_freq %u MHz to neg_freq %u MHz for response",
457 wpa_s
->dpp_auth
->curr_freq
,
458 wpa_s
->dpp_auth
->neg_freq
);
459 offchannel_send_action_done(wpa_s
);
460 wpas_dpp_listen_start(wpa_s
, wpa_s
->dpp_auth
->neg_freq
);
463 if (wpa_s
->dpp_auth_ok_on_ack
)
464 wpa_s
->dpp_auth_ok_on_ack
= 0;
468 static void wpas_dpp_reply_wait_timeout(void *eloop_ctx
, void *timeout_ctx
)
470 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
471 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
473 struct os_reltime now
, diff
;
474 unsigned int wait_time
, diff_ms
;
476 if (!auth
|| !auth
->waiting_auth_resp
)
479 wait_time
= wpa_s
->dpp_resp_wait_time
?
480 wpa_s
->dpp_resp_wait_time
: 2000;
481 os_get_reltime(&now
);
482 os_reltime_sub(&now
, &wpa_s
->dpp_last_init
, &diff
);
483 diff_ms
= diff
.sec
* 1000 + diff
.usec
/ 1000;
484 wpa_printf(MSG_DEBUG
,
485 "DPP: Reply wait timeout - wait_time=%u diff_ms=%u",
488 if (auth
->auth_req_ack
&& diff_ms
>= wait_time
) {
489 /* Peer ACK'ed Authentication Request frame, but did not reply
490 * with Authentication Response frame within two seconds. */
492 "DPP: No response received from responder - stopping initiation attempt");
493 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_AUTH_INIT_FAILED
);
494 offchannel_send_action_done(wpa_s
);
495 wpas_dpp_listen_stop(wpa_s
);
496 dpp_auth_deinit(auth
);
497 wpa_s
->dpp_auth
= NULL
;
501 if (diff_ms
>= wait_time
) {
502 /* Authentication Request frame was not ACK'ed and no reply
503 * was receiving within two seconds. */
504 wpa_printf(MSG_DEBUG
,
505 "DPP: Continue Initiator channel iteration");
506 offchannel_send_action_done(wpa_s
);
507 wpas_dpp_listen_stop(wpa_s
);
508 wpas_dpp_auth_init_next(wpa_s
);
512 /* Driver did not support 2000 ms long wait_time with TX command, so
513 * schedule listen operation to continue waiting for the response.
515 * DPP listen operations continue until stopped, so simply schedule a
516 * new call to this function at the point when the two second reply
517 * wait has expired. */
518 wait_time
-= diff_ms
;
520 freq
= auth
->curr_freq
;
521 if (auth
->neg_freq
> 0)
522 freq
= auth
->neg_freq
;
523 wpa_printf(MSG_DEBUG
,
524 "DPP: Continue reply wait on channel %u MHz for %u ms",
526 wpa_s
->dpp_in_response_listen
= 1;
527 wpas_dpp_listen_start(wpa_s
, freq
);
529 eloop_register_timeout(wait_time
/ 1000, (wait_time
% 1000) * 1000,
530 wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
534 static void wpas_dpp_set_testing_options(struct wpa_supplicant
*wpa_s
,
535 struct dpp_authentication
*auth
)
537 #ifdef CONFIG_TESTING_OPTIONS
538 if (wpa_s
->dpp_config_obj_override
)
539 auth
->config_obj_override
=
540 os_strdup(wpa_s
->dpp_config_obj_override
);
541 if (wpa_s
->dpp_discovery_override
)
542 auth
->discovery_override
=
543 os_strdup(wpa_s
->dpp_discovery_override
);
544 if (wpa_s
->dpp_groups_override
)
545 auth
->groups_override
=
546 os_strdup(wpa_s
->dpp_groups_override
);
547 auth
->ignore_netaccesskey_mismatch
=
548 wpa_s
->dpp_ignore_netaccesskey_mismatch
;
549 #endif /* CONFIG_TESTING_OPTIONS */
553 static int wpas_dpp_set_configurator(struct wpa_supplicant
*wpa_s
,
554 struct dpp_authentication
*auth
,
557 const char *pos
, *end
;
558 struct dpp_configuration
*conf_sta
= NULL
, *conf_ap
= NULL
;
559 struct dpp_configurator
*conf
= NULL
;
560 u8 ssid
[32] = { "test" };
566 char *group_id
= NULL
;
571 wpa_printf(MSG_DEBUG
, "DPP: Set configurator parameters: %s", cmd
);
572 pos
= os_strstr(cmd
, " ssid=");
575 end
= os_strchr(pos
, ' ');
576 ssid_len
= end
? (size_t) (end
- pos
) : os_strlen(pos
);
578 if (ssid_len
> sizeof(ssid
) ||
579 hexstr2bin(pos
, ssid
, ssid_len
) < 0)
583 pos
= os_strstr(cmd
, " pass=");
586 end
= os_strchr(pos
, ' ');
587 pass_len
= end
? (size_t) (end
- pos
) : os_strlen(pos
);
589 if (pass_len
> sizeof(pass
) - 1 || pass_len
< 8 ||
590 hexstr2bin(pos
, (u8
*) pass
, pass_len
) < 0)
594 pos
= os_strstr(cmd
, " psk=");
597 if (hexstr2bin(pos
, psk
, PMK_LEN
) < 0)
602 pos
= os_strstr(cmd
, " group_id=");
607 end
= os_strchr(pos
, ' ');
608 group_id_len
= end
? (size_t) (end
- pos
) : os_strlen(pos
);
609 group_id
= os_malloc(group_id_len
+ 1);
612 os_memcpy(group_id
, pos
, group_id_len
);
613 group_id
[group_id_len
] = '\0';
616 if (os_strstr(cmd
, " conf=sta-")) {
617 conf_sta
= os_zalloc(sizeof(struct dpp_configuration
));
620 os_memcpy(conf_sta
->ssid
, ssid
, ssid_len
);
621 conf_sta
->ssid_len
= ssid_len
;
622 if (os_strstr(cmd
, " conf=sta-psk") ||
623 os_strstr(cmd
, " conf=sta-sae") ||
624 os_strstr(cmd
, " conf=sta-psk-sae")) {
625 if (os_strstr(cmd
, " conf=sta-psk-sae"))
626 conf_sta
->akm
= DPP_AKM_PSK_SAE
;
627 else if (os_strstr(cmd
, " conf=sta-sae"))
628 conf_sta
->akm
= DPP_AKM_SAE
;
630 conf_sta
->akm
= DPP_AKM_PSK
;
632 os_memcpy(conf_sta
->psk
, psk
, PMK_LEN
);
633 } else if (pass_len
> 0) {
634 conf_sta
->passphrase
= os_strdup(pass
);
635 if (!conf_sta
->passphrase
)
640 } else if (os_strstr(cmd
, " conf=sta-dpp")) {
641 conf_sta
->akm
= DPP_AKM_DPP
;
645 if (os_strstr(cmd
, " group_id=")) {
646 conf_sta
->group_id
= group_id
;
651 if (os_strstr(cmd
, " conf=ap-")) {
652 conf_ap
= os_zalloc(sizeof(struct dpp_configuration
));
655 os_memcpy(conf_ap
->ssid
, ssid
, ssid_len
);
656 conf_ap
->ssid_len
= ssid_len
;
657 if (os_strstr(cmd
, " conf=ap-psk") ||
658 os_strstr(cmd
, " conf=ap-sae") ||
659 os_strstr(cmd
, " conf=ap-psk-sae")) {
660 if (os_strstr(cmd
, " conf=ap-psk-sae"))
661 conf_ap
->akm
= DPP_AKM_PSK_SAE
;
662 else if (os_strstr(cmd
, " conf=ap-sae"))
663 conf_ap
->akm
= DPP_AKM_SAE
;
665 conf_ap
->akm
= DPP_AKM_PSK
;
667 os_memcpy(conf_ap
->psk
, psk
, PMK_LEN
);
669 conf_ap
->passphrase
= os_strdup(pass
);
670 if (!conf_ap
->passphrase
)
673 } else if (os_strstr(cmd
, " conf=ap-dpp")) {
674 conf_ap
->akm
= DPP_AKM_DPP
;
678 if (os_strstr(cmd
, " group_id=")) {
679 conf_ap
->group_id
= group_id
;
684 pos
= os_strstr(cmd
, " expiry=");
689 val
= strtol(pos
, NULL
, 0);
693 conf_sta
->netaccesskey_expiry
= val
;
695 conf_ap
->netaccesskey_expiry
= val
;
698 pos
= os_strstr(cmd
, " configurator=");
701 conf
= dpp_configurator_get_id(wpa_s
, atoi(pos
));
704 "DPP: Could not find the specified configurator");
708 auth
->conf_sta
= conf_sta
;
709 auth
->conf_ap
= conf_ap
;
715 wpa_msg(wpa_s
, MSG_INFO
, "DPP: Failed to set configurator parameters");
716 dpp_configuration_free(conf_sta
);
717 dpp_configuration_free(conf_ap
);
723 static void wpas_dpp_init_timeout(void *eloop_ctx
, void *timeout_ctx
)
725 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
727 if (!wpa_s
->dpp_auth
)
729 wpa_printf(MSG_DEBUG
, "DPP: Retry initiation after timeout");
730 wpas_dpp_auth_init_next(wpa_s
);
734 static int wpas_dpp_auth_init_next(struct wpa_supplicant
*wpa_s
)
736 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
738 unsigned int wait_time
, max_wait_time
, freq
, max_tries
, used
;
739 struct os_reltime now
, diff
;
741 wpa_s
->dpp_in_response_listen
= 0;
745 if (auth
->freq_idx
== 0)
746 os_get_reltime(&wpa_s
->dpp_init_iter_start
);
748 if (auth
->freq_idx
>= auth
->num_freq
) {
749 auth
->num_freq_iters
++;
750 if (wpa_s
->dpp_init_max_tries
)
751 max_tries
= wpa_s
->dpp_init_max_tries
;
754 if (auth
->num_freq_iters
>= max_tries
|| auth
->auth_req_ack
) {
756 "DPP: No response received from responder - stopping initiation attempt");
757 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_AUTH_INIT_FAILED
);
758 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
,
760 offchannel_send_action_done(wpa_s
);
761 dpp_auth_deinit(wpa_s
->dpp_auth
);
762 wpa_s
->dpp_auth
= NULL
;
766 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
767 if (wpa_s
->dpp_init_retry_time
)
768 wait_time
= wpa_s
->dpp_init_retry_time
;
771 os_get_reltime(&now
);
772 os_reltime_sub(&now
, &wpa_s
->dpp_init_iter_start
, &diff
);
773 used
= diff
.sec
* 1000 + diff
.usec
/ 1000;
774 if (used
> wait_time
)
778 wpa_printf(MSG_DEBUG
, "DPP: Next init attempt in %u ms",
780 eloop_register_timeout(wait_time
/ 1000,
781 (wait_time
% 1000) * 1000,
782 wpas_dpp_init_timeout
, wpa_s
,
786 freq
= auth
->freq
[auth
->freq_idx
++];
787 auth
->curr_freq
= freq
;
789 if (is_zero_ether_addr(auth
->peer_bi
->mac_addr
))
792 dst
= auth
->peer_bi
->mac_addr
;
793 wpa_s
->dpp_auth_ok_on_ack
= 0;
794 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
795 wait_time
= wpa_s
->max_remain_on_chan
;
796 max_wait_time
= wpa_s
->dpp_resp_wait_time
?
797 wpa_s
->dpp_resp_wait_time
: 2000;
798 if (wait_time
> max_wait_time
)
799 wait_time
= max_wait_time
;
800 wait_time
+= 10; /* give the driver some extra time to complete */
801 eloop_register_timeout(wait_time
/ 1000, (wait_time
% 1000) * 1000,
802 wpas_dpp_reply_wait_timeout
,
805 if (auth
->neg_freq
> 0 && freq
!= auth
->neg_freq
) {
806 wpa_printf(MSG_DEBUG
,
807 "DPP: Initiate on %u MHz and move to neg_freq %u MHz for response",
808 freq
, auth
->neg_freq
);
810 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
811 MAC2STR(dst
), freq
, DPP_PA_AUTHENTICATION_REQ
);
812 auth
->auth_req_ack
= 0;
813 os_get_reltime(&wpa_s
->dpp_last_init
);
814 return offchannel_send_action(wpa_s
, freq
, dst
,
815 wpa_s
->own_addr
, broadcast
,
816 wpabuf_head(auth
->req_msg
),
817 wpabuf_len(auth
->req_msg
),
818 wait_time
, wpas_dpp_tx_status
, 0);
822 int wpas_dpp_auth_init(struct wpa_supplicant
*wpa_s
, const char *cmd
)
825 struct dpp_bootstrap_info
*peer_bi
, *own_bi
= NULL
;
826 u8 allowed_roles
= DPP_CAPAB_CONFIGURATOR
;
827 unsigned int neg_freq
= 0;
829 wpa_s
->dpp_gas_client
= 0;
831 pos
= os_strstr(cmd
, " peer=");
835 peer_bi
= dpp_bootstrap_get_id(wpa_s
, atoi(pos
));
838 "DPP: Could not find bootstrapping info for the identified peer");
842 pos
= os_strstr(cmd
, " own=");
845 own_bi
= dpp_bootstrap_get_id(wpa_s
, atoi(pos
));
848 "DPP: Could not find bootstrapping info for the identified local entry");
852 if (peer_bi
->curve
!= own_bi
->curve
) {
854 "DPP: Mismatching curves in bootstrapping info (peer=%s own=%s)",
855 peer_bi
->curve
->name
, own_bi
->curve
->name
);
860 pos
= os_strstr(cmd
, " role=");
863 if (os_strncmp(pos
, "configurator", 12) == 0)
864 allowed_roles
= DPP_CAPAB_CONFIGURATOR
;
865 else if (os_strncmp(pos
, "enrollee", 8) == 0)
866 allowed_roles
= DPP_CAPAB_ENROLLEE
;
867 else if (os_strncmp(pos
, "either", 6) == 0)
868 allowed_roles
= DPP_CAPAB_CONFIGURATOR
|
874 pos
= os_strstr(cmd
, " netrole=");
877 wpa_s
->dpp_netrole_ap
= os_strncmp(pos
, "ap", 2) == 0;
880 pos
= os_strstr(cmd
, " neg_freq=");
882 neg_freq
= atoi(pos
+ 10);
884 if (wpa_s
->dpp_auth
) {
885 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
886 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
887 eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout
, wpa_s
,
889 offchannel_send_action_done(wpa_s
);
890 dpp_auth_deinit(wpa_s
->dpp_auth
);
892 wpa_s
->dpp_auth
= dpp_auth_init(wpa_s
, peer_bi
, own_bi
, allowed_roles
,
894 wpa_s
->hw
.modes
, wpa_s
->hw
.num_modes
);
895 if (!wpa_s
->dpp_auth
)
897 wpas_dpp_set_testing_options(wpa_s
, wpa_s
->dpp_auth
);
898 if (wpas_dpp_set_configurator(wpa_s
, wpa_s
->dpp_auth
, cmd
) < 0) {
899 dpp_auth_deinit(wpa_s
->dpp_auth
);
900 wpa_s
->dpp_auth
= NULL
;
904 wpa_s
->dpp_auth
->neg_freq
= neg_freq
;
906 if (!is_zero_ether_addr(peer_bi
->mac_addr
))
907 os_memcpy(wpa_s
->dpp_auth
->peer_mac_addr
, peer_bi
->mac_addr
,
910 return wpas_dpp_auth_init_next(wpa_s
);
916 struct wpas_dpp_listen_work
{
918 unsigned int duration
;
919 struct wpabuf
*probe_resp_ie
;
923 static void wpas_dpp_listen_work_free(struct wpas_dpp_listen_work
*lwork
)
931 static void wpas_dpp_listen_work_done(struct wpa_supplicant
*wpa_s
)
933 struct wpas_dpp_listen_work
*lwork
;
935 if (!wpa_s
->dpp_listen_work
)
938 lwork
= wpa_s
->dpp_listen_work
->ctx
;
939 wpas_dpp_listen_work_free(lwork
);
940 radio_work_done(wpa_s
->dpp_listen_work
);
941 wpa_s
->dpp_listen_work
= NULL
;
945 static void dpp_start_listen_cb(struct wpa_radio_work
*work
, int deinit
)
947 struct wpa_supplicant
*wpa_s
= work
->wpa_s
;
948 struct wpas_dpp_listen_work
*lwork
= work
->ctx
;
952 wpa_s
->dpp_listen_work
= NULL
;
953 wpas_dpp_listen_stop(wpa_s
);
955 wpas_dpp_listen_work_free(lwork
);
959 wpa_s
->dpp_listen_work
= work
;
961 wpa_s
->dpp_pending_listen_freq
= lwork
->freq
;
963 if (wpa_drv_remain_on_channel(wpa_s
, lwork
->freq
,
964 wpa_s
->max_remain_on_chan
) < 0) {
965 wpa_printf(MSG_DEBUG
,
966 "DPP: Failed to request the driver to remain on channel (%u MHz) for listen",
968 wpa_s
->dpp_listen_freq
= 0;
969 wpas_dpp_listen_work_done(wpa_s
);
970 wpa_s
->dpp_pending_listen_freq
= 0;
973 wpa_s
->off_channel_freq
= 0;
974 wpa_s
->roc_waiting_drv_freq
= lwork
->freq
;
978 static int wpas_dpp_listen_start(struct wpa_supplicant
*wpa_s
,
981 struct wpas_dpp_listen_work
*lwork
;
983 if (wpa_s
->dpp_listen_work
) {
984 wpa_printf(MSG_DEBUG
,
985 "DPP: Reject start_listen since dpp_listen_work already exists");
989 if (wpa_s
->dpp_listen_freq
)
990 wpas_dpp_listen_stop(wpa_s
);
991 wpa_s
->dpp_listen_freq
= freq
;
993 lwork
= os_zalloc(sizeof(*lwork
));
998 if (radio_add_work(wpa_s
, freq
, "dpp-listen", 0, dpp_start_listen_cb
,
1000 wpas_dpp_listen_work_free(lwork
);
1008 int wpas_dpp_listen(struct wpa_supplicant
*wpa_s
, const char *cmd
)
1016 if (os_strstr(cmd
, " role=configurator"))
1017 wpa_s
->dpp_allowed_roles
= DPP_CAPAB_CONFIGURATOR
;
1018 else if (os_strstr(cmd
, " role=enrollee"))
1019 wpa_s
->dpp_allowed_roles
= DPP_CAPAB_ENROLLEE
;
1021 wpa_s
->dpp_allowed_roles
= DPP_CAPAB_CONFIGURATOR
|
1023 wpa_s
->dpp_qr_mutual
= os_strstr(cmd
, " qr=mutual") != NULL
;
1024 wpa_s
->dpp_netrole_ap
= os_strstr(cmd
, " netrole=ap") != NULL
;
1025 if (wpa_s
->dpp_listen_freq
== (unsigned int) freq
) {
1026 wpa_printf(MSG_DEBUG
, "DPP: Already listening on %u MHz",
1031 return wpas_dpp_listen_start(wpa_s
, freq
);
1035 void wpas_dpp_listen_stop(struct wpa_supplicant
*wpa_s
)
1037 wpa_s
->dpp_in_response_listen
= 0;
1038 if (!wpa_s
->dpp_listen_freq
)
1041 wpa_printf(MSG_DEBUG
, "DPP: Stop listen on %u MHz",
1042 wpa_s
->dpp_listen_freq
);
1043 wpa_drv_cancel_remain_on_channel(wpa_s
);
1044 wpa_s
->dpp_listen_freq
= 0;
1045 wpas_dpp_listen_work_done(wpa_s
);
1049 void wpas_dpp_cancel_remain_on_channel_cb(struct wpa_supplicant
*wpa_s
,
1052 wpas_dpp_listen_work_done(wpa_s
);
1054 if (wpa_s
->dpp_auth
&& wpa_s
->dpp_in_response_listen
) {
1055 unsigned int new_freq
;
1057 /* Continue listen with a new remain-on-channel */
1058 if (wpa_s
->dpp_auth
->neg_freq
> 0)
1059 new_freq
= wpa_s
->dpp_auth
->neg_freq
;
1061 new_freq
= wpa_s
->dpp_auth
->curr_freq
;
1062 wpa_printf(MSG_DEBUG
,
1063 "DPP: Continue wait on %u MHz for the ongoing DPP provisioning session",
1065 wpas_dpp_listen_start(wpa_s
, new_freq
);
1069 if (wpa_s
->dpp_listen_freq
) {
1070 /* Continue listen with a new remain-on-channel */
1071 wpas_dpp_listen_start(wpa_s
, wpa_s
->dpp_listen_freq
);
1076 static void wpas_dpp_rx_auth_req(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1077 const u8
*hdr
, const u8
*buf
, size_t len
,
1080 const u8
*r_bootstrap
, *i_bootstrap
;
1081 u16 r_bootstrap_len
, i_bootstrap_len
;
1082 struct dpp_bootstrap_info
*bi
, *own_bi
= NULL
, *peer_bi
= NULL
;
1084 wpa_printf(MSG_DEBUG
, "DPP: Authentication Request from " MACSTR
,
1087 r_bootstrap
= dpp_get_attr(buf
, len
, DPP_ATTR_R_BOOTSTRAP_KEY_HASH
,
1089 if (!r_bootstrap
|| r_bootstrap_len
!= SHA256_MAC_LEN
) {
1090 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
1091 "Missing or invalid required Responder Bootstrapping Key Hash attribute");
1094 wpa_hexdump(MSG_MSGDUMP
, "DPP: Responder Bootstrapping Key Hash",
1095 r_bootstrap
, r_bootstrap_len
);
1097 i_bootstrap
= dpp_get_attr(buf
, len
, DPP_ATTR_I_BOOTSTRAP_KEY_HASH
,
1099 if (!i_bootstrap
|| i_bootstrap_len
!= SHA256_MAC_LEN
) {
1100 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
1101 "Missing or invalid required Initiator Bootstrapping Key Hash attribute");
1104 wpa_hexdump(MSG_MSGDUMP
, "DPP: Initiator Bootstrapping Key Hash",
1105 i_bootstrap
, i_bootstrap_len
);
1107 /* Try to find own and peer bootstrapping key matches based on the
1108 * received hash values */
1109 dl_list_for_each(bi
, &wpa_s
->dpp_bootstrap
, struct dpp_bootstrap_info
,
1111 if (!own_bi
&& bi
->own
&&
1112 os_memcmp(bi
->pubkey_hash
, r_bootstrap
,
1113 SHA256_MAC_LEN
) == 0) {
1114 wpa_printf(MSG_DEBUG
,
1115 "DPP: Found matching own bootstrapping information");
1119 if (!peer_bi
&& !bi
->own
&&
1120 os_memcmp(bi
->pubkey_hash
, i_bootstrap
,
1121 SHA256_MAC_LEN
) == 0) {
1122 wpa_printf(MSG_DEBUG
,
1123 "DPP: Found matching peer bootstrapping information");
1127 if (own_bi
&& peer_bi
)
1132 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
1133 "No matching own bootstrapping key found - ignore message");
1137 if (wpa_s
->dpp_auth
) {
1138 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
1139 "Already in DPP authentication exchange - ignore new one");
1143 wpa_s
->dpp_gas_client
= 0;
1144 wpa_s
->dpp_auth_ok_on_ack
= 0;
1145 wpa_s
->dpp_auth
= dpp_auth_req_rx(wpa_s
, wpa_s
->dpp_allowed_roles
,
1146 wpa_s
->dpp_qr_mutual
,
1147 peer_bi
, own_bi
, freq
, hdr
, buf
, len
);
1148 if (!wpa_s
->dpp_auth
) {
1149 wpa_printf(MSG_DEBUG
, "DPP: No response generated");
1152 wpas_dpp_set_testing_options(wpa_s
, wpa_s
->dpp_auth
);
1153 if (wpas_dpp_set_configurator(wpa_s
, wpa_s
->dpp_auth
,
1154 wpa_s
->dpp_configurator_params
) < 0) {
1155 dpp_auth_deinit(wpa_s
->dpp_auth
);
1156 wpa_s
->dpp_auth
= NULL
;
1159 os_memcpy(wpa_s
->dpp_auth
->peer_mac_addr
, src
, ETH_ALEN
);
1161 if (wpa_s
->dpp_listen_freq
&&
1162 wpa_s
->dpp_listen_freq
!= wpa_s
->dpp_auth
->curr_freq
) {
1163 wpa_printf(MSG_DEBUG
,
1164 "DPP: Stop listen on %u MHz to allow response on the request %u MHz",
1165 wpa_s
->dpp_listen_freq
, wpa_s
->dpp_auth
->curr_freq
);
1166 wpas_dpp_listen_stop(wpa_s
);
1169 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1170 MAC2STR(src
), wpa_s
->dpp_auth
->curr_freq
,
1171 DPP_PA_AUTHENTICATION_RESP
);
1172 offchannel_send_action(wpa_s
, wpa_s
->dpp_auth
->curr_freq
,
1173 src
, wpa_s
->own_addr
, broadcast
,
1174 wpabuf_head(wpa_s
->dpp_auth
->resp_msg
),
1175 wpabuf_len(wpa_s
->dpp_auth
->resp_msg
),
1176 500, wpas_dpp_tx_status
, 0);
1180 static void wpas_dpp_start_gas_server(struct wpa_supplicant
*wpa_s
)
1182 /* TODO: stop wait and start ROC */
1186 static struct wpa_ssid
* wpas_dpp_add_network(struct wpa_supplicant
*wpa_s
,
1187 struct dpp_authentication
*auth
)
1189 struct wpa_ssid
*ssid
;
1192 if (auth
->akm
== DPP_AKM_SAE
) {
1194 struct wpa_driver_capa capa
;
1197 res
= wpa_drv_get_capa(wpa_s
, &capa
);
1199 !(capa
.key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_SAE
) &&
1200 !(wpa_s
->drv_flags
& WPA_DRIVER_FLAGS_SAE
)) {
1201 wpa_printf(MSG_DEBUG
,
1202 "DPP: SAE not supported by the driver");
1205 #else /* CONFIG_SAE */
1206 wpa_printf(MSG_DEBUG
, "DPP: SAE not supported in the build");
1208 #endif /* CONFIG_SAE */
1210 #endif /* CONFIG_DPP2 */
1212 ssid
= wpa_config_add_network(wpa_s
->conf
);
1215 wpas_notify_network_added(wpa_s
, ssid
);
1216 wpa_config_set_network_defaults(ssid
);
1219 ssid
->ssid
= os_malloc(auth
->ssid_len
);
1222 os_memcpy(ssid
->ssid
, auth
->ssid
, auth
->ssid_len
);
1223 ssid
->ssid_len
= auth
->ssid_len
;
1225 if (auth
->connector
) {
1226 ssid
->key_mgmt
= WPA_KEY_MGMT_DPP
;
1227 ssid
->ieee80211w
= MGMT_FRAME_PROTECTION_REQUIRED
;
1228 ssid
->dpp_connector
= os_strdup(auth
->connector
);
1229 if (!ssid
->dpp_connector
)
1233 if (auth
->c_sign_key
) {
1234 ssid
->dpp_csign
= os_malloc(wpabuf_len(auth
->c_sign_key
));
1235 if (!ssid
->dpp_csign
)
1237 os_memcpy(ssid
->dpp_csign
, wpabuf_head(auth
->c_sign_key
),
1238 wpabuf_len(auth
->c_sign_key
));
1239 ssid
->dpp_csign_len
= wpabuf_len(auth
->c_sign_key
);
1242 if (auth
->net_access_key
) {
1243 ssid
->dpp_netaccesskey
=
1244 os_malloc(wpabuf_len(auth
->net_access_key
));
1245 if (!ssid
->dpp_netaccesskey
)
1247 os_memcpy(ssid
->dpp_netaccesskey
,
1248 wpabuf_head(auth
->net_access_key
),
1249 wpabuf_len(auth
->net_access_key
));
1250 ssid
->dpp_netaccesskey_len
= wpabuf_len(auth
->net_access_key
);
1251 ssid
->dpp_netaccesskey_expiry
= auth
->net_access_key_expiry
;
1254 if (!auth
->connector
) {
1256 if (auth
->akm
== DPP_AKM_PSK
|| auth
->akm
== DPP_AKM_PSK_SAE
)
1257 ssid
->key_mgmt
|= WPA_KEY_MGMT_PSK
|
1258 WPA_KEY_MGMT_PSK_SHA256
| WPA_KEY_MGMT_FT_PSK
;
1259 if (auth
->akm
== DPP_AKM_SAE
|| auth
->akm
== DPP_AKM_PSK_SAE
)
1260 ssid
->key_mgmt
|= WPA_KEY_MGMT_SAE
|
1261 WPA_KEY_MGMT_FT_SAE
;
1262 ssid
->ieee80211w
= MGMT_FRAME_PROTECTION_OPTIONAL
;
1263 if (auth
->passphrase
[0]) {
1264 if (wpa_config_set_quoted(ssid
, "psk",
1265 auth
->passphrase
) < 0)
1267 wpa_config_update_psk(ssid
);
1268 ssid
->export_keys
= 1;
1270 ssid
->psk_set
= auth
->psk_set
;
1271 os_memcpy(ssid
->psk
, auth
->psk
, PMK_LEN
);
1277 wpas_notify_network_removed(wpa_s
, ssid
);
1278 wpa_config_remove_network(wpa_s
->conf
, ssid
->id
);
1283 static int wpas_dpp_process_config(struct wpa_supplicant
*wpa_s
,
1284 struct dpp_authentication
*auth
)
1286 struct wpa_ssid
*ssid
;
1288 if (wpa_s
->conf
->dpp_config_processing
< 1)
1291 ssid
= wpas_dpp_add_network(wpa_s
, auth
);
1295 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_NETWORK_ID
"%d", ssid
->id
);
1296 if (wpa_s
->conf
->dpp_config_processing
== 2)
1299 #ifndef CONFIG_NO_CONFIG_WRITE
1300 if (wpa_s
->conf
->update_config
&&
1301 wpa_config_write(wpa_s
->confname
, wpa_s
->conf
))
1302 wpa_printf(MSG_DEBUG
, "DPP: Failed to update configuration");
1303 #endif /* CONFIG_NO_CONFIG_WRITE */
1305 if (wpa_s
->conf
->dpp_config_processing
< 2)
1309 if (auth
->peer_version
>= 2) {
1310 wpa_printf(MSG_DEBUG
,
1311 "DPP: Postpone connection attempt to wait for completion of DPP Configuration Result");
1312 auth
->connect_on_tx_status
= 1;
1315 #endif /* CONFIG_DPP2 */
1317 wpas_dpp_try_to_connect(wpa_s
);
1322 static int wpas_dpp_handle_config_obj(struct wpa_supplicant
*wpa_s
,
1323 struct dpp_authentication
*auth
)
1325 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_RECEIVED
);
1327 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONFOBJ_SSID
"%s",
1328 wpa_ssid_txt(auth
->ssid
, auth
->ssid_len
));
1329 if (auth
->connector
) {
1330 /* TODO: Save the Connector and consider using a command
1331 * to fetch the value instead of sending an event with
1332 * it. The Connector could end up being larger than what
1333 * most clients are ready to receive as an event
1335 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONNECTOR
"%s",
1338 if (auth
->c_sign_key
) {
1342 hexlen
= 2 * wpabuf_len(auth
->c_sign_key
) + 1;
1343 hex
= os_malloc(hexlen
);
1345 wpa_snprintf_hex(hex
, hexlen
,
1346 wpabuf_head(auth
->c_sign_key
),
1347 wpabuf_len(auth
->c_sign_key
));
1348 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_C_SIGN_KEY
"%s",
1353 if (auth
->net_access_key
) {
1357 hexlen
= 2 * wpabuf_len(auth
->net_access_key
) + 1;
1358 hex
= os_malloc(hexlen
);
1360 wpa_snprintf_hex(hex
, hexlen
,
1361 wpabuf_head(auth
->net_access_key
),
1362 wpabuf_len(auth
->net_access_key
));
1363 if (auth
->net_access_key_expiry
)
1364 wpa_msg(wpa_s
, MSG_INFO
,
1365 DPP_EVENT_NET_ACCESS_KEY
"%s %lu", hex
,
1367 auth
->net_access_key_expiry
);
1369 wpa_msg(wpa_s
, MSG_INFO
,
1370 DPP_EVENT_NET_ACCESS_KEY
"%s", hex
);
1375 return wpas_dpp_process_config(wpa_s
, auth
);
1379 static void wpas_dpp_gas_resp_cb(void *ctx
, const u8
*addr
, u8 dialog_token
,
1380 enum gas_query_result result
,
1381 const struct wpabuf
*adv_proto
,
1382 const struct wpabuf
*resp
, u16 status_code
)
1384 struct wpa_supplicant
*wpa_s
= ctx
;
1386 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1388 enum dpp_status_error status
= DPP_STATUS_CONFIG_REJECTED
;
1390 wpa_s
->dpp_gas_dialog_token
= -1;
1392 if (!auth
|| !auth
->auth_success
) {
1393 wpa_printf(MSG_DEBUG
, "DPP: No matching exchange in progress");
1396 if (result
!= GAS_QUERY_SUCCESS
||
1397 !resp
|| status_code
!= WLAN_STATUS_SUCCESS
) {
1398 wpa_printf(MSG_DEBUG
, "DPP: GAS query did not succeed");
1402 wpa_hexdump_buf(MSG_DEBUG
, "DPP: Configuration Response adv_proto",
1404 wpa_hexdump_buf(MSG_DEBUG
, "DPP: Configuration Response (GAS response)",
1407 if (wpabuf_len(adv_proto
) != 10 ||
1408 !(pos
= wpabuf_head(adv_proto
)) ||
1409 pos
[0] != WLAN_EID_ADV_PROTO
||
1411 pos
[3] != WLAN_EID_VENDOR_SPECIFIC
||
1413 WPA_GET_BE24(&pos
[5]) != OUI_WFA
||
1416 wpa_printf(MSG_DEBUG
,
1417 "DPP: Not a DPP Advertisement Protocol ID");
1421 if (dpp_conf_resp_rx(auth
, resp
) < 0) {
1422 wpa_printf(MSG_DEBUG
, "DPP: Configuration attempt failed");
1426 res
= wpas_dpp_handle_config_obj(wpa_s
, auth
);
1430 status
= DPP_STATUS_OK
;
1432 if (status
!= DPP_STATUS_OK
)
1433 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
1435 if (auth
->peer_version
>= 2 &&
1436 auth
->conf_resp_status
== DPP_STATUS_OK
) {
1439 wpa_printf(MSG_DEBUG
, "DPP: Send DPP Configuration Result");
1440 msg
= dpp_build_conf_result(auth
, status
);
1444 wpa_msg(wpa_s
, MSG_INFO
,
1445 DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1446 MAC2STR(addr
), auth
->curr_freq
,
1447 DPP_PA_CONFIGURATION_RESULT
);
1448 offchannel_send_action(wpa_s
, auth
->curr_freq
,
1449 addr
, wpa_s
->own_addr
, broadcast
,
1452 500, wpas_dpp_tx_status
, 0);
1455 /* This exchange will be terminated in the TX status handler */
1459 #endif /* CONFIG_DPP2 */
1460 dpp_auth_deinit(wpa_s
->dpp_auth
);
1461 wpa_s
->dpp_auth
= NULL
;
1465 static void wpas_dpp_start_gas_client(struct wpa_supplicant
*wpa_s
)
1467 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1468 struct wpabuf
*buf
, *conf_req
;
1472 wpa_s
->dpp_gas_client
= 1;
1473 os_snprintf(json
, sizeof(json
),
1474 "{\"name\":\"Test\","
1475 "\"wi-fi_tech\":\"infra\","
1476 "\"netRole\":\"%s\"}",
1477 wpa_s
->dpp_netrole_ap
? "ap" : "sta");
1478 #ifdef CONFIG_TESTING_OPTIONS
1479 if (dpp_test
== DPP_TEST_INVALID_CONFIG_ATTR_OBJ_CONF_REQ
) {
1480 wpa_printf(MSG_INFO
, "DPP: TESTING - invalid Config Attr");
1481 json
[29] = 'k'; /* replace "infra" with "knfra" */
1483 #endif /* CONFIG_TESTING_OPTIONS */
1484 wpa_printf(MSG_DEBUG
, "DPP: GAS Config Attributes: %s", json
);
1486 offchannel_send_action_done(wpa_s
);
1487 wpas_dpp_listen_stop(wpa_s
);
1489 conf_req
= dpp_build_conf_req(auth
, json
);
1491 wpa_printf(MSG_DEBUG
,
1492 "DPP: No configuration request data available");
1496 buf
= gas_build_initial_req(0, 10 + 2 + wpabuf_len(conf_req
));
1498 wpabuf_free(conf_req
);
1502 /* Advertisement Protocol IE */
1503 wpabuf_put_u8(buf
, WLAN_EID_ADV_PROTO
);
1504 wpabuf_put_u8(buf
, 8); /* Length */
1505 wpabuf_put_u8(buf
, 0x7f);
1506 wpabuf_put_u8(buf
, WLAN_EID_VENDOR_SPECIFIC
);
1507 wpabuf_put_u8(buf
, 5);
1508 wpabuf_put_be24(buf
, OUI_WFA
);
1509 wpabuf_put_u8(buf
, DPP_OUI_TYPE
);
1510 wpabuf_put_u8(buf
, 0x01);
1513 wpabuf_put_le16(buf
, wpabuf_len(conf_req
));
1514 wpabuf_put_buf(buf
, conf_req
);
1515 wpabuf_free(conf_req
);
1517 wpa_printf(MSG_DEBUG
, "DPP: GAS request to " MACSTR
" (freq %u MHz)",
1518 MAC2STR(auth
->peer_mac_addr
), auth
->curr_freq
);
1520 res
= gas_query_req(wpa_s
->gas
, auth
->peer_mac_addr
, auth
->curr_freq
,
1521 1, buf
, wpas_dpp_gas_resp_cb
, wpa_s
);
1523 wpa_msg(wpa_s
, MSG_DEBUG
, "GAS: Failed to send Query Request");
1526 wpa_printf(MSG_DEBUG
,
1527 "DPP: GAS query started with dialog token %u", res
);
1528 wpa_s
->dpp_gas_dialog_token
= res
;
1533 static void wpas_dpp_auth_success(struct wpa_supplicant
*wpa_s
, int initiator
)
1535 wpa_printf(MSG_DEBUG
, "DPP: Authentication succeeded");
1536 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_AUTH_SUCCESS
"init=%d", initiator
);
1537 #ifdef CONFIG_TESTING_OPTIONS
1538 if (dpp_test
== DPP_TEST_STOP_AT_AUTH_CONF
) {
1539 wpa_printf(MSG_INFO
,
1540 "DPP: TESTING - stop at Authentication Confirm");
1541 if (wpa_s
->dpp_auth
->configurator
) {
1542 /* Prevent GAS response */
1543 wpa_s
->dpp_auth
->auth_success
= 0;
1547 #endif /* CONFIG_TESTING_OPTIONS */
1549 if (wpa_s
->dpp_auth
->configurator
)
1550 wpas_dpp_start_gas_server(wpa_s
);
1552 wpas_dpp_start_gas_client(wpa_s
);
1556 static void wpas_dpp_rx_auth_resp(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1557 const u8
*hdr
, const u8
*buf
, size_t len
,
1560 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1563 wpa_printf(MSG_DEBUG
, "DPP: Authentication Response from " MACSTR
1564 " (freq %u MHz)", MAC2STR(src
), freq
);
1567 wpa_printf(MSG_DEBUG
,
1568 "DPP: No DPP Authentication in progress - drop");
1572 if (!is_zero_ether_addr(auth
->peer_mac_addr
) &&
1573 os_memcmp(src
, auth
->peer_mac_addr
, ETH_ALEN
) != 0) {
1574 wpa_printf(MSG_DEBUG
, "DPP: MAC address mismatch (expected "
1575 MACSTR
") - drop", MAC2STR(auth
->peer_mac_addr
));
1579 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
1581 if (auth
->curr_freq
!= freq
&& auth
->neg_freq
== freq
) {
1582 wpa_printf(MSG_DEBUG
,
1583 "DPP: Responder accepted request for different negotiation channel");
1584 auth
->curr_freq
= freq
;
1587 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
1588 msg
= dpp_auth_resp_rx(auth
, hdr
, buf
, len
);
1590 if (auth
->auth_resp_status
== DPP_STATUS_RESPONSE_PENDING
) {
1591 wpa_printf(MSG_DEBUG
,
1592 "DPP: Start wait for full response");
1593 offchannel_send_action_done(wpa_s
);
1594 wpas_dpp_listen_start(wpa_s
, auth
->curr_freq
);
1597 wpa_printf(MSG_DEBUG
, "DPP: No confirm generated");
1600 os_memcpy(auth
->peer_mac_addr
, src
, ETH_ALEN
);
1602 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1603 MAC2STR(src
), auth
->curr_freq
, DPP_PA_AUTHENTICATION_CONF
);
1604 offchannel_send_action(wpa_s
, auth
->curr_freq
,
1605 src
, wpa_s
->own_addr
, broadcast
,
1606 wpabuf_head(msg
), wpabuf_len(msg
),
1607 500, wpas_dpp_tx_status
, 0);
1609 wpa_s
->dpp_auth_ok_on_ack
= 1;
1613 static void wpas_dpp_rx_auth_conf(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1614 const u8
*hdr
, const u8
*buf
, size_t len
)
1616 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1618 wpa_printf(MSG_DEBUG
, "DPP: Authentication Confirmation from " MACSTR
,
1622 wpa_printf(MSG_DEBUG
,
1623 "DPP: No DPP Authentication in progress - drop");
1627 if (os_memcmp(src
, auth
->peer_mac_addr
, ETH_ALEN
) != 0) {
1628 wpa_printf(MSG_DEBUG
, "DPP: MAC address mismatch (expected "
1629 MACSTR
") - drop", MAC2STR(auth
->peer_mac_addr
));
1633 if (dpp_auth_conf_rx(auth
, hdr
, buf
, len
) < 0) {
1634 wpa_printf(MSG_DEBUG
, "DPP: Authentication failed");
1638 wpas_dpp_auth_success(wpa_s
, 0);
1644 static void wpas_dpp_config_result_wait_timeout(void *eloop_ctx
,
1647 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
1648 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1650 if (!auth
|| !auth
->waiting_conf_result
)
1653 wpa_printf(MSG_DEBUG
,
1654 "DPP: Timeout while waiting for Configuration Result");
1655 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
1656 dpp_auth_deinit(auth
);
1657 wpa_s
->dpp_auth
= NULL
;
1661 static void wpas_dpp_rx_conf_result(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1662 const u8
*hdr
, const u8
*buf
, size_t len
)
1664 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1665 enum dpp_status_error status
;
1667 wpa_printf(MSG_DEBUG
, "DPP: Configuration Result from " MACSTR
,
1670 if (!auth
|| !auth
->waiting_conf_result
) {
1671 wpa_printf(MSG_DEBUG
,
1672 "DPP: No DPP Configuration waiting for result - drop");
1676 if (os_memcmp(src
, auth
->peer_mac_addr
, ETH_ALEN
) != 0) {
1677 wpa_printf(MSG_DEBUG
, "DPP: MAC address mismatch (expected "
1678 MACSTR
") - drop", MAC2STR(auth
->peer_mac_addr
));
1682 status
= dpp_conf_result_rx(auth
, hdr
, buf
, len
);
1684 offchannel_send_action_done(wpa_s
);
1685 wpas_dpp_listen_stop(wpa_s
);
1686 if (status
== DPP_STATUS_OK
)
1687 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_SENT
);
1689 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
1690 dpp_auth_deinit(auth
);
1691 wpa_s
->dpp_auth
= NULL
;
1692 eloop_cancel_timeout(wpas_dpp_config_result_wait_timeout
, wpa_s
, NULL
);
1695 #endif /* CONFIG_DPP2 */
1698 static void wpas_dpp_rx_peer_disc_resp(struct wpa_supplicant
*wpa_s
,
1700 const u8
*buf
, size_t len
)
1702 struct wpa_ssid
*ssid
;
1703 const u8
*connector
, *trans_id
, *status
;
1704 u16 connector_len
, trans_id_len
, status_len
;
1705 struct dpp_introduction intro
;
1706 struct rsn_pmksa_cache_entry
*entry
;
1708 struct os_reltime rnow
;
1710 unsigned int seconds
;
1711 enum dpp_status_error res
;
1713 wpa_printf(MSG_DEBUG
, "DPP: Peer Discovery Response from " MACSTR
,
1715 if (is_zero_ether_addr(wpa_s
->dpp_intro_bssid
) ||
1716 os_memcmp(src
, wpa_s
->dpp_intro_bssid
, ETH_ALEN
) != 0) {
1717 wpa_printf(MSG_DEBUG
, "DPP: Not waiting for response from "
1718 MACSTR
" - drop", MAC2STR(src
));
1721 offchannel_send_action_done(wpa_s
);
1723 for (ssid
= wpa_s
->conf
->ssid
; ssid
; ssid
= ssid
->next
) {
1724 if (ssid
== wpa_s
->dpp_intro_network
)
1727 if (!ssid
|| !ssid
->dpp_connector
|| !ssid
->dpp_netaccesskey
||
1729 wpa_printf(MSG_DEBUG
,
1730 "DPP: Profile not found for network introduction");
1734 trans_id
= dpp_get_attr(buf
, len
, DPP_ATTR_TRANSACTION_ID
,
1736 if (!trans_id
|| trans_id_len
!= 1) {
1737 wpa_printf(MSG_DEBUG
,
1738 "DPP: Peer did not include Transaction ID");
1739 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1740 " fail=missing_transaction_id", MAC2STR(src
));
1743 if (trans_id
[0] != TRANSACTION_ID
) {
1744 wpa_printf(MSG_DEBUG
,
1745 "DPP: Ignore frame with unexpected Transaction ID %u",
1747 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1748 " fail=transaction_id_mismatch", MAC2STR(src
));
1752 status
= dpp_get_attr(buf
, len
, DPP_ATTR_STATUS
, &status_len
);
1753 if (!status
|| status_len
!= 1) {
1754 wpa_printf(MSG_DEBUG
, "DPP: Peer did not include Status");
1755 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1756 " fail=missing_status", MAC2STR(src
));
1759 if (status
[0] != DPP_STATUS_OK
) {
1760 wpa_printf(MSG_DEBUG
,
1761 "DPP: Peer rejected network introduction: Status %u",
1763 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1764 " status=%u", MAC2STR(src
), status
[0]);
1768 connector
= dpp_get_attr(buf
, len
, DPP_ATTR_CONNECTOR
, &connector_len
);
1770 wpa_printf(MSG_DEBUG
,
1771 "DPP: Peer did not include its Connector");
1772 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1773 " fail=missing_connector", MAC2STR(src
));
1777 res
= dpp_peer_intro(&intro
, ssid
->dpp_connector
,
1778 ssid
->dpp_netaccesskey
,
1779 ssid
->dpp_netaccesskey_len
,
1781 ssid
->dpp_csign_len
,
1782 connector
, connector_len
, &expiry
);
1783 if (res
!= DPP_STATUS_OK
) {
1784 wpa_printf(MSG_INFO
,
1785 "DPP: Network Introduction protocol resulted in failure");
1786 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1787 " fail=peer_connector_validation_failed", MAC2STR(src
));
1791 entry
= os_zalloc(sizeof(*entry
));
1794 os_memcpy(entry
->aa
, src
, ETH_ALEN
);
1795 os_memcpy(entry
->pmkid
, intro
.pmkid
, PMKID_LEN
);
1796 os_memcpy(entry
->pmk
, intro
.pmk
, intro
.pmk_len
);
1797 entry
->pmk_len
= intro
.pmk_len
;
1798 entry
->akmp
= WPA_KEY_MGMT_DPP
;
1801 seconds
= expiry
- now
.sec
;
1803 seconds
= 86400 * 7;
1805 os_get_reltime(&rnow
);
1806 entry
->expiration
= rnow
.sec
+ seconds
;
1807 entry
->reauth_time
= rnow
.sec
+ seconds
;
1808 entry
->network_ctx
= ssid
;
1809 wpa_sm_pmksa_cache_add_entry(wpa_s
->wpa
, entry
);
1811 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1812 " status=%u", MAC2STR(src
), status
[0]);
1814 wpa_printf(MSG_DEBUG
,
1815 "DPP: Try connection again after successful network introduction");
1816 if (wpa_supplicant_fast_associate(wpa_s
) != 1) {
1817 wpa_supplicant_cancel_sched_scan(wpa_s
);
1818 wpa_supplicant_req_scan(wpa_s
, 0, 0);
1821 os_memset(&intro
, 0, sizeof(intro
));
1825 static int wpas_dpp_allow_ir(struct wpa_supplicant
*wpa_s
, unsigned int freq
)
1829 if (!wpa_s
->hw
.modes
)
1832 for (i
= 0; i
< wpa_s
->hw
.num_modes
; i
++) {
1833 struct hostapd_hw_modes
*mode
= &wpa_s
->hw
.modes
[i
];
1835 for (j
= 0; j
< mode
->num_channels
; j
++) {
1836 struct hostapd_channel_data
*chan
= &mode
->channels
[j
];
1838 if (chan
->freq
!= (int) freq
)
1841 if (chan
->flag
& (HOSTAPD_CHAN_DISABLED
|
1842 HOSTAPD_CHAN_NO_IR
|
1843 HOSTAPD_CHAN_RADAR
))
1850 wpa_printf(MSG_DEBUG
,
1851 "DPP: Frequency %u MHz not supported or does not allow PKEX initiation in the current channel list",
1858 static int wpas_dpp_pkex_next_channel(struct wpa_supplicant
*wpa_s
,
1859 struct dpp_pkex
*pkex
)
1861 if (pkex
->freq
== 2437)
1863 else if (pkex
->freq
== 5745)
1865 else if (pkex
->freq
== 5220)
1868 return -1; /* no more channels to try */
1870 if (wpas_dpp_allow_ir(wpa_s
, pkex
->freq
) == 1) {
1871 wpa_printf(MSG_DEBUG
, "DPP: Try to initiate on %u MHz",
1876 /* Could not use this channel - try the next one */
1877 return wpas_dpp_pkex_next_channel(wpa_s
, pkex
);
1881 static void wpas_dpp_pkex_retry_timeout(void *eloop_ctx
, void *timeout_ctx
)
1883 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
1884 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
1886 if (!pkex
|| !pkex
->exchange_req
)
1888 if (pkex
->exch_req_tries
>= 5) {
1889 if (wpas_dpp_pkex_next_channel(wpa_s
, pkex
) < 0) {
1890 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
1891 "No response from PKEX peer");
1892 dpp_pkex_free(pkex
);
1893 wpa_s
->dpp_pkex
= NULL
;
1896 pkex
->exch_req_tries
= 0;
1899 pkex
->exch_req_tries
++;
1900 wpa_printf(MSG_DEBUG
, "DPP: Retransmit PKEX Exchange Request (try %u)",
1901 pkex
->exch_req_tries
);
1902 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1903 MAC2STR(broadcast
), pkex
->freq
, DPP_PA_PKEX_EXCHANGE_REQ
);
1904 offchannel_send_action(wpa_s
, pkex
->freq
, broadcast
,
1905 wpa_s
->own_addr
, broadcast
,
1906 wpabuf_head(pkex
->exchange_req
),
1907 wpabuf_len(pkex
->exchange_req
),
1908 pkex
->exch_req_wait_time
,
1909 wpas_dpp_tx_pkex_status
, 0);
1914 wpas_dpp_tx_pkex_status(struct wpa_supplicant
*wpa_s
,
1915 unsigned int freq
, const u8
*dst
,
1916 const u8
*src
, const u8
*bssid
,
1917 const u8
*data
, size_t data_len
,
1918 enum offchannel_send_action_result result
)
1920 const char *res_txt
;
1921 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
1923 res_txt
= result
== OFFCHANNEL_SEND_ACTION_SUCCESS
? "SUCCESS" :
1924 (result
== OFFCHANNEL_SEND_ACTION_NO_ACK
? "no-ACK" :
1926 wpa_printf(MSG_DEBUG
, "DPP: TX status: freq=%u dst=" MACSTR
1927 " result=%s (PKEX)",
1928 freq
, MAC2STR(dst
), res_txt
);
1929 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX_STATUS
"dst=" MACSTR
1930 " freq=%u result=%s", MAC2STR(dst
), freq
, res_txt
);
1933 wpa_printf(MSG_DEBUG
,
1934 "DPP: Ignore TX status since there is no ongoing PKEX exchange");
1939 wpa_printf(MSG_DEBUG
,
1940 "DPP: Terminate PKEX exchange due to an earlier error");
1941 if (pkex
->t
> pkex
->own_bi
->pkex_t
)
1942 pkex
->own_bi
->pkex_t
= pkex
->t
;
1943 dpp_pkex_free(pkex
);
1944 wpa_s
->dpp_pkex
= NULL
;
1948 if (pkex
->exch_req_wait_time
&& pkex
->exchange_req
) {
1949 /* Wait for PKEX Exchange Response frame and retry request if
1950 * no response is seen. */
1951 eloop_cancel_timeout(wpas_dpp_pkex_retry_timeout
, wpa_s
, NULL
);
1952 eloop_register_timeout(pkex
->exch_req_wait_time
/ 1000,
1953 (pkex
->exch_req_wait_time
% 1000) * 1000,
1954 wpas_dpp_pkex_retry_timeout
, wpa_s
,
1961 wpas_dpp_rx_pkex_exchange_req(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1962 const u8
*buf
, size_t len
, unsigned int freq
)
1965 unsigned int wait_time
;
1967 wpa_printf(MSG_DEBUG
, "DPP: PKEX Exchange Request from " MACSTR
,
1970 /* TODO: Support multiple PKEX codes by iterating over all the enabled
1973 if (!wpa_s
->dpp_pkex_code
|| !wpa_s
->dpp_pkex_bi
) {
1974 wpa_printf(MSG_DEBUG
,
1975 "DPP: No PKEX code configured - ignore request");
1979 if (wpa_s
->dpp_pkex
) {
1980 /* TODO: Support parallel operations */
1981 wpa_printf(MSG_DEBUG
,
1982 "DPP: Already in PKEX session - ignore new request");
1986 wpa_s
->dpp_pkex
= dpp_pkex_rx_exchange_req(wpa_s
, wpa_s
->dpp_pkex_bi
,
1987 wpa_s
->own_addr
, src
,
1988 wpa_s
->dpp_pkex_identifier
,
1989 wpa_s
->dpp_pkex_code
,
1991 if (!wpa_s
->dpp_pkex
) {
1992 wpa_printf(MSG_DEBUG
,
1993 "DPP: Failed to process the request - ignore it");
1997 msg
= wpa_s
->dpp_pkex
->exchange_resp
;
1998 wait_time
= wpa_s
->max_remain_on_chan
;
1999 if (wait_time
> 2000)
2001 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
2002 MAC2STR(src
), freq
, DPP_PA_PKEX_EXCHANGE_RESP
);
2003 offchannel_send_action(wpa_s
, freq
, src
, wpa_s
->own_addr
,
2005 wpabuf_head(msg
), wpabuf_len(msg
),
2006 wait_time
, wpas_dpp_tx_pkex_status
, 0);
2011 wpas_dpp_rx_pkex_exchange_resp(struct wpa_supplicant
*wpa_s
, const u8
*src
,
2012 const u8
*buf
, size_t len
, unsigned int freq
)
2015 unsigned int wait_time
;
2017 wpa_printf(MSG_DEBUG
, "DPP: PKEX Exchange Response from " MACSTR
,
2020 /* TODO: Support multiple PKEX codes by iterating over all the enabled
2023 if (!wpa_s
->dpp_pkex
|| !wpa_s
->dpp_pkex
->initiator
||
2024 wpa_s
->dpp_pkex
->exchange_done
) {
2025 wpa_printf(MSG_DEBUG
, "DPP: No matching PKEX session");
2029 eloop_cancel_timeout(wpas_dpp_pkex_retry_timeout
, wpa_s
, NULL
);
2030 wpa_s
->dpp_pkex
->exch_req_wait_time
= 0;
2032 msg
= dpp_pkex_rx_exchange_resp(wpa_s
->dpp_pkex
, src
, buf
, len
);
2034 wpa_printf(MSG_DEBUG
, "DPP: Failed to process the response");
2038 wpa_printf(MSG_DEBUG
, "DPP: Send PKEX Commit-Reveal Request to " MACSTR
,
2041 wait_time
= wpa_s
->max_remain_on_chan
;
2042 if (wait_time
> 2000)
2044 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
2045 MAC2STR(src
), freq
, DPP_PA_PKEX_COMMIT_REVEAL_REQ
);
2046 offchannel_send_action(wpa_s
, freq
, src
, wpa_s
->own_addr
,
2048 wpabuf_head(msg
), wpabuf_len(msg
),
2049 wait_time
, wpas_dpp_tx_pkex_status
, 0);
2054 static struct dpp_bootstrap_info
*
2055 wpas_dpp_pkex_finish(struct wpa_supplicant
*wpa_s
, const u8
*peer
,
2058 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
2059 struct dpp_bootstrap_info
*bi
;
2061 bi
= os_zalloc(sizeof(*bi
));
2064 bi
->id
= wpas_dpp_next_id(wpa_s
);
2065 bi
->type
= DPP_BOOTSTRAP_PKEX
;
2066 os_memcpy(bi
->mac_addr
, peer
, ETH_ALEN
);
2069 bi
->curve
= pkex
->own_bi
->curve
;
2070 bi
->pubkey
= pkex
->peer_bootstrap_key
;
2071 pkex
->peer_bootstrap_key
= NULL
;
2072 dpp_pkex_free(pkex
);
2073 wpa_s
->dpp_pkex
= NULL
;
2074 if (dpp_bootstrap_key_hash(bi
) < 0) {
2075 dpp_bootstrap_info_free(bi
);
2078 dl_list_add(&wpa_s
->dpp_bootstrap
, &bi
->list
);
2084 wpas_dpp_rx_pkex_commit_reveal_req(struct wpa_supplicant
*wpa_s
, const u8
*src
,
2085 const u8
*hdr
, const u8
*buf
, size_t len
,
2089 unsigned int wait_time
;
2090 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
2092 wpa_printf(MSG_DEBUG
, "DPP: PKEX Commit-Reveal Request from " MACSTR
,
2095 if (!pkex
|| pkex
->initiator
|| !pkex
->exchange_done
) {
2096 wpa_printf(MSG_DEBUG
, "DPP: No matching PKEX session");
2100 msg
= dpp_pkex_rx_commit_reveal_req(pkex
, hdr
, buf
, len
);
2102 wpa_printf(MSG_DEBUG
, "DPP: Failed to process the request");
2104 wpa_printf(MSG_DEBUG
, "DPP: Terminate PKEX exchange");
2105 if (pkex
->t
> pkex
->own_bi
->pkex_t
)
2106 pkex
->own_bi
->pkex_t
= pkex
->t
;
2107 dpp_pkex_free(wpa_s
->dpp_pkex
);
2108 wpa_s
->dpp_pkex
= NULL
;
2113 wpa_printf(MSG_DEBUG
, "DPP: Send PKEX Commit-Reveal Response to "
2114 MACSTR
, MAC2STR(src
));
2116 wait_time
= wpa_s
->max_remain_on_chan
;
2117 if (wait_time
> 2000)
2119 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
2120 MAC2STR(src
), freq
, DPP_PA_PKEX_COMMIT_REVEAL_RESP
);
2121 offchannel_send_action(wpa_s
, freq
, src
, wpa_s
->own_addr
,
2123 wpabuf_head(msg
), wpabuf_len(msg
),
2124 wait_time
, wpas_dpp_tx_pkex_status
, 0);
2127 wpas_dpp_pkex_finish(wpa_s
, src
, freq
);
2132 wpas_dpp_rx_pkex_commit_reveal_resp(struct wpa_supplicant
*wpa_s
, const u8
*src
,
2133 const u8
*hdr
, const u8
*buf
, size_t len
,
2137 struct dpp_bootstrap_info
*bi
;
2138 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
2141 wpa_printf(MSG_DEBUG
, "DPP: PKEX Commit-Reveal Response from " MACSTR
,
2144 if (!pkex
|| !pkex
->initiator
|| !pkex
->exchange_done
) {
2145 wpa_printf(MSG_DEBUG
, "DPP: No matching PKEX session");
2149 res
= dpp_pkex_rx_commit_reveal_resp(pkex
, hdr
, buf
, len
);
2151 wpa_printf(MSG_DEBUG
, "DPP: Failed to process the response");
2155 bi
= wpas_dpp_pkex_finish(wpa_s
, src
, freq
);
2159 os_snprintf(cmd
, sizeof(cmd
), " peer=%u %s",
2161 wpa_s
->dpp_pkex_auth_cmd
? wpa_s
->dpp_pkex_auth_cmd
: "");
2162 wpa_printf(MSG_DEBUG
,
2163 "DPP: Start authentication after PKEX with parameters: %s",
2165 if (wpas_dpp_auth_init(wpa_s
, cmd
) < 0) {
2166 wpa_printf(MSG_DEBUG
,
2167 "DPP: Authentication initialization failed");
2173 void wpas_dpp_rx_action(struct wpa_supplicant
*wpa_s
, const u8
*src
,
2174 const u8
*buf
, size_t len
, unsigned int freq
)
2177 enum dpp_public_action_frame_type type
;
2179 unsigned int pkex_t
;
2181 if (len
< DPP_HDR_LEN
)
2183 if (WPA_GET_BE24(buf
) != OUI_WFA
|| buf
[3] != DPP_OUI_TYPE
)
2188 crypto_suite
= *buf
++;
2192 wpa_printf(MSG_DEBUG
,
2193 "DPP: Received DPP Public Action frame crypto suite %u type %d from "
2195 crypto_suite
, type
, MAC2STR(src
), freq
);
2196 if (crypto_suite
!= 1) {
2197 wpa_printf(MSG_DEBUG
, "DPP: Unsupported crypto suite %u",
2199 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_RX
"src=" MACSTR
2200 " freq=%u type=%d ignore=unsupported-crypto-suite",
2201 MAC2STR(src
), freq
, type
);
2204 wpa_hexdump(MSG_MSGDUMP
, "DPP: Received message attributes", buf
, len
);
2205 if (dpp_check_attrs(buf
, len
) < 0) {
2206 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_RX
"src=" MACSTR
2207 " freq=%u type=%d ignore=invalid-attributes",
2208 MAC2STR(src
), freq
, type
);
2211 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_RX
"src=" MACSTR
" freq=%u type=%d",
2212 MAC2STR(src
), freq
, type
);
2215 case DPP_PA_AUTHENTICATION_REQ
:
2216 wpas_dpp_rx_auth_req(wpa_s
, src
, hdr
, buf
, len
, freq
);
2218 case DPP_PA_AUTHENTICATION_RESP
:
2219 wpas_dpp_rx_auth_resp(wpa_s
, src
, hdr
, buf
, len
, freq
);
2221 case DPP_PA_AUTHENTICATION_CONF
:
2222 wpas_dpp_rx_auth_conf(wpa_s
, src
, hdr
, buf
, len
);
2224 case DPP_PA_PEER_DISCOVERY_RESP
:
2225 wpas_dpp_rx_peer_disc_resp(wpa_s
, src
, buf
, len
);
2227 case DPP_PA_PKEX_EXCHANGE_REQ
:
2228 wpas_dpp_rx_pkex_exchange_req(wpa_s
, src
, buf
, len
, freq
);
2230 case DPP_PA_PKEX_EXCHANGE_RESP
:
2231 wpas_dpp_rx_pkex_exchange_resp(wpa_s
, src
, buf
, len
, freq
);
2233 case DPP_PA_PKEX_COMMIT_REVEAL_REQ
:
2234 wpas_dpp_rx_pkex_commit_reveal_req(wpa_s
, src
, hdr
, buf
, len
,
2237 case DPP_PA_PKEX_COMMIT_REVEAL_RESP
:
2238 wpas_dpp_rx_pkex_commit_reveal_resp(wpa_s
, src
, hdr
, buf
, len
,
2242 case DPP_PA_CONFIGURATION_RESULT
:
2243 wpas_dpp_rx_conf_result(wpa_s
, src
, hdr
, buf
, len
);
2245 #endif /* CONFIG_DPP2 */
2247 wpa_printf(MSG_DEBUG
,
2248 "DPP: Ignored unsupported frame subtype %d", type
);
2252 if (wpa_s
->dpp_pkex
)
2253 pkex_t
= wpa_s
->dpp_pkex
->t
;
2254 else if (wpa_s
->dpp_pkex_bi
)
2255 pkex_t
= wpa_s
->dpp_pkex_bi
->pkex_t
;
2258 if (pkex_t
>= PKEX_COUNTER_T_LIMIT
) {
2259 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_PKEX_T_LIMIT
"id=0");
2260 wpas_dpp_pkex_remove(wpa_s
, "*");
2265 static struct wpabuf
*
2266 wpas_dpp_gas_req_handler(void *ctx
, const u8
*sa
, const u8
*query
,
2269 struct wpa_supplicant
*wpa_s
= ctx
;
2270 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
2271 struct wpabuf
*resp
;
2273 wpa_printf(MSG_DEBUG
, "DPP: GAS request from " MACSTR
,
2275 if (!auth
|| !auth
->auth_success
||
2276 os_memcmp(sa
, auth
->peer_mac_addr
, ETH_ALEN
) != 0) {
2277 wpa_printf(MSG_DEBUG
, "DPP: No matching exchange in progress");
2280 wpa_hexdump(MSG_DEBUG
,
2281 "DPP: Received Configuration Request (GAS Query Request)",
2283 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_REQ_RX
"src=" MACSTR
,
2285 resp
= dpp_conf_req_rx(auth
, query
, query_len
);
2287 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
2288 auth
->conf_resp
= resp
;
2294 wpas_dpp_gas_status_handler(void *ctx
, struct wpabuf
*resp
, int ok
)
2296 struct wpa_supplicant
*wpa_s
= ctx
;
2297 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
2303 if (auth
->conf_resp
!= resp
) {
2304 wpa_printf(MSG_DEBUG
,
2305 "DPP: Ignore GAS status report (ok=%d) for unknown response",
2311 wpa_printf(MSG_DEBUG
, "DPP: Configuration exchange completed (ok=%d)",
2313 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
2314 eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout
, wpa_s
, NULL
);
2316 if (ok
&& auth
->peer_version
>= 2 &&
2317 auth
->conf_resp_status
== DPP_STATUS_OK
) {
2318 wpa_printf(MSG_DEBUG
, "DPP: Wait for Configuration Result");
2319 auth
->waiting_conf_result
= 1;
2320 auth
->conf_resp
= NULL
;
2322 eloop_cancel_timeout(wpas_dpp_config_result_wait_timeout
,
2324 eloop_register_timeout(2, 0,
2325 wpas_dpp_config_result_wait_timeout
,
2329 #endif /* CONFIG_DPP2 */
2330 offchannel_send_action_done(wpa_s
);
2331 wpas_dpp_listen_stop(wpa_s
);
2333 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_SENT
);
2335 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
2336 dpp_auth_deinit(wpa_s
->dpp_auth
);
2337 wpa_s
->dpp_auth
= NULL
;
2342 static unsigned int wpas_dpp_next_configurator_id(struct wpa_supplicant
*wpa_s
)
2344 struct dpp_configurator
*conf
;
2345 unsigned int max_id
= 0;
2347 dl_list_for_each(conf
, &wpa_s
->dpp_configurator
,
2348 struct dpp_configurator
, list
) {
2349 if (conf
->id
> max_id
)
2356 int wpas_dpp_configurator_add(struct wpa_supplicant
*wpa_s
, const char *cmd
)
2361 size_t privkey_len
= 0;
2363 struct dpp_configurator
*conf
= NULL
;
2365 curve
= get_param(cmd
, " curve=");
2366 key
= get_param(cmd
, " key=");
2369 privkey_len
= os_strlen(key
) / 2;
2370 privkey
= os_malloc(privkey_len
);
2372 hexstr2bin(key
, privkey
, privkey_len
) < 0)
2376 conf
= dpp_keygen_configurator(curve
, privkey
, privkey_len
);
2380 conf
->id
= wpas_dpp_next_configurator_id(wpa_s
);
2381 dl_list_add(&wpa_s
->dpp_configurator
, &conf
->list
);
2386 str_clear_free(key
);
2387 bin_clear_free(privkey
, privkey_len
);
2388 dpp_configurator_free(conf
);
2393 static int dpp_configurator_del(struct wpa_supplicant
*wpa_s
, unsigned int id
)
2395 struct dpp_configurator
*conf
, *tmp
;
2398 dl_list_for_each_safe(conf
, tmp
, &wpa_s
->dpp_configurator
,
2399 struct dpp_configurator
, list
) {
2400 if (id
&& conf
->id
!= id
)
2403 dl_list_del(&conf
->list
);
2404 dpp_configurator_free(conf
);
2408 return 0; /* flush succeeds regardless of entries found */
2409 return found
? 0 : -1;
2413 int wpas_dpp_configurator_remove(struct wpa_supplicant
*wpa_s
, const char *id
)
2415 unsigned int id_val
;
2417 if (os_strcmp(id
, "*") == 0) {
2425 return dpp_configurator_del(wpa_s
, id_val
);
2429 int wpas_dpp_configurator_sign(struct wpa_supplicant
*wpa_s
, const char *cmd
)
2431 struct dpp_authentication
*auth
;
2435 auth
= os_zalloc(sizeof(*auth
));
2439 curve
= get_param(cmd
, " curve=");
2440 wpas_dpp_set_testing_options(wpa_s
, auth
);
2441 if (wpas_dpp_set_configurator(wpa_s
, auth
, cmd
) == 0 &&
2442 dpp_configurator_own_config(auth
, curve
, 0) == 0)
2443 ret
= wpas_dpp_handle_config_obj(wpa_s
, auth
);
2445 dpp_auth_deinit(auth
);
2452 int wpas_dpp_configurator_get_key(struct wpa_supplicant
*wpa_s
, unsigned int id
,
2453 char *buf
, size_t buflen
)
2455 struct dpp_configurator
*conf
;
2457 conf
= dpp_configurator_get_id(wpa_s
, id
);
2461 return dpp_configurator_get_key(conf
, buf
, buflen
);
2466 wpas_dpp_tx_introduction_status(struct wpa_supplicant
*wpa_s
,
2467 unsigned int freq
, const u8
*dst
,
2468 const u8
*src
, const u8
*bssid
,
2469 const u8
*data
, size_t data_len
,
2470 enum offchannel_send_action_result result
)
2472 const char *res_txt
;
2474 res_txt
= result
== OFFCHANNEL_SEND_ACTION_SUCCESS
? "SUCCESS" :
2475 (result
== OFFCHANNEL_SEND_ACTION_NO_ACK
? "no-ACK" :
2477 wpa_printf(MSG_DEBUG
, "DPP: TX status: freq=%u dst=" MACSTR
2478 " result=%s (DPP Peer Discovery Request)",
2479 freq
, MAC2STR(dst
), res_txt
);
2480 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX_STATUS
"dst=" MACSTR
2481 " freq=%u result=%s", MAC2STR(dst
), freq
, res_txt
);
2482 /* TODO: Time out wait for response more quickly in error cases? */
2486 int wpas_dpp_check_connect(struct wpa_supplicant
*wpa_s
, struct wpa_ssid
*ssid
,
2487 struct wpa_bss
*bss
)
2491 unsigned int wait_time
;
2493 if (!(ssid
->key_mgmt
& WPA_KEY_MGMT_DPP
) || !bss
)
2494 return 0; /* Not using DPP AKM - continue */
2495 if (wpa_sm_pmksa_exists(wpa_s
->wpa
, bss
->bssid
, ssid
))
2496 return 0; /* PMKSA exists for DPP AKM - continue */
2498 if (!ssid
->dpp_connector
|| !ssid
->dpp_netaccesskey
||
2500 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_MISSING_CONNECTOR
2502 !ssid
->dpp_connector
? "Connector" :
2503 (!ssid
->dpp_netaccesskey
? "netAccessKey" :
2510 if (ssid
->dpp_netaccesskey_expiry
&&
2511 (os_time_t
) ssid
->dpp_netaccesskey_expiry
< now
.sec
) {
2512 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_MISSING_CONNECTOR
2513 "netAccessKey expired");
2517 wpa_printf(MSG_DEBUG
,
2518 "DPP: Starting network introduction protocol to derive PMKSA for "
2519 MACSTR
, MAC2STR(bss
->bssid
));
2521 msg
= dpp_alloc_msg(DPP_PA_PEER_DISCOVERY_REQ
,
2522 5 + 4 + os_strlen(ssid
->dpp_connector
));
2526 #ifdef CONFIG_TESTING_OPTIONS
2527 if (dpp_test
== DPP_TEST_NO_TRANSACTION_ID_PEER_DISC_REQ
) {
2528 wpa_printf(MSG_INFO
, "DPP: TESTING - no Transaction ID");
2531 if (dpp_test
== DPP_TEST_INVALID_TRANSACTION_ID_PEER_DISC_REQ
) {
2532 wpa_printf(MSG_INFO
, "DPP: TESTING - invalid Transaction ID");
2533 wpabuf_put_le16(msg
, DPP_ATTR_TRANSACTION_ID
);
2534 wpabuf_put_le16(msg
, 0);
2537 #endif /* CONFIG_TESTING_OPTIONS */
2539 /* Transaction ID */
2540 wpabuf_put_le16(msg
, DPP_ATTR_TRANSACTION_ID
);
2541 wpabuf_put_le16(msg
, 1);
2542 wpabuf_put_u8(msg
, TRANSACTION_ID
);
2544 #ifdef CONFIG_TESTING_OPTIONS
2546 if (dpp_test
== DPP_TEST_NO_CONNECTOR_PEER_DISC_REQ
) {
2547 wpa_printf(MSG_INFO
, "DPP: TESTING - no Connector");
2548 goto skip_connector
;
2550 if (dpp_test
== DPP_TEST_INVALID_CONNECTOR_PEER_DISC_REQ
) {
2553 wpa_printf(MSG_INFO
, "DPP: TESTING - invalid Connector");
2554 connector
= dpp_corrupt_connector_signature(
2555 ssid
->dpp_connector
);
2560 wpabuf_put_le16(msg
, DPP_ATTR_CONNECTOR
);
2561 wpabuf_put_le16(msg
, os_strlen(connector
));
2562 wpabuf_put_str(msg
, connector
);
2564 goto skip_connector
;
2566 #endif /* CONFIG_TESTING_OPTIONS */
2569 wpabuf_put_le16(msg
, DPP_ATTR_CONNECTOR
);
2570 wpabuf_put_le16(msg
, os_strlen(ssid
->dpp_connector
));
2571 wpabuf_put_str(msg
, ssid
->dpp_connector
);
2573 #ifdef CONFIG_TESTING_OPTIONS
2575 #endif /* CONFIG_TESTING_OPTIONS */
2577 /* TODO: Timeout on AP response */
2578 wait_time
= wpa_s
->max_remain_on_chan
;
2579 if (wait_time
> 2000)
2581 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
2582 MAC2STR(bss
->bssid
), bss
->freq
, DPP_PA_PEER_DISCOVERY_REQ
);
2583 offchannel_send_action(wpa_s
, bss
->freq
, bss
->bssid
, wpa_s
->own_addr
,
2585 wpabuf_head(msg
), wpabuf_len(msg
),
2586 wait_time
, wpas_dpp_tx_introduction_status
, 0);
2589 /* Request this connection attempt to terminate - new one will be
2590 * started when network introduction protocol completes */
2591 os_memcpy(wpa_s
->dpp_intro_bssid
, bss
->bssid
, ETH_ALEN
);
2592 wpa_s
->dpp_intro_network
= ssid
;
2597 int wpas_dpp_pkex_add(struct wpa_supplicant
*wpa_s
, const char *cmd
)
2599 struct dpp_bootstrap_info
*own_bi
;
2600 const char *pos
, *end
;
2601 unsigned int wait_time
;
2603 pos
= os_strstr(cmd
, " own=");
2607 own_bi
= dpp_bootstrap_get_id(wpa_s
, atoi(pos
));
2609 wpa_printf(MSG_DEBUG
,
2610 "DPP: Identified bootstrap info not found");
2613 if (own_bi
->type
!= DPP_BOOTSTRAP_PKEX
) {
2614 wpa_printf(MSG_DEBUG
,
2615 "DPP: Identified bootstrap info not for PKEX");
2618 wpa_s
->dpp_pkex_bi
= own_bi
;
2619 own_bi
->pkex_t
= 0; /* clear pending errors on new code */
2621 os_free(wpa_s
->dpp_pkex_identifier
);
2622 wpa_s
->dpp_pkex_identifier
= NULL
;
2623 pos
= os_strstr(cmd
, " identifier=");
2626 end
= os_strchr(pos
, ' ');
2629 wpa_s
->dpp_pkex_identifier
= os_malloc(end
- pos
+ 1);
2630 if (!wpa_s
->dpp_pkex_identifier
)
2632 os_memcpy(wpa_s
->dpp_pkex_identifier
, pos
, end
- pos
);
2633 wpa_s
->dpp_pkex_identifier
[end
- pos
] = '\0';
2636 pos
= os_strstr(cmd
, " code=");
2639 os_free(wpa_s
->dpp_pkex_code
);
2640 wpa_s
->dpp_pkex_code
= os_strdup(pos
+ 6);
2641 if (!wpa_s
->dpp_pkex_code
)
2644 if (os_strstr(cmd
, " init=1")) {
2645 struct dpp_pkex
*pkex
;
2648 wpa_printf(MSG_DEBUG
, "DPP: Initiating PKEX");
2649 dpp_pkex_free(wpa_s
->dpp_pkex
);
2650 wpa_s
->dpp_pkex
= dpp_pkex_init(wpa_s
, own_bi
, wpa_s
->own_addr
,
2651 wpa_s
->dpp_pkex_identifier
,
2652 wpa_s
->dpp_pkex_code
);
2653 pkex
= wpa_s
->dpp_pkex
;
2657 msg
= pkex
->exchange_req
;
2658 wait_time
= wpa_s
->max_remain_on_chan
;
2659 if (wait_time
> 2000)
2662 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
2664 MAC2STR(broadcast
), pkex
->freq
,
2665 DPP_PA_PKEX_EXCHANGE_REQ
);
2666 offchannel_send_action(wpa_s
, pkex
->freq
, broadcast
,
2667 wpa_s
->own_addr
, broadcast
,
2668 wpabuf_head(msg
), wpabuf_len(msg
),
2669 wait_time
, wpas_dpp_tx_pkex_status
, 0);
2672 pkex
->exch_req_wait_time
= wait_time
;
2673 pkex
->exch_req_tries
= 1;
2676 /* TODO: Support multiple PKEX info entries */
2678 os_free(wpa_s
->dpp_pkex_auth_cmd
);
2679 wpa_s
->dpp_pkex_auth_cmd
= os_strdup(cmd
);
2685 int wpas_dpp_pkex_remove(struct wpa_supplicant
*wpa_s
, const char *id
)
2687 unsigned int id_val
;
2689 if (os_strcmp(id
, "*") == 0) {
2697 if ((id_val
!= 0 && id_val
!= 1) || !wpa_s
->dpp_pkex_code
)
2700 /* TODO: Support multiple PKEX entries */
2701 os_free(wpa_s
->dpp_pkex_code
);
2702 wpa_s
->dpp_pkex_code
= NULL
;
2703 os_free(wpa_s
->dpp_pkex_identifier
);
2704 wpa_s
->dpp_pkex_identifier
= NULL
;
2705 os_free(wpa_s
->dpp_pkex_auth_cmd
);
2706 wpa_s
->dpp_pkex_auth_cmd
= NULL
;
2707 wpa_s
->dpp_pkex_bi
= NULL
;
2708 /* TODO: Remove dpp_pkex only if it is for the identified PKEX code */
2709 dpp_pkex_free(wpa_s
->dpp_pkex
);
2710 wpa_s
->dpp_pkex
= NULL
;
2715 void wpas_dpp_stop(struct wpa_supplicant
*wpa_s
)
2717 dpp_auth_deinit(wpa_s
->dpp_auth
);
2718 wpa_s
->dpp_auth
= NULL
;
2719 dpp_pkex_free(wpa_s
->dpp_pkex
);
2720 wpa_s
->dpp_pkex
= NULL
;
2721 if (wpa_s
->dpp_gas_client
&& wpa_s
->dpp_gas_dialog_token
>= 0)
2722 gas_query_stop(wpa_s
->gas
, wpa_s
->dpp_gas_dialog_token
);
2726 int wpas_dpp_init(struct wpa_supplicant
*wpa_s
)
2730 adv_proto_id
[0] = WLAN_EID_VENDOR_SPECIFIC
;
2731 adv_proto_id
[1] = 5;
2732 WPA_PUT_BE24(&adv_proto_id
[2], OUI_WFA
);
2733 adv_proto_id
[5] = DPP_OUI_TYPE
;
2734 adv_proto_id
[6] = 0x01;
2736 if (gas_server_register(wpa_s
->gas_server
, adv_proto_id
,
2737 sizeof(adv_proto_id
), wpas_dpp_gas_req_handler
,
2738 wpas_dpp_gas_status_handler
, wpa_s
) < 0)
2740 dl_list_init(&wpa_s
->dpp_bootstrap
);
2741 dl_list_init(&wpa_s
->dpp_configurator
);
2742 wpa_s
->dpp_init_done
= 1;
2747 void wpas_dpp_deinit(struct wpa_supplicant
*wpa_s
)
2749 #ifdef CONFIG_TESTING_OPTIONS
2750 os_free(wpa_s
->dpp_config_obj_override
);
2751 wpa_s
->dpp_config_obj_override
= NULL
;
2752 os_free(wpa_s
->dpp_discovery_override
);
2753 wpa_s
->dpp_discovery_override
= NULL
;
2754 os_free(wpa_s
->dpp_groups_override
);
2755 wpa_s
->dpp_groups_override
= NULL
;
2756 wpa_s
->dpp_ignore_netaccesskey_mismatch
= 0;
2757 #endif /* CONFIG_TESTING_OPTIONS */
2758 if (!wpa_s
->dpp_init_done
)
2760 eloop_cancel_timeout(wpas_dpp_pkex_retry_timeout
, wpa_s
, NULL
);
2761 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
2762 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
2763 eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout
, wpa_s
, NULL
);
2765 eloop_cancel_timeout(wpas_dpp_config_result_wait_timeout
, wpa_s
, NULL
);
2766 #endif /* CONFIG_DPP2 */
2767 offchannel_send_action_done(wpa_s
);
2768 wpas_dpp_listen_stop(wpa_s
);
2769 dpp_bootstrap_del(wpa_s
, 0);
2770 dpp_configurator_del(wpa_s
, 0);
2771 wpas_dpp_stop(wpa_s
);
2772 wpas_dpp_pkex_remove(wpa_s
, "*");
2773 os_memset(wpa_s
->dpp_intro_bssid
, 0, ETH_ALEN
);
2774 os_free(wpa_s
->dpp_configurator_params
);
2775 wpa_s
->dpp_configurator_params
= NULL
;