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