]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/wpa/src/ap/dpp_hostapd.c
Update hostapd/wpa_supplicant to 2.8 to fix multiple vulnerabilities.
[FreeBSD/FreeBSD.git] / contrib / wpa / src / ap / dpp_hostapd.c
1 /*
2  * hostapd / DPP integration
3  * Copyright (c) 2017, Qualcomm Atheros, Inc.
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8
9 #include "utils/includes.h"
10
11 #include "utils/common.h"
12 #include "utils/eloop.h"
13 #include "common/dpp.h"
14 #include "common/gas.h"
15 #include "common/wpa_ctrl.h"
16 #include "hostapd.h"
17 #include "ap_drv_ops.h"
18 #include "gas_query_ap.h"
19 #include "wpa_auth.h"
20 #include "dpp_hostapd.h"
21
22
23 static void hostapd_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx);
24 static void hostapd_dpp_auth_success(struct hostapd_data *hapd, int initiator);
25 static void hostapd_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx);
26 static int hostapd_dpp_auth_init_next(struct hostapd_data *hapd);
27
28 static const u8 broadcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
29
30
31 /**
32  * hostapd_dpp_qr_code - Parse and add DPP bootstrapping info from a QR Code
33  * @hapd: Pointer to hostapd_data
34  * @cmd: DPP URI read from a QR Code
35  * Returns: Identifier of the stored info or -1 on failure
36  */
37 int hostapd_dpp_qr_code(struct hostapd_data *hapd, const char *cmd)
38 {
39         struct dpp_bootstrap_info *bi;
40         struct dpp_authentication *auth = hapd->dpp_auth;
41
42         bi = dpp_add_qr_code(hapd->iface->interfaces->dpp, cmd);
43         if (!bi)
44                 return -1;
45
46         if (auth && auth->response_pending &&
47             dpp_notify_new_qr_code(auth, bi) == 1) {
48                 wpa_printf(MSG_DEBUG,
49                            "DPP: Sending out pending authentication response");
50                 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
51                         " freq=%u type=%d",
52                         MAC2STR(auth->peer_mac_addr), auth->curr_freq,
53                         DPP_PA_AUTHENTICATION_RESP);
54                 hostapd_drv_send_action(hapd, auth->curr_freq, 0,
55                                         auth->peer_mac_addr,
56                                         wpabuf_head(hapd->dpp_auth->resp_msg),
57                                         wpabuf_len(hapd->dpp_auth->resp_msg));
58         }
59
60         return bi->id;
61 }
62
63
64 static void hostapd_dpp_auth_resp_retry_timeout(void *eloop_ctx,
65                                                 void *timeout_ctx)
66 {
67         struct hostapd_data *hapd = eloop_ctx;
68         struct dpp_authentication *auth = hapd->dpp_auth;
69
70         if (!auth || !auth->resp_msg)
71                 return;
72
73         wpa_printf(MSG_DEBUG,
74                    "DPP: Retry Authentication Response after timeout");
75         wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
76                 " freq=%u type=%d",
77                 MAC2STR(auth->peer_mac_addr), auth->curr_freq,
78                 DPP_PA_AUTHENTICATION_RESP);
79         hostapd_drv_send_action(hapd, auth->curr_freq, 500, auth->peer_mac_addr,
80                                 wpabuf_head(auth->resp_msg),
81                                 wpabuf_len(auth->resp_msg));
82 }
83
84
85 static void hostapd_dpp_auth_resp_retry(struct hostapd_data *hapd)
86 {
87         struct dpp_authentication *auth = hapd->dpp_auth;
88         unsigned int wait_time, max_tries;
89
90         if (!auth || !auth->resp_msg)
91                 return;
92
93         if (hapd->dpp_resp_max_tries)
94                 max_tries = hapd->dpp_resp_max_tries;
95         else
96                 max_tries = 5;
97         auth->auth_resp_tries++;
98         if (auth->auth_resp_tries >= max_tries) {
99                 wpa_printf(MSG_INFO,
100                            "DPP: No confirm received from initiator - stopping exchange");
101                 hostapd_drv_send_action_cancel_wait(hapd);
102                 dpp_auth_deinit(hapd->dpp_auth);
103                 hapd->dpp_auth = NULL;
104                 return;
105         }
106
107         if (hapd->dpp_resp_retry_time)
108                 wait_time = hapd->dpp_resp_retry_time;
109         else
110                 wait_time = 1000;
111         wpa_printf(MSG_DEBUG,
112                    "DPP: Schedule retransmission of Authentication Response frame in %u ms",
113                 wait_time);
114         eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
115         eloop_register_timeout(wait_time / 1000,
116                                (wait_time % 1000) * 1000,
117                                hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
118 }
119
120
121 void hostapd_dpp_tx_status(struct hostapd_data *hapd, const u8 *dst,
122                            const u8 *data, size_t data_len, int ok)
123 {
124         struct dpp_authentication *auth = hapd->dpp_auth;
125
126         wpa_printf(MSG_DEBUG, "DPP: TX status: dst=" MACSTR " ok=%d",
127                    MAC2STR(dst), ok);
128         wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX_STATUS "dst=" MACSTR
129                 " result=%s", MAC2STR(dst), ok ? "SUCCESS" : "FAILED");
130
131         if (!hapd->dpp_auth) {
132                 wpa_printf(MSG_DEBUG,
133                            "DPP: Ignore TX status since there is no ongoing authentication exchange");
134                 return;
135         }
136
137 #ifdef CONFIG_DPP2
138         if (auth->connect_on_tx_status) {
139                 wpa_printf(MSG_DEBUG,
140                            "DPP: Complete exchange on configuration result");
141                 dpp_auth_deinit(hapd->dpp_auth);
142                 hapd->dpp_auth = NULL;
143                 return;
144         }
145 #endif /* CONFIG_DPP2 */
146
147         if (hapd->dpp_auth->remove_on_tx_status) {
148                 wpa_printf(MSG_DEBUG,
149                            "DPP: Terminate authentication exchange due to an earlier error");
150                 eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
151                 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
152                                      hapd, NULL);
153                 eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd,
154                                      NULL);
155                 hostapd_drv_send_action_cancel_wait(hapd);
156                 dpp_auth_deinit(hapd->dpp_auth);
157                 hapd->dpp_auth = NULL;
158                 return;
159         }
160
161         if (hapd->dpp_auth_ok_on_ack)
162                 hostapd_dpp_auth_success(hapd, 1);
163
164         if (!is_broadcast_ether_addr(dst) && !ok) {
165                 wpa_printf(MSG_DEBUG,
166                            "DPP: Unicast DPP Action frame was not ACKed");
167                 if (auth->waiting_auth_resp) {
168                         /* In case of DPP Authentication Request frame, move to
169                          * the next channel immediately. */
170                         hostapd_drv_send_action_cancel_wait(hapd);
171                         hostapd_dpp_auth_init_next(hapd);
172                         return;
173                 }
174                 if (auth->waiting_auth_conf) {
175                         hostapd_dpp_auth_resp_retry(hapd);
176                         return;
177                 }
178         }
179
180         if (!is_broadcast_ether_addr(dst) && auth->waiting_auth_resp && ok) {
181                 /* Allow timeout handling to stop iteration if no response is
182                  * received from a peer that has ACKed a request. */
183                 auth->auth_req_ack = 1;
184         }
185
186         if (!hapd->dpp_auth_ok_on_ack && hapd->dpp_auth->neg_freq > 0 &&
187             hapd->dpp_auth->curr_freq != hapd->dpp_auth->neg_freq) {
188                 wpa_printf(MSG_DEBUG,
189                            "DPP: Move from curr_freq %u MHz to neg_freq %u MHz for response",
190                            hapd->dpp_auth->curr_freq,
191                            hapd->dpp_auth->neg_freq);
192                 hostapd_drv_send_action_cancel_wait(hapd);
193
194                 if (hapd->dpp_auth->neg_freq !=
195                     (unsigned int) hapd->iface->freq && hapd->iface->freq > 0) {
196                         /* TODO: Listen operation on non-operating channel */
197                         wpa_printf(MSG_INFO,
198                                    "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)",
199                                    hapd->dpp_auth->neg_freq, hapd->iface->freq);
200                 }
201         }
202
203         if (hapd->dpp_auth_ok_on_ack)
204                 hapd->dpp_auth_ok_on_ack = 0;
205 }
206
207
208 static void hostapd_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx)
209 {
210         struct hostapd_data *hapd = eloop_ctx;
211         struct dpp_authentication *auth = hapd->dpp_auth;
212         unsigned int freq;
213         struct os_reltime now, diff;
214         unsigned int wait_time, diff_ms;
215
216         if (!auth || !auth->waiting_auth_resp)
217                 return;
218
219         wait_time = hapd->dpp_resp_wait_time ?
220                 hapd->dpp_resp_wait_time : 2000;
221         os_get_reltime(&now);
222         os_reltime_sub(&now, &hapd->dpp_last_init, &diff);
223         diff_ms = diff.sec * 1000 + diff.usec / 1000;
224         wpa_printf(MSG_DEBUG,
225                    "DPP: Reply wait timeout - wait_time=%u diff_ms=%u",
226                    wait_time, diff_ms);
227
228         if (auth->auth_req_ack && diff_ms >= wait_time) {
229                 /* Peer ACK'ed Authentication Request frame, but did not reply
230                  * with Authentication Response frame within two seconds. */
231                 wpa_printf(MSG_INFO,
232                            "DPP: No response received from responder - stopping initiation attempt");
233                 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_AUTH_INIT_FAILED);
234                 hostapd_drv_send_action_cancel_wait(hapd);
235                 hostapd_dpp_listen_stop(hapd);
236                 dpp_auth_deinit(auth);
237                 hapd->dpp_auth = NULL;
238                 return;
239         }
240
241         if (diff_ms >= wait_time) {
242                 /* Authentication Request frame was not ACK'ed and no reply
243                  * was receiving within two seconds. */
244                 wpa_printf(MSG_DEBUG,
245                            "DPP: Continue Initiator channel iteration");
246                 hostapd_drv_send_action_cancel_wait(hapd);
247                 hostapd_dpp_listen_stop(hapd);
248                 hostapd_dpp_auth_init_next(hapd);
249                 return;
250         }
251
252         /* Driver did not support 2000 ms long wait_time with TX command, so
253          * schedule listen operation to continue waiting for the response.
254          *
255          * DPP listen operations continue until stopped, so simply schedule a
256          * new call to this function at the point when the two second reply
257          * wait has expired. */
258         wait_time -= diff_ms;
259
260         freq = auth->curr_freq;
261         if (auth->neg_freq > 0)
262                 freq = auth->neg_freq;
263         wpa_printf(MSG_DEBUG,
264                    "DPP: Continue reply wait on channel %u MHz for %u ms",
265                    freq, wait_time);
266         hapd->dpp_in_response_listen = 1;
267
268         if (freq != (unsigned int) hapd->iface->freq && hapd->iface->freq > 0) {
269                 /* TODO: Listen operation on non-operating channel */
270                 wpa_printf(MSG_INFO,
271                            "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)",
272                            freq, hapd->iface->freq);
273         }
274
275         eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
276                                hostapd_dpp_reply_wait_timeout, hapd, NULL);
277 }
278
279
280 static void hostapd_dpp_set_testing_options(struct hostapd_data *hapd,
281                                             struct dpp_authentication *auth)
282 {
283 #ifdef CONFIG_TESTING_OPTIONS
284         if (hapd->dpp_config_obj_override)
285                 auth->config_obj_override =
286                         os_strdup(hapd->dpp_config_obj_override);
287         if (hapd->dpp_discovery_override)
288                 auth->discovery_override =
289                         os_strdup(hapd->dpp_discovery_override);
290         if (hapd->dpp_groups_override)
291                 auth->groups_override = os_strdup(hapd->dpp_groups_override);
292         auth->ignore_netaccesskey_mismatch =
293                 hapd->dpp_ignore_netaccesskey_mismatch;
294 #endif /* CONFIG_TESTING_OPTIONS */
295 }
296
297
298 static void hostapd_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx)
299 {
300         struct hostapd_data *hapd = eloop_ctx;
301
302         if (!hapd->dpp_auth)
303                 return;
304         wpa_printf(MSG_DEBUG, "DPP: Retry initiation after timeout");
305         hostapd_dpp_auth_init_next(hapd);
306 }
307
308
309 static int hostapd_dpp_auth_init_next(struct hostapd_data *hapd)
310 {
311         struct dpp_authentication *auth = hapd->dpp_auth;
312         const u8 *dst;
313         unsigned int wait_time, max_wait_time, freq, max_tries, used;
314         struct os_reltime now, diff;
315
316         if (!auth)
317                 return -1;
318
319         if (auth->freq_idx == 0)
320                 os_get_reltime(&hapd->dpp_init_iter_start);
321
322         if (auth->freq_idx >= auth->num_freq) {
323                 auth->num_freq_iters++;
324                 if (hapd->dpp_init_max_tries)
325                         max_tries = hapd->dpp_init_max_tries;
326                 else
327                         max_tries = 5;
328                 if (auth->num_freq_iters >= max_tries || auth->auth_req_ack) {
329                         wpa_printf(MSG_INFO,
330                                    "DPP: No response received from responder - stopping initiation attempt");
331                         wpa_msg(hapd->msg_ctx, MSG_INFO,
332                                 DPP_EVENT_AUTH_INIT_FAILED);
333                         eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
334                                              hapd, NULL);
335                         hostapd_drv_send_action_cancel_wait(hapd);
336                         dpp_auth_deinit(hapd->dpp_auth);
337                         hapd->dpp_auth = NULL;
338                         return -1;
339                 }
340                 auth->freq_idx = 0;
341                 eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
342                 if (hapd->dpp_init_retry_time)
343                         wait_time = hapd->dpp_init_retry_time;
344                 else
345                         wait_time = 10000;
346                 os_get_reltime(&now);
347                 os_reltime_sub(&now, &hapd->dpp_init_iter_start, &diff);
348                 used = diff.sec * 1000 + diff.usec / 1000;
349                 if (used > wait_time)
350                         wait_time = 0;
351                 else
352                         wait_time -= used;
353                 wpa_printf(MSG_DEBUG, "DPP: Next init attempt in %u ms",
354                            wait_time);
355                 eloop_register_timeout(wait_time / 1000,
356                                        (wait_time % 1000) * 1000,
357                                        hostapd_dpp_init_timeout, hapd,
358                                        NULL);
359                 return 0;
360         }
361         freq = auth->freq[auth->freq_idx++];
362         auth->curr_freq = freq;
363
364         if (is_zero_ether_addr(auth->peer_bi->mac_addr))
365                 dst = broadcast;
366         else
367                 dst = auth->peer_bi->mac_addr;
368         hapd->dpp_auth_ok_on_ack = 0;
369         eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
370         wait_time = 2000; /* TODO: hapd->max_remain_on_chan; */
371         max_wait_time = hapd->dpp_resp_wait_time ?
372                 hapd->dpp_resp_wait_time : 2000;
373         if (wait_time > max_wait_time)
374                 wait_time = max_wait_time;
375         wait_time += 10; /* give the driver some extra time to complete */
376         eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
377                                hostapd_dpp_reply_wait_timeout, hapd, NULL);
378         wait_time -= 10;
379         if (auth->neg_freq > 0 && freq != auth->neg_freq) {
380                 wpa_printf(MSG_DEBUG,
381                            "DPP: Initiate on %u MHz and move to neg_freq %u MHz for response",
382                            freq, auth->neg_freq);
383         }
384         wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
385                 " freq=%u type=%d",
386                 MAC2STR(dst), freq, DPP_PA_AUTHENTICATION_REQ);
387         auth->auth_req_ack = 0;
388         os_get_reltime(&hapd->dpp_last_init);
389         return hostapd_drv_send_action(hapd, freq, wait_time,
390                                        dst,
391                                        wpabuf_head(hapd->dpp_auth->req_msg),
392                                        wpabuf_len(hapd->dpp_auth->req_msg));
393 }
394
395
396 int hostapd_dpp_auth_init(struct hostapd_data *hapd, const char *cmd)
397 {
398         const char *pos;
399         struct dpp_bootstrap_info *peer_bi, *own_bi = NULL;
400         u8 allowed_roles = DPP_CAPAB_CONFIGURATOR;
401         unsigned int neg_freq = 0;
402
403         pos = os_strstr(cmd, " peer=");
404         if (!pos)
405                 return -1;
406         pos += 6;
407         peer_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
408         if (!peer_bi) {
409                 wpa_printf(MSG_INFO,
410                            "DPP: Could not find bootstrapping info for the identified peer");
411                 return -1;
412         }
413
414         pos = os_strstr(cmd, " own=");
415         if (pos) {
416                 pos += 5;
417                 own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp,
418                                               atoi(pos));
419                 if (!own_bi) {
420                         wpa_printf(MSG_INFO,
421                                    "DPP: Could not find bootstrapping info for the identified local entry");
422                         return -1;
423                 }
424
425                 if (peer_bi->curve != own_bi->curve) {
426                         wpa_printf(MSG_INFO,
427                                    "DPP: Mismatching curves in bootstrapping info (peer=%s own=%s)",
428                                    peer_bi->curve->name, own_bi->curve->name);
429                         return -1;
430                 }
431         }
432
433         pos = os_strstr(cmd, " role=");
434         if (pos) {
435                 pos += 6;
436                 if (os_strncmp(pos, "configurator", 12) == 0)
437                         allowed_roles = DPP_CAPAB_CONFIGURATOR;
438                 else if (os_strncmp(pos, "enrollee", 8) == 0)
439                         allowed_roles = DPP_CAPAB_ENROLLEE;
440                 else if (os_strncmp(pos, "either", 6) == 0)
441                         allowed_roles = DPP_CAPAB_CONFIGURATOR |
442                                 DPP_CAPAB_ENROLLEE;
443                 else
444                         goto fail;
445         }
446
447         pos = os_strstr(cmd, " neg_freq=");
448         if (pos)
449                 neg_freq = atoi(pos + 10);
450
451         if (hapd->dpp_auth) {
452                 eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
453                 eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
454                                      hapd, NULL);
455                 eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd,
456                                      NULL);
457                 hostapd_drv_send_action_cancel_wait(hapd);
458                 dpp_auth_deinit(hapd->dpp_auth);
459         }
460
461         hapd->dpp_auth = dpp_auth_init(hapd->msg_ctx, peer_bi, own_bi,
462                                        allowed_roles, neg_freq,
463                                        hapd->iface->hw_features,
464                                        hapd->iface->num_hw_features);
465         if (!hapd->dpp_auth)
466                 goto fail;
467         hostapd_dpp_set_testing_options(hapd, hapd->dpp_auth);
468         if (dpp_set_configurator(hapd->iface->interfaces->dpp, hapd->msg_ctx,
469                                  hapd->dpp_auth, cmd) < 0) {
470                 dpp_auth_deinit(hapd->dpp_auth);
471                 hapd->dpp_auth = NULL;
472                 goto fail;
473         }
474
475         hapd->dpp_auth->neg_freq = neg_freq;
476
477         if (!is_zero_ether_addr(peer_bi->mac_addr))
478                 os_memcpy(hapd->dpp_auth->peer_mac_addr, peer_bi->mac_addr,
479                           ETH_ALEN);
480
481         return hostapd_dpp_auth_init_next(hapd);
482 fail:
483         return -1;
484 }
485
486
487 int hostapd_dpp_listen(struct hostapd_data *hapd, const char *cmd)
488 {
489         int freq;
490
491         freq = atoi(cmd);
492         if (freq <= 0)
493                 return -1;
494
495         if (os_strstr(cmd, " role=configurator"))
496                 hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR;
497         else if (os_strstr(cmd, " role=enrollee"))
498                 hapd->dpp_allowed_roles = DPP_CAPAB_ENROLLEE;
499         else
500                 hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR |
501                         DPP_CAPAB_ENROLLEE;
502         hapd->dpp_qr_mutual = os_strstr(cmd, " qr=mutual") != NULL;
503
504         if (freq != hapd->iface->freq && hapd->iface->freq > 0) {
505                 /* TODO: Listen operation on non-operating channel */
506                 wpa_printf(MSG_INFO,
507                            "DPP: Listen operation on non-operating channel (%d MHz) is not yet supported (operating channel: %d MHz)",
508                            freq, hapd->iface->freq);
509                 return -1;
510         }
511
512         return 0;
513 }
514
515
516 void hostapd_dpp_listen_stop(struct hostapd_data *hapd)
517 {
518         /* TODO: Stop listen operation on non-operating channel */
519 }
520
521
522 static void hostapd_dpp_rx_auth_req(struct hostapd_data *hapd, const u8 *src,
523                                     const u8 *hdr, const u8 *buf, size_t len,
524                                     unsigned int freq)
525 {
526         const u8 *r_bootstrap, *i_bootstrap;
527         u16 r_bootstrap_len, i_bootstrap_len;
528         struct dpp_bootstrap_info *own_bi = NULL, *peer_bi = NULL;
529
530         if (!hapd->iface->interfaces->dpp)
531                 return;
532
533         wpa_printf(MSG_DEBUG, "DPP: Authentication Request from " MACSTR,
534                    MAC2STR(src));
535
536         r_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
537                                    &r_bootstrap_len);
538         if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) {
539                 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
540                         "Missing or invalid required Responder Bootstrapping Key Hash attribute");
541                 return;
542         }
543         wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash",
544                     r_bootstrap, r_bootstrap_len);
545
546         i_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_I_BOOTSTRAP_KEY_HASH,
547                                    &i_bootstrap_len);
548         if (!i_bootstrap || i_bootstrap_len != SHA256_MAC_LEN) {
549                 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
550                         "Missing or invalid required Initiator Bootstrapping Key Hash attribute");
551                 return;
552         }
553         wpa_hexdump(MSG_MSGDUMP, "DPP: Initiator Bootstrapping Key Hash",
554                     i_bootstrap, i_bootstrap_len);
555
556         /* Try to find own and peer bootstrapping key matches based on the
557          * received hash values */
558         dpp_bootstrap_find_pair(hapd->iface->interfaces->dpp, i_bootstrap,
559                                 r_bootstrap, &own_bi, &peer_bi);
560         if (!own_bi) {
561                 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
562                         "No matching own bootstrapping key found - ignore message");
563                 return;
564         }
565
566         if (hapd->dpp_auth) {
567                 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
568                         "Already in DPP authentication exchange - ignore new one");
569                 return;
570         }
571
572         hapd->dpp_auth_ok_on_ack = 0;
573         hapd->dpp_auth = dpp_auth_req_rx(hapd->msg_ctx, hapd->dpp_allowed_roles,
574                                          hapd->dpp_qr_mutual,
575                                          peer_bi, own_bi, freq, hdr, buf, len);
576         if (!hapd->dpp_auth) {
577                 wpa_printf(MSG_DEBUG, "DPP: No response generated");
578                 return;
579         }
580         hostapd_dpp_set_testing_options(hapd, hapd->dpp_auth);
581         if (dpp_set_configurator(hapd->iface->interfaces->dpp, hapd->msg_ctx,
582                                  hapd->dpp_auth,
583                                  hapd->dpp_configurator_params) < 0) {
584                 dpp_auth_deinit(hapd->dpp_auth);
585                 hapd->dpp_auth = NULL;
586                 return;
587         }
588         os_memcpy(hapd->dpp_auth->peer_mac_addr, src, ETH_ALEN);
589
590         wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
591                 " freq=%u type=%d",
592                 MAC2STR(src), hapd->dpp_auth->curr_freq,
593                 DPP_PA_AUTHENTICATION_RESP);
594         hostapd_drv_send_action(hapd, hapd->dpp_auth->curr_freq, 0,
595                                 src, wpabuf_head(hapd->dpp_auth->resp_msg),
596                                 wpabuf_len(hapd->dpp_auth->resp_msg));
597 }
598
599
600 static void hostapd_dpp_handle_config_obj(struct hostapd_data *hapd,
601                                           struct dpp_authentication *auth)
602 {
603         wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_RECEIVED);
604         wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_AKM "%s",
605                 dpp_akm_str(auth->akm));
606         if (auth->ssid_len)
607                 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_SSID "%s",
608                         wpa_ssid_txt(auth->ssid, auth->ssid_len));
609         if (auth->connector) {
610                 /* TODO: Save the Connector and consider using a command
611                  * to fetch the value instead of sending an event with
612                  * it. The Connector could end up being larger than what
613                  * most clients are ready to receive as an event
614                  * message. */
615                 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONNECTOR "%s",
616                         auth->connector);
617         } else if (auth->passphrase[0]) {
618                 char hex[64 * 2 + 1];
619
620                 wpa_snprintf_hex(hex, sizeof(hex),
621                                  (const u8 *) auth->passphrase,
622                                  os_strlen(auth->passphrase));
623                 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_PASS "%s",
624                         hex);
625         } else if (auth->psk_set) {
626                 char hex[PMK_LEN * 2 + 1];
627
628                 wpa_snprintf_hex(hex, sizeof(hex), auth->psk, PMK_LEN);
629                 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONFOBJ_PSK "%s",
630                         hex);
631         }
632         if (auth->c_sign_key) {
633                 char *hex;
634                 size_t hexlen;
635
636                 hexlen = 2 * wpabuf_len(auth->c_sign_key) + 1;
637                 hex = os_malloc(hexlen);
638                 if (hex) {
639                         wpa_snprintf_hex(hex, hexlen,
640                                          wpabuf_head(auth->c_sign_key),
641                                          wpabuf_len(auth->c_sign_key));
642                         wpa_msg(hapd->msg_ctx, MSG_INFO,
643                                 DPP_EVENT_C_SIGN_KEY "%s", hex);
644                         os_free(hex);
645                 }
646         }
647         if (auth->net_access_key) {
648                 char *hex;
649                 size_t hexlen;
650
651                 hexlen = 2 * wpabuf_len(auth->net_access_key) + 1;
652                 hex = os_malloc(hexlen);
653                 if (hex) {
654                         wpa_snprintf_hex(hex, hexlen,
655                                          wpabuf_head(auth->net_access_key),
656                                          wpabuf_len(auth->net_access_key));
657                         if (auth->net_access_key_expiry)
658                                 wpa_msg(hapd->msg_ctx, MSG_INFO,
659                                         DPP_EVENT_NET_ACCESS_KEY "%s %lu", hex,
660                                         (unsigned long)
661                                         auth->net_access_key_expiry);
662                         else
663                                 wpa_msg(hapd->msg_ctx, MSG_INFO,
664                                         DPP_EVENT_NET_ACCESS_KEY "%s", hex);
665                         os_free(hex);
666                 }
667         }
668 }
669
670
671 static void hostapd_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token,
672                                     enum gas_query_ap_result result,
673                                     const struct wpabuf *adv_proto,
674                                     const struct wpabuf *resp, u16 status_code)
675 {
676         struct hostapd_data *hapd = ctx;
677         const u8 *pos;
678         struct dpp_authentication *auth = hapd->dpp_auth;
679         enum dpp_status_error status = DPP_STATUS_CONFIG_REJECTED;
680
681         if (!auth || !auth->auth_success) {
682                 wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
683                 return;
684         }
685         if (!resp || status_code != WLAN_STATUS_SUCCESS) {
686                 wpa_printf(MSG_DEBUG, "DPP: GAS query did not succeed");
687                 goto fail;
688         }
689
690         wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response adv_proto",
691                         adv_proto);
692         wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response (GAS response)",
693                         resp);
694
695         if (wpabuf_len(adv_proto) != 10 ||
696             !(pos = wpabuf_head(adv_proto)) ||
697             pos[0] != WLAN_EID_ADV_PROTO ||
698             pos[1] != 8 ||
699             pos[3] != WLAN_EID_VENDOR_SPECIFIC ||
700             pos[4] != 5 ||
701             WPA_GET_BE24(&pos[5]) != OUI_WFA ||
702             pos[8] != 0x1a ||
703             pos[9] != 1) {
704                 wpa_printf(MSG_DEBUG,
705                            "DPP: Not a DPP Advertisement Protocol ID");
706                 goto fail;
707         }
708
709         if (dpp_conf_resp_rx(auth, resp) < 0) {
710                 wpa_printf(MSG_DEBUG, "DPP: Configuration attempt failed");
711                 goto fail;
712         }
713
714         hostapd_dpp_handle_config_obj(hapd, auth);
715         status = DPP_STATUS_OK;
716 #ifdef CONFIG_TESTING_OPTIONS
717         if (dpp_test == DPP_TEST_REJECT_CONFIG) {
718                 wpa_printf(MSG_INFO, "DPP: TESTING - Reject Config Object");
719                 status = DPP_STATUS_CONFIG_REJECTED;
720         }
721 #endif /* CONFIG_TESTING_OPTIONS */
722 fail:
723         if (status != DPP_STATUS_OK)
724                 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
725 #ifdef CONFIG_DPP2
726         if (auth->peer_version >= 2 &&
727             auth->conf_resp_status == DPP_STATUS_OK) {
728                 struct wpabuf *msg;
729
730                 wpa_printf(MSG_DEBUG, "DPP: Send DPP Configuration Result");
731                 msg = dpp_build_conf_result(auth, status);
732                 if (!msg)
733                         goto fail2;
734
735                 wpa_msg(hapd->msg_ctx, MSG_INFO,
736                         DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
737                         MAC2STR(addr), auth->curr_freq,
738                         DPP_PA_CONFIGURATION_RESULT);
739                 hostapd_drv_send_action(hapd, auth->curr_freq, 0,
740                                         addr, wpabuf_head(msg),
741                                         wpabuf_len(msg));
742                 wpabuf_free(msg);
743
744                 /* This exchange will be terminated in the TX status handler */
745                 auth->connect_on_tx_status = 1;
746                 return;
747         }
748 fail2:
749 #endif /* CONFIG_DPP2 */
750         dpp_auth_deinit(hapd->dpp_auth);
751         hapd->dpp_auth = NULL;
752 }
753
754
755 static void hostapd_dpp_start_gas_client(struct hostapd_data *hapd)
756 {
757         struct dpp_authentication *auth = hapd->dpp_auth;
758         struct wpabuf *buf;
759         char json[100];
760         int res;
761         int netrole_ap = 1;
762
763         os_snprintf(json, sizeof(json),
764                     "{\"name\":\"Test\","
765                     "\"wi-fi_tech\":\"infra\","
766                     "\"netRole\":\"%s\"}",
767                     netrole_ap ? "ap" : "sta");
768         wpa_printf(MSG_DEBUG, "DPP: GAS Config Attributes: %s", json);
769
770         buf = dpp_build_conf_req(auth, json);
771         if (!buf) {
772                 wpa_printf(MSG_DEBUG,
773                            "DPP: No configuration request data available");
774                 return;
775         }
776
777         wpa_printf(MSG_DEBUG, "DPP: GAS request to " MACSTR " (freq %u MHz)",
778                    MAC2STR(auth->peer_mac_addr), auth->curr_freq);
779
780         res = gas_query_ap_req(hapd->gas, auth->peer_mac_addr, auth->curr_freq,
781                                buf, hostapd_dpp_gas_resp_cb, hapd);
782         if (res < 0) {
783                 wpa_msg(hapd->msg_ctx, MSG_DEBUG,
784                         "GAS: Failed to send Query Request");
785                 wpabuf_free(buf);
786         } else {
787                 wpa_printf(MSG_DEBUG,
788                            "DPP: GAS query started with dialog token %u", res);
789         }
790 }
791
792
793 static void hostapd_dpp_auth_success(struct hostapd_data *hapd, int initiator)
794 {
795         wpa_printf(MSG_DEBUG, "DPP: Authentication succeeded");
796         wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_AUTH_SUCCESS "init=%d",
797                 initiator);
798 #ifdef CONFIG_TESTING_OPTIONS
799         if (dpp_test == DPP_TEST_STOP_AT_AUTH_CONF) {
800                 wpa_printf(MSG_INFO,
801                            "DPP: TESTING - stop at Authentication Confirm");
802                 if (hapd->dpp_auth->configurator) {
803                         /* Prevent GAS response */
804                         hapd->dpp_auth->auth_success = 0;
805                 }
806                 return;
807         }
808 #endif /* CONFIG_TESTING_OPTIONS */
809
810         if (!hapd->dpp_auth->configurator)
811                 hostapd_dpp_start_gas_client(hapd);
812 }
813
814
815 static void hostapd_dpp_rx_auth_resp(struct hostapd_data *hapd, const u8 *src,
816                                      const u8 *hdr, const u8 *buf, size_t len,
817                                      unsigned int freq)
818 {
819         struct dpp_authentication *auth = hapd->dpp_auth;
820         struct wpabuf *msg;
821
822         wpa_printf(MSG_DEBUG, "DPP: Authentication Response from " MACSTR,
823                    MAC2STR(src));
824
825         if (!auth) {
826                 wpa_printf(MSG_DEBUG,
827                            "DPP: No DPP Authentication in progress - drop");
828                 return;
829         }
830
831         if (!is_zero_ether_addr(auth->peer_mac_addr) &&
832             os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
833                 wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
834                            MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
835                 return;
836         }
837
838         eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
839
840         if (auth->curr_freq != freq && auth->neg_freq == freq) {
841                 wpa_printf(MSG_DEBUG,
842                            "DPP: Responder accepted request for different negotiation channel");
843                 auth->curr_freq = freq;
844         }
845
846         eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
847         msg = dpp_auth_resp_rx(auth, hdr, buf, len);
848         if (!msg) {
849                 if (auth->auth_resp_status == DPP_STATUS_RESPONSE_PENDING) {
850                         wpa_printf(MSG_DEBUG, "DPP: Wait for full response");
851                         return;
852                 }
853                 wpa_printf(MSG_DEBUG, "DPP: No confirm generated");
854                 return;
855         }
856         os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
857
858         wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
859                 " freq=%u type=%d", MAC2STR(src), auth->curr_freq,
860                 DPP_PA_AUTHENTICATION_CONF);
861         hostapd_drv_send_action(hapd, auth->curr_freq, 0, src,
862                                 wpabuf_head(msg), wpabuf_len(msg));
863         wpabuf_free(msg);
864         hapd->dpp_auth_ok_on_ack = 1;
865 }
866
867
868 static void hostapd_dpp_rx_auth_conf(struct hostapd_data *hapd, const u8 *src,
869                                      const u8 *hdr, const u8 *buf, size_t len)
870 {
871         struct dpp_authentication *auth = hapd->dpp_auth;
872
873         wpa_printf(MSG_DEBUG, "DPP: Authentication Confirmation from " MACSTR,
874                    MAC2STR(src));
875
876         if (!auth) {
877                 wpa_printf(MSG_DEBUG,
878                            "DPP: No DPP Authentication in progress - drop");
879                 return;
880         }
881
882         if (os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
883                 wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
884                            MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
885                 return;
886         }
887
888         if (dpp_auth_conf_rx(auth, hdr, buf, len) < 0) {
889                 wpa_printf(MSG_DEBUG, "DPP: Authentication failed");
890                 return;
891         }
892
893         hostapd_dpp_auth_success(hapd, 0);
894 }
895
896
897 #ifdef CONFIG_DPP2
898
899 static void hostapd_dpp_config_result_wait_timeout(void *eloop_ctx,
900                                                    void *timeout_ctx)
901 {
902         struct hostapd_data *hapd = eloop_ctx;
903         struct dpp_authentication *auth = hapd->dpp_auth;
904
905         if (!auth || !auth->waiting_conf_result)
906                 return;
907
908         wpa_printf(MSG_DEBUG,
909                    "DPP: Timeout while waiting for Configuration Result");
910         wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
911         dpp_auth_deinit(auth);
912         hapd->dpp_auth = NULL;
913 }
914
915
916 static void hostapd_dpp_rx_conf_result(struct hostapd_data *hapd, const u8 *src,
917                                        const u8 *hdr, const u8 *buf, size_t len)
918 {
919         struct dpp_authentication *auth = hapd->dpp_auth;
920         enum dpp_status_error status;
921
922         wpa_printf(MSG_DEBUG, "DPP: Configuration Result from " MACSTR,
923                    MAC2STR(src));
924
925         if (!auth || !auth->waiting_conf_result) {
926                 wpa_printf(MSG_DEBUG,
927                            "DPP: No DPP Configuration waiting for result - drop");
928                 return;
929         }
930
931         if (os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
932                 wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
933                            MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
934                 return;
935         }
936
937         status = dpp_conf_result_rx(auth, hdr, buf, len);
938
939         hostapd_drv_send_action_cancel_wait(hapd);
940         hostapd_dpp_listen_stop(hapd);
941         if (status == DPP_STATUS_OK)
942                 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_SENT);
943         else
944                 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
945         dpp_auth_deinit(auth);
946         hapd->dpp_auth = NULL;
947         eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout, hapd,
948                              NULL);
949 }
950
951 #endif /* CONFIG_DPP2 */
952
953
954 static void hostapd_dpp_send_peer_disc_resp(struct hostapd_data *hapd,
955                                             const u8 *src, unsigned int freq,
956                                             u8 trans_id,
957                                             enum dpp_status_error status)
958 {
959         struct wpabuf *msg;
960
961         msg = dpp_alloc_msg(DPP_PA_PEER_DISCOVERY_RESP,
962                             5 + 5 + 4 + os_strlen(hapd->conf->dpp_connector));
963         if (!msg)
964                 return;
965
966 #ifdef CONFIG_TESTING_OPTIONS
967         if (dpp_test == DPP_TEST_NO_TRANSACTION_ID_PEER_DISC_RESP) {
968                 wpa_printf(MSG_INFO, "DPP: TESTING - no Transaction ID");
969                 goto skip_trans_id;
970         }
971         if (dpp_test == DPP_TEST_INVALID_TRANSACTION_ID_PEER_DISC_RESP) {
972                 wpa_printf(MSG_INFO, "DPP: TESTING - invalid Transaction ID");
973                 trans_id ^= 0x01;
974         }
975 #endif /* CONFIG_TESTING_OPTIONS */
976
977         /* Transaction ID */
978         wpabuf_put_le16(msg, DPP_ATTR_TRANSACTION_ID);
979         wpabuf_put_le16(msg, 1);
980         wpabuf_put_u8(msg, trans_id);
981
982 #ifdef CONFIG_TESTING_OPTIONS
983 skip_trans_id:
984         if (dpp_test == DPP_TEST_NO_STATUS_PEER_DISC_RESP) {
985                 wpa_printf(MSG_INFO, "DPP: TESTING - no Status");
986                 goto skip_status;
987         }
988         if (dpp_test == DPP_TEST_INVALID_STATUS_PEER_DISC_RESP) {
989                 wpa_printf(MSG_INFO, "DPP: TESTING - invalid Status");
990                 status = 254;
991         }
992 #endif /* CONFIG_TESTING_OPTIONS */
993
994         /* DPP Status */
995         wpabuf_put_le16(msg, DPP_ATTR_STATUS);
996         wpabuf_put_le16(msg, 1);
997         wpabuf_put_u8(msg, status);
998
999 #ifdef CONFIG_TESTING_OPTIONS
1000 skip_status:
1001         if (dpp_test == DPP_TEST_NO_CONNECTOR_PEER_DISC_RESP) {
1002                 wpa_printf(MSG_INFO, "DPP: TESTING - no Connector");
1003                 goto skip_connector;
1004         }
1005         if (status == DPP_STATUS_OK &&
1006             dpp_test == DPP_TEST_INVALID_CONNECTOR_PEER_DISC_RESP) {
1007                 char *connector;
1008
1009                 wpa_printf(MSG_INFO, "DPP: TESTING - invalid Connector");
1010                 connector = dpp_corrupt_connector_signature(
1011                         hapd->conf->dpp_connector);
1012                 if (!connector) {
1013                         wpabuf_free(msg);
1014                         return;
1015                 }
1016                 wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
1017                 wpabuf_put_le16(msg, os_strlen(connector));
1018                 wpabuf_put_str(msg, connector);
1019                 os_free(connector);
1020                 goto skip_connector;
1021         }
1022 #endif /* CONFIG_TESTING_OPTIONS */
1023
1024         /* DPP Connector */
1025         if (status == DPP_STATUS_OK) {
1026                 wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
1027                 wpabuf_put_le16(msg, os_strlen(hapd->conf->dpp_connector));
1028                 wpabuf_put_str(msg, hapd->conf->dpp_connector);
1029         }
1030
1031 #ifdef CONFIG_TESTING_OPTIONS
1032 skip_connector:
1033 #endif /* CONFIG_TESTING_OPTIONS */
1034
1035         wpa_printf(MSG_DEBUG, "DPP: Send Peer Discovery Response to " MACSTR
1036                    " status=%d", MAC2STR(src), status);
1037         wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1038                 " freq=%u type=%d status=%d", MAC2STR(src), freq,
1039                 DPP_PA_PEER_DISCOVERY_RESP, status);
1040         hostapd_drv_send_action(hapd, freq, 0, src,
1041                                 wpabuf_head(msg), wpabuf_len(msg));
1042         wpabuf_free(msg);
1043 }
1044
1045
1046 static void hostapd_dpp_rx_peer_disc_req(struct hostapd_data *hapd,
1047                                          const u8 *src,
1048                                          const u8 *buf, size_t len,
1049                                          unsigned int freq)
1050 {
1051         const u8 *connector, *trans_id;
1052         u16 connector_len, trans_id_len;
1053         struct os_time now;
1054         struct dpp_introduction intro;
1055         os_time_t expire;
1056         int expiration;
1057         enum dpp_status_error res;
1058
1059         wpa_printf(MSG_DEBUG, "DPP: Peer Discovery Request from " MACSTR,
1060                    MAC2STR(src));
1061         if (!hapd->wpa_auth ||
1062             !(hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) ||
1063             !(hapd->conf->wpa & WPA_PROTO_RSN)) {
1064                 wpa_printf(MSG_DEBUG, "DPP: DPP AKM not in use");
1065                 return;
1066         }
1067
1068         if (!hapd->conf->dpp_connector || !hapd->conf->dpp_netaccesskey ||
1069             !hapd->conf->dpp_csign) {
1070                 wpa_printf(MSG_DEBUG, "DPP: No own Connector/keys set");
1071                 return;
1072         }
1073
1074         os_get_time(&now);
1075
1076         if (hapd->conf->dpp_netaccesskey_expiry &&
1077             (os_time_t) hapd->conf->dpp_netaccesskey_expiry < now.sec) {
1078                 wpa_printf(MSG_INFO, "DPP: Own netAccessKey expired");
1079                 return;
1080         }
1081
1082         trans_id = dpp_get_attr(buf, len, DPP_ATTR_TRANSACTION_ID,
1083                                &trans_id_len);
1084         if (!trans_id || trans_id_len != 1) {
1085                 wpa_printf(MSG_DEBUG,
1086                            "DPP: Peer did not include Transaction ID");
1087                 return;
1088         }
1089
1090         connector = dpp_get_attr(buf, len, DPP_ATTR_CONNECTOR, &connector_len);
1091         if (!connector) {
1092                 wpa_printf(MSG_DEBUG,
1093                            "DPP: Peer did not include its Connector");
1094                 return;
1095         }
1096
1097         res = dpp_peer_intro(&intro, hapd->conf->dpp_connector,
1098                              wpabuf_head(hapd->conf->dpp_netaccesskey),
1099                              wpabuf_len(hapd->conf->dpp_netaccesskey),
1100                              wpabuf_head(hapd->conf->dpp_csign),
1101                              wpabuf_len(hapd->conf->dpp_csign),
1102                              connector, connector_len, &expire);
1103         if (res == 255) {
1104                 wpa_printf(MSG_INFO,
1105                            "DPP: Network Introduction protocol resulted in internal failure (peer "
1106                            MACSTR ")", MAC2STR(src));
1107                 return;
1108         }
1109         if (res != DPP_STATUS_OK) {
1110                 wpa_printf(MSG_INFO,
1111                            "DPP: Network Introduction protocol resulted in failure (peer "
1112                            MACSTR " status %d)", MAC2STR(src), res);
1113                 hostapd_dpp_send_peer_disc_resp(hapd, src, freq, trans_id[0],
1114                                                 res);
1115                 return;
1116         }
1117
1118         if (!expire || (os_time_t) hapd->conf->dpp_netaccesskey_expiry < expire)
1119                 expire = hapd->conf->dpp_netaccesskey_expiry;
1120         if (expire)
1121                 expiration = expire - now.sec;
1122         else
1123                 expiration = 0;
1124
1125         if (wpa_auth_pmksa_add2(hapd->wpa_auth, src, intro.pmk, intro.pmk_len,
1126                                 intro.pmkid, expiration,
1127                                 WPA_KEY_MGMT_DPP) < 0) {
1128                 wpa_printf(MSG_ERROR, "DPP: Failed to add PMKSA cache entry");
1129                 return;
1130         }
1131
1132         hostapd_dpp_send_peer_disc_resp(hapd, src, freq, trans_id[0],
1133                                         DPP_STATUS_OK);
1134 }
1135
1136
1137 static void
1138 hostapd_dpp_rx_pkex_exchange_req(struct hostapd_data *hapd, const u8 *src,
1139                                  const u8 *buf, size_t len,
1140                                  unsigned int freq)
1141 {
1142         struct wpabuf *msg;
1143
1144         wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Request from " MACSTR,
1145                    MAC2STR(src));
1146
1147         /* TODO: Support multiple PKEX codes by iterating over all the enabled
1148          * values here */
1149
1150         if (!hapd->dpp_pkex_code || !hapd->dpp_pkex_bi) {
1151                 wpa_printf(MSG_DEBUG,
1152                            "DPP: No PKEX code configured - ignore request");
1153                 return;
1154         }
1155
1156         if (hapd->dpp_pkex) {
1157                 /* TODO: Support parallel operations */
1158                 wpa_printf(MSG_DEBUG,
1159                            "DPP: Already in PKEX session - ignore new request");
1160                 return;
1161         }
1162
1163         hapd->dpp_pkex = dpp_pkex_rx_exchange_req(hapd->msg_ctx,
1164                                                   hapd->dpp_pkex_bi,
1165                                                   hapd->own_addr, src,
1166                                                   hapd->dpp_pkex_identifier,
1167                                                   hapd->dpp_pkex_code,
1168                                                   buf, len);
1169         if (!hapd->dpp_pkex) {
1170                 wpa_printf(MSG_DEBUG,
1171                            "DPP: Failed to process the request - ignore it");
1172                 return;
1173         }
1174
1175         msg = hapd->dpp_pkex->exchange_resp;
1176         wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1177                 " freq=%u type=%d", MAC2STR(src), freq,
1178                 DPP_PA_PKEX_EXCHANGE_RESP);
1179         hostapd_drv_send_action(hapd, freq, 0, src,
1180                                 wpabuf_head(msg), wpabuf_len(msg));
1181         if (hapd->dpp_pkex->failed) {
1182                 wpa_printf(MSG_DEBUG,
1183                            "DPP: Terminate PKEX exchange due to an earlier error");
1184                 if (hapd->dpp_pkex->t > hapd->dpp_pkex->own_bi->pkex_t)
1185                         hapd->dpp_pkex->own_bi->pkex_t = hapd->dpp_pkex->t;
1186                 dpp_pkex_free(hapd->dpp_pkex);
1187                 hapd->dpp_pkex = NULL;
1188         }
1189 }
1190
1191
1192 static void
1193 hostapd_dpp_rx_pkex_exchange_resp(struct hostapd_data *hapd, const u8 *src,
1194                                   const u8 *buf, size_t len, unsigned int freq)
1195 {
1196         struct wpabuf *msg;
1197
1198         wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Response from " MACSTR,
1199                    MAC2STR(src));
1200
1201         /* TODO: Support multiple PKEX codes by iterating over all the enabled
1202          * values here */
1203
1204         if (!hapd->dpp_pkex || !hapd->dpp_pkex->initiator ||
1205             hapd->dpp_pkex->exchange_done) {
1206                 wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
1207                 return;
1208         }
1209
1210         msg = dpp_pkex_rx_exchange_resp(hapd->dpp_pkex, src, buf, len);
1211         if (!msg) {
1212                 wpa_printf(MSG_DEBUG, "DPP: Failed to process the response");
1213                 return;
1214         }
1215
1216         wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Request to " MACSTR,
1217                    MAC2STR(src));
1218
1219         wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1220                 " freq=%u type=%d", MAC2STR(src), freq,
1221                 DPP_PA_PKEX_COMMIT_REVEAL_REQ);
1222         hostapd_drv_send_action(hapd, freq, 0, src,
1223                                 wpabuf_head(msg), wpabuf_len(msg));
1224         wpabuf_free(msg);
1225 }
1226
1227
1228 static void
1229 hostapd_dpp_rx_pkex_commit_reveal_req(struct hostapd_data *hapd, const u8 *src,
1230                                       const u8 *hdr, const u8 *buf, size_t len,
1231                                       unsigned int freq)
1232 {
1233         struct wpabuf *msg;
1234         struct dpp_pkex *pkex = hapd->dpp_pkex;
1235         struct dpp_bootstrap_info *bi;
1236
1237         wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Request from " MACSTR,
1238                    MAC2STR(src));
1239
1240         if (!pkex || pkex->initiator || !pkex->exchange_done) {
1241                 wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
1242                 return;
1243         }
1244
1245         msg = dpp_pkex_rx_commit_reveal_req(pkex, hdr, buf, len);
1246         if (!msg) {
1247                 wpa_printf(MSG_DEBUG, "DPP: Failed to process the request");
1248                 if (hapd->dpp_pkex->failed) {
1249                         wpa_printf(MSG_DEBUG, "DPP: Terminate PKEX exchange");
1250                         if (hapd->dpp_pkex->t > hapd->dpp_pkex->own_bi->pkex_t)
1251                                 hapd->dpp_pkex->own_bi->pkex_t =
1252                                         hapd->dpp_pkex->t;
1253                         dpp_pkex_free(hapd->dpp_pkex);
1254                         hapd->dpp_pkex = NULL;
1255                 }
1256                 return;
1257         }
1258
1259         wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Response to "
1260                    MACSTR, MAC2STR(src));
1261
1262         wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1263                 " freq=%u type=%d", MAC2STR(src), freq,
1264                 DPP_PA_PKEX_COMMIT_REVEAL_RESP);
1265         hostapd_drv_send_action(hapd, freq, 0, src,
1266                                 wpabuf_head(msg), wpabuf_len(msg));
1267         wpabuf_free(msg);
1268
1269         bi = dpp_pkex_finish(hapd->iface->interfaces->dpp, pkex, src, freq);
1270         if (!bi)
1271                 return;
1272         hapd->dpp_pkex = NULL;
1273 }
1274
1275
1276 static void
1277 hostapd_dpp_rx_pkex_commit_reveal_resp(struct hostapd_data *hapd, const u8 *src,
1278                                        const u8 *hdr, const u8 *buf, size_t len,
1279                                        unsigned int freq)
1280 {
1281         int res;
1282         struct dpp_bootstrap_info *bi;
1283         struct dpp_pkex *pkex = hapd->dpp_pkex;
1284         char cmd[500];
1285
1286         wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Response from " MACSTR,
1287                    MAC2STR(src));
1288
1289         if (!pkex || !pkex->initiator || !pkex->exchange_done) {
1290                 wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
1291                 return;
1292         }
1293
1294         res = dpp_pkex_rx_commit_reveal_resp(pkex, hdr, buf, len);
1295         if (res < 0) {
1296                 wpa_printf(MSG_DEBUG, "DPP: Failed to process the response");
1297                 return;
1298         }
1299
1300         bi = dpp_pkex_finish(hapd->iface->interfaces->dpp, pkex, src, freq);
1301         if (!bi)
1302                 return;
1303         hapd->dpp_pkex = NULL;
1304
1305         os_snprintf(cmd, sizeof(cmd), " peer=%u %s",
1306                     bi->id,
1307                     hapd->dpp_pkex_auth_cmd ? hapd->dpp_pkex_auth_cmd : "");
1308         wpa_printf(MSG_DEBUG,
1309                    "DPP: Start authentication after PKEX with parameters: %s",
1310                    cmd);
1311         if (hostapd_dpp_auth_init(hapd, cmd) < 0) {
1312                 wpa_printf(MSG_DEBUG,
1313                            "DPP: Authentication initialization failed");
1314                 return;
1315         }
1316 }
1317
1318
1319 void hostapd_dpp_rx_action(struct hostapd_data *hapd, const u8 *src,
1320                            const u8 *buf, size_t len, unsigned int freq)
1321 {
1322         u8 crypto_suite;
1323         enum dpp_public_action_frame_type type;
1324         const u8 *hdr;
1325         unsigned int pkex_t;
1326
1327         if (len < DPP_HDR_LEN)
1328                 return;
1329         if (WPA_GET_BE24(buf) != OUI_WFA || buf[3] != DPP_OUI_TYPE)
1330                 return;
1331         hdr = buf;
1332         buf += 4;
1333         len -= 4;
1334         crypto_suite = *buf++;
1335         type = *buf++;
1336         len -= 2;
1337
1338         wpa_printf(MSG_DEBUG,
1339                    "DPP: Received DPP Public Action frame crypto suite %u type %d from "
1340                    MACSTR " freq=%u",
1341                    crypto_suite, type, MAC2STR(src), freq);
1342         if (crypto_suite != 1) {
1343                 wpa_printf(MSG_DEBUG, "DPP: Unsupported crypto suite %u",
1344                            crypto_suite);
1345                 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
1346                         " freq=%u type=%d ignore=unsupported-crypto-suite",
1347                         MAC2STR(src), freq, type);
1348                 return;
1349         }
1350         wpa_hexdump(MSG_MSGDUMP, "DPP: Received message attributes", buf, len);
1351         if (dpp_check_attrs(buf, len) < 0) {
1352                 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
1353                         " freq=%u type=%d ignore=invalid-attributes",
1354                         MAC2STR(src), freq, type);
1355                 return;
1356         }
1357         wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_RX "src=" MACSTR
1358                 " freq=%u type=%d", MAC2STR(src), freq, type);
1359
1360         switch (type) {
1361         case DPP_PA_AUTHENTICATION_REQ:
1362                 hostapd_dpp_rx_auth_req(hapd, src, hdr, buf, len, freq);
1363                 break;
1364         case DPP_PA_AUTHENTICATION_RESP:
1365                 hostapd_dpp_rx_auth_resp(hapd, src, hdr, buf, len, freq);
1366                 break;
1367         case DPP_PA_AUTHENTICATION_CONF:
1368                 hostapd_dpp_rx_auth_conf(hapd, src, hdr, buf, len);
1369                 break;
1370         case DPP_PA_PEER_DISCOVERY_REQ:
1371                 hostapd_dpp_rx_peer_disc_req(hapd, src, buf, len, freq);
1372                 break;
1373         case DPP_PA_PKEX_EXCHANGE_REQ:
1374                 hostapd_dpp_rx_pkex_exchange_req(hapd, src, buf, len, freq);
1375                 break;
1376         case DPP_PA_PKEX_EXCHANGE_RESP:
1377                 hostapd_dpp_rx_pkex_exchange_resp(hapd, src, buf, len, freq);
1378                 break;
1379         case DPP_PA_PKEX_COMMIT_REVEAL_REQ:
1380                 hostapd_dpp_rx_pkex_commit_reveal_req(hapd, src, hdr, buf, len,
1381                                                       freq);
1382                 break;
1383         case DPP_PA_PKEX_COMMIT_REVEAL_RESP:
1384                 hostapd_dpp_rx_pkex_commit_reveal_resp(hapd, src, hdr, buf, len,
1385                                                        freq);
1386                 break;
1387 #ifdef CONFIG_DPP2
1388         case DPP_PA_CONFIGURATION_RESULT:
1389                 hostapd_dpp_rx_conf_result(hapd, src, hdr, buf, len);
1390                 break;
1391 #endif /* CONFIG_DPP2 */
1392         default:
1393                 wpa_printf(MSG_DEBUG,
1394                            "DPP: Ignored unsupported frame subtype %d", type);
1395                 break;
1396         }
1397
1398         if (hapd->dpp_pkex)
1399                 pkex_t = hapd->dpp_pkex->t;
1400         else if (hapd->dpp_pkex_bi)
1401                 pkex_t = hapd->dpp_pkex_bi->pkex_t;
1402         else
1403                 pkex_t = 0;
1404         if (pkex_t >= PKEX_COUNTER_T_LIMIT) {
1405                 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PKEX_T_LIMIT "id=0");
1406                 hostapd_dpp_pkex_remove(hapd, "*");
1407         }
1408 }
1409
1410
1411 struct wpabuf *
1412 hostapd_dpp_gas_req_handler(struct hostapd_data *hapd, const u8 *sa,
1413                             const u8 *query, size_t query_len)
1414 {
1415         struct dpp_authentication *auth = hapd->dpp_auth;
1416         struct wpabuf *resp;
1417
1418         wpa_printf(MSG_DEBUG, "DPP: GAS request from " MACSTR, MAC2STR(sa));
1419         if (!auth || !auth->auth_success ||
1420             os_memcmp(sa, auth->peer_mac_addr, ETH_ALEN) != 0) {
1421                 wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
1422                 return NULL;
1423         }
1424         wpa_hexdump(MSG_DEBUG,
1425                     "DPP: Received Configuration Request (GAS Query Request)",
1426                     query, query_len);
1427         wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_REQ_RX "src=" MACSTR,
1428                 MAC2STR(sa));
1429         resp = dpp_conf_req_rx(auth, query, query_len);
1430         if (!resp)
1431                 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
1432         return resp;
1433 }
1434
1435
1436 void hostapd_dpp_gas_status_handler(struct hostapd_data *hapd, int ok)
1437 {
1438         struct dpp_authentication *auth = hapd->dpp_auth;
1439
1440         if (!auth)
1441                 return;
1442
1443         wpa_printf(MSG_DEBUG, "DPP: Configuration exchange completed (ok=%d)",
1444                    ok);
1445         eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
1446         eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
1447 #ifdef CONFIG_DPP2
1448         if (ok && auth->peer_version >= 2 &&
1449             auth->conf_resp_status == DPP_STATUS_OK) {
1450                 wpa_printf(MSG_DEBUG, "DPP: Wait for Configuration Result");
1451                 auth->waiting_conf_result = 1;
1452                 eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout,
1453                                      hapd, NULL);
1454                 eloop_register_timeout(2, 0,
1455                                        hostapd_dpp_config_result_wait_timeout,
1456                                        hapd, NULL);
1457                 return;
1458         }
1459 #endif /* CONFIG_DPP2 */
1460         hostapd_drv_send_action_cancel_wait(hapd);
1461
1462         if (ok)
1463                 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_SENT);
1464         else
1465                 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_CONF_FAILED);
1466         dpp_auth_deinit(hapd->dpp_auth);
1467         hapd->dpp_auth = NULL;
1468 }
1469
1470
1471 int hostapd_dpp_configurator_sign(struct hostapd_data *hapd, const char *cmd)
1472 {
1473         struct dpp_authentication *auth;
1474         int ret = -1;
1475         char *curve = NULL;
1476
1477         auth = os_zalloc(sizeof(*auth));
1478         if (!auth)
1479                 return -1;
1480
1481         curve = get_param(cmd, " curve=");
1482         hostapd_dpp_set_testing_options(hapd, auth);
1483         if (dpp_set_configurator(hapd->iface->interfaces->dpp, hapd->msg_ctx,
1484                                  auth, cmd) == 0 &&
1485             dpp_configurator_own_config(auth, curve, 1) == 0) {
1486                 hostapd_dpp_handle_config_obj(hapd, auth);
1487                 ret = 0;
1488         }
1489
1490         dpp_auth_deinit(auth);
1491         os_free(curve);
1492
1493         return ret;
1494 }
1495
1496
1497 int hostapd_dpp_pkex_add(struct hostapd_data *hapd, const char *cmd)
1498 {
1499         struct dpp_bootstrap_info *own_bi;
1500         const char *pos, *end;
1501
1502         pos = os_strstr(cmd, " own=");
1503         if (!pos)
1504                 return -1;
1505         pos += 5;
1506         own_bi = dpp_bootstrap_get_id(hapd->iface->interfaces->dpp, atoi(pos));
1507         if (!own_bi) {
1508                 wpa_printf(MSG_DEBUG,
1509                            "DPP: Identified bootstrap info not found");
1510                 return -1;
1511         }
1512         if (own_bi->type != DPP_BOOTSTRAP_PKEX) {
1513                 wpa_printf(MSG_DEBUG,
1514                            "DPP: Identified bootstrap info not for PKEX");
1515                 return -1;
1516         }
1517         hapd->dpp_pkex_bi = own_bi;
1518         own_bi->pkex_t = 0; /* clear pending errors on new code */
1519
1520         os_free(hapd->dpp_pkex_identifier);
1521         hapd->dpp_pkex_identifier = NULL;
1522         pos = os_strstr(cmd, " identifier=");
1523         if (pos) {
1524                 pos += 12;
1525                 end = os_strchr(pos, ' ');
1526                 if (!end)
1527                         return -1;
1528                 hapd->dpp_pkex_identifier = os_malloc(end - pos + 1);
1529                 if (!hapd->dpp_pkex_identifier)
1530                         return -1;
1531                 os_memcpy(hapd->dpp_pkex_identifier, pos, end - pos);
1532                 hapd->dpp_pkex_identifier[end - pos] = '\0';
1533         }
1534
1535         pos = os_strstr(cmd, " code=");
1536         if (!pos)
1537                 return -1;
1538         os_free(hapd->dpp_pkex_code);
1539         hapd->dpp_pkex_code = os_strdup(pos + 6);
1540         if (!hapd->dpp_pkex_code)
1541                 return -1;
1542
1543         if (os_strstr(cmd, " init=1")) {
1544                 struct wpabuf *msg;
1545
1546                 wpa_printf(MSG_DEBUG, "DPP: Initiating PKEX");
1547                 dpp_pkex_free(hapd->dpp_pkex);
1548                 hapd->dpp_pkex = dpp_pkex_init(hapd->msg_ctx, own_bi,
1549                                                hapd->own_addr,
1550                                                hapd->dpp_pkex_identifier,
1551                                                hapd->dpp_pkex_code);
1552                 if (!hapd->dpp_pkex)
1553                         return -1;
1554
1555                 msg = hapd->dpp_pkex->exchange_req;
1556                 /* TODO: Which channel to use? */
1557                 wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
1558                         " freq=%u type=%d", MAC2STR(broadcast), 2437,
1559                         DPP_PA_PKEX_EXCHANGE_REQ);
1560                 hostapd_drv_send_action(hapd, 2437, 0, broadcast,
1561                                         wpabuf_head(msg), wpabuf_len(msg));
1562         }
1563
1564         /* TODO: Support multiple PKEX info entries */
1565
1566         os_free(hapd->dpp_pkex_auth_cmd);
1567         hapd->dpp_pkex_auth_cmd = os_strdup(cmd);
1568
1569         return 1;
1570 }
1571
1572
1573 int hostapd_dpp_pkex_remove(struct hostapd_data *hapd, const char *id)
1574 {
1575         unsigned int id_val;
1576
1577         if (os_strcmp(id, "*") == 0) {
1578                 id_val = 0;
1579         } else {
1580                 id_val = atoi(id);
1581                 if (id_val == 0)
1582                         return -1;
1583         }
1584
1585         if ((id_val != 0 && id_val != 1) || !hapd->dpp_pkex_code)
1586                 return -1;
1587
1588         /* TODO: Support multiple PKEX entries */
1589         os_free(hapd->dpp_pkex_code);
1590         hapd->dpp_pkex_code = NULL;
1591         os_free(hapd->dpp_pkex_identifier);
1592         hapd->dpp_pkex_identifier = NULL;
1593         os_free(hapd->dpp_pkex_auth_cmd);
1594         hapd->dpp_pkex_auth_cmd = NULL;
1595         hapd->dpp_pkex_bi = NULL;
1596         /* TODO: Remove dpp_pkex only if it is for the identified PKEX code */
1597         dpp_pkex_free(hapd->dpp_pkex);
1598         hapd->dpp_pkex = NULL;
1599         return 0;
1600 }
1601
1602
1603 void hostapd_dpp_stop(struct hostapd_data *hapd)
1604 {
1605         dpp_auth_deinit(hapd->dpp_auth);
1606         hapd->dpp_auth = NULL;
1607         dpp_pkex_free(hapd->dpp_pkex);
1608         hapd->dpp_pkex = NULL;
1609 }
1610
1611
1612 int hostapd_dpp_init(struct hostapd_data *hapd)
1613 {
1614         hapd->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR | DPP_CAPAB_ENROLLEE;
1615         hapd->dpp_init_done = 1;
1616         return 0;
1617 }
1618
1619
1620 void hostapd_dpp_deinit(struct hostapd_data *hapd)
1621 {
1622 #ifdef CONFIG_TESTING_OPTIONS
1623         os_free(hapd->dpp_config_obj_override);
1624         hapd->dpp_config_obj_override = NULL;
1625         os_free(hapd->dpp_discovery_override);
1626         hapd->dpp_discovery_override = NULL;
1627         os_free(hapd->dpp_groups_override);
1628         hapd->dpp_groups_override = NULL;
1629         hapd->dpp_ignore_netaccesskey_mismatch = 0;
1630 #endif /* CONFIG_TESTING_OPTIONS */
1631         if (!hapd->dpp_init_done)
1632                 return;
1633         eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
1634         eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
1635         eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
1636 #ifdef CONFIG_DPP2
1637         eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout, hapd,
1638                              NULL);
1639 #endif /* CONFIG_DPP2 */
1640         dpp_auth_deinit(hapd->dpp_auth);
1641         hapd->dpp_auth = NULL;
1642         hostapd_dpp_pkex_remove(hapd, "*");
1643         hapd->dpp_pkex = NULL;
1644         os_free(hapd->dpp_configurator_params);
1645         hapd->dpp_configurator_params = NULL;
1646 }