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