1d86e5828SJouni Malinen /* 2d86e5828SJouni Malinen * Sigma Control API DUT (station/AP/sniffer) 3d86e5828SJouni Malinen * Copyright (c) 2017, Qualcomm Atheros, Inc. 4d86e5828SJouni Malinen * All Rights Reserved. 5d86e5828SJouni Malinen * Licensed under the Clear BSD license. See README for more details. 6d86e5828SJouni Malinen */ 7d86e5828SJouni Malinen 8d86e5828SJouni Malinen #include "sigma_dut.h" 9d86e5828SJouni Malinen #include "wpa_ctrl.h" 10d86e5828SJouni Malinen #include "wpa_helpers.h" 11d86e5828SJouni Malinen 12d86e5828SJouni Malinen 13d86e5828SJouni Malinen static int sigma_dut_is_ap(struct sigma_dut *dut) 14d86e5828SJouni Malinen { 15d86e5828SJouni Malinen return dut->device_type == AP_unknown || 16d86e5828SJouni Malinen dut->device_type == AP_testbed || 17d86e5828SJouni Malinen dut->device_type == AP_dut; 18d86e5828SJouni Malinen } 19d86e5828SJouni Malinen 20d86e5828SJouni Malinen 21d86e5828SJouni Malinen static int dpp_hostapd_run(struct sigma_dut *dut) 22d86e5828SJouni Malinen { 23d86e5828SJouni Malinen if (dut->hostapd_running) 24d86e5828SJouni Malinen return 0; 25d86e5828SJouni Malinen 26d86e5828SJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, 27d86e5828SJouni Malinen "Starting hostapd in unconfigured state for DPP"); 28d86e5828SJouni Malinen snprintf(dut->ap_ssid, sizeof(dut->ap_ssid), "unconfigured"); 29d86e5828SJouni Malinen dut->ap_channel = 11; 30d86e5828SJouni Malinen dut->ap_is_dual = 0; 31d86e5828SJouni Malinen dut->ap_mode = AP_11ng; 32d86e5828SJouni Malinen dut->ap_key_mgmt = AP_OPEN; 33d86e5828SJouni Malinen dut->ap_cipher = AP_PLAIN; 34d86e5828SJouni Malinen return cmd_ap_config_commit(dut, NULL, NULL) == 1 ? 0 : -1; 35d86e5828SJouni Malinen } 36d86e5828SJouni Malinen 37d86e5828SJouni Malinen 38d86e5828SJouni Malinen static const char * dpp_get_curve(struct sigma_cmd *cmd, const char *arg) 39d86e5828SJouni Malinen { 40d86e5828SJouni Malinen const char *val = get_param(cmd, arg); 41d86e5828SJouni Malinen 42d86e5828SJouni Malinen if (!val) 43d86e5828SJouni Malinen val = "P-256"; 44d86e5828SJouni Malinen else if (strcasecmp(val, "BP-256R1") == 0) 45d86e5828SJouni Malinen val = "BP-256"; 46d86e5828SJouni Malinen else if (strcasecmp(val, "BP-384R1") == 0) 47d86e5828SJouni Malinen val = "BP-384"; 48d86e5828SJouni Malinen else if (strcasecmp(val, "BP-512R1") == 0) 49d86e5828SJouni Malinen val = "BP-512"; 50d86e5828SJouni Malinen 51d86e5828SJouni Malinen return val; 52d86e5828SJouni Malinen } 53d86e5828SJouni Malinen 54d86e5828SJouni Malinen 55d86e5828SJouni Malinen static int dpp_get_local_bootstrap(struct sigma_dut *dut, 56d86e5828SJouni Malinen struct sigma_conn *conn, 57d86e5828SJouni Malinen struct sigma_cmd *cmd) 58d86e5828SJouni Malinen { 59d86e5828SJouni Malinen const char *curve = dpp_get_curve(cmd, "DPPCryptoIdentifier"); 60d86e5828SJouni Malinen const char *bs = get_param(cmd, "DPPBS"); 614161c3f0SJouni Malinen const char *chan_list = get_param(cmd, "DPPChannelList"); 624161c3f0SJouni Malinen char *pos, mac[50], buf[200], resp[1000], hex[2000]; 63d86e5828SJouni Malinen const char *ifname = get_station_ifname(); 64d86e5828SJouni Malinen 65d86e5828SJouni Malinen if (strcasecmp(bs, "QR") != 0) { 66d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 67d86e5828SJouni Malinen "errorCode,Unsupported DPPBS"); 68d86e5828SJouni Malinen return 0; 69d86e5828SJouni Malinen } 70d86e5828SJouni Malinen 71d86e5828SJouni Malinen if (sigma_dut_is_ap(dut)) { 72d86e5828SJouni Malinen u8 bssid[ETH_ALEN]; 73d86e5828SJouni Malinen 74d86e5828SJouni Malinen if (!dut->hostapd_ifname) { 75d86e5828SJouni Malinen sigma_dut_print(dut, DUT_MSG_ERROR, 76d86e5828SJouni Malinen "hostapd ifname not specified (-j)"); 77d86e5828SJouni Malinen return -2; 78d86e5828SJouni Malinen } 79d86e5828SJouni Malinen ifname = dut->hostapd_ifname; 80d86e5828SJouni Malinen if (get_hwaddr(dut->hostapd_ifname, bssid) < 0) { 81d86e5828SJouni Malinen sigma_dut_print(dut, DUT_MSG_ERROR, 82d86e5828SJouni Malinen "Could not get MAC address for %s", 83d86e5828SJouni Malinen dut->hostapd_ifname); 84d86e5828SJouni Malinen return -2; 85d86e5828SJouni Malinen } 86d86e5828SJouni Malinen snprintf(mac, sizeof(mac), "%02x%02x%02x%02x%02x%02x", 87d86e5828SJouni Malinen bssid[0], bssid[1], bssid[2], 88d86e5828SJouni Malinen bssid[3], bssid[4], bssid[5]); 89d86e5828SJouni Malinen } else { 90d86e5828SJouni Malinen if (get_wpa_status(ifname, "address", mac, sizeof(mac)) < 0) 91d86e5828SJouni Malinen return -2; 92d86e5828SJouni Malinen } 93d86e5828SJouni Malinen 94d86e5828SJouni Malinen pos = mac; 95d86e5828SJouni Malinen while (*pos) { 96d86e5828SJouni Malinen if (*pos == ':') 97d86e5828SJouni Malinen memmove(pos, pos + 1, strlen(pos)); 98d86e5828SJouni Malinen else 99d86e5828SJouni Malinen pos++; 100d86e5828SJouni Malinen } 101d86e5828SJouni Malinen 102d86e5828SJouni Malinen if (sigma_dut_is_ap(dut) && dpp_hostapd_run(dut) < 0) { 103d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 104d86e5828SJouni Malinen "errorCode,Failed to start hostapd"); 105d86e5828SJouni Malinen return 0; 106d86e5828SJouni Malinen } 107d86e5828SJouni Malinen 1084161c3f0SJouni Malinen if (chan_list && 1094161c3f0SJouni Malinen (strcmp(chan_list, "0/0") == 0 || chan_list[0] == '\0')) { 1104161c3f0SJouni Malinen /* No channel list */ 1114161c3f0SJouni Malinen snprintf(buf, sizeof(buf), 1124161c3f0SJouni Malinen "DPP_BOOTSTRAP_GEN type=qrcode curve=%s mac=%s", 1134161c3f0SJouni Malinen curve, mac); 1144161c3f0SJouni Malinen } else if (chan_list) { 1154161c3f0SJouni Malinen /* Channel list override (CTT case) - space separated tuple(s) 1164161c3f0SJouni Malinen * of OperatingClass/Channel; convert to wpa_supplicant/hostapd 1174161c3f0SJouni Malinen * format: comma separated tuples */ 1184161c3f0SJouni Malinen strlcpy(resp, chan_list, sizeof(resp)); 1194161c3f0SJouni Malinen for (pos = resp; *pos; pos++) { 1204161c3f0SJouni Malinen if (*pos == ' ') 1214161c3f0SJouni Malinen *pos = ','; 1224161c3f0SJouni Malinen } 1234161c3f0SJouni Malinen snprintf(buf, sizeof(buf), 1244161c3f0SJouni Malinen "DPP_BOOTSTRAP_GEN type=qrcode curve=%s chan=%s mac=%s", 1254161c3f0SJouni Malinen curve, resp, mac); 1264161c3f0SJouni Malinen } else { 1274161c3f0SJouni Malinen /* Default channel list (normal DUT case) */ 1284161c3f0SJouni Malinen snprintf(buf, sizeof(buf), 1294161c3f0SJouni Malinen "DPP_BOOTSTRAP_GEN type=qrcode curve=%s chan=81/11 mac=%s", 1304161c3f0SJouni Malinen curve, mac); 1314161c3f0SJouni Malinen } 1324161c3f0SJouni Malinen 133d86e5828SJouni Malinen if (wpa_command_resp(ifname, buf, resp, sizeof(resp)) < 0) 134d86e5828SJouni Malinen return -2; 135d86e5828SJouni Malinen if (strncmp(resp, "FAIL", 4) == 0) 136d86e5828SJouni Malinen return -2; 137d86e5828SJouni Malinen dut->dpp_local_bootstrap = atoi(resp); 138d86e5828SJouni Malinen snprintf(buf, sizeof(buf), "DPP_BOOTSTRAP_GET_URI %d", 139d86e5828SJouni Malinen atoi(resp)); 140d86e5828SJouni Malinen if (wpa_command_resp(ifname, buf, resp, sizeof(resp)) < 0) 141d86e5828SJouni Malinen return -2; 142d86e5828SJouni Malinen if (strncmp(resp, "FAIL", 4) == 0) 143d86e5828SJouni Malinen return -2; 144d86e5828SJouni Malinen 145d86e5828SJouni Malinen sigma_dut_print(dut, DUT_MSG_DEBUG, "URI: %s", resp); 146d86e5828SJouni Malinen ascii2hexstr(resp, hex); 147d86e5828SJouni Malinen snprintf(resp, sizeof(resp), "BootstrappingData,%s", hex); 148d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, resp); 149d86e5828SJouni Malinen return 0; 150d86e5828SJouni Malinen } 151d86e5828SJouni Malinen 152d86e5828SJouni Malinen 153d86e5828SJouni Malinen static int dpp_set_peer_bootstrap(struct sigma_dut *dut, 154d86e5828SJouni Malinen struct sigma_conn *conn, 155d86e5828SJouni Malinen struct sigma_cmd *cmd) 156d86e5828SJouni Malinen { 157d86e5828SJouni Malinen const char *val = get_param(cmd, "DPPBootstrappingdata"); 158b1dd21f8SJouni Malinen char uri[1000]; 159d86e5828SJouni Malinen int res; 160d86e5828SJouni Malinen 161d86e5828SJouni Malinen if (!val) { 162d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 163d86e5828SJouni Malinen "errorCode,Missing DPPBootstrappingdata"); 164d86e5828SJouni Malinen return 0; 165d86e5828SJouni Malinen } 166d86e5828SJouni Malinen 167d86e5828SJouni Malinen res = parse_hexstr(val, (unsigned char *) uri, sizeof(uri)); 168d86e5828SJouni Malinen if (res < 0 || (size_t) res >= sizeof(uri)) 169d86e5828SJouni Malinen return -2; 170d86e5828SJouni Malinen uri[res] = '\0'; 171d86e5828SJouni Malinen sigma_dut_print(dut, DUT_MSG_DEBUG, "URI: %s", uri); 172b1dd21f8SJouni Malinen free(dut->dpp_peer_uri); 173b1dd21f8SJouni Malinen dut->dpp_peer_uri = strdup(uri); 174d86e5828SJouni Malinen 175d86e5828SJouni Malinen return 1; 176d86e5828SJouni Malinen } 177d86e5828SJouni Malinen 178d86e5828SJouni Malinen 179d86e5828SJouni Malinen static int dpp_hostapd_conf_update(struct sigma_dut *dut, 180d86e5828SJouni Malinen struct sigma_conn *conn, const char *ifname, 181d86e5828SJouni Malinen struct wpa_ctrl *ctrl) 182d86e5828SJouni Malinen { 183d86e5828SJouni Malinen int res; 184d86e5828SJouni Malinen char buf[2000], buf2[2500], *pos, *pos2; 185b4c5e3b8SJouni Malinen const char *conf_data_events[] = { 186b4c5e3b8SJouni Malinen "DPP-CONNECTOR", 187b4c5e3b8SJouni Malinen "DPP-CONFOBJ-PASS", 188b4c5e3b8SJouni Malinen "DPP-CONFOBJ-PSK", 189b4c5e3b8SJouni Malinen NULL 190b4c5e3b8SJouni Malinen }; 191d86e5828SJouni Malinen 192d86e5828SJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, 193d86e5828SJouni Malinen "Update hostapd configuration based on DPP Config Object"); 194d86e5828SJouni Malinen 195d86e5828SJouni Malinen if (wpa_command(ifname, "SET wpa 2") < 0 || 196d86e5828SJouni Malinen wpa_command(ifname, "SET wpa_key_mgmt DPP") < 0 || 1970d34723dSJouni Malinen wpa_command(ifname, "SET ieee80211w 1") < 0 || 198d86e5828SJouni Malinen wpa_command(ifname, "SET rsn_pairwise CCMP") < 0) { 199d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 200d86e5828SJouni Malinen "errorCode,Failed to update AP security parameters"); 201d86e5828SJouni Malinen goto out; 202d86e5828SJouni Malinen } 203d86e5828SJouni Malinen 204d86e5828SJouni Malinen res = get_wpa_cli_event(dut, ctrl, "DPP-CONFOBJ-SSID", 205d86e5828SJouni Malinen buf, sizeof(buf)); 206d86e5828SJouni Malinen if (res < 0) { 207d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 208d86e5828SJouni Malinen "errorCode,No DPP-CONFOBJ-SSID"); 209d86e5828SJouni Malinen goto out; 210d86e5828SJouni Malinen } 211d86e5828SJouni Malinen pos = strchr(buf, ' '); 212d86e5828SJouni Malinen if (!pos) 213d86e5828SJouni Malinen return -2; 214d86e5828SJouni Malinen pos++; 215d86e5828SJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, 216d86e5828SJouni Malinen "DPP: Config Object SSID: %s", pos); 217d86e5828SJouni Malinen snprintf(buf2, sizeof(buf2), "SET ssid %s", pos); 218d86e5828SJouni Malinen if (wpa_command(ifname, buf2) < 0) { 219d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 220d86e5828SJouni Malinen "errorCode,Failed to update AP SSID"); 221d86e5828SJouni Malinen goto out; 222d86e5828SJouni Malinen } 223d86e5828SJouni Malinen 224b4c5e3b8SJouni Malinen res = get_wpa_cli_events(dut, ctrl, conf_data_events, buf, sizeof(buf)); 225d86e5828SJouni Malinen if (res < 0) { 226d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 227b4c5e3b8SJouni Malinen "errorCode,No DPP-CONNECTOR/DPP-CONFOBJ-PASS/PSK"); 228d86e5828SJouni Malinen goto out; 229d86e5828SJouni Malinen } 230b4c5e3b8SJouni Malinen 231b4c5e3b8SJouni Malinen if (!strstr(buf, "DPP-CONNECTOR")) { 232b4c5e3b8SJouni Malinen if (wpa_command(ifname, "SET wpa_key_mgmt WPA-PSK") < 0) { 233b4c5e3b8SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 234b4c5e3b8SJouni Malinen "errorCode,Failed to update AP security parameters"); 235b4c5e3b8SJouni Malinen goto out; 236b4c5e3b8SJouni Malinen } 237b4c5e3b8SJouni Malinen 238b4c5e3b8SJouni Malinen pos = strchr(buf, ' '); 239b4c5e3b8SJouni Malinen if (!pos) 240b4c5e3b8SJouni Malinen return -2; 241b4c5e3b8SJouni Malinen pos++; 242b4c5e3b8SJouni Malinen if (strstr(buf, "DPP-CONFOBJ-PASS")) { 243b4c5e3b8SJouni Malinen char pass[64]; 244b4c5e3b8SJouni Malinen int pass_len; 245b4c5e3b8SJouni Malinen 246b4c5e3b8SJouni Malinen pass_len = parse_hexstr(pos, (u8 *) pass, sizeof(pass)); 247b4c5e3b8SJouni Malinen if (pass_len < 0 || pass_len >= sizeof(pass)) 248b4c5e3b8SJouni Malinen return -2; 249b4c5e3b8SJouni Malinen pass[pass_len] = '\0'; 250b4c5e3b8SJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, 251b4c5e3b8SJouni Malinen "DPP: Passphrase: %s", pass); 252b4c5e3b8SJouni Malinen snprintf(buf2, sizeof(buf2), "SET wpa_passphrase %s", 253b4c5e3b8SJouni Malinen pass); 254b4c5e3b8SJouni Malinen if (wpa_command(ifname, buf2) < 0) { 255b4c5e3b8SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 256b4c5e3b8SJouni Malinen "errorCode,Failed to set passphrase"); 257b4c5e3b8SJouni Malinen goto out; 258b4c5e3b8SJouni Malinen } 259b4c5e3b8SJouni Malinen } else if (strstr(buf, "DPP-CONFOBJ-PSK")) { 260b4c5e3b8SJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, 261b4c5e3b8SJouni Malinen "DPP: PSK: %s", pos); 262b4c5e3b8SJouni Malinen snprintf(buf2, sizeof(buf2), "SET wpa_psk %s", pos); 263b4c5e3b8SJouni Malinen if (wpa_command(ifname, buf2) < 0) { 264b4c5e3b8SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 265b4c5e3b8SJouni Malinen "errorCode,Failed to set PSK"); 266b4c5e3b8SJouni Malinen goto out; 267b4c5e3b8SJouni Malinen } 268b4c5e3b8SJouni Malinen } 269b4c5e3b8SJouni Malinen 270b4c5e3b8SJouni Malinen goto skip_dpp_akm; 271b4c5e3b8SJouni Malinen } 272b4c5e3b8SJouni Malinen 273d86e5828SJouni Malinen pos = strchr(buf, ' '); 274d86e5828SJouni Malinen if (!pos) 275d86e5828SJouni Malinen return -2; 276d86e5828SJouni Malinen pos++; 277d86e5828SJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "DPP: Connector: %s", pos); 278d86e5828SJouni Malinen snprintf(buf2, sizeof(buf2), "SET dpp_connector %s", pos); 279d86e5828SJouni Malinen if (wpa_command(ifname, buf2) < 0) { 280d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 281d86e5828SJouni Malinen "errorCode,Failed to update AP Connector"); 282d86e5828SJouni Malinen goto out; 283d86e5828SJouni Malinen } 284d86e5828SJouni Malinen 285d86e5828SJouni Malinen res = get_wpa_cli_event(dut, ctrl, "DPP-C-SIGN-KEY", 286d86e5828SJouni Malinen buf, sizeof(buf)); 287d86e5828SJouni Malinen if (res < 0) { 288d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 289d86e5828SJouni Malinen "errorCode,No DPP-C-SIGN-KEY"); 290d86e5828SJouni Malinen goto out; 291d86e5828SJouni Malinen } 292d86e5828SJouni Malinen pos = strchr(buf, ' '); 293d86e5828SJouni Malinen if (!pos) 294d86e5828SJouni Malinen return -2; 295d86e5828SJouni Malinen pos++; 296d86e5828SJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "DPP: C-sign-key: %s", pos); 297d86e5828SJouni Malinen snprintf(buf2, sizeof(buf2), "SET dpp_csign %s", pos); 298d86e5828SJouni Malinen if (wpa_command(ifname, buf2) < 0) { 299d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 300d86e5828SJouni Malinen "errorCode,Failed to update AP C-sign-key"); 301d86e5828SJouni Malinen goto out; 302d86e5828SJouni Malinen } 303d86e5828SJouni Malinen 304d86e5828SJouni Malinen res = get_wpa_cli_event(dut, ctrl, "DPP-NET-ACCESS-KEY", 305d86e5828SJouni Malinen buf, sizeof(buf)); 306d86e5828SJouni Malinen if (res < 0) { 307d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 308d86e5828SJouni Malinen "errorCode,No DPP-NET-ACCESS-KEY"); 309d86e5828SJouni Malinen goto out; 310d86e5828SJouni Malinen } 311d86e5828SJouni Malinen pos = strchr(buf, ' '); 312d86e5828SJouni Malinen if (!pos) 313d86e5828SJouni Malinen return -2; 314d86e5828SJouni Malinen pos++; 315d86e5828SJouni Malinen pos2 = strchr(pos, ' '); 316d86e5828SJouni Malinen if (pos2) 317d86e5828SJouni Malinen *pos2++ = '\0'; 318d86e5828SJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "DPP: netAccessKey: %s", pos); 319d86e5828SJouni Malinen snprintf(buf2, sizeof(buf2), "SET dpp_netaccesskey %s", pos); 320d86e5828SJouni Malinen if (wpa_command(ifname, buf2) < 0) { 321d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 322d86e5828SJouni Malinen "errorCode,Failed to update AP netAccessKey"); 323d86e5828SJouni Malinen goto out; 324d86e5828SJouni Malinen } 325d86e5828SJouni Malinen if (pos2) { 326d86e5828SJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, 327d86e5828SJouni Malinen "DPP: netAccessKey expiry: %s", pos2); 328d86e5828SJouni Malinen snprintf(buf2, sizeof(buf2), "SET dpp_netaccesskey_expiry %s", 329d86e5828SJouni Malinen pos2); 330d86e5828SJouni Malinen if (wpa_command(ifname, buf2) < 0) { 331d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 332d86e5828SJouni Malinen "errorCode,Failed to update AP netAccessKey expiry"); 333d86e5828SJouni Malinen goto out; 334d86e5828SJouni Malinen } 335d86e5828SJouni Malinen } 336b4c5e3b8SJouni Malinen skip_dpp_akm: 337d86e5828SJouni Malinen 338d86e5828SJouni Malinen if (wpa_command(ifname, "DISABLE") < 0 || 339d86e5828SJouni Malinen wpa_command(ifname, "ENABLE") < 0) { 340d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 341d86e5828SJouni Malinen "errorCode,Failed to update AP configuration"); 342d86e5828SJouni Malinen goto out; 343d86e5828SJouni Malinen } 344d86e5828SJouni Malinen 345d86e5828SJouni Malinen res = get_wpa_cli_event(dut, ctrl, "AP-ENABLED", buf, sizeof(buf)); 346d86e5828SJouni Malinen if (res < 0) { 347d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, "errorCode,No AP-ENABLED"); 348d86e5828SJouni Malinen goto out; 349d86e5828SJouni Malinen } 350d86e5828SJouni Malinen 351d86e5828SJouni Malinen return 1; 352d86e5828SJouni Malinen out: 353d86e5828SJouni Malinen return 0; 354d86e5828SJouni Malinen } 355d86e5828SJouni Malinen 356d86e5828SJouni Malinen 357772299f1SJouni Malinen struct dpp_test_info { 358772299f1SJouni Malinen const char *step; 359772299f1SJouni Malinen const char *frame; 360772299f1SJouni Malinen const char *attr; 361772299f1SJouni Malinen int value; 362772299f1SJouni Malinen }; 363772299f1SJouni Malinen 364772299f1SJouni Malinen static const struct dpp_test_info dpp_tests[] = { 365772299f1SJouni Malinen { "InvalidValue", "AuthenticationRequest", "WrappedData", 1 }, 366772299f1SJouni Malinen { "InvalidValue", "AuthenticationResponse", "WrappedData", 2 }, 367f96fcee3SJouni Malinen { "InvalidValue", "AuthenticationResponse", "PrimaryWrappedData", 2 }, 368772299f1SJouni Malinen { "InvalidValue", "AuthenticationConfirm", "WrappedData", 3 }, 369772299f1SJouni Malinen { "InvalidValue", "PKEXCRRequest", "WrappedData", 4 }, 370772299f1SJouni Malinen { "InvalidValue", "PKEXCRResponse", "WrappedData", 5 }, 371772299f1SJouni Malinen { "InvalidValue", "ConfigurationRequest", "WrappedData", 6 }, 372772299f1SJouni Malinen { "InvalidValue", "ConfigurationResponse", "WrappedData", 7 }, 373772299f1SJouni Malinen { "InvalidValue", "AuthenticationRequest", "InitCapabilities", 8 }, 374772299f1SJouni Malinen { "MissingAttribute", "AuthenticationRequest", "RespBSKeyHash", 10 }, 375772299f1SJouni Malinen { "MissingAttribute", "AuthenticationRequest", "InitBSKeyHash", 11 }, 376772299f1SJouni Malinen { "MissingAttribute", "AuthenticationRequest", "InitProtocolKey", 12 }, 377772299f1SJouni Malinen { "MissingAttribute", "AuthenticationRequest", "InitNonce", 13 }, 378772299f1SJouni Malinen { "MissingAttribute", "AuthenticationRequest", "InitCapabilities", 14 }, 379772299f1SJouni Malinen { "MissingAttribute", "AuthenticationRequest", "WrappedData", 15 }, 380772299f1SJouni Malinen { "MissingAttribute", "AuthenticationResponse", "DPPStatus", 16 }, 381772299f1SJouni Malinen { "MissingAttribute", "AuthenticationResponse", "RespBSKeyHash", 17 }, 382772299f1SJouni Malinen { "MissingAttribute", "AuthenticationResponse", "InitBSKeyHash", 18 }, 383772299f1SJouni Malinen { "MissingAttribute", "AuthenticationResponse", "RespProtocolKey", 19 }, 384772299f1SJouni Malinen { "MissingAttribute", "AuthenticationResponse", "RespNonce", 20 }, 385772299f1SJouni Malinen { "MissingAttribute", "AuthenticationResponse", "InitNonce", 21 }, 386772299f1SJouni Malinen { "MissingAttribute", "AuthenticationResponse", "RespCapabilities", 387772299f1SJouni Malinen 22 }, 388772299f1SJouni Malinen { "MissingAttribute", "AuthenticationResponse", "RespAuthTag", 23 }, 389772299f1SJouni Malinen { "MissingAttribute", "AuthenticationResponse", "WrappedData", 24 }, 390f96fcee3SJouni Malinen { "MissingAttribute", "AuthenticationResponse", "PrimaryWrappedData", 391f96fcee3SJouni Malinen 24 }, 392772299f1SJouni Malinen { "MissingAttribute", "AuthenticationConfirm", "DPPStatus", 25 }, 393772299f1SJouni Malinen { "MissingAttribute", "AuthenticationConfirm", "RespBSKeyHash", 26 }, 394772299f1SJouni Malinen { "MissingAttribute", "AuthenticationConfirm", "InitBSKeyHash", 27 }, 395772299f1SJouni Malinen { "MissingAttribute", "AuthenticationConfirm", "InitAuthTag", 28 }, 396772299f1SJouni Malinen { "MissingAttribute", "AuthenticationConfirm", "WrappedData", 29 }, 397772299f1SJouni Malinen { "InvalidValue", "AuthenticationResponse", "InitNonce", 30 }, 398772299f1SJouni Malinen { "InvalidValue", "AuthenticationResponse", "RespCapabilities", 31 }, 399772299f1SJouni Malinen { "InvalidValue", "AuthenticationResponse", "RespAuthTag", 32 }, 400772299f1SJouni Malinen { "InvalidValue", "AuthenticationConfirm", "InitAuthTag", 33 }, 401772299f1SJouni Malinen { "MissingAttribute", "PKEXExchangeRequest", "FiniteCyclicGroup", 34 }, 402772299f1SJouni Malinen { "MissingAttribute", "PKEXExchangeRequest", "EncryptedKey", 35 }, 403772299f1SJouni Malinen { "MissingAttribute", "PKEXExchangeResponse", "DPPStatus", 36 }, 404772299f1SJouni Malinen { "MissingAttribute", "PKEXExchangeResponse", "EncryptedKey", 37 }, 405772299f1SJouni Malinen { "MissingAttribute", "PKEXCRRequest", "BSKey", 38 }, 406772299f1SJouni Malinen { "MissingAttribute", "PKEXCRRequest", "InitAuthTag", 39 }, 407772299f1SJouni Malinen { "MissingAttribute", "PKEXCRRequest", "WrappedData", 40 }, 408772299f1SJouni Malinen { "MissingAttribute", "PKEXCRResponse", "BSKey", 41 }, 409772299f1SJouni Malinen { "MissingAttribute", "PKEXCRResponse", "RespAuthTag", 42 }, 410772299f1SJouni Malinen { "MissingAttribute", "PKEXCRResponse", "WrappedData", 43 }, 411772299f1SJouni Malinen { "InvalidValue", "PKEXExchangeRequest", "EncryptedKey", 44 }, 412772299f1SJouni Malinen { "InvalidValue", "PKEXExchangeResponse", "EncryptedKey", 45 }, 413772299f1SJouni Malinen { "InvalidValue", "PKEXExchangeResponse", "DPPStatus", 46 }, 414772299f1SJouni Malinen { "InvalidValue", "PKEXCRRequest", "BSKey", 47 }, 415772299f1SJouni Malinen { "InvalidValue", "PKEXCRResponse", "BSKey", 48 }, 416772299f1SJouni Malinen { "InvalidValue", "PKEXCRRequest", "InitAuthTag", 49 }, 417772299f1SJouni Malinen { "InvalidValue", "PKEXCRResponse", "RespAuthTag", 50 }, 418772299f1SJouni Malinen { "MissingAttribute", "ConfigurationRequest", "EnrolleeNonce", 51 }, 419772299f1SJouni Malinen { "MissingAttribute", "ConfigurationRequest", "ConfigAttr", 52 }, 420772299f1SJouni Malinen { "MissingAttribute", "ConfigurationRequest", "WrappedData", 53 }, 421772299f1SJouni Malinen { "MissingAttribute", "ConfigurationResponse", "EnrolleeNonce", 54 }, 422772299f1SJouni Malinen { "MissingAttribute", "ConfigurationResponse", "ConfigObj", 55 }, 423772299f1SJouni Malinen { "MissingAttribute", "ConfigurationResponse", "DPPStatus", 56 }, 424772299f1SJouni Malinen { "MissingAttribute", "ConfigurationResponse", "WrappedData", 57 }, 425772299f1SJouni Malinen { "InvalidValue", "ConfigurationResponse", "DPPStatus", 58 }, 426772299f1SJouni Malinen { "InvalidValue", "ConfigurationResponse", "EnrolleeNonce", 59 }, 42753558e0fSJouni Malinen { "MissingAttribute", "PeerDiscoveryRequest", "TransactionID", 60 }, 42853558e0fSJouni Malinen { "MissingAttribute", "PeerDiscoveryRequest", "Connector", 61 }, 42953558e0fSJouni Malinen { "MissingAttribute", "PeerDiscoveryResponse", "TransactionID", 62 }, 43053558e0fSJouni Malinen { "MissingAttribute", "PeerDiscoveryResponse", "DPPStatus", 63 }, 43153558e0fSJouni Malinen { "MissingAttribute", "PeerDiscoveryResponse", "Connector", 64 }, 432ae624487SJouni Malinen { "InvalidValue", "AuthenticationRequest", "InitProtocolKey", 66 }, 433ae624487SJouni Malinen { "InvalidValue", "AuthenticationResponse", "RespProtocolKey", 67 }, 434ae624487SJouni Malinen { "InvalidValue", "AuthenticationRequest", "RespBSKeyHash", 68 }, 435ae624487SJouni Malinen { "InvalidValue", "AuthenticationRequest", "InitBSKeyHash", 69 }, 436ae624487SJouni Malinen { "InvalidValue", "AuthenticationResponse", "RespBSKeyHash", 70 }, 437ae624487SJouni Malinen { "InvalidValue", "AuthenticationResponse", "InitBSKeyHash", 71 }, 438ae624487SJouni Malinen { "InvalidValue", "AuthenticationConfirm", "RespBSKeyHash", 72 }, 439ae624487SJouni Malinen { "InvalidValue", "AuthenticationConfirm", "InitBSKeyHash", 73 }, 440ae624487SJouni Malinen { "InvalidValue", "AuthenticationResponse", "DPPStatus", 74 }, 441ae624487SJouni Malinen { "InvalidValue", "AuthenticationConfirm", "DPPStatus", 75 }, 442ae624487SJouni Malinen { "InvalidValue", "ConfigurationRequest", "ConfigAttr", 76 }, 443ae624487SJouni Malinen { "InvalidValue", "PeerDiscoveryResponse", "TransactionID", 77 }, 444ae624487SJouni Malinen { "InvalidValue", "PeerDiscoveryResponse", "DPPStatus", 78 }, 445ae624487SJouni Malinen { "InvalidValue", "PeerDiscoveryResponse", "Connector", 79 }, 446ae624487SJouni Malinen { "InvalidValue", "PeerDiscoveryRequest", "Connector", 80 }, 44767795a76SJouni Malinen { "InvalidValue", "AuthenticationRequest", "InitNonce", 81 }, 448772299f1SJouni Malinen { NULL, NULL, NULL, 0 } 449772299f1SJouni Malinen }; 450772299f1SJouni Malinen 451772299f1SJouni Malinen 452772299f1SJouni Malinen static int dpp_get_test(const char *step, const char *frame, const char *attr) 453772299f1SJouni Malinen { 454772299f1SJouni Malinen int i; 455772299f1SJouni Malinen 456772299f1SJouni Malinen for (i = 0; dpp_tests[i].step; i++) { 457772299f1SJouni Malinen if (strcasecmp(step, dpp_tests[i].step) == 0 && 458772299f1SJouni Malinen strcasecmp(frame, dpp_tests[i].frame) == 0 && 459772299f1SJouni Malinen strcasecmp(attr, dpp_tests[i].attr) == 0) 460772299f1SJouni Malinen return dpp_tests[i].value; 461772299f1SJouni Malinen } 462772299f1SJouni Malinen 463772299f1SJouni Malinen return -1; 464772299f1SJouni Malinen } 465772299f1SJouni Malinen 466772299f1SJouni Malinen 467772299f1SJouni Malinen static int dpp_wait_tx_status(struct sigma_dut *dut, struct wpa_ctrl *ctrl, 468772299f1SJouni Malinen int frame_type) 469772299f1SJouni Malinen { 470772299f1SJouni Malinen char buf[200], tmp[20]; 471772299f1SJouni Malinen int res; 472772299f1SJouni Malinen 473772299f1SJouni Malinen snprintf(tmp, sizeof(tmp), "type=%d", frame_type); 474772299f1SJouni Malinen for (;;) { 475772299f1SJouni Malinen res = get_wpa_cli_event(dut, ctrl, "DPP-TX", buf, sizeof(buf)); 476772299f1SJouni Malinen if (res < 0) 477772299f1SJouni Malinen return -1; 478772299f1SJouni Malinen if (strstr(buf, tmp) != NULL) 479772299f1SJouni Malinen break; 480772299f1SJouni Malinen } 481772299f1SJouni Malinen 482772299f1SJouni Malinen res = get_wpa_cli_event(dut, ctrl, "DPP-TX-STATUS", 483772299f1SJouni Malinen buf, sizeof(buf)); 484772299f1SJouni Malinen if (res < 0 || strstr(buf, "result=FAILED") != NULL) 485772299f1SJouni Malinen return -1; 486772299f1SJouni Malinen 487772299f1SJouni Malinen return 0; 488772299f1SJouni Malinen } 489772299f1SJouni Malinen 490772299f1SJouni Malinen 491d86e5828SJouni Malinen static int dpp_manual_dpp(struct sigma_dut *dut, 492d86e5828SJouni Malinen struct sigma_conn *conn, 493d86e5828SJouni Malinen struct sigma_cmd *cmd) 494d86e5828SJouni Malinen { 495d86e5828SJouni Malinen /* TODO */ 496d86e5828SJouni Malinen return -1; 497d86e5828SJouni Malinen } 498d86e5828SJouni Malinen 499d86e5828SJouni Malinen 500d86e5828SJouni Malinen static int dpp_automatic_dpp(struct sigma_dut *dut, 501d86e5828SJouni Malinen struct sigma_conn *conn, 502d86e5828SJouni Malinen struct sigma_cmd *cmd) 503d86e5828SJouni Malinen { 504d86e5828SJouni Malinen const char *bs = get_param(cmd, "DPPBS"); 505d86e5828SJouni Malinen const char *auth_role = get_param(cmd, "DPPAuthRole"); 506d86e5828SJouni Malinen const char *prov_role = get_param(cmd, "DPPProvisioningRole"); 507d86e5828SJouni Malinen const char *pkex_code = get_param(cmd, "DPPPKEXCode"); 508d86e5828SJouni Malinen const char *pkex_code_id = get_param(cmd, "DPPPKEXCodeIdentifier"); 509d86e5828SJouni Malinen const char *wait_conn = get_param(cmd, "DPPWaitForConnect"); 510d86e5828SJouni Malinen const char *self_conf = get_param(cmd, "DPPSelfConfigure"); 511772299f1SJouni Malinen const char *step = get_param(cmd, "DPPStep"); 512772299f1SJouni Malinen const char *frametype = get_param(cmd, "DPPFrameType"); 513772299f1SJouni Malinen const char *attr = get_param(cmd, "DPPIEAttribute"); 514d86e5828SJouni Malinen const char *role; 515d86e5828SJouni Malinen const char *val; 516d86e5828SJouni Malinen const char *conf_role; 517d86e5828SJouni Malinen int conf_index = -1; 518d86e5828SJouni Malinen char buf[2000]; 519d86e5828SJouni Malinen char conf_ssid[100]; 520d86e5828SJouni Malinen char conf_pass[100]; 521d86e5828SJouni Malinen char pkex_identifier[200]; 522d86e5828SJouni Malinen struct wpa_ctrl *ctrl; 523d86e5828SJouni Malinen int res; 524d86e5828SJouni Malinen unsigned int old_timeout; 525d86e5828SJouni Malinen int own_pkex_id = -1; 526d86e5828SJouni Malinen const char *ifname = get_station_ifname(); 527d86e5828SJouni Malinen const char *auth_events[] = { 528d86e5828SJouni Malinen "DPP-AUTH-SUCCESS", 529d86e5828SJouni Malinen "DPP-NOT-COMPATIBLE", 530d86e5828SJouni Malinen "DPP-RESPONSE-PENDING", 531d86e5828SJouni Malinen "DPP-SCAN-PEER-QR-CODE", 532d86e5828SJouni Malinen NULL 533d86e5828SJouni Malinen }; 534d86e5828SJouni Malinen const char *conf_events[] = { 535d86e5828SJouni Malinen "DPP-CONF-RECEIVED", 536d86e5828SJouni Malinen "DPP-CONF-SENT", 537d86e5828SJouni Malinen "DPP-CONF-FAILED", 538d86e5828SJouni Malinen NULL 539d86e5828SJouni Malinen }; 540d86e5828SJouni Malinen const char *conn_events[] = { 541d86e5828SJouni Malinen "PMKSA-CACHE-ADDED", 542d86e5828SJouni Malinen "CTRL-EVENT-CONNECTED", 543d86e5828SJouni Malinen NULL 544d86e5828SJouni Malinen }; 5453d291f70SJouni Malinen const char *groups_override = NULL; 546772299f1SJouni Malinen const char *result; 547d86e5828SJouni Malinen 548d86e5828SJouni Malinen if (!wait_conn) 549d86e5828SJouni Malinen wait_conn = "no"; 550d86e5828SJouni Malinen if (!self_conf) 551d86e5828SJouni Malinen self_conf = "no"; 552d86e5828SJouni Malinen 553d86e5828SJouni Malinen if (!auth_role) { 554d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 555d86e5828SJouni Malinen "errorCode,Missing DPPAuthRole"); 556d86e5828SJouni Malinen return 0; 557d86e5828SJouni Malinen } 558d86e5828SJouni Malinen 559d86e5828SJouni Malinen if (!prov_role) { 560d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 561d86e5828SJouni Malinen "errorCode,Missing DPPProvisioningRole"); 562d86e5828SJouni Malinen return 0; 563d86e5828SJouni Malinen } 564d86e5828SJouni Malinen 565772299f1SJouni Malinen if ((step || frametype || attr) && (!step || !frametype || !attr)) { 566772299f1SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 567772299f1SJouni Malinen "errorCode,Invalid DPPStep,DPPFrameType,DPPIEAttribute combination"); 568772299f1SJouni Malinen return 0; 569772299f1SJouni Malinen } 570772299f1SJouni Malinen 571d86e5828SJouni Malinen if (sigma_dut_is_ap(dut)) { 572d86e5828SJouni Malinen if (!dut->hostapd_ifname) { 573d86e5828SJouni Malinen sigma_dut_print(dut, DUT_MSG_ERROR, 574d86e5828SJouni Malinen "hostapd ifname not specified (-j)"); 575d86e5828SJouni Malinen return -2; 576d86e5828SJouni Malinen } 577d86e5828SJouni Malinen ifname = dut->hostapd_ifname; 578d86e5828SJouni Malinen 579d86e5828SJouni Malinen if (dpp_hostapd_run(dut) < 0) { 580d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 581d86e5828SJouni Malinen "errorCode,Failed to start hostapd"); 582d86e5828SJouni Malinen return 0; 583d86e5828SJouni Malinen } 584d86e5828SJouni Malinen } 585d86e5828SJouni Malinen 58667acb0cfSJouni Malinen if (strcasecmp(prov_role, "Configurator") == 0 || 58767acb0cfSJouni Malinen strcasecmp(prov_role, "Both") == 0) { 588d86e5828SJouni Malinen if (dut->dpp_conf_id < 0) { 589d86e5828SJouni Malinen snprintf(buf, sizeof(buf), 590d86e5828SJouni Malinen "DPP_CONFIGURATOR_ADD curve=%s", 591d86e5828SJouni Malinen dpp_get_curve(cmd, "DPPSigningKeyECC")); 592d86e5828SJouni Malinen if (wpa_command_resp(ifname, buf, 593d86e5828SJouni Malinen buf, sizeof(buf)) < 0) { 594d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 595d86e5828SJouni Malinen "errorCode,Failed to set up configurator"); 596d86e5828SJouni Malinen return 0; 597d86e5828SJouni Malinen } 598d86e5828SJouni Malinen dut->dpp_conf_id = atoi(buf); 599d86e5828SJouni Malinen } 60067acb0cfSJouni Malinen if (strcasecmp(prov_role, "Configurator") == 0) 601d86e5828SJouni Malinen role = "configurator"; 60267acb0cfSJouni Malinen else 60367acb0cfSJouni Malinen role = "either"; 604d86e5828SJouni Malinen } else if (strcasecmp(prov_role, "Enrollee") == 0) { 605d86e5828SJouni Malinen role = "enrollee"; 606d86e5828SJouni Malinen } else { 607d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 608d86e5828SJouni Malinen "errorCode,Unknown DPPProvisioningRole"); 609d86e5828SJouni Malinen return 0; 610d86e5828SJouni Malinen } 611d86e5828SJouni Malinen 612d86e5828SJouni Malinen pkex_identifier[0] = '\0'; 613d86e5828SJouni Malinen if (strcasecmp(bs, "PKEX") == 0) { 6144f47a272SJouni Malinen if (sigma_dut_is_ap(dut) && dut->ap_channel != 6) { 6154f47a272SJouni Malinen /* For now, have to make operating channel match DPP 6164f47a272SJouni Malinen * listen channel. This should be removed once hostapd 6174f47a272SJouni Malinen * has support for DPP listen on non-operating channel. 6184f47a272SJouni Malinen */ 6194f47a272SJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, 6204f47a272SJouni Malinen "Update hostapd operating channel to match listen needs"); 6214f47a272SJouni Malinen dut->ap_channel = 6; 6224f47a272SJouni Malinen if (wpa_command(ifname, "SET channel 6") < 0 || 6234f47a272SJouni Malinen wpa_command(ifname, "DISABLE") < 0 || 6244f47a272SJouni Malinen wpa_command(ifname, "ENABLE") < 0) { 6254f47a272SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 6264f47a272SJouni Malinen "errorCode,Failed to update channel"); 6274f47a272SJouni Malinen return 0; 6284f47a272SJouni Malinen } 6294f47a272SJouni Malinen } 6304f47a272SJouni Malinen 631d86e5828SJouni Malinen if (!pkex_code) { 632d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 633d86e5828SJouni Malinen "errorCode,Missing DPPPKEXCode"); 634d86e5828SJouni Malinen return 0; 635d86e5828SJouni Malinen } 636d86e5828SJouni Malinen 637d86e5828SJouni Malinen if (pkex_code_id) 638d86e5828SJouni Malinen snprintf(pkex_identifier, sizeof(pkex_identifier), 639d86e5828SJouni Malinen "identifier=%s ", pkex_code_id); 640d86e5828SJouni Malinen 641d86e5828SJouni Malinen snprintf(buf, sizeof(buf), 642d86e5828SJouni Malinen "DPP_BOOTSTRAP_GEN type=pkex curve=%s", 643d86e5828SJouni Malinen dpp_get_curve(cmd, "DPPCryptoIdentifier")); 644d86e5828SJouni Malinen if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0) { 645d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 646d86e5828SJouni Malinen "errorCode,Failed to set up PKEX"); 647d86e5828SJouni Malinen return 0; 648d86e5828SJouni Malinen } 649d86e5828SJouni Malinen own_pkex_id = atoi(buf); 650d86e5828SJouni Malinen } 651d86e5828SJouni Malinen 652d86e5828SJouni Malinen ctrl = open_wpa_mon(ifname); 653d86e5828SJouni Malinen if (!ctrl) { 654d86e5828SJouni Malinen sigma_dut_print(dut, DUT_MSG_ERROR, 655d86e5828SJouni Malinen "Failed to open wpa_supplicant monitor connection"); 656d86e5828SJouni Malinen return -2; 657d86e5828SJouni Malinen } 658d86e5828SJouni Malinen 659d86e5828SJouni Malinen old_timeout = dut->default_timeout; 660d86e5828SJouni Malinen val = get_param(cmd, "DPPTimeout"); 661d86e5828SJouni Malinen if (val && atoi(val) > 0) { 662d86e5828SJouni Malinen dut->default_timeout = atoi(val); 663d86e5828SJouni Malinen sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP timeout: %u", 664d86e5828SJouni Malinen dut->default_timeout); 665d86e5828SJouni Malinen } 666d86e5828SJouni Malinen 667d86e5828SJouni Malinen conf_ssid[0] = '\0'; 668d86e5828SJouni Malinen conf_pass[0] = '\0'; 669d86e5828SJouni Malinen val = get_param(cmd, "DPPConfIndex"); 670d86e5828SJouni Malinen if (val) 671d86e5828SJouni Malinen conf_index = atoi(val); 672d86e5828SJouni Malinen val = get_param(cmd, "DPPConfEnrolleeRole"); 673d86e5828SJouni Malinen switch (conf_index) { 674258cc26aSJouni Malinen case -1: 675258cc26aSJouni Malinen conf_role = NULL; 676258cc26aSJouni Malinen break; 677d86e5828SJouni Malinen case 1: 678d86e5828SJouni Malinen ascii2hexstr("DPPNET01", buf); 679d86e5828SJouni Malinen snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf); 6803d291f70SJouni Malinen if (val && strcasecmp(val, "AP") == 0) { 681d86e5828SJouni Malinen conf_role = "ap-dpp"; 6823d291f70SJouni Malinen groups_override = "[{\"groupId\":\"DPPGROUP_DPP_INFRA\",\"netRole\":\"ap\"}]"; 6833d291f70SJouni Malinen } else { 684d86e5828SJouni Malinen conf_role = "sta-dpp"; 6853d291f70SJouni Malinen groups_override = "[{\"groupId\":\"DPPGROUP_DPP_INFRA\",\"netRole\":\"sta\"}]"; 6863d291f70SJouni Malinen } 687d86e5828SJouni Malinen break; 688d86e5828SJouni Malinen case 2: 689d86e5828SJouni Malinen ascii2hexstr("DPPNET01", buf); 690d86e5828SJouni Malinen snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf); 6918f81cdfaSJouni Malinen snprintf(conf_pass, sizeof(conf_pass), 6928f81cdfaSJouni Malinen "psk=10506e102ad1e7f95112f6b127675bb8344dacacea60403f3fa4055aec85b0fc"); 693d86e5828SJouni Malinen if (val && strcasecmp(val, "AP") == 0) 694d86e5828SJouni Malinen conf_role = "ap-psk"; 695d86e5828SJouni Malinen else 696d86e5828SJouni Malinen conf_role = "sta-psk"; 697d86e5828SJouni Malinen break; 698d86e5828SJouni Malinen case 3: 699d86e5828SJouni Malinen ascii2hexstr("DPPNET01", buf); 700d86e5828SJouni Malinen snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf); 701d86e5828SJouni Malinen ascii2hexstr("ThisIsDppPassphrase", buf); 702d86e5828SJouni Malinen snprintf(conf_pass, sizeof(conf_pass), "pass=%s", buf); 703d86e5828SJouni Malinen if (val && strcasecmp(val, "AP") == 0) 704d86e5828SJouni Malinen conf_role = "ap-psk"; 705d86e5828SJouni Malinen else 706d86e5828SJouni Malinen conf_role = "sta-psk"; 707d86e5828SJouni Malinen break; 7083d291f70SJouni Malinen case 4: 7093d291f70SJouni Malinen ascii2hexstr("DPPNET01", buf); 7103d291f70SJouni Malinen snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf); 7113d291f70SJouni Malinen if (val && strcasecmp(val, "AP") == 0) { 7123d291f70SJouni Malinen conf_role = "ap-dpp"; 7133d291f70SJouni Malinen groups_override = "[{\"groupId\":\"DPPGROUP_DPP_INFRA2\",\"netRole\":\"ap\"}]"; 7143d291f70SJouni Malinen } else { 7153d291f70SJouni Malinen conf_role = "sta-dpp"; 7163d291f70SJouni Malinen groups_override = "[{\"groupId\":\"DPPGROUP_DPP_INFRA2\",\"netRole\":\"sta\"}]"; 7173d291f70SJouni Malinen } 7183d291f70SJouni Malinen break; 719f7490768SJouni Malinen default: 720f7490768SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 721f7490768SJouni Malinen "errorCode,Unsupported DPPConfIndex"); 722f7490768SJouni Malinen goto out; 723d86e5828SJouni Malinen } 724d86e5828SJouni Malinen 7253d291f70SJouni Malinen if (groups_override) { 7263d291f70SJouni Malinen snprintf(buf, sizeof(buf), "SET dpp_groups_override %s", 7273d291f70SJouni Malinen groups_override); 7283d291f70SJouni Malinen if (wpa_command(ifname, buf) < 0) { 7293d291f70SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 7303d291f70SJouni Malinen "errorCode,Failed to set cred:groups"); 7313d291f70SJouni Malinen goto out; 7323d291f70SJouni Malinen } 7333d291f70SJouni Malinen } 7343d291f70SJouni Malinen 735772299f1SJouni Malinen if (step) { 736772299f1SJouni Malinen int test; 737772299f1SJouni Malinen 738772299f1SJouni Malinen test = dpp_get_test(step, frametype, attr); 739772299f1SJouni Malinen if (test <= 0) { 740772299f1SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 741772299f1SJouni Malinen "errorCode,Unsupported DPPStep/DPPFrameType/DPPIEAttribute"); 742772299f1SJouni Malinen goto out; 743772299f1SJouni Malinen } 744772299f1SJouni Malinen 745772299f1SJouni Malinen snprintf(buf, sizeof(buf), "SET dpp_test %d", test); 746772299f1SJouni Malinen if (wpa_command(ifname, buf) < 0) { 747772299f1SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 748772299f1SJouni Malinen "errorCode,Failed to set dpp_test"); 749772299f1SJouni Malinen goto out; 750772299f1SJouni Malinen } 751772299f1SJouni Malinen } else { 752772299f1SJouni Malinen wpa_command(ifname, "SET dpp_test 0"); 753772299f1SJouni Malinen } 754772299f1SJouni Malinen 755fbb268d7SJouni Malinen if (strcasecmp(self_conf, "Yes") == 0) { 756fbb268d7SJouni Malinen if (strcasecmp(prov_role, "Configurator") != 0) { 757fbb268d7SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 758fbb268d7SJouni Malinen "errorCode,Invalid DPPSelfConfigure use - only allowed for Configurator role"); 759fbb268d7SJouni Malinen goto out; 760fbb268d7SJouni Malinen } 761fbb268d7SJouni Malinen if (!conf_role) { 762fbb268d7SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 763fbb268d7SJouni Malinen "errorCode,Missing DPPConfIndex"); 764fbb268d7SJouni Malinen goto out; 765fbb268d7SJouni Malinen } 766fbb268d7SJouni Malinen 767fbb268d7SJouni Malinen snprintf(buf, sizeof(buf), 768fbb268d7SJouni Malinen "DPP_CONFIGURATOR_SIGN conf=%s %s %s configurator=%d", 769fbb268d7SJouni Malinen conf_role, conf_ssid, conf_pass, dut->dpp_conf_id); 770fbb268d7SJouni Malinen if (wpa_command(ifname, buf) < 0) { 771fbb268d7SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 772fbb268d7SJouni Malinen "errorCode,Failed to initiate DPP self-configuration"); 773fbb268d7SJouni Malinen goto out; 774fbb268d7SJouni Malinen } 775*174db64fSJouni Malinen if (sigma_dut_is_ap(dut)) 776*174db64fSJouni Malinen goto update_ap; 777fbb268d7SJouni Malinen goto wait_connect; 778fbb268d7SJouni Malinen } else if (strcasecmp(auth_role, "Initiator") == 0) { 779d86e5828SJouni Malinen char own_txt[20]; 780b1dd21f8SJouni Malinen int dpp_peer_bootstrap = -1; 781b5ab828bSJouni Malinen char neg_freq[30]; 782b5ab828bSJouni Malinen 783b5ab828bSJouni Malinen neg_freq[0] = '\0'; 784b5ab828bSJouni Malinen val = get_param(cmd, "DPPSubsequentChannel"); 785b5ab828bSJouni Malinen if (val) { 786b5ab828bSJouni Malinen int opclass, channel, freq; 787b5ab828bSJouni Malinen 788b5ab828bSJouni Malinen opclass = atoi(val); 789b5ab828bSJouni Malinen val = strchr(val, '/'); 790b5ab828bSJouni Malinen if (opclass == 0 || !val) { 791b5ab828bSJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 792b5ab828bSJouni Malinen "errorCode,Invalid DPPSubsequentChannel"); 793b5ab828bSJouni Malinen goto out; 794b5ab828bSJouni Malinen } 795b5ab828bSJouni Malinen val++; 796b5ab828bSJouni Malinen channel = atoi(val); 797b5ab828bSJouni Malinen 798b5ab828bSJouni Malinen /* Ignoring opclass for now; could use it here for more 799b5ab828bSJouni Malinen * robust frequency determination. */ 800b5ab828bSJouni Malinen freq = channel_to_freq(channel); 801b5ab828bSJouni Malinen if (!freq) { 802b5ab828bSJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 803b5ab828bSJouni Malinen "errorCode,Unsupported DPPSubsequentChannel channel"); 804b5ab828bSJouni Malinen goto out; 805b5ab828bSJouni Malinen } 806b5ab828bSJouni Malinen snprintf(neg_freq, sizeof(neg_freq), " neg_freq=%d", 807b5ab828bSJouni Malinen freq); 808b5ab828bSJouni Malinen } 809b1dd21f8SJouni Malinen 810b1dd21f8SJouni Malinen if (strcasecmp(bs, "QR") == 0) { 811b1dd21f8SJouni Malinen if (!dut->dpp_peer_uri) { 812b1dd21f8SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 813b1dd21f8SJouni Malinen "errorCode,Missing peer bootstrapping info"); 814b1dd21f8SJouni Malinen goto out; 815b1dd21f8SJouni Malinen } 816b1dd21f8SJouni Malinen 817b1dd21f8SJouni Malinen snprintf(buf, sizeof(buf), "DPP_QR_CODE %s", 818b1dd21f8SJouni Malinen dut->dpp_peer_uri); 819b1dd21f8SJouni Malinen if (wpa_command_resp(ifname, buf, buf, 820b1dd21f8SJouni Malinen sizeof(buf)) < 0) { 821b1dd21f8SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 822b1dd21f8SJouni Malinen "errorCode,Failed to parse URI"); 823b1dd21f8SJouni Malinen goto out; 824b1dd21f8SJouni Malinen } 825b1dd21f8SJouni Malinen dpp_peer_bootstrap = atoi(buf); 826b1dd21f8SJouni Malinen } 827d86e5828SJouni Malinen 82863d5041cSJouni Malinen if (dut->dpp_local_bootstrap >= 0) 829d86e5828SJouni Malinen snprintf(own_txt, sizeof(own_txt), " own=%d", 830d86e5828SJouni Malinen dut->dpp_local_bootstrap); 831d86e5828SJouni Malinen else 832d86e5828SJouni Malinen own_txt[0] = '\0'; 833d86e5828SJouni Malinen if (strcasecmp(bs, "QR") == 0 && 83467acb0cfSJouni Malinen (strcasecmp(prov_role, "Configurator") == 0 || 83567acb0cfSJouni Malinen strcasecmp(prov_role, "Both") == 0)) { 836258cc26aSJouni Malinen if (!conf_role) { 837258cc26aSJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 838258cc26aSJouni Malinen "errorCode,Missing DPPConfIndex"); 839258cc26aSJouni Malinen goto out; 840258cc26aSJouni Malinen } 841d86e5828SJouni Malinen snprintf(buf, sizeof(buf), 842b5ab828bSJouni Malinen "DPP_AUTH_INIT peer=%d%s role=%s conf=%s %s %s configurator=%d%s", 843b1dd21f8SJouni Malinen dpp_peer_bootstrap, own_txt, role, 844d86e5828SJouni Malinen conf_role, conf_ssid, conf_pass, 845b5ab828bSJouni Malinen dut->dpp_conf_id, neg_freq); 846d86e5828SJouni Malinen } else if (strcasecmp(bs, "QR") == 0) { 847d86e5828SJouni Malinen snprintf(buf, sizeof(buf), 848b5ab828bSJouni Malinen "DPP_AUTH_INIT peer=%d%s role=%s%s", 849b5ab828bSJouni Malinen dpp_peer_bootstrap, own_txt, role, neg_freq); 850d86e5828SJouni Malinen } else if (strcasecmp(bs, "PKEX") == 0 && 85167acb0cfSJouni Malinen (strcasecmp(prov_role, "Configurator") == 0 || 85267acb0cfSJouni Malinen strcasecmp(prov_role, "Both") == 0)) { 853258cc26aSJouni Malinen if (!conf_role) { 854258cc26aSJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 855258cc26aSJouni Malinen "errorCode,Missing DPPConfIndex"); 856258cc26aSJouni Malinen goto out; 857258cc26aSJouni Malinen } 858d86e5828SJouni Malinen snprintf(buf, sizeof(buf), 859d86e5828SJouni Malinen "DPP_PKEX_ADD own=%d init=1 role=%s conf=%s %s %s configurator=%d %scode=%s", 860d86e5828SJouni Malinen own_pkex_id, role, conf_role, 861d86e5828SJouni Malinen conf_ssid, conf_pass, dut->dpp_conf_id, 862d86e5828SJouni Malinen pkex_identifier, pkex_code); 863d86e5828SJouni Malinen } else if (strcasecmp(bs, "PKEX") == 0) { 864d86e5828SJouni Malinen snprintf(buf, sizeof(buf), 865d86e5828SJouni Malinen "DPP_PKEX_ADD own=%d init=1 role=%s %scode=%s", 866d86e5828SJouni Malinen own_pkex_id, role, pkex_identifier, pkex_code); 867d551c6fcSJouni Malinen } else { 868d551c6fcSJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 869d551c6fcSJouni Malinen "errorCode,Unsupported DPPBS"); 870d551c6fcSJouni Malinen goto out; 871d86e5828SJouni Malinen } 872d86e5828SJouni Malinen if (wpa_command(ifname, buf) < 0) { 873d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 874d86e5828SJouni Malinen "errorCode,Failed to initiate DPP authentication"); 875d86e5828SJouni Malinen goto out; 876d86e5828SJouni Malinen } 877d86e5828SJouni Malinen } else if (strcasecmp(auth_role, "Responder") == 0) { 87867f096aaSJouni Malinen const char *delay_qr_resp; 87963d5041cSJouni Malinen int mutual; 880d3afc5cbSJouni Malinen int freq = 2462; /* default: channel 11 */ 881d3afc5cbSJouni Malinen 88267f096aaSJouni Malinen delay_qr_resp = get_param(cmd, "DPPDelayQRResponse"); 88367f096aaSJouni Malinen 88463d5041cSJouni Malinen val = get_param(cmd, "DPPAuthDirection"); 88563d5041cSJouni Malinen mutual = val && strcasecmp(val, "Mutual") == 0; 88663d5041cSJouni Malinen 887d3afc5cbSJouni Malinen val = get_param(cmd, "DPPListenChannel"); 888d3afc5cbSJouni Malinen if (val) { 889d3afc5cbSJouni Malinen freq = channel_to_freq(atoi(val)); 890d3afc5cbSJouni Malinen if (freq == 0) { 891d3afc5cbSJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 892d3afc5cbSJouni Malinen "errorCode,Unsupported DPPListenChannel value"); 893d3afc5cbSJouni Malinen goto out; 894d3afc5cbSJouni Malinen } 895d3afc5cbSJouni Malinen } 896d86e5828SJouni Malinen 897b1dd21f8SJouni Malinen if (!delay_qr_resp && dut->dpp_peer_uri) { 898b1dd21f8SJouni Malinen snprintf(buf, sizeof(buf), "DPP_QR_CODE %s", 899b1dd21f8SJouni Malinen dut->dpp_peer_uri); 900b1dd21f8SJouni Malinen if (wpa_command_resp(ifname, buf, buf, 901b1dd21f8SJouni Malinen sizeof(buf)) < 0) { 902b1dd21f8SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 903b1dd21f8SJouni Malinen "errorCode,Failed to parse URI"); 904b1dd21f8SJouni Malinen goto out; 905b1dd21f8SJouni Malinen } 906b1dd21f8SJouni Malinen } 907b1dd21f8SJouni Malinen 908d86e5828SJouni Malinen if (strcasecmp(prov_role, "Configurator") == 0) { 909258cc26aSJouni Malinen if (!conf_role) { 910258cc26aSJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 911258cc26aSJouni Malinen "errorCode,Missing DPPConfIndex"); 912258cc26aSJouni Malinen goto out; 913258cc26aSJouni Malinen } 914d86e5828SJouni Malinen snprintf(buf, sizeof(buf), 915d86e5828SJouni Malinen "SET dpp_configurator_params conf=%s %s %s configurator=%d", 916d86e5828SJouni Malinen conf_role, conf_ssid, conf_pass, 917d86e5828SJouni Malinen dut->dpp_conf_id); 918d86e5828SJouni Malinen if (wpa_command(ifname, buf) < 0) { 919d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 920d86e5828SJouni Malinen "errorCode,Failed to set configurator parameters"); 921d86e5828SJouni Malinen goto out; 922d86e5828SJouni Malinen } 923d86e5828SJouni Malinen } 924d86e5828SJouni Malinen if (strcasecmp(bs, "PKEX") == 0) { 925d86e5828SJouni Malinen freq = 2437; 926d86e5828SJouni Malinen 927d86e5828SJouni Malinen snprintf(buf, sizeof(buf), 928d86e5828SJouni Malinen "DPP_PKEX_ADD own=%d role=%s %scode=%s", 929d86e5828SJouni Malinen own_pkex_id, role, pkex_identifier, pkex_code); 930d86e5828SJouni Malinen if (wpa_command(ifname, buf) < 0) { 931d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 932d86e5828SJouni Malinen "errorCode,Failed to configure DPP PKEX"); 933d86e5828SJouni Malinen goto out; 934d86e5828SJouni Malinen } 935d86e5828SJouni Malinen } 936d86e5828SJouni Malinen 937fd7359aeSJouni Malinen snprintf(buf, sizeof(buf), "DPP_LISTEN %d role=%s%s", 938fd7359aeSJouni Malinen freq, role, 939fd7359aeSJouni Malinen (strcasecmp(bs, "QR") == 0 && mutual) ? 940fd7359aeSJouni Malinen " qr=mutual" : ""); 941d86e5828SJouni Malinen if (wpa_command(ifname, buf) < 0) { 942d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 943d86e5828SJouni Malinen "errorCode,Failed to start DPP listen"); 944d86e5828SJouni Malinen goto out; 945d86e5828SJouni Malinen } 946b1dd21f8SJouni Malinen 947b1dd21f8SJouni Malinen if (delay_qr_resp && mutual && dut->dpp_peer_uri) { 948b1dd21f8SJouni Malinen int wait_time = atoi(delay_qr_resp); 949b1dd21f8SJouni Malinen 950b1dd21f8SJouni Malinen res = get_wpa_cli_events(dut, ctrl, auth_events, 951b1dd21f8SJouni Malinen buf, sizeof(buf)); 952b1dd21f8SJouni Malinen if (res < 0) { 953b1dd21f8SJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, 954b1dd21f8SJouni Malinen "BootstrapResult,OK,AuthResult,Timeout"); 955b1dd21f8SJouni Malinen goto out; 956b1dd21f8SJouni Malinen } 957b1dd21f8SJouni Malinen sigma_dut_print(dut, DUT_MSG_DEBUG, 958b1dd21f8SJouni Malinen "DPP auth result: %s", buf); 959b1dd21f8SJouni Malinen if (strstr(buf, "DPP-SCAN-PEER-QR-CODE") == NULL) { 960b1dd21f8SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 961b1dd21f8SJouni Malinen "errorCode,No scan request for peer QR Code seen"); 962b1dd21f8SJouni Malinen goto out; 963b1dd21f8SJouni Malinen } 964b1dd21f8SJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, 965b1dd21f8SJouni Malinen "Waiting %d second(s) before processing peer URI", 966b1dd21f8SJouni Malinen wait_time); 967b1dd21f8SJouni Malinen sleep(wait_time); 968b1dd21f8SJouni Malinen 969b1dd21f8SJouni Malinen snprintf(buf, sizeof(buf), "DPP_QR_CODE %s", 970b1dd21f8SJouni Malinen dut->dpp_peer_uri); 971b1dd21f8SJouni Malinen if (wpa_command_resp(ifname, buf, buf, 972b1dd21f8SJouni Malinen sizeof(buf)) < 0) { 973b1dd21f8SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 974b1dd21f8SJouni Malinen "errorCode,Failed to parse URI"); 975b1dd21f8SJouni Malinen goto out; 976b1dd21f8SJouni Malinen } 977b1dd21f8SJouni Malinen } 978d86e5828SJouni Malinen } else { 979d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 980d86e5828SJouni Malinen "errorCode,Unknown DPPAuthRole"); 981d86e5828SJouni Malinen goto out; 982d86e5828SJouni Malinen } 983d86e5828SJouni Malinen 984772299f1SJouni Malinen if (frametype && strcasecmp(frametype, "PKEXExchangeRequest") == 0) { 985772299f1SJouni Malinen if (dpp_wait_tx_status(dut, ctrl, 7) < 0) 986772299f1SJouni Malinen result = "BootstrapResult,Timeout"; 987772299f1SJouni Malinen else 988772299f1SJouni Malinen result = "BootstrapResult,Errorsent"; 989772299f1SJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, result); 990772299f1SJouni Malinen goto out; 991772299f1SJouni Malinen } 992772299f1SJouni Malinen 993772299f1SJouni Malinen if (frametype && strcasecmp(frametype, "PKEXExchangeResponse") == 0) { 994772299f1SJouni Malinen if (dpp_wait_tx_status(dut, ctrl, 8) < 0) 995772299f1SJouni Malinen result = "BootstrapResult,Timeout"; 996772299f1SJouni Malinen else 997772299f1SJouni Malinen result = "BootstrapResult,Errorsent"; 998772299f1SJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, result); 999772299f1SJouni Malinen goto out; 1000772299f1SJouni Malinen } 1001772299f1SJouni Malinen 1002772299f1SJouni Malinen if (frametype && strcasecmp(frametype, "PKEXCRRequest") == 0) { 1003772299f1SJouni Malinen if (dpp_wait_tx_status(dut, ctrl, 9) < 0) 1004772299f1SJouni Malinen result = "BootstrapResult,Timeout"; 1005772299f1SJouni Malinen else 1006772299f1SJouni Malinen result = "BootstrapResult,Errorsent"; 1007772299f1SJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, result); 1008772299f1SJouni Malinen goto out; 1009772299f1SJouni Malinen } 1010772299f1SJouni Malinen 1011772299f1SJouni Malinen if (frametype && strcasecmp(frametype, "PKEXCRResponse") == 0) { 1012772299f1SJouni Malinen if (dpp_wait_tx_status(dut, ctrl, 10) < 0) 1013772299f1SJouni Malinen result = "BootstrapResult,Timeout"; 1014772299f1SJouni Malinen else 1015772299f1SJouni Malinen result = "BootstrapResult,Errorsent"; 1016772299f1SJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, result); 1017772299f1SJouni Malinen goto out; 1018772299f1SJouni Malinen } 1019772299f1SJouni Malinen 1020772299f1SJouni Malinen if (frametype && strcasecmp(frametype, "AuthenticationRequest") == 0) { 1021772299f1SJouni Malinen if (dpp_wait_tx_status(dut, ctrl, 0) < 0) 1022772299f1SJouni Malinen result = "BootstrapResult,OK,AuthResult,Timeout"; 1023772299f1SJouni Malinen else 1024772299f1SJouni Malinen result = "BootstrapResult,OK,AuthResult,Errorsent"; 1025772299f1SJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, result); 1026772299f1SJouni Malinen goto out; 1027772299f1SJouni Malinen } 1028772299f1SJouni Malinen 1029772299f1SJouni Malinen if (frametype && strcasecmp(frametype, "AuthenticationResponse") == 0) { 1030772299f1SJouni Malinen if (dpp_wait_tx_status(dut, ctrl, 1) < 0) 1031772299f1SJouni Malinen result = "BootstrapResult,OK,AuthResult,Timeout"; 1032772299f1SJouni Malinen else 1033772299f1SJouni Malinen result = "BootstrapResult,OK,AuthResult,Errorsent"; 1034772299f1SJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, result); 1035772299f1SJouni Malinen goto out; 1036772299f1SJouni Malinen } 1037772299f1SJouni Malinen 1038772299f1SJouni Malinen if (frametype && strcasecmp(frametype, "AuthenticationConfirm") == 0) { 1039772299f1SJouni Malinen if (dpp_wait_tx_status(dut, ctrl, 2) < 0) 1040772299f1SJouni Malinen result = "BootstrapResult,OK,AuthResult,Timeout"; 1041772299f1SJouni Malinen else 1042772299f1SJouni Malinen result = "BootstrapResult,OK,AuthResult,Errorsent"; 1043772299f1SJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, result); 1044772299f1SJouni Malinen goto out; 1045772299f1SJouni Malinen } 1046772299f1SJouni Malinen 1047d86e5828SJouni Malinen res = get_wpa_cli_events(dut, ctrl, auth_events, buf, sizeof(buf)); 1048d86e5828SJouni Malinen if (res < 0) { 1049d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, 1050d86e5828SJouni Malinen "BootstrapResult,OK,AuthResult,Timeout"); 1051d86e5828SJouni Malinen goto out; 1052d86e5828SJouni Malinen } 1053d86e5828SJouni Malinen sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP auth result: %s", buf); 1054d86e5828SJouni Malinen 10552e9c8a46SJouni Malinen if (strstr(buf, "DPP-RESPONSE-PENDING")) { 10562e9c8a46SJouni Malinen /* Wait for the actual result after the peer has scanned the 10572e9c8a46SJouni Malinen * QR Code. */ 10582e9c8a46SJouni Malinen res = get_wpa_cli_events(dut, ctrl, auth_events, 10592e9c8a46SJouni Malinen buf, sizeof(buf)); 10602e9c8a46SJouni Malinen if (res < 0) { 10612e9c8a46SJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, 10622e9c8a46SJouni Malinen "BootstrapResult,OK,AuthResult,Timeout"); 10632e9c8a46SJouni Malinen goto out; 10642e9c8a46SJouni Malinen } 10652e9c8a46SJouni Malinen } 10662e9c8a46SJouni Malinen 1067d86e5828SJouni Malinen if (strstr(buf, "DPP-NOT-COMPATIBLE")) { 1068d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, 1069d86e5828SJouni Malinen "BootstrapResult,OK,AuthResult,ROLES_NOT_COMPATIBLE"); 1070d86e5828SJouni Malinen goto out; 1071d86e5828SJouni Malinen } 1072d86e5828SJouni Malinen 1073d86e5828SJouni Malinen if (!strstr(buf, "DPP-AUTH-SUCCESS")) { 1074d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, 1075d86e5828SJouni Malinen "BootstrapResult,OK,AuthResult,FAILED"); 1076d86e5828SJouni Malinen goto out; 1077d86e5828SJouni Malinen } 1078d86e5828SJouni Malinen 1079772299f1SJouni Malinen if (frametype && strcasecmp(frametype, "ConfigurationRequest") == 0) { 1080772299f1SJouni Malinen res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE", 1081772299f1SJouni Malinen buf, sizeof(buf)); 1082772299f1SJouni Malinen if (res < 0) 1083772299f1SJouni Malinen result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Timeout"; 1084772299f1SJouni Malinen else 1085772299f1SJouni Malinen result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Errorsent"; 1086772299f1SJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, result); 1087772299f1SJouni Malinen goto out; 1088772299f1SJouni Malinen } 1089772299f1SJouni Malinen 1090772299f1SJouni Malinen if (frametype && strcasecmp(frametype, "ConfigurationResponse") == 0) { 1091772299f1SJouni Malinen res = get_wpa_cli_event(dut, ctrl, "DPP-CONF-SENT", 1092772299f1SJouni Malinen buf, sizeof(buf)); 1093772299f1SJouni Malinen if (res < 0) 1094772299f1SJouni Malinen result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Timeout"; 1095772299f1SJouni Malinen else 1096772299f1SJouni Malinen result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Errorsent"; 1097772299f1SJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, result); 1098772299f1SJouni Malinen goto out; 1099772299f1SJouni Malinen } 1100772299f1SJouni Malinen 1101d86e5828SJouni Malinen res = get_wpa_cli_events(dut, ctrl, conf_events, buf, sizeof(buf)); 1102d86e5828SJouni Malinen if (res < 0) { 1103d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, 1104d86e5828SJouni Malinen "BootstrapResult,OK,AuthResult,OK,ConfResult,Timeout"); 1105d86e5828SJouni Malinen goto out; 1106d86e5828SJouni Malinen } 1107d86e5828SJouni Malinen sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP conf result: %s", buf); 1108d86e5828SJouni Malinen 1109d86e5828SJouni Malinen if (!strstr(buf, "DPP-CONF-SENT") && 1110d86e5828SJouni Malinen !strstr(buf, "DPP-CONF-RECEIVED")) { 1111d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, 1112d86e5828SJouni Malinen "BootstrapResult,OK,AuthResult,OK,ConfResult,FAILED"); 1113d86e5828SJouni Malinen goto out; 1114d86e5828SJouni Malinen } 1115d86e5828SJouni Malinen 1116d86e5828SJouni Malinen if (sigma_dut_is_ap(dut) && 1117d86e5828SJouni Malinen strcasecmp(prov_role, "Enrollee") == 0) { 1118*174db64fSJouni Malinen update_ap: 1119d86e5828SJouni Malinen res = dpp_hostapd_conf_update(dut, conn, ifname, ctrl); 1120d86e5828SJouni Malinen if (res == 0) 1121d86e5828SJouni Malinen goto out; 1122d86e5828SJouni Malinen if (res < 0) { 1123d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, NULL); 1124d86e5828SJouni Malinen goto out; 1125d86e5828SJouni Malinen } 1126d86e5828SJouni Malinen } 1127d86e5828SJouni Malinen 1128d86e5828SJouni Malinen if (strcasecmp(wait_conn, "Yes") == 0 && 1129d86e5828SJouni Malinen !sigma_dut_is_ap(dut) && 1130d86e5828SJouni Malinen strcasecmp(prov_role, "Enrollee") == 0) { 1131fbb268d7SJouni Malinen wait_connect: 113253558e0fSJouni Malinen if (frametype && strcasecmp(frametype, 113353558e0fSJouni Malinen "PeerDiscoveryRequest") == 0) { 113453558e0fSJouni Malinen if (dpp_wait_tx_status(dut, ctrl, 5) < 0) 113553558e0fSJouni Malinen result = "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Timeout"; 113653558e0fSJouni Malinen else 113753558e0fSJouni Malinen result = "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Errorsent"; 113853558e0fSJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, result); 113953558e0fSJouni Malinen goto out; 114053558e0fSJouni Malinen } 114153558e0fSJouni Malinen 1142d86e5828SJouni Malinen res = get_wpa_cli_events(dut, ctrl, conn_events, 1143d86e5828SJouni Malinen buf, sizeof(buf)); 1144d86e5828SJouni Malinen if (res < 0) { 1145d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, 1146d86e5828SJouni Malinen "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Timeout,NetworkConnectResult,Timeout"); 1147d86e5828SJouni Malinen goto out; 1148d86e5828SJouni Malinen } 1149d86e5828SJouni Malinen sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP connect result: %s", 1150d86e5828SJouni Malinen buf); 1151d86e5828SJouni Malinen 1152d86e5828SJouni Malinen if (strstr(buf, "PMKSA-CACHE-ADDED")) { 1153d86e5828SJouni Malinen res = get_wpa_cli_events(dut, ctrl, conn_events, 1154d86e5828SJouni Malinen buf, sizeof(buf)); 1155d86e5828SJouni Malinen if (res < 0) { 1156d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, 1157d86e5828SJouni Malinen "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,Timeout"); 1158d86e5828SJouni Malinen goto out; 1159d86e5828SJouni Malinen } 1160d86e5828SJouni Malinen sigma_dut_print(dut, DUT_MSG_DEBUG, 1161d86e5828SJouni Malinen "DPP connect result: %s", buf); 1162d86e5828SJouni Malinen if (strstr(buf, "CTRL-EVENT-CONNECTED")) 1163d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, 1164d86e5828SJouni Malinen "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,OK"); 1165d86e5828SJouni Malinen else 1166d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, 1167d86e5828SJouni Malinen "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,Timeout"); 1168d86e5828SJouni Malinen goto out; 1169d86e5828SJouni Malinen } 1170d86e5828SJouni Malinen 1171d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, 1172d86e5828SJouni Malinen "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkConnectResult,OK"); 1173d86e5828SJouni Malinen goto out; 1174d86e5828SJouni Malinen } 1175d86e5828SJouni Malinen 117653558e0fSJouni Malinen if (strcasecmp(wait_conn, "Yes") == 0 && 117753558e0fSJouni Malinen frametype && strcasecmp(frametype, "PeerDiscoveryResponse") == 0) { 117853558e0fSJouni Malinen if (dpp_wait_tx_status(dut, ctrl, 6) < 0) 117953558e0fSJouni Malinen result = "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Timeout"; 118053558e0fSJouni Malinen else 118153558e0fSJouni Malinen result = "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Errorsent"; 118253558e0fSJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, result); 118353558e0fSJouni Malinen goto out; 118453558e0fSJouni Malinen } 118553558e0fSJouni Malinen 1186d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, 1187d86e5828SJouni Malinen "BootstrapResult,OK,AuthResult,OK,ConfResult,OK"); 1188d86e5828SJouni Malinen out: 1189d86e5828SJouni Malinen wpa_ctrl_detach(ctrl); 1190d86e5828SJouni Malinen wpa_ctrl_close(ctrl); 1191d86e5828SJouni Malinen dut->default_timeout = old_timeout; 1192d86e5828SJouni Malinen return 0; 1193d86e5828SJouni Malinen } 1194d86e5828SJouni Malinen 1195d86e5828SJouni Malinen 1196d86e5828SJouni Malinen int dpp_dev_exec_action(struct sigma_dut *dut, struct sigma_conn *conn, 1197d86e5828SJouni Malinen struct sigma_cmd *cmd) 1198d86e5828SJouni Malinen { 1199d86e5828SJouni Malinen const char *type = get_param(cmd, "DPPActionType"); 1200d86e5828SJouni Malinen const char *bs = get_param(cmd, "DPPBS"); 1201d86e5828SJouni Malinen 1202d86e5828SJouni Malinen if (!bs) { 1203d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 1204d86e5828SJouni Malinen "errorCode,Missing DPPBS"); 1205d86e5828SJouni Malinen return 0; 1206d86e5828SJouni Malinen } 1207d86e5828SJouni Malinen 1208d86e5828SJouni Malinen if (!type) { 1209d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 1210d86e5828SJouni Malinen "errorCode,Missing DPPActionType"); 1211d86e5828SJouni Malinen return 0; 1212d86e5828SJouni Malinen } 1213d86e5828SJouni Malinen 1214d86e5828SJouni Malinen if (strcasecmp(type, "GetLocalBootstrap") == 0) 1215d86e5828SJouni Malinen return dpp_get_local_bootstrap(dut, conn, cmd); 1216d86e5828SJouni Malinen if (strcasecmp(type, "SetPeerBootstrap") == 0) 1217d86e5828SJouni Malinen return dpp_set_peer_bootstrap(dut, conn, cmd); 1218d86e5828SJouni Malinen if (strcasecmp(type, "ManualDPP") == 0) 1219d86e5828SJouni Malinen return dpp_manual_dpp(dut, conn, cmd); 1220d86e5828SJouni Malinen if (strcasecmp(type, "AutomaticDPP") == 0) 1221d86e5828SJouni Malinen return dpp_automatic_dpp(dut, conn, cmd); 1222d86e5828SJouni Malinen 1223d86e5828SJouni Malinen send_resp(dut, conn, SIGMA_ERROR, 1224d86e5828SJouni Malinen "errorCode,Unsupported DPPActionType"); 1225d86e5828SJouni Malinen return 0; 1226d86e5828SJouni Malinen } 1227