3 * Copyright (c) 2017, Qualcomm Atheros, Inc.
4 * Copyright (c) 2018-2019, 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 "utils/ip_addr.h"
15 #include "common/dpp.h"
16 #include "common/gas.h"
17 #include "common/gas_server.h"
18 #include "rsn_supp/wpa.h"
19 #include "rsn_supp/pmksa_cache.h"
20 #include "wpa_supplicant_i.h"
23 #include "offchannel.h"
24 #include "gas_query.h"
28 #include "dpp_supplicant.h"
31 static int wpas_dpp_listen_start(struct wpa_supplicant
*wpa_s
,
33 static void wpas_dpp_reply_wait_timeout(void *eloop_ctx
, void *timeout_ctx
);
34 static void wpas_dpp_auth_success(struct wpa_supplicant
*wpa_s
, int initiator
);
35 static void wpas_dpp_tx_status(struct wpa_supplicant
*wpa_s
,
36 unsigned int freq
, const u8
*dst
,
37 const u8
*src
, const u8
*bssid
,
38 const u8
*data
, size_t data_len
,
39 enum offchannel_send_action_result result
);
40 static void wpas_dpp_init_timeout(void *eloop_ctx
, void *timeout_ctx
);
41 static int wpas_dpp_auth_init_next(struct wpa_supplicant
*wpa_s
);
43 wpas_dpp_tx_pkex_status(struct wpa_supplicant
*wpa_s
,
44 unsigned int freq
, const u8
*dst
,
45 const u8
*src
, const u8
*bssid
,
46 const u8
*data
, size_t data_len
,
47 enum offchannel_send_action_result result
);
49 static const u8 broadcast
[ETH_ALEN
] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
51 /* Use a hardcoded Transaction ID 1 in Peer Discovery frames since there is only
52 * a single transaction in progress at any point in time. */
53 static const u8 TRANSACTION_ID
= 1;
57 * wpas_dpp_qr_code - Parse and add DPP bootstrapping info from a QR Code
58 * @wpa_s: Pointer to wpa_supplicant data
59 * @cmd: DPP URI read from a QR Code
60 * Returns: Identifier of the stored info or -1 on failure
62 int wpas_dpp_qr_code(struct wpa_supplicant
*wpa_s
, const char *cmd
)
64 struct dpp_bootstrap_info
*bi
;
65 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
67 bi
= dpp_add_qr_code(wpa_s
->dpp
, cmd
);
71 if (auth
&& auth
->response_pending
&&
72 dpp_notify_new_qr_code(auth
, bi
) == 1) {
74 "DPP: Sending out pending authentication response");
75 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
77 MAC2STR(auth
->peer_mac_addr
), auth
->curr_freq
,
78 DPP_PA_AUTHENTICATION_RESP
);
79 offchannel_send_action(wpa_s
, auth
->curr_freq
,
80 auth
->peer_mac_addr
, wpa_s
->own_addr
,
82 wpabuf_head(auth
->resp_msg
),
83 wpabuf_len(auth
->resp_msg
),
84 500, wpas_dpp_tx_status
, 0);
92 * wpas_dpp_nfc_uri - Parse and add DPP bootstrapping info from NFC Tag (URI)
93 * @wpa_s: Pointer to wpa_supplicant data
94 * @cmd: DPP URI read from a NFC Tag (URI NDEF message)
95 * Returns: Identifier of the stored info or -1 on failure
97 int wpas_dpp_nfc_uri(struct wpa_supplicant
*wpa_s
, const char *cmd
)
99 struct dpp_bootstrap_info
*bi
;
101 bi
= dpp_add_nfc_uri(wpa_s
->dpp
, cmd
);
109 static void wpas_dpp_auth_resp_retry_timeout(void *eloop_ctx
, void *timeout_ctx
)
111 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
112 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
114 if (!auth
|| !auth
->resp_msg
)
117 wpa_printf(MSG_DEBUG
,
118 "DPP: Retry Authentication Response after timeout");
119 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
121 MAC2STR(auth
->peer_mac_addr
), auth
->curr_freq
,
122 DPP_PA_AUTHENTICATION_RESP
);
123 offchannel_send_action(wpa_s
, auth
->curr_freq
, auth
->peer_mac_addr
,
124 wpa_s
->own_addr
, broadcast
,
125 wpabuf_head(auth
->resp_msg
),
126 wpabuf_len(auth
->resp_msg
),
127 500, wpas_dpp_tx_status
, 0);
131 static void wpas_dpp_auth_resp_retry(struct wpa_supplicant
*wpa_s
)
133 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
134 unsigned int wait_time
, max_tries
;
136 if (!auth
|| !auth
->resp_msg
)
139 if (wpa_s
->dpp_resp_max_tries
)
140 max_tries
= wpa_s
->dpp_resp_max_tries
;
143 auth
->auth_resp_tries
++;
144 if (auth
->auth_resp_tries
>= max_tries
) {
145 wpa_printf(MSG_INFO
, "DPP: No confirm received from initiator - stopping exchange");
146 offchannel_send_action_done(wpa_s
);
147 dpp_auth_deinit(wpa_s
->dpp_auth
);
148 wpa_s
->dpp_auth
= NULL
;
152 if (wpa_s
->dpp_resp_retry_time
)
153 wait_time
= wpa_s
->dpp_resp_retry_time
;
156 wpa_printf(MSG_DEBUG
,
157 "DPP: Schedule retransmission of Authentication Response frame in %u ms",
159 eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout
, wpa_s
, NULL
);
160 eloop_register_timeout(wait_time
/ 1000,
161 (wait_time
% 1000) * 1000,
162 wpas_dpp_auth_resp_retry_timeout
, wpa_s
, NULL
);
166 static void wpas_dpp_try_to_connect(struct wpa_supplicant
*wpa_s
)
168 wpa_printf(MSG_DEBUG
, "DPP: Trying to connect to the new network");
169 wpa_s
->suitable_network
= 0;
170 wpa_s
->no_suitable_network
= 0;
171 wpa_s
->disconnected
= 0;
172 wpa_s
->reassociate
= 1;
173 wpa_s
->scan_runs
= 0;
174 wpa_s
->normal_scans
= 0;
175 wpa_supplicant_cancel_sched_scan(wpa_s
);
176 wpa_supplicant_req_scan(wpa_s
, 0, 0);
182 static void wpas_dpp_conn_status_result_timeout(void *eloop_ctx
,
185 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
186 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
187 enum dpp_status_error result
;
189 if (!auth
|| !auth
->conn_status_requested
)
192 wpa_printf(MSG_DEBUG
,
193 "DPP: Connection timeout - report Connection Status Result");
194 if (wpa_s
->suitable_network
)
195 result
= DPP_STATUS_AUTH_FAILURE
;
196 else if (wpa_s
->no_suitable_network
)
197 result
= DPP_STATUS_NO_AP
;
199 result
= 255; /* What to report here for unexpected state? */
200 wpas_dpp_send_conn_status_result(wpa_s
, result
);
204 static char * wpas_dpp_scan_channel_list(struct wpa_supplicant
*wpa_s
)
206 char *str
, *end
, *pos
;
209 u8 last_op_class
= 0;
212 if (!wpa_s
->last_scan_freqs
|| !wpa_s
->num_last_scan_freqs
)
215 len
= wpa_s
->num_last_scan_freqs
* 8;
216 str
= os_zalloc(len
);
222 for (i
= 0; i
< wpa_s
->num_last_scan_freqs
; i
++) {
223 enum hostapd_hw_mode mode
;
224 u8 op_class
, channel
;
226 mode
= ieee80211_freq_to_channel_ext(wpa_s
->last_scan_freqs
[i
],
227 0, 0, &op_class
, &channel
);
228 if (mode
== NUM_HOSTAPD_MODES
)
230 if (op_class
== last_op_class
)
231 res
= os_snprintf(pos
, end
- pos
, ",%d", channel
);
233 res
= os_snprintf(pos
, end
- pos
, "%s%d/%d",
234 pos
== str
? "" : ",",
236 if (os_snprintf_error(end
- pos
, res
)) {
241 last_op_class
= op_class
;
252 void wpas_dpp_send_conn_status_result(struct wpa_supplicant
*wpa_s
,
253 enum dpp_status_error result
)
256 const char *channel_list
= NULL
;
257 char *channel_list_buf
= NULL
;
258 struct wpa_ssid
*ssid
= wpa_s
->current_ssid
;
259 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
261 eloop_cancel_timeout(wpas_dpp_conn_status_result_timeout
, wpa_s
, NULL
);
263 if (!auth
|| !auth
->conn_status_requested
)
265 auth
->conn_status_requested
= 0;
266 wpa_printf(MSG_DEBUG
, "DPP: Report connection status result %d",
269 if (result
== DPP_STATUS_NO_AP
) {
270 channel_list_buf
= wpas_dpp_scan_channel_list(wpa_s
);
271 channel_list
= channel_list_buf
;
274 msg
= dpp_build_conn_status_result(auth
, result
,
276 wpa_s
->dpp_last_ssid
,
277 ssid
? ssid
->ssid_len
:
278 wpa_s
->dpp_last_ssid_len
,
280 os_free(channel_list_buf
);
282 dpp_auth_deinit(wpa_s
->dpp_auth
);
283 wpa_s
->dpp_auth
= NULL
;
287 wpa_msg(wpa_s
, MSG_INFO
,
288 DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
289 MAC2STR(auth
->peer_mac_addr
), auth
->curr_freq
,
290 DPP_PA_CONNECTION_STATUS_RESULT
);
291 offchannel_send_action(wpa_s
, auth
->curr_freq
,
292 auth
->peer_mac_addr
, wpa_s
->own_addr
, broadcast
,
293 wpabuf_head(msg
), wpabuf_len(msg
),
294 500, wpas_dpp_tx_status
, 0);
297 /* This exchange will be terminated in the TX status handler */
298 auth
->remove_on_tx_status
= 1;
304 void wpas_dpp_connected(struct wpa_supplicant
*wpa_s
)
306 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
308 if (auth
&& auth
->conn_status_requested
)
309 wpas_dpp_send_conn_status_result(wpa_s
, DPP_STATUS_OK
);
312 #endif /* CONFIG_DPP2 */
315 static void wpas_dpp_tx_status(struct wpa_supplicant
*wpa_s
,
316 unsigned int freq
, const u8
*dst
,
317 const u8
*src
, const u8
*bssid
,
318 const u8
*data
, size_t data_len
,
319 enum offchannel_send_action_result result
)
322 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
324 res_txt
= result
== OFFCHANNEL_SEND_ACTION_SUCCESS
? "SUCCESS" :
325 (result
== OFFCHANNEL_SEND_ACTION_NO_ACK
? "no-ACK" :
327 wpa_printf(MSG_DEBUG
, "DPP: TX status: freq=%u dst=" MACSTR
328 " result=%s", freq
, MAC2STR(dst
), res_txt
);
329 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX_STATUS
"dst=" MACSTR
330 " freq=%u result=%s", MAC2STR(dst
), freq
, res_txt
);
332 if (!wpa_s
->dpp_auth
) {
333 wpa_printf(MSG_DEBUG
,
334 "DPP: Ignore TX status since there is no ongoing authentication exchange");
339 if (auth
->connect_on_tx_status
) {
340 auth
->connect_on_tx_status
= 0;
341 wpa_printf(MSG_DEBUG
,
342 "DPP: Try to connect after completed configuration result");
343 wpas_dpp_try_to_connect(wpa_s
);
344 if (auth
->conn_status_requested
) {
345 wpa_printf(MSG_DEBUG
,
346 "DPP: Start 15 second timeout for reporting connection status result");
347 eloop_cancel_timeout(
348 wpas_dpp_conn_status_result_timeout
,
350 eloop_register_timeout(
351 15, 0, wpas_dpp_conn_status_result_timeout
,
354 dpp_auth_deinit(wpa_s
->dpp_auth
);
355 wpa_s
->dpp_auth
= NULL
;
359 #endif /* CONFIG_DPP2 */
361 if (wpa_s
->dpp_auth
->remove_on_tx_status
) {
362 wpa_printf(MSG_DEBUG
,
363 "DPP: Terminate authentication exchange due to a request to do so on TX status");
364 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
365 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
366 eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout
, wpa_s
,
368 offchannel_send_action_done(wpa_s
);
369 dpp_auth_deinit(wpa_s
->dpp_auth
);
370 wpa_s
->dpp_auth
= NULL
;
374 if (wpa_s
->dpp_auth_ok_on_ack
)
375 wpas_dpp_auth_success(wpa_s
, 1);
377 if (!is_broadcast_ether_addr(dst
) &&
378 result
!= OFFCHANNEL_SEND_ACTION_SUCCESS
) {
379 wpa_printf(MSG_DEBUG
,
380 "DPP: Unicast DPP Action frame was not ACKed");
381 if (auth
->waiting_auth_resp
) {
382 /* In case of DPP Authentication Request frame, move to
383 * the next channel immediately. */
384 offchannel_send_action_done(wpa_s
);
385 wpas_dpp_auth_init_next(wpa_s
);
388 if (auth
->waiting_auth_conf
) {
389 wpas_dpp_auth_resp_retry(wpa_s
);
394 if (!is_broadcast_ether_addr(dst
) && auth
->waiting_auth_resp
&&
395 result
== OFFCHANNEL_SEND_ACTION_SUCCESS
) {
396 /* Allow timeout handling to stop iteration if no response is
397 * received from a peer that has ACKed a request. */
398 auth
->auth_req_ack
= 1;
401 if (!wpa_s
->dpp_auth_ok_on_ack
&& wpa_s
->dpp_auth
->neg_freq
> 0 &&
402 wpa_s
->dpp_auth
->curr_freq
!= wpa_s
->dpp_auth
->neg_freq
) {
403 wpa_printf(MSG_DEBUG
,
404 "DPP: Move from curr_freq %u MHz to neg_freq %u MHz for response",
405 wpa_s
->dpp_auth
->curr_freq
,
406 wpa_s
->dpp_auth
->neg_freq
);
407 offchannel_send_action_done(wpa_s
);
408 wpas_dpp_listen_start(wpa_s
, wpa_s
->dpp_auth
->neg_freq
);
411 if (wpa_s
->dpp_auth_ok_on_ack
)
412 wpa_s
->dpp_auth_ok_on_ack
= 0;
416 static void wpas_dpp_reply_wait_timeout(void *eloop_ctx
, void *timeout_ctx
)
418 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
419 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
421 struct os_reltime now
, diff
;
422 unsigned int wait_time
, diff_ms
;
424 if (!auth
|| !auth
->waiting_auth_resp
)
427 wait_time
= wpa_s
->dpp_resp_wait_time
?
428 wpa_s
->dpp_resp_wait_time
: 2000;
429 os_get_reltime(&now
);
430 os_reltime_sub(&now
, &wpa_s
->dpp_last_init
, &diff
);
431 diff_ms
= diff
.sec
* 1000 + diff
.usec
/ 1000;
432 wpa_printf(MSG_DEBUG
,
433 "DPP: Reply wait timeout - wait_time=%u diff_ms=%u",
436 if (auth
->auth_req_ack
&& diff_ms
>= wait_time
) {
437 /* Peer ACK'ed Authentication Request frame, but did not reply
438 * with Authentication Response frame within two seconds. */
440 "DPP: No response received from responder - stopping initiation attempt");
441 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_AUTH_INIT_FAILED
);
442 offchannel_send_action_done(wpa_s
);
443 wpas_dpp_listen_stop(wpa_s
);
444 dpp_auth_deinit(auth
);
445 wpa_s
->dpp_auth
= NULL
;
449 if (diff_ms
>= wait_time
) {
450 /* Authentication Request frame was not ACK'ed and no reply
451 * was receiving within two seconds. */
452 wpa_printf(MSG_DEBUG
,
453 "DPP: Continue Initiator channel iteration");
454 offchannel_send_action_done(wpa_s
);
455 wpas_dpp_listen_stop(wpa_s
);
456 wpas_dpp_auth_init_next(wpa_s
);
460 /* Driver did not support 2000 ms long wait_time with TX command, so
461 * schedule listen operation to continue waiting for the response.
463 * DPP listen operations continue until stopped, so simply schedule a
464 * new call to this function at the point when the two second reply
465 * wait has expired. */
466 wait_time
-= diff_ms
;
468 freq
= auth
->curr_freq
;
469 if (auth
->neg_freq
> 0)
470 freq
= auth
->neg_freq
;
471 wpa_printf(MSG_DEBUG
,
472 "DPP: Continue reply wait on channel %u MHz for %u ms",
474 wpa_s
->dpp_in_response_listen
= 1;
475 wpas_dpp_listen_start(wpa_s
, freq
);
477 eloop_register_timeout(wait_time
/ 1000, (wait_time
% 1000) * 1000,
478 wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
482 static void wpas_dpp_set_testing_options(struct wpa_supplicant
*wpa_s
,
483 struct dpp_authentication
*auth
)
485 #ifdef CONFIG_TESTING_OPTIONS
486 if (wpa_s
->dpp_config_obj_override
)
487 auth
->config_obj_override
=
488 os_strdup(wpa_s
->dpp_config_obj_override
);
489 if (wpa_s
->dpp_discovery_override
)
490 auth
->discovery_override
=
491 os_strdup(wpa_s
->dpp_discovery_override
);
492 if (wpa_s
->dpp_groups_override
)
493 auth
->groups_override
=
494 os_strdup(wpa_s
->dpp_groups_override
);
495 auth
->ignore_netaccesskey_mismatch
=
496 wpa_s
->dpp_ignore_netaccesskey_mismatch
;
497 #endif /* CONFIG_TESTING_OPTIONS */
501 static void wpas_dpp_init_timeout(void *eloop_ctx
, void *timeout_ctx
)
503 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
505 if (!wpa_s
->dpp_auth
)
507 wpa_printf(MSG_DEBUG
, "DPP: Retry initiation after timeout");
508 wpas_dpp_auth_init_next(wpa_s
);
512 static int wpas_dpp_auth_init_next(struct wpa_supplicant
*wpa_s
)
514 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
516 unsigned int wait_time
, max_wait_time
, freq
, max_tries
, used
;
517 struct os_reltime now
, diff
;
519 wpa_s
->dpp_in_response_listen
= 0;
523 if (auth
->freq_idx
== 0)
524 os_get_reltime(&wpa_s
->dpp_init_iter_start
);
526 if (auth
->freq_idx
>= auth
->num_freq
) {
527 auth
->num_freq_iters
++;
528 if (wpa_s
->dpp_init_max_tries
)
529 max_tries
= wpa_s
->dpp_init_max_tries
;
532 if (auth
->num_freq_iters
>= max_tries
|| auth
->auth_req_ack
) {
534 "DPP: No response received from responder - stopping initiation attempt");
535 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_AUTH_INIT_FAILED
);
536 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
,
538 offchannel_send_action_done(wpa_s
);
539 dpp_auth_deinit(wpa_s
->dpp_auth
);
540 wpa_s
->dpp_auth
= NULL
;
544 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
545 if (wpa_s
->dpp_init_retry_time
)
546 wait_time
= wpa_s
->dpp_init_retry_time
;
549 os_get_reltime(&now
);
550 os_reltime_sub(&now
, &wpa_s
->dpp_init_iter_start
, &diff
);
551 used
= diff
.sec
* 1000 + diff
.usec
/ 1000;
552 if (used
> wait_time
)
556 wpa_printf(MSG_DEBUG
, "DPP: Next init attempt in %u ms",
558 eloop_register_timeout(wait_time
/ 1000,
559 (wait_time
% 1000) * 1000,
560 wpas_dpp_init_timeout
, wpa_s
,
564 freq
= auth
->freq
[auth
->freq_idx
++];
565 auth
->curr_freq
= freq
;
567 if (is_zero_ether_addr(auth
->peer_bi
->mac_addr
))
570 dst
= auth
->peer_bi
->mac_addr
;
571 wpa_s
->dpp_auth_ok_on_ack
= 0;
572 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
573 wait_time
= wpa_s
->max_remain_on_chan
;
574 max_wait_time
= wpa_s
->dpp_resp_wait_time
?
575 wpa_s
->dpp_resp_wait_time
: 2000;
576 if (wait_time
> max_wait_time
)
577 wait_time
= max_wait_time
;
578 wait_time
+= 10; /* give the driver some extra time to complete */
579 eloop_register_timeout(wait_time
/ 1000, (wait_time
% 1000) * 1000,
580 wpas_dpp_reply_wait_timeout
,
583 if (auth
->neg_freq
> 0 && freq
!= auth
->neg_freq
) {
584 wpa_printf(MSG_DEBUG
,
585 "DPP: Initiate on %u MHz and move to neg_freq %u MHz for response",
586 freq
, auth
->neg_freq
);
588 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
589 MAC2STR(dst
), freq
, DPP_PA_AUTHENTICATION_REQ
);
590 auth
->auth_req_ack
= 0;
591 os_get_reltime(&wpa_s
->dpp_last_init
);
592 return offchannel_send_action(wpa_s
, freq
, dst
,
593 wpa_s
->own_addr
, broadcast
,
594 wpabuf_head(auth
->req_msg
),
595 wpabuf_len(auth
->req_msg
),
596 wait_time
, wpas_dpp_tx_status
, 0);
600 int wpas_dpp_auth_init(struct wpa_supplicant
*wpa_s
, const char *cmd
)
603 struct dpp_bootstrap_info
*peer_bi
, *own_bi
= NULL
;
604 struct dpp_authentication
*auth
;
605 u8 allowed_roles
= DPP_CAPAB_CONFIGURATOR
;
606 unsigned int neg_freq
= 0;
609 int tcp_port
= DPP_TCP_PORT
;
610 struct hostapd_ip_addr ipaddr
;
612 #endif /* CONFIG_DPP2 */
614 wpa_s
->dpp_gas_client
= 0;
616 pos
= os_strstr(cmd
, " peer=");
620 peer_bi
= dpp_bootstrap_get_id(wpa_s
->dpp
, atoi(pos
));
623 "DPP: Could not find bootstrapping info for the identified peer");
628 pos
= os_strstr(cmd
, " tcp_port=");
631 tcp_port
= atoi(pos
);
634 addr
= get_param(cmd
, " tcp_addr=");
638 res
= hostapd_parse_ip_addr(addr
, &ipaddr
);
644 #endif /* CONFIG_DPP2 */
646 pos
= os_strstr(cmd
, " own=");
649 own_bi
= dpp_bootstrap_get_id(wpa_s
->dpp
, atoi(pos
));
652 "DPP: Could not find bootstrapping info for the identified local entry");
656 if (peer_bi
->curve
!= own_bi
->curve
) {
658 "DPP: Mismatching curves in bootstrapping info (peer=%s own=%s)",
659 peer_bi
->curve
->name
, own_bi
->curve
->name
);
664 pos
= os_strstr(cmd
, " role=");
667 if (os_strncmp(pos
, "configurator", 12) == 0)
668 allowed_roles
= DPP_CAPAB_CONFIGURATOR
;
669 else if (os_strncmp(pos
, "enrollee", 8) == 0)
670 allowed_roles
= DPP_CAPAB_ENROLLEE
;
671 else if (os_strncmp(pos
, "either", 6) == 0)
672 allowed_roles
= DPP_CAPAB_CONFIGURATOR
|
678 pos
= os_strstr(cmd
, " netrole=");
681 if (os_strncmp(pos
, "ap", 2) == 0)
682 wpa_s
->dpp_netrole
= DPP_NETROLE_AP
;
684 wpa_s
->dpp_netrole
= DPP_NETROLE_STA
;
687 pos
= os_strstr(cmd
, " neg_freq=");
689 neg_freq
= atoi(pos
+ 10);
691 if (!tcp
&& wpa_s
->dpp_auth
) {
692 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
693 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
694 eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout
, wpa_s
,
696 offchannel_send_action_done(wpa_s
);
697 dpp_auth_deinit(wpa_s
->dpp_auth
);
698 wpa_s
->dpp_auth
= NULL
;
701 auth
= dpp_auth_init(wpa_s
, peer_bi
, own_bi
, allowed_roles
, neg_freq
,
702 wpa_s
->hw
.modes
, wpa_s
->hw
.num_modes
);
705 wpas_dpp_set_testing_options(wpa_s
, auth
);
706 if (dpp_set_configurator(wpa_s
->dpp
, wpa_s
, auth
, cmd
) < 0) {
707 dpp_auth_deinit(auth
);
711 auth
->neg_freq
= neg_freq
;
713 if (!is_zero_ether_addr(peer_bi
->mac_addr
))
714 os_memcpy(auth
->peer_mac_addr
, peer_bi
->mac_addr
, ETH_ALEN
);
718 return dpp_tcp_init(wpa_s
->dpp
, auth
, &ipaddr
, tcp_port
);
719 #endif /* CONFIG_DPP2 */
721 wpa_s
->dpp_auth
= auth
;
722 return wpas_dpp_auth_init_next(wpa_s
);
728 struct wpas_dpp_listen_work
{
730 unsigned int duration
;
731 struct wpabuf
*probe_resp_ie
;
735 static void wpas_dpp_listen_work_free(struct wpas_dpp_listen_work
*lwork
)
743 static void wpas_dpp_listen_work_done(struct wpa_supplicant
*wpa_s
)
745 struct wpas_dpp_listen_work
*lwork
;
747 if (!wpa_s
->dpp_listen_work
)
750 lwork
= wpa_s
->dpp_listen_work
->ctx
;
751 wpas_dpp_listen_work_free(lwork
);
752 radio_work_done(wpa_s
->dpp_listen_work
);
753 wpa_s
->dpp_listen_work
= NULL
;
757 static void dpp_start_listen_cb(struct wpa_radio_work
*work
, int deinit
)
759 struct wpa_supplicant
*wpa_s
= work
->wpa_s
;
760 struct wpas_dpp_listen_work
*lwork
= work
->ctx
;
764 wpa_s
->dpp_listen_work
= NULL
;
765 wpas_dpp_listen_stop(wpa_s
);
767 wpas_dpp_listen_work_free(lwork
);
771 wpa_s
->dpp_listen_work
= work
;
773 wpa_s
->dpp_pending_listen_freq
= lwork
->freq
;
775 if (wpa_drv_remain_on_channel(wpa_s
, lwork
->freq
,
776 wpa_s
->max_remain_on_chan
) < 0) {
777 wpa_printf(MSG_DEBUG
,
778 "DPP: Failed to request the driver to remain on channel (%u MHz) for listen",
780 wpa_s
->dpp_listen_freq
= 0;
781 wpas_dpp_listen_work_done(wpa_s
);
782 wpa_s
->dpp_pending_listen_freq
= 0;
785 wpa_s
->off_channel_freq
= 0;
786 wpa_s
->roc_waiting_drv_freq
= lwork
->freq
;
790 static int wpas_dpp_listen_start(struct wpa_supplicant
*wpa_s
,
793 struct wpas_dpp_listen_work
*lwork
;
795 if (wpa_s
->dpp_listen_work
) {
796 wpa_printf(MSG_DEBUG
,
797 "DPP: Reject start_listen since dpp_listen_work already exists");
801 if (wpa_s
->dpp_listen_freq
)
802 wpas_dpp_listen_stop(wpa_s
);
803 wpa_s
->dpp_listen_freq
= freq
;
805 lwork
= os_zalloc(sizeof(*lwork
));
810 if (radio_add_work(wpa_s
, freq
, "dpp-listen", 0, dpp_start_listen_cb
,
812 wpas_dpp_listen_work_free(lwork
);
820 int wpas_dpp_listen(struct wpa_supplicant
*wpa_s
, const char *cmd
)
828 if (os_strstr(cmd
, " role=configurator"))
829 wpa_s
->dpp_allowed_roles
= DPP_CAPAB_CONFIGURATOR
;
830 else if (os_strstr(cmd
, " role=enrollee"))
831 wpa_s
->dpp_allowed_roles
= DPP_CAPAB_ENROLLEE
;
833 wpa_s
->dpp_allowed_roles
= DPP_CAPAB_CONFIGURATOR
|
835 wpa_s
->dpp_qr_mutual
= os_strstr(cmd
, " qr=mutual") != NULL
;
836 if (os_strstr(cmd
, " netrole=ap"))
837 wpa_s
->dpp_netrole
= DPP_NETROLE_AP
;
839 wpa_s
->dpp_netrole
= DPP_NETROLE_STA
;
840 if (wpa_s
->dpp_listen_freq
== (unsigned int) freq
) {
841 wpa_printf(MSG_DEBUG
, "DPP: Already listening on %u MHz",
846 return wpas_dpp_listen_start(wpa_s
, freq
);
850 void wpas_dpp_listen_stop(struct wpa_supplicant
*wpa_s
)
852 wpa_s
->dpp_in_response_listen
= 0;
853 if (!wpa_s
->dpp_listen_freq
)
856 wpa_printf(MSG_DEBUG
, "DPP: Stop listen on %u MHz",
857 wpa_s
->dpp_listen_freq
);
858 wpa_drv_cancel_remain_on_channel(wpa_s
);
859 wpa_s
->dpp_listen_freq
= 0;
860 wpas_dpp_listen_work_done(wpa_s
);
864 void wpas_dpp_cancel_remain_on_channel_cb(struct wpa_supplicant
*wpa_s
,
867 wpas_dpp_listen_work_done(wpa_s
);
869 if (wpa_s
->dpp_auth
&& wpa_s
->dpp_in_response_listen
) {
870 unsigned int new_freq
;
872 /* Continue listen with a new remain-on-channel */
873 if (wpa_s
->dpp_auth
->neg_freq
> 0)
874 new_freq
= wpa_s
->dpp_auth
->neg_freq
;
876 new_freq
= wpa_s
->dpp_auth
->curr_freq
;
877 wpa_printf(MSG_DEBUG
,
878 "DPP: Continue wait on %u MHz for the ongoing DPP provisioning session",
880 wpas_dpp_listen_start(wpa_s
, new_freq
);
884 if (wpa_s
->dpp_listen_freq
) {
885 /* Continue listen with a new remain-on-channel */
886 wpas_dpp_listen_start(wpa_s
, wpa_s
->dpp_listen_freq
);
891 static void wpas_dpp_rx_auth_req(struct wpa_supplicant
*wpa_s
, const u8
*src
,
892 const u8
*hdr
, const u8
*buf
, size_t len
,
895 const u8
*r_bootstrap
, *i_bootstrap
;
896 u16 r_bootstrap_len
, i_bootstrap_len
;
897 struct dpp_bootstrap_info
*own_bi
= NULL
, *peer_bi
= NULL
;
902 wpa_printf(MSG_DEBUG
, "DPP: Authentication Request from " MACSTR
,
905 r_bootstrap
= dpp_get_attr(buf
, len
, DPP_ATTR_R_BOOTSTRAP_KEY_HASH
,
907 if (!r_bootstrap
|| r_bootstrap_len
!= SHA256_MAC_LEN
) {
908 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
909 "Missing or invalid required Responder Bootstrapping Key Hash attribute");
912 wpa_hexdump(MSG_MSGDUMP
, "DPP: Responder Bootstrapping Key Hash",
913 r_bootstrap
, r_bootstrap_len
);
915 i_bootstrap
= dpp_get_attr(buf
, len
, DPP_ATTR_I_BOOTSTRAP_KEY_HASH
,
917 if (!i_bootstrap
|| i_bootstrap_len
!= SHA256_MAC_LEN
) {
918 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
919 "Missing or invalid required Initiator Bootstrapping Key Hash attribute");
922 wpa_hexdump(MSG_MSGDUMP
, "DPP: Initiator Bootstrapping Key Hash",
923 i_bootstrap
, i_bootstrap_len
);
925 /* Try to find own and peer bootstrapping key matches based on the
926 * received hash values */
927 dpp_bootstrap_find_pair(wpa_s
->dpp
, i_bootstrap
, r_bootstrap
,
930 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
931 "No matching own bootstrapping key found - ignore message");
935 if (wpa_s
->dpp_auth
) {
936 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
937 "Already in DPP authentication exchange - ignore new one");
941 wpa_s
->dpp_gas_client
= 0;
942 wpa_s
->dpp_auth_ok_on_ack
= 0;
943 wpa_s
->dpp_auth
= dpp_auth_req_rx(wpa_s
, wpa_s
->dpp_allowed_roles
,
944 wpa_s
->dpp_qr_mutual
,
945 peer_bi
, own_bi
, freq
, hdr
, buf
, len
);
946 if (!wpa_s
->dpp_auth
) {
947 wpa_printf(MSG_DEBUG
, "DPP: No response generated");
950 wpas_dpp_set_testing_options(wpa_s
, wpa_s
->dpp_auth
);
951 if (dpp_set_configurator(wpa_s
->dpp
, wpa_s
, wpa_s
->dpp_auth
,
952 wpa_s
->dpp_configurator_params
) < 0) {
953 dpp_auth_deinit(wpa_s
->dpp_auth
);
954 wpa_s
->dpp_auth
= NULL
;
957 os_memcpy(wpa_s
->dpp_auth
->peer_mac_addr
, src
, ETH_ALEN
);
959 if (wpa_s
->dpp_listen_freq
&&
960 wpa_s
->dpp_listen_freq
!= wpa_s
->dpp_auth
->curr_freq
) {
961 wpa_printf(MSG_DEBUG
,
962 "DPP: Stop listen on %u MHz to allow response on the request %u MHz",
963 wpa_s
->dpp_listen_freq
, wpa_s
->dpp_auth
->curr_freq
);
964 wpas_dpp_listen_stop(wpa_s
);
967 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
968 MAC2STR(src
), wpa_s
->dpp_auth
->curr_freq
,
969 DPP_PA_AUTHENTICATION_RESP
);
970 offchannel_send_action(wpa_s
, wpa_s
->dpp_auth
->curr_freq
,
971 src
, wpa_s
->own_addr
, broadcast
,
972 wpabuf_head(wpa_s
->dpp_auth
->resp_msg
),
973 wpabuf_len(wpa_s
->dpp_auth
->resp_msg
),
974 500, wpas_dpp_tx_status
, 0);
978 static void wpas_dpp_start_gas_server(struct wpa_supplicant
*wpa_s
)
980 /* TODO: stop wait and start ROC */
984 static struct wpa_ssid
* wpas_dpp_add_network(struct wpa_supplicant
*wpa_s
,
985 struct dpp_authentication
*auth
,
986 struct dpp_config_obj
*conf
)
988 struct wpa_ssid
*ssid
;
991 if (conf
->akm
== DPP_AKM_SAE
) {
993 struct wpa_driver_capa capa
;
996 res
= wpa_drv_get_capa(wpa_s
, &capa
);
998 !(capa
.key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_SAE
) &&
999 !(wpa_s
->drv_flags
& WPA_DRIVER_FLAGS_SAE
)) {
1000 wpa_printf(MSG_DEBUG
,
1001 "DPP: SAE not supported by the driver");
1004 #else /* CONFIG_SAE */
1005 wpa_printf(MSG_DEBUG
, "DPP: SAE not supported in the build");
1007 #endif /* CONFIG_SAE */
1009 #endif /* CONFIG_DPP2 */
1011 ssid
= wpa_config_add_network(wpa_s
->conf
);
1014 wpas_notify_network_added(wpa_s
, ssid
);
1015 wpa_config_set_network_defaults(ssid
);
1018 ssid
->ssid
= os_malloc(conf
->ssid_len
);
1021 os_memcpy(ssid
->ssid
, conf
->ssid
, conf
->ssid_len
);
1022 ssid
->ssid_len
= conf
->ssid_len
;
1024 if (conf
->connector
) {
1025 ssid
->key_mgmt
= WPA_KEY_MGMT_DPP
;
1026 ssid
->ieee80211w
= MGMT_FRAME_PROTECTION_REQUIRED
;
1027 ssid
->dpp_connector
= os_strdup(conf
->connector
);
1028 if (!ssid
->dpp_connector
)
1032 if (conf
->c_sign_key
) {
1033 ssid
->dpp_csign
= os_malloc(wpabuf_len(conf
->c_sign_key
));
1034 if (!ssid
->dpp_csign
)
1036 os_memcpy(ssid
->dpp_csign
, wpabuf_head(conf
->c_sign_key
),
1037 wpabuf_len(conf
->c_sign_key
));
1038 ssid
->dpp_csign_len
= wpabuf_len(conf
->c_sign_key
);
1041 if (auth
->net_access_key
) {
1042 ssid
->dpp_netaccesskey
=
1043 os_malloc(wpabuf_len(auth
->net_access_key
));
1044 if (!ssid
->dpp_netaccesskey
)
1046 os_memcpy(ssid
->dpp_netaccesskey
,
1047 wpabuf_head(auth
->net_access_key
),
1048 wpabuf_len(auth
->net_access_key
));
1049 ssid
->dpp_netaccesskey_len
= wpabuf_len(auth
->net_access_key
);
1050 ssid
->dpp_netaccesskey_expiry
= auth
->net_access_key_expiry
;
1053 if (!conf
->connector
|| dpp_akm_psk(conf
->akm
) ||
1054 dpp_akm_sae(conf
->akm
)) {
1055 if (!conf
->connector
)
1057 if (dpp_akm_psk(conf
->akm
))
1058 ssid
->key_mgmt
|= WPA_KEY_MGMT_PSK
|
1059 WPA_KEY_MGMT_PSK_SHA256
| WPA_KEY_MGMT_FT_PSK
;
1060 if (dpp_akm_sae(conf
->akm
))
1061 ssid
->key_mgmt
|= WPA_KEY_MGMT_SAE
|
1062 WPA_KEY_MGMT_FT_SAE
;
1063 ssid
->ieee80211w
= MGMT_FRAME_PROTECTION_OPTIONAL
;
1064 if (conf
->passphrase
[0]) {
1065 if (wpa_config_set_quoted(ssid
, "psk",
1066 conf
->passphrase
) < 0)
1068 wpa_config_update_psk(ssid
);
1069 ssid
->export_keys
= 1;
1071 ssid
->psk_set
= conf
->psk_set
;
1072 os_memcpy(ssid
->psk
, conf
->psk
, PMK_LEN
);
1076 os_memcpy(wpa_s
->dpp_last_ssid
, conf
->ssid
, conf
->ssid_len
);
1077 wpa_s
->dpp_last_ssid_len
= conf
->ssid_len
;
1081 wpas_notify_network_removed(wpa_s
, ssid
);
1082 wpa_config_remove_network(wpa_s
->conf
, ssid
->id
);
1087 static int wpas_dpp_process_config(struct wpa_supplicant
*wpa_s
,
1088 struct dpp_authentication
*auth
,
1089 struct dpp_config_obj
*conf
)
1091 struct wpa_ssid
*ssid
;
1093 if (wpa_s
->conf
->dpp_config_processing
< 1)
1096 ssid
= wpas_dpp_add_network(wpa_s
, auth
, conf
);
1100 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_NETWORK_ID
"%d", ssid
->id
);
1101 if (wpa_s
->conf
->dpp_config_processing
== 2)
1104 #ifndef CONFIG_NO_CONFIG_WRITE
1105 if (wpa_s
->conf
->update_config
&&
1106 wpa_config_write(wpa_s
->confname
, wpa_s
->conf
))
1107 wpa_printf(MSG_DEBUG
, "DPP: Failed to update configuration");
1108 #endif /* CONFIG_NO_CONFIG_WRITE */
1114 static void wpas_dpp_post_process_config(struct wpa_supplicant
*wpa_s
,
1115 struct dpp_authentication
*auth
)
1117 if (wpa_s
->conf
->dpp_config_processing
< 2)
1121 if (auth
->peer_version
>= 2) {
1122 wpa_printf(MSG_DEBUG
,
1123 "DPP: Postpone connection attempt to wait for completion of DPP Configuration Result");
1124 auth
->connect_on_tx_status
= 1;
1127 #endif /* CONFIG_DPP2 */
1129 wpas_dpp_try_to_connect(wpa_s
);
1133 static int wpas_dpp_handle_config_obj(struct wpa_supplicant
*wpa_s
,
1134 struct dpp_authentication
*auth
,
1135 struct dpp_config_obj
*conf
)
1137 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_RECEIVED
);
1139 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONFOBJ_SSID
"%s",
1140 wpa_ssid_txt(conf
->ssid
, conf
->ssid_len
));
1141 if (conf
->ssid_charset
)
1142 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONFOBJ_SSID_CHARSET
"%d",
1143 conf
->ssid_charset
);
1144 if (conf
->connector
) {
1145 /* TODO: Save the Connector and consider using a command
1146 * to fetch the value instead of sending an event with
1147 * it. The Connector could end up being larger than what
1148 * most clients are ready to receive as an event
1150 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONNECTOR
"%s",
1153 if (conf
->c_sign_key
) {
1157 hexlen
= 2 * wpabuf_len(conf
->c_sign_key
) + 1;
1158 hex
= os_malloc(hexlen
);
1160 wpa_snprintf_hex(hex
, hexlen
,
1161 wpabuf_head(conf
->c_sign_key
),
1162 wpabuf_len(conf
->c_sign_key
));
1163 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_C_SIGN_KEY
"%s",
1168 if (auth
->net_access_key
) {
1172 hexlen
= 2 * wpabuf_len(auth
->net_access_key
) + 1;
1173 hex
= os_malloc(hexlen
);
1175 wpa_snprintf_hex(hex
, hexlen
,
1176 wpabuf_head(auth
->net_access_key
),
1177 wpabuf_len(auth
->net_access_key
));
1178 if (auth
->net_access_key_expiry
)
1179 wpa_msg(wpa_s
, MSG_INFO
,
1180 DPP_EVENT_NET_ACCESS_KEY
"%s %lu", hex
,
1182 auth
->net_access_key_expiry
);
1184 wpa_msg(wpa_s
, MSG_INFO
,
1185 DPP_EVENT_NET_ACCESS_KEY
"%s", hex
);
1190 return wpas_dpp_process_config(wpa_s
, auth
, conf
);
1194 static void wpas_dpp_gas_resp_cb(void *ctx
, const u8
*addr
, u8 dialog_token
,
1195 enum gas_query_result result
,
1196 const struct wpabuf
*adv_proto
,
1197 const struct wpabuf
*resp
, u16 status_code
)
1199 struct wpa_supplicant
*wpa_s
= ctx
;
1201 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1203 enum dpp_status_error status
= DPP_STATUS_CONFIG_REJECTED
;
1206 wpa_s
->dpp_gas_dialog_token
= -1;
1208 if (!auth
|| !auth
->auth_success
) {
1209 wpa_printf(MSG_DEBUG
, "DPP: No matching exchange in progress");
1212 if (result
!= GAS_QUERY_SUCCESS
||
1213 !resp
|| status_code
!= WLAN_STATUS_SUCCESS
) {
1214 wpa_printf(MSG_DEBUG
, "DPP: GAS query did not succeed");
1218 wpa_hexdump_buf(MSG_DEBUG
, "DPP: Configuration Response adv_proto",
1220 wpa_hexdump_buf(MSG_DEBUG
, "DPP: Configuration Response (GAS response)",
1223 if (wpabuf_len(adv_proto
) != 10 ||
1224 !(pos
= wpabuf_head(adv_proto
)) ||
1225 pos
[0] != WLAN_EID_ADV_PROTO
||
1227 pos
[3] != WLAN_EID_VENDOR_SPECIFIC
||
1229 WPA_GET_BE24(&pos
[5]) != OUI_WFA
||
1232 wpa_printf(MSG_DEBUG
,
1233 "DPP: Not a DPP Advertisement Protocol ID");
1237 if (dpp_conf_resp_rx(auth
, resp
) < 0) {
1238 wpa_printf(MSG_DEBUG
, "DPP: Configuration attempt failed");
1242 for (i
= 0; i
< auth
->num_conf_obj
; i
++) {
1243 res
= wpas_dpp_handle_config_obj(wpa_s
, auth
,
1244 &auth
->conf_obj
[i
]);
1248 if (auth
->num_conf_obj
)
1249 wpas_dpp_post_process_config(wpa_s
, auth
);
1251 status
= DPP_STATUS_OK
;
1252 #ifdef CONFIG_TESTING_OPTIONS
1253 if (dpp_test
== DPP_TEST_REJECT_CONFIG
) {
1254 wpa_printf(MSG_INFO
, "DPP: TESTING - Reject Config Object");
1255 status
= DPP_STATUS_CONFIG_REJECTED
;
1257 #endif /* CONFIG_TESTING_OPTIONS */
1259 if (status
!= DPP_STATUS_OK
)
1260 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
1262 if (auth
->peer_version
>= 2 &&
1263 auth
->conf_resp_status
== DPP_STATUS_OK
) {
1266 wpa_printf(MSG_DEBUG
, "DPP: Send DPP Configuration Result");
1267 msg
= dpp_build_conf_result(auth
, status
);
1271 wpa_msg(wpa_s
, MSG_INFO
,
1272 DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1273 MAC2STR(addr
), auth
->curr_freq
,
1274 DPP_PA_CONFIGURATION_RESULT
);
1275 offchannel_send_action(wpa_s
, auth
->curr_freq
,
1276 addr
, wpa_s
->own_addr
, broadcast
,
1279 500, wpas_dpp_tx_status
, 0);
1282 /* This exchange will be terminated in the TX status handler */
1286 #endif /* CONFIG_DPP2 */
1287 dpp_auth_deinit(wpa_s
->dpp_auth
);
1288 wpa_s
->dpp_auth
= NULL
;
1292 static void wpas_dpp_start_gas_client(struct wpa_supplicant
*wpa_s
)
1294 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1297 int *supp_op_classes
;
1299 wpa_s
->dpp_gas_client
= 1;
1300 offchannel_send_action_done(wpa_s
);
1301 wpas_dpp_listen_stop(wpa_s
);
1303 supp_op_classes
= wpas_supp_op_classes(wpa_s
);
1304 buf
= dpp_build_conf_req_helper(auth
, wpa_s
->conf
->dpp_name
,
1306 wpa_s
->conf
->dpp_mud_url
,
1308 os_free(supp_op_classes
);
1310 wpa_printf(MSG_DEBUG
,
1311 "DPP: No configuration request data available");
1315 wpa_printf(MSG_DEBUG
, "DPP: GAS request to " MACSTR
" (freq %u MHz)",
1316 MAC2STR(auth
->peer_mac_addr
), auth
->curr_freq
);
1318 res
= gas_query_req(wpa_s
->gas
, auth
->peer_mac_addr
, auth
->curr_freq
,
1319 1, buf
, wpas_dpp_gas_resp_cb
, wpa_s
);
1321 wpa_msg(wpa_s
, MSG_DEBUG
, "GAS: Failed to send Query Request");
1324 wpa_printf(MSG_DEBUG
,
1325 "DPP: GAS query started with dialog token %u", res
);
1326 wpa_s
->dpp_gas_dialog_token
= res
;
1331 static void wpas_dpp_auth_success(struct wpa_supplicant
*wpa_s
, int initiator
)
1333 wpa_printf(MSG_DEBUG
, "DPP: Authentication succeeded");
1334 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_AUTH_SUCCESS
"init=%d", initiator
);
1335 #ifdef CONFIG_TESTING_OPTIONS
1336 if (dpp_test
== DPP_TEST_STOP_AT_AUTH_CONF
) {
1337 wpa_printf(MSG_INFO
,
1338 "DPP: TESTING - stop at Authentication Confirm");
1339 if (wpa_s
->dpp_auth
->configurator
) {
1340 /* Prevent GAS response */
1341 wpa_s
->dpp_auth
->auth_success
= 0;
1345 #endif /* CONFIG_TESTING_OPTIONS */
1347 if (wpa_s
->dpp_auth
->configurator
)
1348 wpas_dpp_start_gas_server(wpa_s
);
1350 wpas_dpp_start_gas_client(wpa_s
);
1354 static void wpas_dpp_rx_auth_resp(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1355 const u8
*hdr
, const u8
*buf
, size_t len
,
1358 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1361 wpa_printf(MSG_DEBUG
, "DPP: Authentication Response from " MACSTR
1362 " (freq %u MHz)", MAC2STR(src
), freq
);
1365 wpa_printf(MSG_DEBUG
,
1366 "DPP: No DPP Authentication in progress - drop");
1370 if (!is_zero_ether_addr(auth
->peer_mac_addr
) &&
1371 os_memcmp(src
, auth
->peer_mac_addr
, ETH_ALEN
) != 0) {
1372 wpa_printf(MSG_DEBUG
, "DPP: MAC address mismatch (expected "
1373 MACSTR
") - drop", MAC2STR(auth
->peer_mac_addr
));
1377 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
1379 if (auth
->curr_freq
!= freq
&& auth
->neg_freq
== freq
) {
1380 wpa_printf(MSG_DEBUG
,
1381 "DPP: Responder accepted request for different negotiation channel");
1382 auth
->curr_freq
= freq
;
1385 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
1386 msg
= dpp_auth_resp_rx(auth
, hdr
, buf
, len
);
1388 if (auth
->auth_resp_status
== DPP_STATUS_RESPONSE_PENDING
) {
1389 wpa_printf(MSG_DEBUG
,
1390 "DPP: Start wait for full response");
1391 offchannel_send_action_done(wpa_s
);
1392 wpas_dpp_listen_start(wpa_s
, auth
->curr_freq
);
1395 wpa_printf(MSG_DEBUG
, "DPP: No confirm generated");
1398 os_memcpy(auth
->peer_mac_addr
, src
, ETH_ALEN
);
1400 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1401 MAC2STR(src
), auth
->curr_freq
, DPP_PA_AUTHENTICATION_CONF
);
1402 offchannel_send_action(wpa_s
, auth
->curr_freq
,
1403 src
, wpa_s
->own_addr
, broadcast
,
1404 wpabuf_head(msg
), wpabuf_len(msg
),
1405 500, wpas_dpp_tx_status
, 0);
1407 wpa_s
->dpp_auth_ok_on_ack
= 1;
1411 static void wpas_dpp_rx_auth_conf(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1412 const u8
*hdr
, const u8
*buf
, size_t len
)
1414 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1416 wpa_printf(MSG_DEBUG
, "DPP: Authentication Confirmation from " MACSTR
,
1420 wpa_printf(MSG_DEBUG
,
1421 "DPP: No DPP Authentication in progress - drop");
1425 if (os_memcmp(src
, auth
->peer_mac_addr
, ETH_ALEN
) != 0) {
1426 wpa_printf(MSG_DEBUG
, "DPP: MAC address mismatch (expected "
1427 MACSTR
") - drop", MAC2STR(auth
->peer_mac_addr
));
1431 if (dpp_auth_conf_rx(auth
, hdr
, buf
, len
) < 0) {
1432 wpa_printf(MSG_DEBUG
, "DPP: Authentication failed");
1436 wpas_dpp_auth_success(wpa_s
, 0);
1442 static void wpas_dpp_config_result_wait_timeout(void *eloop_ctx
,
1445 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
1446 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1448 if (!auth
|| !auth
->waiting_conf_result
)
1451 wpa_printf(MSG_DEBUG
,
1452 "DPP: Timeout while waiting for Configuration Result");
1453 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
1454 dpp_auth_deinit(auth
);
1455 wpa_s
->dpp_auth
= NULL
;
1459 static void wpas_dpp_conn_status_result_wait_timeout(void *eloop_ctx
,
1462 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
1463 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1465 if (!auth
|| !auth
->waiting_conn_status_result
)
1468 wpa_printf(MSG_DEBUG
,
1469 "DPP: Timeout while waiting for Connection Status Result");
1470 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONN_STATUS_RESULT
"timeout");
1471 wpas_dpp_listen_stop(wpa_s
);
1472 dpp_auth_deinit(auth
);
1473 wpa_s
->dpp_auth
= NULL
;
1477 static void wpas_dpp_rx_conf_result(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1478 const u8
*hdr
, const u8
*buf
, size_t len
)
1480 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1481 enum dpp_status_error status
;
1483 wpa_printf(MSG_DEBUG
, "DPP: Configuration Result from " MACSTR
,
1486 if (!auth
|| !auth
->waiting_conf_result
) {
1487 wpa_printf(MSG_DEBUG
,
1488 "DPP: No DPP Configuration waiting for result - drop");
1492 if (os_memcmp(src
, auth
->peer_mac_addr
, ETH_ALEN
) != 0) {
1493 wpa_printf(MSG_DEBUG
, "DPP: MAC address mismatch (expected "
1494 MACSTR
") - drop", MAC2STR(auth
->peer_mac_addr
));
1498 status
= dpp_conf_result_rx(auth
, hdr
, buf
, len
);
1500 if (status
== DPP_STATUS_OK
&& auth
->send_conn_status
) {
1501 wpa_msg(wpa_s
, MSG_INFO
,
1502 DPP_EVENT_CONF_SENT
"wait_conn_status=1");
1503 wpa_printf(MSG_DEBUG
, "DPP: Wait for Connection Status Result");
1504 eloop_cancel_timeout(wpas_dpp_config_result_wait_timeout
,
1506 auth
->waiting_conn_status_result
= 1;
1507 eloop_cancel_timeout(wpas_dpp_conn_status_result_wait_timeout
,
1509 eloop_register_timeout(16, 0,
1510 wpas_dpp_conn_status_result_wait_timeout
,
1512 offchannel_send_action_done(wpa_s
);
1513 wpas_dpp_listen_start(wpa_s
, auth
->neg_freq
? auth
->neg_freq
:
1517 offchannel_send_action_done(wpa_s
);
1518 wpas_dpp_listen_stop(wpa_s
);
1519 if (status
== DPP_STATUS_OK
)
1520 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_SENT
);
1522 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
1523 dpp_auth_deinit(auth
);
1524 wpa_s
->dpp_auth
= NULL
;
1525 eloop_cancel_timeout(wpas_dpp_config_result_wait_timeout
, wpa_s
, NULL
);
1529 static void wpas_dpp_rx_conn_status_result(struct wpa_supplicant
*wpa_s
,
1530 const u8
*src
, const u8
*hdr
,
1531 const u8
*buf
, size_t len
)
1533 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1534 enum dpp_status_error status
;
1535 u8 ssid
[SSID_MAX_LEN
];
1536 size_t ssid_len
= 0;
1537 char *channel_list
= NULL
;
1539 wpa_printf(MSG_DEBUG
, "DPP: Connection Status Result");
1541 if (!auth
|| !auth
->waiting_conn_status_result
) {
1542 wpa_printf(MSG_DEBUG
,
1543 "DPP: No DPP Configuration waiting for connection status result - drop");
1547 status
= dpp_conn_status_result_rx(auth
, hdr
, buf
, len
,
1548 ssid
, &ssid_len
, &channel_list
);
1549 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONN_STATUS_RESULT
1550 "result=%d ssid=%s channel_list=%s",
1551 status
, wpa_ssid_txt(ssid
, ssid_len
),
1552 channel_list
? channel_list
: "N/A");
1553 os_free(channel_list
);
1554 offchannel_send_action_done(wpa_s
);
1555 wpas_dpp_listen_stop(wpa_s
);
1556 dpp_auth_deinit(auth
);
1557 wpa_s
->dpp_auth
= NULL
;
1558 eloop_cancel_timeout(wpas_dpp_conn_status_result_wait_timeout
,
1563 static int wpas_dpp_process_conf_obj(void *ctx
,
1564 struct dpp_authentication
*auth
)
1566 struct wpa_supplicant
*wpa_s
= ctx
;
1570 for (i
= 0; i
< auth
->num_conf_obj
; i
++) {
1571 res
= wpas_dpp_handle_config_obj(wpa_s
, auth
,
1572 &auth
->conf_obj
[i
]);
1577 wpas_dpp_post_process_config(wpa_s
, auth
);
1582 #endif /* CONFIG_DPP2 */
1585 static void wpas_dpp_rx_peer_disc_resp(struct wpa_supplicant
*wpa_s
,
1587 const u8
*buf
, size_t len
)
1589 struct wpa_ssid
*ssid
;
1590 const u8
*connector
, *trans_id
, *status
;
1591 u16 connector_len
, trans_id_len
, status_len
;
1592 struct dpp_introduction intro
;
1593 struct rsn_pmksa_cache_entry
*entry
;
1595 struct os_reltime rnow
;
1597 unsigned int seconds
;
1598 enum dpp_status_error res
;
1600 wpa_printf(MSG_DEBUG
, "DPP: Peer Discovery Response from " MACSTR
,
1602 if (is_zero_ether_addr(wpa_s
->dpp_intro_bssid
) ||
1603 os_memcmp(src
, wpa_s
->dpp_intro_bssid
, ETH_ALEN
) != 0) {
1604 wpa_printf(MSG_DEBUG
, "DPP: Not waiting for response from "
1605 MACSTR
" - drop", MAC2STR(src
));
1608 offchannel_send_action_done(wpa_s
);
1610 for (ssid
= wpa_s
->conf
->ssid
; ssid
; ssid
= ssid
->next
) {
1611 if (ssid
== wpa_s
->dpp_intro_network
)
1614 if (!ssid
|| !ssid
->dpp_connector
|| !ssid
->dpp_netaccesskey
||
1616 wpa_printf(MSG_DEBUG
,
1617 "DPP: Profile not found for network introduction");
1621 trans_id
= dpp_get_attr(buf
, len
, DPP_ATTR_TRANSACTION_ID
,
1623 if (!trans_id
|| trans_id_len
!= 1) {
1624 wpa_printf(MSG_DEBUG
,
1625 "DPP: Peer did not include Transaction ID");
1626 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1627 " fail=missing_transaction_id", MAC2STR(src
));
1630 if (trans_id
[0] != TRANSACTION_ID
) {
1631 wpa_printf(MSG_DEBUG
,
1632 "DPP: Ignore frame with unexpected Transaction ID %u",
1634 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1635 " fail=transaction_id_mismatch", MAC2STR(src
));
1639 status
= dpp_get_attr(buf
, len
, DPP_ATTR_STATUS
, &status_len
);
1640 if (!status
|| status_len
!= 1) {
1641 wpa_printf(MSG_DEBUG
, "DPP: Peer did not include Status");
1642 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1643 " fail=missing_status", MAC2STR(src
));
1646 if (status
[0] != DPP_STATUS_OK
) {
1647 wpa_printf(MSG_DEBUG
,
1648 "DPP: Peer rejected network introduction: Status %u",
1650 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1651 " status=%u", MAC2STR(src
), status
[0]);
1653 wpas_dpp_send_conn_status_result(wpa_s
, status
[0]);
1654 #endif /* CONFIG_DPP2 */
1658 connector
= dpp_get_attr(buf
, len
, DPP_ATTR_CONNECTOR
, &connector_len
);
1660 wpa_printf(MSG_DEBUG
,
1661 "DPP: Peer did not include its Connector");
1662 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1663 " fail=missing_connector", MAC2STR(src
));
1667 res
= dpp_peer_intro(&intro
, ssid
->dpp_connector
,
1668 ssid
->dpp_netaccesskey
,
1669 ssid
->dpp_netaccesskey_len
,
1671 ssid
->dpp_csign_len
,
1672 connector
, connector_len
, &expiry
);
1673 if (res
!= DPP_STATUS_OK
) {
1674 wpa_printf(MSG_INFO
,
1675 "DPP: Network Introduction protocol resulted in failure");
1676 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1677 " fail=peer_connector_validation_failed", MAC2STR(src
));
1679 wpas_dpp_send_conn_status_result(wpa_s
, res
);
1680 #endif /* CONFIG_DPP2 */
1684 entry
= os_zalloc(sizeof(*entry
));
1687 os_memcpy(entry
->aa
, src
, ETH_ALEN
);
1688 os_memcpy(entry
->pmkid
, intro
.pmkid
, PMKID_LEN
);
1689 os_memcpy(entry
->pmk
, intro
.pmk
, intro
.pmk_len
);
1690 entry
->pmk_len
= intro
.pmk_len
;
1691 entry
->akmp
= WPA_KEY_MGMT_DPP
;
1694 seconds
= expiry
- now
.sec
;
1696 seconds
= 86400 * 7;
1698 os_get_reltime(&rnow
);
1699 entry
->expiration
= rnow
.sec
+ seconds
;
1700 entry
->reauth_time
= rnow
.sec
+ seconds
;
1701 entry
->network_ctx
= ssid
;
1702 wpa_sm_pmksa_cache_add_entry(wpa_s
->wpa
, entry
);
1704 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1705 " status=%u", MAC2STR(src
), status
[0]);
1707 wpa_printf(MSG_DEBUG
,
1708 "DPP: Try connection again after successful network introduction");
1709 if (wpa_supplicant_fast_associate(wpa_s
) != 1) {
1710 wpa_supplicant_cancel_sched_scan(wpa_s
);
1711 wpa_supplicant_req_scan(wpa_s
, 0, 0);
1714 os_memset(&intro
, 0, sizeof(intro
));
1718 static int wpas_dpp_allow_ir(struct wpa_supplicant
*wpa_s
, unsigned int freq
)
1722 if (!wpa_s
->hw
.modes
)
1725 for (i
= 0; i
< wpa_s
->hw
.num_modes
; i
++) {
1726 struct hostapd_hw_modes
*mode
= &wpa_s
->hw
.modes
[i
];
1728 for (j
= 0; j
< mode
->num_channels
; j
++) {
1729 struct hostapd_channel_data
*chan
= &mode
->channels
[j
];
1731 if (chan
->freq
!= (int) freq
)
1734 if (chan
->flag
& (HOSTAPD_CHAN_DISABLED
|
1735 HOSTAPD_CHAN_NO_IR
|
1736 HOSTAPD_CHAN_RADAR
))
1743 wpa_printf(MSG_DEBUG
,
1744 "DPP: Frequency %u MHz not supported or does not allow PKEX initiation in the current channel list",
1751 static int wpas_dpp_pkex_next_channel(struct wpa_supplicant
*wpa_s
,
1752 struct dpp_pkex
*pkex
)
1754 if (pkex
->freq
== 2437)
1756 else if (pkex
->freq
== 5745)
1758 else if (pkex
->freq
== 5220)
1761 return -1; /* no more channels to try */
1763 if (wpas_dpp_allow_ir(wpa_s
, pkex
->freq
) == 1) {
1764 wpa_printf(MSG_DEBUG
, "DPP: Try to initiate on %u MHz",
1769 /* Could not use this channel - try the next one */
1770 return wpas_dpp_pkex_next_channel(wpa_s
, pkex
);
1774 static void wpas_dpp_pkex_retry_timeout(void *eloop_ctx
, void *timeout_ctx
)
1776 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
1777 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
1779 if (!pkex
|| !pkex
->exchange_req
)
1781 if (pkex
->exch_req_tries
>= 5) {
1782 if (wpas_dpp_pkex_next_channel(wpa_s
, pkex
) < 0) {
1783 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
1784 "No response from PKEX peer");
1785 dpp_pkex_free(pkex
);
1786 wpa_s
->dpp_pkex
= NULL
;
1789 pkex
->exch_req_tries
= 0;
1792 pkex
->exch_req_tries
++;
1793 wpa_printf(MSG_DEBUG
, "DPP: Retransmit PKEX Exchange Request (try %u)",
1794 pkex
->exch_req_tries
);
1795 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1796 MAC2STR(broadcast
), pkex
->freq
, DPP_PA_PKEX_EXCHANGE_REQ
);
1797 offchannel_send_action(wpa_s
, pkex
->freq
, broadcast
,
1798 wpa_s
->own_addr
, broadcast
,
1799 wpabuf_head(pkex
->exchange_req
),
1800 wpabuf_len(pkex
->exchange_req
),
1801 pkex
->exch_req_wait_time
,
1802 wpas_dpp_tx_pkex_status
, 0);
1807 wpas_dpp_tx_pkex_status(struct wpa_supplicant
*wpa_s
,
1808 unsigned int freq
, const u8
*dst
,
1809 const u8
*src
, const u8
*bssid
,
1810 const u8
*data
, size_t data_len
,
1811 enum offchannel_send_action_result result
)
1813 const char *res_txt
;
1814 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
1816 res_txt
= result
== OFFCHANNEL_SEND_ACTION_SUCCESS
? "SUCCESS" :
1817 (result
== OFFCHANNEL_SEND_ACTION_NO_ACK
? "no-ACK" :
1819 wpa_printf(MSG_DEBUG
, "DPP: TX status: freq=%u dst=" MACSTR
1820 " result=%s (PKEX)",
1821 freq
, MAC2STR(dst
), res_txt
);
1822 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX_STATUS
"dst=" MACSTR
1823 " freq=%u result=%s", MAC2STR(dst
), freq
, res_txt
);
1826 wpa_printf(MSG_DEBUG
,
1827 "DPP: Ignore TX status since there is no ongoing PKEX exchange");
1832 wpa_printf(MSG_DEBUG
,
1833 "DPP: Terminate PKEX exchange due to an earlier error");
1834 if (pkex
->t
> pkex
->own_bi
->pkex_t
)
1835 pkex
->own_bi
->pkex_t
= pkex
->t
;
1836 dpp_pkex_free(pkex
);
1837 wpa_s
->dpp_pkex
= NULL
;
1841 if (pkex
->exch_req_wait_time
&& pkex
->exchange_req
) {
1842 /* Wait for PKEX Exchange Response frame and retry request if
1843 * no response is seen. */
1844 eloop_cancel_timeout(wpas_dpp_pkex_retry_timeout
, wpa_s
, NULL
);
1845 eloop_register_timeout(pkex
->exch_req_wait_time
/ 1000,
1846 (pkex
->exch_req_wait_time
% 1000) * 1000,
1847 wpas_dpp_pkex_retry_timeout
, wpa_s
,
1854 wpas_dpp_rx_pkex_exchange_req(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1855 const u8
*buf
, size_t len
, unsigned int freq
)
1858 unsigned int wait_time
;
1860 wpa_printf(MSG_DEBUG
, "DPP: PKEX Exchange Request from " MACSTR
,
1863 /* TODO: Support multiple PKEX codes by iterating over all the enabled
1866 if (!wpa_s
->dpp_pkex_code
|| !wpa_s
->dpp_pkex_bi
) {
1867 wpa_printf(MSG_DEBUG
,
1868 "DPP: No PKEX code configured - ignore request");
1872 if (wpa_s
->dpp_pkex
) {
1873 /* TODO: Support parallel operations */
1874 wpa_printf(MSG_DEBUG
,
1875 "DPP: Already in PKEX session - ignore new request");
1879 wpa_s
->dpp_pkex
= dpp_pkex_rx_exchange_req(wpa_s
, wpa_s
->dpp_pkex_bi
,
1880 wpa_s
->own_addr
, src
,
1881 wpa_s
->dpp_pkex_identifier
,
1882 wpa_s
->dpp_pkex_code
,
1884 if (!wpa_s
->dpp_pkex
) {
1885 wpa_printf(MSG_DEBUG
,
1886 "DPP: Failed to process the request - ignore it");
1890 msg
= wpa_s
->dpp_pkex
->exchange_resp
;
1891 wait_time
= wpa_s
->max_remain_on_chan
;
1892 if (wait_time
> 2000)
1894 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1895 MAC2STR(src
), freq
, DPP_PA_PKEX_EXCHANGE_RESP
);
1896 offchannel_send_action(wpa_s
, freq
, src
, wpa_s
->own_addr
,
1898 wpabuf_head(msg
), wpabuf_len(msg
),
1899 wait_time
, wpas_dpp_tx_pkex_status
, 0);
1904 wpas_dpp_rx_pkex_exchange_resp(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1905 const u8
*buf
, size_t len
, unsigned int freq
)
1908 unsigned int wait_time
;
1910 wpa_printf(MSG_DEBUG
, "DPP: PKEX Exchange Response from " MACSTR
,
1913 /* TODO: Support multiple PKEX codes by iterating over all the enabled
1916 if (!wpa_s
->dpp_pkex
|| !wpa_s
->dpp_pkex
->initiator
||
1917 wpa_s
->dpp_pkex
->exchange_done
) {
1918 wpa_printf(MSG_DEBUG
, "DPP: No matching PKEX session");
1922 eloop_cancel_timeout(wpas_dpp_pkex_retry_timeout
, wpa_s
, NULL
);
1923 wpa_s
->dpp_pkex
->exch_req_wait_time
= 0;
1925 msg
= dpp_pkex_rx_exchange_resp(wpa_s
->dpp_pkex
, src
, buf
, len
);
1927 wpa_printf(MSG_DEBUG
, "DPP: Failed to process the response");
1931 wpa_printf(MSG_DEBUG
, "DPP: Send PKEX Commit-Reveal Request to " MACSTR
,
1934 wait_time
= wpa_s
->max_remain_on_chan
;
1935 if (wait_time
> 2000)
1937 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1938 MAC2STR(src
), freq
, DPP_PA_PKEX_COMMIT_REVEAL_REQ
);
1939 offchannel_send_action(wpa_s
, freq
, src
, wpa_s
->own_addr
,
1941 wpabuf_head(msg
), wpabuf_len(msg
),
1942 wait_time
, wpas_dpp_tx_pkex_status
, 0);
1947 static struct dpp_bootstrap_info
*
1948 wpas_dpp_pkex_finish(struct wpa_supplicant
*wpa_s
, const u8
*peer
,
1951 struct dpp_bootstrap_info
*bi
;
1953 bi
= dpp_pkex_finish(wpa_s
->dpp
, wpa_s
->dpp_pkex
, peer
, freq
);
1956 wpa_s
->dpp_pkex
= NULL
;
1962 wpas_dpp_rx_pkex_commit_reveal_req(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1963 const u8
*hdr
, const u8
*buf
, size_t len
,
1967 unsigned int wait_time
;
1968 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
1970 wpa_printf(MSG_DEBUG
, "DPP: PKEX Commit-Reveal Request from " MACSTR
,
1973 if (!pkex
|| pkex
->initiator
|| !pkex
->exchange_done
) {
1974 wpa_printf(MSG_DEBUG
, "DPP: No matching PKEX session");
1978 msg
= dpp_pkex_rx_commit_reveal_req(pkex
, hdr
, buf
, len
);
1980 wpa_printf(MSG_DEBUG
, "DPP: Failed to process the request");
1982 wpa_printf(MSG_DEBUG
, "DPP: Terminate PKEX exchange");
1983 if (pkex
->t
> pkex
->own_bi
->pkex_t
)
1984 pkex
->own_bi
->pkex_t
= pkex
->t
;
1985 dpp_pkex_free(wpa_s
->dpp_pkex
);
1986 wpa_s
->dpp_pkex
= NULL
;
1991 wpa_printf(MSG_DEBUG
, "DPP: Send PKEX Commit-Reveal Response to "
1992 MACSTR
, MAC2STR(src
));
1994 wait_time
= wpa_s
->max_remain_on_chan
;
1995 if (wait_time
> 2000)
1997 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1998 MAC2STR(src
), freq
, DPP_PA_PKEX_COMMIT_REVEAL_RESP
);
1999 offchannel_send_action(wpa_s
, freq
, src
, wpa_s
->own_addr
,
2001 wpabuf_head(msg
), wpabuf_len(msg
),
2002 wait_time
, wpas_dpp_tx_pkex_status
, 0);
2005 wpas_dpp_pkex_finish(wpa_s
, src
, freq
);
2010 wpas_dpp_rx_pkex_commit_reveal_resp(struct wpa_supplicant
*wpa_s
, const u8
*src
,
2011 const u8
*hdr
, const u8
*buf
, size_t len
,
2015 struct dpp_bootstrap_info
*bi
;
2016 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
2019 wpa_printf(MSG_DEBUG
, "DPP: PKEX Commit-Reveal Response from " MACSTR
,
2022 if (!pkex
|| !pkex
->initiator
|| !pkex
->exchange_done
) {
2023 wpa_printf(MSG_DEBUG
, "DPP: No matching PKEX session");
2027 res
= dpp_pkex_rx_commit_reveal_resp(pkex
, hdr
, buf
, len
);
2029 wpa_printf(MSG_DEBUG
, "DPP: Failed to process the response");
2033 bi
= wpas_dpp_pkex_finish(wpa_s
, src
, freq
);
2037 os_snprintf(cmd
, sizeof(cmd
), " peer=%u %s",
2039 wpa_s
->dpp_pkex_auth_cmd
? wpa_s
->dpp_pkex_auth_cmd
: "");
2040 wpa_printf(MSG_DEBUG
,
2041 "DPP: Start authentication after PKEX with parameters: %s",
2043 if (wpas_dpp_auth_init(wpa_s
, cmd
) < 0) {
2044 wpa_printf(MSG_DEBUG
,
2045 "DPP: Authentication initialization failed");
2051 void wpas_dpp_rx_action(struct wpa_supplicant
*wpa_s
, const u8
*src
,
2052 const u8
*buf
, size_t len
, unsigned int freq
)
2055 enum dpp_public_action_frame_type type
;
2057 unsigned int pkex_t
;
2059 if (len
< DPP_HDR_LEN
)
2061 if (WPA_GET_BE24(buf
) != OUI_WFA
|| buf
[3] != DPP_OUI_TYPE
)
2066 crypto_suite
= *buf
++;
2070 wpa_printf(MSG_DEBUG
,
2071 "DPP: Received DPP Public Action frame crypto suite %u type %d from "
2073 crypto_suite
, type
, MAC2STR(src
), freq
);
2074 if (crypto_suite
!= 1) {
2075 wpa_printf(MSG_DEBUG
, "DPP: Unsupported crypto suite %u",
2077 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_RX
"src=" MACSTR
2078 " freq=%u type=%d ignore=unsupported-crypto-suite",
2079 MAC2STR(src
), freq
, type
);
2082 wpa_hexdump(MSG_MSGDUMP
, "DPP: Received message attributes", buf
, len
);
2083 if (dpp_check_attrs(buf
, len
) < 0) {
2084 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_RX
"src=" MACSTR
2085 " freq=%u type=%d ignore=invalid-attributes",
2086 MAC2STR(src
), freq
, type
);
2089 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_RX
"src=" MACSTR
" freq=%u type=%d",
2090 MAC2STR(src
), freq
, type
);
2093 case DPP_PA_AUTHENTICATION_REQ
:
2094 wpas_dpp_rx_auth_req(wpa_s
, src
, hdr
, buf
, len
, freq
);
2096 case DPP_PA_AUTHENTICATION_RESP
:
2097 wpas_dpp_rx_auth_resp(wpa_s
, src
, hdr
, buf
, len
, freq
);
2099 case DPP_PA_AUTHENTICATION_CONF
:
2100 wpas_dpp_rx_auth_conf(wpa_s
, src
, hdr
, buf
, len
);
2102 case DPP_PA_PEER_DISCOVERY_RESP
:
2103 wpas_dpp_rx_peer_disc_resp(wpa_s
, src
, buf
, len
);
2105 case DPP_PA_PKEX_EXCHANGE_REQ
:
2106 wpas_dpp_rx_pkex_exchange_req(wpa_s
, src
, buf
, len
, freq
);
2108 case DPP_PA_PKEX_EXCHANGE_RESP
:
2109 wpas_dpp_rx_pkex_exchange_resp(wpa_s
, src
, buf
, len
, freq
);
2111 case DPP_PA_PKEX_COMMIT_REVEAL_REQ
:
2112 wpas_dpp_rx_pkex_commit_reveal_req(wpa_s
, src
, hdr
, buf
, len
,
2115 case DPP_PA_PKEX_COMMIT_REVEAL_RESP
:
2116 wpas_dpp_rx_pkex_commit_reveal_resp(wpa_s
, src
, hdr
, buf
, len
,
2120 case DPP_PA_CONFIGURATION_RESULT
:
2121 wpas_dpp_rx_conf_result(wpa_s
, src
, hdr
, buf
, len
);
2123 case DPP_PA_CONNECTION_STATUS_RESULT
:
2124 wpas_dpp_rx_conn_status_result(wpa_s
, src
, hdr
, buf
, len
);
2126 #endif /* CONFIG_DPP2 */
2128 wpa_printf(MSG_DEBUG
,
2129 "DPP: Ignored unsupported frame subtype %d", type
);
2133 if (wpa_s
->dpp_pkex
)
2134 pkex_t
= wpa_s
->dpp_pkex
->t
;
2135 else if (wpa_s
->dpp_pkex_bi
)
2136 pkex_t
= wpa_s
->dpp_pkex_bi
->pkex_t
;
2139 if (pkex_t
>= PKEX_COUNTER_T_LIMIT
) {
2140 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_PKEX_T_LIMIT
"id=0");
2141 wpas_dpp_pkex_remove(wpa_s
, "*");
2146 static struct wpabuf
*
2147 wpas_dpp_gas_req_handler(void *ctx
, const u8
*sa
, const u8
*query
,
2150 struct wpa_supplicant
*wpa_s
= ctx
;
2151 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
2152 struct wpabuf
*resp
;
2154 wpa_printf(MSG_DEBUG
, "DPP: GAS request from " MACSTR
,
2156 if (!auth
|| !auth
->auth_success
||
2157 os_memcmp(sa
, auth
->peer_mac_addr
, ETH_ALEN
) != 0) {
2158 wpa_printf(MSG_DEBUG
, "DPP: No matching exchange in progress");
2162 if (wpa_s
->dpp_auth_ok_on_ack
&& auth
->configurator
) {
2163 wpa_printf(MSG_DEBUG
,
2164 "DPP: Have not received ACK for Auth Confirm yet - assume it was received based on this GAS request");
2165 /* wpas_dpp_auth_success() would normally have been called from
2166 * TX status handler, but since there was no such handler call
2167 * yet, simply send out the event message and proceed with
2169 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_AUTH_SUCCESS
"init=1");
2170 wpa_s
->dpp_auth_ok_on_ack
= 0;
2173 wpa_hexdump(MSG_DEBUG
,
2174 "DPP: Received Configuration Request (GAS Query Request)",
2176 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_REQ_RX
"src=" MACSTR
,
2178 resp
= dpp_conf_req_rx(auth
, query
, query_len
);
2180 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
2181 auth
->conf_resp
= resp
;
2187 wpas_dpp_gas_status_handler(void *ctx
, struct wpabuf
*resp
, int ok
)
2189 struct wpa_supplicant
*wpa_s
= ctx
;
2190 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
2196 if (auth
->conf_resp
!= resp
) {
2197 wpa_printf(MSG_DEBUG
,
2198 "DPP: Ignore GAS status report (ok=%d) for unknown response",
2204 wpa_printf(MSG_DEBUG
, "DPP: Configuration exchange completed (ok=%d)",
2206 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
2207 eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout
, wpa_s
, NULL
);
2209 if (ok
&& auth
->peer_version
>= 2 &&
2210 auth
->conf_resp_status
== DPP_STATUS_OK
) {
2211 wpa_printf(MSG_DEBUG
, "DPP: Wait for Configuration Result");
2212 auth
->waiting_conf_result
= 1;
2213 auth
->conf_resp
= NULL
;
2215 eloop_cancel_timeout(wpas_dpp_config_result_wait_timeout
,
2217 eloop_register_timeout(2, 0,
2218 wpas_dpp_config_result_wait_timeout
,
2222 #endif /* CONFIG_DPP2 */
2223 offchannel_send_action_done(wpa_s
);
2224 wpas_dpp_listen_stop(wpa_s
);
2226 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_SENT
);
2228 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
2229 dpp_auth_deinit(wpa_s
->dpp_auth
);
2230 wpa_s
->dpp_auth
= NULL
;
2235 int wpas_dpp_configurator_sign(struct wpa_supplicant
*wpa_s
, const char *cmd
)
2237 struct dpp_authentication
*auth
;
2241 auth
= os_zalloc(sizeof(*auth
));
2245 curve
= get_param(cmd
, " curve=");
2246 wpas_dpp_set_testing_options(wpa_s
, auth
);
2247 if (dpp_set_configurator(wpa_s
->dpp
, wpa_s
, auth
, cmd
) == 0 &&
2248 dpp_configurator_own_config(auth
, curve
, 0) == 0)
2249 ret
= wpas_dpp_handle_config_obj(wpa_s
, auth
,
2250 &auth
->conf_obj
[0]);
2252 wpas_dpp_post_process_config(wpa_s
, auth
);
2254 dpp_auth_deinit(auth
);
2262 wpas_dpp_tx_introduction_status(struct wpa_supplicant
*wpa_s
,
2263 unsigned int freq
, const u8
*dst
,
2264 const u8
*src
, const u8
*bssid
,
2265 const u8
*data
, size_t data_len
,
2266 enum offchannel_send_action_result result
)
2268 const char *res_txt
;
2270 res_txt
= result
== OFFCHANNEL_SEND_ACTION_SUCCESS
? "SUCCESS" :
2271 (result
== OFFCHANNEL_SEND_ACTION_NO_ACK
? "no-ACK" :
2273 wpa_printf(MSG_DEBUG
, "DPP: TX status: freq=%u dst=" MACSTR
2274 " result=%s (DPP Peer Discovery Request)",
2275 freq
, MAC2STR(dst
), res_txt
);
2276 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX_STATUS
"dst=" MACSTR
2277 " freq=%u result=%s", MAC2STR(dst
), freq
, res_txt
);
2278 /* TODO: Time out wait for response more quickly in error cases? */
2282 int wpas_dpp_check_connect(struct wpa_supplicant
*wpa_s
, struct wpa_ssid
*ssid
,
2283 struct wpa_bss
*bss
)
2287 unsigned int wait_time
;
2289 struct wpa_ie_data ied
;
2291 if (!(ssid
->key_mgmt
& WPA_KEY_MGMT_DPP
) || !bss
)
2292 return 0; /* Not using DPP AKM - continue */
2293 rsn
= wpa_bss_get_ie(bss
, WLAN_EID_RSN
);
2294 if (rsn
&& wpa_parse_wpa_ie(rsn
, 2 + rsn
[1], &ied
) == 0 &&
2295 !(ied
.key_mgmt
& WPA_KEY_MGMT_DPP
))
2296 return 0; /* AP does not support DPP AKM - continue */
2297 if (wpa_sm_pmksa_exists(wpa_s
->wpa
, bss
->bssid
, ssid
))
2298 return 0; /* PMKSA exists for DPP AKM - continue */
2300 if (!ssid
->dpp_connector
|| !ssid
->dpp_netaccesskey
||
2302 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_MISSING_CONNECTOR
2304 !ssid
->dpp_connector
? "Connector" :
2305 (!ssid
->dpp_netaccesskey
? "netAccessKey" :
2312 if (ssid
->dpp_netaccesskey_expiry
&&
2313 (os_time_t
) ssid
->dpp_netaccesskey_expiry
< now
.sec
) {
2314 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_MISSING_CONNECTOR
2315 "netAccessKey expired");
2319 wpa_printf(MSG_DEBUG
,
2320 "DPP: Starting network introduction protocol to derive PMKSA for "
2321 MACSTR
, MAC2STR(bss
->bssid
));
2323 msg
= dpp_alloc_msg(DPP_PA_PEER_DISCOVERY_REQ
,
2324 5 + 4 + os_strlen(ssid
->dpp_connector
));
2328 #ifdef CONFIG_TESTING_OPTIONS
2329 if (dpp_test
== DPP_TEST_NO_TRANSACTION_ID_PEER_DISC_REQ
) {
2330 wpa_printf(MSG_INFO
, "DPP: TESTING - no Transaction ID");
2333 if (dpp_test
== DPP_TEST_INVALID_TRANSACTION_ID_PEER_DISC_REQ
) {
2334 wpa_printf(MSG_INFO
, "DPP: TESTING - invalid Transaction ID");
2335 wpabuf_put_le16(msg
, DPP_ATTR_TRANSACTION_ID
);
2336 wpabuf_put_le16(msg
, 0);
2339 #endif /* CONFIG_TESTING_OPTIONS */
2341 /* Transaction ID */
2342 wpabuf_put_le16(msg
, DPP_ATTR_TRANSACTION_ID
);
2343 wpabuf_put_le16(msg
, 1);
2344 wpabuf_put_u8(msg
, TRANSACTION_ID
);
2346 #ifdef CONFIG_TESTING_OPTIONS
2348 if (dpp_test
== DPP_TEST_NO_CONNECTOR_PEER_DISC_REQ
) {
2349 wpa_printf(MSG_INFO
, "DPP: TESTING - no Connector");
2350 goto skip_connector
;
2352 if (dpp_test
== DPP_TEST_INVALID_CONNECTOR_PEER_DISC_REQ
) {
2355 wpa_printf(MSG_INFO
, "DPP: TESTING - invalid Connector");
2356 connector
= dpp_corrupt_connector_signature(
2357 ssid
->dpp_connector
);
2362 wpabuf_put_le16(msg
, DPP_ATTR_CONNECTOR
);
2363 wpabuf_put_le16(msg
, os_strlen(connector
));
2364 wpabuf_put_str(msg
, connector
);
2366 goto skip_connector
;
2368 #endif /* CONFIG_TESTING_OPTIONS */
2371 wpabuf_put_le16(msg
, DPP_ATTR_CONNECTOR
);
2372 wpabuf_put_le16(msg
, os_strlen(ssid
->dpp_connector
));
2373 wpabuf_put_str(msg
, ssid
->dpp_connector
);
2375 #ifdef CONFIG_TESTING_OPTIONS
2377 #endif /* CONFIG_TESTING_OPTIONS */
2379 /* TODO: Timeout on AP response */
2380 wait_time
= wpa_s
->max_remain_on_chan
;
2381 if (wait_time
> 2000)
2383 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
2384 MAC2STR(bss
->bssid
), bss
->freq
, DPP_PA_PEER_DISCOVERY_REQ
);
2385 offchannel_send_action(wpa_s
, bss
->freq
, bss
->bssid
, wpa_s
->own_addr
,
2387 wpabuf_head(msg
), wpabuf_len(msg
),
2388 wait_time
, wpas_dpp_tx_introduction_status
, 0);
2391 /* Request this connection attempt to terminate - new one will be
2392 * started when network introduction protocol completes */
2393 os_memcpy(wpa_s
->dpp_intro_bssid
, bss
->bssid
, ETH_ALEN
);
2394 wpa_s
->dpp_intro_network
= ssid
;
2399 int wpas_dpp_pkex_add(struct wpa_supplicant
*wpa_s
, const char *cmd
)
2401 struct dpp_bootstrap_info
*own_bi
;
2402 const char *pos
, *end
;
2403 unsigned int wait_time
;
2405 pos
= os_strstr(cmd
, " own=");
2409 own_bi
= dpp_bootstrap_get_id(wpa_s
->dpp
, atoi(pos
));
2411 wpa_printf(MSG_DEBUG
,
2412 "DPP: Identified bootstrap info not found");
2415 if (own_bi
->type
!= DPP_BOOTSTRAP_PKEX
) {
2416 wpa_printf(MSG_DEBUG
,
2417 "DPP: Identified bootstrap info not for PKEX");
2420 wpa_s
->dpp_pkex_bi
= own_bi
;
2421 own_bi
->pkex_t
= 0; /* clear pending errors on new code */
2423 os_free(wpa_s
->dpp_pkex_identifier
);
2424 wpa_s
->dpp_pkex_identifier
= NULL
;
2425 pos
= os_strstr(cmd
, " identifier=");
2428 end
= os_strchr(pos
, ' ');
2431 wpa_s
->dpp_pkex_identifier
= os_malloc(end
- pos
+ 1);
2432 if (!wpa_s
->dpp_pkex_identifier
)
2434 os_memcpy(wpa_s
->dpp_pkex_identifier
, pos
, end
- pos
);
2435 wpa_s
->dpp_pkex_identifier
[end
- pos
] = '\0';
2438 pos
= os_strstr(cmd
, " code=");
2441 os_free(wpa_s
->dpp_pkex_code
);
2442 wpa_s
->dpp_pkex_code
= os_strdup(pos
+ 6);
2443 if (!wpa_s
->dpp_pkex_code
)
2446 if (os_strstr(cmd
, " init=1")) {
2447 struct dpp_pkex
*pkex
;
2450 wpa_printf(MSG_DEBUG
, "DPP: Initiating PKEX");
2451 dpp_pkex_free(wpa_s
->dpp_pkex
);
2452 wpa_s
->dpp_pkex
= dpp_pkex_init(wpa_s
, own_bi
, wpa_s
->own_addr
,
2453 wpa_s
->dpp_pkex_identifier
,
2454 wpa_s
->dpp_pkex_code
);
2455 pkex
= wpa_s
->dpp_pkex
;
2459 msg
= pkex
->exchange_req
;
2460 wait_time
= wpa_s
->max_remain_on_chan
;
2461 if (wait_time
> 2000)
2464 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
2466 MAC2STR(broadcast
), pkex
->freq
,
2467 DPP_PA_PKEX_EXCHANGE_REQ
);
2468 offchannel_send_action(wpa_s
, pkex
->freq
, broadcast
,
2469 wpa_s
->own_addr
, broadcast
,
2470 wpabuf_head(msg
), wpabuf_len(msg
),
2471 wait_time
, wpas_dpp_tx_pkex_status
, 0);
2474 pkex
->exch_req_wait_time
= wait_time
;
2475 pkex
->exch_req_tries
= 1;
2478 /* TODO: Support multiple PKEX info entries */
2480 os_free(wpa_s
->dpp_pkex_auth_cmd
);
2481 wpa_s
->dpp_pkex_auth_cmd
= os_strdup(cmd
);
2487 int wpas_dpp_pkex_remove(struct wpa_supplicant
*wpa_s
, const char *id
)
2489 unsigned int id_val
;
2491 if (os_strcmp(id
, "*") == 0) {
2499 if ((id_val
!= 0 && id_val
!= 1) || !wpa_s
->dpp_pkex_code
)
2502 /* TODO: Support multiple PKEX entries */
2503 os_free(wpa_s
->dpp_pkex_code
);
2504 wpa_s
->dpp_pkex_code
= NULL
;
2505 os_free(wpa_s
->dpp_pkex_identifier
);
2506 wpa_s
->dpp_pkex_identifier
= NULL
;
2507 os_free(wpa_s
->dpp_pkex_auth_cmd
);
2508 wpa_s
->dpp_pkex_auth_cmd
= NULL
;
2509 wpa_s
->dpp_pkex_bi
= NULL
;
2510 /* TODO: Remove dpp_pkex only if it is for the identified PKEX code */
2511 dpp_pkex_free(wpa_s
->dpp_pkex
);
2512 wpa_s
->dpp_pkex
= NULL
;
2517 void wpas_dpp_stop(struct wpa_supplicant
*wpa_s
)
2519 dpp_auth_deinit(wpa_s
->dpp_auth
);
2520 wpa_s
->dpp_auth
= NULL
;
2521 dpp_pkex_free(wpa_s
->dpp_pkex
);
2522 wpa_s
->dpp_pkex
= NULL
;
2523 if (wpa_s
->dpp_gas_client
&& wpa_s
->dpp_gas_dialog_token
>= 0)
2524 gas_query_stop(wpa_s
->gas
, wpa_s
->dpp_gas_dialog_token
);
2528 int wpas_dpp_init(struct wpa_supplicant
*wpa_s
)
2530 struct dpp_global_config config
;
2533 adv_proto_id
[0] = WLAN_EID_VENDOR_SPECIFIC
;
2534 adv_proto_id
[1] = 5;
2535 WPA_PUT_BE24(&adv_proto_id
[2], OUI_WFA
);
2536 adv_proto_id
[5] = DPP_OUI_TYPE
;
2537 adv_proto_id
[6] = 0x01;
2539 if (gas_server_register(wpa_s
->gas_server
, adv_proto_id
,
2540 sizeof(adv_proto_id
), wpas_dpp_gas_req_handler
,
2541 wpas_dpp_gas_status_handler
, wpa_s
) < 0)
2544 os_memset(&config
, 0, sizeof(config
));
2545 config
.msg_ctx
= wpa_s
;
2546 config
.cb_ctx
= wpa_s
;
2548 config
.process_conf_obj
= wpas_dpp_process_conf_obj
;
2549 #endif /* CONFIG_DPP2 */
2550 wpa_s
->dpp
= dpp_global_init(&config
);
2551 return wpa_s
->dpp
? 0 : -1;
2555 void wpas_dpp_deinit(struct wpa_supplicant
*wpa_s
)
2557 #ifdef CONFIG_TESTING_OPTIONS
2558 os_free(wpa_s
->dpp_config_obj_override
);
2559 wpa_s
->dpp_config_obj_override
= NULL
;
2560 os_free(wpa_s
->dpp_discovery_override
);
2561 wpa_s
->dpp_discovery_override
= NULL
;
2562 os_free(wpa_s
->dpp_groups_override
);
2563 wpa_s
->dpp_groups_override
= NULL
;
2564 wpa_s
->dpp_ignore_netaccesskey_mismatch
= 0;
2565 #endif /* CONFIG_TESTING_OPTIONS */
2568 dpp_global_clear(wpa_s
->dpp
);
2569 eloop_cancel_timeout(wpas_dpp_pkex_retry_timeout
, wpa_s
, NULL
);
2570 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
2571 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
2572 eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout
, wpa_s
, NULL
);
2574 eloop_cancel_timeout(wpas_dpp_config_result_wait_timeout
, wpa_s
, NULL
);
2575 eloop_cancel_timeout(wpas_dpp_conn_status_result_wait_timeout
,
2577 eloop_cancel_timeout(wpas_dpp_conn_status_result_timeout
, wpa_s
, NULL
);
2578 dpp_pfs_free(wpa_s
->dpp_pfs
);
2579 wpa_s
->dpp_pfs
= NULL
;
2580 #endif /* CONFIG_DPP2 */
2581 offchannel_send_action_done(wpa_s
);
2582 wpas_dpp_listen_stop(wpa_s
);
2583 wpas_dpp_stop(wpa_s
);
2584 wpas_dpp_pkex_remove(wpa_s
, "*");
2585 os_memset(wpa_s
->dpp_intro_bssid
, 0, ETH_ALEN
);
2586 os_free(wpa_s
->dpp_configurator_params
);
2587 wpa_s
->dpp_configurator_params
= NULL
;
2592 int wpas_dpp_controller_start(struct wpa_supplicant
*wpa_s
, const char *cmd
)
2594 struct dpp_controller_config config
;
2597 os_memset(&config
, 0, sizeof(config
));
2599 pos
= os_strstr(cmd
, " tcp_port=");
2602 config
.tcp_port
= atoi(pos
);
2605 config
.configurator_params
= wpa_s
->dpp_configurator_params
;
2606 return dpp_controller_start(wpa_s
->dpp
, &config
);
2608 #endif /* CONFIG_DPP2 */