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 if (wpa_s
->wpa_state
== WPA_SCANNING
)
201 wpas_abort_ongoing_scan(wpa_s
);
202 wpas_dpp_send_conn_status_result(wpa_s
, result
);
206 static char * wpas_dpp_scan_channel_list(struct wpa_supplicant
*wpa_s
)
208 char *str
, *end
, *pos
;
211 u8 last_op_class
= 0;
214 if (!wpa_s
->last_scan_freqs
|| !wpa_s
->num_last_scan_freqs
)
217 len
= wpa_s
->num_last_scan_freqs
* 8;
218 str
= os_zalloc(len
);
224 for (i
= 0; i
< wpa_s
->num_last_scan_freqs
; i
++) {
225 enum hostapd_hw_mode mode
;
226 u8 op_class
, channel
;
228 mode
= ieee80211_freq_to_channel_ext(wpa_s
->last_scan_freqs
[i
],
229 0, 0, &op_class
, &channel
);
230 if (mode
== NUM_HOSTAPD_MODES
)
232 if (op_class
== last_op_class
)
233 res
= os_snprintf(pos
, end
- pos
, ",%d", channel
);
235 res
= os_snprintf(pos
, end
- pos
, "%s%d/%d",
236 pos
== str
? "" : ",",
238 if (os_snprintf_error(end
- pos
, res
)) {
243 last_op_class
= op_class
;
254 void wpas_dpp_send_conn_status_result(struct wpa_supplicant
*wpa_s
,
255 enum dpp_status_error result
)
258 const char *channel_list
= NULL
;
259 char *channel_list_buf
= NULL
;
260 struct wpa_ssid
*ssid
= wpa_s
->current_ssid
;
261 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
263 eloop_cancel_timeout(wpas_dpp_conn_status_result_timeout
, wpa_s
, NULL
);
265 if (!auth
|| !auth
->conn_status_requested
)
267 auth
->conn_status_requested
= 0;
268 wpa_printf(MSG_DEBUG
, "DPP: Report connection status result %d",
271 if (result
== DPP_STATUS_NO_AP
) {
272 channel_list_buf
= wpas_dpp_scan_channel_list(wpa_s
);
273 channel_list
= channel_list_buf
;
276 msg
= dpp_build_conn_status_result(auth
, result
,
278 wpa_s
->dpp_last_ssid
,
279 ssid
? ssid
->ssid_len
:
280 wpa_s
->dpp_last_ssid_len
,
282 os_free(channel_list_buf
);
284 dpp_auth_deinit(wpa_s
->dpp_auth
);
285 wpa_s
->dpp_auth
= NULL
;
289 wpa_msg(wpa_s
, MSG_INFO
,
290 DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
291 MAC2STR(auth
->peer_mac_addr
), auth
->curr_freq
,
292 DPP_PA_CONNECTION_STATUS_RESULT
);
293 offchannel_send_action(wpa_s
, auth
->curr_freq
,
294 auth
->peer_mac_addr
, wpa_s
->own_addr
, broadcast
,
295 wpabuf_head(msg
), wpabuf_len(msg
),
296 500, wpas_dpp_tx_status
, 0);
299 /* This exchange will be terminated in the TX status handler */
300 auth
->remove_on_tx_status
= 1;
306 void wpas_dpp_connected(struct wpa_supplicant
*wpa_s
)
308 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
310 if (auth
&& auth
->conn_status_requested
)
311 wpas_dpp_send_conn_status_result(wpa_s
, DPP_STATUS_OK
);
314 #endif /* CONFIG_DPP2 */
317 static void wpas_dpp_tx_status(struct wpa_supplicant
*wpa_s
,
318 unsigned int freq
, const u8
*dst
,
319 const u8
*src
, const u8
*bssid
,
320 const u8
*data
, size_t data_len
,
321 enum offchannel_send_action_result result
)
324 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
326 res_txt
= result
== OFFCHANNEL_SEND_ACTION_SUCCESS
? "SUCCESS" :
327 (result
== OFFCHANNEL_SEND_ACTION_NO_ACK
? "no-ACK" :
329 wpa_printf(MSG_DEBUG
, "DPP: TX status: freq=%u dst=" MACSTR
330 " result=%s", freq
, MAC2STR(dst
), res_txt
);
331 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX_STATUS
"dst=" MACSTR
332 " freq=%u result=%s", MAC2STR(dst
), freq
, res_txt
);
334 if (!wpa_s
->dpp_auth
) {
335 wpa_printf(MSG_DEBUG
,
336 "DPP: Ignore TX status since there is no ongoing authentication exchange");
341 if (auth
->connect_on_tx_status
) {
342 auth
->connect_on_tx_status
= 0;
343 wpa_printf(MSG_DEBUG
,
344 "DPP: Try to connect after completed configuration result");
345 wpas_dpp_try_to_connect(wpa_s
);
346 if (auth
->conn_status_requested
) {
347 wpa_printf(MSG_DEBUG
,
348 "DPP: Start 15 second timeout for reporting connection status result");
349 eloop_cancel_timeout(
350 wpas_dpp_conn_status_result_timeout
,
352 eloop_register_timeout(
353 15, 0, wpas_dpp_conn_status_result_timeout
,
356 dpp_auth_deinit(wpa_s
->dpp_auth
);
357 wpa_s
->dpp_auth
= NULL
;
361 #endif /* CONFIG_DPP2 */
363 if (wpa_s
->dpp_auth
->remove_on_tx_status
) {
364 wpa_printf(MSG_DEBUG
,
365 "DPP: Terminate authentication exchange due to a request to do so on TX status");
366 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
367 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
368 eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout
, wpa_s
,
370 offchannel_send_action_done(wpa_s
);
371 dpp_auth_deinit(wpa_s
->dpp_auth
);
372 wpa_s
->dpp_auth
= NULL
;
376 if (wpa_s
->dpp_auth_ok_on_ack
)
377 wpas_dpp_auth_success(wpa_s
, 1);
379 if (!is_broadcast_ether_addr(dst
) &&
380 result
!= OFFCHANNEL_SEND_ACTION_SUCCESS
) {
381 wpa_printf(MSG_DEBUG
,
382 "DPP: Unicast DPP Action frame was not ACKed");
383 if (auth
->waiting_auth_resp
) {
384 /* In case of DPP Authentication Request frame, move to
385 * the next channel immediately. */
386 offchannel_send_action_done(wpa_s
);
387 wpas_dpp_auth_init_next(wpa_s
);
390 if (auth
->waiting_auth_conf
) {
391 wpas_dpp_auth_resp_retry(wpa_s
);
396 if (!is_broadcast_ether_addr(dst
) && auth
->waiting_auth_resp
&&
397 result
== OFFCHANNEL_SEND_ACTION_SUCCESS
) {
398 /* Allow timeout handling to stop iteration if no response is
399 * received from a peer that has ACKed a request. */
400 auth
->auth_req_ack
= 1;
403 if (!wpa_s
->dpp_auth_ok_on_ack
&& wpa_s
->dpp_auth
->neg_freq
> 0 &&
404 wpa_s
->dpp_auth
->curr_freq
!= wpa_s
->dpp_auth
->neg_freq
) {
405 wpa_printf(MSG_DEBUG
,
406 "DPP: Move from curr_freq %u MHz to neg_freq %u MHz for response",
407 wpa_s
->dpp_auth
->curr_freq
,
408 wpa_s
->dpp_auth
->neg_freq
);
409 offchannel_send_action_done(wpa_s
);
410 wpas_dpp_listen_start(wpa_s
, wpa_s
->dpp_auth
->neg_freq
);
413 if (wpa_s
->dpp_auth_ok_on_ack
)
414 wpa_s
->dpp_auth_ok_on_ack
= 0;
418 static void wpas_dpp_reply_wait_timeout(void *eloop_ctx
, void *timeout_ctx
)
420 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
421 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
423 struct os_reltime now
, diff
;
424 unsigned int wait_time
, diff_ms
;
426 if (!auth
|| !auth
->waiting_auth_resp
)
429 wait_time
= wpa_s
->dpp_resp_wait_time
?
430 wpa_s
->dpp_resp_wait_time
: 2000;
431 os_get_reltime(&now
);
432 os_reltime_sub(&now
, &wpa_s
->dpp_last_init
, &diff
);
433 diff_ms
= diff
.sec
* 1000 + diff
.usec
/ 1000;
434 wpa_printf(MSG_DEBUG
,
435 "DPP: Reply wait timeout - wait_time=%u diff_ms=%u",
438 if (auth
->auth_req_ack
&& diff_ms
>= wait_time
) {
439 /* Peer ACK'ed Authentication Request frame, but did not reply
440 * with Authentication Response frame within two seconds. */
442 "DPP: No response received from responder - stopping initiation attempt");
443 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_AUTH_INIT_FAILED
);
444 offchannel_send_action_done(wpa_s
);
445 wpas_dpp_listen_stop(wpa_s
);
446 dpp_auth_deinit(auth
);
447 wpa_s
->dpp_auth
= NULL
;
451 if (diff_ms
>= wait_time
) {
452 /* Authentication Request frame was not ACK'ed and no reply
453 * was receiving within two seconds. */
454 wpa_printf(MSG_DEBUG
,
455 "DPP: Continue Initiator channel iteration");
456 offchannel_send_action_done(wpa_s
);
457 wpas_dpp_listen_stop(wpa_s
);
458 wpas_dpp_auth_init_next(wpa_s
);
462 /* Driver did not support 2000 ms long wait_time with TX command, so
463 * schedule listen operation to continue waiting for the response.
465 * DPP listen operations continue until stopped, so simply schedule a
466 * new call to this function at the point when the two second reply
467 * wait has expired. */
468 wait_time
-= diff_ms
;
470 freq
= auth
->curr_freq
;
471 if (auth
->neg_freq
> 0)
472 freq
= auth
->neg_freq
;
473 wpa_printf(MSG_DEBUG
,
474 "DPP: Continue reply wait on channel %u MHz for %u ms",
476 wpa_s
->dpp_in_response_listen
= 1;
477 wpas_dpp_listen_start(wpa_s
, freq
);
479 eloop_register_timeout(wait_time
/ 1000, (wait_time
% 1000) * 1000,
480 wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
484 static void wpas_dpp_set_testing_options(struct wpa_supplicant
*wpa_s
,
485 struct dpp_authentication
*auth
)
487 #ifdef CONFIG_TESTING_OPTIONS
488 if (wpa_s
->dpp_config_obj_override
)
489 auth
->config_obj_override
=
490 os_strdup(wpa_s
->dpp_config_obj_override
);
491 if (wpa_s
->dpp_discovery_override
)
492 auth
->discovery_override
=
493 os_strdup(wpa_s
->dpp_discovery_override
);
494 if (wpa_s
->dpp_groups_override
)
495 auth
->groups_override
=
496 os_strdup(wpa_s
->dpp_groups_override
);
497 auth
->ignore_netaccesskey_mismatch
=
498 wpa_s
->dpp_ignore_netaccesskey_mismatch
;
499 #endif /* CONFIG_TESTING_OPTIONS */
503 static void wpas_dpp_init_timeout(void *eloop_ctx
, void *timeout_ctx
)
505 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
507 if (!wpa_s
->dpp_auth
)
509 wpa_printf(MSG_DEBUG
, "DPP: Retry initiation after timeout");
510 wpas_dpp_auth_init_next(wpa_s
);
514 static int wpas_dpp_auth_init_next(struct wpa_supplicant
*wpa_s
)
516 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
518 unsigned int wait_time
, max_wait_time
, freq
, max_tries
, used
;
519 struct os_reltime now
, diff
;
521 wpa_s
->dpp_in_response_listen
= 0;
525 if (auth
->freq_idx
== 0)
526 os_get_reltime(&wpa_s
->dpp_init_iter_start
);
528 if (auth
->freq_idx
>= auth
->num_freq
) {
529 auth
->num_freq_iters
++;
530 if (wpa_s
->dpp_init_max_tries
)
531 max_tries
= wpa_s
->dpp_init_max_tries
;
534 if (auth
->num_freq_iters
>= max_tries
|| auth
->auth_req_ack
) {
536 "DPP: No response received from responder - stopping initiation attempt");
537 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_AUTH_INIT_FAILED
);
538 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
,
540 offchannel_send_action_done(wpa_s
);
541 dpp_auth_deinit(wpa_s
->dpp_auth
);
542 wpa_s
->dpp_auth
= NULL
;
546 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
547 if (wpa_s
->dpp_init_retry_time
)
548 wait_time
= wpa_s
->dpp_init_retry_time
;
551 os_get_reltime(&now
);
552 os_reltime_sub(&now
, &wpa_s
->dpp_init_iter_start
, &diff
);
553 used
= diff
.sec
* 1000 + diff
.usec
/ 1000;
554 if (used
> wait_time
)
558 wpa_printf(MSG_DEBUG
, "DPP: Next init attempt in %u ms",
560 eloop_register_timeout(wait_time
/ 1000,
561 (wait_time
% 1000) * 1000,
562 wpas_dpp_init_timeout
, wpa_s
,
566 freq
= auth
->freq
[auth
->freq_idx
++];
567 auth
->curr_freq
= freq
;
569 if (is_zero_ether_addr(auth
->peer_bi
->mac_addr
))
572 dst
= auth
->peer_bi
->mac_addr
;
573 wpa_s
->dpp_auth_ok_on_ack
= 0;
574 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
575 wait_time
= wpa_s
->max_remain_on_chan
;
576 max_wait_time
= wpa_s
->dpp_resp_wait_time
?
577 wpa_s
->dpp_resp_wait_time
: 2000;
578 if (wait_time
> max_wait_time
)
579 wait_time
= max_wait_time
;
580 wait_time
+= 10; /* give the driver some extra time to complete */
581 eloop_register_timeout(wait_time
/ 1000, (wait_time
% 1000) * 1000,
582 wpas_dpp_reply_wait_timeout
,
585 if (auth
->neg_freq
> 0 && freq
!= auth
->neg_freq
) {
586 wpa_printf(MSG_DEBUG
,
587 "DPP: Initiate on %u MHz and move to neg_freq %u MHz for response",
588 freq
, auth
->neg_freq
);
590 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
591 MAC2STR(dst
), freq
, DPP_PA_AUTHENTICATION_REQ
);
592 auth
->auth_req_ack
= 0;
593 os_get_reltime(&wpa_s
->dpp_last_init
);
594 return offchannel_send_action(wpa_s
, freq
, dst
,
595 wpa_s
->own_addr
, broadcast
,
596 wpabuf_head(auth
->req_msg
),
597 wpabuf_len(auth
->req_msg
),
598 wait_time
, wpas_dpp_tx_status
, 0);
602 int wpas_dpp_auth_init(struct wpa_supplicant
*wpa_s
, const char *cmd
)
605 struct dpp_bootstrap_info
*peer_bi
, *own_bi
= NULL
;
606 struct dpp_authentication
*auth
;
607 u8 allowed_roles
= DPP_CAPAB_CONFIGURATOR
;
608 unsigned int neg_freq
= 0;
611 int tcp_port
= DPP_TCP_PORT
;
612 struct hostapd_ip_addr ipaddr
;
614 #endif /* CONFIG_DPP2 */
616 wpa_s
->dpp_gas_client
= 0;
618 pos
= os_strstr(cmd
, " peer=");
622 peer_bi
= dpp_bootstrap_get_id(wpa_s
->dpp
, atoi(pos
));
625 "DPP: Could not find bootstrapping info for the identified peer");
630 pos
= os_strstr(cmd
, " tcp_port=");
633 tcp_port
= atoi(pos
);
636 addr
= get_param(cmd
, " tcp_addr=");
640 res
= hostapd_parse_ip_addr(addr
, &ipaddr
);
646 #endif /* CONFIG_DPP2 */
648 pos
= os_strstr(cmd
, " own=");
651 own_bi
= dpp_bootstrap_get_id(wpa_s
->dpp
, atoi(pos
));
654 "DPP: Could not find bootstrapping info for the identified local entry");
658 if (peer_bi
->curve
!= own_bi
->curve
) {
660 "DPP: Mismatching curves in bootstrapping info (peer=%s own=%s)",
661 peer_bi
->curve
->name
, own_bi
->curve
->name
);
666 pos
= os_strstr(cmd
, " role=");
669 if (os_strncmp(pos
, "configurator", 12) == 0)
670 allowed_roles
= DPP_CAPAB_CONFIGURATOR
;
671 else if (os_strncmp(pos
, "enrollee", 8) == 0)
672 allowed_roles
= DPP_CAPAB_ENROLLEE
;
673 else if (os_strncmp(pos
, "either", 6) == 0)
674 allowed_roles
= DPP_CAPAB_CONFIGURATOR
|
680 pos
= os_strstr(cmd
, " netrole=");
683 if (os_strncmp(pos
, "ap", 2) == 0)
684 wpa_s
->dpp_netrole
= DPP_NETROLE_AP
;
685 else if (os_strncmp(pos
, "configurator", 12) == 0)
686 wpa_s
->dpp_netrole
= DPP_NETROLE_CONFIGURATOR
;
688 wpa_s
->dpp_netrole
= DPP_NETROLE_STA
;
691 pos
= os_strstr(cmd
, " neg_freq=");
693 neg_freq
= atoi(pos
+ 10);
695 if (!tcp
&& wpa_s
->dpp_auth
) {
696 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
697 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
698 eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout
, wpa_s
,
700 offchannel_send_action_done(wpa_s
);
701 dpp_auth_deinit(wpa_s
->dpp_auth
);
702 wpa_s
->dpp_auth
= NULL
;
705 auth
= dpp_auth_init(wpa_s
, peer_bi
, own_bi
, allowed_roles
, neg_freq
,
706 wpa_s
->hw
.modes
, wpa_s
->hw
.num_modes
);
709 wpas_dpp_set_testing_options(wpa_s
, auth
);
710 if (dpp_set_configurator(wpa_s
->dpp
, wpa_s
, auth
, cmd
) < 0) {
711 dpp_auth_deinit(auth
);
715 auth
->neg_freq
= neg_freq
;
717 if (!is_zero_ether_addr(peer_bi
->mac_addr
))
718 os_memcpy(auth
->peer_mac_addr
, peer_bi
->mac_addr
, ETH_ALEN
);
722 return dpp_tcp_init(wpa_s
->dpp
, auth
, &ipaddr
, tcp_port
);
723 #endif /* CONFIG_DPP2 */
725 wpa_s
->dpp_auth
= auth
;
726 return wpas_dpp_auth_init_next(wpa_s
);
732 struct wpas_dpp_listen_work
{
734 unsigned int duration
;
735 struct wpabuf
*probe_resp_ie
;
739 static void wpas_dpp_listen_work_free(struct wpas_dpp_listen_work
*lwork
)
747 static void wpas_dpp_listen_work_done(struct wpa_supplicant
*wpa_s
)
749 struct wpas_dpp_listen_work
*lwork
;
751 if (!wpa_s
->dpp_listen_work
)
754 lwork
= wpa_s
->dpp_listen_work
->ctx
;
755 wpas_dpp_listen_work_free(lwork
);
756 radio_work_done(wpa_s
->dpp_listen_work
);
757 wpa_s
->dpp_listen_work
= NULL
;
761 static void dpp_start_listen_cb(struct wpa_radio_work
*work
, int deinit
)
763 struct wpa_supplicant
*wpa_s
= work
->wpa_s
;
764 struct wpas_dpp_listen_work
*lwork
= work
->ctx
;
768 wpa_s
->dpp_listen_work
= NULL
;
769 wpas_dpp_listen_stop(wpa_s
);
771 wpas_dpp_listen_work_free(lwork
);
775 wpa_s
->dpp_listen_work
= work
;
777 wpa_s
->dpp_pending_listen_freq
= lwork
->freq
;
779 if (wpa_drv_remain_on_channel(wpa_s
, lwork
->freq
,
780 wpa_s
->max_remain_on_chan
) < 0) {
781 wpa_printf(MSG_DEBUG
,
782 "DPP: Failed to request the driver to remain on channel (%u MHz) for listen",
784 wpa_s
->dpp_listen_freq
= 0;
785 wpas_dpp_listen_work_done(wpa_s
);
786 wpa_s
->dpp_pending_listen_freq
= 0;
789 wpa_s
->off_channel_freq
= 0;
790 wpa_s
->roc_waiting_drv_freq
= lwork
->freq
;
794 static int wpas_dpp_listen_start(struct wpa_supplicant
*wpa_s
,
797 struct wpas_dpp_listen_work
*lwork
;
799 if (wpa_s
->dpp_listen_work
) {
800 wpa_printf(MSG_DEBUG
,
801 "DPP: Reject start_listen since dpp_listen_work already exists");
805 if (wpa_s
->dpp_listen_freq
)
806 wpas_dpp_listen_stop(wpa_s
);
807 wpa_s
->dpp_listen_freq
= freq
;
809 lwork
= os_zalloc(sizeof(*lwork
));
814 if (radio_add_work(wpa_s
, freq
, "dpp-listen", 0, dpp_start_listen_cb
,
816 wpas_dpp_listen_work_free(lwork
);
824 int wpas_dpp_listen(struct wpa_supplicant
*wpa_s
, const char *cmd
)
832 if (os_strstr(cmd
, " role=configurator"))
833 wpa_s
->dpp_allowed_roles
= DPP_CAPAB_CONFIGURATOR
;
834 else if (os_strstr(cmd
, " role=enrollee"))
835 wpa_s
->dpp_allowed_roles
= DPP_CAPAB_ENROLLEE
;
837 wpa_s
->dpp_allowed_roles
= DPP_CAPAB_CONFIGURATOR
|
839 wpa_s
->dpp_qr_mutual
= os_strstr(cmd
, " qr=mutual") != NULL
;
840 if (os_strstr(cmd
, " netrole=ap"))
841 wpa_s
->dpp_netrole
= DPP_NETROLE_AP
;
842 else if (os_strstr(cmd
, " netrole=configurator"))
843 wpa_s
->dpp_netrole
= DPP_NETROLE_CONFIGURATOR
;
845 wpa_s
->dpp_netrole
= DPP_NETROLE_STA
;
846 if (wpa_s
->dpp_listen_freq
== (unsigned int) freq
) {
847 wpa_printf(MSG_DEBUG
, "DPP: Already listening on %u MHz",
852 return wpas_dpp_listen_start(wpa_s
, freq
);
856 void wpas_dpp_listen_stop(struct wpa_supplicant
*wpa_s
)
858 wpa_s
->dpp_in_response_listen
= 0;
859 if (!wpa_s
->dpp_listen_freq
)
862 wpa_printf(MSG_DEBUG
, "DPP: Stop listen on %u MHz",
863 wpa_s
->dpp_listen_freq
);
864 wpa_drv_cancel_remain_on_channel(wpa_s
);
865 wpa_s
->dpp_listen_freq
= 0;
866 wpas_dpp_listen_work_done(wpa_s
);
870 void wpas_dpp_cancel_remain_on_channel_cb(struct wpa_supplicant
*wpa_s
,
873 wpas_dpp_listen_work_done(wpa_s
);
875 if (wpa_s
->dpp_auth
&& wpa_s
->dpp_in_response_listen
) {
876 unsigned int new_freq
;
878 /* Continue listen with a new remain-on-channel */
879 if (wpa_s
->dpp_auth
->neg_freq
> 0)
880 new_freq
= wpa_s
->dpp_auth
->neg_freq
;
882 new_freq
= wpa_s
->dpp_auth
->curr_freq
;
883 wpa_printf(MSG_DEBUG
,
884 "DPP: Continue wait on %u MHz for the ongoing DPP provisioning session",
886 wpas_dpp_listen_start(wpa_s
, new_freq
);
890 if (wpa_s
->dpp_listen_freq
) {
891 /* Continue listen with a new remain-on-channel */
892 wpas_dpp_listen_start(wpa_s
, wpa_s
->dpp_listen_freq
);
897 static void wpas_dpp_rx_auth_req(struct wpa_supplicant
*wpa_s
, const u8
*src
,
898 const u8
*hdr
, const u8
*buf
, size_t len
,
901 const u8
*r_bootstrap
, *i_bootstrap
;
902 u16 r_bootstrap_len
, i_bootstrap_len
;
903 struct dpp_bootstrap_info
*own_bi
= NULL
, *peer_bi
= NULL
;
908 wpa_printf(MSG_DEBUG
, "DPP: Authentication Request from " MACSTR
,
911 r_bootstrap
= dpp_get_attr(buf
, len
, DPP_ATTR_R_BOOTSTRAP_KEY_HASH
,
913 if (!r_bootstrap
|| r_bootstrap_len
!= SHA256_MAC_LEN
) {
914 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
915 "Missing or invalid required Responder Bootstrapping Key Hash attribute");
918 wpa_hexdump(MSG_MSGDUMP
, "DPP: Responder Bootstrapping Key Hash",
919 r_bootstrap
, r_bootstrap_len
);
921 i_bootstrap
= dpp_get_attr(buf
, len
, DPP_ATTR_I_BOOTSTRAP_KEY_HASH
,
923 if (!i_bootstrap
|| i_bootstrap_len
!= SHA256_MAC_LEN
) {
924 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
925 "Missing or invalid required Initiator Bootstrapping Key Hash attribute");
928 wpa_hexdump(MSG_MSGDUMP
, "DPP: Initiator Bootstrapping Key Hash",
929 i_bootstrap
, i_bootstrap_len
);
931 /* Try to find own and peer bootstrapping key matches based on the
932 * received hash values */
933 dpp_bootstrap_find_pair(wpa_s
->dpp
, i_bootstrap
, r_bootstrap
,
936 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
937 "No matching own bootstrapping key found - ignore message");
941 if (wpa_s
->dpp_auth
) {
942 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
943 "Already in DPP authentication exchange - ignore new one");
947 wpa_s
->dpp_gas_client
= 0;
948 wpa_s
->dpp_auth_ok_on_ack
= 0;
949 wpa_s
->dpp_auth
= dpp_auth_req_rx(wpa_s
, wpa_s
->dpp_allowed_roles
,
950 wpa_s
->dpp_qr_mutual
,
951 peer_bi
, own_bi
, freq
, hdr
, buf
, len
);
952 if (!wpa_s
->dpp_auth
) {
953 wpa_printf(MSG_DEBUG
, "DPP: No response generated");
956 wpas_dpp_set_testing_options(wpa_s
, wpa_s
->dpp_auth
);
957 if (dpp_set_configurator(wpa_s
->dpp
, wpa_s
, wpa_s
->dpp_auth
,
958 wpa_s
->dpp_configurator_params
) < 0) {
959 dpp_auth_deinit(wpa_s
->dpp_auth
);
960 wpa_s
->dpp_auth
= NULL
;
963 os_memcpy(wpa_s
->dpp_auth
->peer_mac_addr
, src
, ETH_ALEN
);
965 if (wpa_s
->dpp_listen_freq
&&
966 wpa_s
->dpp_listen_freq
!= wpa_s
->dpp_auth
->curr_freq
) {
967 wpa_printf(MSG_DEBUG
,
968 "DPP: Stop listen on %u MHz to allow response on the request %u MHz",
969 wpa_s
->dpp_listen_freq
, wpa_s
->dpp_auth
->curr_freq
);
970 wpas_dpp_listen_stop(wpa_s
);
973 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
974 MAC2STR(src
), wpa_s
->dpp_auth
->curr_freq
,
975 DPP_PA_AUTHENTICATION_RESP
);
976 offchannel_send_action(wpa_s
, wpa_s
->dpp_auth
->curr_freq
,
977 src
, wpa_s
->own_addr
, broadcast
,
978 wpabuf_head(wpa_s
->dpp_auth
->resp_msg
),
979 wpabuf_len(wpa_s
->dpp_auth
->resp_msg
),
980 500, wpas_dpp_tx_status
, 0);
984 static void wpas_dpp_start_gas_server(struct wpa_supplicant
*wpa_s
)
986 /* TODO: stop wait and start ROC */
990 static struct wpa_ssid
* wpas_dpp_add_network(struct wpa_supplicant
*wpa_s
,
991 struct dpp_authentication
*auth
,
992 struct dpp_config_obj
*conf
)
994 struct wpa_ssid
*ssid
;
997 if (conf
->akm
== DPP_AKM_SAE
) {
999 struct wpa_driver_capa capa
;
1002 res
= wpa_drv_get_capa(wpa_s
, &capa
);
1004 !(capa
.key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_SAE
) &&
1005 !(wpa_s
->drv_flags
& WPA_DRIVER_FLAGS_SAE
)) {
1006 wpa_printf(MSG_DEBUG
,
1007 "DPP: SAE not supported by the driver");
1010 #else /* CONFIG_SAE */
1011 wpa_printf(MSG_DEBUG
, "DPP: SAE not supported in the build");
1013 #endif /* CONFIG_SAE */
1015 #endif /* CONFIG_DPP2 */
1017 ssid
= wpa_config_add_network(wpa_s
->conf
);
1020 wpas_notify_network_added(wpa_s
, ssid
);
1021 wpa_config_set_network_defaults(ssid
);
1024 ssid
->ssid
= os_malloc(conf
->ssid_len
);
1027 os_memcpy(ssid
->ssid
, conf
->ssid
, conf
->ssid_len
);
1028 ssid
->ssid_len
= conf
->ssid_len
;
1030 if (conf
->connector
) {
1031 ssid
->key_mgmt
= WPA_KEY_MGMT_DPP
;
1032 ssid
->ieee80211w
= MGMT_FRAME_PROTECTION_REQUIRED
;
1033 ssid
->dpp_connector
= os_strdup(conf
->connector
);
1034 if (!ssid
->dpp_connector
)
1038 if (conf
->c_sign_key
) {
1039 ssid
->dpp_csign
= os_malloc(wpabuf_len(conf
->c_sign_key
));
1040 if (!ssid
->dpp_csign
)
1042 os_memcpy(ssid
->dpp_csign
, wpabuf_head(conf
->c_sign_key
),
1043 wpabuf_len(conf
->c_sign_key
));
1044 ssid
->dpp_csign_len
= wpabuf_len(conf
->c_sign_key
);
1047 if (auth
->net_access_key
) {
1048 ssid
->dpp_netaccesskey
=
1049 os_malloc(wpabuf_len(auth
->net_access_key
));
1050 if (!ssid
->dpp_netaccesskey
)
1052 os_memcpy(ssid
->dpp_netaccesskey
,
1053 wpabuf_head(auth
->net_access_key
),
1054 wpabuf_len(auth
->net_access_key
));
1055 ssid
->dpp_netaccesskey_len
= wpabuf_len(auth
->net_access_key
);
1056 ssid
->dpp_netaccesskey_expiry
= auth
->net_access_key_expiry
;
1059 if (!conf
->connector
|| dpp_akm_psk(conf
->akm
) ||
1060 dpp_akm_sae(conf
->akm
)) {
1061 if (!conf
->connector
)
1063 if (dpp_akm_psk(conf
->akm
))
1064 ssid
->key_mgmt
|= WPA_KEY_MGMT_PSK
|
1065 WPA_KEY_MGMT_PSK_SHA256
| WPA_KEY_MGMT_FT_PSK
;
1066 if (dpp_akm_sae(conf
->akm
))
1067 ssid
->key_mgmt
|= WPA_KEY_MGMT_SAE
|
1068 WPA_KEY_MGMT_FT_SAE
;
1069 ssid
->ieee80211w
= MGMT_FRAME_PROTECTION_OPTIONAL
;
1070 if (conf
->passphrase
[0]) {
1071 if (wpa_config_set_quoted(ssid
, "psk",
1072 conf
->passphrase
) < 0)
1074 wpa_config_update_psk(ssid
);
1075 ssid
->export_keys
= 1;
1077 ssid
->psk_set
= conf
->psk_set
;
1078 os_memcpy(ssid
->psk
, conf
->psk
, PMK_LEN
);
1082 os_memcpy(wpa_s
->dpp_last_ssid
, conf
->ssid
, conf
->ssid_len
);
1083 wpa_s
->dpp_last_ssid_len
= conf
->ssid_len
;
1087 wpas_notify_network_removed(wpa_s
, ssid
);
1088 wpa_config_remove_network(wpa_s
->conf
, ssid
->id
);
1093 static int wpas_dpp_process_config(struct wpa_supplicant
*wpa_s
,
1094 struct dpp_authentication
*auth
,
1095 struct dpp_config_obj
*conf
)
1097 struct wpa_ssid
*ssid
;
1099 if (wpa_s
->conf
->dpp_config_processing
< 1)
1102 ssid
= wpas_dpp_add_network(wpa_s
, auth
, conf
);
1106 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_NETWORK_ID
"%d", ssid
->id
);
1107 if (wpa_s
->conf
->dpp_config_processing
== 2)
1110 #ifndef CONFIG_NO_CONFIG_WRITE
1111 if (wpa_s
->conf
->update_config
&&
1112 wpa_config_write(wpa_s
->confname
, wpa_s
->conf
))
1113 wpa_printf(MSG_DEBUG
, "DPP: Failed to update configuration");
1114 #endif /* CONFIG_NO_CONFIG_WRITE */
1120 static void wpas_dpp_post_process_config(struct wpa_supplicant
*wpa_s
,
1121 struct dpp_authentication
*auth
)
1123 if (wpa_s
->conf
->dpp_config_processing
< 2)
1127 if (auth
->peer_version
>= 2) {
1128 wpa_printf(MSG_DEBUG
,
1129 "DPP: Postpone connection attempt to wait for completion of DPP Configuration Result");
1130 auth
->connect_on_tx_status
= 1;
1133 #endif /* CONFIG_DPP2 */
1135 wpas_dpp_try_to_connect(wpa_s
);
1139 static int wpas_dpp_handle_config_obj(struct wpa_supplicant
*wpa_s
,
1140 struct dpp_authentication
*auth
,
1141 struct dpp_config_obj
*conf
)
1143 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_RECEIVED
);
1145 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONFOBJ_SSID
"%s",
1146 wpa_ssid_txt(conf
->ssid
, conf
->ssid_len
));
1147 if (conf
->ssid_charset
)
1148 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONFOBJ_SSID_CHARSET
"%d",
1149 conf
->ssid_charset
);
1150 if (conf
->connector
) {
1151 /* TODO: Save the Connector and consider using a command
1152 * to fetch the value instead of sending an event with
1153 * it. The Connector could end up being larger than what
1154 * most clients are ready to receive as an event
1156 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONNECTOR
"%s",
1159 if (conf
->c_sign_key
) {
1163 hexlen
= 2 * wpabuf_len(conf
->c_sign_key
) + 1;
1164 hex
= os_malloc(hexlen
);
1166 wpa_snprintf_hex(hex
, hexlen
,
1167 wpabuf_head(conf
->c_sign_key
),
1168 wpabuf_len(conf
->c_sign_key
));
1169 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_C_SIGN_KEY
"%s",
1174 if (auth
->net_access_key
) {
1178 hexlen
= 2 * wpabuf_len(auth
->net_access_key
) + 1;
1179 hex
= os_malloc(hexlen
);
1181 wpa_snprintf_hex(hex
, hexlen
,
1182 wpabuf_head(auth
->net_access_key
),
1183 wpabuf_len(auth
->net_access_key
));
1184 if (auth
->net_access_key_expiry
)
1185 wpa_msg(wpa_s
, MSG_INFO
,
1186 DPP_EVENT_NET_ACCESS_KEY
"%s %lu", hex
,
1188 auth
->net_access_key_expiry
);
1190 wpa_msg(wpa_s
, MSG_INFO
,
1191 DPP_EVENT_NET_ACCESS_KEY
"%s", hex
);
1196 return wpas_dpp_process_config(wpa_s
, auth
, conf
);
1200 static void wpas_dpp_gas_resp_cb(void *ctx
, const u8
*addr
, u8 dialog_token
,
1201 enum gas_query_result result
,
1202 const struct wpabuf
*adv_proto
,
1203 const struct wpabuf
*resp
, u16 status_code
)
1205 struct wpa_supplicant
*wpa_s
= ctx
;
1207 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1209 enum dpp_status_error status
= DPP_STATUS_CONFIG_REJECTED
;
1212 wpa_s
->dpp_gas_dialog_token
= -1;
1214 if (!auth
|| !auth
->auth_success
) {
1215 wpa_printf(MSG_DEBUG
, "DPP: No matching exchange in progress");
1218 if (result
!= GAS_QUERY_SUCCESS
||
1219 !resp
|| status_code
!= WLAN_STATUS_SUCCESS
) {
1220 wpa_printf(MSG_DEBUG
, "DPP: GAS query did not succeed");
1224 wpa_hexdump_buf(MSG_DEBUG
, "DPP: Configuration Response adv_proto",
1226 wpa_hexdump_buf(MSG_DEBUG
, "DPP: Configuration Response (GAS response)",
1229 if (wpabuf_len(adv_proto
) != 10 ||
1230 !(pos
= wpabuf_head(adv_proto
)) ||
1231 pos
[0] != WLAN_EID_ADV_PROTO
||
1233 pos
[3] != WLAN_EID_VENDOR_SPECIFIC
||
1235 WPA_GET_BE24(&pos
[5]) != OUI_WFA
||
1238 wpa_printf(MSG_DEBUG
,
1239 "DPP: Not a DPP Advertisement Protocol ID");
1243 if (dpp_conf_resp_rx(auth
, resp
) < 0) {
1244 wpa_printf(MSG_DEBUG
, "DPP: Configuration attempt failed");
1248 for (i
= 0; i
< auth
->num_conf_obj
; i
++) {
1249 res
= wpas_dpp_handle_config_obj(wpa_s
, auth
,
1250 &auth
->conf_obj
[i
]);
1254 if (auth
->num_conf_obj
)
1255 wpas_dpp_post_process_config(wpa_s
, auth
);
1257 status
= DPP_STATUS_OK
;
1258 #ifdef CONFIG_TESTING_OPTIONS
1259 if (dpp_test
== DPP_TEST_REJECT_CONFIG
) {
1260 wpa_printf(MSG_INFO
, "DPP: TESTING - Reject Config Object");
1261 status
= DPP_STATUS_CONFIG_REJECTED
;
1263 #endif /* CONFIG_TESTING_OPTIONS */
1265 if (status
!= DPP_STATUS_OK
)
1266 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
1268 if (auth
->peer_version
>= 2 &&
1269 auth
->conf_resp_status
== DPP_STATUS_OK
) {
1272 wpa_printf(MSG_DEBUG
, "DPP: Send DPP Configuration Result");
1273 msg
= dpp_build_conf_result(auth
, status
);
1277 wpa_msg(wpa_s
, MSG_INFO
,
1278 DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1279 MAC2STR(addr
), auth
->curr_freq
,
1280 DPP_PA_CONFIGURATION_RESULT
);
1281 offchannel_send_action(wpa_s
, auth
->curr_freq
,
1282 addr
, wpa_s
->own_addr
, broadcast
,
1285 500, wpas_dpp_tx_status
, 0);
1288 /* This exchange will be terminated in the TX status handler */
1292 #endif /* CONFIG_DPP2 */
1293 dpp_auth_deinit(wpa_s
->dpp_auth
);
1294 wpa_s
->dpp_auth
= NULL
;
1298 static void wpas_dpp_start_gas_client(struct wpa_supplicant
*wpa_s
)
1300 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1303 int *supp_op_classes
;
1305 wpa_s
->dpp_gas_client
= 1;
1306 offchannel_send_action_done(wpa_s
);
1307 wpas_dpp_listen_stop(wpa_s
);
1309 supp_op_classes
= wpas_supp_op_classes(wpa_s
);
1310 buf
= dpp_build_conf_req_helper(auth
, wpa_s
->conf
->dpp_name
,
1312 wpa_s
->conf
->dpp_mud_url
,
1314 os_free(supp_op_classes
);
1316 wpa_printf(MSG_DEBUG
,
1317 "DPP: No configuration request data available");
1321 wpa_printf(MSG_DEBUG
, "DPP: GAS request to " MACSTR
" (freq %u MHz)",
1322 MAC2STR(auth
->peer_mac_addr
), auth
->curr_freq
);
1324 res
= gas_query_req(wpa_s
->gas
, auth
->peer_mac_addr
, auth
->curr_freq
,
1325 1, buf
, wpas_dpp_gas_resp_cb
, wpa_s
);
1327 wpa_msg(wpa_s
, MSG_DEBUG
, "GAS: Failed to send Query Request");
1330 wpa_printf(MSG_DEBUG
,
1331 "DPP: GAS query started with dialog token %u", res
);
1332 wpa_s
->dpp_gas_dialog_token
= res
;
1337 static void wpas_dpp_auth_success(struct wpa_supplicant
*wpa_s
, int initiator
)
1339 wpa_printf(MSG_DEBUG
, "DPP: Authentication succeeded");
1340 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_AUTH_SUCCESS
"init=%d", initiator
);
1341 #ifdef CONFIG_TESTING_OPTIONS
1342 if (dpp_test
== DPP_TEST_STOP_AT_AUTH_CONF
) {
1343 wpa_printf(MSG_INFO
,
1344 "DPP: TESTING - stop at Authentication Confirm");
1345 if (wpa_s
->dpp_auth
->configurator
) {
1346 /* Prevent GAS response */
1347 wpa_s
->dpp_auth
->auth_success
= 0;
1351 #endif /* CONFIG_TESTING_OPTIONS */
1353 if (wpa_s
->dpp_auth
->configurator
)
1354 wpas_dpp_start_gas_server(wpa_s
);
1356 wpas_dpp_start_gas_client(wpa_s
);
1360 static void wpas_dpp_rx_auth_resp(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1361 const u8
*hdr
, const u8
*buf
, size_t len
,
1364 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1367 wpa_printf(MSG_DEBUG
, "DPP: Authentication Response from " MACSTR
1368 " (freq %u MHz)", MAC2STR(src
), freq
);
1371 wpa_printf(MSG_DEBUG
,
1372 "DPP: No DPP Authentication in progress - drop");
1376 if (!is_zero_ether_addr(auth
->peer_mac_addr
) &&
1377 os_memcmp(src
, auth
->peer_mac_addr
, ETH_ALEN
) != 0) {
1378 wpa_printf(MSG_DEBUG
, "DPP: MAC address mismatch (expected "
1379 MACSTR
") - drop", MAC2STR(auth
->peer_mac_addr
));
1383 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
1385 if (auth
->curr_freq
!= freq
&& auth
->neg_freq
== freq
) {
1386 wpa_printf(MSG_DEBUG
,
1387 "DPP: Responder accepted request for different negotiation channel");
1388 auth
->curr_freq
= freq
;
1391 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
1392 msg
= dpp_auth_resp_rx(auth
, hdr
, buf
, len
);
1394 if (auth
->auth_resp_status
== DPP_STATUS_RESPONSE_PENDING
) {
1395 wpa_printf(MSG_DEBUG
,
1396 "DPP: Start wait for full response");
1397 offchannel_send_action_done(wpa_s
);
1398 wpas_dpp_listen_start(wpa_s
, auth
->curr_freq
);
1401 wpa_printf(MSG_DEBUG
, "DPP: No confirm generated");
1404 os_memcpy(auth
->peer_mac_addr
, src
, ETH_ALEN
);
1406 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1407 MAC2STR(src
), auth
->curr_freq
, DPP_PA_AUTHENTICATION_CONF
);
1408 offchannel_send_action(wpa_s
, auth
->curr_freq
,
1409 src
, wpa_s
->own_addr
, broadcast
,
1410 wpabuf_head(msg
), wpabuf_len(msg
),
1411 500, wpas_dpp_tx_status
, 0);
1413 wpa_s
->dpp_auth_ok_on_ack
= 1;
1417 static void wpas_dpp_rx_auth_conf(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1418 const u8
*hdr
, const u8
*buf
, size_t len
)
1420 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1422 wpa_printf(MSG_DEBUG
, "DPP: Authentication Confirmation from " MACSTR
,
1426 wpa_printf(MSG_DEBUG
,
1427 "DPP: No DPP Authentication in progress - drop");
1431 if (os_memcmp(src
, auth
->peer_mac_addr
, ETH_ALEN
) != 0) {
1432 wpa_printf(MSG_DEBUG
, "DPP: MAC address mismatch (expected "
1433 MACSTR
") - drop", MAC2STR(auth
->peer_mac_addr
));
1437 if (dpp_auth_conf_rx(auth
, hdr
, buf
, len
) < 0) {
1438 wpa_printf(MSG_DEBUG
, "DPP: Authentication failed");
1442 wpas_dpp_auth_success(wpa_s
, 0);
1448 static void wpas_dpp_config_result_wait_timeout(void *eloop_ctx
,
1451 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
1452 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1454 if (!auth
|| !auth
->waiting_conf_result
)
1457 wpa_printf(MSG_DEBUG
,
1458 "DPP: Timeout while waiting for Configuration Result");
1459 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
1460 dpp_auth_deinit(auth
);
1461 wpa_s
->dpp_auth
= NULL
;
1465 static void wpas_dpp_conn_status_result_wait_timeout(void *eloop_ctx
,
1468 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
1469 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1471 if (!auth
|| !auth
->waiting_conn_status_result
)
1474 wpa_printf(MSG_DEBUG
,
1475 "DPP: Timeout while waiting for Connection Status Result");
1476 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONN_STATUS_RESULT
"timeout");
1477 wpas_dpp_listen_stop(wpa_s
);
1478 dpp_auth_deinit(auth
);
1479 wpa_s
->dpp_auth
= NULL
;
1483 static void wpas_dpp_rx_conf_result(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1484 const u8
*hdr
, const u8
*buf
, size_t len
)
1486 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1487 enum dpp_status_error status
;
1489 wpa_printf(MSG_DEBUG
, "DPP: Configuration Result from " MACSTR
,
1492 if (!auth
|| !auth
->waiting_conf_result
) {
1493 wpa_printf(MSG_DEBUG
,
1494 "DPP: No DPP Configuration waiting for result - drop");
1498 if (os_memcmp(src
, auth
->peer_mac_addr
, ETH_ALEN
) != 0) {
1499 wpa_printf(MSG_DEBUG
, "DPP: MAC address mismatch (expected "
1500 MACSTR
") - drop", MAC2STR(auth
->peer_mac_addr
));
1504 status
= dpp_conf_result_rx(auth
, hdr
, buf
, len
);
1506 if (status
== DPP_STATUS_OK
&& auth
->send_conn_status
) {
1507 wpa_msg(wpa_s
, MSG_INFO
,
1508 DPP_EVENT_CONF_SENT
"wait_conn_status=1");
1509 wpa_printf(MSG_DEBUG
, "DPP: Wait for Connection Status Result");
1510 eloop_cancel_timeout(wpas_dpp_config_result_wait_timeout
,
1512 auth
->waiting_conn_status_result
= 1;
1513 eloop_cancel_timeout(wpas_dpp_conn_status_result_wait_timeout
,
1515 eloop_register_timeout(16, 0,
1516 wpas_dpp_conn_status_result_wait_timeout
,
1518 offchannel_send_action_done(wpa_s
);
1519 wpas_dpp_listen_start(wpa_s
, auth
->neg_freq
? auth
->neg_freq
:
1523 offchannel_send_action_done(wpa_s
);
1524 wpas_dpp_listen_stop(wpa_s
);
1525 if (status
== DPP_STATUS_OK
)
1526 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_SENT
);
1528 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
1529 dpp_auth_deinit(auth
);
1530 wpa_s
->dpp_auth
= NULL
;
1531 eloop_cancel_timeout(wpas_dpp_config_result_wait_timeout
, wpa_s
, NULL
);
1535 static void wpas_dpp_rx_conn_status_result(struct wpa_supplicant
*wpa_s
,
1536 const u8
*src
, const u8
*hdr
,
1537 const u8
*buf
, size_t len
)
1539 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1540 enum dpp_status_error status
;
1541 u8 ssid
[SSID_MAX_LEN
];
1542 size_t ssid_len
= 0;
1543 char *channel_list
= NULL
;
1545 wpa_printf(MSG_DEBUG
, "DPP: Connection Status Result");
1547 if (!auth
|| !auth
->waiting_conn_status_result
) {
1548 wpa_printf(MSG_DEBUG
,
1549 "DPP: No DPP Configuration waiting for connection status result - drop");
1553 status
= dpp_conn_status_result_rx(auth
, hdr
, buf
, len
,
1554 ssid
, &ssid_len
, &channel_list
);
1555 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONN_STATUS_RESULT
1556 "result=%d ssid=%s channel_list=%s",
1557 status
, wpa_ssid_txt(ssid
, ssid_len
),
1558 channel_list
? channel_list
: "N/A");
1559 os_free(channel_list
);
1560 offchannel_send_action_done(wpa_s
);
1561 wpas_dpp_listen_stop(wpa_s
);
1562 dpp_auth_deinit(auth
);
1563 wpa_s
->dpp_auth
= NULL
;
1564 eloop_cancel_timeout(wpas_dpp_conn_status_result_wait_timeout
,
1569 static int wpas_dpp_process_conf_obj(void *ctx
,
1570 struct dpp_authentication
*auth
)
1572 struct wpa_supplicant
*wpa_s
= ctx
;
1576 for (i
= 0; i
< auth
->num_conf_obj
; i
++) {
1577 res
= wpas_dpp_handle_config_obj(wpa_s
, auth
,
1578 &auth
->conf_obj
[i
]);
1583 wpas_dpp_post_process_config(wpa_s
, auth
);
1588 #endif /* CONFIG_DPP2 */
1591 static void wpas_dpp_rx_peer_disc_resp(struct wpa_supplicant
*wpa_s
,
1593 const u8
*buf
, size_t len
)
1595 struct wpa_ssid
*ssid
;
1596 const u8
*connector
, *trans_id
, *status
;
1597 u16 connector_len
, trans_id_len
, status_len
;
1598 struct dpp_introduction intro
;
1599 struct rsn_pmksa_cache_entry
*entry
;
1601 struct os_reltime rnow
;
1603 unsigned int seconds
;
1604 enum dpp_status_error res
;
1606 wpa_printf(MSG_DEBUG
, "DPP: Peer Discovery Response from " MACSTR
,
1608 if (is_zero_ether_addr(wpa_s
->dpp_intro_bssid
) ||
1609 os_memcmp(src
, wpa_s
->dpp_intro_bssid
, ETH_ALEN
) != 0) {
1610 wpa_printf(MSG_DEBUG
, "DPP: Not waiting for response from "
1611 MACSTR
" - drop", MAC2STR(src
));
1614 offchannel_send_action_done(wpa_s
);
1616 for (ssid
= wpa_s
->conf
->ssid
; ssid
; ssid
= ssid
->next
) {
1617 if (ssid
== wpa_s
->dpp_intro_network
)
1620 if (!ssid
|| !ssid
->dpp_connector
|| !ssid
->dpp_netaccesskey
||
1622 wpa_printf(MSG_DEBUG
,
1623 "DPP: Profile not found for network introduction");
1627 trans_id
= dpp_get_attr(buf
, len
, DPP_ATTR_TRANSACTION_ID
,
1629 if (!trans_id
|| trans_id_len
!= 1) {
1630 wpa_printf(MSG_DEBUG
,
1631 "DPP: Peer did not include Transaction ID");
1632 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1633 " fail=missing_transaction_id", MAC2STR(src
));
1636 if (trans_id
[0] != TRANSACTION_ID
) {
1637 wpa_printf(MSG_DEBUG
,
1638 "DPP: Ignore frame with unexpected Transaction ID %u",
1640 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1641 " fail=transaction_id_mismatch", MAC2STR(src
));
1645 status
= dpp_get_attr(buf
, len
, DPP_ATTR_STATUS
, &status_len
);
1646 if (!status
|| status_len
!= 1) {
1647 wpa_printf(MSG_DEBUG
, "DPP: Peer did not include Status");
1648 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1649 " fail=missing_status", MAC2STR(src
));
1652 if (status
[0] != DPP_STATUS_OK
) {
1653 wpa_printf(MSG_DEBUG
,
1654 "DPP: Peer rejected network introduction: Status %u",
1656 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1657 " status=%u", MAC2STR(src
), status
[0]);
1659 wpas_dpp_send_conn_status_result(wpa_s
, status
[0]);
1660 #endif /* CONFIG_DPP2 */
1664 connector
= dpp_get_attr(buf
, len
, DPP_ATTR_CONNECTOR
, &connector_len
);
1666 wpa_printf(MSG_DEBUG
,
1667 "DPP: Peer did not include its Connector");
1668 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1669 " fail=missing_connector", MAC2STR(src
));
1673 res
= dpp_peer_intro(&intro
, ssid
->dpp_connector
,
1674 ssid
->dpp_netaccesskey
,
1675 ssid
->dpp_netaccesskey_len
,
1677 ssid
->dpp_csign_len
,
1678 connector
, connector_len
, &expiry
);
1679 if (res
!= DPP_STATUS_OK
) {
1680 wpa_printf(MSG_INFO
,
1681 "DPP: Network Introduction protocol resulted in failure");
1682 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1683 " fail=peer_connector_validation_failed", MAC2STR(src
));
1685 wpas_dpp_send_conn_status_result(wpa_s
, res
);
1686 #endif /* CONFIG_DPP2 */
1690 entry
= os_zalloc(sizeof(*entry
));
1693 os_memcpy(entry
->aa
, src
, ETH_ALEN
);
1694 os_memcpy(entry
->pmkid
, intro
.pmkid
, PMKID_LEN
);
1695 os_memcpy(entry
->pmk
, intro
.pmk
, intro
.pmk_len
);
1696 entry
->pmk_len
= intro
.pmk_len
;
1697 entry
->akmp
= WPA_KEY_MGMT_DPP
;
1700 seconds
= expiry
- now
.sec
;
1702 seconds
= 86400 * 7;
1704 os_get_reltime(&rnow
);
1705 entry
->expiration
= rnow
.sec
+ seconds
;
1706 entry
->reauth_time
= rnow
.sec
+ seconds
;
1707 entry
->network_ctx
= ssid
;
1708 wpa_sm_pmksa_cache_add_entry(wpa_s
->wpa
, entry
);
1710 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1711 " status=%u", MAC2STR(src
), status
[0]);
1713 wpa_printf(MSG_DEBUG
,
1714 "DPP: Try connection again after successful network introduction");
1715 if (wpa_supplicant_fast_associate(wpa_s
) != 1) {
1716 wpa_supplicant_cancel_sched_scan(wpa_s
);
1717 wpa_supplicant_req_scan(wpa_s
, 0, 0);
1720 os_memset(&intro
, 0, sizeof(intro
));
1724 static int wpas_dpp_allow_ir(struct wpa_supplicant
*wpa_s
, unsigned int freq
)
1728 if (!wpa_s
->hw
.modes
)
1731 for (i
= 0; i
< wpa_s
->hw
.num_modes
; i
++) {
1732 struct hostapd_hw_modes
*mode
= &wpa_s
->hw
.modes
[i
];
1734 for (j
= 0; j
< mode
->num_channels
; j
++) {
1735 struct hostapd_channel_data
*chan
= &mode
->channels
[j
];
1737 if (chan
->freq
!= (int) freq
)
1740 if (chan
->flag
& (HOSTAPD_CHAN_DISABLED
|
1741 HOSTAPD_CHAN_NO_IR
|
1742 HOSTAPD_CHAN_RADAR
))
1749 wpa_printf(MSG_DEBUG
,
1750 "DPP: Frequency %u MHz not supported or does not allow PKEX initiation in the current channel list",
1757 static int wpas_dpp_pkex_next_channel(struct wpa_supplicant
*wpa_s
,
1758 struct dpp_pkex
*pkex
)
1760 if (pkex
->freq
== 2437)
1762 else if (pkex
->freq
== 5745)
1764 else if (pkex
->freq
== 5220)
1767 return -1; /* no more channels to try */
1769 if (wpas_dpp_allow_ir(wpa_s
, pkex
->freq
) == 1) {
1770 wpa_printf(MSG_DEBUG
, "DPP: Try to initiate on %u MHz",
1775 /* Could not use this channel - try the next one */
1776 return wpas_dpp_pkex_next_channel(wpa_s
, pkex
);
1780 static void wpas_dpp_pkex_retry_timeout(void *eloop_ctx
, void *timeout_ctx
)
1782 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
1783 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
1785 if (!pkex
|| !pkex
->exchange_req
)
1787 if (pkex
->exch_req_tries
>= 5) {
1788 if (wpas_dpp_pkex_next_channel(wpa_s
, pkex
) < 0) {
1789 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
1790 "No response from PKEX peer");
1791 dpp_pkex_free(pkex
);
1792 wpa_s
->dpp_pkex
= NULL
;
1795 pkex
->exch_req_tries
= 0;
1798 pkex
->exch_req_tries
++;
1799 wpa_printf(MSG_DEBUG
, "DPP: Retransmit PKEX Exchange Request (try %u)",
1800 pkex
->exch_req_tries
);
1801 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1802 MAC2STR(broadcast
), pkex
->freq
, DPP_PA_PKEX_EXCHANGE_REQ
);
1803 offchannel_send_action(wpa_s
, pkex
->freq
, broadcast
,
1804 wpa_s
->own_addr
, broadcast
,
1805 wpabuf_head(pkex
->exchange_req
),
1806 wpabuf_len(pkex
->exchange_req
),
1807 pkex
->exch_req_wait_time
,
1808 wpas_dpp_tx_pkex_status
, 0);
1813 wpas_dpp_tx_pkex_status(struct wpa_supplicant
*wpa_s
,
1814 unsigned int freq
, const u8
*dst
,
1815 const u8
*src
, const u8
*bssid
,
1816 const u8
*data
, size_t data_len
,
1817 enum offchannel_send_action_result result
)
1819 const char *res_txt
;
1820 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
1822 res_txt
= result
== OFFCHANNEL_SEND_ACTION_SUCCESS
? "SUCCESS" :
1823 (result
== OFFCHANNEL_SEND_ACTION_NO_ACK
? "no-ACK" :
1825 wpa_printf(MSG_DEBUG
, "DPP: TX status: freq=%u dst=" MACSTR
1826 " result=%s (PKEX)",
1827 freq
, MAC2STR(dst
), res_txt
);
1828 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX_STATUS
"dst=" MACSTR
1829 " freq=%u result=%s", MAC2STR(dst
), freq
, res_txt
);
1832 wpa_printf(MSG_DEBUG
,
1833 "DPP: Ignore TX status since there is no ongoing PKEX exchange");
1838 wpa_printf(MSG_DEBUG
,
1839 "DPP: Terminate PKEX exchange due to an earlier error");
1840 if (pkex
->t
> pkex
->own_bi
->pkex_t
)
1841 pkex
->own_bi
->pkex_t
= pkex
->t
;
1842 dpp_pkex_free(pkex
);
1843 wpa_s
->dpp_pkex
= NULL
;
1847 if (pkex
->exch_req_wait_time
&& pkex
->exchange_req
) {
1848 /* Wait for PKEX Exchange Response frame and retry request if
1849 * no response is seen. */
1850 eloop_cancel_timeout(wpas_dpp_pkex_retry_timeout
, wpa_s
, NULL
);
1851 eloop_register_timeout(pkex
->exch_req_wait_time
/ 1000,
1852 (pkex
->exch_req_wait_time
% 1000) * 1000,
1853 wpas_dpp_pkex_retry_timeout
, wpa_s
,
1860 wpas_dpp_rx_pkex_exchange_req(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1861 const u8
*buf
, size_t len
, unsigned int freq
)
1864 unsigned int wait_time
;
1866 wpa_printf(MSG_DEBUG
, "DPP: PKEX Exchange Request from " MACSTR
,
1869 /* TODO: Support multiple PKEX codes by iterating over all the enabled
1872 if (!wpa_s
->dpp_pkex_code
|| !wpa_s
->dpp_pkex_bi
) {
1873 wpa_printf(MSG_DEBUG
,
1874 "DPP: No PKEX code configured - ignore request");
1878 if (wpa_s
->dpp_pkex
) {
1879 /* TODO: Support parallel operations */
1880 wpa_printf(MSG_DEBUG
,
1881 "DPP: Already in PKEX session - ignore new request");
1885 wpa_s
->dpp_pkex
= dpp_pkex_rx_exchange_req(wpa_s
, wpa_s
->dpp_pkex_bi
,
1886 wpa_s
->own_addr
, src
,
1887 wpa_s
->dpp_pkex_identifier
,
1888 wpa_s
->dpp_pkex_code
,
1890 if (!wpa_s
->dpp_pkex
) {
1891 wpa_printf(MSG_DEBUG
,
1892 "DPP: Failed to process the request - ignore it");
1896 msg
= wpa_s
->dpp_pkex
->exchange_resp
;
1897 wait_time
= wpa_s
->max_remain_on_chan
;
1898 if (wait_time
> 2000)
1900 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1901 MAC2STR(src
), freq
, DPP_PA_PKEX_EXCHANGE_RESP
);
1902 offchannel_send_action(wpa_s
, freq
, src
, wpa_s
->own_addr
,
1904 wpabuf_head(msg
), wpabuf_len(msg
),
1905 wait_time
, wpas_dpp_tx_pkex_status
, 0);
1910 wpas_dpp_rx_pkex_exchange_resp(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1911 const u8
*buf
, size_t len
, unsigned int freq
)
1914 unsigned int wait_time
;
1916 wpa_printf(MSG_DEBUG
, "DPP: PKEX Exchange Response from " MACSTR
,
1919 /* TODO: Support multiple PKEX codes by iterating over all the enabled
1922 if (!wpa_s
->dpp_pkex
|| !wpa_s
->dpp_pkex
->initiator
||
1923 wpa_s
->dpp_pkex
->exchange_done
) {
1924 wpa_printf(MSG_DEBUG
, "DPP: No matching PKEX session");
1928 eloop_cancel_timeout(wpas_dpp_pkex_retry_timeout
, wpa_s
, NULL
);
1929 wpa_s
->dpp_pkex
->exch_req_wait_time
= 0;
1931 msg
= dpp_pkex_rx_exchange_resp(wpa_s
->dpp_pkex
, src
, buf
, len
);
1933 wpa_printf(MSG_DEBUG
, "DPP: Failed to process the response");
1937 wpa_printf(MSG_DEBUG
, "DPP: Send PKEX Commit-Reveal Request to " MACSTR
,
1940 wait_time
= wpa_s
->max_remain_on_chan
;
1941 if (wait_time
> 2000)
1943 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1944 MAC2STR(src
), freq
, DPP_PA_PKEX_COMMIT_REVEAL_REQ
);
1945 offchannel_send_action(wpa_s
, freq
, src
, wpa_s
->own_addr
,
1947 wpabuf_head(msg
), wpabuf_len(msg
),
1948 wait_time
, wpas_dpp_tx_pkex_status
, 0);
1953 static struct dpp_bootstrap_info
*
1954 wpas_dpp_pkex_finish(struct wpa_supplicant
*wpa_s
, const u8
*peer
,
1957 struct dpp_bootstrap_info
*bi
;
1959 bi
= dpp_pkex_finish(wpa_s
->dpp
, wpa_s
->dpp_pkex
, peer
, freq
);
1962 wpa_s
->dpp_pkex
= NULL
;
1968 wpas_dpp_rx_pkex_commit_reveal_req(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1969 const u8
*hdr
, const u8
*buf
, size_t len
,
1973 unsigned int wait_time
;
1974 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
1976 wpa_printf(MSG_DEBUG
, "DPP: PKEX Commit-Reveal Request from " MACSTR
,
1979 if (!pkex
|| pkex
->initiator
|| !pkex
->exchange_done
) {
1980 wpa_printf(MSG_DEBUG
, "DPP: No matching PKEX session");
1984 msg
= dpp_pkex_rx_commit_reveal_req(pkex
, hdr
, buf
, len
);
1986 wpa_printf(MSG_DEBUG
, "DPP: Failed to process the request");
1988 wpa_printf(MSG_DEBUG
, "DPP: Terminate PKEX exchange");
1989 if (pkex
->t
> pkex
->own_bi
->pkex_t
)
1990 pkex
->own_bi
->pkex_t
= pkex
->t
;
1991 dpp_pkex_free(wpa_s
->dpp_pkex
);
1992 wpa_s
->dpp_pkex
= NULL
;
1997 wpa_printf(MSG_DEBUG
, "DPP: Send PKEX Commit-Reveal Response to "
1998 MACSTR
, MAC2STR(src
));
2000 wait_time
= wpa_s
->max_remain_on_chan
;
2001 if (wait_time
> 2000)
2003 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
2004 MAC2STR(src
), freq
, DPP_PA_PKEX_COMMIT_REVEAL_RESP
);
2005 offchannel_send_action(wpa_s
, freq
, src
, wpa_s
->own_addr
,
2007 wpabuf_head(msg
), wpabuf_len(msg
),
2008 wait_time
, wpas_dpp_tx_pkex_status
, 0);
2011 wpas_dpp_pkex_finish(wpa_s
, src
, freq
);
2016 wpas_dpp_rx_pkex_commit_reveal_resp(struct wpa_supplicant
*wpa_s
, const u8
*src
,
2017 const u8
*hdr
, const u8
*buf
, size_t len
,
2021 struct dpp_bootstrap_info
*bi
;
2022 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
2025 wpa_printf(MSG_DEBUG
, "DPP: PKEX Commit-Reveal Response from " MACSTR
,
2028 if (!pkex
|| !pkex
->initiator
|| !pkex
->exchange_done
) {
2029 wpa_printf(MSG_DEBUG
, "DPP: No matching PKEX session");
2033 res
= dpp_pkex_rx_commit_reveal_resp(pkex
, hdr
, buf
, len
);
2035 wpa_printf(MSG_DEBUG
, "DPP: Failed to process the response");
2039 bi
= wpas_dpp_pkex_finish(wpa_s
, src
, freq
);
2043 os_snprintf(cmd
, sizeof(cmd
), " peer=%u %s",
2045 wpa_s
->dpp_pkex_auth_cmd
? wpa_s
->dpp_pkex_auth_cmd
: "");
2046 wpa_printf(MSG_DEBUG
,
2047 "DPP: Start authentication after PKEX with parameters: %s",
2049 if (wpas_dpp_auth_init(wpa_s
, cmd
) < 0) {
2050 wpa_printf(MSG_DEBUG
,
2051 "DPP: Authentication initialization failed");
2057 void wpas_dpp_rx_action(struct wpa_supplicant
*wpa_s
, const u8
*src
,
2058 const u8
*buf
, size_t len
, unsigned int freq
)
2061 enum dpp_public_action_frame_type type
;
2063 unsigned int pkex_t
;
2065 if (len
< DPP_HDR_LEN
)
2067 if (WPA_GET_BE24(buf
) != OUI_WFA
|| buf
[3] != DPP_OUI_TYPE
)
2072 crypto_suite
= *buf
++;
2076 wpa_printf(MSG_DEBUG
,
2077 "DPP: Received DPP Public Action frame crypto suite %u type %d from "
2079 crypto_suite
, type
, MAC2STR(src
), freq
);
2080 if (crypto_suite
!= 1) {
2081 wpa_printf(MSG_DEBUG
, "DPP: Unsupported crypto suite %u",
2083 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_RX
"src=" MACSTR
2084 " freq=%u type=%d ignore=unsupported-crypto-suite",
2085 MAC2STR(src
), freq
, type
);
2088 wpa_hexdump(MSG_MSGDUMP
, "DPP: Received message attributes", buf
, len
);
2089 if (dpp_check_attrs(buf
, len
) < 0) {
2090 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_RX
"src=" MACSTR
2091 " freq=%u type=%d ignore=invalid-attributes",
2092 MAC2STR(src
), freq
, type
);
2095 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_RX
"src=" MACSTR
" freq=%u type=%d",
2096 MAC2STR(src
), freq
, type
);
2099 case DPP_PA_AUTHENTICATION_REQ
:
2100 wpas_dpp_rx_auth_req(wpa_s
, src
, hdr
, buf
, len
, freq
);
2102 case DPP_PA_AUTHENTICATION_RESP
:
2103 wpas_dpp_rx_auth_resp(wpa_s
, src
, hdr
, buf
, len
, freq
);
2105 case DPP_PA_AUTHENTICATION_CONF
:
2106 wpas_dpp_rx_auth_conf(wpa_s
, src
, hdr
, buf
, len
);
2108 case DPP_PA_PEER_DISCOVERY_RESP
:
2109 wpas_dpp_rx_peer_disc_resp(wpa_s
, src
, buf
, len
);
2111 case DPP_PA_PKEX_EXCHANGE_REQ
:
2112 wpas_dpp_rx_pkex_exchange_req(wpa_s
, src
, buf
, len
, freq
);
2114 case DPP_PA_PKEX_EXCHANGE_RESP
:
2115 wpas_dpp_rx_pkex_exchange_resp(wpa_s
, src
, buf
, len
, freq
);
2117 case DPP_PA_PKEX_COMMIT_REVEAL_REQ
:
2118 wpas_dpp_rx_pkex_commit_reveal_req(wpa_s
, src
, hdr
, buf
, len
,
2121 case DPP_PA_PKEX_COMMIT_REVEAL_RESP
:
2122 wpas_dpp_rx_pkex_commit_reveal_resp(wpa_s
, src
, hdr
, buf
, len
,
2126 case DPP_PA_CONFIGURATION_RESULT
:
2127 wpas_dpp_rx_conf_result(wpa_s
, src
, hdr
, buf
, len
);
2129 case DPP_PA_CONNECTION_STATUS_RESULT
:
2130 wpas_dpp_rx_conn_status_result(wpa_s
, src
, hdr
, buf
, len
);
2132 #endif /* CONFIG_DPP2 */
2134 wpa_printf(MSG_DEBUG
,
2135 "DPP: Ignored unsupported frame subtype %d", type
);
2139 if (wpa_s
->dpp_pkex
)
2140 pkex_t
= wpa_s
->dpp_pkex
->t
;
2141 else if (wpa_s
->dpp_pkex_bi
)
2142 pkex_t
= wpa_s
->dpp_pkex_bi
->pkex_t
;
2145 if (pkex_t
>= PKEX_COUNTER_T_LIMIT
) {
2146 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_PKEX_T_LIMIT
"id=0");
2147 wpas_dpp_pkex_remove(wpa_s
, "*");
2152 static struct wpabuf
*
2153 wpas_dpp_gas_req_handler(void *ctx
, const u8
*sa
, const u8
*query
,
2156 struct wpa_supplicant
*wpa_s
= ctx
;
2157 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
2158 struct wpabuf
*resp
;
2160 wpa_printf(MSG_DEBUG
, "DPP: GAS request from " MACSTR
,
2162 if (!auth
|| !auth
->auth_success
||
2163 os_memcmp(sa
, auth
->peer_mac_addr
, ETH_ALEN
) != 0) {
2164 wpa_printf(MSG_DEBUG
, "DPP: No matching exchange in progress");
2168 if (wpa_s
->dpp_auth_ok_on_ack
&& auth
->configurator
) {
2169 wpa_printf(MSG_DEBUG
,
2170 "DPP: Have not received ACK for Auth Confirm yet - assume it was received based on this GAS request");
2171 /* wpas_dpp_auth_success() would normally have been called from
2172 * TX status handler, but since there was no such handler call
2173 * yet, simply send out the event message and proceed with
2175 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_AUTH_SUCCESS
"init=1");
2176 wpa_s
->dpp_auth_ok_on_ack
= 0;
2179 wpa_hexdump(MSG_DEBUG
,
2180 "DPP: Received Configuration Request (GAS Query Request)",
2182 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_REQ_RX
"src=" MACSTR
,
2184 resp
= dpp_conf_req_rx(auth
, query
, query_len
);
2186 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
2187 auth
->conf_resp
= resp
;
2193 wpas_dpp_gas_status_handler(void *ctx
, struct wpabuf
*resp
, int ok
)
2195 struct wpa_supplicant
*wpa_s
= ctx
;
2196 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
2202 if (auth
->conf_resp
!= resp
) {
2203 wpa_printf(MSG_DEBUG
,
2204 "DPP: Ignore GAS status report (ok=%d) for unknown response",
2210 wpa_printf(MSG_DEBUG
, "DPP: Configuration exchange completed (ok=%d)",
2212 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
2213 eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout
, wpa_s
, NULL
);
2215 if (ok
&& auth
->peer_version
>= 2 &&
2216 auth
->conf_resp_status
== DPP_STATUS_OK
) {
2217 wpa_printf(MSG_DEBUG
, "DPP: Wait for Configuration Result");
2218 auth
->waiting_conf_result
= 1;
2219 auth
->conf_resp
= NULL
;
2221 eloop_cancel_timeout(wpas_dpp_config_result_wait_timeout
,
2223 eloop_register_timeout(2, 0,
2224 wpas_dpp_config_result_wait_timeout
,
2228 #endif /* CONFIG_DPP2 */
2229 offchannel_send_action_done(wpa_s
);
2230 wpas_dpp_listen_stop(wpa_s
);
2232 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_SENT
);
2234 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
2235 dpp_auth_deinit(wpa_s
->dpp_auth
);
2236 wpa_s
->dpp_auth
= NULL
;
2241 int wpas_dpp_configurator_sign(struct wpa_supplicant
*wpa_s
, const char *cmd
)
2243 struct dpp_authentication
*auth
;
2247 auth
= os_zalloc(sizeof(*auth
));
2251 curve
= get_param(cmd
, " curve=");
2252 wpas_dpp_set_testing_options(wpa_s
, auth
);
2253 if (dpp_set_configurator(wpa_s
->dpp
, wpa_s
, auth
, cmd
) == 0 &&
2254 dpp_configurator_own_config(auth
, curve
, 0) == 0)
2255 ret
= wpas_dpp_handle_config_obj(wpa_s
, auth
,
2256 &auth
->conf_obj
[0]);
2258 wpas_dpp_post_process_config(wpa_s
, auth
);
2260 dpp_auth_deinit(auth
);
2268 wpas_dpp_tx_introduction_status(struct wpa_supplicant
*wpa_s
,
2269 unsigned int freq
, const u8
*dst
,
2270 const u8
*src
, const u8
*bssid
,
2271 const u8
*data
, size_t data_len
,
2272 enum offchannel_send_action_result result
)
2274 const char *res_txt
;
2276 res_txt
= result
== OFFCHANNEL_SEND_ACTION_SUCCESS
? "SUCCESS" :
2277 (result
== OFFCHANNEL_SEND_ACTION_NO_ACK
? "no-ACK" :
2279 wpa_printf(MSG_DEBUG
, "DPP: TX status: freq=%u dst=" MACSTR
2280 " result=%s (DPP Peer Discovery Request)",
2281 freq
, MAC2STR(dst
), res_txt
);
2282 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX_STATUS
"dst=" MACSTR
2283 " freq=%u result=%s", MAC2STR(dst
), freq
, res_txt
);
2284 /* TODO: Time out wait for response more quickly in error cases? */
2288 int wpas_dpp_check_connect(struct wpa_supplicant
*wpa_s
, struct wpa_ssid
*ssid
,
2289 struct wpa_bss
*bss
)
2293 unsigned int wait_time
;
2295 struct wpa_ie_data ied
;
2297 if (!(ssid
->key_mgmt
& WPA_KEY_MGMT_DPP
) || !bss
)
2298 return 0; /* Not using DPP AKM - continue */
2299 rsn
= wpa_bss_get_ie(bss
, WLAN_EID_RSN
);
2300 if (rsn
&& wpa_parse_wpa_ie(rsn
, 2 + rsn
[1], &ied
) == 0 &&
2301 !(ied
.key_mgmt
& WPA_KEY_MGMT_DPP
))
2302 return 0; /* AP does not support DPP AKM - continue */
2303 if (wpa_sm_pmksa_exists(wpa_s
->wpa
, bss
->bssid
, ssid
))
2304 return 0; /* PMKSA exists for DPP AKM - continue */
2306 if (!ssid
->dpp_connector
|| !ssid
->dpp_netaccesskey
||
2308 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_MISSING_CONNECTOR
2310 !ssid
->dpp_connector
? "Connector" :
2311 (!ssid
->dpp_netaccesskey
? "netAccessKey" :
2318 if (ssid
->dpp_netaccesskey_expiry
&&
2319 (os_time_t
) ssid
->dpp_netaccesskey_expiry
< now
.sec
) {
2320 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_MISSING_CONNECTOR
2321 "netAccessKey expired");
2325 wpa_printf(MSG_DEBUG
,
2326 "DPP: Starting network introduction protocol to derive PMKSA for "
2327 MACSTR
, MAC2STR(bss
->bssid
));
2329 msg
= dpp_alloc_msg(DPP_PA_PEER_DISCOVERY_REQ
,
2330 5 + 4 + os_strlen(ssid
->dpp_connector
));
2334 #ifdef CONFIG_TESTING_OPTIONS
2335 if (dpp_test
== DPP_TEST_NO_TRANSACTION_ID_PEER_DISC_REQ
) {
2336 wpa_printf(MSG_INFO
, "DPP: TESTING - no Transaction ID");
2339 if (dpp_test
== DPP_TEST_INVALID_TRANSACTION_ID_PEER_DISC_REQ
) {
2340 wpa_printf(MSG_INFO
, "DPP: TESTING - invalid Transaction ID");
2341 wpabuf_put_le16(msg
, DPP_ATTR_TRANSACTION_ID
);
2342 wpabuf_put_le16(msg
, 0);
2345 #endif /* CONFIG_TESTING_OPTIONS */
2347 /* Transaction ID */
2348 wpabuf_put_le16(msg
, DPP_ATTR_TRANSACTION_ID
);
2349 wpabuf_put_le16(msg
, 1);
2350 wpabuf_put_u8(msg
, TRANSACTION_ID
);
2352 #ifdef CONFIG_TESTING_OPTIONS
2354 if (dpp_test
== DPP_TEST_NO_CONNECTOR_PEER_DISC_REQ
) {
2355 wpa_printf(MSG_INFO
, "DPP: TESTING - no Connector");
2356 goto skip_connector
;
2358 if (dpp_test
== DPP_TEST_INVALID_CONNECTOR_PEER_DISC_REQ
) {
2361 wpa_printf(MSG_INFO
, "DPP: TESTING - invalid Connector");
2362 connector
= dpp_corrupt_connector_signature(
2363 ssid
->dpp_connector
);
2368 wpabuf_put_le16(msg
, DPP_ATTR_CONNECTOR
);
2369 wpabuf_put_le16(msg
, os_strlen(connector
));
2370 wpabuf_put_str(msg
, connector
);
2372 goto skip_connector
;
2374 #endif /* CONFIG_TESTING_OPTIONS */
2377 wpabuf_put_le16(msg
, DPP_ATTR_CONNECTOR
);
2378 wpabuf_put_le16(msg
, os_strlen(ssid
->dpp_connector
));
2379 wpabuf_put_str(msg
, ssid
->dpp_connector
);
2381 #ifdef CONFIG_TESTING_OPTIONS
2383 #endif /* CONFIG_TESTING_OPTIONS */
2385 /* TODO: Timeout on AP response */
2386 wait_time
= wpa_s
->max_remain_on_chan
;
2387 if (wait_time
> 2000)
2389 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
2390 MAC2STR(bss
->bssid
), bss
->freq
, DPP_PA_PEER_DISCOVERY_REQ
);
2391 offchannel_send_action(wpa_s
, bss
->freq
, bss
->bssid
, wpa_s
->own_addr
,
2393 wpabuf_head(msg
), wpabuf_len(msg
),
2394 wait_time
, wpas_dpp_tx_introduction_status
, 0);
2397 /* Request this connection attempt to terminate - new one will be
2398 * started when network introduction protocol completes */
2399 os_memcpy(wpa_s
->dpp_intro_bssid
, bss
->bssid
, ETH_ALEN
);
2400 wpa_s
->dpp_intro_network
= ssid
;
2405 int wpas_dpp_pkex_add(struct wpa_supplicant
*wpa_s
, const char *cmd
)
2407 struct dpp_bootstrap_info
*own_bi
;
2408 const char *pos
, *end
;
2409 unsigned int wait_time
;
2411 pos
= os_strstr(cmd
, " own=");
2415 own_bi
= dpp_bootstrap_get_id(wpa_s
->dpp
, atoi(pos
));
2417 wpa_printf(MSG_DEBUG
,
2418 "DPP: Identified bootstrap info not found");
2421 if (own_bi
->type
!= DPP_BOOTSTRAP_PKEX
) {
2422 wpa_printf(MSG_DEBUG
,
2423 "DPP: Identified bootstrap info not for PKEX");
2426 wpa_s
->dpp_pkex_bi
= own_bi
;
2427 own_bi
->pkex_t
= 0; /* clear pending errors on new code */
2429 os_free(wpa_s
->dpp_pkex_identifier
);
2430 wpa_s
->dpp_pkex_identifier
= NULL
;
2431 pos
= os_strstr(cmd
, " identifier=");
2434 end
= os_strchr(pos
, ' ');
2437 wpa_s
->dpp_pkex_identifier
= os_malloc(end
- pos
+ 1);
2438 if (!wpa_s
->dpp_pkex_identifier
)
2440 os_memcpy(wpa_s
->dpp_pkex_identifier
, pos
, end
- pos
);
2441 wpa_s
->dpp_pkex_identifier
[end
- pos
] = '\0';
2444 pos
= os_strstr(cmd
, " code=");
2447 os_free(wpa_s
->dpp_pkex_code
);
2448 wpa_s
->dpp_pkex_code
= os_strdup(pos
+ 6);
2449 if (!wpa_s
->dpp_pkex_code
)
2452 if (os_strstr(cmd
, " init=1")) {
2453 struct dpp_pkex
*pkex
;
2456 wpa_printf(MSG_DEBUG
, "DPP: Initiating PKEX");
2457 dpp_pkex_free(wpa_s
->dpp_pkex
);
2458 wpa_s
->dpp_pkex
= dpp_pkex_init(wpa_s
, own_bi
, wpa_s
->own_addr
,
2459 wpa_s
->dpp_pkex_identifier
,
2460 wpa_s
->dpp_pkex_code
);
2461 pkex
= wpa_s
->dpp_pkex
;
2465 msg
= pkex
->exchange_req
;
2466 wait_time
= wpa_s
->max_remain_on_chan
;
2467 if (wait_time
> 2000)
2470 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
2472 MAC2STR(broadcast
), pkex
->freq
,
2473 DPP_PA_PKEX_EXCHANGE_REQ
);
2474 offchannel_send_action(wpa_s
, pkex
->freq
, broadcast
,
2475 wpa_s
->own_addr
, broadcast
,
2476 wpabuf_head(msg
), wpabuf_len(msg
),
2477 wait_time
, wpas_dpp_tx_pkex_status
, 0);
2480 pkex
->exch_req_wait_time
= wait_time
;
2481 pkex
->exch_req_tries
= 1;
2484 /* TODO: Support multiple PKEX info entries */
2486 os_free(wpa_s
->dpp_pkex_auth_cmd
);
2487 wpa_s
->dpp_pkex_auth_cmd
= os_strdup(cmd
);
2493 int wpas_dpp_pkex_remove(struct wpa_supplicant
*wpa_s
, const char *id
)
2495 unsigned int id_val
;
2497 if (os_strcmp(id
, "*") == 0) {
2505 if ((id_val
!= 0 && id_val
!= 1) || !wpa_s
->dpp_pkex_code
)
2508 /* TODO: Support multiple PKEX entries */
2509 os_free(wpa_s
->dpp_pkex_code
);
2510 wpa_s
->dpp_pkex_code
= NULL
;
2511 os_free(wpa_s
->dpp_pkex_identifier
);
2512 wpa_s
->dpp_pkex_identifier
= NULL
;
2513 os_free(wpa_s
->dpp_pkex_auth_cmd
);
2514 wpa_s
->dpp_pkex_auth_cmd
= NULL
;
2515 wpa_s
->dpp_pkex_bi
= NULL
;
2516 /* TODO: Remove dpp_pkex only if it is for the identified PKEX code */
2517 dpp_pkex_free(wpa_s
->dpp_pkex
);
2518 wpa_s
->dpp_pkex
= NULL
;
2523 void wpas_dpp_stop(struct wpa_supplicant
*wpa_s
)
2525 dpp_auth_deinit(wpa_s
->dpp_auth
);
2526 wpa_s
->dpp_auth
= NULL
;
2527 dpp_pkex_free(wpa_s
->dpp_pkex
);
2528 wpa_s
->dpp_pkex
= NULL
;
2529 if (wpa_s
->dpp_gas_client
&& wpa_s
->dpp_gas_dialog_token
>= 0)
2530 gas_query_stop(wpa_s
->gas
, wpa_s
->dpp_gas_dialog_token
);
2534 int wpas_dpp_init(struct wpa_supplicant
*wpa_s
)
2536 struct dpp_global_config config
;
2539 adv_proto_id
[0] = WLAN_EID_VENDOR_SPECIFIC
;
2540 adv_proto_id
[1] = 5;
2541 WPA_PUT_BE24(&adv_proto_id
[2], OUI_WFA
);
2542 adv_proto_id
[5] = DPP_OUI_TYPE
;
2543 adv_proto_id
[6] = 0x01;
2545 if (gas_server_register(wpa_s
->gas_server
, adv_proto_id
,
2546 sizeof(adv_proto_id
), wpas_dpp_gas_req_handler
,
2547 wpas_dpp_gas_status_handler
, wpa_s
) < 0)
2550 os_memset(&config
, 0, sizeof(config
));
2551 config
.msg_ctx
= wpa_s
;
2552 config
.cb_ctx
= wpa_s
;
2554 config
.process_conf_obj
= wpas_dpp_process_conf_obj
;
2555 #endif /* CONFIG_DPP2 */
2556 wpa_s
->dpp
= dpp_global_init(&config
);
2557 return wpa_s
->dpp
? 0 : -1;
2561 void wpas_dpp_deinit(struct wpa_supplicant
*wpa_s
)
2563 #ifdef CONFIG_TESTING_OPTIONS
2564 os_free(wpa_s
->dpp_config_obj_override
);
2565 wpa_s
->dpp_config_obj_override
= NULL
;
2566 os_free(wpa_s
->dpp_discovery_override
);
2567 wpa_s
->dpp_discovery_override
= NULL
;
2568 os_free(wpa_s
->dpp_groups_override
);
2569 wpa_s
->dpp_groups_override
= NULL
;
2570 wpa_s
->dpp_ignore_netaccesskey_mismatch
= 0;
2571 #endif /* CONFIG_TESTING_OPTIONS */
2574 dpp_global_clear(wpa_s
->dpp
);
2575 eloop_cancel_timeout(wpas_dpp_pkex_retry_timeout
, wpa_s
, NULL
);
2576 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
2577 eloop_cancel_timeout(wpas_dpp_init_timeout
, wpa_s
, NULL
);
2578 eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout
, wpa_s
, NULL
);
2580 eloop_cancel_timeout(wpas_dpp_config_result_wait_timeout
, wpa_s
, NULL
);
2581 eloop_cancel_timeout(wpas_dpp_conn_status_result_wait_timeout
,
2583 eloop_cancel_timeout(wpas_dpp_conn_status_result_timeout
, wpa_s
, NULL
);
2584 dpp_pfs_free(wpa_s
->dpp_pfs
);
2585 wpa_s
->dpp_pfs
= NULL
;
2586 #endif /* CONFIG_DPP2 */
2587 offchannel_send_action_done(wpa_s
);
2588 wpas_dpp_listen_stop(wpa_s
);
2589 wpas_dpp_stop(wpa_s
);
2590 wpas_dpp_pkex_remove(wpa_s
, "*");
2591 os_memset(wpa_s
->dpp_intro_bssid
, 0, ETH_ALEN
);
2592 os_free(wpa_s
->dpp_configurator_params
);
2593 wpa_s
->dpp_configurator_params
= NULL
;
2598 int wpas_dpp_controller_start(struct wpa_supplicant
*wpa_s
, const char *cmd
)
2600 struct dpp_controller_config config
;
2603 os_memset(&config
, 0, sizeof(config
));
2605 pos
= os_strstr(cmd
, " tcp_port=");
2608 config
.tcp_port
= atoi(pos
);
2611 config
.configurator_params
= wpa_s
->dpp_configurator_params
;
2612 return dpp_controller_start(wpa_s
->dpp
, &config
);
2614 #endif /* CONFIG_DPP2 */