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 extern char *sigma_cert_path; 16 17 #ifdef ANDROID 18 char *dpp_qrcode_file = "/sdcard/wpadebug_qrdata.txt"; 19 #endif /* ANDROID */ 20 21 22 static int sigma_dut_is_ap(struct sigma_dut *dut) 23 { 24 return dut->device_type == AP_unknown || 25 dut->device_type == AP_testbed || 26 dut->device_type == AP_dut; 27 } 28 29 30 static int dpp_hostapd_run(struct sigma_dut *dut) 31 { 32 if (dut->hostapd_running) 33 return 0; 34 35 sigma_dut_print(dut, DUT_MSG_INFO, 36 "Starting hostapd in unconfigured state for DPP"); 37 snprintf(dut->ap_ssid, sizeof(dut->ap_ssid), "unconfigured"); 38 if (!dut->ap_oper_chn) 39 dut->ap_channel = 11; 40 dut->ap_is_dual = 0; 41 dut->ap_mode = dut->ap_channel <= 14 ? AP_11ng : AP_11na; 42 dut->ap_key_mgmt = AP_OPEN; 43 dut->ap_cipher = AP_PLAIN; 44 if (!dut->ap_dpp_conf_addr || !dut->ap_dpp_conf_pkhash) 45 dut->ap_start_disabled = 1; 46 return cmd_ap_config_commit(dut, NULL, NULL) == 1 ? 0 : -1; 47 } 48 49 50 static int dpp_hostapd_beacon(struct sigma_dut *dut) 51 { 52 const char *ifname = dut->hostapd_ifname; 53 54 if (!dut->ap_start_disabled) 55 return 0; 56 57 sigma_dut_print(dut, DUT_MSG_INFO, "Start beaconing"); 58 if (!ifname || 59 wpa_command(ifname, "SET start_disabled 0") < 0 || 60 wpa_command(ifname, "DISABLE") < 0 || 61 wpa_command(ifname, "ENABLE") < 0) 62 return -1; 63 64 dut->ap_start_disabled = 0; 65 return 0; 66 } 67 68 69 static const char * dpp_get_curve(struct sigma_cmd *cmd, const char *arg) 70 { 71 const char *val = get_param(cmd, arg); 72 73 if (!val) 74 val = "P-256"; 75 else if (strcasecmp(val, "BP-256R1") == 0) 76 val = "BP-256"; 77 else if (strcasecmp(val, "BP-384R1") == 0) 78 val = "BP-384"; 79 else if (strcasecmp(val, "BP-512R1") == 0) 80 val = "BP-512"; 81 82 return val; 83 } 84 85 86 static enum sigma_cmd_result 87 dpp_get_local_bootstrap(struct sigma_dut *dut, struct sigma_conn *conn, 88 struct sigma_cmd *cmd, int send_result, int *success) 89 { 90 const char *curve = dpp_get_curve(cmd, "DPPCryptoIdentifier"); 91 const char *bs = get_param(cmd, "DPPBS"); 92 const char *chan_list = get_param(cmd, "DPPChannelList"); 93 char *pos, mac[50], buf[200], resp[1000], hex[2000]; 94 const char *ifname = get_station_ifname(dut); 95 int res; 96 const char *type; 97 98 if (success) 99 *success = 0; 100 if (strcasecmp(bs, "QR") == 0) { 101 type = "qrcode"; 102 } else if (strcasecmp(bs, "NFC") == 0) { 103 type ="nfc-uri"; 104 } else { 105 send_resp(dut, conn, SIGMA_ERROR, 106 "errorCode,Unsupported DPPBS"); 107 return STATUS_SENT_ERROR; 108 } 109 110 if (sigma_dut_is_ap(dut)) { 111 u8 bssid[ETH_ALEN]; 112 113 if (!dut->hostapd_ifname) { 114 sigma_dut_print(dut, DUT_MSG_ERROR, 115 "hostapd ifname not specified (-j)"); 116 return ERROR_SEND_STATUS; 117 } 118 ifname = dut->hostapd_ifname; 119 if (get_hwaddr(dut->hostapd_ifname, bssid) < 0) { 120 sigma_dut_print(dut, DUT_MSG_ERROR, 121 "Could not get MAC address for %s", 122 dut->hostapd_ifname); 123 return ERROR_SEND_STATUS; 124 } 125 snprintf(mac, sizeof(mac), "%02x%02x%02x%02x%02x%02x", 126 bssid[0], bssid[1], bssid[2], 127 bssid[3], bssid[4], bssid[5]); 128 } else { 129 if (get_wpa_status(ifname, "address", mac, sizeof(mac)) < 0) { 130 send_resp(dut, conn, SIGMA_ERROR, 131 "errorCode,Failed to get own MAC address from wpa_supplicant"); 132 return STATUS_SENT_ERROR; 133 } 134 } 135 136 pos = mac; 137 while (*pos) { 138 if (*pos == ':') 139 memmove(pos, pos + 1, strlen(pos)); 140 else 141 pos++; 142 } 143 144 if (sigma_dut_is_ap(dut) && dpp_hostapd_run(dut) < 0) { 145 send_resp(dut, conn, SIGMA_ERROR, 146 "errorCode,Failed to start hostapd"); 147 return STATUS_SENT_ERROR; 148 } 149 150 if (chan_list && 151 (strcmp(chan_list, "0/0") == 0 || chan_list[0] == '\0')) { 152 /* No channel list */ 153 res = snprintf(buf, sizeof(buf), 154 "DPP_BOOTSTRAP_GEN type=%s curve=%s mac=%s", 155 type, curve, mac); 156 } else if (chan_list) { 157 /* Channel list override (CTT case) - space separated tuple(s) 158 * of OperatingClass/Channel; convert to wpa_supplicant/hostapd 159 * format: comma separated tuples */ 160 strlcpy(resp, chan_list, sizeof(resp)); 161 for (pos = resp; *pos; pos++) { 162 if (*pos == ' ') 163 *pos = ','; 164 } 165 res = snprintf(buf, sizeof(buf), 166 "DPP_BOOTSTRAP_GEN type=%s curve=%s chan=%s mac=%s", 167 type, curve, resp, mac); 168 } else { 169 int channel = 11; 170 171 /* Default channel list (normal DUT case) */ 172 if (sigma_dut_is_ap(dut) && dut->hostapd_running && 173 dut->ap_oper_chn && 174 dut->ap_channel > 0 && dut->ap_channel <= 13) 175 channel = dut->ap_channel; 176 res = snprintf(buf, sizeof(buf), 177 "DPP_BOOTSTRAP_GEN type=%s curve=%s chan=81/%d mac=%s", 178 type, curve, channel, mac); 179 } 180 181 if (res < 0 || res >= sizeof(buf) || 182 wpa_command_resp(ifname, buf, resp, sizeof(resp)) < 0 || 183 strncmp(resp, "FAIL", 4) == 0) 184 return ERROR_SEND_STATUS; 185 dut->dpp_local_bootstrap = atoi(resp); 186 snprintf(buf, sizeof(buf), "DPP_BOOTSTRAP_GET_URI %d", 187 atoi(resp)); 188 if (wpa_command_resp(ifname, buf, resp, sizeof(resp)) < 0 || 189 strncmp(resp, "FAIL", 4) == 0) 190 return ERROR_SEND_STATUS; 191 192 sigma_dut_print(dut, DUT_MSG_DEBUG, "URI: %s", resp); 193 194 if (send_result) { 195 ascii2hexstr(resp, hex); 196 res = snprintf(resp, sizeof(resp), "BootstrappingData,%s", hex); 197 send_resp(dut, conn, SIGMA_COMPLETE, 198 res >= 0 && res < sizeof(resp) ? resp : NULL); 199 } 200 201 if (success) 202 *success = 1; 203 return STATUS_SENT; 204 } 205 206 207 static enum sigma_cmd_result dpp_set_peer_bootstrap(struct sigma_dut *dut, 208 struct sigma_conn *conn, 209 struct sigma_cmd *cmd) 210 { 211 const char *val = get_param(cmd, "DPPBootstrappingdata"); 212 char uri[1000]; 213 int res; 214 215 if (!val) { 216 send_resp(dut, conn, SIGMA_ERROR, 217 "errorCode,Missing DPPBootstrappingdata"); 218 return STATUS_SENT_ERROR; 219 } 220 221 res = parse_hexstr(val, (unsigned char *) uri, sizeof(uri)); 222 if (res < 0 || (size_t) res >= sizeof(uri)) 223 return ERROR_SEND_STATUS; 224 uri[res] = '\0'; 225 sigma_dut_print(dut, DUT_MSG_DEBUG, "URI: %s", uri); 226 free(dut->dpp_peer_uri); 227 dut->dpp_peer_uri = strdup(uri); 228 229 return SUCCESS_SEND_STATUS; 230 } 231 232 233 static int dpp_hostapd_conf_update(struct sigma_dut *dut, 234 struct sigma_conn *conn, const char *ifname, 235 struct wpa_ctrl *ctrl) 236 { 237 int res; 238 char buf[2000], buf2[2500], *pos, *pos2; 239 const char *conf_data_events[] = { 240 "DPP-CONNECTOR", 241 "DPP-CONFOBJ-PASS", 242 "DPP-CONFOBJ-PSK", 243 "DPP-C-SIGN-KEY", 244 "DPP-NET-ACCESS-KEY", 245 NULL 246 }; 247 unsigned int old_timeout; 248 int legacy_akm, dpp_akm; 249 char *connector = NULL, *psk = NULL, *csign = NULL, 250 *net_access_key = NULL; 251 char pass[64]; 252 int pass_len = 0; 253 int ret = 0; 254 255 sigma_dut_print(dut, DUT_MSG_INFO, 256 "Update hostapd configuration based on DPP Config Object"); 257 258 if (wpa_command(ifname, "SET wpa 2") < 0 || 259 wpa_command(ifname, "SET wpa_key_mgmt DPP") < 0 || 260 wpa_command(ifname, "SET ieee80211w 1") < 0 || 261 wpa_command(ifname, "SET rsn_pairwise CCMP") < 0) { 262 send_resp(dut, conn, SIGMA_ERROR, 263 "errorCode,Failed to update AP security parameters"); 264 goto out; 265 } 266 267 res = get_wpa_cli_event(dut, ctrl, "DPP-CONFOBJ-AKM", buf, sizeof(buf)); 268 if (res < 0) { 269 send_resp(dut, conn, SIGMA_ERROR, 270 "errorCode,No DPP-CONFOBJ-AKM"); 271 goto out; 272 } 273 pos = strchr(buf, ' '); 274 if (!pos) 275 return -2; 276 pos++; 277 sigma_dut_print(dut, DUT_MSG_INFO, 278 "DPP: Config Object AKM: %s", pos); 279 legacy_akm = strstr(pos, "psk") != NULL || strstr(pos, "sae") != NULL; 280 dpp_akm = strstr(pos, "dpp") != NULL; 281 282 res = get_wpa_cli_event(dut, ctrl, "DPP-CONFOBJ-SSID", 283 buf, sizeof(buf)); 284 if (res < 0) { 285 send_resp(dut, conn, SIGMA_ERROR, 286 "errorCode,No DPP-CONFOBJ-SSID"); 287 goto out; 288 } 289 pos = strchr(buf, ' '); 290 if (!pos) 291 return -2; 292 pos++; 293 sigma_dut_print(dut, DUT_MSG_INFO, 294 "DPP: Config Object SSID: %s", pos); 295 snprintf(buf2, sizeof(buf2), "SET ssid %s", pos); 296 if (wpa_command(ifname, buf2) < 0) { 297 send_resp(dut, conn, SIGMA_ERROR, 298 "errorCode,Failed to update AP SSID"); 299 goto out; 300 } 301 302 if (wpa_command(ifname, "SET utf8_ssid 1") < 0) { 303 send_resp(dut, conn, SIGMA_ERROR, 304 "errorCode,Failed to update AP UTF-8 SSID capa"); 305 goto out; 306 } 307 308 while ((dpp_akm && (!connector || !csign || !net_access_key)) || 309 (legacy_akm && !pass_len && !psk)) { 310 res = get_wpa_cli_events(dut, ctrl, conf_data_events, 311 buf, sizeof(buf)); 312 if (res < 0) { 313 send_resp(dut, conn, SIGMA_ERROR, 314 "errorCode,Not all config object information received"); 315 goto out; 316 } 317 318 if (strstr(buf, "DPP-CONNECTOR")) { 319 pos = strchr(buf, ' '); 320 if (!pos) { 321 ret = -2; 322 goto out; 323 } 324 pos++; 325 sigma_dut_print(dut, DUT_MSG_INFO, "DPP: Connector: %s", 326 pos); 327 if (!connector) 328 connector = strdup(pos); 329 } else if (strstr(buf, "DPP-C-SIGN-KEY")) { 330 pos = strchr(buf, ' '); 331 if (!pos) { 332 ret = -2; 333 goto out; 334 } 335 pos++; 336 sigma_dut_print(dut, DUT_MSG_INFO, 337 "DPP: C-sign-key: %s", pos); 338 if (!csign) 339 csign = strdup(pos); 340 } else if (strstr(buf, "DPP-NET-ACCESS-KEY")) { 341 pos = strchr(buf, ' '); 342 if (!pos) { 343 ret = -2; 344 goto out; 345 } 346 pos++; 347 if (!net_access_key) 348 net_access_key = strdup(pos); 349 } else if (strstr(buf, "DPP-CONFOBJ-PASS")) { 350 pos = strchr(buf, ' '); 351 if (!pos) { 352 ret = -2; 353 goto out; 354 } 355 pos++; 356 pass_len = parse_hexstr(pos, (u8 *) pass, sizeof(pass)); 357 if (pass_len < 0 || (size_t) pass_len >= sizeof(pass)) { 358 ret = -2; 359 goto out; 360 } 361 pass[pass_len] = '\0'; 362 sigma_dut_print(dut, DUT_MSG_INFO, 363 "DPP: Passphrase: %s", pass); 364 } else if (strstr(buf, "DPP-CONFOBJ-PSK")) { 365 pos = strchr(buf, ' '); 366 if (!pos) { 367 ret = -2; 368 goto out; 369 } 370 pos++; 371 sigma_dut_print(dut, DUT_MSG_INFO, "DPP: PSK: %s", pos); 372 if (!psk) 373 psk = strdup(pos); 374 } 375 } 376 377 if ((!connector || !dpp_akm) && 378 wpa_command(ifname, "SET wpa_key_mgmt WPA-PSK") < 0) { 379 send_resp(dut, conn, SIGMA_ERROR, 380 "errorCode,Failed to update AP security parameters"); 381 goto out; 382 } 383 384 if (connector && dpp_akm && legacy_akm && 385 wpa_command(ifname, "SET wpa_key_mgmt DPP WPA-PSK") < 0) { 386 send_resp(dut, conn, SIGMA_ERROR, 387 "errorCode,Failed to update AP security parameters"); 388 goto out; 389 } 390 391 if (pass_len) { 392 snprintf(buf2, sizeof(buf2), "SET wpa_passphrase %s", 393 pass); 394 if (wpa_command(ifname, buf2) < 0) { 395 send_resp(dut, conn, SIGMA_ERROR, 396 "errorCode,Failed to set passphrase"); 397 goto out; 398 } 399 } else if (psk) { 400 snprintf(buf2, sizeof(buf2), "SET wpa_psk %s", psk); 401 if (wpa_command(ifname, buf2) < 0) { 402 send_resp(dut, conn, SIGMA_ERROR, 403 "errorCode,Failed to set PSK"); 404 goto out; 405 } 406 } 407 408 if (connector) { 409 snprintf(buf2, sizeof(buf2), "SET dpp_connector %s", connector); 410 if (wpa_command(ifname, buf2) < 0) { 411 send_resp(dut, conn, SIGMA_ERROR, 412 "errorCode,Failed to update AP Connector"); 413 goto out; 414 } 415 } 416 417 if (csign) { 418 snprintf(buf2, sizeof(buf2), "SET dpp_csign %s", csign); 419 if (wpa_command(ifname, buf2) < 0) { 420 send_resp(dut, conn, SIGMA_ERROR, 421 "errorCode,Failed to update AP C-sign-key"); 422 goto out; 423 } 424 } 425 426 if (net_access_key) { 427 pos2 = strchr(net_access_key, ' '); 428 if (pos2) 429 *pos2++ = '\0'; 430 sigma_dut_print(dut, DUT_MSG_INFO, "DPP: netAccessKey: %s", 431 net_access_key); 432 snprintf(buf2, sizeof(buf2), "SET dpp_netaccesskey %s", 433 net_access_key); 434 if (wpa_command(ifname, buf2) < 0) { 435 send_resp(dut, conn, SIGMA_ERROR, 436 "errorCode,Failed to update AP netAccessKey"); 437 goto out; 438 } 439 if (pos2) { 440 sigma_dut_print(dut, DUT_MSG_INFO, 441 "DPP: netAccessKey expiry: %s", pos2); 442 snprintf(buf2, sizeof(buf2), 443 "SET dpp_netaccesskey_expiry %s", pos2); 444 if (wpa_command(ifname, buf2) < 0) { 445 send_resp(dut, conn, SIGMA_ERROR, 446 "errorCode,Failed to update AP netAccessKey expiry"); 447 goto out; 448 } 449 } 450 } 451 452 if (dut->ap_start_disabled) 453 sigma_dut_print(dut, DUT_MSG_INFO, "Clear ap_start_disabled"); 454 if (wpa_command(ifname, "SET start_disabled 0") < 0 && 455 dut->ap_start_disabled) { 456 send_resp(dut, conn, SIGMA_ERROR, 457 "errorCode,Failed to update AP security parameters"); 458 goto out; 459 } 460 dut->ap_start_disabled = 0; 461 462 /* Wait for a possible Configuration Result to be sent */ 463 old_timeout = dut->default_timeout; 464 dut->default_timeout = 1; 465 get_wpa_cli_event(dut, ctrl, "DPP-TX-STATUS", buf, sizeof(buf)); 466 dut->default_timeout = old_timeout; 467 468 if (dut->ap_oper_chn) { 469 sigma_dut_print(dut, DUT_MSG_INFO, 470 "Set AP operating channel %d", 471 dut->ap_channel); 472 snprintf(buf, sizeof(buf), "SET channel %d", dut->ap_channel); 473 wpa_command(ifname, buf); 474 } 475 if (wpa_command(ifname, "DISABLE") < 0 || 476 wpa_command(ifname, "ENABLE") < 0) { 477 send_resp(dut, conn, SIGMA_ERROR, 478 "errorCode,Failed to update AP configuration"); 479 goto out; 480 } 481 482 res = get_wpa_cli_event(dut, ctrl, "AP-ENABLED", buf, sizeof(buf)); 483 if (res < 0) { 484 send_resp(dut, conn, SIGMA_ERROR, "errorCode,No AP-ENABLED"); 485 goto out; 486 } 487 488 ret = 1; 489 out: 490 free(connector); 491 free(psk); 492 free(csign); 493 free(net_access_key); 494 return ret; 495 } 496 497 498 struct dpp_test_info { 499 const char *step; 500 const char *frame; 501 const char *attr; 502 int value; 503 }; 504 505 static const struct dpp_test_info dpp_tests[] = { 506 { "InvalidValue", "AuthenticationRequest", "WrappedData", 1 }, 507 { "InvalidValue", "AuthenticationResponse", "WrappedData", 2 }, 508 { "InvalidValue", "AuthenticationResponse", "PrimaryWrappedData", 2 }, 509 { "InvalidValue", "AuthenticationConfirm", "WrappedData", 3 }, 510 { "InvalidValue", "PKEXCRRequest", "WrappedData", 4 }, 511 { "InvalidValue", "PKEXCRResponse", "WrappedData", 5 }, 512 { "InvalidValue", "ConfigurationRequest", "WrappedData", 6 }, 513 { "InvalidValue", "ConfigurationResponse", "WrappedData", 7 }, 514 { "InvalidValue", "AuthenticationRequest", "InitCapabilities", 8 }, 515 { "MissingAttribute", "AuthenticationRequest", "RespBSKeyHash", 10 }, 516 { "MissingAttribute", "AuthenticationRequest", "InitBSKeyHash", 11 }, 517 { "MissingAttribute", "AuthenticationRequest", "InitProtocolKey", 12 }, 518 { "MissingAttribute", "AuthenticationRequest", "InitNonce", 13 }, 519 { "MissingAttribute", "AuthenticationRequest", "InitCapabilities", 14 }, 520 { "MissingAttribute", "AuthenticationRequest", "WrappedData", 15 }, 521 { "MissingAttribute", "AuthenticationResponse", "DPPStatus", 16 }, 522 { "MissingAttribute", "AuthenticationResponse", "RespBSKeyHash", 17 }, 523 { "MissingAttribute", "AuthenticationResponse", "InitBSKeyHash", 18 }, 524 { "MissingAttribute", "AuthenticationResponse", "RespProtocolKey", 19 }, 525 { "MissingAttribute", "AuthenticationResponse", "RespNonce", 20 }, 526 { "MissingAttribute", "AuthenticationResponse", "InitNonce", 21 }, 527 { "MissingAttribute", "AuthenticationResponse", "RespCapabilities", 528 22 }, 529 { "MissingAttribute", "AuthenticationResponse", "RespAuthTag", 23 }, 530 { "MissingAttribute", "AuthenticationResponse", "WrappedData", 24 }, 531 { "MissingAttribute", "AuthenticationResponse", "PrimaryWrappedData", 532 24 }, 533 { "MissingAttribute", "AuthenticationConfirm", "DPPStatus", 25 }, 534 { "MissingAttribute", "AuthenticationConfirm", "RespBSKeyHash", 26 }, 535 { "MissingAttribute", "AuthenticationConfirm", "InitBSKeyHash", 27 }, 536 { "MissingAttribute", "AuthenticationConfirm", "InitAuthTag", 28 }, 537 { "MissingAttribute", "AuthenticationConfirm", "WrappedData", 29 }, 538 { "InvalidValue", "AuthenticationResponse", "InitNonce", 30 }, 539 { "InvalidValue", "AuthenticationResponse", "RespCapabilities", 31 }, 540 { "InvalidValue", "AuthenticationResponse", "RespAuthTag", 32 }, 541 { "InvalidValue", "AuthenticationConfirm", "InitAuthTag", 33 }, 542 { "MissingAttribute", "PKEXExchangeRequest", "FiniteCyclicGroup", 34 }, 543 { "MissingAttribute", "PKEXExchangeRequest", "EncryptedKey", 35 }, 544 { "MissingAttribute", "PKEXExchangeResponse", "DPPStatus", 36 }, 545 { "MissingAttribute", "PKEXExchangeResponse", "EncryptedKey", 37 }, 546 { "MissingAttribute", "PKEXCRRequest", "BSKey", 38 }, 547 { "MissingAttribute", "PKEXCRRequest", "InitAuthTag", 39 }, 548 { "MissingAttribute", "PKEXCRRequest", "WrappedData", 40 }, 549 { "MissingAttribute", "PKEXCRResponse", "BSKey", 41 }, 550 { "MissingAttribute", "PKEXCRResponse", "RespAuthTag", 42 }, 551 { "MissingAttribute", "PKEXCRResponse", "WrappedData", 43 }, 552 { "InvalidValue", "PKEXExchangeRequest", "EncryptedKey", 44 }, 553 { "InvalidValue", "PKEXExchangeResponse", "EncryptedKey", 45 }, 554 { "InvalidValue", "PKEXExchangeResponse", "DPPStatus", 46 }, 555 { "InvalidValue", "PKEXCRRequest", "BSKey", 47 }, 556 { "InvalidValue", "PKEXCRResponse", "BSKey", 48 }, 557 { "InvalidValue", "PKEXCRRequest", "InitAuthTag", 49 }, 558 { "InvalidValue", "PKEXCRResponse", "RespAuthTag", 50 }, 559 { "MissingAttribute", "ConfigurationRequest", "EnrolleeNonce", 51 }, 560 { "MissingAttribute", "ConfigurationRequest", "ConfigAttr", 52 }, 561 { "MissingAttribute", "ConfigurationRequest", "WrappedData", 53 }, 562 { "MissingAttribute", "ConfigurationResponse", "EnrolleeNonce", 54 }, 563 { "MissingAttribute", "ConfigurationResponse", "ConfigObj", 55 }, 564 { "MissingAttribute", "ConfigurationResponse", "DPPStatus", 56 }, 565 { "MissingAttribute", "ConfigurationResponse", "WrappedData", 57 }, 566 { "InvalidValue", "ConfigurationResponse", "DPPStatus", 58 }, 567 { "InvalidValue", "ConfigurationResponse", "EnrolleeNonce", 59 }, 568 { "MissingAttribute", "PeerDiscoveryRequest", "TransactionID", 60 }, 569 { "MissingAttribute", "PeerDiscoveryRequest", "Connector", 61 }, 570 { "MissingAttribute", "PeerDiscoveryResponse", "TransactionID", 62 }, 571 { "MissingAttribute", "PeerDiscoveryResponse", "DPPStatus", 63 }, 572 { "MissingAttribute", "PeerDiscoveryResponse", "Connector", 64 }, 573 { "InvalidValue", "AuthenticationRequest", "InitProtocolKey", 66 }, 574 { "InvalidValue", "AuthenticationResponse", "RespProtocolKey", 67 }, 575 { "InvalidValue", "AuthenticationRequest", "RespBSKeyHash", 68 }, 576 { "InvalidValue", "AuthenticationRequest", "InitBSKeyHash", 69 }, 577 { "InvalidValue", "AuthenticationResponse", "RespBSKeyHash", 70 }, 578 { "InvalidValue", "AuthenticationResponse", "InitBSKeyHash", 71 }, 579 { "InvalidValue", "AuthenticationConfirm", "RespBSKeyHash", 72 }, 580 { "InvalidValue", "AuthenticationConfirm", "InitBSKeyHash", 73 }, 581 { "InvalidValue", "AuthenticationResponse", "DPPStatus", 74 }, 582 { "InvalidValue", "AuthenticationConfirm", "DPPStatus", 75 }, 583 { "InvalidValue", "ConfigurationRequest", "ConfigAttr", 76 }, 584 { "InvalidValue", "PeerDiscoveryResponse", "TransactionID", 77 }, 585 { "InvalidValue", "PeerDiscoveryResponse", "DPPStatus", 78 }, 586 { "InvalidValue", "PeerDiscoveryResponse", "Connector", 79 }, 587 { "InvalidValue", "PeerDiscoveryRequest", "Connector", 80 }, 588 { "InvalidValue", "AuthenticationRequest", "InitNonce", 81 }, 589 { "InvalidValue", "PeerDiscoveryRequest", "TransactionID", 82 }, 590 { "InvalidValue", "ConfigurationRequest", "EnrolleeNonce", 83 }, 591 { "Timeout", "PKEXExchangeResponse", NULL, 84 }, 592 { "Timeout", "PKEXCRRequest", NULL, 85 }, 593 { "Timeout", "PKEXCRResponse", NULL, 86 }, 594 { "Timeout", "AuthenticationRequest", NULL, 87 }, 595 { "Timeout", "AuthenticationResponse", NULL, 88 }, 596 { "Timeout", "AuthenticationConfirm", NULL, 89 }, 597 { "Timeout", "ConfigurationRequest", NULL, 90 }, 598 { NULL, NULL, NULL, 0 } 599 }; 600 601 602 static int dpp_get_test(const char *step, const char *frame, const char *attr) 603 { 604 int i; 605 606 for (i = 0; dpp_tests[i].step; i++) { 607 if (strcasecmp(step, dpp_tests[i].step) == 0 && 608 strcasecmp(frame, dpp_tests[i].frame) == 0 && 609 ((!attr && dpp_tests[i].attr == NULL) || 610 (attr && strcasecmp(attr, dpp_tests[i].attr) == 0))) 611 return dpp_tests[i].value; 612 } 613 614 return -1; 615 } 616 617 618 static int dpp_wait_tx(struct sigma_dut *dut, struct wpa_ctrl *ctrl, 619 int frame_type) 620 { 621 char buf[200], tmp[20]; 622 int res; 623 624 snprintf(tmp, sizeof(tmp), "type=%d", frame_type); 625 for (;;) { 626 res = get_wpa_cli_event(dut, ctrl, "DPP-TX", buf, sizeof(buf)); 627 if (res < 0) 628 return -1; 629 if (strstr(buf, tmp) != NULL) 630 break; 631 } 632 633 return 0; 634 } 635 636 637 static int dpp_wait_tx_status(struct sigma_dut *dut, struct wpa_ctrl *ctrl, 638 int frame_type) 639 { 640 char buf[200], tmp[20]; 641 int res; 642 643 snprintf(tmp, sizeof(tmp), "type=%d", frame_type); 644 for (;;) { 645 res = get_wpa_cli_event(dut, ctrl, "DPP-TX", buf, sizeof(buf)); 646 if (res < 0) 647 return -1; 648 if (strstr(buf, tmp) != NULL) 649 break; 650 } 651 652 res = get_wpa_cli_event(dut, ctrl, "DPP-TX-STATUS", 653 buf, sizeof(buf)); 654 if (res < 0 || strstr(buf, "result=FAILED") != NULL) 655 return -1; 656 657 return 0; 658 } 659 660 661 static int dpp_wait_rx(struct sigma_dut *dut, struct wpa_ctrl *ctrl, 662 int frame_type, unsigned int max_wait) 663 { 664 char buf[200], tmp[20]; 665 int res; 666 unsigned int old_timeout; 667 668 old_timeout = dut->default_timeout; 669 if (max_wait > 0 && dut->default_timeout > max_wait) 670 dut->default_timeout = max_wait; 671 672 snprintf(tmp, sizeof(tmp), "type=%d", frame_type); 673 for (;;) { 674 res = get_wpa_cli_event(dut, ctrl, "DPP-RX", buf, sizeof(buf)); 675 if (res < 0) { 676 dut->default_timeout = old_timeout; 677 return -1; 678 } 679 if (strstr(buf, tmp) != NULL) 680 break; 681 } 682 683 dut->default_timeout = old_timeout; 684 return 0; 685 } 686 687 688 static int dpp_wait_rx_conf_req(struct sigma_dut *dut, struct wpa_ctrl *ctrl, 689 unsigned int max_wait) 690 { 691 char buf[200]; 692 int res; 693 unsigned int old_timeout; 694 695 old_timeout = dut->default_timeout; 696 if (max_wait > 0 && dut->default_timeout > max_wait) 697 dut->default_timeout = max_wait; 698 699 for (;;) { 700 res = get_wpa_cli_event(dut, ctrl, "DPP-CONF-REQ-RX", 701 buf, sizeof(buf)); 702 if (res < 0) { 703 dut->default_timeout = old_timeout; 704 return -1; 705 } 706 707 break; 708 } 709 710 dut->default_timeout = old_timeout; 711 return 0; 712 } 713 714 715 static int dpp_scan_peer_qrcode(struct sigma_dut *dut) 716 { 717 #ifdef ANDROID 718 char buf[100]; 719 char *buf2 = NULL; 720 FILE *fp = NULL; 721 uint32_t length; 722 unsigned int count; 723 724 unlink(dpp_qrcode_file); 725 726 snprintf(buf, sizeof(buf), 727 "am start -n w1.fi.wpadebug/w1.fi.wpadebug.QrCodeReadActivity"); 728 if (system(buf) != 0) { 729 sigma_dut_print(dut, DUT_MSG_ERROR, 730 "Failed to launch QR Code scanner"); 731 return -1; 732 } 733 734 count = 0; 735 while (!(fp = fopen(dpp_qrcode_file, "r"))) { 736 if (count > dut->default_timeout) { 737 sigma_dut_print(dut, DUT_MSG_ERROR, 738 "Failed to open dpp_qrcode_file - QR Code scanning timed out"); 739 return -1; 740 } 741 742 sleep(1); 743 count++; 744 } 745 746 if (fseek(fp, 0, SEEK_END) < 0 || (length = ftell(fp)) <= 0 || 747 fseek(fp, 0, SEEK_SET) < 0) { 748 sigma_dut_print(dut, DUT_MSG_ERROR, 749 "Failed to get QR Code result file length"); 750 fclose(fp); 751 return -1; 752 } 753 754 buf2 = malloc(length + 1); 755 if (!buf2) { 756 fclose(fp); 757 return -1; 758 } 759 760 if (fread(buf2, 1, length, fp) != length) { 761 fclose(fp); 762 free(buf2); 763 return -1; 764 } 765 766 fclose(fp); 767 buf2[length] = '\0'; 768 769 free(dut->dpp_peer_uri); 770 dut->dpp_peer_uri = strdup(buf2); 771 free(buf2); 772 return 0; 773 #else /* ANDROID */ 774 pid_t pid; 775 int pid_status; 776 int pipe_out[2]; 777 char buf[4000], *pos; 778 ssize_t len; 779 int res = -1, ret; 780 struct timeval tv; 781 fd_set rfd; 782 783 if (pipe(pipe_out) != 0) { 784 perror("pipe"); 785 return -1; 786 } 787 788 pid = fork(); 789 if (pid < 0) { 790 perror("fork"); 791 close(pipe_out[0]); 792 close(pipe_out[1]); 793 return -1; 794 } 795 796 if (pid == 0) { 797 char *argv[4] = { "zbarcam", "--raw", "--prescale=320x240", 798 NULL }; 799 800 dup2(pipe_out[1], STDOUT_FILENO); 801 close(pipe_out[0]); 802 close(pipe_out[1]); 803 execv("/usr/bin/zbarcam", argv); 804 perror("execv"); 805 exit(0); 806 return -1; 807 } 808 809 close(pipe_out[1]); 810 811 FD_ZERO(&rfd); 812 FD_SET(pipe_out[0], &rfd); 813 tv.tv_sec = dut->default_timeout; 814 tv.tv_usec = 0; 815 816 ret = select(pipe_out[0] + 1, &rfd, NULL, NULL, &tv); 817 if (ret < 0) { 818 perror("select"); 819 goto out; 820 } 821 if (ret == 0) { 822 sigma_dut_print(dut, DUT_MSG_DEBUG, 823 "QR Code scanning timed out"); 824 goto out; 825 } 826 827 len = read(pipe_out[0], buf, sizeof(buf)); 828 if (len <= 0) 829 goto out; 830 if (len == sizeof(buf)) 831 len--; 832 buf[len] = '\0'; 833 pos = strchr(buf, '\n'); 834 if (pos) 835 *pos = '\0'; 836 sigma_dut_print(dut, DUT_MSG_DEBUG, "URI from QR scanner: %s", buf); 837 838 free(dut->dpp_peer_uri); 839 dut->dpp_peer_uri = strdup(buf); 840 res = 0; 841 out: 842 close(pipe_out[0]); 843 kill(pid, SIGTERM); 844 waitpid(pid, &pid_status, 0); 845 846 return res; 847 #endif /* ANDROID */ 848 } 849 850 851 static int dpp_display_own_qrcode(struct sigma_dut *dut) 852 { 853 char buf[200], resp[2000]; 854 const char *ifname = get_station_ifname(dut); 855 #ifdef ANDROID 856 FILE *fp; 857 #else /* ANDROID */ 858 pid_t pid; 859 int pid_status; 860 #endif /* ANDROID */ 861 862 snprintf(buf, sizeof(buf), "DPP_BOOTSTRAP_GET_URI %d", 863 dut->dpp_local_bootstrap); 864 if (wpa_command_resp(ifname, buf, resp, sizeof(resp)) < 0 || 865 strncmp(resp, "FAIL", 4) == 0) 866 return -2; 867 sigma_dut_print(dut, DUT_MSG_DEBUG, "Own bootstrap URI: %s", resp); 868 869 #ifdef ANDROID 870 unlink(dpp_qrcode_file); 871 872 fp = fopen(dpp_qrcode_file, "w"); 873 if (!fp) { 874 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open file %s", 875 dpp_qrcode_file); 876 return -2; 877 } 878 879 fwrite(resp, 1, strlen(resp), fp); 880 fclose(fp); 881 882 snprintf(buf, sizeof(buf), 883 "am start -n w1.fi.wpadebug/w1.fi.wpadebug.QrCodeDisplayActivity"); 884 if (system(buf) != 0) { 885 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to display QR Code"); 886 return -1; 887 } 888 #else /* ANDROID */ 889 pid = fork(); 890 if (pid < 0) { 891 perror("fork"); 892 return -1; 893 } 894 895 if (pid == 0) { 896 char *argv[3] = { "qr", resp, NULL }; 897 898 execv("/usr/bin/qr", argv); 899 perror("execv"); 900 exit(0); 901 return -1; 902 } 903 904 waitpid(pid, &pid_status, 0); 905 #endif /* ANDROID */ 906 907 return 0; 908 } 909 910 911 static int dpp_process_auth_response(struct sigma_dut *dut, 912 struct sigma_conn *conn, 913 struct wpa_ctrl *ctrl, 914 const char **auth_events, 915 const char *action_type, 916 int check_mutual, char *buf, size_t buflen) 917 { 918 int res; 919 920 res = get_wpa_cli_events(dut, ctrl, auth_events, buf, buflen); 921 if (res < 0) { 922 send_resp(dut, conn, SIGMA_COMPLETE, 923 "BootstrapResult,OK,AuthResult,Timeout"); 924 return res; 925 } 926 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP auth result: %s", buf); 927 928 if (strstr(buf, "DPP-RESPONSE-PENDING")) { 929 /* Display own QR code in manual mode */ 930 if (action_type && strcasecmp(action_type, "ManualDPP") == 0 && 931 dpp_display_own_qrcode(dut) < 0) { 932 send_resp(dut, conn, SIGMA_ERROR, 933 "errorCode,Failed to display own QR code"); 934 return -1; 935 } 936 937 /* Wait for the actual result after the peer has scanned the 938 * QR Code. */ 939 res = get_wpa_cli_events(dut, ctrl, auth_events, 940 buf, buflen); 941 if (res < 0) { 942 send_resp(dut, conn, SIGMA_COMPLETE, 943 "BootstrapResult,OK,AuthResult,Timeout"); 944 return res; 945 } 946 947 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP auth result: %s", buf); 948 } else if (strstr(buf, "DPP-AUTH-INIT-FAILED")) { 949 send_resp(dut, conn, SIGMA_ERROR, 950 "errorCode,Peer did not reply to DPP Authentication Request"); 951 return -1; 952 } 953 954 if (check_mutual) { 955 if (strstr(buf, "DPP-NOT-COMPATIBLE")) { 956 send_resp(dut, conn, SIGMA_COMPLETE, 957 "BootstrapResult,OK,AuthResult,ROLES_NOT_COMPATIBLE"); 958 return -1; 959 } 960 961 if (!strstr(buf, "DPP-AUTH-DIRECTION")) { 962 send_resp(dut, conn, SIGMA_ERROR, 963 "errorCode,No event for auth direction seen"); 964 return -1; 965 } 966 967 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP auth direction: %s", 968 buf); 969 if (strstr(buf, "mutual=1") == NULL) { 970 send_resp(dut, conn, SIGMA_ERROR, 971 "errorCode,Peer did not use mutual authentication"); 972 return -1; 973 } 974 } 975 976 return 0; 977 } 978 979 980 static int dpp_process_csr(struct sigma_dut *dut, const char *ifname, 981 char *csr_event) 982 { 983 FILE *f; 984 char buf[2000], cmd[2500], tmp[300]; 985 char *pos; 986 int peer; 987 size_t len; 988 989 pos = strstr(csr_event, " peer="); 990 if (!pos) { 991 sigma_dut_print(dut, DUT_MSG_INFO, "No peer id known for CSR"); 992 return -1; 993 } 994 pos += 6; 995 peer = atoi(pos); 996 997 pos = strstr(csr_event, " csr="); 998 if (!pos) { 999 sigma_dut_print(dut, DUT_MSG_INFO, "No CSR found"); 1000 return -1; 1001 } 1002 pos += 5; 1003 1004 snprintf(tmp, sizeof(tmp), "%s/dpp-ca-certbag", sigma_cert_path); 1005 unlink(tmp); 1006 1007 snprintf(tmp, sizeof(tmp), "%s/dpp-ca-csr", sigma_cert_path); 1008 f = fopen(tmp, "w"); 1009 if (!f) { 1010 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to write CSR file"); 1011 return -1; 1012 } 1013 fprintf(f, "%s", pos); 1014 fclose(f); 1015 1016 if (run_system_wrapper(dut, "./dpp-ca.py %s", sigma_cert_path) < 0) { 1017 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to run dpp-ca.py"); 1018 return -1; 1019 } 1020 1021 snprintf(tmp, sizeof(tmp), "%s/dpp-ca-certbag", sigma_cert_path); 1022 f = fopen(tmp, "r"); 1023 if (!f) { 1024 sigma_dut_print(dut, DUT_MSG_INFO, "No certBag available"); 1025 return -1; 1026 } 1027 len = fread(buf, 1, sizeof(buf), f); 1028 fclose(f); 1029 if (len >= sizeof(buf)) { 1030 sigma_dut_print(dut, DUT_MSG_INFO, "No bufferroom for certBag"); 1031 return -1; 1032 } 1033 buf[len] = '\0'; 1034 1035 snprintf(cmd, sizeof(cmd), "DPP_CA_SET peer=%d name=certBag value=%s", 1036 peer, buf); 1037 if (wpa_command(ifname, cmd) < 0) { 1038 sigma_dut_print(dut, DUT_MSG_INFO, "DPP_CA_SET failed"); 1039 return -1; 1040 } 1041 1042 return 0; 1043 } 1044 1045 1046 static enum sigma_cmd_result dpp_automatic_dpp(struct sigma_dut *dut, 1047 struct sigma_conn *conn, 1048 struct sigma_cmd *cmd) 1049 { 1050 const char *bs = get_param(cmd, "DPPBS"); 1051 const char *type = get_param(cmd, "DPPActionType"); 1052 const char *auth_role = get_param(cmd, "DPPAuthRole"); 1053 const char *prov_role = get_param(cmd, "DPPProvisioningRole"); 1054 const char *pkex_code = get_param(cmd, "DPPPKEXCode"); 1055 const char *pkex_code_id = get_param(cmd, "DPPPKEXCodeIdentifier"); 1056 const char *wait_conn = get_param(cmd, "DPPWaitForConnect"); 1057 const char *self_conf = get_param(cmd, "DPPSelfConfigure"); 1058 const char *step = get_param(cmd, "DPPStep"); 1059 const char *frametype = get_param(cmd, "DPPFrameType"); 1060 const char *attr = get_param(cmd, "DPPIEAttribute"); 1061 const char *action_type = get_param(cmd, "DPPActionType"); 1062 const char *tcp = get_param(cmd, "DPPOverTCP"); 1063 const char *nfc_handover = get_param(cmd, "DPPNFCHandover"); 1064 const char *role; 1065 const char *netrole = NULL; 1066 const char *val; 1067 const char *conf_role; 1068 int conf_index = -1; 1069 char buf[2000], *pos, *pos2; 1070 char buf2[200]; 1071 char conf_ssid[100]; 1072 char conf_pass[100]; 1073 char csrattrs[200]; 1074 char pkex_identifier[200]; 1075 struct wpa_ctrl *ctrl; 1076 int res; 1077 unsigned int old_timeout; 1078 int own_pkex_id = -1; 1079 const char *ifname = get_station_ifname(dut); 1080 const char *auth_events[] = { 1081 "DPP-AUTH-SUCCESS", 1082 "DPP-AUTH-INIT-FAILED", 1083 "DPP-NOT-COMPATIBLE", 1084 "DPP-RESPONSE-PENDING", 1085 "DPP-SCAN-PEER-QR-CODE", 1086 "DPP-AUTH-DIRECTION", 1087 NULL 1088 }; 1089 const char *conf_events[] = { 1090 "DPP-CONF-RECEIVED", 1091 "DPP-CONF-SENT", 1092 "DPP-CONF-FAILED", 1093 "DPP-MUD-URL", 1094 NULL 1095 }; 1096 const char *conn_events[] = { 1097 "PMKSA-CACHE-ADDED", 1098 "CTRL-EVENT-CONNECTED", 1099 NULL 1100 }; 1101 const char *group_id_str = NULL; 1102 char group_id[100]; 1103 char conf2[300]; 1104 const char *result; 1105 int check_mutual = 0; 1106 int enrollee_ap; 1107 int enrollee_configurator; 1108 int force_gas_fragm = 0; 1109 int not_dpp_akm = 0; 1110 int akm_use_selector = 0; 1111 int conn_status; 1112 int chirp = 0; 1113 int manual = strcasecmp(type, "ManualDPP") == 0; 1114 time_t start, now; 1115 FILE *f; 1116 char *no_mud_url = ""; 1117 char *mud_url = no_mud_url; 1118 1119 time(&start); 1120 1121 if (!wait_conn) 1122 wait_conn = "no"; 1123 if (!self_conf) 1124 self_conf = "no"; 1125 1126 if (!prov_role) { 1127 send_resp(dut, conn, SIGMA_ERROR, 1128 "errorCode,Missing DPPProvisioningRole"); 1129 return STATUS_SENT_ERROR; 1130 } 1131 1132 val = get_param(cmd, "DPPConfEnrolleeRole"); 1133 if (val) { 1134 enrollee_ap = strcasecmp(val, "AP") == 0; 1135 enrollee_configurator = strcasecmp(val, "Configurator") == 0; 1136 } else { 1137 enrollee_ap = sigma_dut_is_ap(dut); 1138 enrollee_configurator = 0; 1139 } 1140 1141 val = get_param(cmd, "DPPNetworkRole"); 1142 if (val) { 1143 if (strcasecmp(val, "AP") == 0) { 1144 netrole = "ap"; 1145 } else if (strcasecmp(val, "STA") == 0) { 1146 netrole = "sta"; 1147 } else if (strcasecmp(val, "Configurator") == 0) { 1148 netrole = "configurator"; 1149 } else { 1150 send_resp(dut, conn, SIGMA_ERROR, 1151 "errorCode,Unsupported DPPNetworkRole value"); 1152 return STATUS_SENT_ERROR; 1153 } 1154 } 1155 1156 val = get_param(cmd, "DPPChirp"); 1157 if (val) 1158 chirp = get_enable_disable(val); 1159 1160 if ((step || frametype) && (!step || !frametype)) { 1161 send_resp(dut, conn, SIGMA_ERROR, 1162 "errorCode,Invalid DPPStep,DPPFrameType,DPPIEAttribute combination"); 1163 return STATUS_SENT_ERROR; 1164 } 1165 1166 val = get_param(cmd, "MUDURL"); 1167 if (val) { 1168 snprintf(buf, sizeof(buf), "SET dpp_mud_url %s", val); 1169 if (wpa_command(ifname, buf) < 0) { 1170 send_resp(dut, conn, SIGMA_ERROR, 1171 "errorCode,Failed to set MUD URL"); 1172 return STATUS_SENT_ERROR; 1173 } 1174 } 1175 1176 if (sigma_dut_is_ap(dut)) { 1177 if (!dut->hostapd_ifname) { 1178 sigma_dut_print(dut, DUT_MSG_ERROR, 1179 "hostapd ifname not specified (-j)"); 1180 return ERROR_SEND_STATUS; 1181 } 1182 ifname = dut->hostapd_ifname; 1183 1184 if (dpp_hostapd_run(dut) < 0) { 1185 send_resp(dut, conn, SIGMA_ERROR, 1186 "errorCode,Failed to start hostapd"); 1187 return STATUS_SENT_ERROR; 1188 } 1189 } 1190 1191 if (strcasecmp(prov_role, "Configurator") == 0 || 1192 strcasecmp(prov_role, "Both") == 0) { 1193 if (dut->dpp_conf_id < 0) { 1194 snprintf(buf, sizeof(buf), 1195 "DPP_CONFIGURATOR_ADD curve=%s", 1196 dpp_get_curve(cmd, "DPPSigningKeyECC")); 1197 if (wpa_command_resp(ifname, buf, 1198 buf, sizeof(buf)) < 0) { 1199 send_resp(dut, conn, SIGMA_ERROR, 1200 "errorCode,Failed to set up configurator"); 1201 return STATUS_SENT_ERROR; 1202 } 1203 dut->dpp_conf_id = atoi(buf); 1204 } 1205 if (strcasecmp(prov_role, "Configurator") == 0) 1206 role = "configurator"; 1207 else 1208 role = "either"; 1209 } else if (strcasecmp(prov_role, "Enrollee") == 0) { 1210 role = "enrollee"; 1211 } else { 1212 send_resp(dut, conn, SIGMA_ERROR, 1213 "errorCode,Unknown DPPProvisioningRole"); 1214 return STATUS_SENT_ERROR; 1215 } 1216 1217 pkex_identifier[0] = '\0'; 1218 if (strcasecmp(bs, "PKEX") == 0) { 1219 if (sigma_dut_is_ap(dut) && dut->ap_channel != 6) { 1220 /* For now, have to make operating channel match DPP 1221 * listen channel. This should be removed once hostapd 1222 * has support for DPP listen on non-operating channel. 1223 */ 1224 sigma_dut_print(dut, DUT_MSG_INFO, 1225 "Update hostapd operating channel to match listen needs"); 1226 dut->ap_channel = 6; 1227 1228 if (get_driver_type(dut) == DRIVER_OPENWRT) { 1229 snprintf(buf, sizeof(buf), 1230 "iwconfig %s channel %d", 1231 dut->hostapd_ifname, dut->ap_channel); 1232 run_system(dut, buf); 1233 } 1234 1235 if (wpa_command(ifname, "SET channel 6") < 0 || 1236 wpa_command(ifname, "DISABLE") < 0 || 1237 wpa_command(ifname, "ENABLE") < 0) { 1238 send_resp(dut, conn, SIGMA_ERROR, 1239 "errorCode,Failed to update channel"); 1240 return STATUS_SENT_ERROR; 1241 } 1242 } 1243 1244 if (!pkex_code) { 1245 send_resp(dut, conn, SIGMA_ERROR, 1246 "errorCode,Missing DPPPKEXCode"); 1247 return STATUS_SENT_ERROR; 1248 } 1249 1250 if (pkex_code_id) 1251 snprintf(pkex_identifier, sizeof(pkex_identifier), 1252 "identifier=%s ", pkex_code_id); 1253 1254 snprintf(buf, sizeof(buf), 1255 "DPP_BOOTSTRAP_GEN type=pkex curve=%s", 1256 dpp_get_curve(cmd, "DPPCryptoIdentifier")); 1257 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0) { 1258 send_resp(dut, conn, SIGMA_ERROR, 1259 "errorCode,Failed to set up PKEX"); 1260 return STATUS_SENT_ERROR; 1261 } 1262 own_pkex_id = atoi(buf); 1263 } 1264 1265 ctrl = open_wpa_mon(ifname); 1266 if (!ctrl) { 1267 sigma_dut_print(dut, DUT_MSG_ERROR, 1268 "Failed to open wpa_supplicant monitor connection"); 1269 return ERROR_SEND_STATUS; 1270 } 1271 1272 old_timeout = dut->default_timeout; 1273 val = get_param(cmd, "DPPTimeout"); 1274 if (val && atoi(val) > 0) { 1275 dut->default_timeout = atoi(val); 1276 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP timeout: %u", 1277 dut->default_timeout); 1278 } 1279 1280 val = get_param(cmd, "DPPStatusQuery"); 1281 conn_status = val && strcasecmp(val, "Yes") == 0; 1282 1283 conf_ssid[0] = '\0'; 1284 conf_pass[0] = '\0'; 1285 csrattrs[0] = '\0'; 1286 group_id[0] = '\0'; 1287 conf2[0] = '\0'; 1288 if (!enrollee_configurator) { 1289 val = get_param(cmd, "DPPConfIndex"); 1290 if (val) 1291 conf_index = atoi(val); 1292 } 1293 switch (conf_index) { 1294 case -1: 1295 if (enrollee_configurator) 1296 conf_role = "configurator"; 1297 else 1298 conf_role = NULL; 1299 break; 1300 case 1: 1301 ascii2hexstr("DPPNET01", buf); 1302 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf); 1303 if (res < 0 || res >= sizeof(conf_ssid)) 1304 goto err; 1305 if (enrollee_ap) { 1306 conf_role = "ap-dpp"; 1307 } else { 1308 conf_role = "sta-dpp"; 1309 } 1310 group_id_str = "DPPGROUP_DPP_INFRA"; 1311 break; 1312 case 2: 1313 ascii2hexstr("DPPNET01", buf); 1314 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf); 1315 if (res < 0 || res >= sizeof(conf_ssid)) 1316 goto err; 1317 snprintf(conf_pass, sizeof(conf_pass), 1318 "psk=10506e102ad1e7f95112f6b127675bb8344dacacea60403f3fa4055aec85b0fc"); 1319 if (enrollee_ap) 1320 conf_role = "ap-psk"; 1321 else 1322 conf_role = "sta-psk"; 1323 break; 1324 case 3: 1325 ascii2hexstr("DPPNET01", buf); 1326 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf); 1327 if (res < 0 || res >= sizeof(conf_ssid)) 1328 goto err; 1329 ascii2hexstr("ThisIsDppPassphrase", buf); 1330 res = snprintf(conf_pass, sizeof(conf_pass), "pass=%s", buf); 1331 if (res < 0 || res >= sizeof(conf_pass)) 1332 goto err; 1333 if (enrollee_ap) 1334 conf_role = "ap-psk"; 1335 else 1336 conf_role = "sta-psk"; 1337 break; 1338 case 4: 1339 ascii2hexstr("DPPNET01", buf); 1340 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf); 1341 if (res < 0 || res >= sizeof(conf_ssid)) 1342 goto err; 1343 if (enrollee_ap) { 1344 conf_role = "ap-dpp"; 1345 } else { 1346 conf_role = "sta-dpp"; 1347 } 1348 group_id_str = "DPPGROUP_DPP_INFRA2"; 1349 break; 1350 case 5: 1351 ascii2hexstr("DPPNET01", buf); 1352 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf); 1353 if (res < 0 || res >= sizeof(conf_ssid)) 1354 goto err; 1355 ascii2hexstr("ThisIsDppPassphrase", buf); 1356 res = snprintf(conf_pass, sizeof(conf_pass), "pass=%s", buf); 1357 if (res < 0 || res >= sizeof(conf_pass)) 1358 goto err; 1359 if (enrollee_ap) 1360 conf_role = "ap-sae"; 1361 else 1362 conf_role = "sta-sae"; 1363 break; 1364 case 6: 1365 ascii2hexstr("DPPNET01", buf); 1366 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf); 1367 if (res < 0 || res >= sizeof(conf_ssid)) 1368 goto err; 1369 ascii2hexstr("ThisIsDppPassphrase", buf); 1370 res = snprintf(conf_pass, sizeof(conf_pass), "pass=%s", buf); 1371 if (res < 0 || res >= sizeof(conf_pass)) 1372 goto err; 1373 if (enrollee_ap) 1374 conf_role = "ap-psk-sae"; 1375 else 1376 conf_role = "sta-psk-sae"; 1377 break; 1378 case 7: 1379 ascii2hexstr("DPPNET01", buf); 1380 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf); 1381 if (res < 0 || res >= sizeof(conf_ssid)) 1382 goto err; 1383 if (enrollee_ap) { 1384 conf_role = "ap-dpp"; 1385 } else { 1386 conf_role = "sta-dpp"; 1387 } 1388 group_id_str = "DPPGROUP_DPP_INFRA"; 1389 force_gas_fragm = 1; 1390 break; 1391 case 8: 1392 case 9: 1393 ascii2hexstr("DPPNET01", buf); 1394 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf); 1395 if (res < 0 || res >= sizeof(conf_ssid)) 1396 goto err; 1397 ascii2hexstr("This_is_legacy_password", buf); 1398 res = snprintf(conf_pass, sizeof(conf_pass), "pass=%s", buf); 1399 if (res < 0 || res >= sizeof(conf_pass)) 1400 goto err; 1401 if (enrollee_ap) { 1402 conf_role = "ap-dpp+psk+sae"; 1403 } else { 1404 conf_role = "sta-dpp+psk+sae"; 1405 } 1406 group_id_str = "DPPGROUP_DPP_INFRA1"; 1407 if (conf_index == 9) 1408 akm_use_selector = 1; 1409 break; 1410 case 10: 1411 ascii2hexstr("DPPNET01", buf); 1412 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf); 1413 if (res < 0 || res >= sizeof(conf_ssid)) 1414 goto err; 1415 if (enrollee_ap) 1416 conf_role = "ap-dpp"; 1417 else 1418 conf_role = "sta-dpp"; 1419 group_id_str = "DPPGROUP_DPP_INFRA1"; 1420 ascii2hexstr("DPPNET02", buf); 1421 ascii2hexstr("This_is_legacy_password", buf2); 1422 res = snprintf(conf2, sizeof(conf2), 1423 " @CONF-OBJ-SEP@ conf=%s-dpp+psk+sae ssid=%s pass=%s group_id=DPPGROUP_DPP_INFRA2", 1424 enrollee_ap ? "ap" : "sta", buf, buf2); 1425 if (res < 0 || res >= sizeof(conf2)) 1426 goto err; 1427 break; 1428 case 11: 1429 ascii2hexstr("DPPNET01", buf); 1430 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf); 1431 if (res < 0 || res >= sizeof(conf_ssid)) 1432 goto err; 1433 if (enrollee_ap) { 1434 send_resp(dut, conn, SIGMA_ERROR, 1435 "errorCode,dot1x AKM provisioning not supported for AP"); 1436 goto out; 1437 } 1438 conf_role = "sta-dot1x"; 1439 snprintf(buf, sizeof(buf), "%s/dpp-ca-csrattrs", 1440 sigma_cert_path); 1441 f = fopen(buf, "r"); 1442 if (f) { 1443 size_t len; 1444 int r; 1445 1446 len = fread(buf, 1, sizeof(buf), f); 1447 fclose(f); 1448 if (len >= sizeof(buf)) { 1449 send_resp(dut, conn, SIGMA_ERROR, 1450 "errorCode,No room for csrAttrs"); 1451 goto out; 1452 } 1453 buf[len] = '\0'; 1454 sigma_dut_print(dut, DUT_MSG_INFO, 1455 "Use csrAttrs from file"); 1456 r = snprintf(csrattrs, sizeof(csrattrs), 1457 " csrattrs=%s", buf); 1458 if (r <= 0 || r >= sizeof(csrattrs)) { 1459 send_resp(dut, conn, SIGMA_ERROR, 1460 "errorCode,No room for csrAttrs"); 1461 goto out; 1462 } 1463 } else { 1464 sigma_dut_print(dut, DUT_MSG_INFO, 1465 "Use default csrAttrs"); 1466 snprintf(csrattrs, sizeof(csrattrs), "%s", 1467 " csrattrs=MAsGCSqGSIb3DQEJBw=="); 1468 } 1469 break; 1470 default: 1471 send_resp(dut, conn, SIGMA_ERROR, 1472 "errorCode,Unsupported DPPConfIndex"); 1473 goto out; 1474 } 1475 1476 if (group_id_str) 1477 snprintf(group_id, sizeof(group_id), " group_id=%s", 1478 group_id_str); 1479 1480 if (force_gas_fragm) { 1481 char spaces[1500]; 1482 1483 memset(spaces, ' ', sizeof(spaces)); 1484 spaces[sizeof(spaces) - 1] = '\0'; 1485 1486 snprintf(buf, sizeof(buf), 1487 "SET dpp_discovery_override {\"ssid\":\"DPPNET01\"}%s", 1488 spaces); 1489 if (wpa_command(ifname, buf) < 0) { 1490 send_resp(dut, conn, SIGMA_ERROR, 1491 "errorCode,Failed to set discovery override"); 1492 goto out; 1493 } 1494 } 1495 1496 if (step) { 1497 int test; 1498 1499 test = dpp_get_test(step, frametype, attr); 1500 if (test <= 0) { 1501 send_resp(dut, conn, SIGMA_ERROR, 1502 "errorCode,Unsupported DPPStep/DPPFrameType/DPPIEAttribute"); 1503 goto out; 1504 } 1505 1506 snprintf(buf, sizeof(buf), "SET dpp_test %d", test); 1507 if (wpa_command(ifname, buf) < 0) { 1508 send_resp(dut, conn, SIGMA_ERROR, 1509 "errorCode,Failed to set dpp_test"); 1510 goto out; 1511 } 1512 } else { 1513 wpa_command(ifname, "SET dpp_test 0"); 1514 } 1515 1516 if (strcasecmp(self_conf, "Yes") == 0) { 1517 if (strcasecmp(prov_role, "Configurator") != 0) { 1518 send_resp(dut, conn, SIGMA_ERROR, 1519 "errorCode,Invalid DPPSelfConfigure use - only allowed for Configurator role"); 1520 goto out; 1521 } 1522 if (!conf_role) { 1523 send_resp(dut, conn, SIGMA_ERROR, 1524 "errorCode,Missing DPPConfIndex"); 1525 goto out; 1526 } 1527 1528 snprintf(buf, sizeof(buf), 1529 "DPP_CONFIGURATOR_SIGN conf=%s %s %s configurator=%d", 1530 conf_role, conf_ssid, conf_pass, dut->dpp_conf_id); 1531 if (wpa_command(ifname, buf) < 0) { 1532 send_resp(dut, conn, SIGMA_ERROR, 1533 "errorCode,Failed to initiate DPP self-configuration"); 1534 goto out; 1535 } 1536 if (sigma_dut_is_ap(dut)) 1537 goto update_ap; 1538 goto wait_connect; 1539 } else if (manual && strcasecmp(bs, "NFC") == 0) { 1540 const char *val = get_param(cmd, "DPPNFCInit"); 1541 int init = !val || atoi(val) > 0; 1542 pid_t pid; 1543 int pid_status; 1544 int enrollee = 0; 1545 int tag_read = 0; 1546 int tag_write_uri = 0; 1547 int tag_write_hs = 0; 1548 const char *tx_rx_events[] = { "DPP-TX", "DPP-RX", NULL }; 1549 const char *chan_list, *alt_chan_list; 1550 char chan_list2[200], alt_chan_list2[200]; 1551 1552 if (strcasecmp(prov_role, "Configurator") == 0 || 1553 strcasecmp(prov_role, "Both") == 0) { 1554 if (!conf_role) { 1555 send_resp(dut, conn, SIGMA_ERROR, 1556 "errorCode,Missing DPPConfIndex"); 1557 goto out; 1558 } 1559 snprintf(buf, sizeof(buf), 1560 "SET dpp_configurator_params conf=%s %s %s configurator=%d%s%s%s%s%s", 1561 conf_role, conf_ssid, conf_pass, 1562 dut->dpp_conf_id, group_id, 1563 akm_use_selector ? " akm_use_selector=1" : "", 1564 conn_status ? " conn_status=1" : "", 1565 csrattrs, conf2); 1566 if (wpa_command(ifname, buf) < 0) { 1567 send_resp(dut, conn, SIGMA_ERROR, 1568 "errorCode,Failed to set configurator parameters"); 1569 goto out; 1570 } 1571 snprintf(buf, sizeof(buf), 1572 "conf=%s %s %s configurator=%d%s%s%s%s%s", 1573 conf_role, conf_ssid, conf_pass, 1574 dut->dpp_conf_id, group_id, 1575 akm_use_selector ? " akm_use_selector=1" : "", 1576 conn_status ? " conn_status=1" : "", csrattrs, 1577 conf2); 1578 } else { 1579 buf[0] = '\0'; 1580 enrollee = 1; 1581 } 1582 1583 val = get_param(cmd, "DPPNFCTag"); 1584 if (val) { 1585 if (strcasecmp(val, "Read") == 0) { 1586 tag_read = 1; 1587 } else if (strcasecmp(val, "Write-HS") == 0) { 1588 tag_write_hs = 1; 1589 } else if (strcasecmp(val, "Write-URI") == 0) { 1590 tag_write_uri = 1; 1591 } else { 1592 send_resp(dut, conn, SIGMA_ERROR, 1593 "errorCode,Unsupported DPPNFCTag value"); 1594 goto out; 1595 } 1596 } 1597 1598 chan_list = get_param(cmd, "DPPChannelList"); 1599 if (chan_list) { 1600 strlcpy(chan_list2, chan_list, sizeof(chan_list2)); 1601 for (pos = chan_list2; *pos; pos++) { 1602 if (*pos == ' ') 1603 *pos = ','; 1604 } 1605 } 1606 alt_chan_list = get_param(cmd, "DPPNFCAltChannelList"); 1607 if (alt_chan_list) { 1608 strlcpy(alt_chan_list2, alt_chan_list, 1609 sizeof(alt_chan_list2)); 1610 for (pos = alt_chan_list2; *pos; pos++) { 1611 if (*pos == ' ') 1612 *pos = ','; 1613 } 1614 } 1615 1616 run_system(dut, "killall dpp-nfc.py"); 1617 sigma_dut_print(dut, DUT_MSG_INFO, "Manual NFC operation"); 1618 if (!file_exists("dpp-nfc.py")) { 1619 send_resp(dut, conn, SIGMA_ERROR, 1620 "errorCode,dpp-nfc.py not found"); 1621 goto out; 1622 } 1623 1624 pid = fork(); 1625 if (pid < 0) { 1626 perror("fork"); 1627 send_resp(dut, conn, SIGMA_ERROR, 1628 "errorCode,fork() failed"); 1629 goto out; 1630 } 1631 1632 if (pid == 0) { 1633 char *argv[100]; 1634 int pos = 0; 1635 1636 argv[pos++] = "dpp-nfc.py"; 1637 argv[pos++] = "--only-one"; 1638 argv[pos++] = "--no-input"; 1639 argv[pos++] = "-i"; 1640 argv[pos++] = (char *) ifname; 1641 argv[pos++] = "--ctrl"; 1642 argv[pos++] = sigma_wpas_ctrl; 1643 argv[pos++] = enrollee ? "--enrollee" : 1644 "--configurator"; 1645 argv[pos++] = "--config-params"; 1646 argv[pos++] = buf; 1647 if (chan_list && strcmp(chan_list, "0/0") != 0) { 1648 argv[pos++] = "--chan"; 1649 argv[pos++] = chan_list2; 1650 } 1651 if (alt_chan_list && 1652 strcmp(alt_chan_list, "0/0") != 0) { 1653 argv[pos++] = "--altchan"; 1654 argv[pos++] = alt_chan_list2; 1655 } 1656 if (init) 1657 argv[pos++] = "-I"; 1658 if (netrole) { 1659 argv[pos++] = "--netrole"; 1660 argv[pos++] = (char *) netrole; 1661 } 1662 if (tag_read || tag_write_hs || tag_write_uri) 1663 argv[pos++] = "--no-wait"; 1664 if (!tag_read && !tag_write_hs && !tag_write_uri) 1665 argv[pos++] = "--handover-only"; 1666 if (tag_read) 1667 argv[pos++] = "--tag-read-only"; 1668 else if (tag_write_hs) 1669 argv[pos++] = "write-nfc-hs"; 1670 else if (tag_write_uri) 1671 argv[pos++] = "write-nfc-uri"; 1672 argv[pos] = NULL; 1673 1674 execv("./dpp-nfc.py", argv); 1675 perror("execv"); 1676 exit(0); 1677 return -1; 1678 } 1679 1680 usleep(300000); 1681 for (;;) { 1682 if (waitpid(pid, &pid_status, WNOHANG) > 0) { 1683 int status = WEXITSTATUS(pid_status); 1684 1685 sigma_dut_print(dut, DUT_MSG_DEBUG, 1686 "dpp-nfc.py exited (status %d)", 1687 status); 1688 if (status == 1) { 1689 send_resp(dut, conn, SIGMA_ERROR, 1690 "errorCode,dpp-nfc.py operation failed"); 1691 goto out; 1692 } 1693 break; 1694 } 1695 1696 time(&now); 1697 if ((unsigned int) (now - start) >= 1698 dut->default_timeout) { 1699 sigma_dut_print(dut, DUT_MSG_DEBUG, 1700 "dpp-nfc.py did not exit within timeout - stop it"); 1701 kill(pid, SIGTERM); 1702 waitpid(pid, &pid_status, 0); 1703 send_resp(dut, conn, SIGMA_ERROR, 1704 "errorCode,dpp-nfc.py did not complete within timeout"); 1705 goto out; 1706 } 1707 1708 old_timeout = dut->default_timeout; 1709 dut->default_timeout = 2; 1710 1711 res = get_wpa_cli_events(dut, ctrl, tx_rx_events, 1712 buf, sizeof(buf)); 1713 dut->default_timeout = old_timeout; 1714 if (res >= 0) { 1715 sigma_dut_print(dut, DUT_MSG_DEBUG, 1716 "DPP exchange started"); 1717 usleep(500000); 1718 kill(pid, SIGTERM); 1719 waitpid(pid, &pid_status, 0); 1720 break; 1721 } 1722 } 1723 } else if ((nfc_handover && 1724 strcasecmp(nfc_handover, "Negotiated_Requestor") == 0) || 1725 ((!nfc_handover || 1726 strcasecmp(nfc_handover, "Static") == 0) && 1727 auth_role && strcasecmp(auth_role, "Initiator") == 0)) { 1728 char own_txt[20]; 1729 int dpp_peer_bootstrap = -1; 1730 char neg_freq[30]; 1731 1732 val = get_param(cmd, "DPPAuthDirection"); 1733 check_mutual = val && strcasecmp(val, "Mutual") == 0; 1734 1735 neg_freq[0] = '\0'; 1736 val = get_param(cmd, "DPPSubsequentChannel"); 1737 if (val) { 1738 int opclass, channel, freq; 1739 1740 opclass = atoi(val); 1741 val = strchr(val, '/'); 1742 if (opclass == 0 || !val) { 1743 send_resp(dut, conn, SIGMA_ERROR, 1744 "errorCode,Invalid DPPSubsequentChannel"); 1745 goto out; 1746 } 1747 val++; 1748 channel = atoi(val); 1749 1750 /* Ignoring opclass for now; could use it here for more 1751 * robust frequency determination. */ 1752 freq = channel_to_freq(dut, channel); 1753 if (!freq) { 1754 send_resp(dut, conn, SIGMA_ERROR, 1755 "errorCode,Unsupported DPPSubsequentChannel channel"); 1756 goto out; 1757 } 1758 snprintf(neg_freq, sizeof(neg_freq), " neg_freq=%d", 1759 freq); 1760 } 1761 1762 if (strcasecmp(bs, "QR") == 0) { 1763 if (!dut->dpp_peer_uri) { 1764 send_resp(dut, conn, SIGMA_ERROR, 1765 "errorCode,Missing peer bootstrapping info"); 1766 goto out; 1767 } 1768 1769 snprintf(buf, sizeof(buf), "DPP_QR_CODE %s", 1770 dut->dpp_peer_uri); 1771 if (wpa_command_resp(ifname, buf, buf, 1772 sizeof(buf)) < 0 || 1773 strncmp(buf, "FAIL", 4) == 0) { 1774 send_resp(dut, conn, SIGMA_ERROR, 1775 "errorCode,Failed to parse URI"); 1776 goto out; 1777 } 1778 dpp_peer_bootstrap = atoi(buf); 1779 } else if (strcasecmp(bs, "NFC") == 0 && nfc_handover && 1780 strcasecmp(nfc_handover, "Static") == 0) { 1781 if (!dut->dpp_peer_uri) { 1782 send_resp(dut, conn, SIGMA_ERROR, 1783 "errorCode,Missing peer bootstrapping info"); 1784 goto out; 1785 } 1786 1787 snprintf(buf, sizeof(buf), "DPP_NFC_URI %s", 1788 dut->dpp_peer_uri); 1789 if (wpa_command_resp(ifname, buf, 1790 buf, sizeof(buf)) < 0 || 1791 strncmp(buf, "FAIL", 4) == 0) { 1792 send_resp(dut, conn, SIGMA_ERROR, 1793 "errorCode,Failed to process URI from NFC Tag"); 1794 goto out; 1795 } 1796 dpp_peer_bootstrap = atoi(buf); 1797 } else if (strcasecmp(bs, "NFC") == 0) { 1798 if (!dut->dpp_peer_uri) { 1799 send_resp(dut, conn, SIGMA_ERROR, 1800 "errorCode,Missing peer bootstrapping info"); 1801 goto out; 1802 } 1803 if (dut->dpp_local_bootstrap < 0) { 1804 send_resp(dut, conn, SIGMA_ERROR, 1805 "errorCode,Missing own bootstrapping info"); 1806 goto out; 1807 } 1808 1809 snprintf(buf, sizeof(buf), 1810 "DPP_NFC_HANDOVER_SEL own=%d uri=%s", 1811 dut->dpp_local_bootstrap, dut->dpp_peer_uri); 1812 if (wpa_command_resp(ifname, buf, 1813 buf, sizeof(buf)) < 0 || 1814 strncmp(buf, "FAIL", 4) == 0) { 1815 send_resp(dut, conn, SIGMA_ERROR, 1816 "errorCode,Failed to process NFC Handover Select"); 1817 goto out; 1818 } 1819 dpp_peer_bootstrap = atoi(buf); 1820 } 1821 1822 if (dut->dpp_local_bootstrap >= 0) 1823 snprintf(own_txt, sizeof(own_txt), " own=%d", 1824 dut->dpp_local_bootstrap); 1825 else 1826 own_txt[0] = '\0'; 1827 if (chirp) { 1828 int freq = 2437; /* default: channel 6 */ 1829 1830 val = get_param(cmd, "DPPChirpChannel"); 1831 if (val) { 1832 freq = channel_to_freq(dut, atoi(val)); 1833 if (!freq) { 1834 send_resp(dut, conn, SIGMA_ERROR, 1835 "errorCode,Unsupported DPPChirpChannel channel"); 1836 goto out; 1837 } 1838 } 1839 1840 if (strcasecmp(prov_role, "Configurator") == 0 || 1841 strcasecmp(prov_role, "Both") == 0) { 1842 if (!conf_role) { 1843 send_resp(dut, conn, SIGMA_ERROR, 1844 "errorCode,Missing DPPConfIndex"); 1845 goto out; 1846 } 1847 snprintf(buf, sizeof(buf), 1848 "SET dpp_configurator_params conf=%s %s %s configurator=%d%s%s%s%s%s", 1849 conf_role, conf_ssid, conf_pass, 1850 dut->dpp_conf_id, group_id, 1851 akm_use_selector ? 1852 " akm_use_selector=1" : "", 1853 conn_status ? " conn_status=1" : "", 1854 csrattrs, conf2); 1855 if (wpa_command(ifname, buf) < 0) { 1856 send_resp(dut, conn, SIGMA_ERROR, 1857 "errorCode,Failed to set configurator parameters"); 1858 goto out; 1859 } 1860 } 1861 1862 if (tcp && strcasecmp(tcp, "yes") == 0) { 1863 snprintf(buf, sizeof(buf), 1864 "DPP_CONTROLLER_START"); 1865 } else { 1866 snprintf(buf, sizeof(buf), 1867 "DPP_LISTEN %d role=%s%s%s", 1868 freq, role, 1869 netrole ? " netrole=" : "", 1870 netrole ? netrole : ""); 1871 } 1872 } else if ((strcasecmp(bs, "QR") == 0 || 1873 strcasecmp(bs, "NFC") == 0) && 1874 (strcasecmp(prov_role, "Configurator") == 0 || 1875 strcasecmp(prov_role, "Both") == 0)) { 1876 if (!conf_role) { 1877 send_resp(dut, conn, SIGMA_ERROR, 1878 "errorCode,Missing DPPConfIndex"); 1879 goto out; 1880 } 1881 snprintf(buf, sizeof(buf), 1882 "DPP_AUTH_INIT peer=%d%s role=%s%s%s conf=%s %s %s configurator=%d%s%s%s%s%s%s%s%s", 1883 dpp_peer_bootstrap, own_txt, role, 1884 netrole ? " netrole=" : "", 1885 netrole ? netrole : "", 1886 conf_role, conf_ssid, conf_pass, 1887 dut->dpp_conf_id, neg_freq, group_id, 1888 akm_use_selector ? " akm_use_selector=1" : "", 1889 conn_status ? " conn_status=1" : "", 1890 tcp ? " tcp_addr=" : "", 1891 tcp ? tcp : "", 1892 csrattrs, conf2); 1893 } else if (tcp && (strcasecmp(bs, "QR") == 0 || 1894 strcasecmp(bs, "NFC") == 0)) { 1895 snprintf(buf, sizeof(buf), 1896 "DPP_AUTH_INIT peer=%d%s role=%s%s%s tcp_addr=%s%s%s", 1897 dpp_peer_bootstrap, own_txt, role, 1898 netrole ? " netrole=" : "", 1899 netrole ? netrole : "", 1900 tcp, neg_freq, group_id); 1901 } else if (strcasecmp(bs, "QR") == 0 || 1902 strcasecmp(bs, "NFC") == 0) { 1903 snprintf(buf, sizeof(buf), 1904 "DPP_AUTH_INIT peer=%d%s role=%s%s%s%s%s", 1905 dpp_peer_bootstrap, own_txt, role, 1906 netrole ? " netrole=" : "", 1907 netrole ? netrole : "", 1908 neg_freq, group_id); 1909 } else if (strcasecmp(bs, "PKEX") == 0 && 1910 (strcasecmp(prov_role, "Configurator") == 0 || 1911 strcasecmp(prov_role, "Both") == 0)) { 1912 if (!conf_role) { 1913 send_resp(dut, conn, SIGMA_ERROR, 1914 "errorCode,Missing DPPConfIndex"); 1915 goto out; 1916 } 1917 snprintf(buf, sizeof(buf), 1918 "DPP_PKEX_ADD own=%d init=1 role=%s conf=%s %s %s configurator=%d%s %scode=%s", 1919 own_pkex_id, role, conf_role, 1920 conf_ssid, conf_pass, dut->dpp_conf_id, 1921 csrattrs, pkex_identifier, pkex_code); 1922 } else if (strcasecmp(bs, "PKEX") == 0) { 1923 snprintf(buf, sizeof(buf), 1924 "DPP_PKEX_ADD own=%d init=1 role=%s %scode=%s", 1925 own_pkex_id, role, pkex_identifier, pkex_code); 1926 } else { 1927 send_resp(dut, conn, SIGMA_ERROR, 1928 "errorCode,Unsupported DPPBS"); 1929 goto out; 1930 } 1931 if (wpa_command(ifname, buf) < 0) { 1932 send_resp(dut, conn, SIGMA_ERROR, 1933 "errorCode,Failed to initiate DPP authentication"); 1934 goto out; 1935 } 1936 } else if ((nfc_handover && 1937 strcasecmp(nfc_handover, "Negotiated_Selector") == 0) || 1938 ((!nfc_handover || 1939 strcasecmp(nfc_handover, "Static") == 0) && 1940 auth_role && strcasecmp(auth_role, "Responder") == 0)) { 1941 const char *delay_qr_resp; 1942 int mutual; 1943 int freq = 2462; /* default: channel 11 */ 1944 1945 if (sigma_dut_is_ap(dut) && dut->hostapd_running && 1946 dut->ap_oper_chn) 1947 freq = channel_to_freq(dut, dut->ap_channel); 1948 1949 if (strcasecmp(bs, "PKEX") == 0) { 1950 /* default: channel 6 for PKEX */ 1951 freq = 2437; 1952 } 1953 1954 delay_qr_resp = get_param(cmd, "DPPDelayQRResponse"); 1955 1956 val = get_param(cmd, "DPPAuthDirection"); 1957 mutual = val && strcasecmp(val, "Mutual") == 0; 1958 1959 val = get_param(cmd, "DPPListenChannel"); 1960 if (val) { 1961 freq = channel_to_freq(dut, atoi(val)); 1962 if (freq == 0) { 1963 send_resp(dut, conn, SIGMA_ERROR, 1964 "errorCode,Unsupported DPPListenChannel value"); 1965 goto out; 1966 } 1967 1968 if (sigma_dut_is_ap(dut) && !chirp && 1969 dut->ap_start_disabled && 1970 atoi(val) != dut->ap_channel) { 1971 sigma_dut_print(dut, DUT_MSG_INFO, 1972 "Use requested listen channel as the initial operating channel"); 1973 snprintf(buf, sizeof(buf), "SET channel %d", 1974 atoi(val)); 1975 wpa_command(ifname, buf); 1976 } 1977 } 1978 1979 if (sigma_dut_is_ap(dut) && dpp_hostapd_beacon(dut) < 0) { 1980 send_resp(dut, conn, SIGMA_ERROR, 1981 "errorCode,Failed to start AP mode listen"); 1982 goto out; 1983 } 1984 1985 if (strcasecmp(bs, "NFC") == 0 && nfc_handover && 1986 strcasecmp(nfc_handover, "Static") == 0) { 1987 /* No steps needed here - waiting for peer to initiate 1988 * once it reads the URI from the NFC Tag */ 1989 } else if (strcasecmp(bs, "NFC") == 0) { 1990 if (!dut->dpp_peer_uri) { 1991 send_resp(dut, conn, SIGMA_ERROR, 1992 "errorCode,Missing peer bootstrapping info"); 1993 goto out; 1994 } 1995 if (dut->dpp_local_bootstrap < 0) { 1996 send_resp(dut, conn, SIGMA_ERROR, 1997 "errorCode,Missing own bootstrapping info"); 1998 goto out; 1999 } 2000 2001 snprintf(buf, sizeof(buf), 2002 "DPP_NFC_HANDOVER_REQ own=%d uri=%s", 2003 dut->dpp_local_bootstrap, dut->dpp_peer_uri); 2004 if (wpa_command(ifname, buf) < 0) { 2005 send_resp(dut, conn, SIGMA_ERROR, 2006 "errorCode,Failed to process NFC Handover Request"); 2007 goto out; 2008 } 2009 2010 snprintf(buf, sizeof(buf), "DPP_BOOTSTRAP_INFO %d", 2011 dut->dpp_local_bootstrap); 2012 if (wpa_command_resp(ifname, buf, 2013 buf, sizeof(buf)) < 0 || 2014 strncmp(buf, "FAIL", 4) == 0) { 2015 send_resp(dut, conn, SIGMA_ERROR, 2016 "errorCode,Failed to get bootstrap information"); 2017 goto out; 2018 } 2019 pos = buf; 2020 while (pos) { 2021 pos2 = strchr(pos, '\n'); 2022 if (pos2) 2023 *pos2 = '\0'; 2024 if (strncmp(pos, "use_freq=", 9) == 0) { 2025 freq = atoi(pos + 9); 2026 sigma_dut_print(dut, DUT_MSG_DEBUG, 2027 "DPP negotiation frequency from NFC handover: %d MHz", 2028 freq); 2029 break; 2030 } 2031 2032 if (!pos2) 2033 break; 2034 pos = pos2 + 1; 2035 } 2036 } else if (!delay_qr_resp && dut->dpp_peer_uri) { 2037 snprintf(buf, sizeof(buf), "DPP_QR_CODE %s", 2038 dut->dpp_peer_uri); 2039 if (wpa_command_resp(ifname, buf, buf, 2040 sizeof(buf)) < 0) { 2041 send_resp(dut, conn, SIGMA_ERROR, 2042 "errorCode,Failed to parse URI"); 2043 goto out; 2044 } 2045 } 2046 2047 if (strcasecmp(prov_role, "Configurator") == 0) { 2048 if (!conf_role) { 2049 send_resp(dut, conn, SIGMA_ERROR, 2050 "errorCode,Missing DPPConfIndex"); 2051 goto out; 2052 } 2053 snprintf(buf, sizeof(buf), 2054 "SET dpp_configurator_params conf=%s %s %s configurator=%d%s%s%s%s%s", 2055 conf_role, conf_ssid, conf_pass, 2056 dut->dpp_conf_id, group_id, 2057 akm_use_selector ? " akm_use_selector=1" : "", 2058 conn_status ? " conn_status=1" : "", csrattrs, 2059 conf2); 2060 if (wpa_command(ifname, buf) < 0) { 2061 send_resp(dut, conn, SIGMA_ERROR, 2062 "errorCode,Failed to set configurator parameters"); 2063 goto out; 2064 } 2065 } 2066 if (strcasecmp(bs, "PKEX") == 0) { 2067 snprintf(buf, sizeof(buf), 2068 "DPP_PKEX_ADD own=%d role=%s %scode=%s", 2069 own_pkex_id, role, pkex_identifier, pkex_code); 2070 if (wpa_command(ifname, buf) < 0) { 2071 send_resp(dut, conn, SIGMA_ERROR, 2072 "errorCode,Failed to configure DPP PKEX"); 2073 goto out; 2074 } 2075 } 2076 2077 if (chirp) { 2078 snprintf(buf, sizeof(buf), 2079 "DPP_CHIRP own=%d iter=10 listen=%d", 2080 dut->dpp_local_bootstrap, freq); 2081 } else if (tcp && strcasecmp(tcp, "yes") == 0) { 2082 snprintf(buf, sizeof(buf), "DPP_CONTROLLER_START"); 2083 } else { 2084 snprintf(buf, sizeof(buf), 2085 "DPP_LISTEN %d role=%s%s%s%s", 2086 freq, role, 2087 (strcasecmp(bs, "QR") == 0 && mutual) ? 2088 " qr=mutual" : "", 2089 netrole ? " netrole=" : "", 2090 netrole ? netrole : ""); 2091 } 2092 if (wpa_command(ifname, buf) < 0) { 2093 send_resp(dut, conn, SIGMA_ERROR, 2094 "errorCode,Failed to start DPP listen/chirp"); 2095 goto out; 2096 } 2097 2098 if (!(tcp && strcasecmp(tcp, "yes") == 0) && 2099 get_driver_type(dut) == DRIVER_OPENWRT) { 2100 snprintf(buf, sizeof(buf), "iwconfig %s channel %d", 2101 dut->hostapd_ifname, freq_to_channel(freq)); 2102 run_system(dut, buf); 2103 } 2104 2105 if (delay_qr_resp && mutual && dut->dpp_peer_uri) { 2106 int wait_time = atoi(delay_qr_resp); 2107 2108 res = get_wpa_cli_events(dut, ctrl, auth_events, 2109 buf, sizeof(buf)); 2110 if (res < 0) { 2111 send_resp(dut, conn, SIGMA_COMPLETE, 2112 "BootstrapResult,OK,AuthResult,Timeout"); 2113 goto out; 2114 } 2115 sigma_dut_print(dut, DUT_MSG_DEBUG, 2116 "DPP auth result: %s", buf); 2117 if (strstr(buf, "DPP-SCAN-PEER-QR-CODE") == NULL) { 2118 send_resp(dut, conn, SIGMA_ERROR, 2119 "errorCode,No scan request for peer QR Code seen"); 2120 goto out; 2121 } 2122 sigma_dut_print(dut, DUT_MSG_INFO, 2123 "Waiting %d second(s) before processing peer URI", 2124 wait_time); 2125 sleep(wait_time); 2126 2127 snprintf(buf, sizeof(buf), "DPP_QR_CODE %s", 2128 dut->dpp_peer_uri); 2129 if (wpa_command_resp(ifname, buf, buf, 2130 sizeof(buf)) < 0) { 2131 send_resp(dut, conn, SIGMA_ERROR, 2132 "errorCode,Failed to parse URI"); 2133 goto out; 2134 } 2135 } else if (mutual && action_type && 2136 strcasecmp(action_type, "ManualDPP") == 0) { 2137 res = get_wpa_cli_events(dut, ctrl, auth_events, 2138 buf, sizeof(buf)); 2139 if (res < 0) { 2140 send_resp(dut, conn, SIGMA_COMPLETE, 2141 "BootstrapResult,OK,AuthResult,Timeout"); 2142 goto out; 2143 } 2144 sigma_dut_print(dut, DUT_MSG_DEBUG, 2145 "DPP auth result: %s", buf); 2146 if (strstr(buf, "DPP-NOT-COMPATIBLE")) { 2147 send_resp(dut, conn, SIGMA_COMPLETE, 2148 "BootstrapResult,OK,AuthResult,ROLES_NOT_COMPATIBLE"); 2149 goto out; 2150 } 2151 2152 if (strstr(buf, "DPP-SCAN-PEER-QR-CODE") == NULL) { 2153 send_resp(dut, conn, SIGMA_ERROR, 2154 "errorCode,No scan request for peer QR Code seen"); 2155 goto out; 2156 } 2157 2158 if (dpp_scan_peer_qrcode(dut) < 0) { 2159 send_resp(dut, conn, SIGMA_ERROR, 2160 "errorCode,Failed to scan peer QR Code"); 2161 goto out; 2162 } 2163 2164 snprintf(buf, sizeof(buf), "DPP_QR_CODE %s", 2165 dut->dpp_peer_uri); 2166 if (wpa_command_resp(ifname, buf, buf, 2167 sizeof(buf)) < 0) { 2168 send_resp(dut, conn, SIGMA_ERROR, 2169 "errorCode,Failed to parse URI"); 2170 goto out; 2171 } 2172 } 2173 } else { 2174 send_resp(dut, conn, SIGMA_ERROR, 2175 "errorCode,Unknown DPPAuthRole"); 2176 goto out; 2177 } 2178 2179 if (step && strcasecmp(step, "Timeout") == 0) { 2180 result = "errorCode,Unexpected state"; 2181 2182 if (strcasecmp(frametype, "PKEXExchangeResponse") == 0) { 2183 if (dpp_wait_rx(dut, ctrl, 8, -1) < 0) 2184 result = "BootstrapResult,Timeout"; 2185 else 2186 result = "BootstrapResult,Errorsent"; 2187 } 2188 2189 if (strcasecmp(frametype, "PKEXCRRequest") == 0) { 2190 if (dpp_wait_rx(dut, ctrl, 9, -1) < 0) 2191 result = "BootstrapResult,Timeout"; 2192 else 2193 result = "BootstrapResult,Errorsent"; 2194 } 2195 2196 if (strcasecmp(frametype, "PKEXCRResponse") == 0) { 2197 if (dpp_wait_rx(dut, ctrl, 10, -1) < 0) 2198 result = "BootstrapResult,Timeout"; 2199 else 2200 result = "BootstrapResult,Errorsent"; 2201 } 2202 2203 if (strcasecmp(frametype, "AuthenticationRequest") == 0) { 2204 if (dpp_wait_rx(dut, ctrl, 0, -1) < 0) 2205 result = "BootstrapResult,OK,AuthResult,Timeout"; 2206 else 2207 result = "BootstrapResult,OK,AuthResult,Errorsent"; 2208 } 2209 2210 if (strcasecmp(frametype, "AuthenticationResponse") == 0) { 2211 if (dpp_wait_rx(dut, ctrl, 1, -1) < 0) 2212 result = "BootstrapResult,OK,AuthResult,Timeout"; 2213 else 2214 result = "BootstrapResult,OK,AuthResult,Errorsent"; 2215 } 2216 2217 if (strcasecmp(frametype, "AuthenticationConfirm") == 0) { 2218 if (auth_role && 2219 strcasecmp(auth_role, "Initiator") == 0) { 2220 /* This special case of DPPStep,Timeout with 2221 * DPPFrameType,AuthenticationConfirm on an 2222 * Initiator is used to cover need for stopping 2223 * the Initiator/Enrollee from sending out 2224 * Configuration Request message. */ 2225 if (strcasecmp(prov_role, "Enrollee") != 0) { 2226 send_resp(dut, conn, SIGMA_ERROR, 2227 "errorCode,Unexpected use of timeout after AuthenticationConfirm TX in Configurator role"); 2228 goto out; 2229 } 2230 if (check_mutual && 2231 dpp_process_auth_response( 2232 dut, conn, ctrl, auth_events, 2233 action_type, check_mutual, 2234 buf, sizeof(buf)) < 0) 2235 goto out; 2236 if (dpp_wait_tx_status(dut, ctrl, 2) < 0) 2237 result = "BootstrapResult,OK,AuthResult,Timeout"; 2238 else 2239 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationResponse"; 2240 } else { 2241 if (dpp_wait_rx(dut, ctrl, 2, -1) < 0) 2242 result = "BootstrapResult,OK,AuthResult,Timeout"; 2243 else 2244 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationConfirm"; 2245 } 2246 } 2247 2248 if (strcasecmp(frametype, "ConfigurationRequest") == 0) { 2249 if (get_wpa_cli_event(dut, ctrl, "DPP-CONF-FAILED", 2250 buf, sizeof(buf)) < 0) 2251 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Timeout"; 2252 else 2253 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Errorsent"; 2254 } 2255 2256 send_resp(dut, conn, SIGMA_COMPLETE, result); 2257 goto out; 2258 } 2259 2260 if (frametype && strcasecmp(frametype, "PKEXExchangeRequest") == 0) { 2261 if (dpp_wait_tx_status(dut, ctrl, 7) < 0) 2262 result = "BootstrapResult,Timeout"; 2263 else 2264 result = "BootstrapResult,Errorsent"; 2265 send_resp(dut, conn, SIGMA_COMPLETE, result); 2266 goto out; 2267 } 2268 2269 if (frametype && strcasecmp(frametype, "PKEXExchangeResponse") == 0) { 2270 if (dpp_wait_tx_status(dut, ctrl, 8) < 0) 2271 result = "BootstrapResult,Timeout"; 2272 else 2273 result = "BootstrapResult,Errorsent"; 2274 send_resp(dut, conn, SIGMA_COMPLETE, result); 2275 goto out; 2276 } 2277 2278 if (frametype && strcasecmp(frametype, "PKEXCRRequest") == 0) { 2279 if (dpp_wait_tx_status(dut, ctrl, 9) < 0) 2280 result = "BootstrapResult,Timeout"; 2281 else 2282 result = "BootstrapResult,Errorsent"; 2283 send_resp(dut, conn, SIGMA_COMPLETE, result); 2284 goto out; 2285 } 2286 2287 if (frametype && strcasecmp(frametype, "PKEXCRResponse") == 0) { 2288 if (dpp_wait_tx_status(dut, ctrl, 10) < 0) 2289 result = "BootstrapResult,Timeout"; 2290 else 2291 result = "BootstrapResult,Errorsent"; 2292 send_resp(dut, conn, SIGMA_COMPLETE, result); 2293 goto out; 2294 } 2295 2296 if (!frametype && strcasecmp(bs, "PKEX") == 0 && 2297 auth_role && strcasecmp(auth_role, "Responder") == 0) { 2298 if (dpp_wait_tx_status(dut, ctrl, 10) < 0) { 2299 send_resp(dut, conn, SIGMA_COMPLETE, 2300 "BootstrapResult,Timeout"); 2301 goto out; 2302 } 2303 } 2304 2305 if (!frametype && strcasecmp(bs, "PKEX") == 0 && 2306 auth_role && strcasecmp(auth_role, "Initiator") == 0) { 2307 if (dpp_wait_tx(dut, ctrl, 0) < 0) { 2308 send_resp(dut, conn, SIGMA_COMPLETE, 2309 "BootstrapResult,Timeout"); 2310 goto out; 2311 } 2312 } 2313 2314 if (frametype && strcasecmp(frametype, "AuthenticationRequest") == 0) { 2315 if (dpp_wait_tx_status(dut, ctrl, 0) < 0) { 2316 send_resp(dut, conn, SIGMA_COMPLETE, 2317 "BootstrapResult,OK,AuthResult,Timeout"); 2318 goto out; 2319 } 2320 2321 if (dpp_wait_rx(dut, ctrl, 1, 5) < 0) 2322 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,None"; 2323 else if (get_wpa_cli_events(dut, ctrl, auth_events, 2324 buf, sizeof(buf)) >= 0 && 2325 strstr(buf, "DPP-RESPONSE-PENDING") != NULL) 2326 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationResponseWithStatusPending"; 2327 else 2328 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationResponse"; 2329 send_resp(dut, conn, SIGMA_COMPLETE, result); 2330 goto out; 2331 } 2332 2333 if (frametype && strcasecmp(frametype, "AuthenticationResponse") == 0) { 2334 if (dpp_wait_tx_status(dut, ctrl, 1) < 0) { 2335 send_resp(dut, conn, SIGMA_COMPLETE, 2336 "BootstrapResult,OK,AuthResult,Timeout"); 2337 goto out; 2338 } 2339 2340 if (dpp_wait_rx(dut, ctrl, 2, 5) < 0) 2341 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationRequest"; 2342 else 2343 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationConfirm"; 2344 send_resp(dut, conn, SIGMA_COMPLETE, result); 2345 goto out; 2346 } 2347 2348 if (dpp_process_auth_response(dut, conn, ctrl, auth_events, action_type, 2349 check_mutual, buf, sizeof(buf)) < 0) 2350 goto out; 2351 2352 if (frametype && strcasecmp(frametype, "AuthenticationConfirm") == 0) { 2353 if (dpp_wait_tx_status(dut, ctrl, 2) < 0) { 2354 send_resp(dut, conn, SIGMA_COMPLETE, 2355 "BootstrapResult,OK,AuthResult,Timeout"); 2356 goto out; 2357 } 2358 2359 if (dpp_wait_rx_conf_req(dut, ctrl, 5) < 0) 2360 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationResponse"; 2361 else 2362 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,ConfigurationRequest"; 2363 send_resp(dut, conn, SIGMA_COMPLETE, result); 2364 goto out; 2365 } 2366 2367 if (strstr(buf, "DPP-AUTH-DIRECTION")) { 2368 res = get_wpa_cli_events(dut, ctrl, auth_events, 2369 buf, sizeof(buf)); 2370 if (res < 0) { 2371 send_resp(dut, conn, SIGMA_COMPLETE, 2372 "BootstrapResult,OK,AuthResult,Timeout"); 2373 goto out; 2374 } 2375 2376 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP auth result: %s", buf); 2377 } 2378 2379 if (strstr(buf, "DPP-NOT-COMPATIBLE")) { 2380 send_resp(dut, conn, SIGMA_COMPLETE, 2381 "BootstrapResult,OK,AuthResult,ROLES_NOT_COMPATIBLE"); 2382 goto out; 2383 } 2384 2385 if (!strstr(buf, "DPP-AUTH-SUCCESS")) { 2386 send_resp(dut, conn, SIGMA_COMPLETE, 2387 "BootstrapResult,OK,AuthResult,FAILED"); 2388 goto out; 2389 } 2390 2391 if (frametype && strcasecmp(frametype, "ConfigurationRequest") == 0) { 2392 res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE", 2393 buf, sizeof(buf)); 2394 if (res < 0) 2395 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Timeout"; 2396 else 2397 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Errorsent"; 2398 send_resp(dut, conn, SIGMA_COMPLETE, result); 2399 goto out; 2400 } 2401 2402 if (frametype && strcasecmp(frametype, "ConfigurationResponse") == 0) { 2403 res = get_wpa_cli_events(dut, ctrl, conf_events, 2404 buf, sizeof(buf)); 2405 if (res >= 0 && strstr(buf, "DPP-MUD-URL ")) 2406 res = get_wpa_cli_events(dut, ctrl, conf_events, 2407 buf, sizeof(buf)); 2408 if (res < 0) 2409 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Timeout"; 2410 else 2411 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Errorsent,LastFrameReceived,ConfigurationRequest"; 2412 send_resp(dut, conn, SIGMA_COMPLETE, result); 2413 goto out; 2414 } 2415 2416 if (strcasecmp(prov_role, "Configurator") == 0 && csrattrs[0]) { 2417 res = get_wpa_cli_event(dut, ctrl, "DPP-CSR", buf, sizeof(buf)); 2418 if (res < 0) { 2419 send_resp(dut, conn, SIGMA_ERROR, 2420 "errorCode,No CSR received from Enrollee"); 2421 res = STATUS_SENT_ERROR; 2422 goto out; 2423 } 2424 2425 if (dpp_process_csr(dut, ifname, buf) < 0) { 2426 send_resp(dut, conn, SIGMA_ERROR, 2427 "errorCode,Failed to process CSR"); 2428 res = STATUS_SENT_ERROR; 2429 goto out; 2430 } 2431 } 2432 2433 res = get_wpa_cli_events(dut, ctrl, conf_events, buf, sizeof(buf)); 2434 if (res >= 0 && strstr(buf, "DPP-MUD-URL ")) { 2435 size_t url_len; 2436 2437 pos = strchr(buf, ' '); 2438 if (!pos) 2439 goto err; 2440 pos++; 2441 url_len = strlen(buf); 2442 mud_url = malloc(9 + url_len); 2443 if (!mud_url) 2444 goto err; 2445 memcpy(mud_url, ",MUDURL,", 8); 2446 memcpy(mud_url + 8, pos, url_len + 1); 2447 2448 res = get_wpa_cli_events(dut, ctrl, conf_events, 2449 buf, sizeof(buf)); 2450 } 2451 if (res < 0) { 2452 send_resp(dut, conn, SIGMA_COMPLETE, 2453 "BootstrapResult,OK,AuthResult,OK,ConfResult,Timeout"); 2454 goto out; 2455 } 2456 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP conf result: %s", buf); 2457 2458 if (!strstr(buf, "DPP-CONF-SENT") && 2459 !strstr(buf, "DPP-CONF-RECEIVED")) { 2460 send_resp(dut, conn, SIGMA_COMPLETE, 2461 "BootstrapResult,OK,AuthResult,OK,ConfResult,FAILED"); 2462 goto out; 2463 } 2464 2465 if (conn_status && strstr(buf, "DPP-CONF-SENT") && 2466 strstr(buf, "wait_conn_status=1")) { 2467 res = get_wpa_cli_event(dut, ctrl, "DPP-CONN-STATUS-RESULT", 2468 buf, sizeof(buf)); 2469 if (res < 0) { 2470 send_resp(dut, conn, SIGMA_COMPLETE, 2471 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,StatusResult,Timeout"); 2472 } else { 2473 pos = strstr(buf, "result="); 2474 if (!pos) { 2475 send_resp(dut, conn, SIGMA_ERROR, 2476 "errorCode,Status result value not reported"); 2477 } else { 2478 pos += 7; 2479 snprintf(buf, sizeof(buf), 2480 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,StatusResult,%d%s", 2481 atoi(pos), mud_url); 2482 send_resp(dut, conn, SIGMA_COMPLETE, buf); 2483 } 2484 } 2485 goto out; 2486 } 2487 2488 if (strcasecmp(prov_role, "Enrollee") == 0 && netrole && 2489 strcmp(netrole, "configurator") == 0) { 2490 res = get_wpa_cli_event(dut, ctrl, "DPP-CONFIGURATOR-ID", 2491 buf, sizeof(buf)); 2492 if (res < 0) { 2493 send_resp(dut, conn, SIGMA_ERROR, 2494 "errorCode,No DPP-CONFIGURATOR-ID"); 2495 goto out; 2496 } 2497 pos = strchr(buf, ' '); 2498 if (!pos) { 2499 send_resp(dut, conn, SIGMA_ERROR, 2500 "errorCode,Invalid DPP-CONFIGURATOR-ID"); 2501 goto out; 2502 } 2503 pos++; 2504 dut->dpp_conf_id = atoi(pos); 2505 } else if (sigma_dut_is_ap(dut) && 2506 strcasecmp(prov_role, "Enrollee") == 0) { 2507 update_ap: 2508 res = dpp_hostapd_conf_update(dut, conn, ifname, ctrl); 2509 if (res == 0) 2510 goto out; 2511 if (res < 0) { 2512 send_resp(dut, conn, SIGMA_ERROR, NULL); 2513 goto out; 2514 } 2515 } 2516 2517 if (strcasecmp(wait_conn, "Yes") == 0 && 2518 !sigma_dut_is_ap(dut) && 2519 strcasecmp(prov_role, "Enrollee") == 0) { 2520 int netw_id; 2521 char *pos; 2522 2523 res = get_wpa_cli_event(dut, ctrl, "DPP-NETWORK-ID", 2524 buf, sizeof(buf)); 2525 if (res < 0) { 2526 send_resp(dut, conn, SIGMA_ERROR, 2527 "errorCode,No DPP-NETWORK-ID"); 2528 goto out; 2529 } 2530 pos = strchr(buf, ' '); 2531 if (!pos) { 2532 send_resp(dut, conn, SIGMA_ERROR, 2533 "errorCode,Invalid DPP-NETWORK-ID"); 2534 goto out; 2535 } 2536 pos++; 2537 netw_id = atoi(pos); 2538 snprintf(buf, sizeof(buf), "GET_NETWORK %d key_mgmt", netw_id); 2539 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0) { 2540 send_resp(dut, conn, SIGMA_ERROR, 2541 "errorCode,Could not fetch provisioned key_mgmt"); 2542 goto out; 2543 } 2544 if (strncmp(buf, "SAE", 3) == 0) { 2545 /* SAE generates PMKSA-CACHE-ADDED event */ 2546 not_dpp_akm = 1; 2547 } 2548 dut->dpp_network_id = netw_id; 2549 wait_connect: 2550 if (frametype && strcasecmp(frametype, 2551 "PeerDiscoveryRequest") == 0) { 2552 if (dpp_wait_tx_status(dut, ctrl, 5) < 0) 2553 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Timeout"; 2554 else 2555 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Errorsent"; 2556 send_resp(dut, conn, SIGMA_COMPLETE, result); 2557 goto out; 2558 } 2559 2560 res = get_wpa_cli_events(dut, ctrl, conn_events, 2561 buf, sizeof(buf)); 2562 if (res < 0) { 2563 send_resp(dut, conn, SIGMA_COMPLETE, 2564 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Timeout,NetworkConnectResult,Timeout"); 2565 goto out; 2566 } 2567 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP connect result: %s", 2568 buf); 2569 2570 if (strstr(buf, "PMKSA-CACHE-ADDED")) { 2571 res = get_wpa_cli_events(dut, ctrl, conn_events, 2572 buf, sizeof(buf)); 2573 if (res < 0) { 2574 send_resp(dut, conn, SIGMA_COMPLETE, 2575 not_dpp_akm ? 2576 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkConnectResult,Timeout" : 2577 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,Timeout"); 2578 goto out; 2579 } 2580 sigma_dut_print(dut, DUT_MSG_DEBUG, 2581 "DPP connect result: %s", buf); 2582 if (strstr(buf, "CTRL-EVENT-CONNECTED")) 2583 send_resp(dut, conn, SIGMA_COMPLETE, 2584 not_dpp_akm ? 2585 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkConnectResult,OK" : 2586 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,OK"); 2587 else 2588 send_resp(dut, conn, SIGMA_COMPLETE, 2589 not_dpp_akm ? 2590 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkConnectResult,Timeout" : 2591 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,Timeout"); 2592 goto out; 2593 } 2594 2595 send_resp(dut, conn, SIGMA_COMPLETE, 2596 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkConnectResult,OK"); 2597 goto out; 2598 } else if (!sigma_dut_is_ap(dut) && 2599 strcasecmp(prov_role, "Enrollee") == 0) { 2600 /* Store DPP network id for reconfiguration */ 2601 char *pos; 2602 unsigned int old_timeout; 2603 2604 old_timeout = dut->default_timeout; 2605 dut->default_timeout = 3; 2606 res = get_wpa_cli_event(dut, ctrl, "DPP-NETWORK-ID", 2607 buf, sizeof(buf)); 2608 dut->default_timeout = old_timeout; 2609 2610 if (res < 0) { 2611 sigma_dut_print(dut, DUT_MSG_INFO, "No DPP-NETWORK-ID"); 2612 } else { 2613 pos = strchr(buf, ' '); 2614 if (!pos) { 2615 sigma_dut_print(dut, DUT_MSG_INFO, 2616 "Invalid DPP-NETWORK-ID"); 2617 } else { 2618 pos++; 2619 dut->dpp_network_id = atoi(pos); 2620 } 2621 } 2622 } 2623 2624 if (strcasecmp(wait_conn, "Yes") == 0 && 2625 frametype && strcasecmp(frametype, "PeerDiscoveryResponse") == 0) { 2626 if (dpp_wait_tx_status(dut, ctrl, 6) < 0) 2627 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Timeout"; 2628 else 2629 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Errorsent"; 2630 send_resp(dut, conn, SIGMA_COMPLETE, result); 2631 goto out; 2632 } 2633 2634 snprintf(buf, sizeof(buf), 2635 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK%s", mud_url); 2636 send_resp(dut, conn, SIGMA_COMPLETE, buf); 2637 out: 2638 if (mud_url != no_mud_url) 2639 free(mud_url); 2640 wpa_ctrl_detach(ctrl); 2641 wpa_ctrl_close(ctrl); 2642 if (tcp && strcasecmp(tcp, "yes") == 0 && 2643 auth_role && strcasecmp(auth_role, "Responder") == 0) 2644 wpa_command(ifname, "DPP_CONTROLLER_STOP"); 2645 dut->default_timeout = old_timeout; 2646 return STATUS_SENT; 2647 err: 2648 send_resp(dut, conn, SIGMA_ERROR, NULL); 2649 goto out; 2650 } 2651 2652 2653 static enum sigma_cmd_result dpp_manual_dpp(struct sigma_dut *dut, 2654 struct sigma_conn *conn, 2655 struct sigma_cmd *cmd) 2656 { 2657 const char *auth_role = get_param(cmd, "DPPAuthRole"); 2658 const char *self_conf = get_param(cmd, "DPPSelfConfigure"); 2659 enum sigma_cmd_result res = INVALID_SEND_STATUS; 2660 int success; 2661 const char *val; 2662 unsigned int old_timeout; 2663 const char *bs = get_param(cmd, "DPPBS"); 2664 2665 if (!self_conf) 2666 self_conf = "no"; 2667 2668 old_timeout = dut->default_timeout; 2669 val = get_param(cmd, "DPPTimeout"); 2670 if (val && atoi(val) > 0) { 2671 dut->default_timeout = atoi(val); 2672 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP timeout: %u", 2673 dut->default_timeout); 2674 } 2675 2676 if (strcasecmp(bs, "NFC") == 0) { 2677 res = dpp_automatic_dpp(dut, conn, cmd); 2678 goto out; 2679 } 2680 2681 res = dpp_get_local_bootstrap(dut, conn, cmd, 0, &success); 2682 if (res != STATUS_SENT || !success) 2683 goto out; 2684 2685 if (!auth_role) { 2686 send_resp(dut, conn, SIGMA_ERROR, 2687 "errorCode,Missing DPPAuthRole"); 2688 return STATUS_SENT_ERROR; 2689 } 2690 2691 if (strcasecmp(auth_role, "Responder") == 0) { 2692 if (dpp_display_own_qrcode(dut) < 0) { 2693 send_resp(dut, conn, SIGMA_ERROR, 2694 "errorCode,Failed to display own QR code"); 2695 res = STATUS_SENT_ERROR; 2696 goto out; 2697 } 2698 2699 res = dpp_automatic_dpp(dut, conn, cmd); 2700 goto out; 2701 } 2702 2703 if (strcasecmp(auth_role, "Initiator") == 0) { 2704 if (strcasecmp(self_conf, "Yes") != 0) { 2705 if (dpp_scan_peer_qrcode(dut) < 0) { 2706 send_resp(dut, conn, SIGMA_ERROR, 2707 "errorCode,Failed to scan peer QR Code"); 2708 res = STATUS_SENT_ERROR; 2709 goto out; 2710 } 2711 } 2712 2713 res = dpp_automatic_dpp(dut, conn, cmd); 2714 goto out; 2715 } 2716 2717 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unknown DPPAuthRole"); 2718 res = STATUS_SENT_ERROR; 2719 out: 2720 dut->default_timeout = old_timeout; 2721 return res; 2722 } 2723 2724 2725 static enum sigma_cmd_result 2726 dpp_reconfigure_configurator(struct sigma_dut *dut, struct sigma_conn *conn, 2727 struct sigma_cmd *cmd) 2728 { 2729 const char *val; 2730 int freq; 2731 struct wpa_ctrl *ctrl = NULL; 2732 const char *ifname; 2733 int conf_index; 2734 const char *conf_role; 2735 const char *group_id_str = NULL; 2736 char *pos; 2737 char buf[2000]; 2738 char buf2[200]; 2739 char conf_ssid[100]; 2740 char conf_pass[100]; 2741 char csrattrs[200]; 2742 char group_id[100]; 2743 char conf2[300]; 2744 FILE *f; 2745 int enrollee_ap = 0; 2746 int force_gas_fragm = 0; 2747 int akm_use_selector = 0; 2748 int conn_status; 2749 int res; 2750 const char *conf_events[] = { 2751 "DPP-CONF-SENT", 2752 "DPP-CONF-FAILED", 2753 NULL 2754 }; 2755 2756 if (sigma_dut_is_ap(dut)) { 2757 if (!dut->hostapd_ifname) { 2758 sigma_dut_print(dut, DUT_MSG_ERROR, 2759 "hostapd ifname not specified (-j)"); 2760 return ERROR_SEND_STATUS; 2761 } 2762 ifname = dut->hostapd_ifname; 2763 } else { 2764 ifname = get_station_ifname(dut); 2765 } 2766 2767 val = get_param(cmd, "DPPConfEnrolleeRole"); 2768 if (val) 2769 enrollee_ap = strcasecmp(val, "AP") == 0; 2770 2771 val = get_param(cmd, "DPPStatusQuery"); 2772 conn_status = val && strcasecmp(val, "Yes") == 0; 2773 2774 conf_ssid[0] = '\0'; 2775 conf_pass[0] = '\0'; 2776 csrattrs[0] = '\0'; 2777 group_id[0] = '\0'; 2778 conf2[0] = '\0'; 2779 2780 val = get_param(cmd, "DPPConfIndex"); 2781 if (!val) { 2782 sigma_dut_print(dut, DUT_MSG_ERROR, 2783 "DPPConfIndex not specified for Configurator"); 2784 return ERROR_SEND_STATUS; 2785 } 2786 conf_index = atoi(val); 2787 2788 switch (conf_index) { 2789 case 1: 2790 ascii2hexstr("DPPNET01", buf); 2791 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf); 2792 if (res < 0 || res >= sizeof(conf_ssid)) 2793 goto err; 2794 if (enrollee_ap) { 2795 conf_role = "ap-dpp"; 2796 } else { 2797 conf_role = "sta-dpp"; 2798 } 2799 group_id_str = "DPPGROUP_DPP_INFRA"; 2800 break; 2801 case 2: 2802 ascii2hexstr("DPPNET01", buf); 2803 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf); 2804 if (res < 0 || res >= sizeof(conf_ssid)) 2805 goto err; 2806 snprintf(conf_pass, sizeof(conf_pass), 2807 "psk=10506e102ad1e7f95112f6b127675bb8344dacacea60403f3fa4055aec85b0fc"); 2808 if (enrollee_ap) 2809 conf_role = "ap-psk"; 2810 else 2811 conf_role = "sta-psk"; 2812 break; 2813 case 3: 2814 ascii2hexstr("DPPNET01", buf); 2815 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf); 2816 if (res < 0 || res >= sizeof(conf_ssid)) 2817 goto err; 2818 ascii2hexstr("ThisIsDppPassphrase", buf); 2819 res = snprintf(conf_pass, sizeof(conf_pass), "pass=%s", buf); 2820 if (res < 0 || res >= sizeof(conf_pass)) 2821 goto err; 2822 if (enrollee_ap) 2823 conf_role = "ap-psk"; 2824 else 2825 conf_role = "sta-psk"; 2826 break; 2827 case 4: 2828 ascii2hexstr("DPPNET01", buf); 2829 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf); 2830 if (res < 0 || res >= sizeof(conf_ssid)) 2831 goto err; 2832 if (enrollee_ap) { 2833 conf_role = "ap-dpp"; 2834 } else { 2835 conf_role = "sta-dpp"; 2836 } 2837 group_id_str = "DPPGROUP_DPP_INFRA2"; 2838 break; 2839 case 5: 2840 ascii2hexstr("DPPNET01", buf); 2841 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf); 2842 if (res < 0 || res >= sizeof(conf_ssid)) 2843 goto err; 2844 ascii2hexstr("ThisIsDppPassphrase", buf); 2845 res = snprintf(conf_pass, sizeof(conf_pass), "pass=%s", buf); 2846 if (res < 0 || res >= sizeof(conf_pass)) 2847 goto err; 2848 if (enrollee_ap) 2849 conf_role = "ap-sae"; 2850 else 2851 conf_role = "sta-sae"; 2852 break; 2853 case 6: 2854 ascii2hexstr("DPPNET01", buf); 2855 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf); 2856 if (res < 0 || res >= sizeof(conf_ssid)) 2857 goto err; 2858 ascii2hexstr("ThisIsDppPassphrase", buf); 2859 res = snprintf(conf_pass, sizeof(conf_pass), "pass=%s", buf); 2860 if (res < 0 || res >= sizeof(conf_pass)) 2861 goto err; 2862 if (enrollee_ap) 2863 conf_role = "ap-psk-sae"; 2864 else 2865 conf_role = "sta-psk-sae"; 2866 break; 2867 case 7: 2868 ascii2hexstr("DPPNET01", buf); 2869 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf); 2870 if (res < 0 || res >= sizeof(conf_ssid)) 2871 goto err; 2872 if (enrollee_ap) { 2873 conf_role = "ap-dpp"; 2874 } else { 2875 conf_role = "sta-dpp"; 2876 } 2877 group_id_str = "DPPGROUP_DPP_INFRA"; 2878 force_gas_fragm = 1; 2879 break; 2880 case 8: 2881 case 9: 2882 ascii2hexstr("DPPNET01", buf); 2883 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf); 2884 if (res < 0 || res >= sizeof(conf_ssid)) 2885 goto err; 2886 ascii2hexstr("This_is_legacy_password", buf); 2887 res = snprintf(conf_pass, sizeof(conf_pass), "pass=%s", buf); 2888 if (res < 0 || res >= sizeof(conf_pass)) 2889 goto err; 2890 if (enrollee_ap) { 2891 conf_role = "ap-dpp+psk+sae"; 2892 } else { 2893 conf_role = "sta-dpp+psk+sae"; 2894 } 2895 group_id_str = "DPPGROUP_DPP_INFRA1"; 2896 if (conf_index == 9) 2897 akm_use_selector = 1; 2898 break; 2899 case 10: 2900 ascii2hexstr("DPPNET01", buf); 2901 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf); 2902 if (res < 0 || res >= sizeof(conf_ssid)) 2903 goto err; 2904 if (enrollee_ap) 2905 conf_role = "ap-dpp"; 2906 else 2907 conf_role = "sta-dpp"; 2908 group_id_str = "DPPGROUP_DPP_INFRA1"; 2909 ascii2hexstr("DPPNET02", buf); 2910 ascii2hexstr("This_is_legacy_password", buf2); 2911 res = snprintf(conf2, sizeof(conf2), 2912 " @CONF-OBJ-SEP@ conf=%s-dpp+psk+sae ssid=%s pass=%s group_id=DPPGROUP_DPP_INFRA2", 2913 enrollee_ap ? "ap" : "sta", buf, buf2); 2914 if (res < 0 || res >= sizeof(conf2)) 2915 goto err; 2916 break; 2917 case 11: 2918 ascii2hexstr("DPPNET01", buf); 2919 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf); 2920 if (res < 0 || res >= sizeof(conf_ssid)) 2921 goto err; 2922 if (enrollee_ap) { 2923 send_resp(dut, conn, SIGMA_ERROR, 2924 "errorCode,dot1x AKM provisioning not supported for AP"); 2925 goto out; 2926 } 2927 conf_role = "sta-dot1x"; 2928 snprintf(buf, sizeof(buf), "%s/dpp-ca-csrattrs", 2929 sigma_cert_path); 2930 f = fopen(buf, "r"); 2931 if (f) { 2932 size_t len; 2933 int r; 2934 2935 len = fread(buf, 1, sizeof(buf), f); 2936 fclose(f); 2937 if (len >= sizeof(buf)) { 2938 send_resp(dut, conn, SIGMA_ERROR, 2939 "errorCode,No room for csrAttrs"); 2940 goto out; 2941 } 2942 buf[len] = '\0'; 2943 sigma_dut_print(dut, DUT_MSG_INFO, 2944 "Use csrAttrs from file"); 2945 r = snprintf(csrattrs, sizeof(csrattrs), 2946 " csrattrs=%s", buf); 2947 if (r <= 0 || r >= sizeof(csrattrs)) { 2948 send_resp(dut, conn, SIGMA_ERROR, 2949 "errorCode,No room for csrAttrs"); 2950 goto out; 2951 } 2952 } else { 2953 sigma_dut_print(dut, DUT_MSG_INFO, 2954 "Use default csrAttrs"); 2955 snprintf(csrattrs, sizeof(csrattrs), "%s", 2956 " csrattrs=MAsGCSqGSIb3DQEJBw=="); 2957 } 2958 break; 2959 default: 2960 send_resp(dut, conn, SIGMA_ERROR, 2961 "errorCode,Unsupported DPPConfIndex"); 2962 goto out; 2963 } 2964 2965 if (group_id_str) 2966 snprintf(group_id, sizeof(group_id), " group_id=%s", 2967 group_id_str); 2968 2969 if (force_gas_fragm) { 2970 char spaces[1500]; 2971 2972 memset(spaces, ' ', sizeof(spaces)); 2973 spaces[sizeof(spaces) - 1] = '\0'; 2974 2975 snprintf(buf, sizeof(buf), 2976 "SET dpp_discovery_override {\"ssid\":\"DPPNET01\"}%s", 2977 spaces); 2978 if (wpa_command(ifname, buf) < 0) { 2979 send_resp(dut, conn, SIGMA_ERROR, 2980 "errorCode,Failed to set discovery override"); 2981 goto out; 2982 } 2983 } 2984 2985 snprintf(buf, sizeof(buf), 2986 "SET dpp_configurator_params conf=%s %s %s configurator=%d%s%s%s%s%s", 2987 conf_role, conf_ssid, conf_pass, 2988 dut->dpp_conf_id, group_id, 2989 akm_use_selector ? " akm_use_selector=1" : "", 2990 conn_status ? " conn_status=1" : "", csrattrs, 2991 conf2); 2992 if (wpa_command(ifname, buf) < 0) { 2993 send_resp(dut, conn, SIGMA_ERROR, 2994 "errorCode,Failed to set configurator parameters"); 2995 goto out; 2996 } 2997 2998 ctrl = open_wpa_mon(ifname); 2999 if (!ctrl) { 3000 sigma_dut_print(dut, DUT_MSG_ERROR, 3001 "Failed to open wpa_supplicant monitor connection"); 3002 return ERROR_SEND_STATUS; 3003 } 3004 3005 val = get_param(cmd, "DPPListenChannel"); 3006 if (val) { 3007 freq = channel_to_freq(dut, atoi(val)); 3008 if (freq == 0) { 3009 send_resp(dut, conn, SIGMA_ERROR, 3010 "errorCode,Unsupported DPPListenChannel value"); 3011 goto out; 3012 } 3013 snprintf(buf, sizeof(buf), 3014 "DPP_LISTEN %d role=configurator", freq); 3015 if (wpa_command(ifname, buf) < 0) { 3016 send_resp(dut, conn, SIGMA_ERROR, 3017 "errorCode,Could not start listen state"); 3018 goto out; 3019 } 3020 } 3021 3022 res = get_wpa_cli_event(dut, ctrl, "DPP-CONF-REQ-RX", 3023 buf, sizeof(buf)); 3024 if (res < 0) { 3025 send_resp(dut, conn, SIGMA_COMPLETE, 3026 "ReconfigAuthResult,Timeout"); 3027 goto out; 3028 } 3029 3030 res = get_wpa_cli_events(dut, ctrl, conf_events, buf, sizeof(buf)); 3031 if (res < 0) { 3032 send_resp(dut, conn, SIGMA_COMPLETE, 3033 "ReconfigAuthResult,OK,ConfResult,Timeout"); 3034 goto out; 3035 } 3036 if (!strstr(buf, "DPP-CONF-SENT")) { 3037 send_resp(dut, conn, SIGMA_COMPLETE, 3038 "ReconfigAuthResult,OK,ConfResult,FAILED"); 3039 goto out; 3040 } 3041 3042 if (conn_status && strstr(buf, "wait_conn_status=1")) { 3043 res = get_wpa_cli_event(dut, ctrl, "DPP-CONN-STATUS-RESULT", 3044 buf, sizeof(buf)); 3045 if (res < 0) { 3046 send_resp(dut, conn, SIGMA_COMPLETE, 3047 "ReconfigAuthResult,OK,ConfResult,OK,StatusResult,Timeout"); 3048 } else { 3049 pos = strstr(buf, "result="); 3050 if (!pos) { 3051 send_resp(dut, conn, SIGMA_ERROR, 3052 "errorCode,Status result value not reported"); 3053 } else { 3054 pos += 7; 3055 snprintf(buf, sizeof(buf), 3056 "ReconfigAuthResult,OK,ConfResult,OK,StatusResult,%d", 3057 atoi(pos)); 3058 send_resp(dut, conn, SIGMA_COMPLETE, buf); 3059 } 3060 } 3061 goto out; 3062 } 3063 3064 send_resp(dut, conn, SIGMA_COMPLETE, 3065 "ReconfigAuthResult,OK,ConfResult,OK"); 3066 3067 out: 3068 if (ctrl) { 3069 wpa_ctrl_detach(ctrl); 3070 wpa_ctrl_close(ctrl); 3071 } 3072 return STATUS_SENT; 3073 err: 3074 send_resp(dut, conn, SIGMA_ERROR, NULL); 3075 goto out; 3076 } 3077 3078 3079 static enum sigma_cmd_result dpp_reconfigure(struct sigma_dut *dut, 3080 struct sigma_conn *conn, 3081 struct sigma_cmd *cmd) 3082 { 3083 const char *wait_conn; 3084 char buf[200]; 3085 const char *ifname; 3086 struct wpa_ctrl *ctrl; 3087 const char *conf_events[] = { 3088 "DPP-CONF-RECEIVED", 3089 "DPP-CONF-FAILED", 3090 NULL 3091 }; 3092 const char *conn_events[] = { 3093 "PMKSA-CACHE-ADDED", 3094 "CTRL-EVENT-CONNECTED", 3095 NULL 3096 }; 3097 int res; 3098 3099 if (get_param(cmd, "DPPConfIndex")) 3100 return dpp_reconfigure_configurator(dut, conn, cmd); 3101 3102 /* Enrollee reconfiguration steps */ 3103 ifname = get_station_ifname(dut); 3104 wait_conn = get_param(cmd, "DPPWaitForConnect"); 3105 if (!wait_conn) 3106 wait_conn = "no"; 3107 3108 ctrl = open_wpa_mon(ifname); 3109 if (!ctrl) { 3110 sigma_dut_print(dut, DUT_MSG_ERROR, 3111 "Failed to open wpa_supplicant monitor connection"); 3112 return ERROR_SEND_STATUS; 3113 } 3114 3115 snprintf(buf, sizeof(buf), "DPP_RECONFIG %d iter=10", 3116 dut->dpp_network_id); 3117 if (wpa_command(ifname, buf) < 0) { 3118 send_resp(dut, conn, SIGMA_ERROR, 3119 "errorCode,Failed to start reconfiguration"); 3120 goto out; 3121 } 3122 3123 res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-START", 3124 buf, sizeof(buf)); 3125 if (res < 0) { 3126 send_resp(dut, conn, SIGMA_COMPLETE, 3127 "ReconfigAuthResult,Timeout"); 3128 goto out; 3129 } 3130 3131 res = get_wpa_cli_events(dut, ctrl, conf_events, buf, sizeof(buf)); 3132 if (res < 0) { 3133 send_resp(dut, conn, SIGMA_COMPLETE, 3134 "ReconfigAuthResult,OK,ConfResult,Timeout"); 3135 goto out; 3136 } 3137 if (!strstr(buf, "DPP-CONF-RECEIVED")) { 3138 send_resp(dut, conn, SIGMA_COMPLETE, 3139 "ReconfigAuthResult,OK,ConfResult,FAILED"); 3140 goto out; 3141 } 3142 3143 if (strcasecmp(wait_conn, "Yes") == 0) { 3144 int not_dpp_akm = 0; 3145 3146 snprintf(buf, sizeof(buf), "GET_NETWORK %d key_mgmt", 3147 dut->dpp_network_id); 3148 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0) { 3149 send_resp(dut, conn, SIGMA_ERROR, 3150 "errorCode,Could not fetch provisioned key_mgmt"); 3151 goto out; 3152 } 3153 if (strncmp(buf, "SAE", 3) == 0) { 3154 /* SAE generates PMKSA-CACHE-ADDED event */ 3155 not_dpp_akm = 1; 3156 } 3157 3158 res = get_wpa_cli_events(dut, ctrl, conn_events, 3159 buf, sizeof(buf)); 3160 if (res < 0) { 3161 send_resp(dut, conn, SIGMA_COMPLETE, 3162 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Timeout,NetworkConnectResult,Timeout"); 3163 goto out; 3164 } 3165 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP connect result: %s", 3166 buf); 3167 3168 if (strstr(buf, "PMKSA-CACHE-ADDED")) { 3169 res = get_wpa_cli_events(dut, ctrl, conn_events, 3170 buf, sizeof(buf)); 3171 if (res < 0) { 3172 send_resp(dut, conn, SIGMA_COMPLETE, 3173 not_dpp_akm ? 3174 "ReconfigAuthResult,OK,ConfResult,OK,NetworkConnectResult,Timeout" : 3175 "ReconfigAuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,Timeout"); 3176 goto out; 3177 } 3178 sigma_dut_print(dut, DUT_MSG_DEBUG, 3179 "DPP connect result: %s", buf); 3180 if (strstr(buf, "CTRL-EVENT-CONNECTED")) 3181 send_resp(dut, conn, SIGMA_COMPLETE, 3182 not_dpp_akm ? 3183 "ReconfigAuthResult,OK,ConfResult,OK,NetworkConnectResult,OK" : 3184 "ReconfigAuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,OK"); 3185 else 3186 send_resp(dut, conn, SIGMA_COMPLETE, 3187 not_dpp_akm ? 3188 "ReconfigAuthResult,OK,ConfResult,OK,NetworkConnectResult,Timeout" : 3189 "ReconfigAuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,Timeout"); 3190 goto out; 3191 } 3192 3193 send_resp(dut, conn, SIGMA_COMPLETE, 3194 "ReconfigAuthResult,OK,ConfResult,OK,NetworkConnectResult,OK"); 3195 goto out; 3196 } 3197 3198 send_resp(dut, conn, SIGMA_COMPLETE, 3199 "ReconfigAuthResult,OK,ConfResult,OK"); 3200 3201 out: 3202 wpa_ctrl_detach(ctrl); 3203 wpa_ctrl_close(ctrl); 3204 return STATUS_SENT; 3205 } 3206 3207 3208 enum sigma_cmd_result dpp_dev_exec_action(struct sigma_dut *dut, 3209 struct sigma_conn *conn, 3210 struct sigma_cmd *cmd) 3211 { 3212 const char *type = get_param(cmd, "DPPActionType"); 3213 const char *bs = get_param(cmd, "DPPBS"); 3214 3215 if (!type) { 3216 send_resp(dut, conn, SIGMA_ERROR, 3217 "errorCode,Missing DPPActionType"); 3218 return STATUS_SENT_ERROR; 3219 } 3220 3221 if (strcasecmp(type, "DPPReconfigure") == 0) 3222 return dpp_reconfigure(dut, conn, cmd); 3223 3224 if (!bs) { 3225 send_resp(dut, conn, SIGMA_ERROR, 3226 "errorCode,Missing DPPBS"); 3227 return STATUS_SENT_ERROR; 3228 } 3229 3230 if (strcasecmp(type, "GetLocalBootstrap") == 0) 3231 return dpp_get_local_bootstrap(dut, conn, cmd, 1, NULL); 3232 if (strcasecmp(type, "SetPeerBootstrap") == 0) 3233 return dpp_set_peer_bootstrap(dut, conn, cmd); 3234 if (strcasecmp(type, "ManualDPP") == 0) 3235 return dpp_manual_dpp(dut, conn, cmd); 3236 if (strcasecmp(type, "AutomaticDPP") == 0) 3237 return dpp_automatic_dpp(dut, conn, cmd); 3238 3239 send_resp(dut, conn, SIGMA_ERROR, 3240 "errorCode,Unsupported DPPActionType"); 3241 return STATUS_SENT_ERROR; 3242 } 3243