1 /* 2 * Sigma Control API DUT (station/AP/sniffer) 3 * Copyright (c) 2017, Qualcomm Atheros, Inc. 4 * Copyright (c) 2018-2020, The Linux Foundation 5 * All Rights Reserved. 6 * Licensed under the Clear BSD license. See README for more details. 7 */ 8 9 #include "sigma_dut.h" 10 #include <sys/wait.h> 11 #include "wpa_ctrl.h" 12 #include "wpa_helpers.h" 13 14 extern char *sigma_wpas_ctrl; 15 16 #ifdef ANDROID 17 char *dpp_qrcode_file = "/sdcard/wpadebug_qrdata.txt"; 18 #endif /* ANDROID */ 19 20 21 static int sigma_dut_is_ap(struct sigma_dut *dut) 22 { 23 return dut->device_type == AP_unknown || 24 dut->device_type == AP_testbed || 25 dut->device_type == AP_dut; 26 } 27 28 29 static int dpp_hostapd_run(struct sigma_dut *dut) 30 { 31 if (dut->hostapd_running) 32 return 0; 33 34 sigma_dut_print(dut, DUT_MSG_INFO, 35 "Starting hostapd in unconfigured state for DPP"); 36 snprintf(dut->ap_ssid, sizeof(dut->ap_ssid), "unconfigured"); 37 if (!dut->ap_oper_chn) 38 dut->ap_channel = 11; 39 dut->ap_is_dual = 0; 40 dut->ap_mode = dut->ap_channel <= 14 ? AP_11ng : AP_11na; 41 dut->ap_key_mgmt = AP_OPEN; 42 dut->ap_cipher = AP_PLAIN; 43 if (!dut->ap_dpp_conf_addr || !dut->ap_dpp_conf_pkhash) 44 dut->ap_start_disabled = 1; 45 return cmd_ap_config_commit(dut, NULL, NULL) == 1 ? 0 : -1; 46 } 47 48 49 static int dpp_hostapd_beacon(struct sigma_dut *dut) 50 { 51 const char *ifname = dut->hostapd_ifname; 52 53 if (!dut->ap_start_disabled) 54 return 0; 55 56 if (!ifname || 57 wpa_command(ifname, "SET start_disabled 0") < 0 || 58 wpa_command(ifname, "DISABLE") < 0 || 59 wpa_command(ifname, "ENABLE") < 0) 60 return -1; 61 62 dut->ap_start_disabled = 0; 63 return 0; 64 } 65 66 67 static const char * dpp_get_curve(struct sigma_cmd *cmd, const char *arg) 68 { 69 const char *val = get_param(cmd, arg); 70 71 if (!val) 72 val = "P-256"; 73 else if (strcasecmp(val, "BP-256R1") == 0) 74 val = "BP-256"; 75 else if (strcasecmp(val, "BP-384R1") == 0) 76 val = "BP-384"; 77 else if (strcasecmp(val, "BP-512R1") == 0) 78 val = "BP-512"; 79 80 return val; 81 } 82 83 84 static enum sigma_cmd_result 85 dpp_get_local_bootstrap(struct sigma_dut *dut, struct sigma_conn *conn, 86 struct sigma_cmd *cmd, int send_result, int *success) 87 { 88 const char *curve = dpp_get_curve(cmd, "DPPCryptoIdentifier"); 89 const char *bs = get_param(cmd, "DPPBS"); 90 const char *chan_list = get_param(cmd, "DPPChannelList"); 91 char *pos, mac[50], buf[200], resp[1000], hex[2000]; 92 const char *ifname = get_station_ifname(dut); 93 int res; 94 const char *type; 95 96 if (success) 97 *success = 0; 98 if (strcasecmp(bs, "QR") == 0) { 99 type = "qrcode"; 100 } else if (strcasecmp(bs, "NFC") == 0) { 101 type ="nfc-uri"; 102 } else { 103 send_resp(dut, conn, SIGMA_ERROR, 104 "errorCode,Unsupported DPPBS"); 105 return STATUS_SENT_ERROR; 106 } 107 108 if (sigma_dut_is_ap(dut)) { 109 u8 bssid[ETH_ALEN]; 110 111 if (!dut->hostapd_ifname) { 112 sigma_dut_print(dut, DUT_MSG_ERROR, 113 "hostapd ifname not specified (-j)"); 114 return ERROR_SEND_STATUS; 115 } 116 ifname = dut->hostapd_ifname; 117 if (get_hwaddr(dut->hostapd_ifname, bssid) < 0) { 118 sigma_dut_print(dut, DUT_MSG_ERROR, 119 "Could not get MAC address for %s", 120 dut->hostapd_ifname); 121 return ERROR_SEND_STATUS; 122 } 123 snprintf(mac, sizeof(mac), "%02x%02x%02x%02x%02x%02x", 124 bssid[0], bssid[1], bssid[2], 125 bssid[3], bssid[4], bssid[5]); 126 } else { 127 if (get_wpa_status(ifname, "address", mac, sizeof(mac)) < 0) { 128 send_resp(dut, conn, SIGMA_ERROR, 129 "errorCode,Failed to get own MAC address from wpa_supplicant"); 130 return STATUS_SENT_ERROR; 131 } 132 } 133 134 pos = mac; 135 while (*pos) { 136 if (*pos == ':') 137 memmove(pos, pos + 1, strlen(pos)); 138 else 139 pos++; 140 } 141 142 if (sigma_dut_is_ap(dut) && dpp_hostapd_run(dut) < 0) { 143 send_resp(dut, conn, SIGMA_ERROR, 144 "errorCode,Failed to start hostapd"); 145 return STATUS_SENT_ERROR; 146 } 147 148 if (chan_list && 149 (strcmp(chan_list, "0/0") == 0 || chan_list[0] == '\0')) { 150 /* No channel list */ 151 res = snprintf(buf, sizeof(buf), 152 "DPP_BOOTSTRAP_GEN type=%s curve=%s mac=%s", 153 type, curve, mac); 154 } else if (chan_list) { 155 /* Channel list override (CTT case) - space separated tuple(s) 156 * of OperatingClass/Channel; convert to wpa_supplicant/hostapd 157 * format: comma separated tuples */ 158 strlcpy(resp, chan_list, sizeof(resp)); 159 for (pos = resp; *pos; pos++) { 160 if (*pos == ' ') 161 *pos = ','; 162 } 163 res = snprintf(buf, sizeof(buf), 164 "DPP_BOOTSTRAP_GEN type=%s curve=%s chan=%s mac=%s", 165 type, curve, resp, mac); 166 } else { 167 int channel = 11; 168 169 /* Default channel list (normal DUT case) */ 170 if (sigma_dut_is_ap(dut) && dut->hostapd_running && 171 dut->ap_oper_chn && 172 dut->ap_channel > 0 && dut->ap_channel <= 13) 173 channel = dut->ap_channel; 174 res = snprintf(buf, sizeof(buf), 175 "DPP_BOOTSTRAP_GEN type=%s curve=%s chan=81/%d mac=%s", 176 type, curve, channel, mac); 177 } 178 179 if (res < 0 || res >= sizeof(buf) || 180 wpa_command_resp(ifname, buf, resp, sizeof(resp)) < 0 || 181 strncmp(resp, "FAIL", 4) == 0) 182 return ERROR_SEND_STATUS; 183 dut->dpp_local_bootstrap = atoi(resp); 184 snprintf(buf, sizeof(buf), "DPP_BOOTSTRAP_GET_URI %d", 185 atoi(resp)); 186 if (wpa_command_resp(ifname, buf, resp, sizeof(resp)) < 0 || 187 strncmp(resp, "FAIL", 4) == 0) 188 return ERROR_SEND_STATUS; 189 190 sigma_dut_print(dut, DUT_MSG_DEBUG, "URI: %s", resp); 191 192 if (send_result) { 193 ascii2hexstr(resp, hex); 194 res = snprintf(resp, sizeof(resp), "BootstrappingData,%s", hex); 195 send_resp(dut, conn, SIGMA_COMPLETE, 196 res >= 0 && res < sizeof(resp) ? resp : NULL); 197 } 198 199 if (success) 200 *success = 1; 201 return STATUS_SENT; 202 } 203 204 205 static enum sigma_cmd_result dpp_set_peer_bootstrap(struct sigma_dut *dut, 206 struct sigma_conn *conn, 207 struct sigma_cmd *cmd) 208 { 209 const char *val = get_param(cmd, "DPPBootstrappingdata"); 210 char uri[1000]; 211 int res; 212 213 if (!val) { 214 send_resp(dut, conn, SIGMA_ERROR, 215 "errorCode,Missing DPPBootstrappingdata"); 216 return STATUS_SENT_ERROR; 217 } 218 219 res = parse_hexstr(val, (unsigned char *) uri, sizeof(uri)); 220 if (res < 0 || (size_t) res >= sizeof(uri)) 221 return ERROR_SEND_STATUS; 222 uri[res] = '\0'; 223 sigma_dut_print(dut, DUT_MSG_DEBUG, "URI: %s", uri); 224 free(dut->dpp_peer_uri); 225 dut->dpp_peer_uri = strdup(uri); 226 227 return SUCCESS_SEND_STATUS; 228 } 229 230 231 static int dpp_hostapd_conf_update(struct sigma_dut *dut, 232 struct sigma_conn *conn, const char *ifname, 233 struct wpa_ctrl *ctrl) 234 { 235 int res; 236 char buf[2000], buf2[2500], *pos, *pos2; 237 const char *conf_data_events[] = { 238 "DPP-CONNECTOR", 239 "DPP-CONFOBJ-PASS", 240 "DPP-CONFOBJ-PSK", 241 "DPP-C-SIGN-KEY", 242 "DPP-NET-ACCESS-KEY", 243 NULL 244 }; 245 unsigned int old_timeout; 246 int legacy_akm, dpp_akm; 247 char *connector = NULL, *psk = NULL, *csign = NULL, 248 *net_access_key = NULL; 249 char pass[64]; 250 int pass_len = 0; 251 int ret = 0; 252 253 sigma_dut_print(dut, DUT_MSG_INFO, 254 "Update hostapd configuration based on DPP Config Object"); 255 256 if (wpa_command(ifname, "SET wpa 2") < 0 || 257 wpa_command(ifname, "SET wpa_key_mgmt DPP") < 0 || 258 wpa_command(ifname, "SET ieee80211w 1") < 0 || 259 wpa_command(ifname, "SET rsn_pairwise CCMP") < 0) { 260 send_resp(dut, conn, SIGMA_ERROR, 261 "errorCode,Failed to update AP security parameters"); 262 goto out; 263 } 264 265 res = get_wpa_cli_event(dut, ctrl, "DPP-CONFOBJ-AKM", buf, sizeof(buf)); 266 if (res < 0) { 267 send_resp(dut, conn, SIGMA_ERROR, 268 "errorCode,No DPP-CONFOBJ-AKM"); 269 goto out; 270 } 271 pos = strchr(buf, ' '); 272 if (!pos) 273 return -2; 274 pos++; 275 sigma_dut_print(dut, DUT_MSG_INFO, 276 "DPP: Config Object AKM: %s", pos); 277 legacy_akm = strstr(pos, "psk") != NULL || strstr(pos, "sae") != NULL; 278 dpp_akm = strstr(pos, "dpp") != NULL; 279 280 res = get_wpa_cli_event(dut, ctrl, "DPP-CONFOBJ-SSID", 281 buf, sizeof(buf)); 282 if (res < 0) { 283 send_resp(dut, conn, SIGMA_ERROR, 284 "errorCode,No DPP-CONFOBJ-SSID"); 285 goto out; 286 } 287 pos = strchr(buf, ' '); 288 if (!pos) 289 return -2; 290 pos++; 291 sigma_dut_print(dut, DUT_MSG_INFO, 292 "DPP: Config Object SSID: %s", pos); 293 snprintf(buf2, sizeof(buf2), "SET ssid %s", pos); 294 if (wpa_command(ifname, buf2) < 0) { 295 send_resp(dut, conn, SIGMA_ERROR, 296 "errorCode,Failed to update AP SSID"); 297 goto out; 298 } 299 300 if (wpa_command(ifname, "SET utf8_ssid 1") < 0) { 301 send_resp(dut, conn, SIGMA_ERROR, 302 "errorCode,Failed to update AP UTF-8 SSID capa"); 303 goto out; 304 } 305 306 while ((dpp_akm && (!connector || !csign || !net_access_key)) || 307 (legacy_akm && !pass_len && !psk)) { 308 res = get_wpa_cli_events(dut, ctrl, conf_data_events, 309 buf, sizeof(buf)); 310 if (res < 0) { 311 send_resp(dut, conn, SIGMA_ERROR, 312 "errorCode,Not all config object information received"); 313 goto out; 314 } 315 316 if (strstr(buf, "DPP-CONNECTOR")) { 317 pos = strchr(buf, ' '); 318 if (!pos) { 319 ret = -2; 320 goto out; 321 } 322 pos++; 323 sigma_dut_print(dut, DUT_MSG_INFO, "DPP: Connector: %s", 324 pos); 325 if (!connector) 326 connector = strdup(pos); 327 } else if (strstr(buf, "DPP-C-SIGN-KEY")) { 328 pos = strchr(buf, ' '); 329 if (!pos) { 330 ret = -2; 331 goto out; 332 } 333 pos++; 334 sigma_dut_print(dut, DUT_MSG_INFO, 335 "DPP: C-sign-key: %s", pos); 336 if (!csign) 337 csign = strdup(pos); 338 } else if (strstr(buf, "DPP-NET-ACCESS-KEY")) { 339 pos = strchr(buf, ' '); 340 if (!pos) { 341 ret = -2; 342 goto out; 343 } 344 pos++; 345 if (!net_access_key) 346 net_access_key = strdup(pos); 347 } else if (strstr(buf, "DPP-CONFOBJ-PASS")) { 348 pos = strchr(buf, ' '); 349 if (!pos) { 350 ret = -2; 351 goto out; 352 } 353 pos++; 354 pass_len = parse_hexstr(pos, (u8 *) pass, sizeof(pass)); 355 if (pass_len < 0 || (size_t) pass_len >= sizeof(pass)) { 356 ret = -2; 357 goto out; 358 } 359 pass[pass_len] = '\0'; 360 sigma_dut_print(dut, DUT_MSG_INFO, 361 "DPP: Passphrase: %s", pass); 362 } else if (strstr(buf, "DPP-CONFOBJ-PSK")) { 363 pos = strchr(buf, ' '); 364 if (!pos) { 365 ret = -2; 366 goto out; 367 } 368 pos++; 369 sigma_dut_print(dut, DUT_MSG_INFO, "DPP: PSK: %s", pos); 370 if (!psk) 371 psk = strdup(pos); 372 } 373 } 374 375 if ((!connector || !dpp_akm) && 376 wpa_command(ifname, "SET wpa_key_mgmt WPA-PSK") < 0) { 377 send_resp(dut, conn, SIGMA_ERROR, 378 "errorCode,Failed to update AP security parameters"); 379 goto out; 380 } 381 382 if (connector && dpp_akm && legacy_akm && 383 wpa_command(ifname, "SET wpa_key_mgmt DPP WPA-PSK") < 0) { 384 send_resp(dut, conn, SIGMA_ERROR, 385 "errorCode,Failed to update AP security parameters"); 386 goto out; 387 } 388 389 if (pass_len) { 390 snprintf(buf2, sizeof(buf2), "SET wpa_passphrase %s", 391 pass); 392 if (wpa_command(ifname, buf2) < 0) { 393 send_resp(dut, conn, SIGMA_ERROR, 394 "errorCode,Failed to set passphrase"); 395 goto out; 396 } 397 } else if (psk) { 398 snprintf(buf2, sizeof(buf2), "SET wpa_psk %s", psk); 399 if (wpa_command(ifname, buf2) < 0) { 400 send_resp(dut, conn, SIGMA_ERROR, 401 "errorCode,Failed to set PSK"); 402 goto out; 403 } 404 } 405 406 if (connector) { 407 snprintf(buf2, sizeof(buf2), "SET dpp_connector %s", connector); 408 if (wpa_command(ifname, buf2) < 0) { 409 send_resp(dut, conn, SIGMA_ERROR, 410 "errorCode,Failed to update AP Connector"); 411 goto out; 412 } 413 } 414 415 if (csign) { 416 snprintf(buf2, sizeof(buf2), "SET dpp_csign %s", csign); 417 if (wpa_command(ifname, buf2) < 0) { 418 send_resp(dut, conn, SIGMA_ERROR, 419 "errorCode,Failed to update AP C-sign-key"); 420 goto out; 421 } 422 } 423 424 if (net_access_key) { 425 pos2 = strchr(net_access_key, ' '); 426 if (pos2) 427 *pos2++ = '\0'; 428 sigma_dut_print(dut, DUT_MSG_INFO, "DPP: netAccessKey: %s", 429 net_access_key); 430 snprintf(buf2, sizeof(buf2), "SET dpp_netaccesskey %s", 431 net_access_key); 432 if (wpa_command(ifname, buf2) < 0) { 433 send_resp(dut, conn, SIGMA_ERROR, 434 "errorCode,Failed to update AP netAccessKey"); 435 goto out; 436 } 437 if (pos2) { 438 sigma_dut_print(dut, DUT_MSG_INFO, 439 "DPP: netAccessKey expiry: %s", pos2); 440 snprintf(buf2, sizeof(buf2), 441 "SET dpp_netaccesskey_expiry %s", pos2); 442 if (wpa_command(ifname, buf2) < 0) { 443 send_resp(dut, conn, SIGMA_ERROR, 444 "errorCode,Failed to update AP netAccessKey expiry"); 445 goto out; 446 } 447 } 448 } 449 450 if (wpa_command(ifname, "SET start_disabled 0") < 0 && 451 dut->ap_start_disabled) { 452 send_resp(dut, conn, SIGMA_ERROR, 453 "errorCode,Failed to update AP security parameters"); 454 goto out; 455 } 456 dut->ap_start_disabled = 0; 457 458 /* Wait for a possible Configuration Result to be sent */ 459 old_timeout = dut->default_timeout; 460 dut->default_timeout = 1; 461 get_wpa_cli_event(dut, ctrl, "DPP-TX-STATUS", buf, sizeof(buf)); 462 dut->default_timeout = old_timeout; 463 if (wpa_command(ifname, "DISABLE") < 0 || 464 wpa_command(ifname, "ENABLE") < 0) { 465 send_resp(dut, conn, SIGMA_ERROR, 466 "errorCode,Failed to update AP configuration"); 467 goto out; 468 } 469 470 res = get_wpa_cli_event(dut, ctrl, "AP-ENABLED", buf, sizeof(buf)); 471 if (res < 0) { 472 send_resp(dut, conn, SIGMA_ERROR, "errorCode,No AP-ENABLED"); 473 goto out; 474 } 475 476 ret = 1; 477 out: 478 free(connector); 479 free(psk); 480 free(csign); 481 free(net_access_key); 482 return ret; 483 } 484 485 486 struct dpp_test_info { 487 const char *step; 488 const char *frame; 489 const char *attr; 490 int value; 491 }; 492 493 static const struct dpp_test_info dpp_tests[] = { 494 { "InvalidValue", "AuthenticationRequest", "WrappedData", 1 }, 495 { "InvalidValue", "AuthenticationResponse", "WrappedData", 2 }, 496 { "InvalidValue", "AuthenticationResponse", "PrimaryWrappedData", 2 }, 497 { "InvalidValue", "AuthenticationConfirm", "WrappedData", 3 }, 498 { "InvalidValue", "PKEXCRRequest", "WrappedData", 4 }, 499 { "InvalidValue", "PKEXCRResponse", "WrappedData", 5 }, 500 { "InvalidValue", "ConfigurationRequest", "WrappedData", 6 }, 501 { "InvalidValue", "ConfigurationResponse", "WrappedData", 7 }, 502 { "InvalidValue", "AuthenticationRequest", "InitCapabilities", 8 }, 503 { "MissingAttribute", "AuthenticationRequest", "RespBSKeyHash", 10 }, 504 { "MissingAttribute", "AuthenticationRequest", "InitBSKeyHash", 11 }, 505 { "MissingAttribute", "AuthenticationRequest", "InitProtocolKey", 12 }, 506 { "MissingAttribute", "AuthenticationRequest", "InitNonce", 13 }, 507 { "MissingAttribute", "AuthenticationRequest", "InitCapabilities", 14 }, 508 { "MissingAttribute", "AuthenticationRequest", "WrappedData", 15 }, 509 { "MissingAttribute", "AuthenticationResponse", "DPPStatus", 16 }, 510 { "MissingAttribute", "AuthenticationResponse", "RespBSKeyHash", 17 }, 511 { "MissingAttribute", "AuthenticationResponse", "InitBSKeyHash", 18 }, 512 { "MissingAttribute", "AuthenticationResponse", "RespProtocolKey", 19 }, 513 { "MissingAttribute", "AuthenticationResponse", "RespNonce", 20 }, 514 { "MissingAttribute", "AuthenticationResponse", "InitNonce", 21 }, 515 { "MissingAttribute", "AuthenticationResponse", "RespCapabilities", 516 22 }, 517 { "MissingAttribute", "AuthenticationResponse", "RespAuthTag", 23 }, 518 { "MissingAttribute", "AuthenticationResponse", "WrappedData", 24 }, 519 { "MissingAttribute", "AuthenticationResponse", "PrimaryWrappedData", 520 24 }, 521 { "MissingAttribute", "AuthenticationConfirm", "DPPStatus", 25 }, 522 { "MissingAttribute", "AuthenticationConfirm", "RespBSKeyHash", 26 }, 523 { "MissingAttribute", "AuthenticationConfirm", "InitBSKeyHash", 27 }, 524 { "MissingAttribute", "AuthenticationConfirm", "InitAuthTag", 28 }, 525 { "MissingAttribute", "AuthenticationConfirm", "WrappedData", 29 }, 526 { "InvalidValue", "AuthenticationResponse", "InitNonce", 30 }, 527 { "InvalidValue", "AuthenticationResponse", "RespCapabilities", 31 }, 528 { "InvalidValue", "AuthenticationResponse", "RespAuthTag", 32 }, 529 { "InvalidValue", "AuthenticationConfirm", "InitAuthTag", 33 }, 530 { "MissingAttribute", "PKEXExchangeRequest", "FiniteCyclicGroup", 34 }, 531 { "MissingAttribute", "PKEXExchangeRequest", "EncryptedKey", 35 }, 532 { "MissingAttribute", "PKEXExchangeResponse", "DPPStatus", 36 }, 533 { "MissingAttribute", "PKEXExchangeResponse", "EncryptedKey", 37 }, 534 { "MissingAttribute", "PKEXCRRequest", "BSKey", 38 }, 535 { "MissingAttribute", "PKEXCRRequest", "InitAuthTag", 39 }, 536 { "MissingAttribute", "PKEXCRRequest", "WrappedData", 40 }, 537 { "MissingAttribute", "PKEXCRResponse", "BSKey", 41 }, 538 { "MissingAttribute", "PKEXCRResponse", "RespAuthTag", 42 }, 539 { "MissingAttribute", "PKEXCRResponse", "WrappedData", 43 }, 540 { "InvalidValue", "PKEXExchangeRequest", "EncryptedKey", 44 }, 541 { "InvalidValue", "PKEXExchangeResponse", "EncryptedKey", 45 }, 542 { "InvalidValue", "PKEXExchangeResponse", "DPPStatus", 46 }, 543 { "InvalidValue", "PKEXCRRequest", "BSKey", 47 }, 544 { "InvalidValue", "PKEXCRResponse", "BSKey", 48 }, 545 { "InvalidValue", "PKEXCRRequest", "InitAuthTag", 49 }, 546 { "InvalidValue", "PKEXCRResponse", "RespAuthTag", 50 }, 547 { "MissingAttribute", "ConfigurationRequest", "EnrolleeNonce", 51 }, 548 { "MissingAttribute", "ConfigurationRequest", "ConfigAttr", 52 }, 549 { "MissingAttribute", "ConfigurationRequest", "WrappedData", 53 }, 550 { "MissingAttribute", "ConfigurationResponse", "EnrolleeNonce", 54 }, 551 { "MissingAttribute", "ConfigurationResponse", "ConfigObj", 55 }, 552 { "MissingAttribute", "ConfigurationResponse", "DPPStatus", 56 }, 553 { "MissingAttribute", "ConfigurationResponse", "WrappedData", 57 }, 554 { "InvalidValue", "ConfigurationResponse", "DPPStatus", 58 }, 555 { "InvalidValue", "ConfigurationResponse", "EnrolleeNonce", 59 }, 556 { "MissingAttribute", "PeerDiscoveryRequest", "TransactionID", 60 }, 557 { "MissingAttribute", "PeerDiscoveryRequest", "Connector", 61 }, 558 { "MissingAttribute", "PeerDiscoveryResponse", "TransactionID", 62 }, 559 { "MissingAttribute", "PeerDiscoveryResponse", "DPPStatus", 63 }, 560 { "MissingAttribute", "PeerDiscoveryResponse", "Connector", 64 }, 561 { "InvalidValue", "AuthenticationRequest", "InitProtocolKey", 66 }, 562 { "InvalidValue", "AuthenticationResponse", "RespProtocolKey", 67 }, 563 { "InvalidValue", "AuthenticationRequest", "RespBSKeyHash", 68 }, 564 { "InvalidValue", "AuthenticationRequest", "InitBSKeyHash", 69 }, 565 { "InvalidValue", "AuthenticationResponse", "RespBSKeyHash", 70 }, 566 { "InvalidValue", "AuthenticationResponse", "InitBSKeyHash", 71 }, 567 { "InvalidValue", "AuthenticationConfirm", "RespBSKeyHash", 72 }, 568 { "InvalidValue", "AuthenticationConfirm", "InitBSKeyHash", 73 }, 569 { "InvalidValue", "AuthenticationResponse", "DPPStatus", 74 }, 570 { "InvalidValue", "AuthenticationConfirm", "DPPStatus", 75 }, 571 { "InvalidValue", "ConfigurationRequest", "ConfigAttr", 76 }, 572 { "InvalidValue", "PeerDiscoveryResponse", "TransactionID", 77 }, 573 { "InvalidValue", "PeerDiscoveryResponse", "DPPStatus", 78 }, 574 { "InvalidValue", "PeerDiscoveryResponse", "Connector", 79 }, 575 { "InvalidValue", "PeerDiscoveryRequest", "Connector", 80 }, 576 { "InvalidValue", "AuthenticationRequest", "InitNonce", 81 }, 577 { "InvalidValue", "PeerDiscoveryRequest", "TransactionID", 82 }, 578 { "InvalidValue", "ConfigurationRequest", "EnrolleeNonce", 83 }, 579 { "Timeout", "PKEXExchangeResponse", NULL, 84 }, 580 { "Timeout", "PKEXCRRequest", NULL, 85 }, 581 { "Timeout", "PKEXCRResponse", NULL, 86 }, 582 { "Timeout", "AuthenticationRequest", NULL, 87 }, 583 { "Timeout", "AuthenticationResponse", NULL, 88 }, 584 { "Timeout", "AuthenticationConfirm", NULL, 89 }, 585 { "Timeout", "ConfigurationRequest", NULL, 90 }, 586 { NULL, NULL, NULL, 0 } 587 }; 588 589 590 static int dpp_get_test(const char *step, const char *frame, const char *attr) 591 { 592 int i; 593 594 for (i = 0; dpp_tests[i].step; i++) { 595 if (strcasecmp(step, dpp_tests[i].step) == 0 && 596 strcasecmp(frame, dpp_tests[i].frame) == 0 && 597 ((!attr && dpp_tests[i].attr == NULL) || 598 (attr && strcasecmp(attr, dpp_tests[i].attr) == 0))) 599 return dpp_tests[i].value; 600 } 601 602 return -1; 603 } 604 605 606 static int dpp_wait_tx(struct sigma_dut *dut, struct wpa_ctrl *ctrl, 607 int frame_type) 608 { 609 char buf[200], tmp[20]; 610 int res; 611 612 snprintf(tmp, sizeof(tmp), "type=%d", frame_type); 613 for (;;) { 614 res = get_wpa_cli_event(dut, ctrl, "DPP-TX", buf, sizeof(buf)); 615 if (res < 0) 616 return -1; 617 if (strstr(buf, tmp) != NULL) 618 break; 619 } 620 621 return 0; 622 } 623 624 625 static int dpp_wait_tx_status(struct sigma_dut *dut, struct wpa_ctrl *ctrl, 626 int frame_type) 627 { 628 char buf[200], tmp[20]; 629 int res; 630 631 snprintf(tmp, sizeof(tmp), "type=%d", frame_type); 632 for (;;) { 633 res = get_wpa_cli_event(dut, ctrl, "DPP-TX", buf, sizeof(buf)); 634 if (res < 0) 635 return -1; 636 if (strstr(buf, tmp) != NULL) 637 break; 638 } 639 640 res = get_wpa_cli_event(dut, ctrl, "DPP-TX-STATUS", 641 buf, sizeof(buf)); 642 if (res < 0 || strstr(buf, "result=FAILED") != NULL) 643 return -1; 644 645 return 0; 646 } 647 648 649 static int dpp_wait_rx(struct sigma_dut *dut, struct wpa_ctrl *ctrl, 650 int frame_type, unsigned int max_wait) 651 { 652 char buf[200], tmp[20]; 653 int res; 654 unsigned int old_timeout; 655 656 old_timeout = dut->default_timeout; 657 if (max_wait > 0 && dut->default_timeout > max_wait) 658 dut->default_timeout = max_wait; 659 660 snprintf(tmp, sizeof(tmp), "type=%d", frame_type); 661 for (;;) { 662 res = get_wpa_cli_event(dut, ctrl, "DPP-RX", buf, sizeof(buf)); 663 if (res < 0) { 664 dut->default_timeout = old_timeout; 665 return -1; 666 } 667 if (strstr(buf, tmp) != NULL) 668 break; 669 } 670 671 dut->default_timeout = old_timeout; 672 return 0; 673 } 674 675 676 static int dpp_wait_rx_conf_req(struct sigma_dut *dut, struct wpa_ctrl *ctrl, 677 unsigned int max_wait) 678 { 679 char buf[200]; 680 int res; 681 unsigned int old_timeout; 682 683 old_timeout = dut->default_timeout; 684 if (max_wait > 0 && dut->default_timeout > max_wait) 685 dut->default_timeout = max_wait; 686 687 for (;;) { 688 res = get_wpa_cli_event(dut, ctrl, "DPP-CONF-REQ-RX", 689 buf, sizeof(buf)); 690 if (res < 0) { 691 dut->default_timeout = old_timeout; 692 return -1; 693 } 694 695 break; 696 } 697 698 dut->default_timeout = old_timeout; 699 return 0; 700 } 701 702 703 static int dpp_scan_peer_qrcode(struct sigma_dut *dut) 704 { 705 #ifdef ANDROID 706 char buf[100]; 707 char *buf2 = NULL; 708 FILE *fp = NULL; 709 uint32_t length; 710 unsigned int count; 711 712 unlink(dpp_qrcode_file); 713 714 snprintf(buf, sizeof(buf), 715 "am start -n w1.fi.wpadebug/w1.fi.wpadebug.QrCodeReadActivity"); 716 if (system(buf) != 0) { 717 sigma_dut_print(dut, DUT_MSG_ERROR, 718 "Failed to launch QR Code scanner"); 719 return -1; 720 } 721 722 count = 0; 723 while (!(fp = fopen(dpp_qrcode_file, "r"))) { 724 if (count > dut->default_timeout) { 725 sigma_dut_print(dut, DUT_MSG_ERROR, 726 "Failed to open dpp_qrcode_file - QR Code scanning timed out"); 727 return -1; 728 } 729 730 sleep(1); 731 count++; 732 } 733 734 if (fseek(fp, 0, SEEK_END) < 0 || (length = ftell(fp)) <= 0 || 735 fseek(fp, 0, SEEK_SET) < 0) { 736 sigma_dut_print(dut, DUT_MSG_ERROR, 737 "Failed to get QR Code result file length"); 738 fclose(fp); 739 return -1; 740 } 741 742 buf2 = malloc(length + 1); 743 if (!buf2) { 744 fclose(fp); 745 return -1; 746 } 747 748 if (fread(buf2, 1, length, fp) != length) { 749 fclose(fp); 750 free(buf2); 751 return -1; 752 } 753 754 fclose(fp); 755 buf2[length] = '\0'; 756 757 free(dut->dpp_peer_uri); 758 dut->dpp_peer_uri = strdup(buf2); 759 free(buf2); 760 return 0; 761 #else /* ANDROID */ 762 pid_t pid; 763 int pid_status; 764 int pipe_out[2]; 765 char buf[4000], *pos; 766 ssize_t len; 767 int res = -1, ret; 768 struct timeval tv; 769 fd_set rfd; 770 771 if (pipe(pipe_out) != 0) { 772 perror("pipe"); 773 return -1; 774 } 775 776 pid = fork(); 777 if (pid < 0) { 778 perror("fork"); 779 close(pipe_out[0]); 780 close(pipe_out[1]); 781 return -1; 782 } 783 784 if (pid == 0) { 785 char *argv[4] = { "zbarcam", "--raw", "--prescale=320x240", 786 NULL }; 787 788 dup2(pipe_out[1], STDOUT_FILENO); 789 close(pipe_out[0]); 790 close(pipe_out[1]); 791 execv("/usr/bin/zbarcam", argv); 792 perror("execv"); 793 exit(0); 794 return -1; 795 } 796 797 close(pipe_out[1]); 798 799 FD_ZERO(&rfd); 800 FD_SET(pipe_out[0], &rfd); 801 tv.tv_sec = dut->default_timeout; 802 tv.tv_usec = 0; 803 804 ret = select(pipe_out[0] + 1, &rfd, NULL, NULL, &tv); 805 if (ret < 0) { 806 perror("select"); 807 goto out; 808 } 809 if (ret == 0) { 810 sigma_dut_print(dut, DUT_MSG_DEBUG, 811 "QR Code scanning timed out"); 812 goto out; 813 } 814 815 len = read(pipe_out[0], buf, sizeof(buf)); 816 if (len <= 0) 817 goto out; 818 if (len == sizeof(buf)) 819 len--; 820 buf[len] = '\0'; 821 pos = strchr(buf, '\n'); 822 if (pos) 823 *pos = '\0'; 824 sigma_dut_print(dut, DUT_MSG_DEBUG, "URI from QR scanner: %s", buf); 825 826 free(dut->dpp_peer_uri); 827 dut->dpp_peer_uri = strdup(buf); 828 res = 0; 829 out: 830 close(pipe_out[0]); 831 kill(pid, SIGTERM); 832 waitpid(pid, &pid_status, 0); 833 834 return res; 835 #endif /* ANDROID */ 836 } 837 838 839 static int dpp_display_own_qrcode(struct sigma_dut *dut) 840 { 841 char buf[200], resp[2000]; 842 const char *ifname = get_station_ifname(dut); 843 #ifdef ANDROID 844 FILE *fp; 845 #else /* ANDROID */ 846 pid_t pid; 847 int pid_status; 848 #endif /* ANDROID */ 849 850 snprintf(buf, sizeof(buf), "DPP_BOOTSTRAP_GET_URI %d", 851 dut->dpp_local_bootstrap); 852 if (wpa_command_resp(ifname, buf, resp, sizeof(resp)) < 0 || 853 strncmp(resp, "FAIL", 4) == 0) 854 return -2; 855 sigma_dut_print(dut, DUT_MSG_DEBUG, "Own bootstrap URI: %s", resp); 856 857 #ifdef ANDROID 858 unlink(dpp_qrcode_file); 859 860 fp = fopen(dpp_qrcode_file, "w"); 861 if (!fp) { 862 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open file %s", 863 dpp_qrcode_file); 864 return -2; 865 } 866 867 fwrite(resp, 1, strlen(resp), fp); 868 fclose(fp); 869 870 snprintf(buf, sizeof(buf), 871 "am start -n w1.fi.wpadebug/w1.fi.wpadebug.QrCodeDisplayActivity"); 872 if (system(buf) != 0) { 873 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to display QR Code"); 874 return -1; 875 } 876 #else /* ANDROID */ 877 pid = fork(); 878 if (pid < 0) { 879 perror("fork"); 880 return -1; 881 } 882 883 if (pid == 0) { 884 char *argv[3] = { "qr", resp, NULL }; 885 886 execv("/usr/bin/qr", argv); 887 perror("execv"); 888 exit(0); 889 return -1; 890 } 891 892 waitpid(pid, &pid_status, 0); 893 #endif /* ANDROID */ 894 895 return 0; 896 } 897 898 899 static int dpp_process_auth_response(struct sigma_dut *dut, 900 struct sigma_conn *conn, 901 struct wpa_ctrl *ctrl, 902 const char **auth_events, 903 const char *action_type, 904 int check_mutual, char *buf, size_t buflen) 905 { 906 int res; 907 908 res = get_wpa_cli_events(dut, ctrl, auth_events, buf, buflen); 909 if (res < 0) { 910 send_resp(dut, conn, SIGMA_COMPLETE, 911 "BootstrapResult,OK,AuthResult,Timeout"); 912 return res; 913 } 914 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP auth result: %s", buf); 915 916 if (strstr(buf, "DPP-RESPONSE-PENDING")) { 917 /* Display own QR code in manual mode */ 918 if (action_type && strcasecmp(action_type, "ManualDPP") == 0 && 919 dpp_display_own_qrcode(dut) < 0) { 920 send_resp(dut, conn, SIGMA_ERROR, 921 "errorCode,Failed to display own QR code"); 922 return -1; 923 } 924 925 /* Wait for the actual result after the peer has scanned the 926 * QR Code. */ 927 res = get_wpa_cli_events(dut, ctrl, auth_events, 928 buf, buflen); 929 if (res < 0) { 930 send_resp(dut, conn, SIGMA_COMPLETE, 931 "BootstrapResult,OK,AuthResult,Timeout"); 932 return res; 933 } 934 935 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP auth result: %s", buf); 936 } else if (strstr(buf, "DPP-AUTH-INIT-FAILED")) { 937 send_resp(dut, conn, SIGMA_ERROR, 938 "errorCode,Peer did not reply to DPP Authentication Request"); 939 return -1; 940 } 941 942 if (check_mutual) { 943 if (strstr(buf, "DPP-NOT-COMPATIBLE")) { 944 send_resp(dut, conn, SIGMA_COMPLETE, 945 "BootstrapResult,OK,AuthResult,ROLES_NOT_COMPATIBLE"); 946 return -1; 947 } 948 949 if (!strstr(buf, "DPP-AUTH-DIRECTION")) { 950 send_resp(dut, conn, SIGMA_ERROR, 951 "errorCode,No event for auth direction seen"); 952 return -1; 953 } 954 955 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP auth direction: %s", 956 buf); 957 if (strstr(buf, "mutual=1") == NULL) { 958 send_resp(dut, conn, SIGMA_ERROR, 959 "errorCode,Peer did not use mutual authentication"); 960 return -1; 961 } 962 } 963 964 return 0; 965 } 966 967 968 static enum sigma_cmd_result dpp_automatic_dpp(struct sigma_dut *dut, 969 struct sigma_conn *conn, 970 struct sigma_cmd *cmd) 971 { 972 const char *bs = get_param(cmd, "DPPBS"); 973 const char *type = get_param(cmd, "DPPActionType"); 974 const char *auth_role = get_param(cmd, "DPPAuthRole"); 975 const char *prov_role = get_param(cmd, "DPPProvisioningRole"); 976 const char *pkex_code = get_param(cmd, "DPPPKEXCode"); 977 const char *pkex_code_id = get_param(cmd, "DPPPKEXCodeIdentifier"); 978 const char *wait_conn = get_param(cmd, "DPPWaitForConnect"); 979 const char *self_conf = get_param(cmd, "DPPSelfConfigure"); 980 const char *step = get_param(cmd, "DPPStep"); 981 const char *frametype = get_param(cmd, "DPPFrameType"); 982 const char *attr = get_param(cmd, "DPPIEAttribute"); 983 const char *action_type = get_param(cmd, "DPPActionType"); 984 const char *tcp = get_param(cmd, "DPPOverTCP"); 985 const char *nfc_handover = get_param(cmd, "DPPNFCHandover"); 986 const char *role; 987 const char *netrole = NULL; 988 const char *val; 989 const char *conf_role; 990 int conf_index = -1; 991 char buf[2000], *pos, *pos2; 992 char buf2[200]; 993 char conf_ssid[100]; 994 char conf_pass[100]; 995 char pkex_identifier[200]; 996 struct wpa_ctrl *ctrl; 997 int res; 998 unsigned int old_timeout; 999 int own_pkex_id = -1; 1000 const char *ifname = get_station_ifname(dut); 1001 const char *auth_events[] = { 1002 "DPP-AUTH-SUCCESS", 1003 "DPP-AUTH-INIT-FAILED", 1004 "DPP-NOT-COMPATIBLE", 1005 "DPP-RESPONSE-PENDING", 1006 "DPP-SCAN-PEER-QR-CODE", 1007 "DPP-AUTH-DIRECTION", 1008 NULL 1009 }; 1010 const char *conf_events[] = { 1011 "DPP-CONF-RECEIVED", 1012 "DPP-CONF-SENT", 1013 "DPP-CONF-FAILED", 1014 NULL 1015 }; 1016 const char *conn_events[] = { 1017 "PMKSA-CACHE-ADDED", 1018 "CTRL-EVENT-CONNECTED", 1019 NULL 1020 }; 1021 const char *group_id_str = NULL; 1022 char group_id[100]; 1023 char conf2[300]; 1024 const char *result; 1025 int check_mutual = 0; 1026 int enrollee_ap; 1027 int enrollee_configurator; 1028 int force_gas_fragm = 0; 1029 int not_dpp_akm = 0; 1030 int akm_use_selector = 0; 1031 int conn_status; 1032 int chirp = 0; 1033 int manual = strcasecmp(type, "ManualDPP") == 0; 1034 time_t start, now; 1035 1036 time(&start); 1037 1038 if (!wait_conn) 1039 wait_conn = "no"; 1040 if (!self_conf) 1041 self_conf = "no"; 1042 1043 if (!prov_role) { 1044 send_resp(dut, conn, SIGMA_ERROR, 1045 "errorCode,Missing DPPProvisioningRole"); 1046 return STATUS_SENT_ERROR; 1047 } 1048 1049 val = get_param(cmd, "DPPConfEnrolleeRole"); 1050 if (val) { 1051 enrollee_ap = strcasecmp(val, "AP") == 0; 1052 enrollee_configurator = strcasecmp(val, "Configurator") == 0; 1053 } else { 1054 enrollee_ap = sigma_dut_is_ap(dut); 1055 enrollee_configurator = 0; 1056 } 1057 1058 val = get_param(cmd, "DPPNetworkRole"); 1059 if (val) { 1060 if (strcasecmp(val, "AP") == 0) { 1061 netrole = "ap"; 1062 } else if (strcasecmp(val, "STA") == 0) { 1063 netrole = "sta"; 1064 } else if (strcasecmp(val, "Configurator") == 0) { 1065 netrole = "configurator"; 1066 } else { 1067 send_resp(dut, conn, SIGMA_ERROR, 1068 "errorCode,Unsupported DPPNetworkRole value"); 1069 return STATUS_SENT_ERROR; 1070 } 1071 } 1072 1073 val = get_param(cmd, "DPPChirp"); 1074 if (val) 1075 chirp = get_enable_disable(val); 1076 1077 if ((step || frametype) && (!step || !frametype)) { 1078 send_resp(dut, conn, SIGMA_ERROR, 1079 "errorCode,Invalid DPPStep,DPPFrameType,DPPIEAttribute combination"); 1080 return STATUS_SENT_ERROR; 1081 } 1082 1083 val = get_param(cmd, "MUDURL"); 1084 if (val) { 1085 snprintf(buf, sizeof(buf), "SET dpp_mud_url %s", val); 1086 if (wpa_command(ifname, buf) < 0) { 1087 send_resp(dut, conn, SIGMA_ERROR, 1088 "errorCode,Failed to set MUD URL"); 1089 return STATUS_SENT_ERROR; 1090 } 1091 } 1092 1093 if (sigma_dut_is_ap(dut)) { 1094 if (!dut->hostapd_ifname) { 1095 sigma_dut_print(dut, DUT_MSG_ERROR, 1096 "hostapd ifname not specified (-j)"); 1097 return ERROR_SEND_STATUS; 1098 } 1099 ifname = dut->hostapd_ifname; 1100 1101 if (dpp_hostapd_run(dut) < 0) { 1102 send_resp(dut, conn, SIGMA_ERROR, 1103 "errorCode,Failed to start hostapd"); 1104 return STATUS_SENT_ERROR; 1105 } 1106 } 1107 1108 if (strcasecmp(prov_role, "Configurator") == 0 || 1109 strcasecmp(prov_role, "Both") == 0) { 1110 if (dut->dpp_conf_id < 0) { 1111 snprintf(buf, sizeof(buf), 1112 "DPP_CONFIGURATOR_ADD curve=%s", 1113 dpp_get_curve(cmd, "DPPSigningKeyECC")); 1114 if (wpa_command_resp(ifname, buf, 1115 buf, sizeof(buf)) < 0) { 1116 send_resp(dut, conn, SIGMA_ERROR, 1117 "errorCode,Failed to set up configurator"); 1118 return STATUS_SENT_ERROR; 1119 } 1120 dut->dpp_conf_id = atoi(buf); 1121 } 1122 if (strcasecmp(prov_role, "Configurator") == 0) 1123 role = "configurator"; 1124 else 1125 role = "either"; 1126 } else if (strcasecmp(prov_role, "Enrollee") == 0) { 1127 role = "enrollee"; 1128 } else { 1129 send_resp(dut, conn, SIGMA_ERROR, 1130 "errorCode,Unknown DPPProvisioningRole"); 1131 return STATUS_SENT_ERROR; 1132 } 1133 1134 pkex_identifier[0] = '\0'; 1135 if (strcasecmp(bs, "PKEX") == 0) { 1136 if (sigma_dut_is_ap(dut) && dut->ap_channel != 6) { 1137 /* For now, have to make operating channel match DPP 1138 * listen channel. This should be removed once hostapd 1139 * has support for DPP listen on non-operating channel. 1140 */ 1141 sigma_dut_print(dut, DUT_MSG_INFO, 1142 "Update hostapd operating channel to match listen needs"); 1143 dut->ap_channel = 6; 1144 1145 if (get_driver_type(dut) == DRIVER_OPENWRT) { 1146 snprintf(buf, sizeof(buf), 1147 "iwconfig %s channel %d", 1148 dut->hostapd_ifname, dut->ap_channel); 1149 run_system(dut, buf); 1150 } 1151 1152 if (wpa_command(ifname, "SET channel 6") < 0 || 1153 wpa_command(ifname, "DISABLE") < 0 || 1154 wpa_command(ifname, "ENABLE") < 0) { 1155 send_resp(dut, conn, SIGMA_ERROR, 1156 "errorCode,Failed to update channel"); 1157 return STATUS_SENT_ERROR; 1158 } 1159 } 1160 1161 if (!pkex_code) { 1162 send_resp(dut, conn, SIGMA_ERROR, 1163 "errorCode,Missing DPPPKEXCode"); 1164 return STATUS_SENT_ERROR; 1165 } 1166 1167 if (pkex_code_id) 1168 snprintf(pkex_identifier, sizeof(pkex_identifier), 1169 "identifier=%s ", pkex_code_id); 1170 1171 snprintf(buf, sizeof(buf), 1172 "DPP_BOOTSTRAP_GEN type=pkex curve=%s", 1173 dpp_get_curve(cmd, "DPPCryptoIdentifier")); 1174 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0) { 1175 send_resp(dut, conn, SIGMA_ERROR, 1176 "errorCode,Failed to set up PKEX"); 1177 return STATUS_SENT_ERROR; 1178 } 1179 own_pkex_id = atoi(buf); 1180 } 1181 1182 ctrl = open_wpa_mon(ifname); 1183 if (!ctrl) { 1184 sigma_dut_print(dut, DUT_MSG_ERROR, 1185 "Failed to open wpa_supplicant monitor connection"); 1186 return ERROR_SEND_STATUS; 1187 } 1188 1189 old_timeout = dut->default_timeout; 1190 val = get_param(cmd, "DPPTimeout"); 1191 if (val && atoi(val) > 0) { 1192 dut->default_timeout = atoi(val); 1193 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP timeout: %u", 1194 dut->default_timeout); 1195 } 1196 1197 val = get_param(cmd, "DPPStatusQuery"); 1198 conn_status = val && strcasecmp(val, "Yes") == 0; 1199 1200 conf_ssid[0] = '\0'; 1201 conf_pass[0] = '\0'; 1202 group_id[0] = '\0'; 1203 conf2[0] = '\0'; 1204 if (!enrollee_configurator) { 1205 val = get_param(cmd, "DPPConfIndex"); 1206 if (val) 1207 conf_index = atoi(val); 1208 } 1209 switch (conf_index) { 1210 case -1: 1211 if (enrollee_configurator) 1212 conf_role = "configurator"; 1213 else 1214 conf_role = NULL; 1215 break; 1216 case 1: 1217 ascii2hexstr("DPPNET01", buf); 1218 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf); 1219 if (res < 0 || res >= sizeof(conf_ssid)) 1220 goto err; 1221 if (enrollee_ap) { 1222 conf_role = "ap-dpp"; 1223 } else { 1224 conf_role = "sta-dpp"; 1225 } 1226 group_id_str = "DPPGROUP_DPP_INFRA"; 1227 break; 1228 case 2: 1229 ascii2hexstr("DPPNET01", buf); 1230 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf); 1231 if (res < 0 || res >= sizeof(conf_ssid)) 1232 goto err; 1233 snprintf(conf_pass, sizeof(conf_pass), 1234 "psk=10506e102ad1e7f95112f6b127675bb8344dacacea60403f3fa4055aec85b0fc"); 1235 if (enrollee_ap) 1236 conf_role = "ap-psk"; 1237 else 1238 conf_role = "sta-psk"; 1239 break; 1240 case 3: 1241 ascii2hexstr("DPPNET01", buf); 1242 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf); 1243 if (res < 0 || res >= sizeof(conf_ssid)) 1244 goto err; 1245 ascii2hexstr("ThisIsDppPassphrase", buf); 1246 res = snprintf(conf_pass, sizeof(conf_pass), "pass=%s", buf); 1247 if (res < 0 || res >= sizeof(conf_pass)) 1248 goto err; 1249 if (enrollee_ap) 1250 conf_role = "ap-psk"; 1251 else 1252 conf_role = "sta-psk"; 1253 break; 1254 case 4: 1255 ascii2hexstr("DPPNET01", buf); 1256 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf); 1257 if (res < 0 || res >= sizeof(conf_ssid)) 1258 goto err; 1259 if (enrollee_ap) { 1260 conf_role = "ap-dpp"; 1261 } else { 1262 conf_role = "sta-dpp"; 1263 } 1264 group_id_str = "DPPGROUP_DPP_INFRA2"; 1265 break; 1266 case 5: 1267 ascii2hexstr("DPPNET01", buf); 1268 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf); 1269 if (res < 0 || res >= sizeof(conf_ssid)) 1270 goto err; 1271 ascii2hexstr("ThisIsDppPassphrase", buf); 1272 res = snprintf(conf_pass, sizeof(conf_pass), "pass=%s", buf); 1273 if (res < 0 || res >= sizeof(conf_pass)) 1274 goto err; 1275 if (enrollee_ap) 1276 conf_role = "ap-sae"; 1277 else 1278 conf_role = "sta-sae"; 1279 break; 1280 case 6: 1281 ascii2hexstr("DPPNET01", buf); 1282 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf); 1283 if (res < 0 || res >= sizeof(conf_ssid)) 1284 goto err; 1285 ascii2hexstr("ThisIsDppPassphrase", buf); 1286 res = snprintf(conf_pass, sizeof(conf_pass), "pass=%s", buf); 1287 if (res < 0 || res >= sizeof(conf_pass)) 1288 goto err; 1289 if (enrollee_ap) 1290 conf_role = "ap-psk-sae"; 1291 else 1292 conf_role = "sta-psk-sae"; 1293 break; 1294 case 7: 1295 ascii2hexstr("DPPNET01", buf); 1296 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf); 1297 if (res < 0 || res >= sizeof(conf_ssid)) 1298 goto err; 1299 if (enrollee_ap) { 1300 conf_role = "ap-dpp"; 1301 } else { 1302 conf_role = "sta-dpp"; 1303 } 1304 group_id_str = "DPPGROUP_DPP_INFRA"; 1305 force_gas_fragm = 1; 1306 break; 1307 case 8: 1308 case 9: 1309 ascii2hexstr("DPPNET01", buf); 1310 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf); 1311 if (res < 0 || res >= sizeof(conf_ssid)) 1312 goto err; 1313 ascii2hexstr("This_is_legacy_password", buf); 1314 res = snprintf(conf_pass, sizeof(conf_pass), "pass=%s", buf); 1315 if (res < 0 || res >= sizeof(conf_pass)) 1316 goto err; 1317 if (enrollee_ap) { 1318 conf_role = "ap-dpp+psk+sae"; 1319 } else { 1320 conf_role = "sta-dpp+psk+sae"; 1321 } 1322 group_id_str = "DPPGROUP_DPP_INFRA1"; 1323 if (conf_index == 9) 1324 akm_use_selector = 1; 1325 break; 1326 case 10: 1327 ascii2hexstr("DPPNET01", buf); 1328 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf); 1329 if (res < 0 || res >= sizeof(conf_ssid)) 1330 goto err; 1331 if (enrollee_ap) 1332 conf_role = "ap-dpp"; 1333 else 1334 conf_role = "sta-dpp"; 1335 group_id_str = "DPPGROUP_DPP_INFRA1"; 1336 ascii2hexstr("DPPNET02", buf); 1337 ascii2hexstr("This_is_legacy_password", buf2); 1338 res = snprintf(conf2, sizeof(conf2), 1339 " @CONF-OBJ-SEP@ conf=%s-dpp+psk+sae ssid=%s pass=%s group_id=DPPGROUP_DPP_INFRA2", 1340 enrollee_ap ? "ap" : "sta", buf, buf2); 1341 if (res < 0 || res >= sizeof(conf2)) 1342 goto err; 1343 break; 1344 default: 1345 send_resp(dut, conn, SIGMA_ERROR, 1346 "errorCode,Unsupported DPPConfIndex"); 1347 goto out; 1348 } 1349 1350 if (group_id_str) 1351 snprintf(group_id, sizeof(group_id), " group_id=%s", 1352 group_id_str); 1353 1354 if (force_gas_fragm) { 1355 char spaces[1500]; 1356 1357 memset(spaces, ' ', sizeof(spaces)); 1358 spaces[sizeof(spaces) - 1] = '\0'; 1359 1360 snprintf(buf, sizeof(buf), 1361 "SET dpp_discovery_override {\"ssid\":\"DPPNET01\"}%s", 1362 spaces); 1363 if (wpa_command(ifname, buf) < 0) { 1364 send_resp(dut, conn, SIGMA_ERROR, 1365 "errorCode,Failed to set discovery override"); 1366 goto out; 1367 } 1368 } 1369 1370 if (step) { 1371 int test; 1372 1373 test = dpp_get_test(step, frametype, attr); 1374 if (test <= 0) { 1375 send_resp(dut, conn, SIGMA_ERROR, 1376 "errorCode,Unsupported DPPStep/DPPFrameType/DPPIEAttribute"); 1377 goto out; 1378 } 1379 1380 snprintf(buf, sizeof(buf), "SET dpp_test %d", test); 1381 if (wpa_command(ifname, buf) < 0) { 1382 send_resp(dut, conn, SIGMA_ERROR, 1383 "errorCode,Failed to set dpp_test"); 1384 goto out; 1385 } 1386 } else { 1387 wpa_command(ifname, "SET dpp_test 0"); 1388 } 1389 1390 if (strcasecmp(self_conf, "Yes") == 0) { 1391 if (strcasecmp(prov_role, "Configurator") != 0) { 1392 send_resp(dut, conn, SIGMA_ERROR, 1393 "errorCode,Invalid DPPSelfConfigure use - only allowed for Configurator role"); 1394 goto out; 1395 } 1396 if (!conf_role) { 1397 send_resp(dut, conn, SIGMA_ERROR, 1398 "errorCode,Missing DPPConfIndex"); 1399 goto out; 1400 } 1401 1402 snprintf(buf, sizeof(buf), 1403 "DPP_CONFIGURATOR_SIGN conf=%s %s %s configurator=%d", 1404 conf_role, conf_ssid, conf_pass, dut->dpp_conf_id); 1405 if (wpa_command(ifname, buf) < 0) { 1406 send_resp(dut, conn, SIGMA_ERROR, 1407 "errorCode,Failed to initiate DPP self-configuration"); 1408 goto out; 1409 } 1410 if (sigma_dut_is_ap(dut)) 1411 goto update_ap; 1412 goto wait_connect; 1413 } else if (manual && strcasecmp(bs, "NFC") == 0) { 1414 const char *val = get_param(cmd, "DPPNFCInit"); 1415 int init = val && atoi(val) > 0; 1416 pid_t pid; 1417 int pid_status; 1418 int enrollee = 0; 1419 const char *tx_rx_events[] = { "DPP-TX", "DPP-RX", NULL }; 1420 1421 if (strcasecmp(prov_role, "Configurator") == 0 || 1422 strcasecmp(prov_role, "Both") == 0) { 1423 if (!conf_role) { 1424 send_resp(dut, conn, SIGMA_ERROR, 1425 "errorCode,Missing DPPConfIndex"); 1426 goto out; 1427 } 1428 snprintf(buf, sizeof(buf), 1429 "SET dpp_configurator_params conf=%s %s %s configurator=%d%s%s%s%s", 1430 conf_role, conf_ssid, conf_pass, 1431 dut->dpp_conf_id, group_id, 1432 akm_use_selector ? " akm_use_selector=1" : "", 1433 conn_status ? " conn_status=1" : "", conf2); 1434 if (wpa_command(ifname, buf) < 0) { 1435 send_resp(dut, conn, SIGMA_ERROR, 1436 "errorCode,Failed to set configurator parameters"); 1437 goto out; 1438 } 1439 snprintf(buf, sizeof(buf), 1440 "conf=%s %s %s configurator=%d%s%s%s%s", 1441 conf_role, conf_ssid, conf_pass, 1442 dut->dpp_conf_id, group_id, 1443 akm_use_selector ? " akm_use_selector=1" : "", 1444 conn_status ? " conn_status=1" : "", conf2); 1445 } else { 1446 buf[0] = '\0'; 1447 enrollee = 1; 1448 } 1449 1450 run_system(dut, "killall dpp-nfc.py"); 1451 sigma_dut_print(dut, DUT_MSG_INFO, "Manual NFC operation"); 1452 if (!file_exists("dpp-nfc.py")) { 1453 send_resp(dut, conn, SIGMA_ERROR, 1454 "errorCode,dpp-nfc.py not found"); 1455 goto out; 1456 } 1457 1458 pid = fork(); 1459 if (pid < 0) { 1460 perror("fork"); 1461 send_resp(dut, conn, SIGMA_ERROR, 1462 "errorCode,fork() failed"); 1463 goto out; 1464 } 1465 1466 if (pid == 0) { 1467 char * argv[] = { "dpp-nfc.py", 1468 "--only-one", "--no-input", 1469 "-i", (char *) ifname, 1470 "--ctrl", sigma_wpas_ctrl, 1471 enrollee ? "--enrollee" : 1472 "--configurator", 1473 "--config-params", buf, 1474 init ? "-I" : NULL, 1475 NULL }; 1476 1477 execv("./dpp-nfc.py", argv); 1478 perror("execv"); 1479 exit(0); 1480 return -1; 1481 } 1482 1483 usleep(300000); 1484 for (;;) { 1485 if (waitpid(pid, &pid_status, WNOHANG) > 0) { 1486 sigma_dut_print(dut, DUT_MSG_DEBUG, 1487 "dpp-nfc.py exited"); 1488 break; 1489 } 1490 1491 time(&now); 1492 if ((unsigned int) (now - start) >= 1493 dut->default_timeout) { 1494 sigma_dut_print(dut, DUT_MSG_DEBUG, 1495 "dpp-nfc.py did not exit within timeout - stop it"); 1496 kill(pid, SIGTERM); 1497 waitpid(pid, &pid_status, 0); 1498 send_resp(dut, conn, SIGMA_ERROR, 1499 "errorCode,dpp-nfc.py did not complete within timeout"); 1500 goto out; 1501 } 1502 1503 old_timeout = dut->default_timeout; 1504 dut->default_timeout = 2; 1505 1506 res = get_wpa_cli_events(dut, ctrl, tx_rx_events, 1507 buf, sizeof(buf)); 1508 dut->default_timeout = old_timeout; 1509 if (res >= 0) { 1510 sigma_dut_print(dut, DUT_MSG_DEBUG, 1511 "DPP exchange started"); 1512 usleep(500000); 1513 kill(pid, SIGTERM); 1514 waitpid(pid, &pid_status, 0); 1515 break; 1516 } 1517 } 1518 } else if ((nfc_handover && 1519 strcasecmp(nfc_handover, "Negotiated_Requestor") == 0) || 1520 ((!nfc_handover || 1521 strcasecmp(nfc_handover, "Static") == 0) && 1522 auth_role && strcasecmp(auth_role, "Initiator") == 0)) { 1523 char own_txt[20]; 1524 int dpp_peer_bootstrap = -1; 1525 char neg_freq[30]; 1526 1527 val = get_param(cmd, "DPPAuthDirection"); 1528 check_mutual = val && strcasecmp(val, "Mutual") == 0; 1529 1530 neg_freq[0] = '\0'; 1531 val = get_param(cmd, "DPPSubsequentChannel"); 1532 if (val) { 1533 int opclass, channel, freq; 1534 1535 opclass = atoi(val); 1536 val = strchr(val, '/'); 1537 if (opclass == 0 || !val) { 1538 send_resp(dut, conn, SIGMA_ERROR, 1539 "errorCode,Invalid DPPSubsequentChannel"); 1540 goto out; 1541 } 1542 val++; 1543 channel = atoi(val); 1544 1545 /* Ignoring opclass for now; could use it here for more 1546 * robust frequency determination. */ 1547 freq = channel_to_freq(dut, channel); 1548 if (!freq) { 1549 send_resp(dut, conn, SIGMA_ERROR, 1550 "errorCode,Unsupported DPPSubsequentChannel channel"); 1551 goto out; 1552 } 1553 snprintf(neg_freq, sizeof(neg_freq), " neg_freq=%d", 1554 freq); 1555 } 1556 1557 if (strcasecmp(bs, "QR") == 0) { 1558 if (!dut->dpp_peer_uri) { 1559 send_resp(dut, conn, SIGMA_ERROR, 1560 "errorCode,Missing peer bootstrapping info"); 1561 goto out; 1562 } 1563 1564 snprintf(buf, sizeof(buf), "DPP_QR_CODE %s", 1565 dut->dpp_peer_uri); 1566 if (wpa_command_resp(ifname, buf, buf, 1567 sizeof(buf)) < 0 || 1568 strncmp(buf, "FAIL", 4) == 0) { 1569 send_resp(dut, conn, SIGMA_ERROR, 1570 "errorCode,Failed to parse URI"); 1571 goto out; 1572 } 1573 dpp_peer_bootstrap = atoi(buf); 1574 } else if (strcasecmp(bs, "NFC") == 0 && nfc_handover && 1575 strcasecmp(nfc_handover, "Static") == 0) { 1576 if (!dut->dpp_peer_uri) { 1577 send_resp(dut, conn, SIGMA_ERROR, 1578 "errorCode,Missing peer bootstrapping info"); 1579 goto out; 1580 } 1581 1582 snprintf(buf, sizeof(buf), "DPP_NFC_URI %s", 1583 dut->dpp_peer_uri); 1584 if (wpa_command_resp(ifname, buf, 1585 buf, sizeof(buf)) < 0 || 1586 strncmp(buf, "FAIL", 4) == 0) { 1587 send_resp(dut, conn, SIGMA_ERROR, 1588 "errorCode,Failed to process URI from NFC Tag"); 1589 goto out; 1590 } 1591 dpp_peer_bootstrap = atoi(buf); 1592 } else if (strcasecmp(bs, "NFC") == 0) { 1593 if (!dut->dpp_peer_uri) { 1594 send_resp(dut, conn, SIGMA_ERROR, 1595 "errorCode,Missing peer bootstrapping info"); 1596 goto out; 1597 } 1598 if (dut->dpp_local_bootstrap < 0) { 1599 send_resp(dut, conn, SIGMA_ERROR, 1600 "errorCode,Missing own bootstrapping info"); 1601 goto out; 1602 } 1603 1604 snprintf(buf, sizeof(buf), 1605 "DPP_NFC_HANDOVER_SEL own=%d uri=%s", 1606 dut->dpp_local_bootstrap, dut->dpp_peer_uri); 1607 if (wpa_command_resp(ifname, buf, 1608 buf, sizeof(buf)) < 0 || 1609 strncmp(buf, "FAIL", 4) == 0) { 1610 send_resp(dut, conn, SIGMA_ERROR, 1611 "errorCode,Failed to process NFC Handover Select"); 1612 goto out; 1613 } 1614 dpp_peer_bootstrap = atoi(buf); 1615 } 1616 1617 if (dut->dpp_local_bootstrap >= 0) 1618 snprintf(own_txt, sizeof(own_txt), " own=%d", 1619 dut->dpp_local_bootstrap); 1620 else 1621 own_txt[0] = '\0'; 1622 if (chirp) { 1623 int freq = 2437; /* default: channel 6 */ 1624 1625 val = get_param(cmd, "DPPChirpChannel"); 1626 if (val) { 1627 freq = channel_to_freq(dut, atoi(val)); 1628 if (!freq) { 1629 send_resp(dut, conn, SIGMA_ERROR, 1630 "errorCode,Unsupported DPPChirpChannel channel"); 1631 goto out; 1632 } 1633 } 1634 1635 if (strcasecmp(prov_role, "Configurator") == 0 || 1636 strcasecmp(prov_role, "Both") == 0) { 1637 if (!conf_role) { 1638 send_resp(dut, conn, SIGMA_ERROR, 1639 "errorCode,Missing DPPConfIndex"); 1640 goto out; 1641 } 1642 snprintf(buf, sizeof(buf), 1643 "SET dpp_configurator_params conf=%s %s %s configurator=%d%s%s%s%s", 1644 conf_role, conf_ssid, conf_pass, 1645 dut->dpp_conf_id, group_id, 1646 akm_use_selector ? 1647 " akm_use_selector=1" : "", 1648 conn_status ? " conn_status=1" : "", 1649 conf2); 1650 if (wpa_command(ifname, buf) < 0) { 1651 send_resp(dut, conn, SIGMA_ERROR, 1652 "errorCode,Failed to set configurator parameters"); 1653 goto out; 1654 } 1655 } 1656 1657 if (tcp && strcasecmp(tcp, "yes") == 0) { 1658 snprintf(buf, sizeof(buf), 1659 "DPP_CONTROLLER_START"); 1660 } else { 1661 snprintf(buf, sizeof(buf), 1662 "DPP_LISTEN %d role=%s%s%s", 1663 freq, role, 1664 netrole ? " netrole=" : "", 1665 netrole ? netrole : ""); 1666 } 1667 } else if ((strcasecmp(bs, "QR") == 0 || 1668 strcasecmp(bs, "NFC") == 0) && 1669 (strcasecmp(prov_role, "Configurator") == 0 || 1670 strcasecmp(prov_role, "Both") == 0)) { 1671 if (!conf_role) { 1672 send_resp(dut, conn, SIGMA_ERROR, 1673 "errorCode,Missing DPPConfIndex"); 1674 goto out; 1675 } 1676 snprintf(buf, sizeof(buf), 1677 "DPP_AUTH_INIT peer=%d%s role=%s%s%s conf=%s %s %s configurator=%d%s%s%s%s%s%s%s", 1678 dpp_peer_bootstrap, own_txt, role, 1679 netrole ? " netrole=" : "", 1680 netrole ? netrole : "", 1681 conf_role, conf_ssid, conf_pass, 1682 dut->dpp_conf_id, neg_freq, group_id, 1683 akm_use_selector ? " akm_use_selector=1" : "", 1684 conn_status ? " conn_status=1" : "", 1685 tcp ? " tcp_addr=" : "", 1686 tcp ? tcp : "", 1687 conf2); 1688 } else if (tcp && (strcasecmp(bs, "QR") == 0 || 1689 strcasecmp(bs, "NFC") == 0)) { 1690 snprintf(buf, sizeof(buf), 1691 "DPP_AUTH_INIT peer=%d%s role=%s%s%s tcp_addr=%s%s%s", 1692 dpp_peer_bootstrap, own_txt, role, 1693 netrole ? " netrole=" : "", 1694 netrole ? netrole : "", 1695 tcp, neg_freq, group_id); 1696 } else if (strcasecmp(bs, "QR") == 0 || 1697 strcasecmp(bs, "NFC") == 0) { 1698 snprintf(buf, sizeof(buf), 1699 "DPP_AUTH_INIT peer=%d%s role=%s%s%s%s%s", 1700 dpp_peer_bootstrap, own_txt, role, 1701 netrole ? " netrole=" : "", 1702 netrole ? netrole : "", 1703 neg_freq, group_id); 1704 } else if (strcasecmp(bs, "PKEX") == 0 && 1705 (strcasecmp(prov_role, "Configurator") == 0 || 1706 strcasecmp(prov_role, "Both") == 0)) { 1707 if (!conf_role) { 1708 send_resp(dut, conn, SIGMA_ERROR, 1709 "errorCode,Missing DPPConfIndex"); 1710 goto out; 1711 } 1712 snprintf(buf, sizeof(buf), 1713 "DPP_PKEX_ADD own=%d init=1 role=%s conf=%s %s %s configurator=%d %scode=%s", 1714 own_pkex_id, role, conf_role, 1715 conf_ssid, conf_pass, dut->dpp_conf_id, 1716 pkex_identifier, pkex_code); 1717 } else if (strcasecmp(bs, "PKEX") == 0) { 1718 snprintf(buf, sizeof(buf), 1719 "DPP_PKEX_ADD own=%d init=1 role=%s %scode=%s", 1720 own_pkex_id, role, pkex_identifier, pkex_code); 1721 } else { 1722 send_resp(dut, conn, SIGMA_ERROR, 1723 "errorCode,Unsupported DPPBS"); 1724 goto out; 1725 } 1726 if (wpa_command(ifname, buf) < 0) { 1727 send_resp(dut, conn, SIGMA_ERROR, 1728 "errorCode,Failed to initiate DPP authentication"); 1729 goto out; 1730 } 1731 } else if ((nfc_handover && 1732 strcasecmp(nfc_handover, "Negotiated_Selector") == 0) || 1733 ((!nfc_handover || 1734 strcasecmp(nfc_handover, "Static") == 0) && 1735 auth_role && strcasecmp(auth_role, "Responder") == 0)) { 1736 const char *delay_qr_resp; 1737 int mutual; 1738 int freq = 2462; /* default: channel 11 */ 1739 1740 if (sigma_dut_is_ap(dut) && dut->hostapd_running && 1741 dut->ap_oper_chn) 1742 freq = channel_to_freq(dut, dut->ap_channel); 1743 1744 if (sigma_dut_is_ap(dut) && dpp_hostapd_beacon(dut) < 0) { 1745 send_resp(dut, conn, SIGMA_ERROR, 1746 "errorCode,Failed to start AP mode listen"); 1747 goto out; 1748 } 1749 1750 if (strcasecmp(bs, "PKEX") == 0) { 1751 /* default: channel 6 for PKEX */ 1752 freq = 2437; 1753 } 1754 1755 delay_qr_resp = get_param(cmd, "DPPDelayQRResponse"); 1756 1757 val = get_param(cmd, "DPPAuthDirection"); 1758 mutual = val && strcasecmp(val, "Mutual") == 0; 1759 1760 val = get_param(cmd, "DPPListenChannel"); 1761 if (val) { 1762 freq = channel_to_freq(dut, atoi(val)); 1763 if (freq == 0) { 1764 send_resp(dut, conn, SIGMA_ERROR, 1765 "errorCode,Unsupported DPPListenChannel value"); 1766 goto out; 1767 } 1768 } 1769 1770 if (strcasecmp(bs, "NFC") == 0 && nfc_handover && 1771 strcasecmp(nfc_handover, "Static") == 0) { 1772 /* No steps needed here - waiting for peer to initiate 1773 * once it reads the URI from the NFC Tag */ 1774 } else if (strcasecmp(bs, "NFC") == 0) { 1775 if (!dut->dpp_peer_uri) { 1776 send_resp(dut, conn, SIGMA_ERROR, 1777 "errorCode,Missing peer bootstrapping info"); 1778 goto out; 1779 } 1780 if (dut->dpp_local_bootstrap < 0) { 1781 send_resp(dut, conn, SIGMA_ERROR, 1782 "errorCode,Missing own bootstrapping info"); 1783 goto out; 1784 } 1785 1786 snprintf(buf, sizeof(buf), 1787 "DPP_NFC_HANDOVER_REQ own=%d uri=%s", 1788 dut->dpp_local_bootstrap, dut->dpp_peer_uri); 1789 if (wpa_command(ifname, buf) < 0) { 1790 send_resp(dut, conn, SIGMA_ERROR, 1791 "errorCode,Failed to process NFC Handover Request"); 1792 goto out; 1793 } 1794 1795 snprintf(buf, sizeof(buf), "DPP_BOOTSTRAP_INFO %d", 1796 dut->dpp_local_bootstrap); 1797 if (wpa_command_resp(ifname, buf, 1798 buf, sizeof(buf)) < 0 || 1799 strncmp(buf, "FAIL", 4) == 0) { 1800 send_resp(dut, conn, SIGMA_ERROR, 1801 "errorCode,Failed to get bootstrap information"); 1802 goto out; 1803 } 1804 pos = buf; 1805 while (pos) { 1806 pos2 = strchr(pos, '\n'); 1807 if (pos2) 1808 *pos2 = '\0'; 1809 if (strncmp(pos, "use_freq=", 9) == 0) { 1810 freq = atoi(pos + 9); 1811 sigma_dut_print(dut, DUT_MSG_DEBUG, 1812 "DPP negotiation frequency from NFC handover: %d MHz", 1813 freq); 1814 break; 1815 } 1816 1817 if (!pos2) 1818 break; 1819 pos = pos2 + 1; 1820 } 1821 } else if (!delay_qr_resp && dut->dpp_peer_uri) { 1822 snprintf(buf, sizeof(buf), "DPP_QR_CODE %s", 1823 dut->dpp_peer_uri); 1824 if (wpa_command_resp(ifname, buf, buf, 1825 sizeof(buf)) < 0) { 1826 send_resp(dut, conn, SIGMA_ERROR, 1827 "errorCode,Failed to parse URI"); 1828 goto out; 1829 } 1830 } 1831 1832 if (strcasecmp(prov_role, "Configurator") == 0) { 1833 if (!conf_role) { 1834 send_resp(dut, conn, SIGMA_ERROR, 1835 "errorCode,Missing DPPConfIndex"); 1836 goto out; 1837 } 1838 snprintf(buf, sizeof(buf), 1839 "SET dpp_configurator_params conf=%s %s %s configurator=%d%s%s%s%s", 1840 conf_role, conf_ssid, conf_pass, 1841 dut->dpp_conf_id, group_id, 1842 akm_use_selector ? " akm_use_selector=1" : "", 1843 conn_status ? " conn_status=1" : "", 1844 conf2); 1845 if (wpa_command(ifname, buf) < 0) { 1846 send_resp(dut, conn, SIGMA_ERROR, 1847 "errorCode,Failed to set configurator parameters"); 1848 goto out; 1849 } 1850 } 1851 if (strcasecmp(bs, "PKEX") == 0) { 1852 snprintf(buf, sizeof(buf), 1853 "DPP_PKEX_ADD own=%d role=%s %scode=%s", 1854 own_pkex_id, role, pkex_identifier, pkex_code); 1855 if (wpa_command(ifname, buf) < 0) { 1856 send_resp(dut, conn, SIGMA_ERROR, 1857 "errorCode,Failed to configure DPP PKEX"); 1858 goto out; 1859 } 1860 } 1861 1862 if (chirp) { 1863 snprintf(buf, sizeof(buf), 1864 "DPP_CHIRP own=%d iter=10 listen=%d", 1865 dut->dpp_local_bootstrap, freq); 1866 } else if (tcp && strcasecmp(tcp, "yes") == 0) { 1867 snprintf(buf, sizeof(buf), "DPP_CONTROLLER_START"); 1868 } else { 1869 snprintf(buf, sizeof(buf), 1870 "DPP_LISTEN %d role=%s%s%s%s", 1871 freq, role, 1872 (strcasecmp(bs, "QR") == 0 && mutual) ? 1873 " qr=mutual" : "", 1874 netrole ? " netrole=" : "", 1875 netrole ? netrole : ""); 1876 } 1877 if (wpa_command(ifname, buf) < 0) { 1878 send_resp(dut, conn, SIGMA_ERROR, 1879 "errorCode,Failed to start DPP listen/chirp"); 1880 goto out; 1881 } 1882 1883 if (!(tcp && strcasecmp(tcp, "yes") == 0) && 1884 get_driver_type(dut) == DRIVER_OPENWRT) { 1885 snprintf(buf, sizeof(buf), "iwconfig %s channel %d", 1886 dut->hostapd_ifname, freq_to_channel(freq)); 1887 run_system(dut, buf); 1888 } 1889 1890 if (delay_qr_resp && mutual && dut->dpp_peer_uri) { 1891 int wait_time = atoi(delay_qr_resp); 1892 1893 res = get_wpa_cli_events(dut, ctrl, auth_events, 1894 buf, sizeof(buf)); 1895 if (res < 0) { 1896 send_resp(dut, conn, SIGMA_COMPLETE, 1897 "BootstrapResult,OK,AuthResult,Timeout"); 1898 goto out; 1899 } 1900 sigma_dut_print(dut, DUT_MSG_DEBUG, 1901 "DPP auth result: %s", buf); 1902 if (strstr(buf, "DPP-SCAN-PEER-QR-CODE") == NULL) { 1903 send_resp(dut, conn, SIGMA_ERROR, 1904 "errorCode,No scan request for peer QR Code seen"); 1905 goto out; 1906 } 1907 sigma_dut_print(dut, DUT_MSG_INFO, 1908 "Waiting %d second(s) before processing peer URI", 1909 wait_time); 1910 sleep(wait_time); 1911 1912 snprintf(buf, sizeof(buf), "DPP_QR_CODE %s", 1913 dut->dpp_peer_uri); 1914 if (wpa_command_resp(ifname, buf, buf, 1915 sizeof(buf)) < 0) { 1916 send_resp(dut, conn, SIGMA_ERROR, 1917 "errorCode,Failed to parse URI"); 1918 goto out; 1919 } 1920 } else if (mutual && action_type && 1921 strcasecmp(action_type, "ManualDPP") == 0) { 1922 res = get_wpa_cli_events(dut, ctrl, auth_events, 1923 buf, sizeof(buf)); 1924 if (res < 0) { 1925 send_resp(dut, conn, SIGMA_COMPLETE, 1926 "BootstrapResult,OK,AuthResult,Timeout"); 1927 goto out; 1928 } 1929 sigma_dut_print(dut, DUT_MSG_DEBUG, 1930 "DPP auth result: %s", buf); 1931 if (strstr(buf, "DPP-NOT-COMPATIBLE")) { 1932 send_resp(dut, conn, SIGMA_COMPLETE, 1933 "BootstrapResult,OK,AuthResult,ROLES_NOT_COMPATIBLE"); 1934 goto out; 1935 } 1936 1937 if (strstr(buf, "DPP-SCAN-PEER-QR-CODE") == NULL) { 1938 send_resp(dut, conn, SIGMA_ERROR, 1939 "errorCode,No scan request for peer QR Code seen"); 1940 goto out; 1941 } 1942 1943 if (dpp_scan_peer_qrcode(dut) < 0) { 1944 send_resp(dut, conn, SIGMA_ERROR, 1945 "errorCode,Failed to scan peer QR Code"); 1946 goto out; 1947 } 1948 1949 snprintf(buf, sizeof(buf), "DPP_QR_CODE %s", 1950 dut->dpp_peer_uri); 1951 if (wpa_command_resp(ifname, buf, buf, 1952 sizeof(buf)) < 0) { 1953 send_resp(dut, conn, SIGMA_ERROR, 1954 "errorCode,Failed to parse URI"); 1955 goto out; 1956 } 1957 } 1958 } else { 1959 send_resp(dut, conn, SIGMA_ERROR, 1960 "errorCode,Unknown DPPAuthRole"); 1961 goto out; 1962 } 1963 1964 if (step && strcasecmp(step, "Timeout") == 0) { 1965 result = "errorCode,Unexpected state"; 1966 1967 if (strcasecmp(frametype, "PKEXExchangeResponse") == 0) { 1968 if (dpp_wait_rx(dut, ctrl, 8, -1) < 0) 1969 result = "BootstrapResult,Timeout"; 1970 else 1971 result = "BootstrapResult,Errorsent"; 1972 } 1973 1974 if (strcasecmp(frametype, "PKEXCRRequest") == 0) { 1975 if (dpp_wait_rx(dut, ctrl, 9, -1) < 0) 1976 result = "BootstrapResult,Timeout"; 1977 else 1978 result = "BootstrapResult,Errorsent"; 1979 } 1980 1981 if (strcasecmp(frametype, "PKEXCRResponse") == 0) { 1982 if (dpp_wait_rx(dut, ctrl, 10, -1) < 0) 1983 result = "BootstrapResult,Timeout"; 1984 else 1985 result = "BootstrapResult,Errorsent"; 1986 } 1987 1988 if (strcasecmp(frametype, "AuthenticationRequest") == 0) { 1989 if (dpp_wait_rx(dut, ctrl, 0, -1) < 0) 1990 result = "BootstrapResult,OK,AuthResult,Timeout"; 1991 else 1992 result = "BootstrapResult,OK,AuthResult,Errorsent"; 1993 } 1994 1995 if (strcasecmp(frametype, "AuthenticationResponse") == 0) { 1996 if (dpp_wait_rx(dut, ctrl, 1, -1) < 0) 1997 result = "BootstrapResult,OK,AuthResult,Timeout"; 1998 else 1999 result = "BootstrapResult,OK,AuthResult,Errorsent"; 2000 } 2001 2002 if (strcasecmp(frametype, "AuthenticationConfirm") == 0) { 2003 if (auth_role && 2004 strcasecmp(auth_role, "Initiator") == 0) { 2005 /* This special case of DPPStep,Timeout with 2006 * DPPFrameType,AuthenticationConfirm on an 2007 * Initiator is used to cover need for stopping 2008 * the Initiator/Enrollee from sending out 2009 * Configuration Request message. */ 2010 if (strcasecmp(prov_role, "Enrollee") != 0) { 2011 send_resp(dut, conn, SIGMA_ERROR, 2012 "errorCode,Unexpected use of timeout after AuthenticationConfirm TX in Configurator role"); 2013 goto out; 2014 } 2015 if (check_mutual && 2016 dpp_process_auth_response( 2017 dut, conn, ctrl, auth_events, 2018 action_type, check_mutual, 2019 buf, sizeof(buf)) < 0) 2020 goto out; 2021 if (dpp_wait_tx_status(dut, ctrl, 2) < 0) 2022 result = "BootstrapResult,OK,AuthResult,Timeout"; 2023 else 2024 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationResponse"; 2025 } else { 2026 if (dpp_wait_rx(dut, ctrl, 2, -1) < 0) 2027 result = "BootstrapResult,OK,AuthResult,Timeout"; 2028 else 2029 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationConfirm"; 2030 } 2031 } 2032 2033 if (strcasecmp(frametype, "ConfigurationRequest") == 0) { 2034 if (get_wpa_cli_event(dut, ctrl, "DPP-CONF-FAILED", 2035 buf, sizeof(buf)) < 0) 2036 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Timeout"; 2037 else 2038 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Errorsent"; 2039 } 2040 2041 send_resp(dut, conn, SIGMA_COMPLETE, result); 2042 goto out; 2043 } 2044 2045 if (frametype && strcasecmp(frametype, "PKEXExchangeRequest") == 0) { 2046 if (dpp_wait_tx_status(dut, ctrl, 7) < 0) 2047 result = "BootstrapResult,Timeout"; 2048 else 2049 result = "BootstrapResult,Errorsent"; 2050 send_resp(dut, conn, SIGMA_COMPLETE, result); 2051 goto out; 2052 } 2053 2054 if (frametype && strcasecmp(frametype, "PKEXExchangeResponse") == 0) { 2055 if (dpp_wait_tx_status(dut, ctrl, 8) < 0) 2056 result = "BootstrapResult,Timeout"; 2057 else 2058 result = "BootstrapResult,Errorsent"; 2059 send_resp(dut, conn, SIGMA_COMPLETE, result); 2060 goto out; 2061 } 2062 2063 if (frametype && strcasecmp(frametype, "PKEXCRRequest") == 0) { 2064 if (dpp_wait_tx_status(dut, ctrl, 9) < 0) 2065 result = "BootstrapResult,Timeout"; 2066 else 2067 result = "BootstrapResult,Errorsent"; 2068 send_resp(dut, conn, SIGMA_COMPLETE, result); 2069 goto out; 2070 } 2071 2072 if (frametype && strcasecmp(frametype, "PKEXCRResponse") == 0) { 2073 if (dpp_wait_tx_status(dut, ctrl, 10) < 0) 2074 result = "BootstrapResult,Timeout"; 2075 else 2076 result = "BootstrapResult,Errorsent"; 2077 send_resp(dut, conn, SIGMA_COMPLETE, result); 2078 goto out; 2079 } 2080 2081 if (!frametype && strcasecmp(bs, "PKEX") == 0 && 2082 auth_role && strcasecmp(auth_role, "Responder") == 0) { 2083 if (dpp_wait_tx_status(dut, ctrl, 10) < 0) { 2084 send_resp(dut, conn, SIGMA_COMPLETE, 2085 "BootstrapResult,Timeout"); 2086 goto out; 2087 } 2088 } 2089 2090 if (!frametype && strcasecmp(bs, "PKEX") == 0 && 2091 auth_role && strcasecmp(auth_role, "Initiator") == 0) { 2092 if (dpp_wait_tx(dut, ctrl, 0) < 0) { 2093 send_resp(dut, conn, SIGMA_COMPLETE, 2094 "BootstrapResult,Timeout"); 2095 goto out; 2096 } 2097 } 2098 2099 if (frametype && strcasecmp(frametype, "AuthenticationRequest") == 0) { 2100 if (dpp_wait_tx_status(dut, ctrl, 0) < 0) { 2101 send_resp(dut, conn, SIGMA_COMPLETE, 2102 "BootstrapResult,OK,AuthResult,Timeout"); 2103 goto out; 2104 } 2105 2106 if (dpp_wait_rx(dut, ctrl, 1, 5) < 0) 2107 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,None"; 2108 else if (get_wpa_cli_events(dut, ctrl, auth_events, 2109 buf, sizeof(buf)) >= 0 && 2110 strstr(buf, "DPP-RESPONSE-PENDING") != NULL) 2111 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationResponseWithStatusPending"; 2112 else 2113 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationResponse"; 2114 send_resp(dut, conn, SIGMA_COMPLETE, result); 2115 goto out; 2116 } 2117 2118 if (frametype && strcasecmp(frametype, "AuthenticationResponse") == 0) { 2119 if (dpp_wait_tx_status(dut, ctrl, 1) < 0) { 2120 send_resp(dut, conn, SIGMA_COMPLETE, 2121 "BootstrapResult,OK,AuthResult,Timeout"); 2122 goto out; 2123 } 2124 2125 if (dpp_wait_rx(dut, ctrl, 2, 5) < 0) 2126 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationRequest"; 2127 else 2128 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationConfirm"; 2129 send_resp(dut, conn, SIGMA_COMPLETE, result); 2130 goto out; 2131 } 2132 2133 if (dpp_process_auth_response(dut, conn, ctrl, auth_events, action_type, 2134 check_mutual, buf, sizeof(buf)) < 0) 2135 goto out; 2136 2137 if (frametype && strcasecmp(frametype, "AuthenticationConfirm") == 0) { 2138 if (dpp_wait_tx_status(dut, ctrl, 2) < 0) { 2139 send_resp(dut, conn, SIGMA_COMPLETE, 2140 "BootstrapResult,OK,AuthResult,Timeout"); 2141 goto out; 2142 } 2143 2144 if (dpp_wait_rx_conf_req(dut, ctrl, 5) < 0) 2145 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationResponse"; 2146 else 2147 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,ConfigurationRequest"; 2148 send_resp(dut, conn, SIGMA_COMPLETE, result); 2149 goto out; 2150 } 2151 2152 if (strstr(buf, "DPP-AUTH-DIRECTION")) { 2153 res = get_wpa_cli_events(dut, ctrl, auth_events, 2154 buf, sizeof(buf)); 2155 if (res < 0) { 2156 send_resp(dut, conn, SIGMA_COMPLETE, 2157 "BootstrapResult,OK,AuthResult,Timeout"); 2158 goto out; 2159 } 2160 2161 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP auth result: %s", buf); 2162 } 2163 2164 if (strstr(buf, "DPP-NOT-COMPATIBLE")) { 2165 send_resp(dut, conn, SIGMA_COMPLETE, 2166 "BootstrapResult,OK,AuthResult,ROLES_NOT_COMPATIBLE"); 2167 goto out; 2168 } 2169 2170 if (!strstr(buf, "DPP-AUTH-SUCCESS")) { 2171 send_resp(dut, conn, SIGMA_COMPLETE, 2172 "BootstrapResult,OK,AuthResult,FAILED"); 2173 goto out; 2174 } 2175 2176 if (frametype && strcasecmp(frametype, "ConfigurationRequest") == 0) { 2177 res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE", 2178 buf, sizeof(buf)); 2179 if (res < 0) 2180 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Timeout"; 2181 else 2182 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Errorsent"; 2183 send_resp(dut, conn, SIGMA_COMPLETE, result); 2184 goto out; 2185 } 2186 2187 if (frametype && strcasecmp(frametype, "ConfigurationResponse") == 0) { 2188 res = get_wpa_cli_events(dut, ctrl, conf_events, 2189 buf, sizeof(buf)); 2190 if (res < 0) 2191 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Timeout"; 2192 else 2193 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Errorsent,LastFrameReceived,ConfigurationRequest"; 2194 send_resp(dut, conn, SIGMA_COMPLETE, result); 2195 goto out; 2196 } 2197 2198 res = get_wpa_cli_events(dut, ctrl, conf_events, buf, sizeof(buf)); 2199 if (res < 0) { 2200 send_resp(dut, conn, SIGMA_COMPLETE, 2201 "BootstrapResult,OK,AuthResult,OK,ConfResult,Timeout"); 2202 goto out; 2203 } 2204 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP conf result: %s", buf); 2205 2206 if (!strstr(buf, "DPP-CONF-SENT") && 2207 !strstr(buf, "DPP-CONF-RECEIVED")) { 2208 send_resp(dut, conn, SIGMA_COMPLETE, 2209 "BootstrapResult,OK,AuthResult,OK,ConfResult,FAILED"); 2210 goto out; 2211 } 2212 2213 if (conn_status && strstr(buf, "DPP-CONF-SENT") && 2214 strstr(buf, "wait_conn_status=1")) { 2215 res = get_wpa_cli_event(dut, ctrl, "DPP-CONN-STATUS-RESULT", 2216 buf, sizeof(buf)); 2217 if (res < 0) { 2218 send_resp(dut, conn, SIGMA_COMPLETE, 2219 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,StatusResult,Timeout"); 2220 } else { 2221 pos = strstr(buf, "result="); 2222 if (!pos) { 2223 send_resp(dut, conn, SIGMA_ERROR, 2224 "errorCode,Status result value not reported"); 2225 } else { 2226 pos += 7; 2227 snprintf(buf, sizeof(buf), 2228 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,StatusResult,%d", 2229 atoi(pos)); 2230 send_resp(dut, conn, SIGMA_COMPLETE, buf); 2231 } 2232 } 2233 goto out; 2234 } 2235 2236 if (strcasecmp(prov_role, "Enrollee") == 0 && netrole && 2237 strcmp(netrole, "configurator") == 0) { 2238 res = get_wpa_cli_event(dut, ctrl, "DPP-CONFIGURATOR-ID", 2239 buf, sizeof(buf)); 2240 if (res < 0) { 2241 send_resp(dut, conn, SIGMA_ERROR, 2242 "errorCode,No DPP-CONFIGURATOR-ID"); 2243 goto out; 2244 } 2245 pos = strchr(buf, ' '); 2246 if (!pos) { 2247 send_resp(dut, conn, SIGMA_ERROR, 2248 "errorCode,Invalid DPP-CONFIGURATOR-ID"); 2249 goto out; 2250 } 2251 pos++; 2252 dut->dpp_conf_id = atoi(pos); 2253 } else if (sigma_dut_is_ap(dut) && 2254 strcasecmp(prov_role, "Enrollee") == 0) { 2255 update_ap: 2256 res = dpp_hostapd_conf_update(dut, conn, ifname, ctrl); 2257 if (res == 0) 2258 goto out; 2259 if (res < 0) { 2260 send_resp(dut, conn, SIGMA_ERROR, NULL); 2261 goto out; 2262 } 2263 } 2264 2265 if (strcasecmp(wait_conn, "Yes") == 0 && 2266 !sigma_dut_is_ap(dut) && 2267 strcasecmp(prov_role, "Enrollee") == 0) { 2268 int netw_id; 2269 char *pos; 2270 2271 res = get_wpa_cli_event(dut, ctrl, "DPP-NETWORK-ID", 2272 buf, sizeof(buf)); 2273 if (res < 0) { 2274 send_resp(dut, conn, SIGMA_ERROR, 2275 "errorCode,No DPP-NETWORK-ID"); 2276 goto out; 2277 } 2278 pos = strchr(buf, ' '); 2279 if (!pos) { 2280 send_resp(dut, conn, SIGMA_ERROR, 2281 "errorCode,Invalid DPP-NETWORK-ID"); 2282 goto out; 2283 } 2284 pos++; 2285 netw_id = atoi(pos); 2286 snprintf(buf, sizeof(buf), "GET_NETWORK %d key_mgmt", netw_id); 2287 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0) { 2288 send_resp(dut, conn, SIGMA_ERROR, 2289 "errorCode,Could not fetch provisioned key_mgmt"); 2290 goto out; 2291 } 2292 if (strncmp(buf, "SAE", 3) == 0) { 2293 /* SAE generates PMKSA-CACHE-ADDED event */ 2294 not_dpp_akm = 1; 2295 } 2296 wait_connect: 2297 if (frametype && strcasecmp(frametype, 2298 "PeerDiscoveryRequest") == 0) { 2299 if (dpp_wait_tx_status(dut, ctrl, 5) < 0) 2300 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Timeout"; 2301 else 2302 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Errorsent"; 2303 send_resp(dut, conn, SIGMA_COMPLETE, result); 2304 goto out; 2305 } 2306 2307 res = get_wpa_cli_events(dut, ctrl, conn_events, 2308 buf, sizeof(buf)); 2309 if (res < 0) { 2310 send_resp(dut, conn, SIGMA_COMPLETE, 2311 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Timeout,NetworkConnectResult,Timeout"); 2312 goto out; 2313 } 2314 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP connect result: %s", 2315 buf); 2316 2317 if (strstr(buf, "PMKSA-CACHE-ADDED")) { 2318 res = get_wpa_cli_events(dut, ctrl, conn_events, 2319 buf, sizeof(buf)); 2320 if (res < 0) { 2321 send_resp(dut, conn, SIGMA_COMPLETE, 2322 not_dpp_akm ? 2323 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkConnectResult,Timeout" : 2324 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,Timeout"); 2325 goto out; 2326 } 2327 sigma_dut_print(dut, DUT_MSG_DEBUG, 2328 "DPP connect result: %s", buf); 2329 if (strstr(buf, "CTRL-EVENT-CONNECTED")) 2330 send_resp(dut, conn, SIGMA_COMPLETE, 2331 not_dpp_akm ? 2332 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkConnectResult,OK" : 2333 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,OK"); 2334 else 2335 send_resp(dut, conn, SIGMA_COMPLETE, 2336 not_dpp_akm ? 2337 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkConnectResult,Timeout" : 2338 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,Timeout"); 2339 goto out; 2340 } 2341 2342 send_resp(dut, conn, SIGMA_COMPLETE, 2343 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkConnectResult,OK"); 2344 goto out; 2345 } 2346 2347 if (strcasecmp(wait_conn, "Yes") == 0 && 2348 frametype && strcasecmp(frametype, "PeerDiscoveryResponse") == 0) { 2349 if (dpp_wait_tx_status(dut, ctrl, 6) < 0) 2350 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Timeout"; 2351 else 2352 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Errorsent"; 2353 send_resp(dut, conn, SIGMA_COMPLETE, result); 2354 goto out; 2355 } 2356 2357 send_resp(dut, conn, SIGMA_COMPLETE, 2358 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK"); 2359 out: 2360 wpa_ctrl_detach(ctrl); 2361 wpa_ctrl_close(ctrl); 2362 if (tcp && strcasecmp(tcp, "yes") == 0 && 2363 auth_role && strcasecmp(auth_role, "Responder") == 0) 2364 wpa_command(ifname, "DPP_CONTROLLER_STOP"); 2365 dut->default_timeout = old_timeout; 2366 return STATUS_SENT; 2367 err: 2368 send_resp(dut, conn, SIGMA_ERROR, NULL); 2369 goto out; 2370 } 2371 2372 2373 static enum sigma_cmd_result dpp_manual_dpp(struct sigma_dut *dut, 2374 struct sigma_conn *conn, 2375 struct sigma_cmd *cmd) 2376 { 2377 const char *auth_role = get_param(cmd, "DPPAuthRole"); 2378 const char *self_conf = get_param(cmd, "DPPSelfConfigure"); 2379 enum sigma_cmd_result res = INVALID_SEND_STATUS; 2380 int success; 2381 const char *val; 2382 unsigned int old_timeout; 2383 const char *bs = get_param(cmd, "DPPBS"); 2384 2385 if (!auth_role) { 2386 send_resp(dut, conn, SIGMA_ERROR, 2387 "errorCode,Missing DPPAuthRole"); 2388 return STATUS_SENT_ERROR; 2389 } 2390 2391 if (!self_conf) 2392 self_conf = "no"; 2393 2394 old_timeout = dut->default_timeout; 2395 val = get_param(cmd, "DPPTimeout"); 2396 if (val && atoi(val) > 0) { 2397 dut->default_timeout = atoi(val); 2398 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP timeout: %u", 2399 dut->default_timeout); 2400 } 2401 2402 if (strcasecmp(bs, "NFC") == 0) { 2403 res = dpp_automatic_dpp(dut, conn, cmd); 2404 goto out; 2405 } 2406 2407 res = dpp_get_local_bootstrap(dut, conn, cmd, 0, &success); 2408 if (res != STATUS_SENT || !success) 2409 goto out; 2410 2411 if (strcasecmp(auth_role, "Responder") == 0) { 2412 if (dpp_display_own_qrcode(dut) < 0) { 2413 send_resp(dut, conn, SIGMA_ERROR, 2414 "errorCode,Failed to display own QR code"); 2415 res = STATUS_SENT_ERROR; 2416 goto out; 2417 } 2418 2419 res = dpp_automatic_dpp(dut, conn, cmd); 2420 goto out; 2421 } 2422 2423 if (strcasecmp(auth_role, "Initiator") == 0) { 2424 if (strcasecmp(self_conf, "Yes") != 0) { 2425 if (dpp_scan_peer_qrcode(dut) < 0) { 2426 send_resp(dut, conn, SIGMA_ERROR, 2427 "errorCode,Failed to scan peer QR Code"); 2428 res = STATUS_SENT_ERROR; 2429 goto out; 2430 } 2431 } 2432 2433 res = dpp_automatic_dpp(dut, conn, cmd); 2434 goto out; 2435 } 2436 2437 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unknown DPPAuthRole"); 2438 res = STATUS_SENT_ERROR; 2439 out: 2440 dut->default_timeout = old_timeout; 2441 return res; 2442 } 2443 2444 2445 enum sigma_cmd_result dpp_dev_exec_action(struct sigma_dut *dut, 2446 struct sigma_conn *conn, 2447 struct sigma_cmd *cmd) 2448 { 2449 const char *type = get_param(cmd, "DPPActionType"); 2450 const char *bs = get_param(cmd, "DPPBS"); 2451 2452 if (!bs) { 2453 send_resp(dut, conn, SIGMA_ERROR, 2454 "errorCode,Missing DPPBS"); 2455 return STATUS_SENT_ERROR; 2456 } 2457 2458 if (!type) { 2459 send_resp(dut, conn, SIGMA_ERROR, 2460 "errorCode,Missing DPPActionType"); 2461 return STATUS_SENT_ERROR; 2462 } 2463 2464 if (strcasecmp(type, "GetLocalBootstrap") == 0) 2465 return dpp_get_local_bootstrap(dut, conn, cmd, 1, NULL); 2466 if (strcasecmp(type, "SetPeerBootstrap") == 0) 2467 return dpp_set_peer_bootstrap(dut, conn, cmd); 2468 if (strcasecmp(type, "ManualDPP") == 0) 2469 return dpp_manual_dpp(dut, conn, cmd); 2470 if (strcasecmp(type, "AutomaticDPP") == 0) 2471 return dpp_automatic_dpp(dut, conn, cmd); 2472 2473 send_resp(dut, conn, SIGMA_ERROR, 2474 "errorCode,Unsupported DPPActionType"); 2475 return STATUS_SENT_ERROR; 2476 } 2477