blob: be5f432b410309b17a3fd79fd9b413c11a757a56 [file] [log] [blame]
Jouni Malinend86e5822017-08-29 03:55:32 +03001/*
2 * Sigma Control API DUT (station/AP/sniffer)
3 * Copyright (c) 2017, Qualcomm Atheros, Inc.
Jouni Malinenc12ea4a2018-01-05 21:07:10 +02004 * Copyright (c) 2018, The Linux Foundation
Jouni Malinend86e5822017-08-29 03:55:32 +03005 * All Rights Reserved.
6 * Licensed under the Clear BSD license. See README for more details.
7 */
8
9#include "sigma_dut.h"
Jouni Malinen1a38cc32018-01-05 20:59:00 +020010#include <sys/wait.h>
Jouni Malinend86e5822017-08-29 03:55:32 +030011#include "wpa_ctrl.h"
12#include "wpa_helpers.h"
13
Jouni Malinen1a38cc32018-01-05 20:59:00 +020014#ifdef ANDROID
Srinivas Dasaribc9e0552018-01-04 19:24:28 +053015char *dpp_qrcode_file = "/sdcard/wpadebug_qrdata.txt";
Jouni Malinen1a38cc32018-01-05 20:59:00 +020016#endif /* ANDROID */
Srinivas Dasaribc9e0552018-01-04 19:24:28 +053017
Jouni Malinend86e5822017-08-29 03:55:32 +030018
19static int sigma_dut_is_ap(struct sigma_dut *dut)
20{
21 return dut->device_type == AP_unknown ||
22 dut->device_type == AP_testbed ||
23 dut->device_type == AP_dut;
24}
25
26
27static int dpp_hostapd_run(struct sigma_dut *dut)
28{
29 if (dut->hostapd_running)
30 return 0;
31
32 sigma_dut_print(dut, DUT_MSG_INFO,
33 "Starting hostapd in unconfigured state for DPP");
34 snprintf(dut->ap_ssid, sizeof(dut->ap_ssid), "unconfigured");
priyadharshini gowthaman9149afc2018-01-15 13:40:18 -080035 if (!dut->ap_oper_chn)
36 dut->ap_channel = 11;
Jouni Malinend86e5822017-08-29 03:55:32 +030037 dut->ap_is_dual = 0;
priyadharshini gowthamanfa2d7c32018-02-20 13:30:13 -080038 dut->ap_mode = dut->ap_channel <= 14 ? AP_11ng : AP_11na;
Jouni Malinend86e5822017-08-29 03:55:32 +030039 dut->ap_key_mgmt = AP_OPEN;
40 dut->ap_cipher = AP_PLAIN;
41 return cmd_ap_config_commit(dut, NULL, NULL) == 1 ? 0 : -1;
42}
43
44
45static const char * dpp_get_curve(struct sigma_cmd *cmd, const char *arg)
46{
47 const char *val = get_param(cmd, arg);
48
49 if (!val)
50 val = "P-256";
51 else if (strcasecmp(val, "BP-256R1") == 0)
52 val = "BP-256";
53 else if (strcasecmp(val, "BP-384R1") == 0)
54 val = "BP-384";
55 else if (strcasecmp(val, "BP-512R1") == 0)
56 val = "BP-512";
57
58 return val;
59}
60
61
62static int dpp_get_local_bootstrap(struct sigma_dut *dut,
63 struct sigma_conn *conn,
Srinivas Dasaribc9e0552018-01-04 19:24:28 +053064 struct sigma_cmd *cmd, int send_result,
65 int *success)
Jouni Malinend86e5822017-08-29 03:55:32 +030066{
67 const char *curve = dpp_get_curve(cmd, "DPPCryptoIdentifier");
68 const char *bs = get_param(cmd, "DPPBS");
Jouni Malinen4161c3f2017-11-13 18:36:09 +020069 const char *chan_list = get_param(cmd, "DPPChannelList");
70 char *pos, mac[50], buf[200], resp[1000], hex[2000];
Jouni Malinen016ae6c2019-11-04 17:00:01 +020071 const char *ifname = get_station_ifname(dut);
Jouni Malinen3aa72862019-05-29 23:14:51 +030072 int res;
Jouni Malinen6f4ce412020-04-03 13:53:23 +030073 const char *type;
Jouni Malinend86e5822017-08-29 03:55:32 +030074
Srinivas Dasaribc9e0552018-01-04 19:24:28 +053075 if (success)
76 *success = 0;
Jouni Malinen6f4ce412020-04-03 13:53:23 +030077 if (strcasecmp(bs, "QR") == 0) {
78 type = "qrcode";
79 } else if (strcasecmp(bs, "NFC") == 0) {
80 type ="nfc-uri";
81 } else {
Jouni Malinend86e5822017-08-29 03:55:32 +030082 send_resp(dut, conn, SIGMA_ERROR,
83 "errorCode,Unsupported DPPBS");
84 return 0;
85 }
86
87 if (sigma_dut_is_ap(dut)) {
88 u8 bssid[ETH_ALEN];
89
90 if (!dut->hostapd_ifname) {
91 sigma_dut_print(dut, DUT_MSG_ERROR,
92 "hostapd ifname not specified (-j)");
93 return -2;
94 }
95 ifname = dut->hostapd_ifname;
96 if (get_hwaddr(dut->hostapd_ifname, bssid) < 0) {
97 sigma_dut_print(dut, DUT_MSG_ERROR,
98 "Could not get MAC address for %s",
99 dut->hostapd_ifname);
100 return -2;
101 }
102 snprintf(mac, sizeof(mac), "%02x%02x%02x%02x%02x%02x",
103 bssid[0], bssid[1], bssid[2],
104 bssid[3], bssid[4], bssid[5]);
105 } else {
106 if (get_wpa_status(ifname, "address", mac, sizeof(mac)) < 0)
107 return -2;
108 }
109
110 pos = mac;
111 while (*pos) {
112 if (*pos == ':')
113 memmove(pos, pos + 1, strlen(pos));
114 else
115 pos++;
116 }
117
Jouni Malinend86e5822017-08-29 03:55:32 +0300118 if (sigma_dut_is_ap(dut) && dpp_hostapd_run(dut) < 0) {
119 send_resp(dut, conn, SIGMA_ERROR,
120 "errorCode,Failed to start hostapd");
121 return 0;
122 }
123
Jouni Malinen4161c3f2017-11-13 18:36:09 +0200124 if (chan_list &&
125 (strcmp(chan_list, "0/0") == 0 || chan_list[0] == '\0')) {
126 /* No channel list */
Jouni Malinen3aa72862019-05-29 23:14:51 +0300127 res = snprintf(buf, sizeof(buf),
Jouni Malinen6f4ce412020-04-03 13:53:23 +0300128 "DPP_BOOTSTRAP_GEN type=%s curve=%s mac=%s",
129 type, curve, mac);
Jouni Malinen4161c3f2017-11-13 18:36:09 +0200130 } else if (chan_list) {
131 /* Channel list override (CTT case) - space separated tuple(s)
132 * of OperatingClass/Channel; convert to wpa_supplicant/hostapd
133 * format: comma separated tuples */
134 strlcpy(resp, chan_list, sizeof(resp));
135 for (pos = resp; *pos; pos++) {
136 if (*pos == ' ')
137 *pos = ',';
138 }
Jouni Malinen3aa72862019-05-29 23:14:51 +0300139 res = snprintf(buf, sizeof(buf),
Jouni Malinen6f4ce412020-04-03 13:53:23 +0300140 "DPP_BOOTSTRAP_GEN type=%s curve=%s chan=%s mac=%s",
141 type, curve, resp, mac);
Jouni Malinen4161c3f2017-11-13 18:36:09 +0200142 } else {
Jouni Malinenf8d81aa2019-09-27 03:39:40 +0300143 int channel = 11;
144
Jouni Malinen4161c3f2017-11-13 18:36:09 +0200145 /* Default channel list (normal DUT case) */
Jouni Malinenf8d81aa2019-09-27 03:39:40 +0300146 if (sigma_dut_is_ap(dut) && dut->hostapd_running &&
147 dut->ap_oper_chn &&
148 dut->ap_channel > 0 && dut->ap_channel <= 13)
149 channel = dut->ap_channel;
Jouni Malinen3aa72862019-05-29 23:14:51 +0300150 res = snprintf(buf, sizeof(buf),
Jouni Malinen6f4ce412020-04-03 13:53:23 +0300151 "DPP_BOOTSTRAP_GEN type=%s curve=%s chan=81/%d mac=%s",
152 type, curve, channel, mac);
Jouni Malinen4161c3f2017-11-13 18:36:09 +0200153 }
154
Jouni Malinen3aa72862019-05-29 23:14:51 +0300155 if (res < 0 || res >= sizeof(buf) ||
156 wpa_command_resp(ifname, buf, resp, sizeof(resp)) < 0)
Jouni Malinend86e5822017-08-29 03:55:32 +0300157 return -2;
158 if (strncmp(resp, "FAIL", 4) == 0)
159 return -2;
160 dut->dpp_local_bootstrap = atoi(resp);
161 snprintf(buf, sizeof(buf), "DPP_BOOTSTRAP_GET_URI %d",
162 atoi(resp));
163 if (wpa_command_resp(ifname, buf, resp, sizeof(resp)) < 0)
164 return -2;
165 if (strncmp(resp, "FAIL", 4) == 0)
166 return -2;
167
168 sigma_dut_print(dut, DUT_MSG_DEBUG, "URI: %s", resp);
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530169
170 if (send_result) {
171 ascii2hexstr(resp, hex);
Jouni Malinen3aa72862019-05-29 23:14:51 +0300172 res = snprintf(resp, sizeof(resp), "BootstrappingData,%s", hex);
173 send_resp(dut, conn, SIGMA_COMPLETE,
174 res >= 0 && res < sizeof(resp) ? resp : NULL);
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530175 }
176
177 if (success)
178 *success = 1;
Jouni Malinend86e5822017-08-29 03:55:32 +0300179 return 0;
180}
181
182
183static int dpp_set_peer_bootstrap(struct sigma_dut *dut,
184 struct sigma_conn *conn,
185 struct sigma_cmd *cmd)
186{
187 const char *val = get_param(cmd, "DPPBootstrappingdata");
Jouni Malinenb1dd21f2017-11-13 19:14:29 +0200188 char uri[1000];
Jouni Malinend86e5822017-08-29 03:55:32 +0300189 int res;
Jouni Malinend86e5822017-08-29 03:55:32 +0300190
191 if (!val) {
192 send_resp(dut, conn, SIGMA_ERROR,
193 "errorCode,Missing DPPBootstrappingdata");
194 return 0;
195 }
196
197 res = parse_hexstr(val, (unsigned char *) uri, sizeof(uri));
198 if (res < 0 || (size_t) res >= sizeof(uri))
199 return -2;
200 uri[res] = '\0';
201 sigma_dut_print(dut, DUT_MSG_DEBUG, "URI: %s", uri);
Jouni Malinenb1dd21f2017-11-13 19:14:29 +0200202 free(dut->dpp_peer_uri);
203 dut->dpp_peer_uri = strdup(uri);
Jouni Malinend86e5822017-08-29 03:55:32 +0300204
205 return 1;
206}
207
208
209static int dpp_hostapd_conf_update(struct sigma_dut *dut,
210 struct sigma_conn *conn, const char *ifname,
211 struct wpa_ctrl *ctrl)
212{
213 int res;
214 char buf[2000], buf2[2500], *pos, *pos2;
Jouni Malinenb4c5e3b2017-09-15 17:43:20 +0300215 const char *conf_data_events[] = {
216 "DPP-CONNECTOR",
217 "DPP-CONFOBJ-PASS",
218 "DPP-CONFOBJ-PSK",
Jouni Malinen0cd6e362020-04-02 21:33:43 +0300219 "DPP-C-SIGN-KEY",
220 "DPP-NET-ACCESS-KEY",
Jouni Malinenb4c5e3b2017-09-15 17:43:20 +0300221 NULL
222 };
Jouni Malinen20465812020-02-08 01:43:16 +0200223 unsigned int old_timeout;
Jouni Malinen0cd6e362020-04-02 21:33:43 +0300224 int legacy_akm, dpp_akm;
225 char *connector = NULL, *psk = NULL, *csign = NULL,
226 *net_access_key = NULL;
227 char pass[64];
228 int pass_len = 0;
229 int ret = 0;
Jouni Malinend86e5822017-08-29 03:55:32 +0300230
231 sigma_dut_print(dut, DUT_MSG_INFO,
232 "Update hostapd configuration based on DPP Config Object");
233
234 if (wpa_command(ifname, "SET wpa 2") < 0 ||
235 wpa_command(ifname, "SET wpa_key_mgmt DPP") < 0 ||
Jouni Malinen0d347232017-11-01 17:14:00 +0200236 wpa_command(ifname, "SET ieee80211w 1") < 0 ||
Jouni Malinend86e5822017-08-29 03:55:32 +0300237 wpa_command(ifname, "SET rsn_pairwise CCMP") < 0) {
238 send_resp(dut, conn, SIGMA_ERROR,
239 "errorCode,Failed to update AP security parameters");
240 goto out;
241 }
242
Jouni Malinen0cd6e362020-04-02 21:33:43 +0300243 res = get_wpa_cli_event(dut, ctrl, "DPP-CONFOBJ-AKM", buf, sizeof(buf));
244 if (res < 0) {
245 send_resp(dut, conn, SIGMA_ERROR,
246 "errorCode,No DPP-CONFOBJ-AKM");
247 goto out;
248 }
249 pos = strchr(buf, ' ');
250 if (!pos)
251 return -2;
252 pos++;
253 sigma_dut_print(dut, DUT_MSG_INFO,
254 "DPP: Config Object AKM: %s", pos);
255 legacy_akm = strstr(pos, "psk") != NULL || strstr(pos, "sae") != NULL;
256 dpp_akm = strstr(pos, "dpp") != NULL;
257
Jouni Malinend86e5822017-08-29 03:55:32 +0300258 res = get_wpa_cli_event(dut, ctrl, "DPP-CONFOBJ-SSID",
259 buf, sizeof(buf));
260 if (res < 0) {
261 send_resp(dut, conn, SIGMA_ERROR,
262 "errorCode,No DPP-CONFOBJ-SSID");
263 goto out;
264 }
265 pos = strchr(buf, ' ');
266 if (!pos)
267 return -2;
268 pos++;
269 sigma_dut_print(dut, DUT_MSG_INFO,
270 "DPP: Config Object SSID: %s", pos);
271 snprintf(buf2, sizeof(buf2), "SET ssid %s", pos);
272 if (wpa_command(ifname, buf2) < 0) {
273 send_resp(dut, conn, SIGMA_ERROR,
274 "errorCode,Failed to update AP SSID");
275 goto out;
276 }
277
Jouni Malinena7631f12019-11-28 15:37:44 +0200278 if (wpa_command(ifname, "SET utf8_ssid 1") < 0) {
279 send_resp(dut, conn, SIGMA_ERROR,
280 "errorCode,Failed to update AP UTF-8 SSID capa");
281 goto out;
282 }
283
Jouni Malinen0cd6e362020-04-02 21:33:43 +0300284 while ((dpp_akm && (!connector || !csign || !net_access_key)) ||
285 (legacy_akm && !pass_len && !psk)) {
286 res = get_wpa_cli_events(dut, ctrl, conf_data_events,
287 buf, sizeof(buf));
288 if (res < 0) {
Jouni Malinenb4c5e3b2017-09-15 17:43:20 +0300289 send_resp(dut, conn, SIGMA_ERROR,
Jouni Malinen0cd6e362020-04-02 21:33:43 +0300290 "errorCode,Not all config object information received");
Jouni Malinenb4c5e3b2017-09-15 17:43:20 +0300291 goto out;
292 }
293
Jouni Malinen0cd6e362020-04-02 21:33:43 +0300294 if (strstr(buf, "DPP-CONNECTOR")) {
295 pos = strchr(buf, ' ');
296 if (!pos) {
297 ret = -2;
298 goto out;
299 }
300 pos++;
301 sigma_dut_print(dut, DUT_MSG_INFO, "DPP: Connector: %s",
302 pos);
303 if (!connector)
304 connector = strdup(pos);
305 } else if (strstr(buf, "DPP-C-SIGN-KEY")) {
306 pos = strchr(buf, ' ');
307 if (!pos) {
308 ret = -2;
309 goto out;
310 }
311 pos++;
312 sigma_dut_print(dut, DUT_MSG_INFO,
313 "DPP: C-sign-key: %s", pos);
314 if (!csign)
315 csign = strdup(pos);
316 } else if (strstr(buf, "DPP-NET-ACCESS-KEY")) {
317 pos = strchr(buf, ' ');
318 if (!pos) {
319 ret = -2;
320 goto out;
321 }
322 pos++;
323 if (!net_access_key)
324 net_access_key = strdup(pos);
325 } else if (strstr(buf, "DPP-CONFOBJ-PASS")) {
326 pos = strchr(buf, ' ');
327 if (!pos) {
328 ret = -2;
329 goto out;
330 }
331 pos++;
Jouni Malinenb4c5e3b2017-09-15 17:43:20 +0300332 pass_len = parse_hexstr(pos, (u8 *) pass, sizeof(pass));
Jouni Malinen0cd6e362020-04-02 21:33:43 +0300333 if (pass_len < 0 || (size_t) pass_len >= sizeof(pass)) {
334 ret = -2;
335 goto out;
336 }
Jouni Malinenb4c5e3b2017-09-15 17:43:20 +0300337 pass[pass_len] = '\0';
338 sigma_dut_print(dut, DUT_MSG_INFO,
339 "DPP: Passphrase: %s", pass);
Jouni Malinenb4c5e3b2017-09-15 17:43:20 +0300340 } else if (strstr(buf, "DPP-CONFOBJ-PSK")) {
Jouni Malinen0cd6e362020-04-02 21:33:43 +0300341 pos = strchr(buf, ' ');
342 if (!pos) {
343 ret = -2;
Jouni Malinenb4c5e3b2017-09-15 17:43:20 +0300344 goto out;
345 }
Jouni Malinen0cd6e362020-04-02 21:33:43 +0300346 pos++;
347 sigma_dut_print(dut, DUT_MSG_INFO, "DPP: PSK: %s", pos);
348 if (!psk)
349 psk = strdup(pos);
Jouni Malinenb4c5e3b2017-09-15 17:43:20 +0300350 }
Jouni Malinenb4c5e3b2017-09-15 17:43:20 +0300351 }
352
Jouni Malinen0cd6e362020-04-02 21:33:43 +0300353 if ((!connector || !dpp_akm) &&
354 wpa_command(ifname, "SET wpa_key_mgmt WPA-PSK") < 0) {
Jouni Malinend86e5822017-08-29 03:55:32 +0300355 send_resp(dut, conn, SIGMA_ERROR,
Jouni Malinen0cd6e362020-04-02 21:33:43 +0300356 "errorCode,Failed to update AP security parameters");
Jouni Malinend86e5822017-08-29 03:55:32 +0300357 goto out;
358 }
359
Jouni Malinen0cd6e362020-04-02 21:33:43 +0300360 if (connector && dpp_akm && legacy_akm &&
361 wpa_command(ifname, "SET wpa_key_mgmt DPP WPA-PSK") < 0) {
Jouni Malinend86e5822017-08-29 03:55:32 +0300362 send_resp(dut, conn, SIGMA_ERROR,
Jouni Malinen0cd6e362020-04-02 21:33:43 +0300363 "errorCode,Failed to update AP security parameters");
Jouni Malinend86e5822017-08-29 03:55:32 +0300364 goto out;
365 }
Jouni Malinend86e5822017-08-29 03:55:32 +0300366
Jouni Malinen0cd6e362020-04-02 21:33:43 +0300367 if (pass_len) {
368 snprintf(buf2, sizeof(buf2), "SET wpa_passphrase %s",
369 pass);
Jouni Malinend86e5822017-08-29 03:55:32 +0300370 if (wpa_command(ifname, buf2) < 0) {
371 send_resp(dut, conn, SIGMA_ERROR,
Jouni Malinen0cd6e362020-04-02 21:33:43 +0300372 "errorCode,Failed to set passphrase");
373 goto out;
374 }
375 } else if (psk) {
376 snprintf(buf2, sizeof(buf2), "SET wpa_psk %s", psk);
377 if (wpa_command(ifname, buf2) < 0) {
378 send_resp(dut, conn, SIGMA_ERROR,
379 "errorCode,Failed to set PSK");
Jouni Malinend86e5822017-08-29 03:55:32 +0300380 goto out;
381 }
382 }
Jouni Malinen0cd6e362020-04-02 21:33:43 +0300383
384 if (connector) {
385 snprintf(buf2, sizeof(buf2), "SET dpp_connector %s", connector);
386 if (wpa_command(ifname, buf2) < 0) {
387 send_resp(dut, conn, SIGMA_ERROR,
388 "errorCode,Failed to update AP Connector");
389 goto out;
390 }
391 }
392
393 if (csign) {
394 snprintf(buf2, sizeof(buf2), "SET dpp_csign %s", csign);
395 if (wpa_command(ifname, buf2) < 0) {
396 send_resp(dut, conn, SIGMA_ERROR,
397 "errorCode,Failed to update AP C-sign-key");
398 goto out;
399 }
400 }
401
402 if (net_access_key) {
403 pos2 = strchr(net_access_key, ' ');
404 if (pos2)
405 *pos2++ = '\0';
406 sigma_dut_print(dut, DUT_MSG_INFO, "DPP: netAccessKey: %s",
407 net_access_key);
408 snprintf(buf2, sizeof(buf2), "SET dpp_netaccesskey %s",
409 net_access_key);
410 if (wpa_command(ifname, buf2) < 0) {
411 send_resp(dut, conn, SIGMA_ERROR,
412 "errorCode,Failed to update AP netAccessKey");
413 goto out;
414 }
415 if (pos2) {
416 sigma_dut_print(dut, DUT_MSG_INFO,
417 "DPP: netAccessKey expiry: %s", pos2);
418 snprintf(buf2, sizeof(buf2),
419 "SET dpp_netaccesskey_expiry %s", pos2);
420 if (wpa_command(ifname, buf2) < 0) {
421 send_resp(dut, conn, SIGMA_ERROR,
422 "errorCode,Failed to update AP netAccessKey expiry");
423 goto out;
424 }
425 }
426 }
Jouni Malinend86e5822017-08-29 03:55:32 +0300427
Jouni Malinen20465812020-02-08 01:43:16 +0200428 /* Wait for a possible Configuration Result to be sent */
429 old_timeout = dut->default_timeout;
430 dut->default_timeout = 1;
431 get_wpa_cli_event(dut, ctrl, "DPP-TX-STATUS", buf, sizeof(buf));
432 dut->default_timeout = old_timeout;
Jouni Malinend86e5822017-08-29 03:55:32 +0300433 if (wpa_command(ifname, "DISABLE") < 0 ||
434 wpa_command(ifname, "ENABLE") < 0) {
435 send_resp(dut, conn, SIGMA_ERROR,
436 "errorCode,Failed to update AP configuration");
437 goto out;
438 }
439
440 res = get_wpa_cli_event(dut, ctrl, "AP-ENABLED", buf, sizeof(buf));
441 if (res < 0) {
442 send_resp(dut, conn, SIGMA_ERROR, "errorCode,No AP-ENABLED");
443 goto out;
444 }
445
Jouni Malinen0cd6e362020-04-02 21:33:43 +0300446 ret = 1;
Jouni Malinend86e5822017-08-29 03:55:32 +0300447out:
Jouni Malinen0cd6e362020-04-02 21:33:43 +0300448 free(connector);
449 free(psk);
450 free(csign);
451 free(net_access_key);
452 return ret;
Jouni Malinend86e5822017-08-29 03:55:32 +0300453}
454
455
Jouni Malinen772299f2017-11-06 00:36:26 +0200456struct dpp_test_info {
457 const char *step;
458 const char *frame;
459 const char *attr;
460 int value;
461};
462
463static const struct dpp_test_info dpp_tests[] = {
464 { "InvalidValue", "AuthenticationRequest", "WrappedData", 1 },
465 { "InvalidValue", "AuthenticationResponse", "WrappedData", 2 },
Jouni Malinenf96fcee2017-11-22 16:08:35 +0200466 { "InvalidValue", "AuthenticationResponse", "PrimaryWrappedData", 2 },
Jouni Malinen772299f2017-11-06 00:36:26 +0200467 { "InvalidValue", "AuthenticationConfirm", "WrappedData", 3 },
468 { "InvalidValue", "PKEXCRRequest", "WrappedData", 4 },
469 { "InvalidValue", "PKEXCRResponse", "WrappedData", 5 },
470 { "InvalidValue", "ConfigurationRequest", "WrappedData", 6 },
471 { "InvalidValue", "ConfigurationResponse", "WrappedData", 7 },
472 { "InvalidValue", "AuthenticationRequest", "InitCapabilities", 8 },
Jouni Malinen772299f2017-11-06 00:36:26 +0200473 { "MissingAttribute", "AuthenticationRequest", "RespBSKeyHash", 10 },
474 { "MissingAttribute", "AuthenticationRequest", "InitBSKeyHash", 11 },
475 { "MissingAttribute", "AuthenticationRequest", "InitProtocolKey", 12 },
476 { "MissingAttribute", "AuthenticationRequest", "InitNonce", 13 },
477 { "MissingAttribute", "AuthenticationRequest", "InitCapabilities", 14 },
478 { "MissingAttribute", "AuthenticationRequest", "WrappedData", 15 },
479 { "MissingAttribute", "AuthenticationResponse", "DPPStatus", 16 },
480 { "MissingAttribute", "AuthenticationResponse", "RespBSKeyHash", 17 },
481 { "MissingAttribute", "AuthenticationResponse", "InitBSKeyHash", 18 },
482 { "MissingAttribute", "AuthenticationResponse", "RespProtocolKey", 19 },
483 { "MissingAttribute", "AuthenticationResponse", "RespNonce", 20 },
484 { "MissingAttribute", "AuthenticationResponse", "InitNonce", 21 },
485 { "MissingAttribute", "AuthenticationResponse", "RespCapabilities",
486 22 },
487 { "MissingAttribute", "AuthenticationResponse", "RespAuthTag", 23 },
488 { "MissingAttribute", "AuthenticationResponse", "WrappedData", 24 },
Jouni Malinenf96fcee2017-11-22 16:08:35 +0200489 { "MissingAttribute", "AuthenticationResponse", "PrimaryWrappedData",
490 24 },
Jouni Malinen772299f2017-11-06 00:36:26 +0200491 { "MissingAttribute", "AuthenticationConfirm", "DPPStatus", 25 },
492 { "MissingAttribute", "AuthenticationConfirm", "RespBSKeyHash", 26 },
493 { "MissingAttribute", "AuthenticationConfirm", "InitBSKeyHash", 27 },
494 { "MissingAttribute", "AuthenticationConfirm", "InitAuthTag", 28 },
495 { "MissingAttribute", "AuthenticationConfirm", "WrappedData", 29 },
496 { "InvalidValue", "AuthenticationResponse", "InitNonce", 30 },
497 { "InvalidValue", "AuthenticationResponse", "RespCapabilities", 31 },
498 { "InvalidValue", "AuthenticationResponse", "RespAuthTag", 32 },
499 { "InvalidValue", "AuthenticationConfirm", "InitAuthTag", 33 },
500 { "MissingAttribute", "PKEXExchangeRequest", "FiniteCyclicGroup", 34 },
501 { "MissingAttribute", "PKEXExchangeRequest", "EncryptedKey", 35 },
502 { "MissingAttribute", "PKEXExchangeResponse", "DPPStatus", 36 },
503 { "MissingAttribute", "PKEXExchangeResponse", "EncryptedKey", 37 },
504 { "MissingAttribute", "PKEXCRRequest", "BSKey", 38 },
505 { "MissingAttribute", "PKEXCRRequest", "InitAuthTag", 39 },
506 { "MissingAttribute", "PKEXCRRequest", "WrappedData", 40 },
507 { "MissingAttribute", "PKEXCRResponse", "BSKey", 41 },
508 { "MissingAttribute", "PKEXCRResponse", "RespAuthTag", 42 },
509 { "MissingAttribute", "PKEXCRResponse", "WrappedData", 43 },
510 { "InvalidValue", "PKEXExchangeRequest", "EncryptedKey", 44 },
511 { "InvalidValue", "PKEXExchangeResponse", "EncryptedKey", 45 },
512 { "InvalidValue", "PKEXExchangeResponse", "DPPStatus", 46 },
513 { "InvalidValue", "PKEXCRRequest", "BSKey", 47 },
514 { "InvalidValue", "PKEXCRResponse", "BSKey", 48 },
515 { "InvalidValue", "PKEXCRRequest", "InitAuthTag", 49 },
516 { "InvalidValue", "PKEXCRResponse", "RespAuthTag", 50 },
517 { "MissingAttribute", "ConfigurationRequest", "EnrolleeNonce", 51 },
518 { "MissingAttribute", "ConfigurationRequest", "ConfigAttr", 52 },
519 { "MissingAttribute", "ConfigurationRequest", "WrappedData", 53 },
520 { "MissingAttribute", "ConfigurationResponse", "EnrolleeNonce", 54 },
521 { "MissingAttribute", "ConfigurationResponse", "ConfigObj", 55 },
522 { "MissingAttribute", "ConfigurationResponse", "DPPStatus", 56 },
523 { "MissingAttribute", "ConfigurationResponse", "WrappedData", 57 },
524 { "InvalidValue", "ConfigurationResponse", "DPPStatus", 58 },
525 { "InvalidValue", "ConfigurationResponse", "EnrolleeNonce", 59 },
Jouni Malinen53558e02017-11-06 12:58:28 +0200526 { "MissingAttribute", "PeerDiscoveryRequest", "TransactionID", 60 },
527 { "MissingAttribute", "PeerDiscoveryRequest", "Connector", 61 },
528 { "MissingAttribute", "PeerDiscoveryResponse", "TransactionID", 62 },
529 { "MissingAttribute", "PeerDiscoveryResponse", "DPPStatus", 63 },
530 { "MissingAttribute", "PeerDiscoveryResponse", "Connector", 64 },
Jouni Malinenae624482017-11-19 00:13:51 +0200531 { "InvalidValue", "AuthenticationRequest", "InitProtocolKey", 66 },
532 { "InvalidValue", "AuthenticationResponse", "RespProtocolKey", 67 },
533 { "InvalidValue", "AuthenticationRequest", "RespBSKeyHash", 68 },
534 { "InvalidValue", "AuthenticationRequest", "InitBSKeyHash", 69 },
535 { "InvalidValue", "AuthenticationResponse", "RespBSKeyHash", 70 },
536 { "InvalidValue", "AuthenticationResponse", "InitBSKeyHash", 71 },
537 { "InvalidValue", "AuthenticationConfirm", "RespBSKeyHash", 72 },
538 { "InvalidValue", "AuthenticationConfirm", "InitBSKeyHash", 73 },
539 { "InvalidValue", "AuthenticationResponse", "DPPStatus", 74 },
540 { "InvalidValue", "AuthenticationConfirm", "DPPStatus", 75 },
541 { "InvalidValue", "ConfigurationRequest", "ConfigAttr", 76 },
542 { "InvalidValue", "PeerDiscoveryResponse", "TransactionID", 77 },
543 { "InvalidValue", "PeerDiscoveryResponse", "DPPStatus", 78 },
544 { "InvalidValue", "PeerDiscoveryResponse", "Connector", 79 },
545 { "InvalidValue", "PeerDiscoveryRequest", "Connector", 80 },
Jouni Malinen67795a72017-11-22 16:24:43 +0200546 { "InvalidValue", "AuthenticationRequest", "InitNonce", 81 },
Jouni Malinen188839b2017-11-30 22:02:02 +0200547 { "InvalidValue", "PeerDiscoveryRequest", "TransactionID", 82 },
548 { "InvalidValue", "ConfigurationRequest", "EnrolleeNonce", 83 },
Jouni Malinen3a6b92a2017-12-05 20:22:43 +0200549 { "Timeout", "PKEXExchangeResponse", NULL, 84 },
550 { "Timeout", "PKEXCRRequest", NULL, 85 },
551 { "Timeout", "PKEXCRResponse", NULL, 86 },
552 { "Timeout", "AuthenticationRequest", NULL, 87 },
553 { "Timeout", "AuthenticationResponse", NULL, 88 },
554 { "Timeout", "AuthenticationConfirm", NULL, 89 },
555 { "Timeout", "ConfigurationRequest", NULL, 90 },
Jouni Malinen772299f2017-11-06 00:36:26 +0200556 { NULL, NULL, NULL, 0 }
557};
558
559
560static int dpp_get_test(const char *step, const char *frame, const char *attr)
561{
562 int i;
563
564 for (i = 0; dpp_tests[i].step; i++) {
565 if (strcasecmp(step, dpp_tests[i].step) == 0 &&
566 strcasecmp(frame, dpp_tests[i].frame) == 0 &&
Jouni Malinen3a6b92a2017-12-05 20:22:43 +0200567 ((!attr && dpp_tests[i].attr == NULL) ||
568 (attr && strcasecmp(attr, dpp_tests[i].attr) == 0)))
Jouni Malinen772299f2017-11-06 00:36:26 +0200569 return dpp_tests[i].value;
570 }
571
572 return -1;
573}
574
575
Jouni Malinen6792ff42018-02-13 00:25:56 +0200576static int dpp_wait_tx(struct sigma_dut *dut, struct wpa_ctrl *ctrl,
577 int frame_type)
578{
579 char buf[200], tmp[20];
580 int res;
581
582 snprintf(tmp, sizeof(tmp), "type=%d", frame_type);
583 for (;;) {
584 res = get_wpa_cli_event(dut, ctrl, "DPP-TX", buf, sizeof(buf));
585 if (res < 0)
586 return -1;
587 if (strstr(buf, tmp) != NULL)
588 break;
589 }
590
591 return 0;
592}
593
594
Jouni Malinen772299f2017-11-06 00:36:26 +0200595static int dpp_wait_tx_status(struct sigma_dut *dut, struct wpa_ctrl *ctrl,
596 int frame_type)
597{
598 char buf[200], tmp[20];
599 int res;
600
601 snprintf(tmp, sizeof(tmp), "type=%d", frame_type);
602 for (;;) {
603 res = get_wpa_cli_event(dut, ctrl, "DPP-TX", buf, sizeof(buf));
604 if (res < 0)
605 return -1;
606 if (strstr(buf, tmp) != NULL)
607 break;
608 }
609
610 res = get_wpa_cli_event(dut, ctrl, "DPP-TX-STATUS",
611 buf, sizeof(buf));
612 if (res < 0 || strstr(buf, "result=FAILED") != NULL)
613 return -1;
614
615 return 0;
616}
617
618
Jouni Malinen3a6b92a2017-12-05 20:22:43 +0200619static int dpp_wait_rx(struct sigma_dut *dut, struct wpa_ctrl *ctrl,
Jouni Malinen3e4344e2018-01-22 11:47:37 +0200620 int frame_type, unsigned int max_wait)
Jouni Malinen3a6b92a2017-12-05 20:22:43 +0200621{
622 char buf[200], tmp[20];
623 int res;
Jouni Malinen9a3415c2018-01-10 22:12:22 +0200624 unsigned int old_timeout;
625
626 old_timeout = dut->default_timeout;
627 if (max_wait > 0 && dut->default_timeout > max_wait)
628 dut->default_timeout = max_wait;
Jouni Malinen3a6b92a2017-12-05 20:22:43 +0200629
630 snprintf(tmp, sizeof(tmp), "type=%d", frame_type);
631 for (;;) {
632 res = get_wpa_cli_event(dut, ctrl, "DPP-RX", buf, sizeof(buf));
Jouni Malinen9a3415c2018-01-10 22:12:22 +0200633 if (res < 0) {
634 dut->default_timeout = old_timeout;
Jouni Malinen3a6b92a2017-12-05 20:22:43 +0200635 return -1;
Jouni Malinen9a3415c2018-01-10 22:12:22 +0200636 }
Jouni Malinen3a6b92a2017-12-05 20:22:43 +0200637 if (strstr(buf, tmp) != NULL)
638 break;
639 }
640
Jouni Malinen9a3415c2018-01-10 22:12:22 +0200641 dut->default_timeout = old_timeout;
642 return 0;
643}
644
645
646static int dpp_wait_rx_conf_req(struct sigma_dut *dut, struct wpa_ctrl *ctrl,
Jouni Malinen3e4344e2018-01-22 11:47:37 +0200647 unsigned int max_wait)
Jouni Malinen9a3415c2018-01-10 22:12:22 +0200648{
649 char buf[200];
650 int res;
651 unsigned int old_timeout;
652
653 old_timeout = dut->default_timeout;
654 if (max_wait > 0 && dut->default_timeout > max_wait)
655 dut->default_timeout = max_wait;
656
657 for (;;) {
658 res = get_wpa_cli_event(dut, ctrl, "DPP-CONF-REQ-RX",
659 buf, sizeof(buf));
660 if (res < 0) {
661 dut->default_timeout = old_timeout;
662 return -1;
663 }
664
665 break;
666 }
667
668 dut->default_timeout = old_timeout;
Jouni Malinen3a6b92a2017-12-05 20:22:43 +0200669 return 0;
670}
671
672
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530673static int dpp_scan_peer_qrcode(struct sigma_dut *dut)
Jouni Malinend86e5822017-08-29 03:55:32 +0300674{
Jouni Malinen1a38cc32018-01-05 20:59:00 +0200675#ifdef ANDROID
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530676 char buf[100];
677 char *buf2 = NULL;
678 FILE *fp = NULL;
679 uint32_t length;
680 unsigned int count;
681
682 unlink(dpp_qrcode_file);
683
684 snprintf(buf, sizeof(buf),
Jouni Malinen07458342018-02-22 19:23:40 +0200685 "am start -n w1.fi.wpadebug/w1.fi.wpadebug.QrCodeReadActivity");
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530686 if (system(buf) != 0) {
Jouni Malinen07458342018-02-22 19:23:40 +0200687 sigma_dut_print(dut, DUT_MSG_ERROR,
688 "Failed to launch QR Code scanner");
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530689 return -1;
690 }
691
692 count = 0;
693 while (!(fp = fopen(dpp_qrcode_file, "r"))) {
694 if (count > dut->default_timeout) {
695 sigma_dut_print(dut, DUT_MSG_ERROR,
696 "Failed to open dpp_qrcode_file - QR Code scanning timed out");
697 return -1;
698 }
699
700 sleep(1);
701 count++;
702 }
703
704 if (fseek(fp, 0, SEEK_END) < 0 || (length = ftell(fp)) <= 0 ||
705 fseek(fp, 0, SEEK_SET) < 0) {
706 sigma_dut_print(dut, DUT_MSG_ERROR,
707 "Failed to get QR Code result file length");
708 fclose(fp);
709 return -1;
710 }
711
712 buf2 = malloc(length + 1);
713 if (!buf2) {
714 fclose(fp);
715 return -1;
716 }
717
718 if (fread(buf2, 1, length, fp) != length) {
719 fclose(fp);
720 free(buf2);
721 return -1;
722 }
723
724 fclose(fp);
725 buf2[length] = '\0';
726
727 free(dut->dpp_peer_uri);
728 dut->dpp_peer_uri = strdup(buf2);
729 free(buf2);
730 return 0;
Jouni Malinen1a38cc32018-01-05 20:59:00 +0200731#else /* ANDROID */
732 pid_t pid;
733 int pid_status;
734 int pipe_out[2];
735 char buf[4000], *pos;
736 ssize_t len;
737 int res = -1, ret;
738 struct timeval tv;
739 fd_set rfd;
740
741 if (pipe(pipe_out) != 0) {
742 perror("pipe");
743 return -1;
744 }
745
746 pid = fork();
747 if (pid < 0) {
748 perror("fork");
749 close(pipe_out[0]);
750 close(pipe_out[1]);
751 return -1;
752 }
753
754 if (pid == 0) {
755 char *argv[4] = { "zbarcam", "--raw", "--prescale=320x240",
756 NULL };
757
758 dup2(pipe_out[1], STDOUT_FILENO);
759 close(pipe_out[0]);
760 close(pipe_out[1]);
761 execv("/usr/bin/zbarcam", argv);
762 perror("execv");
763 exit(0);
764 return -1;
765 }
766
767 close(pipe_out[1]);
768
769 FD_ZERO(&rfd);
770 FD_SET(pipe_out[0], &rfd);
771 tv.tv_sec = dut->default_timeout;
772 tv.tv_usec = 0;
773
774 ret = select(pipe_out[0] + 1, &rfd, NULL, NULL, &tv);
775 if (ret < 0) {
776 perror("select");
777 goto out;
778 }
779 if (ret == 0) {
780 sigma_dut_print(dut, DUT_MSG_DEBUG,
781 "QR Code scanning timed out");
782 goto out;
783 }
784
785 len = read(pipe_out[0], buf, sizeof(buf));
786 if (len <= 0)
787 goto out;
788 if (len == sizeof(buf))
789 len--;
790 buf[len] = '\0';
791 pos = strchr(buf, '\n');
792 if (pos)
793 *pos = '\0';
794 sigma_dut_print(dut, DUT_MSG_DEBUG, "URI from QR scanner: %s", buf);
795
796 free(dut->dpp_peer_uri);
797 dut->dpp_peer_uri = strdup(buf);
798 res = 0;
799out:
800 close(pipe_out[0]);
801 kill(pid, SIGTERM);
802 waitpid(pid, &pid_status, 0);
803
804 return res;
805#endif /* ANDROID */
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530806}
807
808
809static int dpp_display_own_qrcode(struct sigma_dut *dut)
810{
811 char buf[200], resp[2000];
Jouni Malinen016ae6c2019-11-04 17:00:01 +0200812 const char *ifname = get_station_ifname(dut);
Jouni Malinen1a38cc32018-01-05 20:59:00 +0200813#ifdef ANDROID
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530814 FILE *fp;
Jouni Malinen1a38cc32018-01-05 20:59:00 +0200815#else /* ANDROID */
816 pid_t pid;
817 int pid_status;
818#endif /* ANDROID */
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530819
820 snprintf(buf, sizeof(buf), "DPP_BOOTSTRAP_GET_URI %d",
821 dut->dpp_local_bootstrap);
822 if (wpa_command_resp(ifname, buf, resp, sizeof(resp)) < 0 ||
823 strncmp(resp, "FAIL", 4) == 0)
824 return -2;
Jouni Malinen1a38cc32018-01-05 20:59:00 +0200825 sigma_dut_print(dut, DUT_MSG_DEBUG, "Own bootstrap URI: %s", resp);
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530826
Jouni Malinen1a38cc32018-01-05 20:59:00 +0200827#ifdef ANDROID
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530828 unlink(dpp_qrcode_file);
829
830 fp = fopen(dpp_qrcode_file, "w");
831 if (!fp) {
832 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open file %s",
833 dpp_qrcode_file);
834 return -2;
835 }
836
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530837 fwrite(resp, 1, strlen(resp), fp);
838 fclose(fp);
839
840 snprintf(buf, sizeof(buf),
841 "am start -n w1.fi.wpadebug/w1.fi.wpadebug.QrCodeDisplayActivity");
842 if (system(buf) != 0) {
843 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to display QR Code");
844 return -1;
845 }
Jouni Malinen1a38cc32018-01-05 20:59:00 +0200846#else /* ANDROID */
847 pid = fork();
848 if (pid < 0) {
849 perror("fork");
850 return -1;
851 }
852
853 if (pid == 0) {
854 char *argv[3] = { "qr", resp, NULL };
855
856 execv("/usr/bin/qr", argv);
857 perror("execv");
858 exit(0);
859 return -1;
860 }
861
862 waitpid(pid, &pid_status, 0);
863#endif /* ANDROID */
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530864
865 return 0;
Jouni Malinend86e5822017-08-29 03:55:32 +0300866}
867
868
Srinivas Dasari8d88d822018-03-26 17:57:34 +0530869static int dpp_process_auth_response(struct sigma_dut *dut,
870 struct sigma_conn *conn,
871 struct wpa_ctrl *ctrl,
872 const char **auth_events,
873 const char *action_type,
874 int check_mutual, char *buf, size_t buflen)
875{
876 int res;
877
878 res = get_wpa_cli_events(dut, ctrl, auth_events, buf, buflen);
879 if (res < 0) {
880 send_resp(dut, conn, SIGMA_COMPLETE,
881 "BootstrapResult,OK,AuthResult,Timeout");
882 return res;
883 }
884 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP auth result: %s", buf);
885
886 if (strstr(buf, "DPP-RESPONSE-PENDING")) {
887 /* Display own QR code in manual mode */
888 if (action_type && strcasecmp(action_type, "ManualDPP") == 0 &&
889 dpp_display_own_qrcode(dut) < 0) {
890 send_resp(dut, conn, SIGMA_ERROR,
891 "errorCode,Failed to display own QR code");
892 return -1;
893 }
894
895 /* Wait for the actual result after the peer has scanned the
896 * QR Code. */
897 res = get_wpa_cli_events(dut, ctrl, auth_events,
898 buf, buflen);
899 if (res < 0) {
900 send_resp(dut, conn, SIGMA_COMPLETE,
901 "BootstrapResult,OK,AuthResult,Timeout");
902 return res;
903 }
904
905 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP auth result: %s", buf);
906 }
907
908 if (check_mutual) {
909 if (strstr(buf, "DPP-NOT-COMPATIBLE")) {
910 send_resp(dut, conn, SIGMA_COMPLETE,
911 "BootstrapResult,OK,AuthResult,ROLES_NOT_COMPATIBLE");
912 return -1;
913 }
914
915 if (!strstr(buf, "DPP-AUTH-DIRECTION")) {
916 send_resp(dut, conn, SIGMA_ERROR,
917 "errorCode,No event for auth direction seen");
918 return -1;
919 }
920
921 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP auth direction: %s",
922 buf);
923 if (strstr(buf, "mutual=1") == NULL) {
924 send_resp(dut, conn, SIGMA_ERROR,
925 "errorCode,Peer did not use mutual authentication");
926 return -1;
927 }
928 }
929
930 return 0;
931}
932
933
Jouni Malinend86e5822017-08-29 03:55:32 +0300934static int dpp_automatic_dpp(struct sigma_dut *dut,
935 struct sigma_conn *conn,
936 struct sigma_cmd *cmd)
937{
938 const char *bs = get_param(cmd, "DPPBS");
939 const char *auth_role = get_param(cmd, "DPPAuthRole");
940 const char *prov_role = get_param(cmd, "DPPProvisioningRole");
941 const char *pkex_code = get_param(cmd, "DPPPKEXCode");
942 const char *pkex_code_id = get_param(cmd, "DPPPKEXCodeIdentifier");
943 const char *wait_conn = get_param(cmd, "DPPWaitForConnect");
944 const char *self_conf = get_param(cmd, "DPPSelfConfigure");
Jouni Malinen772299f2017-11-06 00:36:26 +0200945 const char *step = get_param(cmd, "DPPStep");
946 const char *frametype = get_param(cmd, "DPPFrameType");
947 const char *attr = get_param(cmd, "DPPIEAttribute");
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530948 const char *action_type = get_param(cmd, "DPPActionType");
Jouni Malinen785afb42019-10-11 13:07:56 +0300949 const char *tcp = get_param(cmd, "DPPOverTCP");
Jouni Malinenf37fda02020-04-03 14:12:37 +0300950 const char *nfc_handover = get_param(cmd, "DPPNFCHandover");
Jouni Malinend86e5822017-08-29 03:55:32 +0300951 const char *role;
Jouni Malinena28608a2020-02-06 04:20:37 +0200952 const char *netrole = NULL;
Jouni Malinend86e5822017-08-29 03:55:32 +0300953 const char *val;
954 const char *conf_role;
Jouni Malinend86e5822017-08-29 03:55:32 +0300955 int conf_index = -1;
Jouni Malinen3d16ccb2020-04-03 16:00:29 +0300956 char buf[2000], *pos, *pos2;
Jouni Malinendd85cff2019-09-27 01:22:45 +0300957 char buf2[200];
Jouni Malinend86e5822017-08-29 03:55:32 +0300958 char conf_ssid[100];
959 char conf_pass[100];
960 char pkex_identifier[200];
961 struct wpa_ctrl *ctrl;
962 int res;
963 unsigned int old_timeout;
964 int own_pkex_id = -1;
Jouni Malinen016ae6c2019-11-04 17:00:01 +0200965 const char *ifname = get_station_ifname(dut);
Jouni Malinend86e5822017-08-29 03:55:32 +0300966 const char *auth_events[] = {
967 "DPP-AUTH-SUCCESS",
968 "DPP-NOT-COMPATIBLE",
969 "DPP-RESPONSE-PENDING",
970 "DPP-SCAN-PEER-QR-CODE",
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530971 "DPP-AUTH-DIRECTION",
Jouni Malinend86e5822017-08-29 03:55:32 +0300972 NULL
973 };
974 const char *conf_events[] = {
975 "DPP-CONF-RECEIVED",
976 "DPP-CONF-SENT",
977 "DPP-CONF-FAILED",
978 NULL
979 };
980 const char *conn_events[] = {
981 "PMKSA-CACHE-ADDED",
982 "CTRL-EVENT-CONNECTED",
983 NULL
984 };
Purushottam Kushwaha11ab72c2018-08-10 12:40:30 +0530985 const char *group_id_str = NULL;
986 char group_id[100];
Jouni Malinendd85cff2019-09-27 01:22:45 +0300987 char conf2[300];
Jouni Malinen772299f2017-11-06 00:36:26 +0200988 const char *result;
Jouni Malinend1e22f72017-12-05 21:12:17 +0200989 int check_mutual = 0;
Jouni Malinene89cdbf2017-12-11 20:18:24 +0200990 int enrollee_ap;
Jouni Malinena28608a2020-02-06 04:20:37 +0200991 int enrollee_configurator;
Jouni Malinenf2fa0d02018-01-11 20:51:31 +0200992 int force_gas_fragm = 0;
Jouni Malinen85a5a2e2018-04-10 21:40:18 +0300993 int not_dpp_akm = 0;
Jouni Malinen7a7ecf72019-09-27 02:28:46 +0300994 int akm_use_selector = 0;
Jouni Malinen9be22ed2019-10-04 17:02:53 +0300995 int conn_status;
Jouni Malinend86e5822017-08-29 03:55:32 +0300996
997 if (!wait_conn)
998 wait_conn = "no";
999 if (!self_conf)
1000 self_conf = "no";
1001
1002 if (!auth_role) {
1003 send_resp(dut, conn, SIGMA_ERROR,
1004 "errorCode,Missing DPPAuthRole");
1005 return 0;
1006 }
1007
1008 if (!prov_role) {
1009 send_resp(dut, conn, SIGMA_ERROR,
1010 "errorCode,Missing DPPProvisioningRole");
1011 return 0;
1012 }
1013
Jouni Malinene89cdbf2017-12-11 20:18:24 +02001014 val = get_param(cmd, "DPPConfEnrolleeRole");
Jouni Malinena28608a2020-02-06 04:20:37 +02001015 if (val) {
Jouni Malinene89cdbf2017-12-11 20:18:24 +02001016 enrollee_ap = strcasecmp(val, "AP") == 0;
Jouni Malinena28608a2020-02-06 04:20:37 +02001017 enrollee_configurator = strcasecmp(val, "Configurator") == 0;
1018 } else {
Jouni Malinene89cdbf2017-12-11 20:18:24 +02001019 enrollee_ap = sigma_dut_is_ap(dut);
Jouni Malinena28608a2020-02-06 04:20:37 +02001020 enrollee_configurator = 0;
1021 }
1022
1023 val = get_param(cmd, "DPPNetworkRole");
1024 if (val) {
1025 if (strcasecmp(val, "AP") == 0) {
1026 netrole = "ap";
1027 } else if (strcasecmp(val, "STA") == 0) {
1028 netrole = "sta";
1029 } else if (strcasecmp(val, "Configurator") == 0) {
1030 netrole = "configurator";
1031 } else {
1032 send_resp(dut, conn, SIGMA_ERROR,
1033 "errorCode,Unsupported DPPNetworkRole value");
1034 return 0;
1035 }
1036 }
Jouni Malinene89cdbf2017-12-11 20:18:24 +02001037
Jouni Malinen3a6b92a2017-12-05 20:22:43 +02001038 if ((step || frametype) && (!step || !frametype)) {
Jouni Malinen772299f2017-11-06 00:36:26 +02001039 send_resp(dut, conn, SIGMA_ERROR,
1040 "errorCode,Invalid DPPStep,DPPFrameType,DPPIEAttribute combination");
1041 return 0;
1042 }
1043
Jouni Malinend86e5822017-08-29 03:55:32 +03001044 if (sigma_dut_is_ap(dut)) {
1045 if (!dut->hostapd_ifname) {
1046 sigma_dut_print(dut, DUT_MSG_ERROR,
1047 "hostapd ifname not specified (-j)");
1048 return -2;
1049 }
1050 ifname = dut->hostapd_ifname;
1051
1052 if (dpp_hostapd_run(dut) < 0) {
1053 send_resp(dut, conn, SIGMA_ERROR,
1054 "errorCode,Failed to start hostapd");
1055 return 0;
1056 }
1057 }
1058
Jouni Malinen67acb0c2017-11-21 01:01:54 +02001059 if (strcasecmp(prov_role, "Configurator") == 0 ||
1060 strcasecmp(prov_role, "Both") == 0) {
Jouni Malinend86e5822017-08-29 03:55:32 +03001061 if (dut->dpp_conf_id < 0) {
1062 snprintf(buf, sizeof(buf),
1063 "DPP_CONFIGURATOR_ADD curve=%s",
1064 dpp_get_curve(cmd, "DPPSigningKeyECC"));
1065 if (wpa_command_resp(ifname, buf,
1066 buf, sizeof(buf)) < 0) {
1067 send_resp(dut, conn, SIGMA_ERROR,
1068 "errorCode,Failed to set up configurator");
1069 return 0;
1070 }
1071 dut->dpp_conf_id = atoi(buf);
1072 }
Jouni Malinen67acb0c2017-11-21 01:01:54 +02001073 if (strcasecmp(prov_role, "Configurator") == 0)
1074 role = "configurator";
1075 else
1076 role = "either";
Jouni Malinend86e5822017-08-29 03:55:32 +03001077 } else if (strcasecmp(prov_role, "Enrollee") == 0) {
1078 role = "enrollee";
1079 } else {
1080 send_resp(dut, conn, SIGMA_ERROR,
1081 "errorCode,Unknown DPPProvisioningRole");
1082 return 0;
1083 }
1084
1085 pkex_identifier[0] = '\0';
1086 if (strcasecmp(bs, "PKEX") == 0) {
Jouni Malinen4f47a272017-11-04 12:29:11 +02001087 if (sigma_dut_is_ap(dut) && dut->ap_channel != 6) {
1088 /* For now, have to make operating channel match DPP
1089 * listen channel. This should be removed once hostapd
1090 * has support for DPP listen on non-operating channel.
1091 */
1092 sigma_dut_print(dut, DUT_MSG_INFO,
1093 "Update hostapd operating channel to match listen needs");
1094 dut->ap_channel = 6;
priyadharshini gowthamanb4de1962018-01-15 12:21:04 -08001095
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001096 if (get_driver_type(dut) == DRIVER_OPENWRT) {
priyadharshini gowthamanb4de1962018-01-15 12:21:04 -08001097 snprintf(buf, sizeof(buf),
1098 "iwconfig %s channel %d",
1099 dut->hostapd_ifname, dut->ap_channel);
1100 run_system(dut, buf);
1101 }
1102
Jouni Malinen4f47a272017-11-04 12:29:11 +02001103 if (wpa_command(ifname, "SET channel 6") < 0 ||
1104 wpa_command(ifname, "DISABLE") < 0 ||
1105 wpa_command(ifname, "ENABLE") < 0) {
1106 send_resp(dut, conn, SIGMA_ERROR,
1107 "errorCode,Failed to update channel");
1108 return 0;
1109 }
1110 }
1111
Jouni Malinend86e5822017-08-29 03:55:32 +03001112 if (!pkex_code) {
1113 send_resp(dut, conn, SIGMA_ERROR,
1114 "errorCode,Missing DPPPKEXCode");
1115 return 0;
1116 }
1117
1118 if (pkex_code_id)
1119 snprintf(pkex_identifier, sizeof(pkex_identifier),
1120 "identifier=%s ", pkex_code_id);
1121
1122 snprintf(buf, sizeof(buf),
1123 "DPP_BOOTSTRAP_GEN type=pkex curve=%s",
1124 dpp_get_curve(cmd, "DPPCryptoIdentifier"));
1125 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0) {
1126 send_resp(dut, conn, SIGMA_ERROR,
1127 "errorCode,Failed to set up PKEX");
1128 return 0;
1129 }
1130 own_pkex_id = atoi(buf);
1131 }
1132
1133 ctrl = open_wpa_mon(ifname);
1134 if (!ctrl) {
1135 sigma_dut_print(dut, DUT_MSG_ERROR,
1136 "Failed to open wpa_supplicant monitor connection");
1137 return -2;
1138 }
1139
1140 old_timeout = dut->default_timeout;
1141 val = get_param(cmd, "DPPTimeout");
1142 if (val && atoi(val) > 0) {
1143 dut->default_timeout = atoi(val);
1144 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP timeout: %u",
1145 dut->default_timeout);
1146 }
1147
Jouni Malinen9be22ed2019-10-04 17:02:53 +03001148 val = get_param(cmd, "DPPStatusQuery");
1149 conn_status = val && strcasecmp(val, "Yes") == 0;
1150
Jouni Malinend86e5822017-08-29 03:55:32 +03001151 conf_ssid[0] = '\0';
1152 conf_pass[0] = '\0';
Purushottam Kushwaha11ab72c2018-08-10 12:40:30 +05301153 group_id[0] = '\0';
Jouni Malinendd85cff2019-09-27 01:22:45 +03001154 conf2[0] = '\0';
Jouni Malinen05142202020-02-08 01:36:29 +02001155 if (!enrollee_configurator) {
1156 val = get_param(cmd, "DPPConfIndex");
1157 if (val)
1158 conf_index = atoi(val);
1159 }
Jouni Malinend86e5822017-08-29 03:55:32 +03001160 switch (conf_index) {
Jouni Malinen258cc262017-10-13 00:19:56 +03001161 case -1:
Jouni Malinena28608a2020-02-06 04:20:37 +02001162 if (enrollee_configurator)
1163 conf_role = "configurator";
1164 else
1165 conf_role = NULL;
Jouni Malinen258cc262017-10-13 00:19:56 +03001166 break;
Jouni Malinend86e5822017-08-29 03:55:32 +03001167 case 1:
1168 ascii2hexstr("DPPNET01", buf);
Jouni Malinen3aa72862019-05-29 23:14:51 +03001169 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
1170 if (res < 0 || res >= sizeof(conf_ssid))
1171 goto err;
Jouni Malinene89cdbf2017-12-11 20:18:24 +02001172 if (enrollee_ap) {
Jouni Malinend86e5822017-08-29 03:55:32 +03001173 conf_role = "ap-dpp";
Jouni Malinen3d291f72017-11-02 11:31:05 +02001174 } else {
Jouni Malinend86e5822017-08-29 03:55:32 +03001175 conf_role = "sta-dpp";
Jouni Malinen3d291f72017-11-02 11:31:05 +02001176 }
Purushottam Kushwaha11ab72c2018-08-10 12:40:30 +05301177 group_id_str = "DPPGROUP_DPP_INFRA";
Jouni Malinend86e5822017-08-29 03:55:32 +03001178 break;
1179 case 2:
1180 ascii2hexstr("DPPNET01", buf);
Jouni Malinen3aa72862019-05-29 23:14:51 +03001181 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
1182 if (res < 0 || res >= sizeof(conf_ssid))
1183 goto err;
Jouni Malinen8f81cdf2017-09-15 18:15:18 +03001184 snprintf(conf_pass, sizeof(conf_pass),
1185 "psk=10506e102ad1e7f95112f6b127675bb8344dacacea60403f3fa4055aec85b0fc");
Jouni Malinene89cdbf2017-12-11 20:18:24 +02001186 if (enrollee_ap)
Jouni Malinend86e5822017-08-29 03:55:32 +03001187 conf_role = "ap-psk";
1188 else
1189 conf_role = "sta-psk";
1190 break;
1191 case 3:
1192 ascii2hexstr("DPPNET01", buf);
Jouni Malinen3aa72862019-05-29 23:14:51 +03001193 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
1194 if (res < 0 || res >= sizeof(conf_ssid))
1195 goto err;
Jouni Malinend86e5822017-08-29 03:55:32 +03001196 ascii2hexstr("ThisIsDppPassphrase", buf);
Jouni Malinen3aa72862019-05-29 23:14:51 +03001197 res = snprintf(conf_pass, sizeof(conf_pass), "pass=%s", buf);
1198 if (res < 0 || res >= sizeof(conf_pass))
1199 goto err;
Jouni Malinene89cdbf2017-12-11 20:18:24 +02001200 if (enrollee_ap)
Jouni Malinend86e5822017-08-29 03:55:32 +03001201 conf_role = "ap-psk";
1202 else
1203 conf_role = "sta-psk";
1204 break;
Jouni Malinen3d291f72017-11-02 11:31:05 +02001205 case 4:
1206 ascii2hexstr("DPPNET01", buf);
Jouni Malinen3aa72862019-05-29 23:14:51 +03001207 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
1208 if (res < 0 || res >= sizeof(conf_ssid))
1209 goto err;
Jouni Malinene89cdbf2017-12-11 20:18:24 +02001210 if (enrollee_ap) {
Jouni Malinen3d291f72017-11-02 11:31:05 +02001211 conf_role = "ap-dpp";
Jouni Malinen3d291f72017-11-02 11:31:05 +02001212 } else {
1213 conf_role = "sta-dpp";
Jouni Malinen3d291f72017-11-02 11:31:05 +02001214 }
Purushottam Kushwaha11ab72c2018-08-10 12:40:30 +05301215 group_id_str = "DPPGROUP_DPP_INFRA2";
Jouni Malinen3d291f72017-11-02 11:31:05 +02001216 break;
Jouni Malinen7d031c72018-01-09 19:39:56 +02001217 case 5:
1218 ascii2hexstr("DPPNET01", buf);
Jouni Malinen3aa72862019-05-29 23:14:51 +03001219 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
1220 if (res < 0 || res >= sizeof(conf_ssid))
1221 goto err;
Jouni Malinen7d031c72018-01-09 19:39:56 +02001222 ascii2hexstr("ThisIsDppPassphrase", buf);
Jouni Malinen3aa72862019-05-29 23:14:51 +03001223 res = snprintf(conf_pass, sizeof(conf_pass), "pass=%s", buf);
1224 if (res < 0 || res >= sizeof(conf_pass))
1225 goto err;
Jouni Malinen7d031c72018-01-09 19:39:56 +02001226 if (enrollee_ap)
1227 conf_role = "ap-sae";
1228 else
1229 conf_role = "sta-sae";
1230 break;
1231 case 6:
1232 ascii2hexstr("DPPNET01", buf);
Jouni Malinen3aa72862019-05-29 23:14:51 +03001233 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
1234 if (res < 0 || res >= sizeof(conf_ssid))
1235 goto err;
Jouni Malinen7d031c72018-01-09 19:39:56 +02001236 ascii2hexstr("ThisIsDppPassphrase", buf);
Jouni Malinen3aa72862019-05-29 23:14:51 +03001237 res = snprintf(conf_pass, sizeof(conf_pass), "pass=%s", buf);
1238 if (res < 0 || res >= sizeof(conf_pass))
1239 goto err;
Jouni Malinen7d031c72018-01-09 19:39:56 +02001240 if (enrollee_ap)
1241 conf_role = "ap-psk-sae";
1242 else
1243 conf_role = "sta-psk-sae";
1244 break;
Jouni Malinenf2fa0d02018-01-11 20:51:31 +02001245 case 7:
1246 ascii2hexstr("DPPNET01", buf);
Jouni Malinen3aa72862019-05-29 23:14:51 +03001247 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
1248 if (res < 0 || res >= sizeof(conf_ssid))
1249 goto err;
Jouni Malinenf2fa0d02018-01-11 20:51:31 +02001250 if (enrollee_ap) {
1251 conf_role = "ap-dpp";
Jouni Malinenf2fa0d02018-01-11 20:51:31 +02001252 } else {
1253 conf_role = "sta-dpp";
Jouni Malinenf2fa0d02018-01-11 20:51:31 +02001254 }
Purushottam Kushwaha11ab72c2018-08-10 12:40:30 +05301255 group_id_str = "DPPGROUP_DPP_INFRA";
Jouni Malinenf2fa0d02018-01-11 20:51:31 +02001256 force_gas_fragm = 1;
1257 break;
Jouni Malinen0e3941c2019-06-11 01:03:40 +03001258 case 8:
Jouni Malinen7a7ecf72019-09-27 02:28:46 +03001259 case 9:
Jouni Malinen0e3941c2019-06-11 01:03:40 +03001260 ascii2hexstr("DPPNET01", buf);
1261 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
1262 if (res < 0 || res >= sizeof(conf_ssid))
1263 goto err;
1264 ascii2hexstr("This_is_legacy_password", buf);
1265 res = snprintf(conf_pass, sizeof(conf_pass), "pass=%s", buf);
1266 if (res < 0 || res >= sizeof(conf_pass))
1267 goto err;
1268 if (enrollee_ap) {
1269 conf_role = "ap-dpp+psk+sae";
1270 } else {
1271 conf_role = "sta-dpp+psk+sae";
1272 }
1273 group_id_str = "DPPGROUP_DPP_INFRA1";
Jouni Malinen7a7ecf72019-09-27 02:28:46 +03001274 if (conf_index == 9)
1275 akm_use_selector = 1;
Jouni Malinen0e3941c2019-06-11 01:03:40 +03001276 break;
Jouni Malinendd85cff2019-09-27 01:22:45 +03001277 case 10:
1278 ascii2hexstr("DPPNET01", buf);
1279 res = snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
1280 if (res < 0 || res >= sizeof(conf_ssid))
1281 goto err;
1282 if (enrollee_ap)
1283 conf_role = "ap-dpp";
1284 else
1285 conf_role = "sta-dpp";
1286 group_id_str = "DPPGROUP_DPP_INFRA1";
1287 ascii2hexstr("DPPNET02", buf);
1288 ascii2hexstr("This_is_legacy_password", buf2);
1289 res = snprintf(conf2, sizeof(conf2),
1290 " @CONF-OBJ-SEP@ conf=%s-dpp+psk+sae ssid=%s pass=%s group_id=DPPGROUP_DPP_INFRA2",
1291 enrollee_ap ? "ap" : "sta", buf, buf2);
Jouni Malinen7ee04b92019-10-04 16:15:50 +03001292 if (res < 0 || res >= sizeof(conf2))
1293 goto err;
Jouni Malinendd85cff2019-09-27 01:22:45 +03001294 break;
Jouni Malinenf7490762017-10-12 00:34:37 +03001295 default:
1296 send_resp(dut, conn, SIGMA_ERROR,
1297 "errorCode,Unsupported DPPConfIndex");
1298 goto out;
Jouni Malinend86e5822017-08-29 03:55:32 +03001299 }
1300
Purushottam Kushwaha11ab72c2018-08-10 12:40:30 +05301301 if (group_id_str)
1302 snprintf(group_id, sizeof(group_id), " group_id=%s",
1303 group_id_str);
Jouni Malinen3d291f72017-11-02 11:31:05 +02001304
Jouni Malinen2b2230f2018-02-12 13:05:06 +02001305 if (force_gas_fragm) {
1306 char spaces[1500];
1307
1308 memset(spaces, ' ', sizeof(spaces));
1309 spaces[sizeof(spaces) - 1] = '\0';
1310
1311 snprintf(buf, sizeof(buf),
1312 "SET dpp_discovery_override {\"ssid\":\"DPPNET01\"}%s",
1313 spaces);
1314 if (wpa_command(ifname, buf) < 0) {
1315 send_resp(dut, conn, SIGMA_ERROR,
1316 "errorCode,Failed to set discovery override");
1317 goto out;
1318 }
1319 }
1320
Jouni Malinen772299f2017-11-06 00:36:26 +02001321 if (step) {
1322 int test;
1323
1324 test = dpp_get_test(step, frametype, attr);
1325 if (test <= 0) {
1326 send_resp(dut, conn, SIGMA_ERROR,
1327 "errorCode,Unsupported DPPStep/DPPFrameType/DPPIEAttribute");
1328 goto out;
1329 }
1330
1331 snprintf(buf, sizeof(buf), "SET dpp_test %d", test);
1332 if (wpa_command(ifname, buf) < 0) {
1333 send_resp(dut, conn, SIGMA_ERROR,
1334 "errorCode,Failed to set dpp_test");
1335 goto out;
1336 }
1337 } else {
1338 wpa_command(ifname, "SET dpp_test 0");
1339 }
1340
Jouni Malinenfbb268d2017-11-17 18:53:49 +02001341 if (strcasecmp(self_conf, "Yes") == 0) {
1342 if (strcasecmp(prov_role, "Configurator") != 0) {
1343 send_resp(dut, conn, SIGMA_ERROR,
1344 "errorCode,Invalid DPPSelfConfigure use - only allowed for Configurator role");
1345 goto out;
1346 }
1347 if (!conf_role) {
1348 send_resp(dut, conn, SIGMA_ERROR,
1349 "errorCode,Missing DPPConfIndex");
1350 goto out;
1351 }
1352
1353 snprintf(buf, sizeof(buf),
1354 "DPP_CONFIGURATOR_SIGN conf=%s %s %s configurator=%d",
1355 conf_role, conf_ssid, conf_pass, dut->dpp_conf_id);
1356 if (wpa_command(ifname, buf) < 0) {
1357 send_resp(dut, conn, SIGMA_ERROR,
1358 "errorCode,Failed to initiate DPP self-configuration");
1359 goto out;
1360 }
Jouni Malinen174db642017-11-27 20:16:29 +02001361 if (sigma_dut_is_ap(dut))
1362 goto update_ap;
Jouni Malinenfbb268d2017-11-17 18:53:49 +02001363 goto wait_connect;
Jouni Malinenf37fda02020-04-03 14:12:37 +03001364 } else if ((nfc_handover &&
1365 strcasecmp(nfc_handover, "Negotiated_Requestor") == 0) ||
Jouni Malinena8330252020-04-03 16:12:52 +03001366 ((!nfc_handover ||
1367 strcasecmp(nfc_handover, "Static") == 0) &&
1368 strcasecmp(auth_role, "Initiator") == 0)) {
Jouni Malinend86e5822017-08-29 03:55:32 +03001369 char own_txt[20];
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02001370 int dpp_peer_bootstrap = -1;
Jouni Malinenb5ab8282017-11-21 01:12:22 +02001371 char neg_freq[30];
1372
Jouni Malinend1e22f72017-12-05 21:12:17 +02001373 val = get_param(cmd, "DPPAuthDirection");
1374 check_mutual = val && strcasecmp(val, "Mutual") == 0;
1375
Jouni Malinenb5ab8282017-11-21 01:12:22 +02001376 neg_freq[0] = '\0';
1377 val = get_param(cmd, "DPPSubsequentChannel");
1378 if (val) {
1379 int opclass, channel, freq;
1380
1381 opclass = atoi(val);
1382 val = strchr(val, '/');
1383 if (opclass == 0 || !val) {
1384 send_resp(dut, conn, SIGMA_ERROR,
1385 "errorCode,Invalid DPPSubsequentChannel");
1386 goto out;
1387 }
1388 val++;
1389 channel = atoi(val);
1390
1391 /* Ignoring opclass for now; could use it here for more
1392 * robust frequency determination. */
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02001393 freq = channel_to_freq(dut, channel);
Jouni Malinenb5ab8282017-11-21 01:12:22 +02001394 if (!freq) {
1395 send_resp(dut, conn, SIGMA_ERROR,
1396 "errorCode,Unsupported DPPSubsequentChannel channel");
1397 goto out;
1398 }
1399 snprintf(neg_freq, sizeof(neg_freq), " neg_freq=%d",
1400 freq);
1401 }
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02001402
1403 if (strcasecmp(bs, "QR") == 0) {
1404 if (!dut->dpp_peer_uri) {
1405 send_resp(dut, conn, SIGMA_ERROR,
1406 "errorCode,Missing peer bootstrapping info");
1407 goto out;
1408 }
1409
1410 snprintf(buf, sizeof(buf), "DPP_QR_CODE %s",
1411 dut->dpp_peer_uri);
1412 if (wpa_command_resp(ifname, buf, buf,
Jouni Malinen3c27aa82018-03-21 12:04:03 +02001413 sizeof(buf)) < 0 ||
1414 strncmp(buf, "FAIL", 4) == 0) {
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02001415 send_resp(dut, conn, SIGMA_ERROR,
1416 "errorCode,Failed to parse URI");
1417 goto out;
1418 }
1419 dpp_peer_bootstrap = atoi(buf);
Jouni Malinena8330252020-04-03 16:12:52 +03001420 } else if (strcasecmp(bs, "NFC") == 0 && nfc_handover &&
1421 strcasecmp(nfc_handover, "Static") == 0) {
1422 if (!dut->dpp_peer_uri) {
1423 send_resp(dut, conn, SIGMA_ERROR,
1424 "errorCode,Missing peer bootstrapping info");
1425 goto out;
1426 }
1427
1428 snprintf(buf, sizeof(buf), "DPP_NFC_URI %s",
1429 dut->dpp_peer_uri);
1430 if (wpa_command_resp(ifname, buf,
1431 buf, sizeof(buf)) < 0 ||
1432 strncmp(buf, "FAIL", 4) == 0) {
1433 send_resp(dut, conn, SIGMA_ERROR,
1434 "errorCode,Failed to process URI from NFC Tag");
1435 goto out;
1436 }
1437 dpp_peer_bootstrap = atoi(buf);
Jouni Malinenf37fda02020-04-03 14:12:37 +03001438 } else if (strcasecmp(bs, "NFC") == 0) {
1439 if (!dut->dpp_peer_uri) {
1440 send_resp(dut, conn, SIGMA_ERROR,
1441 "errorCode,Missing peer bootstrapping info");
1442 goto out;
1443 }
1444 if (dut->dpp_local_bootstrap < 0) {
1445 send_resp(dut, conn, SIGMA_ERROR,
1446 "errorCode,Missing own bootstrapping info");
1447 goto out;
1448 }
1449
1450 snprintf(buf, sizeof(buf),
1451 "DPP_NFC_HANDOVER_SEL own=%d uri=%s",
1452 dut->dpp_local_bootstrap, dut->dpp_peer_uri);
1453 if (wpa_command_resp(ifname, buf,
1454 buf, sizeof(buf)) < 0 ||
1455 strncmp(buf, "FAIL", 4) == 0) {
1456 send_resp(dut, conn, SIGMA_ERROR,
1457 "errorCode,Failed to process NFC Handover Select");
1458 goto out;
1459 }
1460 dpp_peer_bootstrap = atoi(buf);
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02001461 }
Jouni Malinend86e5822017-08-29 03:55:32 +03001462
Jouni Malinen63d50412017-11-24 11:55:38 +02001463 if (dut->dpp_local_bootstrap >= 0)
Jouni Malinend86e5822017-08-29 03:55:32 +03001464 snprintf(own_txt, sizeof(own_txt), " own=%d",
1465 dut->dpp_local_bootstrap);
1466 else
1467 own_txt[0] = '\0';
Jouni Malinenf37fda02020-04-03 14:12:37 +03001468 if ((strcasecmp(bs, "QR") == 0 || strcasecmp(bs, "NFC") == 0) &&
Jouni Malinen67acb0c2017-11-21 01:01:54 +02001469 (strcasecmp(prov_role, "Configurator") == 0 ||
1470 strcasecmp(prov_role, "Both") == 0)) {
Jouni Malinen258cc262017-10-13 00:19:56 +03001471 if (!conf_role) {
1472 send_resp(dut, conn, SIGMA_ERROR,
1473 "errorCode,Missing DPPConfIndex");
1474 goto out;
1475 }
Jouni Malinend86e5822017-08-29 03:55:32 +03001476 snprintf(buf, sizeof(buf),
Jouni Malinena28608a2020-02-06 04:20:37 +02001477 "DPP_AUTH_INIT peer=%d%s role=%s%s%s conf=%s %s %s configurator=%d%s%s%s%s%s",
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02001478 dpp_peer_bootstrap, own_txt, role,
Jouni Malinena28608a2020-02-06 04:20:37 +02001479 netrole ? " netrole=" : "",
1480 netrole ? netrole : "",
Jouni Malinend86e5822017-08-29 03:55:32 +03001481 conf_role, conf_ssid, conf_pass,
Jouni Malinen7a7ecf72019-09-27 02:28:46 +03001482 dut->dpp_conf_id, neg_freq, group_id,
1483 akm_use_selector ? " akm_use_selector=1" : "",
Jouni Malinen9be22ed2019-10-04 17:02:53 +03001484 conn_status ? " conn_status=1" : "",
Jouni Malinen7a7ecf72019-09-27 02:28:46 +03001485 conf2);
Jouni Malinenf37fda02020-04-03 14:12:37 +03001486 } else if (tcp && (strcasecmp(bs, "QR") == 0 ||
1487 strcasecmp(bs, "NFC") == 0)) {
Jouni Malinen1352f1e2019-10-11 13:27:10 +03001488 snprintf(buf, sizeof(buf),
Jouni Malinena28608a2020-02-06 04:20:37 +02001489 "DPP_AUTH_INIT peer=%d%s role=%s%s%s tcp_addr=%s%s%s",
1490 dpp_peer_bootstrap, own_txt, role,
1491 netrole ? " netrole=" : "",
1492 netrole ? netrole : "",
1493 tcp, neg_freq, group_id);
Jouni Malinenf37fda02020-04-03 14:12:37 +03001494 } else if (strcasecmp(bs, "QR") == 0 ||
1495 strcasecmp(bs, "NFC") == 0) {
Jouni Malinend86e5822017-08-29 03:55:32 +03001496 snprintf(buf, sizeof(buf),
Jouni Malinena28608a2020-02-06 04:20:37 +02001497 "DPP_AUTH_INIT peer=%d%s role=%s%s%s%s%s",
Purushottam Kushwaha11ab72c2018-08-10 12:40:30 +05301498 dpp_peer_bootstrap, own_txt, role,
Jouni Malinena28608a2020-02-06 04:20:37 +02001499 netrole ? " netrole=" : "",
1500 netrole ? netrole : "",
Purushottam Kushwaha11ab72c2018-08-10 12:40:30 +05301501 neg_freq, group_id);
Jouni Malinend86e5822017-08-29 03:55:32 +03001502 } else if (strcasecmp(bs, "PKEX") == 0 &&
Jouni Malinen67acb0c2017-11-21 01:01:54 +02001503 (strcasecmp(prov_role, "Configurator") == 0 ||
1504 strcasecmp(prov_role, "Both") == 0)) {
Jouni Malinen258cc262017-10-13 00:19:56 +03001505 if (!conf_role) {
1506 send_resp(dut, conn, SIGMA_ERROR,
1507 "errorCode,Missing DPPConfIndex");
1508 goto out;
1509 }
Jouni Malinend86e5822017-08-29 03:55:32 +03001510 snprintf(buf, sizeof(buf),
1511 "DPP_PKEX_ADD own=%d init=1 role=%s conf=%s %s %s configurator=%d %scode=%s",
1512 own_pkex_id, role, conf_role,
1513 conf_ssid, conf_pass, dut->dpp_conf_id,
1514 pkex_identifier, pkex_code);
1515 } else if (strcasecmp(bs, "PKEX") == 0) {
1516 snprintf(buf, sizeof(buf),
1517 "DPP_PKEX_ADD own=%d init=1 role=%s %scode=%s",
1518 own_pkex_id, role, pkex_identifier, pkex_code);
Jouni Malinend551c6f2017-10-12 00:32:18 +03001519 } else {
1520 send_resp(dut, conn, SIGMA_ERROR,
1521 "errorCode,Unsupported DPPBS");
1522 goto out;
Jouni Malinend86e5822017-08-29 03:55:32 +03001523 }
1524 if (wpa_command(ifname, buf) < 0) {
1525 send_resp(dut, conn, SIGMA_ERROR,
1526 "errorCode,Failed to initiate DPP authentication");
1527 goto out;
1528 }
Jouni Malinen3d16ccb2020-04-03 16:00:29 +03001529 } else if ((nfc_handover &&
1530 strcasecmp(nfc_handover, "Negotiated_Selector") == 0) ||
Jouni Malinen04054cc2020-04-03 16:21:14 +03001531 ((!nfc_handover ||
1532 strcasecmp(nfc_handover, "Static") == 0) &&
1533 strcasecmp(auth_role, "Responder") == 0)) {
Jouni Malinen67f096a2017-11-24 11:58:51 +02001534 const char *delay_qr_resp;
Jouni Malinen63d50412017-11-24 11:55:38 +02001535 int mutual;
Jouni Malinend3afc5c2017-11-13 18:39:14 +02001536 int freq = 2462; /* default: channel 11 */
1537
Jouni Malinenf8d81aa2019-09-27 03:39:40 +03001538 if (sigma_dut_is_ap(dut) && dut->hostapd_running &&
1539 dut->ap_oper_chn)
1540 freq = channel_to_freq(dut, dut->ap_channel);
1541
Jouni Malinen06cfcb32018-01-11 20:43:50 +02001542 if (strcasecmp(bs, "PKEX") == 0) {
1543 /* default: channel 6 for PKEX */
1544 freq = 2437;
1545 }
1546
Jouni Malinen67f096a2017-11-24 11:58:51 +02001547 delay_qr_resp = get_param(cmd, "DPPDelayQRResponse");
1548
Jouni Malinen63d50412017-11-24 11:55:38 +02001549 val = get_param(cmd, "DPPAuthDirection");
1550 mutual = val && strcasecmp(val, "Mutual") == 0;
1551
Jouni Malinend3afc5c2017-11-13 18:39:14 +02001552 val = get_param(cmd, "DPPListenChannel");
1553 if (val) {
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02001554 freq = channel_to_freq(dut, atoi(val));
Jouni Malinend3afc5c2017-11-13 18:39:14 +02001555 if (freq == 0) {
1556 send_resp(dut, conn, SIGMA_ERROR,
1557 "errorCode,Unsupported DPPListenChannel value");
1558 goto out;
1559 }
1560 }
Jouni Malinend86e5822017-08-29 03:55:32 +03001561
Jouni Malinen04054cc2020-04-03 16:21:14 +03001562 if (strcasecmp(bs, "NFC") == 0 && nfc_handover &&
1563 strcasecmp(nfc_handover, "Static") == 0) {
1564 /* No steps needed here - waiting for peer to initiate
1565 * once it reads the URI from the NFC Tag */
1566 } else if (strcasecmp(bs, "NFC") == 0) {
Jouni Malinen3d16ccb2020-04-03 16:00:29 +03001567 if (!dut->dpp_peer_uri) {
1568 send_resp(dut, conn, SIGMA_ERROR,
1569 "errorCode,Missing peer bootstrapping info");
1570 goto out;
1571 }
1572 if (dut->dpp_local_bootstrap < 0) {
1573 send_resp(dut, conn, SIGMA_ERROR,
1574 "errorCode,Missing own bootstrapping info");
1575 goto out;
1576 }
1577
1578 snprintf(buf, sizeof(buf),
1579 "DPP_NFC_HANDOVER_REQ own=%d uri=%s",
1580 dut->dpp_local_bootstrap, dut->dpp_peer_uri);
1581 if (wpa_command(ifname, buf) < 0) {
1582 send_resp(dut, conn, SIGMA_ERROR,
1583 "errorCode,Failed to process NFC Handover Request");
1584 goto out;
1585 }
1586
1587 snprintf(buf, sizeof(buf), "DPP_BOOTSTRAP_INFO %d",
1588 dut->dpp_local_bootstrap);
1589 if (wpa_command_resp(ifname, buf,
1590 buf, sizeof(buf)) < 0 ||
1591 strncmp(buf, "FAIL", 4) == 0) {
1592 send_resp(dut, conn, SIGMA_ERROR,
1593 "errorCode,Failed to get bootstrap information");
1594 goto out;
1595 }
1596 pos = buf;
1597 while (pos) {
1598 pos2 = strchr(pos, '\n');
1599 if (pos2)
1600 *pos2 = '\0';
1601 if (strncmp(pos, "use_freq=", 9) == 0) {
1602 freq = atoi(pos + 9);
1603 sigma_dut_print(dut, DUT_MSG_DEBUG,
1604 "DPP negotiation frequency from NFC handover: %d MHz",
1605 freq);
1606 break;
1607 }
1608
1609 if (!pos2)
1610 break;
1611 pos = pos2 + 1;
1612 }
1613 } else if (!delay_qr_resp && dut->dpp_peer_uri) {
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02001614 snprintf(buf, sizeof(buf), "DPP_QR_CODE %s",
1615 dut->dpp_peer_uri);
1616 if (wpa_command_resp(ifname, buf, buf,
1617 sizeof(buf)) < 0) {
1618 send_resp(dut, conn, SIGMA_ERROR,
1619 "errorCode,Failed to parse URI");
1620 goto out;
1621 }
1622 }
1623
Jouni Malinend86e5822017-08-29 03:55:32 +03001624 if (strcasecmp(prov_role, "Configurator") == 0) {
Jouni Malinen258cc262017-10-13 00:19:56 +03001625 if (!conf_role) {
1626 send_resp(dut, conn, SIGMA_ERROR,
1627 "errorCode,Missing DPPConfIndex");
1628 goto out;
1629 }
Jouni Malinend86e5822017-08-29 03:55:32 +03001630 snprintf(buf, sizeof(buf),
Jouni Malinen9be22ed2019-10-04 17:02:53 +03001631 "SET dpp_configurator_params conf=%s %s %s configurator=%d%s%s%s%s",
Jouni Malinend86e5822017-08-29 03:55:32 +03001632 conf_role, conf_ssid, conf_pass,
Jouni Malinen7a7ecf72019-09-27 02:28:46 +03001633 dut->dpp_conf_id, group_id,
1634 akm_use_selector ? " akm_use_selector=1" : "",
Jouni Malinen9be22ed2019-10-04 17:02:53 +03001635 conn_status ? " conn_status=1" : "",
Jouni Malinen7a7ecf72019-09-27 02:28:46 +03001636 conf2);
Jouni Malinend86e5822017-08-29 03:55:32 +03001637 if (wpa_command(ifname, buf) < 0) {
1638 send_resp(dut, conn, SIGMA_ERROR,
1639 "errorCode,Failed to set configurator parameters");
1640 goto out;
1641 }
1642 }
1643 if (strcasecmp(bs, "PKEX") == 0) {
Jouni Malinend86e5822017-08-29 03:55:32 +03001644 snprintf(buf, sizeof(buf),
1645 "DPP_PKEX_ADD own=%d role=%s %scode=%s",
1646 own_pkex_id, role, pkex_identifier, pkex_code);
1647 if (wpa_command(ifname, buf) < 0) {
1648 send_resp(dut, conn, SIGMA_ERROR,
1649 "errorCode,Failed to configure DPP PKEX");
1650 goto out;
1651 }
1652 }
1653
Jouni Malinen785afb42019-10-11 13:07:56 +03001654 if (tcp && strcasecmp(tcp, "yes") == 0) {
1655 snprintf(buf, sizeof(buf), "DPP_CONTROLLER_START");
1656 } else {
Jouni Malinena28608a2020-02-06 04:20:37 +02001657 snprintf(buf, sizeof(buf),
1658 "DPP_LISTEN %d role=%s%s%s%s",
Jouni Malinen785afb42019-10-11 13:07:56 +03001659 freq, role,
1660 (strcasecmp(bs, "QR") == 0 && mutual) ?
Jouni Malinena28608a2020-02-06 04:20:37 +02001661 " qr=mutual" : "",
1662 netrole ? " netrole=" : "",
1663 netrole ? netrole : "");
Jouni Malinen785afb42019-10-11 13:07:56 +03001664 }
Jouni Malinenbafc1932017-11-04 11:31:16 +02001665 if (wpa_command(ifname, buf) < 0) {
1666 send_resp(dut, conn, SIGMA_ERROR,
1667 "errorCode,Failed to start DPP listen");
1668 goto out;
Jouni Malinend86e5822017-08-29 03:55:32 +03001669 }
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02001670
Jouni Malinen785afb42019-10-11 13:07:56 +03001671 if (!(tcp && strcasecmp(tcp, "yes") == 0) &&
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001672 get_driver_type(dut) == DRIVER_OPENWRT) {
priyadharshini gowthamanb4de1962018-01-15 12:21:04 -08001673 snprintf(buf, sizeof(buf), "iwconfig %s channel %d",
1674 dut->hostapd_ifname, freq_to_channel(freq));
1675 run_system(dut, buf);
1676 }
1677
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02001678 if (delay_qr_resp && mutual && dut->dpp_peer_uri) {
1679 int wait_time = atoi(delay_qr_resp);
1680
1681 res = get_wpa_cli_events(dut, ctrl, auth_events,
1682 buf, sizeof(buf));
1683 if (res < 0) {
1684 send_resp(dut, conn, SIGMA_COMPLETE,
1685 "BootstrapResult,OK,AuthResult,Timeout");
1686 goto out;
1687 }
1688 sigma_dut_print(dut, DUT_MSG_DEBUG,
1689 "DPP auth result: %s", buf);
1690 if (strstr(buf, "DPP-SCAN-PEER-QR-CODE") == NULL) {
1691 send_resp(dut, conn, SIGMA_ERROR,
1692 "errorCode,No scan request for peer QR Code seen");
1693 goto out;
1694 }
1695 sigma_dut_print(dut, DUT_MSG_INFO,
1696 "Waiting %d second(s) before processing peer URI",
1697 wait_time);
1698 sleep(wait_time);
1699
1700 snprintf(buf, sizeof(buf), "DPP_QR_CODE %s",
1701 dut->dpp_peer_uri);
1702 if (wpa_command_resp(ifname, buf, buf,
1703 sizeof(buf)) < 0) {
1704 send_resp(dut, conn, SIGMA_ERROR,
1705 "errorCode,Failed to parse URI");
1706 goto out;
1707 }
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05301708 } else if (mutual && action_type &&
1709 strcasecmp(action_type, "ManualDPP") == 0) {
1710 res = get_wpa_cli_events(dut, ctrl, auth_events,
1711 buf, sizeof(buf));
1712 if (res < 0) {
1713 send_resp(dut, conn, SIGMA_COMPLETE,
1714 "BootstrapResult,OK,AuthResult,Timeout");
1715 goto out;
1716 }
1717 sigma_dut_print(dut, DUT_MSG_DEBUG,
1718 "DPP auth result: %s", buf);
Srinivas Dasarie3b13932018-03-26 21:51:40 +05301719 if (strstr(buf, "DPP-NOT-COMPATIBLE")) {
1720 send_resp(dut, conn, SIGMA_COMPLETE,
1721 "BootstrapResult,OK,AuthResult,ROLES_NOT_COMPATIBLE");
1722 goto out;
1723 }
1724
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05301725 if (strstr(buf, "DPP-SCAN-PEER-QR-CODE") == NULL) {
1726 send_resp(dut, conn, SIGMA_ERROR,
1727 "errorCode,No scan request for peer QR Code seen");
1728 goto out;
1729 }
1730
1731 if (dpp_scan_peer_qrcode(dut) < 0) {
1732 send_resp(dut, conn, SIGMA_ERROR,
1733 "errorCode,Failed to scan peer QR Code");
1734 goto out;
1735 }
1736
1737 snprintf(buf, sizeof(buf), "DPP_QR_CODE %s",
1738 dut->dpp_peer_uri);
1739 if (wpa_command_resp(ifname, buf, buf,
1740 sizeof(buf)) < 0) {
1741 send_resp(dut, conn, SIGMA_ERROR,
1742 "errorCode,Failed to parse URI");
1743 goto out;
1744 }
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02001745 }
Jouni Malinend86e5822017-08-29 03:55:32 +03001746 } else {
1747 send_resp(dut, conn, SIGMA_ERROR,
1748 "errorCode,Unknown DPPAuthRole");
1749 goto out;
1750 }
1751
Jouni Malinen3a6b92a2017-12-05 20:22:43 +02001752 if (step && strcasecmp(step, "Timeout") == 0) {
1753 result = "errorCode,Unexpected state";
1754
1755 if (strcasecmp(frametype, "PKEXExchangeResponse") == 0) {
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001756 if (dpp_wait_rx(dut, ctrl, 8, -1) < 0)
Jouni Malinen3a6b92a2017-12-05 20:22:43 +02001757 result = "BootstrapResult,Timeout";
1758 else
1759 result = "BootstrapResult,Errorsent";
1760 }
1761
1762 if (strcasecmp(frametype, "PKEXCRRequest") == 0) {
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001763 if (dpp_wait_rx(dut, ctrl, 9, -1) < 0)
Jouni Malinen3a6b92a2017-12-05 20:22:43 +02001764 result = "BootstrapResult,Timeout";
1765 else
1766 result = "BootstrapResult,Errorsent";
1767 }
1768
1769 if (strcasecmp(frametype, "PKEXCRResponse") == 0) {
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001770 if (dpp_wait_rx(dut, ctrl, 10, -1) < 0)
Jouni Malinen3a6b92a2017-12-05 20:22:43 +02001771 result = "BootstrapResult,Timeout";
1772 else
1773 result = "BootstrapResult,Errorsent";
1774 }
1775
1776 if (strcasecmp(frametype, "AuthenticationRequest") == 0) {
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001777 if (dpp_wait_rx(dut, ctrl, 0, -1) < 0)
Jouni Malinen3a6b92a2017-12-05 20:22:43 +02001778 result = "BootstrapResult,OK,AuthResult,Timeout";
1779 else
1780 result = "BootstrapResult,OK,AuthResult,Errorsent";
1781 }
1782
1783 if (strcasecmp(frametype, "AuthenticationResponse") == 0) {
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001784 if (dpp_wait_rx(dut, ctrl, 1, -1) < 0)
Jouni Malinen3a6b92a2017-12-05 20:22:43 +02001785 result = "BootstrapResult,OK,AuthResult,Timeout";
1786 else
1787 result = "BootstrapResult,OK,AuthResult,Errorsent";
1788 }
1789
1790 if (strcasecmp(frametype, "AuthenticationConfirm") == 0) {
Deepak Dhamdhereecb49d82018-03-08 16:48:28 -08001791 if (strcasecmp(auth_role, "Initiator") == 0) {
Jouni Malinena1199882018-03-28 19:34:59 +03001792 /* This special case of DPPStep,Timeout with
1793 * DPPFrameType,AuthenticationConfirm on an
1794 * Initiator is used to cover need for stopping
1795 * the Initiator/Enrollee from sending out
1796 * Configuration Request message. */
1797 if (strcasecmp(prov_role, "Enrollee") != 0) {
1798 send_resp(dut, conn, SIGMA_ERROR,
1799 "errorCode,Unexpected use of timeout after AuthenticationConfirm TX in Configurator role");
1800 goto out;
1801 }
Srinivas Dasari671c9e12018-03-26 17:57:34 +05301802 if (check_mutual &&
1803 dpp_process_auth_response(
1804 dut, conn, ctrl, auth_events,
1805 action_type, check_mutual,
1806 buf, sizeof(buf)) < 0)
1807 goto out;
Deepak Dhamdhereecb49d82018-03-08 16:48:28 -08001808 if (dpp_wait_tx_status(dut, ctrl, 2) < 0)
1809 result = "BootstrapResult,OK,AuthResult,Timeout";
Deepak Dhamdhereecb49d82018-03-08 16:48:28 -08001810 else
Jouni Malinena1199882018-03-28 19:34:59 +03001811 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationResponse";
Deepak Dhamdhereecb49d82018-03-08 16:48:28 -08001812 } else {
1813 if (dpp_wait_rx(dut, ctrl, 2, -1) < 0)
1814 result = "BootstrapResult,OK,AuthResult,Timeout";
1815 else
1816 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationConfirm";
1817 }
Jouni Malinen3a6b92a2017-12-05 20:22:43 +02001818 }
1819
1820 if (strcasecmp(frametype, "ConfigurationRequest") == 0) {
1821 if (get_wpa_cli_event(dut, ctrl, "DPP-CONF-FAILED",
1822 buf, sizeof(buf)) < 0)
1823 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Timeout";
1824 else
1825 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Errorsent";
1826 }
1827
1828 send_resp(dut, conn, SIGMA_COMPLETE, result);
1829 goto out;
1830 }
1831
Jouni Malinen772299f2017-11-06 00:36:26 +02001832 if (frametype && strcasecmp(frametype, "PKEXExchangeRequest") == 0) {
1833 if (dpp_wait_tx_status(dut, ctrl, 7) < 0)
1834 result = "BootstrapResult,Timeout";
1835 else
1836 result = "BootstrapResult,Errorsent";
1837 send_resp(dut, conn, SIGMA_COMPLETE, result);
1838 goto out;
1839 }
1840
1841 if (frametype && strcasecmp(frametype, "PKEXExchangeResponse") == 0) {
1842 if (dpp_wait_tx_status(dut, ctrl, 8) < 0)
1843 result = "BootstrapResult,Timeout";
1844 else
1845 result = "BootstrapResult,Errorsent";
1846 send_resp(dut, conn, SIGMA_COMPLETE, result);
1847 goto out;
1848 }
1849
1850 if (frametype && strcasecmp(frametype, "PKEXCRRequest") == 0) {
1851 if (dpp_wait_tx_status(dut, ctrl, 9) < 0)
1852 result = "BootstrapResult,Timeout";
1853 else
1854 result = "BootstrapResult,Errorsent";
1855 send_resp(dut, conn, SIGMA_COMPLETE, result);
1856 goto out;
1857 }
1858
1859 if (frametype && strcasecmp(frametype, "PKEXCRResponse") == 0) {
1860 if (dpp_wait_tx_status(dut, ctrl, 10) < 0)
1861 result = "BootstrapResult,Timeout";
1862 else
1863 result = "BootstrapResult,Errorsent";
1864 send_resp(dut, conn, SIGMA_COMPLETE, result);
1865 goto out;
1866 }
1867
Jouni Malinen6792ff42018-02-13 00:25:56 +02001868 if (!frametype && strcasecmp(bs, "PKEX") == 0 &&
1869 strcasecmp(auth_role, "Responder") == 0) {
1870 if (dpp_wait_tx_status(dut, ctrl, 10) < 0) {
1871 send_resp(dut, conn, SIGMA_COMPLETE,
1872 "BootstrapResult,Timeout");
1873 goto out;
1874 }
1875 }
1876
1877 if (!frametype && strcasecmp(bs, "PKEX") == 0 &&
1878 strcasecmp(auth_role, "Initiator") == 0) {
1879 if (dpp_wait_tx(dut, ctrl, 0) < 0) {
1880 send_resp(dut, conn, SIGMA_COMPLETE,
1881 "BootstrapResult,Timeout");
1882 goto out;
1883 }
1884 }
1885
Jouni Malinen772299f2017-11-06 00:36:26 +02001886 if (frametype && strcasecmp(frametype, "AuthenticationRequest") == 0) {
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001887 if (dpp_wait_tx_status(dut, ctrl, 0) < 0) {
1888 send_resp(dut, conn, SIGMA_COMPLETE,
1889 "BootstrapResult,OK,AuthResult,Timeout");
1890 goto out;
1891 }
1892
1893 if (dpp_wait_rx(dut, ctrl, 1, 5) < 0)
1894 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,None";
Deepak Dhamdhereb9f1eb92018-03-08 16:36:22 -08001895 else if (get_wpa_cli_events(dut, ctrl, auth_events,
1896 buf, sizeof(buf)) >= 0 &&
1897 strstr(buf, "DPP-RESPONSE-PENDING") != NULL)
1898 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationResponseWithStatusPending";
Jouni Malinen772299f2017-11-06 00:36:26 +02001899 else
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001900 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationResponse";
Jouni Malinen772299f2017-11-06 00:36:26 +02001901 send_resp(dut, conn, SIGMA_COMPLETE, result);
1902 goto out;
1903 }
1904
1905 if (frametype && strcasecmp(frametype, "AuthenticationResponse") == 0) {
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001906 if (dpp_wait_tx_status(dut, ctrl, 1) < 0) {
1907 send_resp(dut, conn, SIGMA_COMPLETE,
1908 "BootstrapResult,OK,AuthResult,Timeout");
1909 goto out;
1910 }
1911
1912 if (dpp_wait_rx(dut, ctrl, 2, 5) < 0)
1913 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationRequest";
Jouni Malinen772299f2017-11-06 00:36:26 +02001914 else
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001915 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationConfirm";
Jouni Malinen772299f2017-11-06 00:36:26 +02001916 send_resp(dut, conn, SIGMA_COMPLETE, result);
1917 goto out;
1918 }
1919
Srinivas Dasari8d88d822018-03-26 17:57:34 +05301920 if (dpp_process_auth_response(dut, conn, ctrl, auth_events, action_type,
1921 check_mutual, buf, sizeof(buf)) < 0)
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05301922 goto out;
Jouni Malinend1e22f72017-12-05 21:12:17 +02001923
Jouni Malinen772299f2017-11-06 00:36:26 +02001924 if (frametype && strcasecmp(frametype, "AuthenticationConfirm") == 0) {
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001925 if (dpp_wait_tx_status(dut, ctrl, 2) < 0) {
1926 send_resp(dut, conn, SIGMA_COMPLETE,
1927 "BootstrapResult,OK,AuthResult,Timeout");
1928 goto out;
1929 }
1930
1931 if (dpp_wait_rx_conf_req(dut, ctrl, 5) < 0)
1932 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationResponse";
Jouni Malinen772299f2017-11-06 00:36:26 +02001933 else
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001934 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,ConfigurationRequest";
Jouni Malinen772299f2017-11-06 00:36:26 +02001935 send_resp(dut, conn, SIGMA_COMPLETE, result);
1936 goto out;
1937 }
1938
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05301939 if (strstr(buf, "DPP-AUTH-DIRECTION")) {
Jouni Malinen2e9c8a42017-11-19 12:06:18 +02001940 res = get_wpa_cli_events(dut, ctrl, auth_events,
1941 buf, sizeof(buf));
1942 if (res < 0) {
1943 send_resp(dut, conn, SIGMA_COMPLETE,
1944 "BootstrapResult,OK,AuthResult,Timeout");
1945 goto out;
1946 }
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05301947
1948 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP auth result: %s", buf);
Jouni Malinen2e9c8a42017-11-19 12:06:18 +02001949 }
1950
Jouni Malinend86e5822017-08-29 03:55:32 +03001951 if (strstr(buf, "DPP-NOT-COMPATIBLE")) {
1952 send_resp(dut, conn, SIGMA_COMPLETE,
1953 "BootstrapResult,OK,AuthResult,ROLES_NOT_COMPATIBLE");
1954 goto out;
1955 }
1956
1957 if (!strstr(buf, "DPP-AUTH-SUCCESS")) {
1958 send_resp(dut, conn, SIGMA_COMPLETE,
1959 "BootstrapResult,OK,AuthResult,FAILED");
1960 goto out;
1961 }
1962
Jouni Malinen772299f2017-11-06 00:36:26 +02001963 if (frametype && strcasecmp(frametype, "ConfigurationRequest") == 0) {
1964 res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE",
1965 buf, sizeof(buf));
1966 if (res < 0)
1967 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Timeout";
1968 else
1969 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Errorsent";
1970 send_resp(dut, conn, SIGMA_COMPLETE, result);
1971 goto out;
1972 }
1973
1974 if (frametype && strcasecmp(frametype, "ConfigurationResponse") == 0) {
Jouni Malinena97b7452019-03-14 20:48:16 +02001975 res = get_wpa_cli_events(dut, ctrl, conf_events,
1976 buf, sizeof(buf));
Jouni Malinen772299f2017-11-06 00:36:26 +02001977 if (res < 0)
1978 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Timeout";
1979 else
Deepak Dhamdhere9b4f2752018-03-08 16:36:22 -08001980 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Errorsent,LastFrameReceived,ConfigurationRequest";
Jouni Malinen772299f2017-11-06 00:36:26 +02001981 send_resp(dut, conn, SIGMA_COMPLETE, result);
1982 goto out;
1983 }
1984
Jouni Malinend86e5822017-08-29 03:55:32 +03001985 res = get_wpa_cli_events(dut, ctrl, conf_events, buf, sizeof(buf));
1986 if (res < 0) {
1987 send_resp(dut, conn, SIGMA_COMPLETE,
1988 "BootstrapResult,OK,AuthResult,OK,ConfResult,Timeout");
1989 goto out;
1990 }
1991 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP conf result: %s", buf);
1992
1993 if (!strstr(buf, "DPP-CONF-SENT") &&
1994 !strstr(buf, "DPP-CONF-RECEIVED")) {
1995 send_resp(dut, conn, SIGMA_COMPLETE,
1996 "BootstrapResult,OK,AuthResult,OK,ConfResult,FAILED");
1997 goto out;
1998 }
1999
Jouni Malinen9be22ed2019-10-04 17:02:53 +03002000 if (conn_status && strstr(buf, "DPP-CONF-SENT") &&
2001 strstr(buf, "wait_conn_status=1")) {
2002 res = get_wpa_cli_event(dut, ctrl, "DPP-CONN-STATUS-RESULT",
2003 buf, sizeof(buf));
2004 if (res < 0) {
2005 send_resp(dut, conn, SIGMA_COMPLETE,
2006 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,StatusResult,Timeout");
2007 } else {
2008 pos = strstr(buf, "result=");
2009 if (!pos) {
2010 send_resp(dut, conn, SIGMA_ERROR,
2011 "errorCode,Status result value not reported");
2012 } else {
2013 pos += 7;
2014 snprintf(buf, sizeof(buf),
2015 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,StatusResult,%d",
2016 atoi(pos));
2017 send_resp(dut, conn, SIGMA_COMPLETE, buf);
2018 }
2019 }
2020 goto out;
2021 }
2022
Jouni Malinena28608a2020-02-06 04:20:37 +02002023 if (strcasecmp(prov_role, "Enrollee") == 0 && netrole &&
2024 strcmp(netrole, "configurator") == 0) {
2025 res = get_wpa_cli_event(dut, ctrl, "DPP-CONFIGURATOR-ID",
2026 buf, sizeof(buf));
2027 if (res < 0) {
2028 send_resp(dut, conn, SIGMA_ERROR,
2029 "errorCode,No DPP-CONFIGURATOR-ID");
2030 goto out;
2031 }
2032 pos = strchr(buf, ' ');
2033 if (!pos) {
2034 send_resp(dut, conn, SIGMA_ERROR,
2035 "errorCode,Invalid DPP-CONFIGURATOR-ID");
2036 goto out;
2037 }
2038 pos++;
2039 dut->dpp_conf_id = atoi(pos);
2040 } else if (sigma_dut_is_ap(dut) &&
2041 strcasecmp(prov_role, "Enrollee") == 0) {
Jouni Malinen174db642017-11-27 20:16:29 +02002042 update_ap:
Jouni Malinend86e5822017-08-29 03:55:32 +03002043 res = dpp_hostapd_conf_update(dut, conn, ifname, ctrl);
2044 if (res == 0)
2045 goto out;
2046 if (res < 0) {
2047 send_resp(dut, conn, SIGMA_ERROR, NULL);
2048 goto out;
2049 }
2050 }
2051
2052 if (strcasecmp(wait_conn, "Yes") == 0 &&
2053 !sigma_dut_is_ap(dut) &&
2054 strcasecmp(prov_role, "Enrollee") == 0) {
Jouni Malinen85a5a2e2018-04-10 21:40:18 +03002055 int netw_id;
2056 char *pos;
2057
2058 res = get_wpa_cli_event(dut, ctrl, "DPP-NETWORK-ID",
2059 buf, sizeof(buf));
2060 if (res < 0) {
2061 send_resp(dut, conn, SIGMA_ERROR,
2062 "errorCode,No DPP-NETWORK-ID");
2063 goto out;
2064 }
2065 pos = strchr(buf, ' ');
2066 if (!pos) {
2067 send_resp(dut, conn, SIGMA_ERROR,
2068 "errorCode,Invalid DPP-NETWORK-ID");
2069 goto out;
2070 }
2071 pos++;
2072 netw_id = atoi(pos);
2073 snprintf(buf, sizeof(buf), "GET_NETWORK %d key_mgmt", netw_id);
2074 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0) {
2075 send_resp(dut, conn, SIGMA_ERROR,
2076 "errorCode,Could not fetch provisioned key_mgmt");
2077 goto out;
2078 }
2079 if (strncmp(buf, "SAE", 3) == 0) {
2080 /* SAE generates PMKSA-CACHE-ADDED event */
2081 not_dpp_akm = 1;
2082 }
Jouni Malinenfbb268d2017-11-17 18:53:49 +02002083 wait_connect:
Jouni Malinen53558e02017-11-06 12:58:28 +02002084 if (frametype && strcasecmp(frametype,
2085 "PeerDiscoveryRequest") == 0) {
2086 if (dpp_wait_tx_status(dut, ctrl, 5) < 0)
2087 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Timeout";
2088 else
2089 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Errorsent";
2090 send_resp(dut, conn, SIGMA_COMPLETE, result);
2091 goto out;
2092 }
2093
Jouni Malinend86e5822017-08-29 03:55:32 +03002094 res = get_wpa_cli_events(dut, ctrl, conn_events,
2095 buf, sizeof(buf));
2096 if (res < 0) {
2097 send_resp(dut, conn, SIGMA_COMPLETE,
2098 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Timeout,NetworkConnectResult,Timeout");
2099 goto out;
2100 }
2101 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP connect result: %s",
2102 buf);
2103
2104 if (strstr(buf, "PMKSA-CACHE-ADDED")) {
2105 res = get_wpa_cli_events(dut, ctrl, conn_events,
2106 buf, sizeof(buf));
2107 if (res < 0) {
2108 send_resp(dut, conn, SIGMA_COMPLETE,
Jouni Malinen85a5a2e2018-04-10 21:40:18 +03002109 not_dpp_akm ?
2110 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkConnectResult,Timeout" :
Jouni Malinend86e5822017-08-29 03:55:32 +03002111 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,Timeout");
2112 goto out;
2113 }
2114 sigma_dut_print(dut, DUT_MSG_DEBUG,
2115 "DPP connect result: %s", buf);
2116 if (strstr(buf, "CTRL-EVENT-CONNECTED"))
2117 send_resp(dut, conn, SIGMA_COMPLETE,
Jouni Malinen85a5a2e2018-04-10 21:40:18 +03002118 not_dpp_akm ?
2119 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkConnectResult,OK" :
Jouni Malinend86e5822017-08-29 03:55:32 +03002120 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,OK");
2121 else
2122 send_resp(dut, conn, SIGMA_COMPLETE,
Jouni Malinen85a5a2e2018-04-10 21:40:18 +03002123 not_dpp_akm ?
2124 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkConnectResult,Timeout" :
Jouni Malinend86e5822017-08-29 03:55:32 +03002125 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,Timeout");
2126 goto out;
2127 }
2128
2129 send_resp(dut, conn, SIGMA_COMPLETE,
2130 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkConnectResult,OK");
2131 goto out;
2132 }
2133
Jouni Malinen53558e02017-11-06 12:58:28 +02002134 if (strcasecmp(wait_conn, "Yes") == 0 &&
2135 frametype && strcasecmp(frametype, "PeerDiscoveryResponse") == 0) {
2136 if (dpp_wait_tx_status(dut, ctrl, 6) < 0)
2137 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Timeout";
2138 else
2139 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Errorsent";
2140 send_resp(dut, conn, SIGMA_COMPLETE, result);
2141 goto out;
2142 }
2143
Jouni Malinend86e5822017-08-29 03:55:32 +03002144 send_resp(dut, conn, SIGMA_COMPLETE,
2145 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK");
2146out:
2147 wpa_ctrl_detach(ctrl);
2148 wpa_ctrl_close(ctrl);
Jouni Malinen785afb42019-10-11 13:07:56 +03002149 if (tcp && strcasecmp(tcp, "yes") == 0 &&
2150 auth_role && strcasecmp(auth_role, "Responder") == 0)
2151 wpa_command(ifname, "DPP_CONTROLLER_STOP");
Jouni Malinend86e5822017-08-29 03:55:32 +03002152 dut->default_timeout = old_timeout;
2153 return 0;
Jouni Malinen3aa72862019-05-29 23:14:51 +03002154err:
2155 send_resp(dut, conn, SIGMA_ERROR, NULL);
2156 goto out;
Jouni Malinend86e5822017-08-29 03:55:32 +03002157}
2158
2159
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05302160static int dpp_manual_dpp(struct sigma_dut *dut,
2161 struct sigma_conn *conn,
2162 struct sigma_cmd *cmd)
2163{
2164 const char *auth_role = get_param(cmd, "DPPAuthRole");
priyadharshini gowthaman2fa651b2018-04-16 17:02:47 -07002165 const char *self_conf = get_param(cmd, "DPPSelfConfigure");
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05302166 int res = -1, success;
2167 const char *val;
2168 unsigned int old_timeout;
2169
2170 if (!auth_role) {
2171 send_resp(dut, conn, SIGMA_ERROR,
2172 "errorCode,Missing DPPAuthRole");
2173 return 0;
2174 }
2175
priyadharshini gowthaman2fa651b2018-04-16 17:02:47 -07002176 if (!self_conf)
2177 self_conf = "no";
2178
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05302179 old_timeout = dut->default_timeout;
2180 val = get_param(cmd, "DPPTimeout");
2181 if (val && atoi(val) > 0) {
2182 dut->default_timeout = atoi(val);
2183 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP timeout: %u",
2184 dut->default_timeout);
2185 }
2186
2187 res = dpp_get_local_bootstrap(dut, conn, cmd, 0, &success);
2188 if (res || !success)
2189 goto out;
2190
2191 if (strcasecmp(auth_role, "Responder") == 0) {
2192 res = dpp_display_own_qrcode(dut);
2193 if (res < 0)
2194 goto out;
2195
2196 res = dpp_automatic_dpp(dut, conn, cmd);
2197 goto out;
2198 }
2199
2200 if (strcasecmp(auth_role, "Initiator") == 0) {
priyadharshini gowthaman2fa651b2018-04-16 17:02:47 -07002201 if (strcasecmp(self_conf, "Yes") != 0) {
2202 res = dpp_scan_peer_qrcode(dut);
2203 if (res < 0) {
2204 send_resp(dut, conn, SIGMA_ERROR,
2205 "errorCode,Failed to scan peer QR Code");
2206 res = 0;
2207 goto out;
2208 }
Jouni Malinen1a38cc32018-01-05 20:59:00 +02002209 }
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05302210
2211 res = dpp_automatic_dpp(dut, conn, cmd);
2212 goto out;
2213 }
2214
2215 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unknown DPPAuthRole");
2216 res = 0;
2217out:
2218 dut->default_timeout = old_timeout;
2219 return res;
2220}
2221
2222
Jouni Malinend86e5822017-08-29 03:55:32 +03002223int dpp_dev_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
2224 struct sigma_cmd *cmd)
2225{
2226 const char *type = get_param(cmd, "DPPActionType");
2227 const char *bs = get_param(cmd, "DPPBS");
2228
2229 if (!bs) {
2230 send_resp(dut, conn, SIGMA_ERROR,
2231 "errorCode,Missing DPPBS");
2232 return 0;
2233 }
2234
2235 if (!type) {
2236 send_resp(dut, conn, SIGMA_ERROR,
2237 "errorCode,Missing DPPActionType");
2238 return 0;
2239 }
2240
2241 if (strcasecmp(type, "GetLocalBootstrap") == 0)
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05302242 return dpp_get_local_bootstrap(dut, conn, cmd, 1, NULL);
Jouni Malinend86e5822017-08-29 03:55:32 +03002243 if (strcasecmp(type, "SetPeerBootstrap") == 0)
2244 return dpp_set_peer_bootstrap(dut, conn, cmd);
2245 if (strcasecmp(type, "ManualDPP") == 0)
2246 return dpp_manual_dpp(dut, conn, cmd);
2247 if (strcasecmp(type, "AutomaticDPP") == 0)
2248 return dpp_automatic_dpp(dut, conn, cmd);
2249
2250 send_resp(dut, conn, SIGMA_ERROR,
2251 "errorCode,Unsupported DPPActionType");
2252 return 0;
2253}