1 /* 2 * wpa_supplicant - DPP 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/gas_server.h" 16 #include "rsn_supp/wpa.h" 17 #include "rsn_supp/pmksa_cache.h" 18 #include "wpa_supplicant_i.h" 19 #include "config.h" 20 #include "driver_i.h" 21 #include "offchannel.h" 22 #include "gas_query.h" 23 #include "bss.h" 24 #include "scan.h" 25 #include "notify.h" 26 #include "dpp_supplicant.h" 27 28 29 static int wpas_dpp_listen_start(struct wpa_supplicant *wpa_s, 30 unsigned int freq); 31 static void wpas_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx); 32 static void wpas_dpp_auth_success(struct wpa_supplicant *wpa_s, int initiator); 33 static void wpas_dpp_tx_status(struct wpa_supplicant *wpa_s, 34 unsigned int freq, const u8 *dst, 35 const u8 *src, const u8 *bssid, 36 const u8 *data, size_t data_len, 37 enum offchannel_send_action_result result); 38 39 static const u8 broadcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 40 41 /* Use a hardcoded Transaction ID 1 in Peer Discovery frames since there is only 42 * a single transaction in progress at any point in time. */ 43 static const u8 TRANSACTION_ID = 1; 44 45 46 static struct dpp_configurator * 47 dpp_configurator_get_id(struct wpa_supplicant *wpa_s, unsigned int id) 48 { 49 struct dpp_configurator *conf; 50 51 dl_list_for_each(conf, &wpa_s->dpp_configurator, 52 struct dpp_configurator, list) { 53 if (conf->id == id) 54 return conf; 55 } 56 return NULL; 57 } 58 59 60 static unsigned int wpas_dpp_next_id(struct wpa_supplicant *wpa_s) 61 { 62 struct dpp_bootstrap_info *bi; 63 unsigned int max_id = 0; 64 65 dl_list_for_each(bi, &wpa_s->dpp_bootstrap, struct dpp_bootstrap_info, 66 list) { 67 if (bi->id > max_id) 68 max_id = bi->id; 69 } 70 return max_id + 1; 71 } 72 73 74 /** 75 * wpas_dpp_qr_code - Parse and add DPP bootstrapping info from a QR Code 76 * @wpa_s: Pointer to wpa_supplicant data 77 * @cmd: DPP URI read from a QR Code 78 * Returns: Identifier of the stored info or -1 on failure 79 */ 80 int wpas_dpp_qr_code(struct wpa_supplicant *wpa_s, const char *cmd) 81 { 82 struct dpp_bootstrap_info *bi; 83 struct dpp_authentication *auth = wpa_s->dpp_auth; 84 85 bi = dpp_parse_qr_code(cmd); 86 if (!bi) 87 return -1; 88 89 bi->id = wpas_dpp_next_id(wpa_s); 90 dl_list_add(&wpa_s->dpp_bootstrap, &bi->list); 91 92 if (auth && auth->response_pending && 93 dpp_notify_new_qr_code(auth, bi) == 1) { 94 wpa_printf(MSG_DEBUG, 95 "DPP: Sending out pending authentication response"); 96 offchannel_send_action(wpa_s, auth->curr_freq, 97 auth->peer_mac_addr, wpa_s->own_addr, 98 broadcast, 99 wpabuf_head(auth->resp_msg), 100 wpabuf_len(auth->resp_msg), 101 500, wpas_dpp_tx_status, 0); 102 } 103 104 return bi->id; 105 } 106 107 108 static char * get_param(const char *cmd, const char *param) 109 { 110 const char *pos, *end; 111 char *val; 112 size_t len; 113 114 pos = os_strstr(cmd, param); 115 if (!pos) 116 return NULL; 117 118 pos += os_strlen(param); 119 end = os_strchr(pos, ' '); 120 if (end) 121 len = end - pos; 122 else 123 len = os_strlen(pos); 124 val = os_malloc(len + 1); 125 if (!val) 126 return NULL; 127 os_memcpy(val, pos, len); 128 val[len] = '\0'; 129 return val; 130 } 131 132 133 int wpas_dpp_bootstrap_gen(struct wpa_supplicant *wpa_s, const char *cmd) 134 { 135 char *chan = NULL, *mac = NULL, *info = NULL, *pk = NULL, *curve = NULL; 136 char *key = NULL; 137 u8 *privkey = NULL; 138 size_t privkey_len = 0; 139 size_t len; 140 int ret = -1; 141 struct dpp_bootstrap_info *bi; 142 143 bi = os_zalloc(sizeof(*bi)); 144 if (!bi) 145 goto fail; 146 147 if (os_strstr(cmd, "type=qrcode")) 148 bi->type = DPP_BOOTSTRAP_QR_CODE; 149 else if (os_strstr(cmd, "type=pkex")) 150 bi->type = DPP_BOOTSTRAP_PKEX; 151 else 152 goto fail; 153 154 chan = get_param(cmd, " chan="); 155 mac = get_param(cmd, " mac="); 156 info = get_param(cmd, " info="); 157 curve = get_param(cmd, " curve="); 158 key = get_param(cmd, " key="); 159 160 if (key) { 161 privkey_len = os_strlen(key) / 2; 162 privkey = os_malloc(privkey_len); 163 if (!privkey || 164 hexstr2bin(key, privkey, privkey_len) < 0) 165 goto fail; 166 } 167 168 pk = dpp_keygen(bi, curve, privkey, privkey_len); 169 if (!pk) 170 goto fail; 171 172 len = 4; /* "DPP:" */ 173 if (chan) { 174 if (dpp_parse_uri_chan_list(bi, chan) < 0) 175 goto fail; 176 len += 3 + os_strlen(chan); /* C:...; */ 177 } 178 if (mac) { 179 if (dpp_parse_uri_mac(bi, mac) < 0) 180 goto fail; 181 len += 3 + os_strlen(mac); /* M:...; */ 182 } 183 if (info) { 184 if (dpp_parse_uri_info(bi, info) < 0) 185 goto fail; 186 len += 3 + os_strlen(info); /* I:...; */ 187 } 188 len += 4 + os_strlen(pk); 189 bi->uri = os_malloc(len + 1); 190 if (!bi->uri) 191 goto fail; 192 os_snprintf(bi->uri, len + 1, "DPP:%s%s%s%s%s%s%s%s%sK:%s;;", 193 chan ? "C:" : "", chan ? chan : "", chan ? ";" : "", 194 mac ? "M:" : "", mac ? mac : "", mac ? ";" : "", 195 info ? "I:" : "", info ? info : "", info ? ";" : "", 196 pk); 197 bi->id = wpas_dpp_next_id(wpa_s); 198 dl_list_add(&wpa_s->dpp_bootstrap, &bi->list); 199 ret = bi->id; 200 bi = NULL; 201 fail: 202 os_free(curve); 203 os_free(pk); 204 os_free(chan); 205 os_free(mac); 206 os_free(info); 207 str_clear_free(key); 208 bin_clear_free(privkey, privkey_len); 209 dpp_bootstrap_info_free(bi); 210 return ret; 211 } 212 213 214 static struct dpp_bootstrap_info * 215 dpp_bootstrap_get_id(struct wpa_supplicant *wpa_s, unsigned int id) 216 { 217 struct dpp_bootstrap_info *bi; 218 219 dl_list_for_each(bi, &wpa_s->dpp_bootstrap, struct dpp_bootstrap_info, 220 list) { 221 if (bi->id == id) 222 return bi; 223 } 224 return NULL; 225 } 226 227 228 static int dpp_bootstrap_del(struct wpa_supplicant *wpa_s, unsigned int id) 229 { 230 struct dpp_bootstrap_info *bi, *tmp; 231 int found = 0; 232 233 dl_list_for_each_safe(bi, tmp, &wpa_s->dpp_bootstrap, 234 struct dpp_bootstrap_info, list) { 235 if (id && bi->id != id) 236 continue; 237 found = 1; 238 dl_list_del(&bi->list); 239 dpp_bootstrap_info_free(bi); 240 } 241 242 if (id == 0) 243 return 0; /* flush succeeds regardless of entries found */ 244 return found ? 0 : -1; 245 } 246 247 248 int wpas_dpp_bootstrap_remove(struct wpa_supplicant *wpa_s, const char *id) 249 { 250 unsigned int id_val; 251 252 if (os_strcmp(id, "*") == 0) { 253 id_val = 0; 254 } else { 255 id_val = atoi(id); 256 if (id_val == 0) 257 return -1; 258 } 259 260 return dpp_bootstrap_del(wpa_s, id_val); 261 } 262 263 264 const char * wpas_dpp_bootstrap_get_uri(struct wpa_supplicant *wpa_s, 265 unsigned int id) 266 { 267 struct dpp_bootstrap_info *bi; 268 269 bi = dpp_bootstrap_get_id(wpa_s, id); 270 if (!bi) 271 return NULL; 272 return bi->uri; 273 } 274 275 276 int wpas_dpp_bootstrap_info(struct wpa_supplicant *wpa_s, int id, 277 char *reply, int reply_size) 278 { 279 struct dpp_bootstrap_info *bi; 280 281 bi = dpp_bootstrap_get_id(wpa_s, id); 282 if (!bi) 283 return -1; 284 return os_snprintf(reply, reply_size, "type=%s\n" 285 "mac_addr=" MACSTR "\n" 286 "info=%s\n" 287 "num_freq=%u\n" 288 "curve=%s\n", 289 dpp_bootstrap_type_txt(bi->type), 290 MAC2STR(bi->mac_addr), 291 bi->info ? bi->info : "", 292 bi->num_freq, 293 bi->curve->name); 294 } 295 296 297 static void wpas_dpp_tx_status(struct wpa_supplicant *wpa_s, 298 unsigned int freq, const u8 *dst, 299 const u8 *src, const u8 *bssid, 300 const u8 *data, size_t data_len, 301 enum offchannel_send_action_result result) 302 { 303 wpa_printf(MSG_DEBUG, "DPP: TX status: freq=%u dst=" MACSTR 304 " result=%s", 305 freq, MAC2STR(dst), 306 result == OFFCHANNEL_SEND_ACTION_SUCCESS ? "SUCCESS" : 307 (result == OFFCHANNEL_SEND_ACTION_NO_ACK ? "no-ACK" : 308 "FAILED")); 309 310 if (!wpa_s->dpp_auth) { 311 wpa_printf(MSG_DEBUG, 312 "DPP: Ignore TX status since there is no ongoing authentication exchange"); 313 return; 314 } 315 316 if (wpa_s->dpp_auth->remove_on_tx_status) { 317 wpa_printf(MSG_DEBUG, 318 "DPP: Terminate authentication exchange due to an earlier error"); 319 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL); 320 offchannel_send_action_done(wpa_s); 321 dpp_auth_deinit(wpa_s->dpp_auth); 322 wpa_s->dpp_auth = NULL; 323 return; 324 } 325 326 if (wpa_s->dpp_auth_ok_on_ack) 327 wpas_dpp_auth_success(wpa_s, 1); 328 329 if (!is_broadcast_ether_addr(dst) && 330 result != OFFCHANNEL_SEND_ACTION_SUCCESS) { 331 wpa_printf(MSG_DEBUG, 332 "DPP: Unicast DPP Action frame was not ACKed"); 333 /* TODO: In case of DPP Authentication Request frame, move to 334 * the next channel immediately */ 335 } 336 } 337 338 339 static void wpas_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx) 340 { 341 struct wpa_supplicant *wpa_s = eloop_ctx; 342 343 if (!wpa_s->dpp_auth) 344 return; 345 wpa_printf(MSG_DEBUG, "DPP: Continue reply wait on channel %u MHz", 346 wpa_s->dpp_auth->curr_freq); 347 wpas_dpp_listen_start(wpa_s, wpa_s->dpp_auth->curr_freq); 348 } 349 350 351 static void wpas_dpp_set_testing_options(struct wpa_supplicant *wpa_s, 352 struct dpp_authentication *auth) 353 { 354 #ifdef CONFIG_TESTING_OPTIONS 355 if (wpa_s->dpp_config_obj_override) 356 auth->config_obj_override = 357 os_strdup(wpa_s->dpp_config_obj_override); 358 if (wpa_s->dpp_discovery_override) 359 auth->discovery_override = 360 os_strdup(wpa_s->dpp_discovery_override); 361 if (wpa_s->dpp_groups_override) 362 auth->groups_override = 363 os_strdup(wpa_s->dpp_groups_override); 364 auth->ignore_netaccesskey_mismatch = 365 wpa_s->dpp_ignore_netaccesskey_mismatch; 366 #endif /* CONFIG_TESTING_OPTIONS */ 367 } 368 369 370 static void wpas_dpp_set_configurator(struct wpa_supplicant *wpa_s, 371 struct dpp_authentication *auth, 372 const char *cmd) 373 { 374 const char *pos, *end; 375 struct dpp_configuration *conf_sta = NULL, *conf_ap = NULL; 376 struct dpp_configurator *conf = NULL; 377 u8 ssid[32] = { "test" }; 378 size_t ssid_len = 4; 379 char pass[64] = { }; 380 size_t pass_len = 0; 381 u8 psk[PMK_LEN]; 382 int psk_set = 0; 383 384 if (!cmd) 385 return; 386 387 wpa_printf(MSG_DEBUG, "DPP: Set configurator parameters: %s", cmd); 388 pos = os_strstr(cmd, " ssid="); 389 if (pos) { 390 pos += 6; 391 end = os_strchr(pos, ' '); 392 ssid_len = end ? (size_t) (end - pos) : os_strlen(pos); 393 ssid_len /= 2; 394 if (ssid_len > sizeof(ssid) || 395 hexstr2bin(pos, ssid, ssid_len) < 0) 396 goto fail; 397 } 398 399 pos = os_strstr(cmd, " pass="); 400 if (pos) { 401 pos += 6; 402 end = os_strchr(pos, ' '); 403 pass_len = end ? (size_t) (end - pos) : os_strlen(pos); 404 pass_len /= 2; 405 if (pass_len > sizeof(pass) - 1 || pass_len < 8 || 406 hexstr2bin(pos, (u8 *) pass, pass_len) < 0) 407 goto fail; 408 } 409 410 pos = os_strstr(cmd, " psk="); 411 if (pos) { 412 pos += 5; 413 if (hexstr2bin(pos, psk, PMK_LEN) < 0) 414 goto fail; 415 psk_set = 1; 416 } 417 418 if (os_strstr(cmd, " conf=sta-")) { 419 conf_sta = os_zalloc(sizeof(struct dpp_configuration)); 420 if (!conf_sta) 421 goto fail; 422 os_memcpy(conf_sta->ssid, ssid, ssid_len); 423 conf_sta->ssid_len = ssid_len; 424 if (os_strstr(cmd, " conf=sta-psk")) { 425 conf_sta->dpp = 0; 426 if (psk_set) { 427 os_memcpy(conf_sta->psk, psk, PMK_LEN); 428 } else { 429 conf_sta->passphrase = os_strdup(pass); 430 if (!conf_sta->passphrase) 431 goto fail; 432 } 433 } else if (os_strstr(cmd, " conf=sta-dpp")) { 434 conf_sta->dpp = 1; 435 } else { 436 goto fail; 437 } 438 } 439 440 if (os_strstr(cmd, " conf=ap-")) { 441 conf_ap = os_zalloc(sizeof(struct dpp_configuration)); 442 if (!conf_ap) 443 goto fail; 444 os_memcpy(conf_ap->ssid, ssid, ssid_len); 445 conf_ap->ssid_len = ssid_len; 446 if (os_strstr(cmd, " conf=ap-psk")) { 447 conf_ap->dpp = 0; 448 if (psk_set) { 449 os_memcpy(conf_ap->psk, psk, PMK_LEN); 450 } else { 451 conf_ap->passphrase = os_strdup(pass); 452 if (!conf_ap->passphrase) 453 goto fail; 454 } 455 } else if (os_strstr(cmd, " conf=ap-dpp")) { 456 conf_ap->dpp = 1; 457 } else { 458 goto fail; 459 } 460 } 461 462 pos = os_strstr(cmd, " expiry="); 463 if (pos) { 464 long int val; 465 466 pos += 8; 467 val = strtol(pos, NULL, 0); 468 if (val <= 0) 469 goto fail; 470 if (conf_sta) 471 conf_sta->netaccesskey_expiry = val; 472 if (conf_ap) 473 conf_ap->netaccesskey_expiry = val; 474 } 475 476 pos = os_strstr(cmd, " configurator="); 477 if (pos) { 478 pos += 14; 479 conf = dpp_configurator_get_id(wpa_s, atoi(pos)); 480 if (!conf) { 481 wpa_printf(MSG_INFO, 482 "DPP: Could not find the specified configurator"); 483 goto fail; 484 } 485 } 486 auth->conf_sta = conf_sta; 487 auth->conf_ap = conf_ap; 488 auth->conf = conf; 489 return; 490 491 fail: 492 wpa_printf(MSG_DEBUG, "DPP: Failed to set configurator parameters"); 493 dpp_configuration_free(conf_sta); 494 dpp_configuration_free(conf_ap); 495 } 496 497 498 int wpas_dpp_auth_init(struct wpa_supplicant *wpa_s, const char *cmd) 499 { 500 const char *pos; 501 struct dpp_bootstrap_info *peer_bi, *own_bi = NULL; 502 const u8 *dst; 503 int res; 504 int configurator = 1; 505 unsigned int wait_time; 506 507 wpa_s->dpp_gas_client = 0; 508 509 pos = os_strstr(cmd, " peer="); 510 if (!pos) 511 return -1; 512 pos += 6; 513 peer_bi = dpp_bootstrap_get_id(wpa_s, atoi(pos)); 514 if (!peer_bi) { 515 wpa_printf(MSG_INFO, 516 "DPP: Could not find bootstrapping info for the identified peer"); 517 return -1; 518 } 519 520 pos = os_strstr(cmd, " own="); 521 if (pos) { 522 pos += 5; 523 own_bi = dpp_bootstrap_get_id(wpa_s, atoi(pos)); 524 if (!own_bi) { 525 wpa_printf(MSG_INFO, 526 "DPP: Could not find bootstrapping info for the identified local entry"); 527 return -1; 528 } 529 530 if (peer_bi->curve != own_bi->curve) { 531 wpa_printf(MSG_INFO, 532 "DPP: Mismatching curves in bootstrapping info (peer=%s own=%s)", 533 peer_bi->curve->name, own_bi->curve->name); 534 return -1; 535 } 536 } 537 538 pos = os_strstr(cmd, " role="); 539 if (pos) { 540 pos += 6; 541 if (os_strncmp(pos, "configurator", 12) == 0) 542 configurator = 1; 543 else if (os_strncmp(pos, "enrollee", 8) == 0) 544 configurator = 0; 545 else 546 goto fail; 547 } 548 549 pos = os_strstr(cmd, " netrole="); 550 if (pos) { 551 pos += 9; 552 wpa_s->dpp_netrole_ap = os_strncmp(pos, "ap", 2) == 0; 553 } 554 555 if (wpa_s->dpp_auth) { 556 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL); 557 offchannel_send_action_done(wpa_s); 558 dpp_auth_deinit(wpa_s->dpp_auth); 559 } 560 wpa_s->dpp_auth = dpp_auth_init(wpa_s, peer_bi, own_bi, configurator); 561 if (!wpa_s->dpp_auth) 562 goto fail; 563 wpas_dpp_set_testing_options(wpa_s, wpa_s->dpp_auth); 564 wpas_dpp_set_configurator(wpa_s, wpa_s->dpp_auth, cmd); 565 566 /* TODO: Support iteration over all frequencies and filtering of 567 * frequencies based on locally enabled channels that allow initiation 568 * of transmission. */ 569 if (peer_bi->num_freq > 0) 570 wpa_s->dpp_auth->curr_freq = peer_bi->freq[0]; 571 else 572 wpa_s->dpp_auth->curr_freq = 2412; 573 574 if (is_zero_ether_addr(peer_bi->mac_addr)) { 575 dst = broadcast; 576 } else { 577 dst = peer_bi->mac_addr; 578 os_memcpy(wpa_s->dpp_auth->peer_mac_addr, peer_bi->mac_addr, 579 ETH_ALEN); 580 } 581 wpa_s->dpp_auth_ok_on_ack = 0; 582 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL); 583 wait_time = wpa_s->max_remain_on_chan; 584 if (wait_time > 2000) 585 wait_time = 2000; 586 eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000, 587 wpas_dpp_reply_wait_timeout, 588 wpa_s, NULL); 589 res = offchannel_send_action(wpa_s, wpa_s->dpp_auth->curr_freq, 590 dst, wpa_s->own_addr, broadcast, 591 wpabuf_head(wpa_s->dpp_auth->req_msg), 592 wpabuf_len(wpa_s->dpp_auth->req_msg), 593 wait_time, wpas_dpp_tx_status, 0); 594 595 return res; 596 fail: 597 return -1; 598 } 599 600 601 struct wpas_dpp_listen_work { 602 unsigned int freq; 603 unsigned int duration; 604 struct wpabuf *probe_resp_ie; 605 }; 606 607 608 static void wpas_dpp_listen_work_free(struct wpas_dpp_listen_work *lwork) 609 { 610 if (!lwork) 611 return; 612 os_free(lwork); 613 } 614 615 616 static void wpas_dpp_listen_work_done(struct wpa_supplicant *wpa_s) 617 { 618 struct wpas_dpp_listen_work *lwork; 619 620 if (!wpa_s->dpp_listen_work) 621 return; 622 623 lwork = wpa_s->dpp_listen_work->ctx; 624 wpas_dpp_listen_work_free(lwork); 625 radio_work_done(wpa_s->dpp_listen_work); 626 wpa_s->dpp_listen_work = NULL; 627 } 628 629 630 static void dpp_start_listen_cb(struct wpa_radio_work *work, int deinit) 631 { 632 struct wpa_supplicant *wpa_s = work->wpa_s; 633 struct wpas_dpp_listen_work *lwork = work->ctx; 634 635 if (deinit) { 636 if (work->started) { 637 wpa_s->dpp_listen_work = NULL; 638 wpas_dpp_listen_stop(wpa_s); 639 } 640 wpas_dpp_listen_work_free(lwork); 641 return; 642 } 643 644 wpa_s->dpp_listen_work = work; 645 646 wpa_s->dpp_pending_listen_freq = lwork->freq; 647 648 if (wpa_drv_remain_on_channel(wpa_s, lwork->freq, 649 wpa_s->max_remain_on_chan) < 0) { 650 wpa_printf(MSG_DEBUG, 651 "DPP: Failed to request the driver to remain on channel (%u MHz) for listen", 652 lwork->freq); 653 wpas_dpp_listen_work_done(wpa_s); 654 wpa_s->dpp_pending_listen_freq = 0; 655 return; 656 } 657 wpa_s->off_channel_freq = 0; 658 wpa_s->roc_waiting_drv_freq = lwork->freq; 659 } 660 661 662 static int wpas_dpp_listen_start(struct wpa_supplicant *wpa_s, 663 unsigned int freq) 664 { 665 struct wpas_dpp_listen_work *lwork; 666 667 if (wpa_s->dpp_listen_work) { 668 wpa_printf(MSG_DEBUG, 669 "DPP: Reject start_listen since dpp_listen_work already exists"); 670 return -1; 671 } 672 673 if (wpa_s->dpp_listen_freq) 674 wpas_dpp_listen_stop(wpa_s); 675 wpa_s->dpp_listen_freq = freq; 676 677 lwork = os_zalloc(sizeof(*lwork)); 678 if (!lwork) 679 return -1; 680 lwork->freq = freq; 681 682 if (radio_add_work(wpa_s, freq, "dpp-listen", 0, dpp_start_listen_cb, 683 lwork) < 0) { 684 wpas_dpp_listen_work_free(lwork); 685 return -1; 686 } 687 688 return 0; 689 } 690 691 692 int wpas_dpp_listen(struct wpa_supplicant *wpa_s, const char *cmd) 693 { 694 int freq; 695 696 freq = atoi(cmd); 697 if (freq <= 0) 698 return -1; 699 700 if (os_strstr(cmd, " role=configurator")) 701 wpa_s->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR; 702 else if (os_strstr(cmd, " role=enrollee")) 703 wpa_s->dpp_allowed_roles = DPP_CAPAB_ENROLLEE; 704 else 705 wpa_s->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR | 706 DPP_CAPAB_ENROLLEE; 707 wpa_s->dpp_qr_mutual = os_strstr(cmd, " qr=mutual") != NULL; 708 wpa_s->dpp_netrole_ap = os_strstr(cmd, " netrole=ap") != NULL; 709 if (wpa_s->dpp_listen_freq == (unsigned int) freq) { 710 wpa_printf(MSG_DEBUG, "DPP: Already listening on %u MHz", 711 freq); 712 return 0; 713 } 714 715 return wpas_dpp_listen_start(wpa_s, freq); 716 } 717 718 719 void wpas_dpp_listen_stop(struct wpa_supplicant *wpa_s) 720 { 721 if (!wpa_s->dpp_listen_freq) 722 return; 723 724 wpa_printf(MSG_DEBUG, "DPP: Stop listen on %u MHz", 725 wpa_s->dpp_listen_freq); 726 wpa_drv_cancel_remain_on_channel(wpa_s); 727 wpa_s->dpp_listen_freq = 0; 728 wpas_dpp_listen_work_done(wpa_s); 729 } 730 731 732 void wpas_dpp_remain_on_channel_cb(struct wpa_supplicant *wpa_s, 733 unsigned int freq) 734 { 735 if (!wpa_s->dpp_listen_freq && !wpa_s->dpp_pending_listen_freq) 736 return; 737 738 wpa_printf(MSG_DEBUG, 739 "DPP: remain-on-channel callback (off_channel_freq=%u dpp_pending_listen_freq=%d roc_waiting_drv_freq=%d freq=%u)", 740 wpa_s->off_channel_freq, wpa_s->dpp_pending_listen_freq, 741 wpa_s->roc_waiting_drv_freq, freq); 742 if (wpa_s->off_channel_freq && 743 wpa_s->off_channel_freq == wpa_s->dpp_pending_listen_freq) { 744 wpa_printf(MSG_DEBUG, "DPP: Listen on %u MHz started", freq); 745 wpa_s->dpp_pending_listen_freq = 0; 746 } else { 747 wpa_printf(MSG_DEBUG, 748 "DPP: Ignore remain-on-channel callback (off_channel_freq=%u dpp_pending_listen_freq=%d freq=%u)", 749 wpa_s->off_channel_freq, 750 wpa_s->dpp_pending_listen_freq, freq); 751 } 752 } 753 754 755 void wpas_dpp_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s, 756 unsigned int freq) 757 { 758 wpas_dpp_listen_work_done(wpa_s); 759 760 if (wpa_s->dpp_auth && !wpa_s->dpp_gas_client) { 761 /* Continue listen with a new remain-on-channel */ 762 wpa_printf(MSG_DEBUG, 763 "DPP: Continue wait on %u MHz for the ongoing DPP provisioning session", 764 wpa_s->dpp_auth->curr_freq); 765 wpas_dpp_listen_start(wpa_s, wpa_s->dpp_auth->curr_freq); 766 return; 767 } 768 769 if (wpa_s->dpp_listen_freq) { 770 /* Continue listen with a new remain-on-channel */ 771 wpas_dpp_listen_start(wpa_s, wpa_s->dpp_listen_freq); 772 } 773 } 774 775 776 static void wpas_dpp_rx_auth_req(struct wpa_supplicant *wpa_s, const u8 *src, 777 const u8 *hdr, const u8 *buf, size_t len, 778 unsigned int freq) 779 { 780 const u8 *r_bootstrap, *i_bootstrap, *wrapped_data; 781 u16 r_bootstrap_len, i_bootstrap_len, wrapped_data_len; 782 struct dpp_bootstrap_info *bi, *own_bi = NULL, *peer_bi = NULL; 783 784 wpa_printf(MSG_DEBUG, "DPP: Authentication Request from " MACSTR, 785 MAC2STR(src)); 786 787 wrapped_data = dpp_get_attr(buf, len, DPP_ATTR_WRAPPED_DATA, 788 &wrapped_data_len); 789 if (!wrapped_data) { 790 wpa_printf(MSG_DEBUG, 791 "DPP: Missing required Wrapped data attribute"); 792 return; 793 } 794 wpa_hexdump(MSG_MSGDUMP, "DPP: Wrapped data", 795 wrapped_data, wrapped_data_len); 796 797 r_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH, 798 &r_bootstrap_len); 799 if (!r_bootstrap || r_bootstrap > wrapped_data || 800 r_bootstrap_len != SHA256_MAC_LEN) { 801 wpa_printf(MSG_DEBUG, 802 "DPP: Missing or invalid required Responder Bootstrapping Key Hash attribute"); 803 return; 804 } 805 wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash", 806 r_bootstrap, r_bootstrap_len); 807 808 i_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_I_BOOTSTRAP_KEY_HASH, 809 &i_bootstrap_len); 810 if (!i_bootstrap || i_bootstrap > wrapped_data || 811 i_bootstrap_len != SHA256_MAC_LEN) { 812 wpa_printf(MSG_DEBUG, 813 "DPP: Missing or invalid required Initiator Bootstrapping Key Hash attribute"); 814 return; 815 } 816 wpa_hexdump(MSG_MSGDUMP, "DPP: Initiator Bootstrapping Key Hash", 817 i_bootstrap, i_bootstrap_len); 818 819 /* Try to find own and peer bootstrapping key matches based on the 820 * received hash values */ 821 dl_list_for_each(bi, &wpa_s->dpp_bootstrap, struct dpp_bootstrap_info, 822 list) { 823 if (!own_bi && bi->own && 824 os_memcmp(bi->pubkey_hash, r_bootstrap, 825 SHA256_MAC_LEN) == 0) { 826 wpa_printf(MSG_DEBUG, 827 "DPP: Found matching own bootstrapping information"); 828 own_bi = bi; 829 } 830 831 if (!peer_bi && !bi->own && 832 os_memcmp(bi->pubkey_hash, i_bootstrap, 833 SHA256_MAC_LEN) == 0) { 834 wpa_printf(MSG_DEBUG, 835 "DPP: Found matching peer bootstrapping information"); 836 peer_bi = bi; 837 } 838 839 if (own_bi && peer_bi) 840 break; 841 } 842 843 if (!own_bi) { 844 wpa_printf(MSG_DEBUG, 845 "DPP: No matching own bootstrapping key found - ignore message"); 846 return; 847 } 848 849 if (wpa_s->dpp_auth) { 850 wpa_printf(MSG_DEBUG, 851 "DPP: Already in DPP authentication exchange - ignore new one"); 852 return; 853 } 854 855 wpa_s->dpp_gas_client = 0; 856 wpa_s->dpp_auth_ok_on_ack = 0; 857 wpa_s->dpp_auth = dpp_auth_req_rx(wpa_s, wpa_s->dpp_allowed_roles, 858 wpa_s->dpp_qr_mutual, 859 peer_bi, own_bi, freq, hdr, buf, 860 wrapped_data, wrapped_data_len); 861 if (!wpa_s->dpp_auth) { 862 wpa_printf(MSG_DEBUG, "DPP: No response generated"); 863 return; 864 } 865 wpas_dpp_set_testing_options(wpa_s, wpa_s->dpp_auth); 866 wpas_dpp_set_configurator(wpa_s, wpa_s->dpp_auth, 867 wpa_s->dpp_configurator_params); 868 os_memcpy(wpa_s->dpp_auth->peer_mac_addr, src, ETH_ALEN); 869 870 offchannel_send_action(wpa_s, wpa_s->dpp_auth->curr_freq, 871 src, wpa_s->own_addr, broadcast, 872 wpabuf_head(wpa_s->dpp_auth->resp_msg), 873 wpabuf_len(wpa_s->dpp_auth->resp_msg), 874 500, wpas_dpp_tx_status, 0); 875 } 876 877 878 static void wpas_dpp_start_gas_server(struct wpa_supplicant *wpa_s) 879 { 880 /* TODO: stop wait and start ROC */ 881 } 882 883 884 static struct wpa_ssid * wpas_dpp_add_network(struct wpa_supplicant *wpa_s, 885 struct dpp_authentication *auth) 886 { 887 struct wpa_ssid *ssid; 888 889 ssid = wpa_config_add_network(wpa_s->conf); 890 if (!ssid) 891 return NULL; 892 wpas_notify_network_added(wpa_s, ssid); 893 wpa_config_set_network_defaults(ssid); 894 ssid->disabled = 1; 895 896 ssid->ssid = os_malloc(auth->ssid_len); 897 if (!ssid->ssid) 898 goto fail; 899 os_memcpy(ssid->ssid, auth->ssid, auth->ssid_len); 900 ssid->ssid_len = auth->ssid_len; 901 902 if (auth->connector) { 903 ssid->key_mgmt = WPA_KEY_MGMT_DPP; 904 ssid->dpp_connector = os_strdup(auth->connector); 905 if (!ssid->dpp_connector) 906 goto fail; 907 } 908 909 if (auth->c_sign_key) { 910 ssid->dpp_csign = os_malloc(wpabuf_len(auth->c_sign_key)); 911 if (!ssid->dpp_csign) 912 goto fail; 913 os_memcpy(ssid->dpp_csign, wpabuf_head(auth->c_sign_key), 914 wpabuf_len(auth->c_sign_key)); 915 ssid->dpp_csign_len = wpabuf_len(auth->c_sign_key); 916 } 917 918 if (auth->net_access_key) { 919 ssid->dpp_netaccesskey = 920 os_malloc(wpabuf_len(auth->net_access_key)); 921 if (!ssid->dpp_netaccesskey) 922 goto fail; 923 os_memcpy(ssid->dpp_netaccesskey, 924 wpabuf_head(auth->net_access_key), 925 wpabuf_len(auth->net_access_key)); 926 ssid->dpp_netaccesskey_len = wpabuf_len(auth->net_access_key); 927 ssid->dpp_netaccesskey_expiry = auth->net_access_key_expiry; 928 } 929 930 if (!auth->connector) { 931 ssid->key_mgmt = WPA_KEY_MGMT_PSK; 932 if (auth->passphrase[0]) { 933 if (wpa_config_set_quoted(ssid, "psk", 934 auth->passphrase) < 0) 935 goto fail; 936 wpa_config_update_psk(ssid); 937 ssid->export_keys = 1; 938 } else { 939 ssid->psk_set = auth->psk_set; 940 os_memcpy(ssid->psk, auth->psk, PMK_LEN); 941 } 942 } 943 944 return ssid; 945 fail: 946 wpas_notify_network_removed(wpa_s, ssid); 947 wpa_config_remove_network(wpa_s->conf, ssid->id); 948 return NULL; 949 } 950 951 952 static void wpas_dpp_process_config(struct wpa_supplicant *wpa_s, 953 struct dpp_authentication *auth) 954 { 955 struct wpa_ssid *ssid; 956 957 if (wpa_s->conf->dpp_config_processing < 1) 958 return; 959 960 ssid = wpas_dpp_add_network(wpa_s, auth); 961 if (!ssid) 962 return; 963 964 wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_NETWORK_ID "%d", ssid->id); 965 if (wpa_s->conf->dpp_config_processing < 2) 966 return; 967 968 wpa_printf(MSG_DEBUG, "DPP: Trying to connect to the new network"); 969 ssid->disabled = 0; 970 wpa_s->disconnected = 0; 971 wpa_s->reassociate = 1; 972 wpa_s->scan_runs = 0; 973 wpa_s->normal_scans = 0; 974 wpa_supplicant_cancel_sched_scan(wpa_s); 975 wpa_supplicant_req_scan(wpa_s, 0, 0); 976 } 977 978 979 static void wpas_dpp_handle_config_obj(struct wpa_supplicant *wpa_s, 980 struct dpp_authentication *auth) 981 { 982 wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_RECEIVED); 983 if (auth->ssid_len) 984 wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONFOBJ_SSID "%s", 985 wpa_ssid_txt(auth->ssid, auth->ssid_len)); 986 if (auth->connector) { 987 /* TODO: Save the Connector and consider using a command 988 * to fetch the value instead of sending an event with 989 * it. The Connector could end up being larger than what 990 * most clients are ready to receive as an event 991 * message. */ 992 wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONNECTOR "%s", 993 auth->connector); 994 } 995 if (auth->c_sign_key) { 996 char *hex; 997 size_t hexlen; 998 999 hexlen = 2 * wpabuf_len(auth->c_sign_key) + 1; 1000 hex = os_malloc(hexlen); 1001 if (hex) { 1002 wpa_snprintf_hex(hex, hexlen, 1003 wpabuf_head(auth->c_sign_key), 1004 wpabuf_len(auth->c_sign_key)); 1005 wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_C_SIGN_KEY "%s", 1006 hex); 1007 os_free(hex); 1008 } 1009 } 1010 if (auth->net_access_key) { 1011 char *hex; 1012 size_t hexlen; 1013 1014 hexlen = 2 * wpabuf_len(auth->net_access_key) + 1; 1015 hex = os_malloc(hexlen); 1016 if (hex) { 1017 wpa_snprintf_hex(hex, hexlen, 1018 wpabuf_head(auth->net_access_key), 1019 wpabuf_len(auth->net_access_key)); 1020 if (auth->net_access_key_expiry) 1021 wpa_msg(wpa_s, MSG_INFO, 1022 DPP_EVENT_NET_ACCESS_KEY "%s %lu", hex, 1023 (long unsigned) 1024 auth->net_access_key_expiry); 1025 else 1026 wpa_msg(wpa_s, MSG_INFO, 1027 DPP_EVENT_NET_ACCESS_KEY "%s", hex); 1028 os_free(hex); 1029 } 1030 } 1031 1032 wpas_dpp_process_config(wpa_s, auth); 1033 } 1034 1035 1036 static void wpas_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token, 1037 enum gas_query_result result, 1038 const struct wpabuf *adv_proto, 1039 const struct wpabuf *resp, u16 status_code) 1040 { 1041 struct wpa_supplicant *wpa_s = ctx; 1042 const u8 *pos; 1043 struct dpp_authentication *auth = wpa_s->dpp_auth; 1044 1045 if (!auth || !auth->auth_success) { 1046 wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress"); 1047 return; 1048 } 1049 if (!resp || status_code != WLAN_STATUS_SUCCESS) { 1050 wpa_printf(MSG_DEBUG, "DPP: GAS query did not succeed"); 1051 goto fail; 1052 } 1053 1054 wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response adv_proto", 1055 adv_proto); 1056 wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response (GAS response)", 1057 resp); 1058 1059 if (wpabuf_len(adv_proto) != 10 || 1060 !(pos = wpabuf_head(adv_proto)) || 1061 pos[0] != WLAN_EID_ADV_PROTO || 1062 pos[1] != 8 || 1063 pos[3] != WLAN_EID_VENDOR_SPECIFIC || 1064 pos[4] != 5 || 1065 WPA_GET_BE24(&pos[5]) != OUI_WFA || 1066 pos[8] != 0x1a || 1067 pos[9] != 1) { 1068 wpa_printf(MSG_DEBUG, 1069 "DPP: Not a DPP Advertisement Protocol ID"); 1070 goto fail; 1071 } 1072 1073 if (dpp_conf_resp_rx(auth, resp) < 0) { 1074 wpa_printf(MSG_DEBUG, "DPP: Configuration attempt failed"); 1075 goto fail; 1076 } 1077 1078 wpas_dpp_handle_config_obj(wpa_s, auth); 1079 dpp_auth_deinit(wpa_s->dpp_auth); 1080 wpa_s->dpp_auth = NULL; 1081 return; 1082 1083 fail: 1084 wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_FAILED); 1085 dpp_auth_deinit(wpa_s->dpp_auth); 1086 wpa_s->dpp_auth = NULL; 1087 } 1088 1089 1090 static void wpas_dpp_start_gas_client(struct wpa_supplicant *wpa_s) 1091 { 1092 struct dpp_authentication *auth = wpa_s->dpp_auth; 1093 struct wpabuf *buf, *conf_req; 1094 char json[100]; 1095 int res; 1096 1097 wpa_s->dpp_gas_client = 1; 1098 os_snprintf(json, sizeof(json), 1099 "{\"name\":\"Test\"," 1100 "\"wi-fi_tech\":\"infra\"," 1101 "\"netRole\":\"%s\"}", 1102 wpa_s->dpp_netrole_ap ? "ap" : "sta"); 1103 wpa_printf(MSG_DEBUG, "DPP: GAS Config Attributes: %s", json); 1104 1105 offchannel_send_action_done(wpa_s); 1106 wpas_dpp_listen_stop(wpa_s); 1107 1108 conf_req = dpp_build_conf_req(auth, json); 1109 if (!conf_req) { 1110 wpa_printf(MSG_DEBUG, 1111 "DPP: No configuration request data available"); 1112 return; 1113 } 1114 1115 buf = gas_build_initial_req(0, 10 + 2 + wpabuf_len(conf_req)); 1116 if (!buf) { 1117 wpabuf_free(conf_req); 1118 return; 1119 } 1120 1121 /* Advertisement Protocol IE */ 1122 wpabuf_put_u8(buf, WLAN_EID_ADV_PROTO); 1123 wpabuf_put_u8(buf, 8); /* Length */ 1124 wpabuf_put_u8(buf, 0x7f); 1125 wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC); 1126 wpabuf_put_u8(buf, 5); 1127 wpabuf_put_be24(buf, OUI_WFA); 1128 wpabuf_put_u8(buf, DPP_OUI_TYPE); 1129 wpabuf_put_u8(buf, 0x01); 1130 1131 /* GAS Query */ 1132 wpabuf_put_le16(buf, wpabuf_len(conf_req)); 1133 wpabuf_put_buf(buf, conf_req); 1134 wpabuf_free(conf_req); 1135 1136 wpa_printf(MSG_DEBUG, "DPP: GAS request to " MACSTR " (freq %u MHz)", 1137 MAC2STR(auth->peer_mac_addr), auth->curr_freq); 1138 1139 res = gas_query_req(wpa_s->gas, auth->peer_mac_addr, auth->curr_freq, 1140 buf, wpas_dpp_gas_resp_cb, wpa_s); 1141 if (res < 0) { 1142 wpa_msg(wpa_s, MSG_DEBUG, "GAS: Failed to send Query Request"); 1143 wpabuf_free(buf); 1144 } else { 1145 wpa_printf(MSG_DEBUG, 1146 "DPP: GAS query started with dialog token %u", res); 1147 } 1148 } 1149 1150 1151 static void wpas_dpp_auth_success(struct wpa_supplicant *wpa_s, int initiator) 1152 { 1153 wpa_printf(MSG_DEBUG, "DPP: Authentication succeeded"); 1154 wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_AUTH_SUCCESS "init=%d", initiator); 1155 1156 if (wpa_s->dpp_auth->configurator) 1157 wpas_dpp_start_gas_server(wpa_s); 1158 else 1159 wpas_dpp_start_gas_client(wpa_s); 1160 } 1161 1162 1163 static void wpas_dpp_rx_auth_resp(struct wpa_supplicant *wpa_s, const u8 *src, 1164 const u8 *hdr, const u8 *buf, size_t len) 1165 { 1166 struct dpp_authentication *auth = wpa_s->dpp_auth; 1167 struct wpabuf *msg; 1168 1169 wpa_printf(MSG_DEBUG, "DPP: Authentication Response from " MACSTR, 1170 MAC2STR(src)); 1171 1172 if (!auth) { 1173 wpa_printf(MSG_DEBUG, 1174 "DPP: No DPP Authentication in progress - drop"); 1175 return; 1176 } 1177 1178 if (!is_zero_ether_addr(auth->peer_mac_addr) && 1179 os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) { 1180 wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected " 1181 MACSTR ") - drop", MAC2STR(auth->peer_mac_addr)); 1182 return; 1183 } 1184 1185 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL); 1186 1187 msg = dpp_auth_resp_rx(auth, hdr, buf, len); 1188 if (!msg) { 1189 if (auth->auth_resp_status == DPP_STATUS_RESPONSE_PENDING) { 1190 wpa_printf(MSG_DEBUG, 1191 "DPP: Start wait for full response"); 1192 offchannel_send_action_done(wpa_s); 1193 wpas_dpp_listen_start(wpa_s, auth->curr_freq); 1194 return; 1195 } 1196 wpa_printf(MSG_DEBUG, "DPP: No confirm generated"); 1197 return; 1198 } 1199 os_memcpy(auth->peer_mac_addr, src, ETH_ALEN); 1200 1201 offchannel_send_action(wpa_s, auth->curr_freq, 1202 src, wpa_s->own_addr, broadcast, 1203 wpabuf_head(msg), wpabuf_len(msg), 1204 500, wpas_dpp_tx_status, 0); 1205 wpabuf_free(msg); 1206 wpa_s->dpp_auth_ok_on_ack = 1; 1207 } 1208 1209 1210 static void wpas_dpp_rx_auth_conf(struct wpa_supplicant *wpa_s, const u8 *src, 1211 const u8 *hdr, const u8 *buf, size_t len) 1212 { 1213 struct dpp_authentication *auth = wpa_s->dpp_auth; 1214 1215 wpa_printf(MSG_DEBUG, "DPP: Authentication Confirmation from " MACSTR, 1216 MAC2STR(src)); 1217 1218 if (!auth) { 1219 wpa_printf(MSG_DEBUG, 1220 "DPP: No DPP Authentication in progress - drop"); 1221 return; 1222 } 1223 1224 if (os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) { 1225 wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected " 1226 MACSTR ") - drop", MAC2STR(auth->peer_mac_addr)); 1227 return; 1228 } 1229 1230 if (dpp_auth_conf_rx(auth, hdr, buf, len) < 0) { 1231 wpa_printf(MSG_DEBUG, "DPP: Authentication failed"); 1232 return; 1233 } 1234 1235 wpas_dpp_auth_success(wpa_s, 0); 1236 } 1237 1238 1239 static void wpas_dpp_rx_peer_disc_resp(struct wpa_supplicant *wpa_s, 1240 const u8 *src, 1241 const u8 *buf, size_t len) 1242 { 1243 struct wpa_ssid *ssid; 1244 const u8 *connector, *trans_id; 1245 u16 connector_len, trans_id_len; 1246 struct dpp_introduction intro; 1247 struct rsn_pmksa_cache_entry *entry; 1248 struct os_time now; 1249 struct os_reltime rnow; 1250 os_time_t expiry; 1251 unsigned int seconds; 1252 1253 wpa_printf(MSG_DEBUG, "DPP: Peer Discovery Response from " MACSTR, 1254 MAC2STR(src)); 1255 if (is_zero_ether_addr(wpa_s->dpp_intro_bssid) || 1256 os_memcmp(src, wpa_s->dpp_intro_bssid, ETH_ALEN) != 0) { 1257 wpa_printf(MSG_DEBUG, "DPP: Not waiting for response from " 1258 MACSTR " - drop", MAC2STR(src)); 1259 return; 1260 } 1261 offchannel_send_action_done(wpa_s); 1262 1263 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) { 1264 if (ssid == wpa_s->dpp_intro_network) 1265 break; 1266 } 1267 if (!ssid || !ssid->dpp_connector || !ssid->dpp_netaccesskey || 1268 !ssid->dpp_csign) { 1269 wpa_printf(MSG_DEBUG, 1270 "DPP: Profile not found for network introduction"); 1271 return; 1272 } 1273 1274 trans_id = dpp_get_attr(buf, len, DPP_ATTR_TRANSACTION_ID, 1275 &trans_id_len); 1276 if (!trans_id || trans_id_len != 1) { 1277 wpa_printf(MSG_DEBUG, 1278 "DPP: Peer did not include Transaction ID"); 1279 goto fail; 1280 } 1281 if (trans_id[0] != TRANSACTION_ID) { 1282 wpa_printf(MSG_DEBUG, 1283 "DPP: Ignore frame with unexpected Transaction ID %u", 1284 trans_id[0]); 1285 goto fail; 1286 } 1287 1288 connector = dpp_get_attr(buf, len, DPP_ATTR_CONNECTOR, &connector_len); 1289 if (!connector) { 1290 wpa_printf(MSG_DEBUG, 1291 "DPP: Peer did not include its Connector"); 1292 return; 1293 } 1294 1295 if (dpp_peer_intro(&intro, ssid->dpp_connector, 1296 ssid->dpp_netaccesskey, 1297 ssid->dpp_netaccesskey_len, 1298 ssid->dpp_csign, 1299 ssid->dpp_csign_len, 1300 connector, connector_len, &expiry) < 0) { 1301 wpa_printf(MSG_INFO, 1302 "DPP: Network Introduction protocol resulted in failure"); 1303 goto fail; 1304 } 1305 1306 entry = os_zalloc(sizeof(*entry)); 1307 if (!entry) 1308 goto fail; 1309 os_memcpy(entry->aa, src, ETH_ALEN); 1310 os_memcpy(entry->pmkid, intro.pmkid, PMKID_LEN); 1311 os_memcpy(entry->pmk, intro.pmk, intro.pmk_len); 1312 entry->pmk_len = intro.pmk_len; 1313 entry->akmp = WPA_KEY_MGMT_DPP; 1314 if (expiry) { 1315 os_get_time(&now); 1316 seconds = expiry - now.sec; 1317 } else { 1318 seconds = 86400 * 7; 1319 } 1320 os_get_reltime(&rnow); 1321 entry->expiration = rnow.sec + seconds; 1322 entry->reauth_time = rnow.sec + seconds; 1323 entry->network_ctx = ssid; 1324 wpa_sm_pmksa_cache_add_entry(wpa_s->wpa, entry); 1325 1326 wpa_printf(MSG_DEBUG, 1327 "DPP: Try connection again after successful network introduction"); 1328 if (wpa_supplicant_fast_associate(wpa_s) != 1) { 1329 wpa_supplicant_cancel_sched_scan(wpa_s); 1330 wpa_supplicant_req_scan(wpa_s, 0, 0); 1331 } 1332 fail: 1333 os_memset(&intro, 0, sizeof(intro)); 1334 } 1335 1336 1337 static void 1338 wpas_dpp_tx_pkex_status(struct wpa_supplicant *wpa_s, 1339 unsigned int freq, const u8 *dst, 1340 const u8 *src, const u8 *bssid, 1341 const u8 *data, size_t data_len, 1342 enum offchannel_send_action_result result) 1343 { 1344 wpa_printf(MSG_DEBUG, "DPP: TX status: freq=%u dst=" MACSTR 1345 " result=%s (PKEX)", 1346 freq, MAC2STR(dst), 1347 result == OFFCHANNEL_SEND_ACTION_SUCCESS ? "SUCCESS" : 1348 (result == OFFCHANNEL_SEND_ACTION_NO_ACK ? "no-ACK" : 1349 "FAILED")); 1350 /* TODO: Time out wait for response more quickly in error cases? */ 1351 } 1352 1353 1354 static void 1355 wpas_dpp_rx_pkex_exchange_req(struct wpa_supplicant *wpa_s, const u8 *src, 1356 const u8 *buf, size_t len, unsigned int freq) 1357 { 1358 struct wpabuf *msg; 1359 unsigned int wait_time; 1360 1361 wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Request from " MACSTR, 1362 MAC2STR(src)); 1363 1364 /* TODO: Support multiple PKEX codes by iterating over all the enabled 1365 * values here */ 1366 1367 if (!wpa_s->dpp_pkex_code || !wpa_s->dpp_pkex_bi) { 1368 wpa_printf(MSG_DEBUG, 1369 "DPP: No PKEX code configured - ignore request"); 1370 return; 1371 } 1372 1373 if (wpa_s->dpp_pkex) { 1374 /* TODO: Support parallel operations */ 1375 wpa_printf(MSG_DEBUG, 1376 "DPP: Already in PKEX session - ignore new request"); 1377 return; 1378 } 1379 1380 wpa_s->dpp_pkex = dpp_pkex_rx_exchange_req(wpa_s->dpp_pkex_bi, 1381 wpa_s->own_addr, src, 1382 wpa_s->dpp_pkex_identifier, 1383 wpa_s->dpp_pkex_code, 1384 buf, len); 1385 if (!wpa_s->dpp_pkex) { 1386 wpa_printf(MSG_DEBUG, 1387 "DPP: Failed to process the request - ignore it"); 1388 return; 1389 } 1390 1391 msg = wpa_s->dpp_pkex->exchange_resp; 1392 wait_time = wpa_s->max_remain_on_chan; 1393 if (wait_time > 2000) 1394 wait_time = 2000; 1395 offchannel_send_action(wpa_s, freq, src, wpa_s->own_addr, 1396 broadcast, 1397 wpabuf_head(msg), wpabuf_len(msg), 1398 wait_time, wpas_dpp_tx_pkex_status, 0); 1399 } 1400 1401 1402 static void 1403 wpas_dpp_rx_pkex_exchange_resp(struct wpa_supplicant *wpa_s, const u8 *src, 1404 const u8 *buf, size_t len, unsigned int freq) 1405 { 1406 struct wpabuf *msg; 1407 unsigned int wait_time; 1408 1409 wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Response from " MACSTR, 1410 MAC2STR(src)); 1411 1412 /* TODO: Support multiple PKEX codes by iterating over all the enabled 1413 * values here */ 1414 1415 if (!wpa_s->dpp_pkex || !wpa_s->dpp_pkex->initiator || 1416 wpa_s->dpp_pkex->exchange_done) { 1417 wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session"); 1418 return; 1419 } 1420 1421 os_memcpy(wpa_s->dpp_pkex->peer_mac, src, ETH_ALEN); 1422 msg = dpp_pkex_rx_exchange_resp(wpa_s->dpp_pkex, buf, len); 1423 if (!msg) { 1424 wpa_printf(MSG_DEBUG, "DPP: Failed to process the response"); 1425 return; 1426 } 1427 1428 wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Request to " MACSTR, 1429 MAC2STR(src)); 1430 1431 wait_time = wpa_s->max_remain_on_chan; 1432 if (wait_time > 2000) 1433 wait_time = 2000; 1434 offchannel_send_action(wpa_s, freq, src, wpa_s->own_addr, 1435 broadcast, 1436 wpabuf_head(msg), wpabuf_len(msg), 1437 wait_time, wpas_dpp_tx_pkex_status, 0); 1438 wpabuf_free(msg); 1439 } 1440 1441 1442 static void 1443 wpas_dpp_rx_pkex_commit_reveal_req(struct wpa_supplicant *wpa_s, const u8 *src, 1444 const u8 *hdr, const u8 *buf, size_t len, 1445 unsigned int freq) 1446 { 1447 struct wpabuf *msg; 1448 unsigned int wait_time; 1449 struct dpp_pkex *pkex = wpa_s->dpp_pkex; 1450 struct dpp_bootstrap_info *bi; 1451 1452 wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Request from " MACSTR, 1453 MAC2STR(src)); 1454 1455 if (!pkex || pkex->initiator || !pkex->exchange_done) { 1456 wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session"); 1457 return; 1458 } 1459 1460 msg = dpp_pkex_rx_commit_reveal_req(pkex, hdr, buf, len); 1461 if (!msg) { 1462 wpa_printf(MSG_DEBUG, "DPP: Failed to process the request"); 1463 return; 1464 } 1465 1466 wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Response to " 1467 MACSTR, MAC2STR(src)); 1468 1469 wait_time = wpa_s->max_remain_on_chan; 1470 if (wait_time > 2000) 1471 wait_time = 2000; 1472 offchannel_send_action(wpa_s, freq, src, wpa_s->own_addr, 1473 broadcast, 1474 wpabuf_head(msg), wpabuf_len(msg), 1475 wait_time, wpas_dpp_tx_pkex_status, 0); 1476 wpabuf_free(msg); 1477 1478 bi = os_zalloc(sizeof(*bi)); 1479 if (!bi) 1480 return; 1481 bi->id = wpas_dpp_next_id(wpa_s); 1482 bi->type = DPP_BOOTSTRAP_PKEX; 1483 os_memcpy(bi->mac_addr, src, ETH_ALEN); 1484 bi->num_freq = 1; 1485 bi->freq[0] = freq; 1486 bi->curve = pkex->own_bi->curve; 1487 bi->pubkey = pkex->peer_bootstrap_key; 1488 pkex->peer_bootstrap_key = NULL; 1489 dpp_pkex_free(pkex); 1490 wpa_s->dpp_pkex = NULL; 1491 if (dpp_bootstrap_key_hash(bi) < 0) { 1492 dpp_bootstrap_info_free(bi); 1493 return; 1494 } 1495 dl_list_add(&wpa_s->dpp_bootstrap, &bi->list); 1496 } 1497 1498 1499 static void 1500 wpas_dpp_rx_pkex_commit_reveal_resp(struct wpa_supplicant *wpa_s, const u8 *src, 1501 const u8 *hdr, const u8 *buf, size_t len, 1502 unsigned int freq) 1503 { 1504 int res; 1505 struct dpp_bootstrap_info *bi, *own_bi; 1506 struct dpp_pkex *pkex = wpa_s->dpp_pkex; 1507 char cmd[500]; 1508 1509 wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Response from " MACSTR, 1510 MAC2STR(src)); 1511 1512 if (!pkex || !pkex->initiator || !pkex->exchange_done) { 1513 wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session"); 1514 return; 1515 } 1516 1517 res = dpp_pkex_rx_commit_reveal_resp(pkex, hdr, buf, len); 1518 if (res < 0) { 1519 wpa_printf(MSG_DEBUG, "DPP: Failed to process the response"); 1520 return; 1521 } 1522 1523 own_bi = pkex->own_bi; 1524 1525 bi = os_zalloc(sizeof(*bi)); 1526 if (!bi) 1527 return; 1528 bi->id = wpas_dpp_next_id(wpa_s); 1529 bi->type = DPP_BOOTSTRAP_PKEX; 1530 os_memcpy(bi->mac_addr, src, ETH_ALEN); 1531 bi->num_freq = 1; 1532 bi->freq[0] = freq; 1533 bi->curve = own_bi->curve; 1534 bi->pubkey = pkex->peer_bootstrap_key; 1535 pkex->peer_bootstrap_key = NULL; 1536 dpp_pkex_free(pkex); 1537 wpa_s->dpp_pkex = NULL; 1538 if (dpp_bootstrap_key_hash(bi) < 0) { 1539 dpp_bootstrap_info_free(bi); 1540 return; 1541 } 1542 dl_list_add(&wpa_s->dpp_bootstrap, &bi->list); 1543 1544 os_snprintf(cmd, sizeof(cmd), " peer=%u %s", 1545 bi->id, 1546 wpa_s->dpp_pkex_auth_cmd ? wpa_s->dpp_pkex_auth_cmd : ""); 1547 wpa_printf(MSG_DEBUG, 1548 "DPP: Start authentication after PKEX with parameters: %s", 1549 cmd); 1550 if (wpas_dpp_auth_init(wpa_s, cmd) < 0) { 1551 wpa_printf(MSG_DEBUG, 1552 "DPP: Authentication initialization failed"); 1553 return; 1554 } 1555 } 1556 1557 1558 void wpas_dpp_rx_action(struct wpa_supplicant *wpa_s, const u8 *src, 1559 const u8 *buf, size_t len, unsigned int freq) 1560 { 1561 u8 crypto_suite; 1562 enum dpp_public_action_frame_type type; 1563 const u8 *hdr; 1564 1565 if (len < DPP_HDR_LEN) 1566 return; 1567 if (WPA_GET_BE24(buf) != OUI_WFA || buf[3] != DPP_OUI_TYPE) 1568 return; 1569 hdr = buf; 1570 buf += 4; 1571 len -= 4; 1572 crypto_suite = *buf++; 1573 type = *buf++; 1574 len -= 2; 1575 1576 wpa_printf(MSG_DEBUG, 1577 "DPP: Received DPP Public Action frame crypto suite %u type %d from " 1578 MACSTR " freq=%u", 1579 crypto_suite, type, MAC2STR(src), freq); 1580 if (crypto_suite != 1) { 1581 wpa_printf(MSG_DEBUG, "DPP: Unsupported crypto suite %u", 1582 crypto_suite); 1583 return; 1584 } 1585 wpa_hexdump(MSG_MSGDUMP, "DPP: Received message attributes", buf, len); 1586 if (dpp_check_attrs(buf, len) < 0) 1587 return; 1588 1589 switch (type) { 1590 case DPP_PA_AUTHENTICATION_REQ: 1591 wpas_dpp_rx_auth_req(wpa_s, src, hdr, buf, len, freq); 1592 break; 1593 case DPP_PA_AUTHENTICATION_RESP: 1594 wpas_dpp_rx_auth_resp(wpa_s, src, hdr, buf, len); 1595 break; 1596 case DPP_PA_AUTHENTICATION_CONF: 1597 wpas_dpp_rx_auth_conf(wpa_s, src, hdr, buf, len); 1598 break; 1599 case DPP_PA_PEER_DISCOVERY_RESP: 1600 wpas_dpp_rx_peer_disc_resp(wpa_s, src, buf, len); 1601 break; 1602 case DPP_PA_PKEX_EXCHANGE_REQ: 1603 wpas_dpp_rx_pkex_exchange_req(wpa_s, src, buf, len, freq); 1604 break; 1605 case DPP_PA_PKEX_EXCHANGE_RESP: 1606 wpas_dpp_rx_pkex_exchange_resp(wpa_s, src, buf, len, freq); 1607 break; 1608 case DPP_PA_PKEX_COMMIT_REVEAL_REQ: 1609 wpas_dpp_rx_pkex_commit_reveal_req(wpa_s, src, hdr, buf, len, 1610 freq); 1611 break; 1612 case DPP_PA_PKEX_COMMIT_REVEAL_RESP: 1613 wpas_dpp_rx_pkex_commit_reveal_resp(wpa_s, src, hdr, buf, len, 1614 freq); 1615 break; 1616 default: 1617 wpa_printf(MSG_DEBUG, 1618 "DPP: Ignored unsupported frame subtype %d", type); 1619 break; 1620 } 1621 } 1622 1623 1624 static struct wpabuf * 1625 wpas_dpp_gas_req_handler(void *ctx, const u8 *sa, const u8 *query, 1626 size_t query_len) 1627 { 1628 struct wpa_supplicant *wpa_s = ctx; 1629 struct dpp_authentication *auth = wpa_s->dpp_auth; 1630 struct wpabuf *resp; 1631 1632 wpa_printf(MSG_DEBUG, "DPP: GAS request from " MACSTR, 1633 MAC2STR(sa)); 1634 if (!auth || !auth->auth_success || 1635 os_memcmp(sa, auth->peer_mac_addr, ETH_ALEN) != 0) { 1636 wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress"); 1637 return NULL; 1638 } 1639 wpa_hexdump(MSG_DEBUG, 1640 "DPP: Received Configuration Request (GAS Query Request)", 1641 query, query_len); 1642 resp = dpp_conf_req_rx(auth, query, query_len); 1643 if (!resp) 1644 wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_FAILED); 1645 return resp; 1646 } 1647 1648 1649 static void 1650 wpas_dpp_gas_status_handler(void *ctx, struct wpabuf *resp, int ok) 1651 { 1652 struct wpa_supplicant *wpa_s = ctx; 1653 struct dpp_authentication *auth = wpa_s->dpp_auth; 1654 1655 if (!auth) { 1656 wpabuf_free(resp); 1657 return; 1658 } 1659 1660 wpa_printf(MSG_DEBUG, "DPP: Configuration exchange completed (ok=%d)", 1661 ok); 1662 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL); 1663 offchannel_send_action_done(wpa_s); 1664 wpas_dpp_listen_stop(wpa_s); 1665 if (ok) 1666 wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_SENT); 1667 else 1668 wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_FAILED); 1669 dpp_auth_deinit(wpa_s->dpp_auth); 1670 wpa_s->dpp_auth = NULL; 1671 wpabuf_free(resp); 1672 } 1673 1674 1675 static unsigned int wpas_dpp_next_configurator_id(struct wpa_supplicant *wpa_s) 1676 { 1677 struct dpp_configurator *conf; 1678 unsigned int max_id = 0; 1679 1680 dl_list_for_each(conf, &wpa_s->dpp_configurator, 1681 struct dpp_configurator, list) { 1682 if (conf->id > max_id) 1683 max_id = conf->id; 1684 } 1685 return max_id + 1; 1686 } 1687 1688 1689 int wpas_dpp_configurator_add(struct wpa_supplicant *wpa_s, const char *cmd) 1690 { 1691 char *curve = NULL; 1692 char *key = NULL; 1693 u8 *privkey = NULL; 1694 size_t privkey_len = 0; 1695 int ret = -1; 1696 struct dpp_configurator *conf = NULL; 1697 1698 curve = get_param(cmd, " curve="); 1699 key = get_param(cmd, " key="); 1700 1701 if (key) { 1702 privkey_len = os_strlen(key) / 2; 1703 privkey = os_malloc(privkey_len); 1704 if (!privkey || 1705 hexstr2bin(key, privkey, privkey_len) < 0) 1706 goto fail; 1707 } 1708 1709 conf = dpp_keygen_configurator(curve, privkey, privkey_len); 1710 if (!conf) 1711 goto fail; 1712 1713 conf->id = wpas_dpp_next_configurator_id(wpa_s); 1714 dl_list_add(&wpa_s->dpp_configurator, &conf->list); 1715 ret = conf->id; 1716 conf = NULL; 1717 fail: 1718 os_free(curve); 1719 str_clear_free(key); 1720 bin_clear_free(privkey, privkey_len); 1721 dpp_configurator_free(conf); 1722 return ret; 1723 } 1724 1725 1726 static int dpp_configurator_del(struct wpa_supplicant *wpa_s, unsigned int id) 1727 { 1728 struct dpp_configurator *conf, *tmp; 1729 int found = 0; 1730 1731 dl_list_for_each_safe(conf, tmp, &wpa_s->dpp_configurator, 1732 struct dpp_configurator, list) { 1733 if (id && conf->id != id) 1734 continue; 1735 found = 1; 1736 dl_list_del(&conf->list); 1737 dpp_configurator_free(conf); 1738 } 1739 1740 if (id == 0) 1741 return 0; /* flush succeeds regardless of entries found */ 1742 return found ? 0 : -1; 1743 } 1744 1745 1746 int wpas_dpp_configurator_remove(struct wpa_supplicant *wpa_s, const char *id) 1747 { 1748 unsigned int id_val; 1749 1750 if (os_strcmp(id, "*") == 0) { 1751 id_val = 0; 1752 } else { 1753 id_val = atoi(id); 1754 if (id_val == 0) 1755 return -1; 1756 } 1757 1758 return dpp_configurator_del(wpa_s, id_val); 1759 } 1760 1761 1762 int wpas_dpp_configurator_sign(struct wpa_supplicant *wpa_s, const char *cmd) 1763 { 1764 struct dpp_authentication *auth; 1765 int ret = -1; 1766 char *curve = NULL; 1767 1768 auth = os_zalloc(sizeof(*auth)); 1769 if (!auth) 1770 return -1; 1771 1772 curve = get_param(cmd, " curve="); 1773 wpas_dpp_set_configurator(wpa_s, auth, cmd); 1774 1775 if (dpp_configurator_own_config(auth, curve) == 0) { 1776 wpas_dpp_handle_config_obj(wpa_s, auth); 1777 ret = 0; 1778 } 1779 1780 dpp_auth_deinit(auth); 1781 os_free(curve); 1782 1783 return ret; 1784 } 1785 1786 1787 static void 1788 wpas_dpp_tx_introduction_status(struct wpa_supplicant *wpa_s, 1789 unsigned int freq, const u8 *dst, 1790 const u8 *src, const u8 *bssid, 1791 const u8 *data, size_t data_len, 1792 enum offchannel_send_action_result result) 1793 { 1794 wpa_printf(MSG_DEBUG, "DPP: TX status: freq=%u dst=" MACSTR 1795 " result=%s (DPP Peer Discovery Request)", 1796 freq, MAC2STR(dst), 1797 result == OFFCHANNEL_SEND_ACTION_SUCCESS ? "SUCCESS" : 1798 (result == OFFCHANNEL_SEND_ACTION_NO_ACK ? "no-ACK" : 1799 "FAILED")); 1800 /* TODO: Time out wait for response more quickly in error cases? */ 1801 } 1802 1803 1804 int wpas_dpp_check_connect(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, 1805 struct wpa_bss *bss) 1806 { 1807 struct os_time now; 1808 struct wpabuf *msg; 1809 unsigned int wait_time; 1810 1811 if (!(ssid->key_mgmt & WPA_KEY_MGMT_DPP) || !bss) 1812 return 0; /* Not using DPP AKM - continue */ 1813 if (wpa_sm_pmksa_exists(wpa_s->wpa, bss->bssid, ssid)) 1814 return 0; /* PMKSA exists for DPP AKM - continue */ 1815 1816 if (!ssid->dpp_connector || !ssid->dpp_netaccesskey || 1817 !ssid->dpp_csign) { 1818 wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_MISSING_CONNECTOR 1819 "missing %s", 1820 !ssid->dpp_connector ? "Connector" : 1821 (!ssid->dpp_netaccesskey ? "netAccessKey" : 1822 "C-sign-key")); 1823 return -1; 1824 } 1825 1826 os_get_time(&now); 1827 1828 if (ssid->dpp_netaccesskey_expiry && 1829 ssid->dpp_netaccesskey_expiry < now.sec) { 1830 wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_MISSING_CONNECTOR 1831 "netAccessKey expired"); 1832 return -1; 1833 } 1834 1835 wpa_printf(MSG_DEBUG, 1836 "DPP: Starting network introduction protocol to derive PMKSA for " 1837 MACSTR, MAC2STR(bss->bssid)); 1838 1839 msg = dpp_alloc_msg(DPP_PA_PEER_DISCOVERY_REQ, 1840 5 + 4 + os_strlen(ssid->dpp_connector)); 1841 if (!msg) 1842 return -1; 1843 1844 /* Transaction ID */ 1845 wpabuf_put_le16(msg, DPP_ATTR_TRANSACTION_ID); 1846 wpabuf_put_le16(msg, 1); 1847 wpabuf_put_u8(msg, TRANSACTION_ID); 1848 1849 /* DPP Connector */ 1850 wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR); 1851 wpabuf_put_le16(msg, os_strlen(ssid->dpp_connector)); 1852 wpabuf_put_str(msg, ssid->dpp_connector); 1853 1854 /* TODO: Timeout on AP response */ 1855 wait_time = wpa_s->max_remain_on_chan; 1856 if (wait_time > 2000) 1857 wait_time = 2000; 1858 offchannel_send_action(wpa_s, bss->freq, bss->bssid, wpa_s->own_addr, 1859 broadcast, 1860 wpabuf_head(msg), wpabuf_len(msg), 1861 wait_time, wpas_dpp_tx_introduction_status, 0); 1862 wpabuf_free(msg); 1863 1864 /* Request this connection attempt to terminate - new one will be 1865 * started when network introduction protocol completes */ 1866 os_memcpy(wpa_s->dpp_intro_bssid, bss->bssid, ETH_ALEN); 1867 wpa_s->dpp_intro_network = ssid; 1868 return 1; 1869 } 1870 1871 1872 int wpas_dpp_pkex_add(struct wpa_supplicant *wpa_s, const char *cmd) 1873 { 1874 struct dpp_bootstrap_info *own_bi; 1875 const char *pos, *end; 1876 unsigned int wait_time; 1877 1878 pos = os_strstr(cmd, " own="); 1879 if (!pos) 1880 return -1; 1881 pos += 5; 1882 own_bi = dpp_bootstrap_get_id(wpa_s, atoi(pos)); 1883 if (!own_bi) { 1884 wpa_printf(MSG_DEBUG, 1885 "DPP: Identified bootstrap info not found"); 1886 return -1; 1887 } 1888 if (own_bi->type != DPP_BOOTSTRAP_PKEX) { 1889 wpa_printf(MSG_DEBUG, 1890 "DPP: Identified bootstrap info not for PKEX"); 1891 return -1; 1892 } 1893 wpa_s->dpp_pkex_bi = own_bi; 1894 1895 os_free(wpa_s->dpp_pkex_identifier); 1896 wpa_s->dpp_pkex_identifier = NULL; 1897 pos = os_strstr(cmd, " identifier="); 1898 if (pos) { 1899 pos += 12; 1900 end = os_strchr(pos, ' '); 1901 if (!end) 1902 return -1; 1903 wpa_s->dpp_pkex_identifier = os_malloc(end - pos + 1); 1904 if (!wpa_s->dpp_pkex_identifier) 1905 return -1; 1906 os_memcpy(wpa_s->dpp_pkex_identifier, pos, end - pos); 1907 wpa_s->dpp_pkex_identifier[end - pos] = '\0'; 1908 } 1909 1910 pos = os_strstr(cmd, " code="); 1911 if (!pos) 1912 return -1; 1913 os_free(wpa_s->dpp_pkex_code); 1914 wpa_s->dpp_pkex_code = os_strdup(pos + 6); 1915 if (!wpa_s->dpp_pkex_code) 1916 return -1; 1917 1918 if (os_strstr(cmd, " init=1")) { 1919 struct wpabuf *msg; 1920 1921 wpa_printf(MSG_DEBUG, "DPP: Initiating PKEX"); 1922 dpp_pkex_free(wpa_s->dpp_pkex); 1923 wpa_s->dpp_pkex = dpp_pkex_init(own_bi, wpa_s->own_addr, 1924 wpa_s->dpp_pkex_identifier, 1925 wpa_s->dpp_pkex_code); 1926 if (!wpa_s->dpp_pkex) 1927 return -1; 1928 1929 msg = wpa_s->dpp_pkex->exchange_req; 1930 wait_time = wpa_s->max_remain_on_chan; 1931 if (wait_time > 2000) 1932 wait_time = 2000; 1933 /* TODO: Which channel to use? */ 1934 offchannel_send_action(wpa_s, 2437, broadcast, wpa_s->own_addr, 1935 broadcast, 1936 wpabuf_head(msg), wpabuf_len(msg), 1937 wait_time, wpas_dpp_tx_pkex_status, 0); 1938 } 1939 1940 /* TODO: Support multiple PKEX info entries */ 1941 1942 os_free(wpa_s->dpp_pkex_auth_cmd); 1943 wpa_s->dpp_pkex_auth_cmd = os_strdup(cmd); 1944 1945 return 1; 1946 } 1947 1948 1949 int wpas_dpp_pkex_remove(struct wpa_supplicant *wpa_s, const char *id) 1950 { 1951 unsigned int id_val; 1952 1953 if (os_strcmp(id, "*") == 0) { 1954 id_val = 0; 1955 } else { 1956 id_val = atoi(id); 1957 if (id_val == 0) 1958 return -1; 1959 } 1960 1961 if ((id_val != 0 && id_val != 1) || !wpa_s->dpp_pkex_code) 1962 return -1; 1963 1964 /* TODO: Support multiple PKEX entries */ 1965 os_free(wpa_s->dpp_pkex_code); 1966 wpa_s->dpp_pkex_code = NULL; 1967 os_free(wpa_s->dpp_pkex_identifier); 1968 wpa_s->dpp_pkex_identifier = NULL; 1969 os_free(wpa_s->dpp_pkex_auth_cmd); 1970 wpa_s->dpp_pkex_auth_cmd = NULL; 1971 wpa_s->dpp_pkex_bi = NULL; 1972 /* TODO: Remove dpp_pkex only if it is for the identified PKEX code */ 1973 dpp_pkex_free(wpa_s->dpp_pkex); 1974 wpa_s->dpp_pkex = NULL; 1975 return 0; 1976 } 1977 1978 1979 int wpas_dpp_init(struct wpa_supplicant *wpa_s) 1980 { 1981 u8 adv_proto_id[7]; 1982 1983 adv_proto_id[0] = WLAN_EID_VENDOR_SPECIFIC; 1984 adv_proto_id[1] = 5; 1985 WPA_PUT_BE24(&adv_proto_id[2], OUI_WFA); 1986 adv_proto_id[5] = DPP_OUI_TYPE; 1987 adv_proto_id[6] = 0x01; 1988 1989 if (gas_server_register(wpa_s->gas_server, adv_proto_id, 1990 sizeof(adv_proto_id), wpas_dpp_gas_req_handler, 1991 wpas_dpp_gas_status_handler, wpa_s) < 0) 1992 return -1; 1993 dl_list_init(&wpa_s->dpp_bootstrap); 1994 dl_list_init(&wpa_s->dpp_configurator); 1995 wpa_s->dpp_init_done = 1; 1996 return 0; 1997 } 1998 1999 2000 void wpas_dpp_deinit(struct wpa_supplicant *wpa_s) 2001 { 2002 #ifdef CONFIG_TESTING_OPTIONS 2003 os_free(wpa_s->dpp_config_obj_override); 2004 wpa_s->dpp_config_obj_override = NULL; 2005 os_free(wpa_s->dpp_discovery_override); 2006 wpa_s->dpp_discovery_override = NULL; 2007 os_free(wpa_s->dpp_groups_override); 2008 wpa_s->dpp_groups_override = NULL; 2009 wpa_s->dpp_ignore_netaccesskey_mismatch = 0; 2010 #endif /* CONFIG_TESTING_OPTIONS */ 2011 if (!wpa_s->dpp_init_done) 2012 return; 2013 eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL); 2014 offchannel_send_action_done(wpa_s); 2015 wpas_dpp_listen_stop(wpa_s); 2016 dpp_bootstrap_del(wpa_s, 0); 2017 dpp_configurator_del(wpa_s, 0); 2018 dpp_auth_deinit(wpa_s->dpp_auth); 2019 wpa_s->dpp_auth = NULL; 2020 wpas_dpp_pkex_remove(wpa_s, "*"); 2021 wpa_s->dpp_pkex = NULL; 2022 os_memset(wpa_s->dpp_intro_bssid, 0, ETH_ALEN); 2023 os_free(wpa_s->dpp_configurator_params); 2024 wpa_s->dpp_configurator_params = NULL; 2025 } 2026