3 * Copyright (c) 2017, Qualcomm Atheros, Inc.
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
9 #include "utils/includes.h"
11 #include "utils/common.h"
12 #include "utils/eloop.h"
13 #include "common/dpp.h"
14 #include "common/gas.h"
15 #include "common/gas_server.h"
16 #include "rsn_supp/wpa.h"
17 #include "rsn_supp/pmksa_cache.h"
18 #include "wpa_supplicant_i.h"
21 #include "offchannel.h"
22 #include "gas_query.h"
26 #include "dpp_supplicant.h"
29 static int wpas_dpp_listen_start(struct wpa_supplicant
*wpa_s
,
31 static void wpas_dpp_reply_wait_timeout(void *eloop_ctx
, void *timeout_ctx
);
32 static void wpas_dpp_auth_success(struct wpa_supplicant
*wpa_s
, int initiator
);
33 static void wpas_dpp_tx_status(struct wpa_supplicant
*wpa_s
,
34 unsigned int freq
, const u8
*dst
,
35 const u8
*src
, const u8
*bssid
,
36 const u8
*data
, size_t data_len
,
37 enum offchannel_send_action_result result
);
39 static const u8 broadcast
[ETH_ALEN
] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
41 /* Use a hardcoded Transaction ID 1 in Peer Discovery frames since there is only
42 * a single transaction in progress at any point in time. */
43 static const u8 TRANSACTION_ID
= 1;
46 static struct dpp_configurator
*
47 dpp_configurator_get_id(struct wpa_supplicant
*wpa_s
, unsigned int id
)
49 struct dpp_configurator
*conf
;
51 dl_list_for_each(conf
, &wpa_s
->dpp_configurator
,
52 struct dpp_configurator
, list
) {
60 static unsigned int wpas_dpp_next_id(struct wpa_supplicant
*wpa_s
)
62 struct dpp_bootstrap_info
*bi
;
63 unsigned int max_id
= 0;
65 dl_list_for_each(bi
, &wpa_s
->dpp_bootstrap
, struct dpp_bootstrap_info
,
75 * wpas_dpp_qr_code - Parse and add DPP bootstrapping info from a QR Code
76 * @wpa_s: Pointer to wpa_supplicant data
77 * @cmd: DPP URI read from a QR Code
78 * Returns: Identifier of the stored info or -1 on failure
80 int wpas_dpp_qr_code(struct wpa_supplicant
*wpa_s
, const char *cmd
)
82 struct dpp_bootstrap_info
*bi
;
83 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
85 bi
= dpp_parse_qr_code(cmd
);
89 bi
->id
= wpas_dpp_next_id(wpa_s
);
90 dl_list_add(&wpa_s
->dpp_bootstrap
, &bi
->list
);
92 if (auth
&& auth
->response_pending
&&
93 dpp_notify_new_qr_code(auth
, bi
) == 1) {
95 "DPP: Sending out pending authentication response");
96 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
98 MAC2STR(auth
->peer_mac_addr
), auth
->curr_freq
,
99 DPP_PA_AUTHENTICATION_RESP
);
100 offchannel_send_action(wpa_s
, auth
->curr_freq
,
101 auth
->peer_mac_addr
, wpa_s
->own_addr
,
103 wpabuf_head(auth
->resp_msg
),
104 wpabuf_len(auth
->resp_msg
),
105 500, wpas_dpp_tx_status
, 0);
112 static char * get_param(const char *cmd
, const char *param
)
114 const char *pos
, *end
;
118 pos
= os_strstr(cmd
, param
);
122 pos
+= os_strlen(param
);
123 end
= os_strchr(pos
, ' ');
127 len
= os_strlen(pos
);
128 val
= os_malloc(len
+ 1);
131 os_memcpy(val
, pos
, len
);
137 int wpas_dpp_bootstrap_gen(struct wpa_supplicant
*wpa_s
, const char *cmd
)
139 char *chan
= NULL
, *mac
= NULL
, *info
= NULL
, *pk
= NULL
, *curve
= NULL
;
142 size_t privkey_len
= 0;
145 struct dpp_bootstrap_info
*bi
;
147 bi
= os_zalloc(sizeof(*bi
));
151 if (os_strstr(cmd
, "type=qrcode"))
152 bi
->type
= DPP_BOOTSTRAP_QR_CODE
;
153 else if (os_strstr(cmd
, "type=pkex"))
154 bi
->type
= DPP_BOOTSTRAP_PKEX
;
158 chan
= get_param(cmd
, " chan=");
159 mac
= get_param(cmd
, " mac=");
160 info
= get_param(cmd
, " info=");
161 curve
= get_param(cmd
, " curve=");
162 key
= get_param(cmd
, " key=");
165 privkey_len
= os_strlen(key
) / 2;
166 privkey
= os_malloc(privkey_len
);
168 hexstr2bin(key
, privkey
, privkey_len
) < 0)
172 pk
= dpp_keygen(bi
, curve
, privkey
, privkey_len
);
176 len
= 4; /* "DPP:" */
178 if (dpp_parse_uri_chan_list(bi
, chan
) < 0)
180 len
+= 3 + os_strlen(chan
); /* C:...; */
183 if (dpp_parse_uri_mac(bi
, mac
) < 0)
185 len
+= 3 + os_strlen(mac
); /* M:...; */
188 if (dpp_parse_uri_info(bi
, info
) < 0)
190 len
+= 3 + os_strlen(info
); /* I:...; */
192 len
+= 4 + os_strlen(pk
);
193 bi
->uri
= os_malloc(len
+ 1);
196 os_snprintf(bi
->uri
, len
+ 1, "DPP:%s%s%s%s%s%s%s%s%sK:%s;;",
197 chan
? "C:" : "", chan
? chan
: "", chan
? ";" : "",
198 mac
? "M:" : "", mac
? mac
: "", mac
? ";" : "",
199 info
? "I:" : "", info
? info
: "", info
? ";" : "",
201 bi
->id
= wpas_dpp_next_id(wpa_s
);
202 dl_list_add(&wpa_s
->dpp_bootstrap
, &bi
->list
);
212 bin_clear_free(privkey
, privkey_len
);
213 dpp_bootstrap_info_free(bi
);
218 static struct dpp_bootstrap_info
*
219 dpp_bootstrap_get_id(struct wpa_supplicant
*wpa_s
, unsigned int id
)
221 struct dpp_bootstrap_info
*bi
;
223 dl_list_for_each(bi
, &wpa_s
->dpp_bootstrap
, struct dpp_bootstrap_info
,
232 static int dpp_bootstrap_del(struct wpa_supplicant
*wpa_s
, unsigned int id
)
234 struct dpp_bootstrap_info
*bi
, *tmp
;
237 dl_list_for_each_safe(bi
, tmp
, &wpa_s
->dpp_bootstrap
,
238 struct dpp_bootstrap_info
, list
) {
239 if (id
&& bi
->id
!= id
)
242 dl_list_del(&bi
->list
);
243 dpp_bootstrap_info_free(bi
);
247 return 0; /* flush succeeds regardless of entries found */
248 return found
? 0 : -1;
252 int wpas_dpp_bootstrap_remove(struct wpa_supplicant
*wpa_s
, const char *id
)
256 if (os_strcmp(id
, "*") == 0) {
264 return dpp_bootstrap_del(wpa_s
, id_val
);
268 const char * wpas_dpp_bootstrap_get_uri(struct wpa_supplicant
*wpa_s
,
271 struct dpp_bootstrap_info
*bi
;
273 bi
= dpp_bootstrap_get_id(wpa_s
, id
);
280 int wpas_dpp_bootstrap_info(struct wpa_supplicant
*wpa_s
, int id
,
281 char *reply
, int reply_size
)
283 struct dpp_bootstrap_info
*bi
;
285 bi
= dpp_bootstrap_get_id(wpa_s
, id
);
288 return os_snprintf(reply
, reply_size
, "type=%s\n"
289 "mac_addr=" MACSTR
"\n"
293 dpp_bootstrap_type_txt(bi
->type
),
294 MAC2STR(bi
->mac_addr
),
295 bi
->info
? bi
->info
: "",
301 static void wpas_dpp_tx_status(struct wpa_supplicant
*wpa_s
,
302 unsigned int freq
, const u8
*dst
,
303 const u8
*src
, const u8
*bssid
,
304 const u8
*data
, size_t data_len
,
305 enum offchannel_send_action_result result
)
309 res_txt
= result
== OFFCHANNEL_SEND_ACTION_SUCCESS
? "SUCCESS" :
310 (result
== OFFCHANNEL_SEND_ACTION_NO_ACK
? "no-ACK" :
312 wpa_printf(MSG_DEBUG
, "DPP: TX status: freq=%u dst=" MACSTR
313 " result=%s", freq
, MAC2STR(dst
), res_txt
);
314 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX_STATUS
"dst=" MACSTR
315 " freq=%u result=%s", MAC2STR(dst
), freq
, res_txt
);
317 if (!wpa_s
->dpp_auth
) {
318 wpa_printf(MSG_DEBUG
,
319 "DPP: Ignore TX status since there is no ongoing authentication exchange");
323 if (wpa_s
->dpp_auth
->remove_on_tx_status
) {
324 wpa_printf(MSG_DEBUG
,
325 "DPP: Terminate authentication exchange due to an earlier error");
326 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
327 offchannel_send_action_done(wpa_s
);
328 dpp_auth_deinit(wpa_s
->dpp_auth
);
329 wpa_s
->dpp_auth
= NULL
;
333 if (wpa_s
->dpp_auth_ok_on_ack
)
334 wpas_dpp_auth_success(wpa_s
, 1);
336 if (!is_broadcast_ether_addr(dst
) &&
337 result
!= OFFCHANNEL_SEND_ACTION_SUCCESS
) {
338 wpa_printf(MSG_DEBUG
,
339 "DPP: Unicast DPP Action frame was not ACKed");
340 /* TODO: In case of DPP Authentication Request frame, move to
341 * the next channel immediately */
344 if (!wpa_s
->dpp_auth_ok_on_ack
&& wpa_s
->dpp_auth
->neg_freq
> 0 &&
345 wpa_s
->dpp_auth
->curr_freq
!= wpa_s
->dpp_auth
->neg_freq
) {
346 wpa_printf(MSG_DEBUG
,
347 "DPP: Move from curr_freq %u MHz to neg_freq %u MHz for response",
348 wpa_s
->dpp_auth
->curr_freq
,
349 wpa_s
->dpp_auth
->neg_freq
);
350 offchannel_send_action_done(wpa_s
);
351 wpas_dpp_listen_start(wpa_s
, wpa_s
->dpp_auth
->neg_freq
);
356 static void wpas_dpp_reply_wait_timeout(void *eloop_ctx
, void *timeout_ctx
)
358 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
361 if (!wpa_s
->dpp_auth
)
363 freq
= wpa_s
->dpp_auth
->curr_freq
;
364 if (wpa_s
->dpp_auth
->neg_freq
> 0)
365 freq
= wpa_s
->dpp_auth
->neg_freq
;
366 wpa_printf(MSG_DEBUG
, "DPP: Continue reply wait on channel %u MHz",
368 wpas_dpp_listen_start(wpa_s
, freq
);
372 static void wpas_dpp_set_testing_options(struct wpa_supplicant
*wpa_s
,
373 struct dpp_authentication
*auth
)
375 #ifdef CONFIG_TESTING_OPTIONS
376 if (wpa_s
->dpp_config_obj_override
)
377 auth
->config_obj_override
=
378 os_strdup(wpa_s
->dpp_config_obj_override
);
379 if (wpa_s
->dpp_discovery_override
)
380 auth
->discovery_override
=
381 os_strdup(wpa_s
->dpp_discovery_override
);
382 if (wpa_s
->dpp_groups_override
)
383 auth
->groups_override
=
384 os_strdup(wpa_s
->dpp_groups_override
);
385 auth
->ignore_netaccesskey_mismatch
=
386 wpa_s
->dpp_ignore_netaccesskey_mismatch
;
387 #endif /* CONFIG_TESTING_OPTIONS */
391 static void wpas_dpp_set_configurator(struct wpa_supplicant
*wpa_s
,
392 struct dpp_authentication
*auth
,
395 const char *pos
, *end
;
396 struct dpp_configuration
*conf_sta
= NULL
, *conf_ap
= NULL
;
397 struct dpp_configurator
*conf
= NULL
;
398 u8 ssid
[32] = { "test" };
408 wpa_printf(MSG_DEBUG
, "DPP: Set configurator parameters: %s", cmd
);
409 pos
= os_strstr(cmd
, " ssid=");
412 end
= os_strchr(pos
, ' ');
413 ssid_len
= end
? (size_t) (end
- pos
) : os_strlen(pos
);
415 if (ssid_len
> sizeof(ssid
) ||
416 hexstr2bin(pos
, ssid
, ssid_len
) < 0)
420 pos
= os_strstr(cmd
, " pass=");
423 end
= os_strchr(pos
, ' ');
424 pass_len
= end
? (size_t) (end
- pos
) : os_strlen(pos
);
426 if (pass_len
> sizeof(pass
) - 1 || pass_len
< 8 ||
427 hexstr2bin(pos
, (u8
*) pass
, pass_len
) < 0)
431 pos
= os_strstr(cmd
, " psk=");
434 if (hexstr2bin(pos
, psk
, PMK_LEN
) < 0)
439 if (os_strstr(cmd
, " conf=sta-")) {
440 conf_sta
= os_zalloc(sizeof(struct dpp_configuration
));
443 os_memcpy(conf_sta
->ssid
, ssid
, ssid_len
);
444 conf_sta
->ssid_len
= ssid_len
;
445 if (os_strstr(cmd
, " conf=sta-psk")) {
448 os_memcpy(conf_sta
->psk
, psk
, PMK_LEN
);
450 conf_sta
->passphrase
= os_strdup(pass
);
451 if (!conf_sta
->passphrase
)
454 } else if (os_strstr(cmd
, " conf=sta-dpp")) {
461 if (os_strstr(cmd
, " conf=ap-")) {
462 conf_ap
= os_zalloc(sizeof(struct dpp_configuration
));
465 os_memcpy(conf_ap
->ssid
, ssid
, ssid_len
);
466 conf_ap
->ssid_len
= ssid_len
;
467 if (os_strstr(cmd
, " conf=ap-psk")) {
470 os_memcpy(conf_ap
->psk
, psk
, PMK_LEN
);
472 conf_ap
->passphrase
= os_strdup(pass
);
473 if (!conf_ap
->passphrase
)
476 } else if (os_strstr(cmd
, " conf=ap-dpp")) {
483 pos
= os_strstr(cmd
, " expiry=");
488 val
= strtol(pos
, NULL
, 0);
492 conf_sta
->netaccesskey_expiry
= val
;
494 conf_ap
->netaccesskey_expiry
= val
;
497 pos
= os_strstr(cmd
, " configurator=");
500 conf
= dpp_configurator_get_id(wpa_s
, atoi(pos
));
503 "DPP: Could not find the specified configurator");
507 auth
->conf_sta
= conf_sta
;
508 auth
->conf_ap
= conf_ap
;
513 wpa_printf(MSG_DEBUG
, "DPP: Failed to set configurator parameters");
514 dpp_configuration_free(conf_sta
);
515 dpp_configuration_free(conf_ap
);
519 int wpas_dpp_auth_init(struct wpa_supplicant
*wpa_s
, const char *cmd
)
522 struct dpp_bootstrap_info
*peer_bi
, *own_bi
= NULL
;
525 int configurator
= 1;
526 unsigned int wait_time
;
527 unsigned int neg_freq
= 0;
529 wpa_s
->dpp_gas_client
= 0;
531 pos
= os_strstr(cmd
, " peer=");
535 peer_bi
= dpp_bootstrap_get_id(wpa_s
, atoi(pos
));
538 "DPP: Could not find bootstrapping info for the identified peer");
542 pos
= os_strstr(cmd
, " own=");
545 own_bi
= dpp_bootstrap_get_id(wpa_s
, atoi(pos
));
548 "DPP: Could not find bootstrapping info for the identified local entry");
552 if (peer_bi
->curve
!= own_bi
->curve
) {
554 "DPP: Mismatching curves in bootstrapping info (peer=%s own=%s)",
555 peer_bi
->curve
->name
, own_bi
->curve
->name
);
560 pos
= os_strstr(cmd
, " role=");
563 if (os_strncmp(pos
, "configurator", 12) == 0)
565 else if (os_strncmp(pos
, "enrollee", 8) == 0)
571 pos
= os_strstr(cmd
, " netrole=");
574 wpa_s
->dpp_netrole_ap
= os_strncmp(pos
, "ap", 2) == 0;
577 pos
= os_strstr(cmd
, " neg_freq=");
579 neg_freq
= atoi(pos
+ 10);
581 if (wpa_s
->dpp_auth
) {
582 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
583 offchannel_send_action_done(wpa_s
);
584 dpp_auth_deinit(wpa_s
->dpp_auth
);
586 wpa_s
->dpp_auth
= dpp_auth_init(wpa_s
, peer_bi
, own_bi
, configurator
,
588 if (!wpa_s
->dpp_auth
)
590 wpas_dpp_set_testing_options(wpa_s
, wpa_s
->dpp_auth
);
591 wpas_dpp_set_configurator(wpa_s
, wpa_s
->dpp_auth
, cmd
);
593 /* TODO: Support iteration over all frequencies and filtering of
594 * frequencies based on locally enabled channels that allow initiation
595 * of transmission. */
596 if (peer_bi
->num_freq
> 0)
597 wpa_s
->dpp_auth
->curr_freq
= peer_bi
->freq
[0];
599 wpa_s
->dpp_auth
->curr_freq
= 2412;
600 wpa_s
->dpp_auth
->neg_freq
= neg_freq
;
602 if (is_zero_ether_addr(peer_bi
->mac_addr
)) {
605 dst
= peer_bi
->mac_addr
;
606 os_memcpy(wpa_s
->dpp_auth
->peer_mac_addr
, peer_bi
->mac_addr
,
609 wpa_s
->dpp_auth_ok_on_ack
= 0;
610 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
611 wait_time
= wpa_s
->max_remain_on_chan
;
612 if (wait_time
> 2000)
614 eloop_register_timeout(wait_time
/ 1000, (wait_time
% 1000) * 1000,
615 wpas_dpp_reply_wait_timeout
,
617 if (neg_freq
> 0 && wpa_s
->dpp_auth
->curr_freq
!= neg_freq
) {
618 wpa_printf(MSG_DEBUG
,
619 "DPP: Initiate on curr_freq %u MHz and move to neg_freq %u MHz for response",
620 wpa_s
->dpp_auth
->curr_freq
,
621 wpa_s
->dpp_auth
->neg_freq
);
623 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
624 MAC2STR(dst
), wpa_s
->dpp_auth
->curr_freq
,
625 DPP_PA_AUTHENTICATION_REQ
);
626 res
= offchannel_send_action(wpa_s
, wpa_s
->dpp_auth
->curr_freq
,
627 dst
, wpa_s
->own_addr
, broadcast
,
628 wpabuf_head(wpa_s
->dpp_auth
->req_msg
),
629 wpabuf_len(wpa_s
->dpp_auth
->req_msg
),
630 wait_time
, wpas_dpp_tx_status
, 0);
638 struct wpas_dpp_listen_work
{
640 unsigned int duration
;
641 struct wpabuf
*probe_resp_ie
;
645 static void wpas_dpp_listen_work_free(struct wpas_dpp_listen_work
*lwork
)
653 static void wpas_dpp_listen_work_done(struct wpa_supplicant
*wpa_s
)
655 struct wpas_dpp_listen_work
*lwork
;
657 if (!wpa_s
->dpp_listen_work
)
660 lwork
= wpa_s
->dpp_listen_work
->ctx
;
661 wpas_dpp_listen_work_free(lwork
);
662 radio_work_done(wpa_s
->dpp_listen_work
);
663 wpa_s
->dpp_listen_work
= NULL
;
667 static void dpp_start_listen_cb(struct wpa_radio_work
*work
, int deinit
)
669 struct wpa_supplicant
*wpa_s
= work
->wpa_s
;
670 struct wpas_dpp_listen_work
*lwork
= work
->ctx
;
674 wpa_s
->dpp_listen_work
= NULL
;
675 wpas_dpp_listen_stop(wpa_s
);
677 wpas_dpp_listen_work_free(lwork
);
681 wpa_s
->dpp_listen_work
= work
;
683 wpa_s
->dpp_pending_listen_freq
= lwork
->freq
;
685 if (wpa_drv_remain_on_channel(wpa_s
, lwork
->freq
,
686 wpa_s
->max_remain_on_chan
) < 0) {
687 wpa_printf(MSG_DEBUG
,
688 "DPP: Failed to request the driver to remain on channel (%u MHz) for listen",
690 wpas_dpp_listen_work_done(wpa_s
);
691 wpa_s
->dpp_pending_listen_freq
= 0;
694 wpa_s
->off_channel_freq
= 0;
695 wpa_s
->roc_waiting_drv_freq
= lwork
->freq
;
699 static int wpas_dpp_listen_start(struct wpa_supplicant
*wpa_s
,
702 struct wpas_dpp_listen_work
*lwork
;
704 if (wpa_s
->dpp_listen_work
) {
705 wpa_printf(MSG_DEBUG
,
706 "DPP: Reject start_listen since dpp_listen_work already exists");
710 if (wpa_s
->dpp_listen_freq
)
711 wpas_dpp_listen_stop(wpa_s
);
712 wpa_s
->dpp_listen_freq
= freq
;
714 lwork
= os_zalloc(sizeof(*lwork
));
719 if (radio_add_work(wpa_s
, freq
, "dpp-listen", 0, dpp_start_listen_cb
,
721 wpas_dpp_listen_work_free(lwork
);
729 int wpas_dpp_listen(struct wpa_supplicant
*wpa_s
, const char *cmd
)
737 if (os_strstr(cmd
, " role=configurator"))
738 wpa_s
->dpp_allowed_roles
= DPP_CAPAB_CONFIGURATOR
;
739 else if (os_strstr(cmd
, " role=enrollee"))
740 wpa_s
->dpp_allowed_roles
= DPP_CAPAB_ENROLLEE
;
742 wpa_s
->dpp_allowed_roles
= DPP_CAPAB_CONFIGURATOR
|
744 wpa_s
->dpp_qr_mutual
= os_strstr(cmd
, " qr=mutual") != NULL
;
745 wpa_s
->dpp_netrole_ap
= os_strstr(cmd
, " netrole=ap") != NULL
;
746 if (wpa_s
->dpp_listen_freq
== (unsigned int) freq
) {
747 wpa_printf(MSG_DEBUG
, "DPP: Already listening on %u MHz",
752 return wpas_dpp_listen_start(wpa_s
, freq
);
756 void wpas_dpp_listen_stop(struct wpa_supplicant
*wpa_s
)
758 if (!wpa_s
->dpp_listen_freq
)
761 wpa_printf(MSG_DEBUG
, "DPP: Stop listen on %u MHz",
762 wpa_s
->dpp_listen_freq
);
763 wpa_drv_cancel_remain_on_channel(wpa_s
);
764 wpa_s
->dpp_listen_freq
= 0;
765 wpas_dpp_listen_work_done(wpa_s
);
769 void wpas_dpp_remain_on_channel_cb(struct wpa_supplicant
*wpa_s
,
772 if (!wpa_s
->dpp_listen_freq
&& !wpa_s
->dpp_pending_listen_freq
)
775 wpa_printf(MSG_DEBUG
,
776 "DPP: remain-on-channel callback (off_channel_freq=%u dpp_pending_listen_freq=%d roc_waiting_drv_freq=%d freq=%u)",
777 wpa_s
->off_channel_freq
, wpa_s
->dpp_pending_listen_freq
,
778 wpa_s
->roc_waiting_drv_freq
, freq
);
779 if (wpa_s
->off_channel_freq
&&
780 wpa_s
->off_channel_freq
== wpa_s
->dpp_pending_listen_freq
) {
781 wpa_printf(MSG_DEBUG
, "DPP: Listen on %u MHz started", freq
);
782 wpa_s
->dpp_pending_listen_freq
= 0;
784 wpa_printf(MSG_DEBUG
,
785 "DPP: Ignore remain-on-channel callback (off_channel_freq=%u dpp_pending_listen_freq=%d freq=%u)",
786 wpa_s
->off_channel_freq
,
787 wpa_s
->dpp_pending_listen_freq
, freq
);
792 void wpas_dpp_cancel_remain_on_channel_cb(struct wpa_supplicant
*wpa_s
,
795 wpas_dpp_listen_work_done(wpa_s
);
797 if (wpa_s
->dpp_auth
&& !wpa_s
->dpp_gas_client
) {
798 /* Continue listen with a new remain-on-channel */
799 wpa_printf(MSG_DEBUG
,
800 "DPP: Continue wait on %u MHz for the ongoing DPP provisioning session",
801 wpa_s
->dpp_auth
->curr_freq
);
802 wpas_dpp_listen_start(wpa_s
, wpa_s
->dpp_auth
->curr_freq
);
806 if (wpa_s
->dpp_listen_freq
) {
807 /* Continue listen with a new remain-on-channel */
808 wpas_dpp_listen_start(wpa_s
, wpa_s
->dpp_listen_freq
);
813 static void wpas_dpp_rx_auth_req(struct wpa_supplicant
*wpa_s
, const u8
*src
,
814 const u8
*hdr
, const u8
*buf
, size_t len
,
817 const u8
*r_bootstrap
, *i_bootstrap
;
818 u16 r_bootstrap_len
, i_bootstrap_len
;
819 struct dpp_bootstrap_info
*bi
, *own_bi
= NULL
, *peer_bi
= NULL
;
821 wpa_printf(MSG_DEBUG
, "DPP: Authentication Request from " MACSTR
,
824 r_bootstrap
= dpp_get_attr(buf
, len
, DPP_ATTR_R_BOOTSTRAP_KEY_HASH
,
826 if (!r_bootstrap
|| r_bootstrap_len
!= SHA256_MAC_LEN
) {
827 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
828 "Missing or invalid required Responder Bootstrapping Key Hash attribute");
831 wpa_hexdump(MSG_MSGDUMP
, "DPP: Responder Bootstrapping Key Hash",
832 r_bootstrap
, r_bootstrap_len
);
834 i_bootstrap
= dpp_get_attr(buf
, len
, DPP_ATTR_I_BOOTSTRAP_KEY_HASH
,
836 if (!i_bootstrap
|| i_bootstrap_len
!= SHA256_MAC_LEN
) {
837 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
838 "Missing or invalid required Initiator Bootstrapping Key Hash attribute");
841 wpa_hexdump(MSG_MSGDUMP
, "DPP: Initiator Bootstrapping Key Hash",
842 i_bootstrap
, i_bootstrap_len
);
844 /* Try to find own and peer bootstrapping key matches based on the
845 * received hash values */
846 dl_list_for_each(bi
, &wpa_s
->dpp_bootstrap
, struct dpp_bootstrap_info
,
848 if (!own_bi
&& bi
->own
&&
849 os_memcmp(bi
->pubkey_hash
, r_bootstrap
,
850 SHA256_MAC_LEN
) == 0) {
851 wpa_printf(MSG_DEBUG
,
852 "DPP: Found matching own bootstrapping information");
856 if (!peer_bi
&& !bi
->own
&&
857 os_memcmp(bi
->pubkey_hash
, i_bootstrap
,
858 SHA256_MAC_LEN
) == 0) {
859 wpa_printf(MSG_DEBUG
,
860 "DPP: Found matching peer bootstrapping information");
864 if (own_bi
&& peer_bi
)
869 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
870 "No matching own bootstrapping key found - ignore message");
874 if (wpa_s
->dpp_auth
) {
875 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_FAIL
876 "Already in DPP authentication exchange - ignore new one");
880 wpa_s
->dpp_gas_client
= 0;
881 wpa_s
->dpp_auth_ok_on_ack
= 0;
882 wpa_s
->dpp_auth
= dpp_auth_req_rx(wpa_s
, wpa_s
->dpp_allowed_roles
,
883 wpa_s
->dpp_qr_mutual
,
884 peer_bi
, own_bi
, freq
, hdr
, buf
, len
);
885 if (!wpa_s
->dpp_auth
) {
886 wpa_printf(MSG_DEBUG
, "DPP: No response generated");
889 wpas_dpp_set_testing_options(wpa_s
, wpa_s
->dpp_auth
);
890 wpas_dpp_set_configurator(wpa_s
, wpa_s
->dpp_auth
,
891 wpa_s
->dpp_configurator_params
);
892 os_memcpy(wpa_s
->dpp_auth
->peer_mac_addr
, src
, ETH_ALEN
);
894 if (wpa_s
->dpp_listen_freq
&&
895 wpa_s
->dpp_listen_freq
!= wpa_s
->dpp_auth
->curr_freq
) {
896 wpa_printf(MSG_DEBUG
,
897 "DPP: Stop listen on %u MHz to allow response on the request %u MHz",
898 wpa_s
->dpp_listen_freq
, wpa_s
->dpp_auth
->curr_freq
);
899 wpas_dpp_listen_stop(wpa_s
);
902 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
903 MAC2STR(src
), wpa_s
->dpp_auth
->curr_freq
,
904 DPP_PA_AUTHENTICATION_RESP
);
905 offchannel_send_action(wpa_s
, wpa_s
->dpp_auth
->curr_freq
,
906 src
, wpa_s
->own_addr
, broadcast
,
907 wpabuf_head(wpa_s
->dpp_auth
->resp_msg
),
908 wpabuf_len(wpa_s
->dpp_auth
->resp_msg
),
909 500, wpas_dpp_tx_status
, 0);
913 static void wpas_dpp_start_gas_server(struct wpa_supplicant
*wpa_s
)
915 /* TODO: stop wait and start ROC */
919 static struct wpa_ssid
* wpas_dpp_add_network(struct wpa_supplicant
*wpa_s
,
920 struct dpp_authentication
*auth
)
922 struct wpa_ssid
*ssid
;
924 ssid
= wpa_config_add_network(wpa_s
->conf
);
927 wpas_notify_network_added(wpa_s
, ssid
);
928 wpa_config_set_network_defaults(ssid
);
931 ssid
->ssid
= os_malloc(auth
->ssid_len
);
934 os_memcpy(ssid
->ssid
, auth
->ssid
, auth
->ssid_len
);
935 ssid
->ssid_len
= auth
->ssid_len
;
937 if (auth
->connector
) {
938 ssid
->key_mgmt
= WPA_KEY_MGMT_DPP
;
939 ssid
->ieee80211w
= 1;
940 ssid
->dpp_connector
= os_strdup(auth
->connector
);
941 if (!ssid
->dpp_connector
)
945 if (auth
->c_sign_key
) {
946 ssid
->dpp_csign
= os_malloc(wpabuf_len(auth
->c_sign_key
));
947 if (!ssid
->dpp_csign
)
949 os_memcpy(ssid
->dpp_csign
, wpabuf_head(auth
->c_sign_key
),
950 wpabuf_len(auth
->c_sign_key
));
951 ssid
->dpp_csign_len
= wpabuf_len(auth
->c_sign_key
);
954 if (auth
->net_access_key
) {
955 ssid
->dpp_netaccesskey
=
956 os_malloc(wpabuf_len(auth
->net_access_key
));
957 if (!ssid
->dpp_netaccesskey
)
959 os_memcpy(ssid
->dpp_netaccesskey
,
960 wpabuf_head(auth
->net_access_key
),
961 wpabuf_len(auth
->net_access_key
));
962 ssid
->dpp_netaccesskey_len
= wpabuf_len(auth
->net_access_key
);
963 ssid
->dpp_netaccesskey_expiry
= auth
->net_access_key_expiry
;
966 if (!auth
->connector
) {
967 ssid
->key_mgmt
= WPA_KEY_MGMT_PSK
| WPA_KEY_MGMT_PSK_SHA256
;
968 ssid
->ieee80211w
= 1;
969 if (auth
->passphrase
[0]) {
970 if (wpa_config_set_quoted(ssid
, "psk",
971 auth
->passphrase
) < 0)
973 wpa_config_update_psk(ssid
);
974 ssid
->export_keys
= 1;
976 ssid
->psk_set
= auth
->psk_set
;
977 os_memcpy(ssid
->psk
, auth
->psk
, PMK_LEN
);
983 wpas_notify_network_removed(wpa_s
, ssid
);
984 wpa_config_remove_network(wpa_s
->conf
, ssid
->id
);
989 static void wpas_dpp_process_config(struct wpa_supplicant
*wpa_s
,
990 struct dpp_authentication
*auth
)
992 struct wpa_ssid
*ssid
;
994 if (wpa_s
->conf
->dpp_config_processing
< 1)
997 ssid
= wpas_dpp_add_network(wpa_s
, auth
);
1001 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_NETWORK_ID
"%d", ssid
->id
);
1002 if (wpa_s
->conf
->dpp_config_processing
< 2)
1005 wpa_printf(MSG_DEBUG
, "DPP: Trying to connect to the new network");
1007 wpa_s
->disconnected
= 0;
1008 wpa_s
->reassociate
= 1;
1009 wpa_s
->scan_runs
= 0;
1010 wpa_s
->normal_scans
= 0;
1011 wpa_supplicant_cancel_sched_scan(wpa_s
);
1012 wpa_supplicant_req_scan(wpa_s
, 0, 0);
1016 static void wpas_dpp_handle_config_obj(struct wpa_supplicant
*wpa_s
,
1017 struct dpp_authentication
*auth
)
1019 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_RECEIVED
);
1021 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONFOBJ_SSID
"%s",
1022 wpa_ssid_txt(auth
->ssid
, auth
->ssid_len
));
1023 if (auth
->connector
) {
1024 /* TODO: Save the Connector and consider using a command
1025 * to fetch the value instead of sending an event with
1026 * it. The Connector could end up being larger than what
1027 * most clients are ready to receive as an event
1029 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONNECTOR
"%s",
1032 if (auth
->c_sign_key
) {
1036 hexlen
= 2 * wpabuf_len(auth
->c_sign_key
) + 1;
1037 hex
= os_malloc(hexlen
);
1039 wpa_snprintf_hex(hex
, hexlen
,
1040 wpabuf_head(auth
->c_sign_key
),
1041 wpabuf_len(auth
->c_sign_key
));
1042 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_C_SIGN_KEY
"%s",
1047 if (auth
->net_access_key
) {
1051 hexlen
= 2 * wpabuf_len(auth
->net_access_key
) + 1;
1052 hex
= os_malloc(hexlen
);
1054 wpa_snprintf_hex(hex
, hexlen
,
1055 wpabuf_head(auth
->net_access_key
),
1056 wpabuf_len(auth
->net_access_key
));
1057 if (auth
->net_access_key_expiry
)
1058 wpa_msg(wpa_s
, MSG_INFO
,
1059 DPP_EVENT_NET_ACCESS_KEY
"%s %lu", hex
,
1061 auth
->net_access_key_expiry
);
1063 wpa_msg(wpa_s
, MSG_INFO
,
1064 DPP_EVENT_NET_ACCESS_KEY
"%s", hex
);
1069 wpas_dpp_process_config(wpa_s
, auth
);
1073 static void wpas_dpp_gas_resp_cb(void *ctx
, const u8
*addr
, u8 dialog_token
,
1074 enum gas_query_result result
,
1075 const struct wpabuf
*adv_proto
,
1076 const struct wpabuf
*resp
, u16 status_code
)
1078 struct wpa_supplicant
*wpa_s
= ctx
;
1080 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1082 if (!auth
|| !auth
->auth_success
) {
1083 wpa_printf(MSG_DEBUG
, "DPP: No matching exchange in progress");
1086 if (!resp
|| status_code
!= WLAN_STATUS_SUCCESS
) {
1087 wpa_printf(MSG_DEBUG
, "DPP: GAS query did not succeed");
1091 wpa_hexdump_buf(MSG_DEBUG
, "DPP: Configuration Response adv_proto",
1093 wpa_hexdump_buf(MSG_DEBUG
, "DPP: Configuration Response (GAS response)",
1096 if (wpabuf_len(adv_proto
) != 10 ||
1097 !(pos
= wpabuf_head(adv_proto
)) ||
1098 pos
[0] != WLAN_EID_ADV_PROTO
||
1100 pos
[3] != WLAN_EID_VENDOR_SPECIFIC
||
1102 WPA_GET_BE24(&pos
[5]) != OUI_WFA
||
1105 wpa_printf(MSG_DEBUG
,
1106 "DPP: Not a DPP Advertisement Protocol ID");
1110 if (dpp_conf_resp_rx(auth
, resp
) < 0) {
1111 wpa_printf(MSG_DEBUG
, "DPP: Configuration attempt failed");
1115 wpas_dpp_handle_config_obj(wpa_s
, auth
);
1116 dpp_auth_deinit(wpa_s
->dpp_auth
);
1117 wpa_s
->dpp_auth
= NULL
;
1121 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
1122 dpp_auth_deinit(wpa_s
->dpp_auth
);
1123 wpa_s
->dpp_auth
= NULL
;
1127 static void wpas_dpp_start_gas_client(struct wpa_supplicant
*wpa_s
)
1129 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1130 struct wpabuf
*buf
, *conf_req
;
1134 wpa_s
->dpp_gas_client
= 1;
1135 os_snprintf(json
, sizeof(json
),
1136 "{\"name\":\"Test\","
1137 "\"wi-fi_tech\":\"infra\","
1138 "\"netRole\":\"%s\"}",
1139 wpa_s
->dpp_netrole_ap
? "ap" : "sta");
1140 wpa_printf(MSG_DEBUG
, "DPP: GAS Config Attributes: %s", json
);
1142 offchannel_send_action_done(wpa_s
);
1143 wpas_dpp_listen_stop(wpa_s
);
1145 conf_req
= dpp_build_conf_req(auth
, json
);
1147 wpa_printf(MSG_DEBUG
,
1148 "DPP: No configuration request data available");
1152 buf
= gas_build_initial_req(0, 10 + 2 + wpabuf_len(conf_req
));
1154 wpabuf_free(conf_req
);
1158 /* Advertisement Protocol IE */
1159 wpabuf_put_u8(buf
, WLAN_EID_ADV_PROTO
);
1160 wpabuf_put_u8(buf
, 8); /* Length */
1161 wpabuf_put_u8(buf
, 0x7f);
1162 wpabuf_put_u8(buf
, WLAN_EID_VENDOR_SPECIFIC
);
1163 wpabuf_put_u8(buf
, 5);
1164 wpabuf_put_be24(buf
, OUI_WFA
);
1165 wpabuf_put_u8(buf
, DPP_OUI_TYPE
);
1166 wpabuf_put_u8(buf
, 0x01);
1169 wpabuf_put_le16(buf
, wpabuf_len(conf_req
));
1170 wpabuf_put_buf(buf
, conf_req
);
1171 wpabuf_free(conf_req
);
1173 wpa_printf(MSG_DEBUG
, "DPP: GAS request to " MACSTR
" (freq %u MHz)",
1174 MAC2STR(auth
->peer_mac_addr
), auth
->curr_freq
);
1176 res
= gas_query_req(wpa_s
->gas
, auth
->peer_mac_addr
, auth
->curr_freq
,
1177 buf
, wpas_dpp_gas_resp_cb
, wpa_s
);
1179 wpa_msg(wpa_s
, MSG_DEBUG
, "GAS: Failed to send Query Request");
1182 wpa_printf(MSG_DEBUG
,
1183 "DPP: GAS query started with dialog token %u", res
);
1188 static void wpas_dpp_auth_success(struct wpa_supplicant
*wpa_s
, int initiator
)
1190 wpa_printf(MSG_DEBUG
, "DPP: Authentication succeeded");
1191 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_AUTH_SUCCESS
"init=%d", initiator
);
1193 if (wpa_s
->dpp_auth
->configurator
)
1194 wpas_dpp_start_gas_server(wpa_s
);
1196 wpas_dpp_start_gas_client(wpa_s
);
1200 static void wpas_dpp_rx_auth_resp(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1201 const u8
*hdr
, const u8
*buf
, size_t len
,
1204 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1207 wpa_printf(MSG_DEBUG
, "DPP: Authentication Response from " MACSTR
1208 " (freq %u MHz)", MAC2STR(src
), freq
);
1211 wpa_printf(MSG_DEBUG
,
1212 "DPP: No DPP Authentication in progress - drop");
1216 if (!is_zero_ether_addr(auth
->peer_mac_addr
) &&
1217 os_memcmp(src
, auth
->peer_mac_addr
, ETH_ALEN
) != 0) {
1218 wpa_printf(MSG_DEBUG
, "DPP: MAC address mismatch (expected "
1219 MACSTR
") - drop", MAC2STR(auth
->peer_mac_addr
));
1223 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
1225 if (auth
->curr_freq
!= freq
&& auth
->neg_freq
== freq
) {
1226 wpa_printf(MSG_DEBUG
,
1227 "DPP: Responder accepted request for different negotiation channel");
1228 auth
->curr_freq
= freq
;
1231 msg
= dpp_auth_resp_rx(auth
, hdr
, buf
, len
);
1233 if (auth
->auth_resp_status
== DPP_STATUS_RESPONSE_PENDING
) {
1234 wpa_printf(MSG_DEBUG
,
1235 "DPP: Start wait for full response");
1236 offchannel_send_action_done(wpa_s
);
1237 wpas_dpp_listen_start(wpa_s
, auth
->curr_freq
);
1240 wpa_printf(MSG_DEBUG
, "DPP: No confirm generated");
1243 os_memcpy(auth
->peer_mac_addr
, src
, ETH_ALEN
);
1245 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1246 MAC2STR(src
), auth
->curr_freq
, DPP_PA_AUTHENTICATION_CONF
);
1247 offchannel_send_action(wpa_s
, auth
->curr_freq
,
1248 src
, wpa_s
->own_addr
, broadcast
,
1249 wpabuf_head(msg
), wpabuf_len(msg
),
1250 500, wpas_dpp_tx_status
, 0);
1252 wpa_s
->dpp_auth_ok_on_ack
= 1;
1256 static void wpas_dpp_rx_auth_conf(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1257 const u8
*hdr
, const u8
*buf
, size_t len
)
1259 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1261 wpa_printf(MSG_DEBUG
, "DPP: Authentication Confirmation from " MACSTR
,
1265 wpa_printf(MSG_DEBUG
,
1266 "DPP: No DPP Authentication in progress - drop");
1270 if (os_memcmp(src
, auth
->peer_mac_addr
, ETH_ALEN
) != 0) {
1271 wpa_printf(MSG_DEBUG
, "DPP: MAC address mismatch (expected "
1272 MACSTR
") - drop", MAC2STR(auth
->peer_mac_addr
));
1276 if (dpp_auth_conf_rx(auth
, hdr
, buf
, len
) < 0) {
1277 wpa_printf(MSG_DEBUG
, "DPP: Authentication failed");
1281 wpas_dpp_auth_success(wpa_s
, 0);
1285 static void wpas_dpp_rx_peer_disc_resp(struct wpa_supplicant
*wpa_s
,
1287 const u8
*buf
, size_t len
)
1289 struct wpa_ssid
*ssid
;
1290 const u8
*connector
, *trans_id
, *status
;
1291 u16 connector_len
, trans_id_len
, status_len
;
1292 struct dpp_introduction intro
;
1293 struct rsn_pmksa_cache_entry
*entry
;
1295 struct os_reltime rnow
;
1297 unsigned int seconds
;
1298 enum dpp_status_error res
;
1300 wpa_printf(MSG_DEBUG
, "DPP: Peer Discovery Response from " MACSTR
,
1302 if (is_zero_ether_addr(wpa_s
->dpp_intro_bssid
) ||
1303 os_memcmp(src
, wpa_s
->dpp_intro_bssid
, ETH_ALEN
) != 0) {
1304 wpa_printf(MSG_DEBUG
, "DPP: Not waiting for response from "
1305 MACSTR
" - drop", MAC2STR(src
));
1308 offchannel_send_action_done(wpa_s
);
1310 for (ssid
= wpa_s
->conf
->ssid
; ssid
; ssid
= ssid
->next
) {
1311 if (ssid
== wpa_s
->dpp_intro_network
)
1314 if (!ssid
|| !ssid
->dpp_connector
|| !ssid
->dpp_netaccesskey
||
1316 wpa_printf(MSG_DEBUG
,
1317 "DPP: Profile not found for network introduction");
1321 trans_id
= dpp_get_attr(buf
, len
, DPP_ATTR_TRANSACTION_ID
,
1323 if (!trans_id
|| trans_id_len
!= 1) {
1324 wpa_printf(MSG_DEBUG
,
1325 "DPP: Peer did not include Transaction ID");
1326 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1327 " fail=missing_transaction_id", MAC2STR(src
));
1330 if (trans_id
[0] != TRANSACTION_ID
) {
1331 wpa_printf(MSG_DEBUG
,
1332 "DPP: Ignore frame with unexpected Transaction ID %u",
1334 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1335 " fail=transaction_id_mismatch", MAC2STR(src
));
1339 status
= dpp_get_attr(buf
, len
, DPP_ATTR_STATUS
, &status_len
);
1340 if (!status
|| status_len
!= 1) {
1341 wpa_printf(MSG_DEBUG
, "DPP: Peer did not include Status");
1342 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1343 " fail=missing_status", MAC2STR(src
));
1346 if (status
[0] != DPP_STATUS_OK
) {
1347 wpa_printf(MSG_DEBUG
,
1348 "DPP: Peer rejected network introduction: Status %u",
1350 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1351 " status=%u", MAC2STR(src
), status
[0]);
1355 connector
= dpp_get_attr(buf
, len
, DPP_ATTR_CONNECTOR
, &connector_len
);
1357 wpa_printf(MSG_DEBUG
,
1358 "DPP: Peer did not include its Connector");
1359 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1360 " fail=missing_connector", MAC2STR(src
));
1364 res
= dpp_peer_intro(&intro
, ssid
->dpp_connector
,
1365 ssid
->dpp_netaccesskey
,
1366 ssid
->dpp_netaccesskey_len
,
1368 ssid
->dpp_csign_len
,
1369 connector
, connector_len
, &expiry
);
1370 if (res
!= DPP_STATUS_OK
) {
1371 wpa_printf(MSG_INFO
,
1372 "DPP: Network Introduction protocol resulted in failure");
1373 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1374 " fail=peer_connector_validation_failed", MAC2STR(src
));
1378 entry
= os_zalloc(sizeof(*entry
));
1381 os_memcpy(entry
->aa
, src
, ETH_ALEN
);
1382 os_memcpy(entry
->pmkid
, intro
.pmkid
, PMKID_LEN
);
1383 os_memcpy(entry
->pmk
, intro
.pmk
, intro
.pmk_len
);
1384 entry
->pmk_len
= intro
.pmk_len
;
1385 entry
->akmp
= WPA_KEY_MGMT_DPP
;
1388 seconds
= expiry
- now
.sec
;
1390 seconds
= 86400 * 7;
1392 os_get_reltime(&rnow
);
1393 entry
->expiration
= rnow
.sec
+ seconds
;
1394 entry
->reauth_time
= rnow
.sec
+ seconds
;
1395 entry
->network_ctx
= ssid
;
1396 wpa_sm_pmksa_cache_add_entry(wpa_s
->wpa
, entry
);
1398 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_INTRO
"peer=" MACSTR
1399 " status=%u", MAC2STR(src
), status
[0]);
1401 wpa_printf(MSG_DEBUG
,
1402 "DPP: Try connection again after successful network introduction");
1403 if (wpa_supplicant_fast_associate(wpa_s
) != 1) {
1404 wpa_supplicant_cancel_sched_scan(wpa_s
);
1405 wpa_supplicant_req_scan(wpa_s
, 0, 0);
1408 os_memset(&intro
, 0, sizeof(intro
));
1413 wpas_dpp_tx_pkex_status(struct wpa_supplicant
*wpa_s
,
1414 unsigned int freq
, const u8
*dst
,
1415 const u8
*src
, const u8
*bssid
,
1416 const u8
*data
, size_t data_len
,
1417 enum offchannel_send_action_result result
)
1419 const char *res_txt
;
1421 res_txt
= result
== OFFCHANNEL_SEND_ACTION_SUCCESS
? "SUCCESS" :
1422 (result
== OFFCHANNEL_SEND_ACTION_NO_ACK
? "no-ACK" :
1424 wpa_printf(MSG_DEBUG
, "DPP: TX status: freq=%u dst=" MACSTR
1425 " result=%s (PKEX)",
1426 freq
, MAC2STR(dst
), res_txt
);
1427 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX_STATUS
"dst=" MACSTR
1428 " freq=%u result=%s", MAC2STR(dst
), freq
, res_txt
);
1429 /* TODO: Time out wait for response more quickly in error cases? */
1434 wpas_dpp_rx_pkex_exchange_req(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1435 const u8
*buf
, size_t len
, unsigned int freq
)
1438 unsigned int wait_time
;
1440 wpa_printf(MSG_DEBUG
, "DPP: PKEX Exchange Request from " MACSTR
,
1443 /* TODO: Support multiple PKEX codes by iterating over all the enabled
1446 if (!wpa_s
->dpp_pkex_code
|| !wpa_s
->dpp_pkex_bi
) {
1447 wpa_printf(MSG_DEBUG
,
1448 "DPP: No PKEX code configured - ignore request");
1452 if (wpa_s
->dpp_pkex
) {
1453 /* TODO: Support parallel operations */
1454 wpa_printf(MSG_DEBUG
,
1455 "DPP: Already in PKEX session - ignore new request");
1459 wpa_s
->dpp_pkex
= dpp_pkex_rx_exchange_req(wpa_s
->dpp_pkex_bi
,
1460 wpa_s
->own_addr
, src
,
1461 wpa_s
->dpp_pkex_identifier
,
1462 wpa_s
->dpp_pkex_code
,
1464 if (!wpa_s
->dpp_pkex
) {
1465 wpa_printf(MSG_DEBUG
,
1466 "DPP: Failed to process the request - ignore it");
1470 msg
= wpa_s
->dpp_pkex
->exchange_resp
;
1471 wait_time
= wpa_s
->max_remain_on_chan
;
1472 if (wait_time
> 2000)
1474 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1475 MAC2STR(src
), freq
, DPP_PA_PKEX_EXCHANGE_RESP
);
1476 offchannel_send_action(wpa_s
, freq
, src
, wpa_s
->own_addr
,
1478 wpabuf_head(msg
), wpabuf_len(msg
),
1479 wait_time
, wpas_dpp_tx_pkex_status
, 0);
1484 wpas_dpp_rx_pkex_exchange_resp(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1485 const u8
*buf
, size_t len
, unsigned int freq
)
1488 unsigned int wait_time
;
1490 wpa_printf(MSG_DEBUG
, "DPP: PKEX Exchange Response from " MACSTR
,
1493 /* TODO: Support multiple PKEX codes by iterating over all the enabled
1496 if (!wpa_s
->dpp_pkex
|| !wpa_s
->dpp_pkex
->initiator
||
1497 wpa_s
->dpp_pkex
->exchange_done
) {
1498 wpa_printf(MSG_DEBUG
, "DPP: No matching PKEX session");
1502 os_memcpy(wpa_s
->dpp_pkex
->peer_mac
, src
, ETH_ALEN
);
1503 msg
= dpp_pkex_rx_exchange_resp(wpa_s
->dpp_pkex
, buf
, len
);
1505 wpa_printf(MSG_DEBUG
, "DPP: Failed to process the response");
1509 wpa_printf(MSG_DEBUG
, "DPP: Send PKEX Commit-Reveal Request to " MACSTR
,
1512 wait_time
= wpa_s
->max_remain_on_chan
;
1513 if (wait_time
> 2000)
1515 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1516 MAC2STR(src
), freq
, DPP_PA_PKEX_COMMIT_REVEAL_REQ
);
1517 offchannel_send_action(wpa_s
, freq
, src
, wpa_s
->own_addr
,
1519 wpabuf_head(msg
), wpabuf_len(msg
),
1520 wait_time
, wpas_dpp_tx_pkex_status
, 0);
1526 wpas_dpp_rx_pkex_commit_reveal_req(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1527 const u8
*hdr
, const u8
*buf
, size_t len
,
1531 unsigned int wait_time
;
1532 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
1533 struct dpp_bootstrap_info
*bi
;
1535 wpa_printf(MSG_DEBUG
, "DPP: PKEX Commit-Reveal Request from " MACSTR
,
1538 if (!pkex
|| pkex
->initiator
|| !pkex
->exchange_done
) {
1539 wpa_printf(MSG_DEBUG
, "DPP: No matching PKEX session");
1543 msg
= dpp_pkex_rx_commit_reveal_req(pkex
, hdr
, buf
, len
);
1545 wpa_printf(MSG_DEBUG
, "DPP: Failed to process the request");
1549 wpa_printf(MSG_DEBUG
, "DPP: Send PKEX Commit-Reveal Response to "
1550 MACSTR
, MAC2STR(src
));
1552 wait_time
= wpa_s
->max_remain_on_chan
;
1553 if (wait_time
> 2000)
1555 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1556 MAC2STR(src
), freq
, DPP_PA_PKEX_COMMIT_REVEAL_RESP
);
1557 offchannel_send_action(wpa_s
, freq
, src
, wpa_s
->own_addr
,
1559 wpabuf_head(msg
), wpabuf_len(msg
),
1560 wait_time
, wpas_dpp_tx_pkex_status
, 0);
1563 bi
= os_zalloc(sizeof(*bi
));
1566 bi
->id
= wpas_dpp_next_id(wpa_s
);
1567 bi
->type
= DPP_BOOTSTRAP_PKEX
;
1568 os_memcpy(bi
->mac_addr
, src
, ETH_ALEN
);
1571 bi
->curve
= pkex
->own_bi
->curve
;
1572 bi
->pubkey
= pkex
->peer_bootstrap_key
;
1573 pkex
->peer_bootstrap_key
= NULL
;
1574 dpp_pkex_free(pkex
);
1575 wpa_s
->dpp_pkex
= NULL
;
1576 if (dpp_bootstrap_key_hash(bi
) < 0) {
1577 dpp_bootstrap_info_free(bi
);
1580 dl_list_add(&wpa_s
->dpp_bootstrap
, &bi
->list
);
1585 wpas_dpp_rx_pkex_commit_reveal_resp(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1586 const u8
*hdr
, const u8
*buf
, size_t len
,
1590 struct dpp_bootstrap_info
*bi
, *own_bi
;
1591 struct dpp_pkex
*pkex
= wpa_s
->dpp_pkex
;
1594 wpa_printf(MSG_DEBUG
, "DPP: PKEX Commit-Reveal Response from " MACSTR
,
1597 if (!pkex
|| !pkex
->initiator
|| !pkex
->exchange_done
) {
1598 wpa_printf(MSG_DEBUG
, "DPP: No matching PKEX session");
1602 res
= dpp_pkex_rx_commit_reveal_resp(pkex
, hdr
, buf
, len
);
1604 wpa_printf(MSG_DEBUG
, "DPP: Failed to process the response");
1608 own_bi
= pkex
->own_bi
;
1610 bi
= os_zalloc(sizeof(*bi
));
1613 bi
->id
= wpas_dpp_next_id(wpa_s
);
1614 bi
->type
= DPP_BOOTSTRAP_PKEX
;
1615 os_memcpy(bi
->mac_addr
, src
, ETH_ALEN
);
1618 bi
->curve
= own_bi
->curve
;
1619 bi
->pubkey
= pkex
->peer_bootstrap_key
;
1620 pkex
->peer_bootstrap_key
= NULL
;
1621 dpp_pkex_free(pkex
);
1622 wpa_s
->dpp_pkex
= NULL
;
1623 if (dpp_bootstrap_key_hash(bi
) < 0) {
1624 dpp_bootstrap_info_free(bi
);
1627 dl_list_add(&wpa_s
->dpp_bootstrap
, &bi
->list
);
1629 os_snprintf(cmd
, sizeof(cmd
), " peer=%u %s",
1631 wpa_s
->dpp_pkex_auth_cmd
? wpa_s
->dpp_pkex_auth_cmd
: "");
1632 wpa_printf(MSG_DEBUG
,
1633 "DPP: Start authentication after PKEX with parameters: %s",
1635 if (wpas_dpp_auth_init(wpa_s
, cmd
) < 0) {
1636 wpa_printf(MSG_DEBUG
,
1637 "DPP: Authentication initialization failed");
1643 void wpas_dpp_rx_action(struct wpa_supplicant
*wpa_s
, const u8
*src
,
1644 const u8
*buf
, size_t len
, unsigned int freq
)
1647 enum dpp_public_action_frame_type type
;
1650 if (len
< DPP_HDR_LEN
)
1652 if (WPA_GET_BE24(buf
) != OUI_WFA
|| buf
[3] != DPP_OUI_TYPE
)
1657 crypto_suite
= *buf
++;
1661 wpa_printf(MSG_DEBUG
,
1662 "DPP: Received DPP Public Action frame crypto suite %u type %d from "
1664 crypto_suite
, type
, MAC2STR(src
), freq
);
1665 if (crypto_suite
!= 1) {
1666 wpa_printf(MSG_DEBUG
, "DPP: Unsupported crypto suite %u",
1668 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_RX
"src=" MACSTR
1669 " freq=%u type=%d ignore=unsupported-crypto-suite",
1670 MAC2STR(src
), freq
, type
);
1673 wpa_hexdump(MSG_MSGDUMP
, "DPP: Received message attributes", buf
, len
);
1674 if (dpp_check_attrs(buf
, len
) < 0) {
1675 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_RX
"src=" MACSTR
1676 " freq=%u type=%d ignore=invalid-attributes",
1677 MAC2STR(src
), freq
, type
);
1680 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_RX
"src=" MACSTR
" freq=%u type=%d",
1681 MAC2STR(src
), freq
, type
);
1684 case DPP_PA_AUTHENTICATION_REQ
:
1685 wpas_dpp_rx_auth_req(wpa_s
, src
, hdr
, buf
, len
, freq
);
1687 case DPP_PA_AUTHENTICATION_RESP
:
1688 wpas_dpp_rx_auth_resp(wpa_s
, src
, hdr
, buf
, len
, freq
);
1690 case DPP_PA_AUTHENTICATION_CONF
:
1691 wpas_dpp_rx_auth_conf(wpa_s
, src
, hdr
, buf
, len
);
1693 case DPP_PA_PEER_DISCOVERY_RESP
:
1694 wpas_dpp_rx_peer_disc_resp(wpa_s
, src
, buf
, len
);
1696 case DPP_PA_PKEX_EXCHANGE_REQ
:
1697 wpas_dpp_rx_pkex_exchange_req(wpa_s
, src
, buf
, len
, freq
);
1699 case DPP_PA_PKEX_EXCHANGE_RESP
:
1700 wpas_dpp_rx_pkex_exchange_resp(wpa_s
, src
, buf
, len
, freq
);
1702 case DPP_PA_PKEX_COMMIT_REVEAL_REQ
:
1703 wpas_dpp_rx_pkex_commit_reveal_req(wpa_s
, src
, hdr
, buf
, len
,
1706 case DPP_PA_PKEX_COMMIT_REVEAL_RESP
:
1707 wpas_dpp_rx_pkex_commit_reveal_resp(wpa_s
, src
, hdr
, buf
, len
,
1711 wpa_printf(MSG_DEBUG
,
1712 "DPP: Ignored unsupported frame subtype %d", type
);
1718 static struct wpabuf
*
1719 wpas_dpp_gas_req_handler(void *ctx
, const u8
*sa
, const u8
*query
,
1722 struct wpa_supplicant
*wpa_s
= ctx
;
1723 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1724 struct wpabuf
*resp
;
1726 wpa_printf(MSG_DEBUG
, "DPP: GAS request from " MACSTR
,
1728 if (!auth
|| !auth
->auth_success
||
1729 os_memcmp(sa
, auth
->peer_mac_addr
, ETH_ALEN
) != 0) {
1730 wpa_printf(MSG_DEBUG
, "DPP: No matching exchange in progress");
1733 wpa_hexdump(MSG_DEBUG
,
1734 "DPP: Received Configuration Request (GAS Query Request)",
1736 resp
= dpp_conf_req_rx(auth
, query
, query_len
);
1738 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
1744 wpas_dpp_gas_status_handler(void *ctx
, struct wpabuf
*resp
, int ok
)
1746 struct wpa_supplicant
*wpa_s
= ctx
;
1747 struct dpp_authentication
*auth
= wpa_s
->dpp_auth
;
1754 wpa_printf(MSG_DEBUG
, "DPP: Configuration exchange completed (ok=%d)",
1756 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
1757 offchannel_send_action_done(wpa_s
);
1758 wpas_dpp_listen_stop(wpa_s
);
1760 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_SENT
);
1762 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_CONF_FAILED
);
1763 dpp_auth_deinit(wpa_s
->dpp_auth
);
1764 wpa_s
->dpp_auth
= NULL
;
1769 static unsigned int wpas_dpp_next_configurator_id(struct wpa_supplicant
*wpa_s
)
1771 struct dpp_configurator
*conf
;
1772 unsigned int max_id
= 0;
1774 dl_list_for_each(conf
, &wpa_s
->dpp_configurator
,
1775 struct dpp_configurator
, list
) {
1776 if (conf
->id
> max_id
)
1783 int wpas_dpp_configurator_add(struct wpa_supplicant
*wpa_s
, const char *cmd
)
1788 size_t privkey_len
= 0;
1790 struct dpp_configurator
*conf
= NULL
;
1792 curve
= get_param(cmd
, " curve=");
1793 key
= get_param(cmd
, " key=");
1796 privkey_len
= os_strlen(key
) / 2;
1797 privkey
= os_malloc(privkey_len
);
1799 hexstr2bin(key
, privkey
, privkey_len
) < 0)
1803 conf
= dpp_keygen_configurator(curve
, privkey
, privkey_len
);
1807 conf
->id
= wpas_dpp_next_configurator_id(wpa_s
);
1808 dl_list_add(&wpa_s
->dpp_configurator
, &conf
->list
);
1813 str_clear_free(key
);
1814 bin_clear_free(privkey
, privkey_len
);
1815 dpp_configurator_free(conf
);
1820 static int dpp_configurator_del(struct wpa_supplicant
*wpa_s
, unsigned int id
)
1822 struct dpp_configurator
*conf
, *tmp
;
1825 dl_list_for_each_safe(conf
, tmp
, &wpa_s
->dpp_configurator
,
1826 struct dpp_configurator
, list
) {
1827 if (id
&& conf
->id
!= id
)
1830 dl_list_del(&conf
->list
);
1831 dpp_configurator_free(conf
);
1835 return 0; /* flush succeeds regardless of entries found */
1836 return found
? 0 : -1;
1840 int wpas_dpp_configurator_remove(struct wpa_supplicant
*wpa_s
, const char *id
)
1842 unsigned int id_val
;
1844 if (os_strcmp(id
, "*") == 0) {
1852 return dpp_configurator_del(wpa_s
, id_val
);
1856 int wpas_dpp_configurator_sign(struct wpa_supplicant
*wpa_s
, const char *cmd
)
1858 struct dpp_authentication
*auth
;
1862 auth
= os_zalloc(sizeof(*auth
));
1866 curve
= get_param(cmd
, " curve=");
1867 wpas_dpp_set_configurator(wpa_s
, auth
, cmd
);
1869 if (dpp_configurator_own_config(auth
, curve
) == 0) {
1870 wpas_dpp_handle_config_obj(wpa_s
, auth
);
1874 dpp_auth_deinit(auth
);
1882 wpas_dpp_tx_introduction_status(struct wpa_supplicant
*wpa_s
,
1883 unsigned int freq
, const u8
*dst
,
1884 const u8
*src
, const u8
*bssid
,
1885 const u8
*data
, size_t data_len
,
1886 enum offchannel_send_action_result result
)
1888 const char *res_txt
;
1890 res_txt
= result
== OFFCHANNEL_SEND_ACTION_SUCCESS
? "SUCCESS" :
1891 (result
== OFFCHANNEL_SEND_ACTION_NO_ACK
? "no-ACK" :
1893 wpa_printf(MSG_DEBUG
, "DPP: TX status: freq=%u dst=" MACSTR
1894 " result=%s (DPP Peer Discovery Request)",
1895 freq
, MAC2STR(dst
), res_txt
);
1896 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX_STATUS
"dst=" MACSTR
1897 " freq=%u result=%s", MAC2STR(dst
), freq
, res_txt
);
1898 /* TODO: Time out wait for response more quickly in error cases? */
1902 int wpas_dpp_check_connect(struct wpa_supplicant
*wpa_s
, struct wpa_ssid
*ssid
,
1903 struct wpa_bss
*bss
)
1907 unsigned int wait_time
;
1909 if (!(ssid
->key_mgmt
& WPA_KEY_MGMT_DPP
) || !bss
)
1910 return 0; /* Not using DPP AKM - continue */
1911 if (wpa_sm_pmksa_exists(wpa_s
->wpa
, bss
->bssid
, ssid
))
1912 return 0; /* PMKSA exists for DPP AKM - continue */
1914 if (!ssid
->dpp_connector
|| !ssid
->dpp_netaccesskey
||
1916 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_MISSING_CONNECTOR
1918 !ssid
->dpp_connector
? "Connector" :
1919 (!ssid
->dpp_netaccesskey
? "netAccessKey" :
1926 if (ssid
->dpp_netaccesskey_expiry
&&
1927 ssid
->dpp_netaccesskey_expiry
< now
.sec
) {
1928 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_MISSING_CONNECTOR
1929 "netAccessKey expired");
1933 wpa_printf(MSG_DEBUG
,
1934 "DPP: Starting network introduction protocol to derive PMKSA for "
1935 MACSTR
, MAC2STR(bss
->bssid
));
1937 msg
= dpp_alloc_msg(DPP_PA_PEER_DISCOVERY_REQ
,
1938 5 + 4 + os_strlen(ssid
->dpp_connector
));
1942 /* Transaction ID */
1943 wpabuf_put_le16(msg
, DPP_ATTR_TRANSACTION_ID
);
1944 wpabuf_put_le16(msg
, 1);
1945 wpabuf_put_u8(msg
, TRANSACTION_ID
);
1948 wpabuf_put_le16(msg
, DPP_ATTR_CONNECTOR
);
1949 wpabuf_put_le16(msg
, os_strlen(ssid
->dpp_connector
));
1950 wpabuf_put_str(msg
, ssid
->dpp_connector
);
1952 /* TODO: Timeout on AP response */
1953 wait_time
= wpa_s
->max_remain_on_chan
;
1954 if (wait_time
> 2000)
1956 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
" freq=%u type=%d",
1957 MAC2STR(bss
->bssid
), bss
->freq
, DPP_PA_PEER_DISCOVERY_REQ
);
1958 offchannel_send_action(wpa_s
, bss
->freq
, bss
->bssid
, wpa_s
->own_addr
,
1960 wpabuf_head(msg
), wpabuf_len(msg
),
1961 wait_time
, wpas_dpp_tx_introduction_status
, 0);
1964 /* Request this connection attempt to terminate - new one will be
1965 * started when network introduction protocol completes */
1966 os_memcpy(wpa_s
->dpp_intro_bssid
, bss
->bssid
, ETH_ALEN
);
1967 wpa_s
->dpp_intro_network
= ssid
;
1972 int wpas_dpp_pkex_add(struct wpa_supplicant
*wpa_s
, const char *cmd
)
1974 struct dpp_bootstrap_info
*own_bi
;
1975 const char *pos
, *end
;
1976 unsigned int wait_time
;
1978 pos
= os_strstr(cmd
, " own=");
1982 own_bi
= dpp_bootstrap_get_id(wpa_s
, atoi(pos
));
1984 wpa_printf(MSG_DEBUG
,
1985 "DPP: Identified bootstrap info not found");
1988 if (own_bi
->type
!= DPP_BOOTSTRAP_PKEX
) {
1989 wpa_printf(MSG_DEBUG
,
1990 "DPP: Identified bootstrap info not for PKEX");
1993 wpa_s
->dpp_pkex_bi
= own_bi
;
1995 os_free(wpa_s
->dpp_pkex_identifier
);
1996 wpa_s
->dpp_pkex_identifier
= NULL
;
1997 pos
= os_strstr(cmd
, " identifier=");
2000 end
= os_strchr(pos
, ' ');
2003 wpa_s
->dpp_pkex_identifier
= os_malloc(end
- pos
+ 1);
2004 if (!wpa_s
->dpp_pkex_identifier
)
2006 os_memcpy(wpa_s
->dpp_pkex_identifier
, pos
, end
- pos
);
2007 wpa_s
->dpp_pkex_identifier
[end
- pos
] = '\0';
2010 pos
= os_strstr(cmd
, " code=");
2013 os_free(wpa_s
->dpp_pkex_code
);
2014 wpa_s
->dpp_pkex_code
= os_strdup(pos
+ 6);
2015 if (!wpa_s
->dpp_pkex_code
)
2018 if (os_strstr(cmd
, " init=1")) {
2021 wpa_printf(MSG_DEBUG
, "DPP: Initiating PKEX");
2022 dpp_pkex_free(wpa_s
->dpp_pkex
);
2023 wpa_s
->dpp_pkex
= dpp_pkex_init(own_bi
, wpa_s
->own_addr
,
2024 wpa_s
->dpp_pkex_identifier
,
2025 wpa_s
->dpp_pkex_code
);
2026 if (!wpa_s
->dpp_pkex
)
2029 msg
= wpa_s
->dpp_pkex
->exchange_req
;
2030 wait_time
= wpa_s
->max_remain_on_chan
;
2031 if (wait_time
> 2000)
2033 /* TODO: Which channel to use? */
2034 wpa_msg(wpa_s
, MSG_INFO
, DPP_EVENT_TX
"dst=" MACSTR
2036 MAC2STR(broadcast
), 2437, DPP_PA_PKEX_EXCHANGE_REQ
);
2037 offchannel_send_action(wpa_s
, 2437, broadcast
, wpa_s
->own_addr
,
2039 wpabuf_head(msg
), wpabuf_len(msg
),
2040 wait_time
, wpas_dpp_tx_pkex_status
, 0);
2043 /* TODO: Support multiple PKEX info entries */
2045 os_free(wpa_s
->dpp_pkex_auth_cmd
);
2046 wpa_s
->dpp_pkex_auth_cmd
= os_strdup(cmd
);
2052 int wpas_dpp_pkex_remove(struct wpa_supplicant
*wpa_s
, const char *id
)
2054 unsigned int id_val
;
2056 if (os_strcmp(id
, "*") == 0) {
2064 if ((id_val
!= 0 && id_val
!= 1) || !wpa_s
->dpp_pkex_code
)
2067 /* TODO: Support multiple PKEX entries */
2068 os_free(wpa_s
->dpp_pkex_code
);
2069 wpa_s
->dpp_pkex_code
= NULL
;
2070 os_free(wpa_s
->dpp_pkex_identifier
);
2071 wpa_s
->dpp_pkex_identifier
= NULL
;
2072 os_free(wpa_s
->dpp_pkex_auth_cmd
);
2073 wpa_s
->dpp_pkex_auth_cmd
= NULL
;
2074 wpa_s
->dpp_pkex_bi
= NULL
;
2075 /* TODO: Remove dpp_pkex only if it is for the identified PKEX code */
2076 dpp_pkex_free(wpa_s
->dpp_pkex
);
2077 wpa_s
->dpp_pkex
= NULL
;
2082 int wpas_dpp_init(struct wpa_supplicant
*wpa_s
)
2086 adv_proto_id
[0] = WLAN_EID_VENDOR_SPECIFIC
;
2087 adv_proto_id
[1] = 5;
2088 WPA_PUT_BE24(&adv_proto_id
[2], OUI_WFA
);
2089 adv_proto_id
[5] = DPP_OUI_TYPE
;
2090 adv_proto_id
[6] = 0x01;
2092 if (gas_server_register(wpa_s
->gas_server
, adv_proto_id
,
2093 sizeof(adv_proto_id
), wpas_dpp_gas_req_handler
,
2094 wpas_dpp_gas_status_handler
, wpa_s
) < 0)
2096 dl_list_init(&wpa_s
->dpp_bootstrap
);
2097 dl_list_init(&wpa_s
->dpp_configurator
);
2098 wpa_s
->dpp_init_done
= 1;
2103 void wpas_dpp_deinit(struct wpa_supplicant
*wpa_s
)
2105 #ifdef CONFIG_TESTING_OPTIONS
2106 os_free(wpa_s
->dpp_config_obj_override
);
2107 wpa_s
->dpp_config_obj_override
= NULL
;
2108 os_free(wpa_s
->dpp_discovery_override
);
2109 wpa_s
->dpp_discovery_override
= NULL
;
2110 os_free(wpa_s
->dpp_groups_override
);
2111 wpa_s
->dpp_groups_override
= NULL
;
2112 wpa_s
->dpp_ignore_netaccesskey_mismatch
= 0;
2113 #endif /* CONFIG_TESTING_OPTIONS */
2114 if (!wpa_s
->dpp_init_done
)
2116 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout
, wpa_s
, NULL
);
2117 offchannel_send_action_done(wpa_s
);
2118 wpas_dpp_listen_stop(wpa_s
);
2119 dpp_bootstrap_del(wpa_s
, 0);
2120 dpp_configurator_del(wpa_s
, 0);
2121 dpp_auth_deinit(wpa_s
->dpp_auth
);
2122 wpa_s
->dpp_auth
= NULL
;
2123 wpas_dpp_pkex_remove(wpa_s
, "*");
2124 wpa_s
->dpp_pkex
= NULL
;
2125 os_memset(wpa_s
->dpp_intro_bssid
, 0, ETH_ALEN
);
2126 os_free(wpa_s
->dpp_configurator_params
);
2127 wpa_s
->dpp_configurator_params
= NULL
;