blob: 001e0b81614488219956f156a2eb8ab88dc36db8 [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 Malinend86e5822017-08-29 03:55:32 +030071 const char *ifname = get_station_ifname();
72
Srinivas Dasaribc9e0552018-01-04 19:24:28 +053073 if (success)
74 *success = 0;
Jouni Malinend86e5822017-08-29 03:55:32 +030075 if (strcasecmp(bs, "QR") != 0) {
76 send_resp(dut, conn, SIGMA_ERROR,
77 "errorCode,Unsupported DPPBS");
78 return 0;
79 }
80
81 if (sigma_dut_is_ap(dut)) {
82 u8 bssid[ETH_ALEN];
83
84 if (!dut->hostapd_ifname) {
85 sigma_dut_print(dut, DUT_MSG_ERROR,
86 "hostapd ifname not specified (-j)");
87 return -2;
88 }
89 ifname = dut->hostapd_ifname;
90 if (get_hwaddr(dut->hostapd_ifname, bssid) < 0) {
91 sigma_dut_print(dut, DUT_MSG_ERROR,
92 "Could not get MAC address for %s",
93 dut->hostapd_ifname);
94 return -2;
95 }
96 snprintf(mac, sizeof(mac), "%02x%02x%02x%02x%02x%02x",
97 bssid[0], bssid[1], bssid[2],
98 bssid[3], bssid[4], bssid[5]);
99 } else {
100 if (get_wpa_status(ifname, "address", mac, sizeof(mac)) < 0)
101 return -2;
102 }
103
104 pos = mac;
105 while (*pos) {
106 if (*pos == ':')
107 memmove(pos, pos + 1, strlen(pos));
108 else
109 pos++;
110 }
111
Jouni Malinend86e5822017-08-29 03:55:32 +0300112 if (sigma_dut_is_ap(dut) && dpp_hostapd_run(dut) < 0) {
113 send_resp(dut, conn, SIGMA_ERROR,
114 "errorCode,Failed to start hostapd");
115 return 0;
116 }
117
Jouni Malinen4161c3f2017-11-13 18:36:09 +0200118 if (chan_list &&
119 (strcmp(chan_list, "0/0") == 0 || chan_list[0] == '\0')) {
120 /* No channel list */
121 snprintf(buf, sizeof(buf),
122 "DPP_BOOTSTRAP_GEN type=qrcode curve=%s mac=%s",
123 curve, mac);
124 } else if (chan_list) {
125 /* Channel list override (CTT case) - space separated tuple(s)
126 * of OperatingClass/Channel; convert to wpa_supplicant/hostapd
127 * format: comma separated tuples */
128 strlcpy(resp, chan_list, sizeof(resp));
129 for (pos = resp; *pos; pos++) {
130 if (*pos == ' ')
131 *pos = ',';
132 }
133 snprintf(buf, sizeof(buf),
134 "DPP_BOOTSTRAP_GEN type=qrcode curve=%s chan=%s mac=%s",
135 curve, resp, mac);
136 } else {
137 /* Default channel list (normal DUT case) */
138 snprintf(buf, sizeof(buf),
139 "DPP_BOOTSTRAP_GEN type=qrcode curve=%s chan=81/11 mac=%s",
140 curve, mac);
141 }
142
Jouni Malinend86e5822017-08-29 03:55:32 +0300143 if (wpa_command_resp(ifname, buf, resp, sizeof(resp)) < 0)
144 return -2;
145 if (strncmp(resp, "FAIL", 4) == 0)
146 return -2;
147 dut->dpp_local_bootstrap = atoi(resp);
148 snprintf(buf, sizeof(buf), "DPP_BOOTSTRAP_GET_URI %d",
149 atoi(resp));
150 if (wpa_command_resp(ifname, buf, resp, sizeof(resp)) < 0)
151 return -2;
152 if (strncmp(resp, "FAIL", 4) == 0)
153 return -2;
154
155 sigma_dut_print(dut, DUT_MSG_DEBUG, "URI: %s", resp);
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530156
157 if (send_result) {
158 ascii2hexstr(resp, hex);
159 snprintf(resp, sizeof(resp), "BootstrappingData,%s", hex);
160 send_resp(dut, conn, SIGMA_COMPLETE, resp);
161 }
162
163 if (success)
164 *success = 1;
Jouni Malinend86e5822017-08-29 03:55:32 +0300165 return 0;
166}
167
168
169static int dpp_set_peer_bootstrap(struct sigma_dut *dut,
170 struct sigma_conn *conn,
171 struct sigma_cmd *cmd)
172{
173 const char *val = get_param(cmd, "DPPBootstrappingdata");
Jouni Malinenb1dd21f2017-11-13 19:14:29 +0200174 char uri[1000];
Jouni Malinend86e5822017-08-29 03:55:32 +0300175 int res;
Jouni Malinend86e5822017-08-29 03:55:32 +0300176
177 if (!val) {
178 send_resp(dut, conn, SIGMA_ERROR,
179 "errorCode,Missing DPPBootstrappingdata");
180 return 0;
181 }
182
183 res = parse_hexstr(val, (unsigned char *) uri, sizeof(uri));
184 if (res < 0 || (size_t) res >= sizeof(uri))
185 return -2;
186 uri[res] = '\0';
187 sigma_dut_print(dut, DUT_MSG_DEBUG, "URI: %s", uri);
Jouni Malinenb1dd21f2017-11-13 19:14:29 +0200188 free(dut->dpp_peer_uri);
189 dut->dpp_peer_uri = strdup(uri);
Jouni Malinend86e5822017-08-29 03:55:32 +0300190
191 return 1;
192}
193
194
195static int dpp_hostapd_conf_update(struct sigma_dut *dut,
196 struct sigma_conn *conn, const char *ifname,
197 struct wpa_ctrl *ctrl)
198{
199 int res;
200 char buf[2000], buf2[2500], *pos, *pos2;
Jouni Malinenb4c5e3b2017-09-15 17:43:20 +0300201 const char *conf_data_events[] = {
202 "DPP-CONNECTOR",
203 "DPP-CONFOBJ-PASS",
204 "DPP-CONFOBJ-PSK",
205 NULL
206 };
Jouni Malinend86e5822017-08-29 03:55:32 +0300207
208 sigma_dut_print(dut, DUT_MSG_INFO,
209 "Update hostapd configuration based on DPP Config Object");
210
211 if (wpa_command(ifname, "SET wpa 2") < 0 ||
212 wpa_command(ifname, "SET wpa_key_mgmt DPP") < 0 ||
Jouni Malinen0d347232017-11-01 17:14:00 +0200213 wpa_command(ifname, "SET ieee80211w 1") < 0 ||
Jouni Malinend86e5822017-08-29 03:55:32 +0300214 wpa_command(ifname, "SET rsn_pairwise CCMP") < 0) {
215 send_resp(dut, conn, SIGMA_ERROR,
216 "errorCode,Failed to update AP security parameters");
217 goto out;
218 }
219
220 res = get_wpa_cli_event(dut, ctrl, "DPP-CONFOBJ-SSID",
221 buf, sizeof(buf));
222 if (res < 0) {
223 send_resp(dut, conn, SIGMA_ERROR,
224 "errorCode,No DPP-CONFOBJ-SSID");
225 goto out;
226 }
227 pos = strchr(buf, ' ');
228 if (!pos)
229 return -2;
230 pos++;
231 sigma_dut_print(dut, DUT_MSG_INFO,
232 "DPP: Config Object SSID: %s", pos);
233 snprintf(buf2, sizeof(buf2), "SET ssid %s", pos);
234 if (wpa_command(ifname, buf2) < 0) {
235 send_resp(dut, conn, SIGMA_ERROR,
236 "errorCode,Failed to update AP SSID");
237 goto out;
238 }
239
Jouni Malinenb4c5e3b2017-09-15 17:43:20 +0300240 res = get_wpa_cli_events(dut, ctrl, conf_data_events, buf, sizeof(buf));
Jouni Malinend86e5822017-08-29 03:55:32 +0300241 if (res < 0) {
242 send_resp(dut, conn, SIGMA_ERROR,
Jouni Malinenb4c5e3b2017-09-15 17:43:20 +0300243 "errorCode,No DPP-CONNECTOR/DPP-CONFOBJ-PASS/PSK");
Jouni Malinend86e5822017-08-29 03:55:32 +0300244 goto out;
245 }
Jouni Malinenb4c5e3b2017-09-15 17:43:20 +0300246
247 if (!strstr(buf, "DPP-CONNECTOR")) {
248 if (wpa_command(ifname, "SET wpa_key_mgmt WPA-PSK") < 0) {
249 send_resp(dut, conn, SIGMA_ERROR,
250 "errorCode,Failed to update AP security parameters");
251 goto out;
252 }
253
254 pos = strchr(buf, ' ');
255 if (!pos)
256 return -2;
257 pos++;
258 if (strstr(buf, "DPP-CONFOBJ-PASS")) {
259 char pass[64];
260 int pass_len;
261
262 pass_len = parse_hexstr(pos, (u8 *) pass, sizeof(pass));
Jouni Malinenfddb7ea2018-01-05 21:02:50 +0200263 if (pass_len < 0 || (size_t) pass_len >= sizeof(pass))
Jouni Malinenb4c5e3b2017-09-15 17:43:20 +0300264 return -2;
265 pass[pass_len] = '\0';
266 sigma_dut_print(dut, DUT_MSG_INFO,
267 "DPP: Passphrase: %s", pass);
268 snprintf(buf2, sizeof(buf2), "SET wpa_passphrase %s",
269 pass);
270 if (wpa_command(ifname, buf2) < 0) {
271 send_resp(dut, conn, SIGMA_ERROR,
272 "errorCode,Failed to set passphrase");
273 goto out;
274 }
275 } else if (strstr(buf, "DPP-CONFOBJ-PSK")) {
276 sigma_dut_print(dut, DUT_MSG_INFO,
277 "DPP: PSK: %s", pos);
278 snprintf(buf2, sizeof(buf2), "SET wpa_psk %s", pos);
279 if (wpa_command(ifname, buf2) < 0) {
280 send_resp(dut, conn, SIGMA_ERROR,
281 "errorCode,Failed to set PSK");
282 goto out;
283 }
284 }
285
286 goto skip_dpp_akm;
287 }
288
Jouni Malinend86e5822017-08-29 03:55:32 +0300289 pos = strchr(buf, ' ');
290 if (!pos)
291 return -2;
292 pos++;
293 sigma_dut_print(dut, DUT_MSG_INFO, "DPP: Connector: %s", pos);
294 snprintf(buf2, sizeof(buf2), "SET dpp_connector %s", pos);
295 if (wpa_command(ifname, buf2) < 0) {
296 send_resp(dut, conn, SIGMA_ERROR,
297 "errorCode,Failed to update AP Connector");
298 goto out;
299 }
300
301 res = get_wpa_cli_event(dut, ctrl, "DPP-C-SIGN-KEY",
302 buf, sizeof(buf));
303 if (res < 0) {
304 send_resp(dut, conn, SIGMA_ERROR,
305 "errorCode,No DPP-C-SIGN-KEY");
306 goto out;
307 }
308 pos = strchr(buf, ' ');
309 if (!pos)
310 return -2;
311 pos++;
Jouni Malinend86e5822017-08-29 03:55:32 +0300312 sigma_dut_print(dut, DUT_MSG_INFO, "DPP: C-sign-key: %s", pos);
313 snprintf(buf2, sizeof(buf2), "SET dpp_csign %s", pos);
314 if (wpa_command(ifname, buf2) < 0) {
315 send_resp(dut, conn, SIGMA_ERROR,
316 "errorCode,Failed to update AP C-sign-key");
317 goto out;
318 }
Jouni Malinend86e5822017-08-29 03:55:32 +0300319
320 res = get_wpa_cli_event(dut, ctrl, "DPP-NET-ACCESS-KEY",
321 buf, sizeof(buf));
322 if (res < 0) {
323 send_resp(dut, conn, SIGMA_ERROR,
324 "errorCode,No DPP-NET-ACCESS-KEY");
325 goto out;
326 }
327 pos = strchr(buf, ' ');
328 if (!pos)
329 return -2;
330 pos++;
331 pos2 = strchr(pos, ' ');
332 if (pos2)
333 *pos2++ = '\0';
334 sigma_dut_print(dut, DUT_MSG_INFO, "DPP: netAccessKey: %s", pos);
335 snprintf(buf2, sizeof(buf2), "SET dpp_netaccesskey %s", pos);
336 if (wpa_command(ifname, buf2) < 0) {
337 send_resp(dut, conn, SIGMA_ERROR,
338 "errorCode,Failed to update AP netAccessKey");
339 goto out;
340 }
341 if (pos2) {
342 sigma_dut_print(dut, DUT_MSG_INFO,
343 "DPP: netAccessKey expiry: %s", pos2);
344 snprintf(buf2, sizeof(buf2), "SET dpp_netaccesskey_expiry %s",
345 pos2);
346 if (wpa_command(ifname, buf2) < 0) {
347 send_resp(dut, conn, SIGMA_ERROR,
348 "errorCode,Failed to update AP netAccessKey expiry");
349 goto out;
350 }
351 }
Jouni Malinenb4c5e3b2017-09-15 17:43:20 +0300352skip_dpp_akm:
Jouni Malinend86e5822017-08-29 03:55:32 +0300353
354 if (wpa_command(ifname, "DISABLE") < 0 ||
355 wpa_command(ifname, "ENABLE") < 0) {
356 send_resp(dut, conn, SIGMA_ERROR,
357 "errorCode,Failed to update AP configuration");
358 goto out;
359 }
360
361 res = get_wpa_cli_event(dut, ctrl, "AP-ENABLED", buf, sizeof(buf));
362 if (res < 0) {
363 send_resp(dut, conn, SIGMA_ERROR, "errorCode,No AP-ENABLED");
364 goto out;
365 }
366
367 return 1;
368out:
369 return 0;
370}
371
372
Jouni Malinen772299f2017-11-06 00:36:26 +0200373struct dpp_test_info {
374 const char *step;
375 const char *frame;
376 const char *attr;
377 int value;
378};
379
380static const struct dpp_test_info dpp_tests[] = {
381 { "InvalidValue", "AuthenticationRequest", "WrappedData", 1 },
382 { "InvalidValue", "AuthenticationResponse", "WrappedData", 2 },
Jouni Malinenf96fcee2017-11-22 16:08:35 +0200383 { "InvalidValue", "AuthenticationResponse", "PrimaryWrappedData", 2 },
Jouni Malinen772299f2017-11-06 00:36:26 +0200384 { "InvalidValue", "AuthenticationConfirm", "WrappedData", 3 },
385 { "InvalidValue", "PKEXCRRequest", "WrappedData", 4 },
386 { "InvalidValue", "PKEXCRResponse", "WrappedData", 5 },
387 { "InvalidValue", "ConfigurationRequest", "WrappedData", 6 },
388 { "InvalidValue", "ConfigurationResponse", "WrappedData", 7 },
389 { "InvalidValue", "AuthenticationRequest", "InitCapabilities", 8 },
Jouni Malinen772299f2017-11-06 00:36:26 +0200390 { "MissingAttribute", "AuthenticationRequest", "RespBSKeyHash", 10 },
391 { "MissingAttribute", "AuthenticationRequest", "InitBSKeyHash", 11 },
392 { "MissingAttribute", "AuthenticationRequest", "InitProtocolKey", 12 },
393 { "MissingAttribute", "AuthenticationRequest", "InitNonce", 13 },
394 { "MissingAttribute", "AuthenticationRequest", "InitCapabilities", 14 },
395 { "MissingAttribute", "AuthenticationRequest", "WrappedData", 15 },
396 { "MissingAttribute", "AuthenticationResponse", "DPPStatus", 16 },
397 { "MissingAttribute", "AuthenticationResponse", "RespBSKeyHash", 17 },
398 { "MissingAttribute", "AuthenticationResponse", "InitBSKeyHash", 18 },
399 { "MissingAttribute", "AuthenticationResponse", "RespProtocolKey", 19 },
400 { "MissingAttribute", "AuthenticationResponse", "RespNonce", 20 },
401 { "MissingAttribute", "AuthenticationResponse", "InitNonce", 21 },
402 { "MissingAttribute", "AuthenticationResponse", "RespCapabilities",
403 22 },
404 { "MissingAttribute", "AuthenticationResponse", "RespAuthTag", 23 },
405 { "MissingAttribute", "AuthenticationResponse", "WrappedData", 24 },
Jouni Malinenf96fcee2017-11-22 16:08:35 +0200406 { "MissingAttribute", "AuthenticationResponse", "PrimaryWrappedData",
407 24 },
Jouni Malinen772299f2017-11-06 00:36:26 +0200408 { "MissingAttribute", "AuthenticationConfirm", "DPPStatus", 25 },
409 { "MissingAttribute", "AuthenticationConfirm", "RespBSKeyHash", 26 },
410 { "MissingAttribute", "AuthenticationConfirm", "InitBSKeyHash", 27 },
411 { "MissingAttribute", "AuthenticationConfirm", "InitAuthTag", 28 },
412 { "MissingAttribute", "AuthenticationConfirm", "WrappedData", 29 },
413 { "InvalidValue", "AuthenticationResponse", "InitNonce", 30 },
414 { "InvalidValue", "AuthenticationResponse", "RespCapabilities", 31 },
415 { "InvalidValue", "AuthenticationResponse", "RespAuthTag", 32 },
416 { "InvalidValue", "AuthenticationConfirm", "InitAuthTag", 33 },
417 { "MissingAttribute", "PKEXExchangeRequest", "FiniteCyclicGroup", 34 },
418 { "MissingAttribute", "PKEXExchangeRequest", "EncryptedKey", 35 },
419 { "MissingAttribute", "PKEXExchangeResponse", "DPPStatus", 36 },
420 { "MissingAttribute", "PKEXExchangeResponse", "EncryptedKey", 37 },
421 { "MissingAttribute", "PKEXCRRequest", "BSKey", 38 },
422 { "MissingAttribute", "PKEXCRRequest", "InitAuthTag", 39 },
423 { "MissingAttribute", "PKEXCRRequest", "WrappedData", 40 },
424 { "MissingAttribute", "PKEXCRResponse", "BSKey", 41 },
425 { "MissingAttribute", "PKEXCRResponse", "RespAuthTag", 42 },
426 { "MissingAttribute", "PKEXCRResponse", "WrappedData", 43 },
427 { "InvalidValue", "PKEXExchangeRequest", "EncryptedKey", 44 },
428 { "InvalidValue", "PKEXExchangeResponse", "EncryptedKey", 45 },
429 { "InvalidValue", "PKEXExchangeResponse", "DPPStatus", 46 },
430 { "InvalidValue", "PKEXCRRequest", "BSKey", 47 },
431 { "InvalidValue", "PKEXCRResponse", "BSKey", 48 },
432 { "InvalidValue", "PKEXCRRequest", "InitAuthTag", 49 },
433 { "InvalidValue", "PKEXCRResponse", "RespAuthTag", 50 },
434 { "MissingAttribute", "ConfigurationRequest", "EnrolleeNonce", 51 },
435 { "MissingAttribute", "ConfigurationRequest", "ConfigAttr", 52 },
436 { "MissingAttribute", "ConfigurationRequest", "WrappedData", 53 },
437 { "MissingAttribute", "ConfigurationResponse", "EnrolleeNonce", 54 },
438 { "MissingAttribute", "ConfigurationResponse", "ConfigObj", 55 },
439 { "MissingAttribute", "ConfigurationResponse", "DPPStatus", 56 },
440 { "MissingAttribute", "ConfigurationResponse", "WrappedData", 57 },
441 { "InvalidValue", "ConfigurationResponse", "DPPStatus", 58 },
442 { "InvalidValue", "ConfigurationResponse", "EnrolleeNonce", 59 },
Jouni Malinen53558e02017-11-06 12:58:28 +0200443 { "MissingAttribute", "PeerDiscoveryRequest", "TransactionID", 60 },
444 { "MissingAttribute", "PeerDiscoveryRequest", "Connector", 61 },
445 { "MissingAttribute", "PeerDiscoveryResponse", "TransactionID", 62 },
446 { "MissingAttribute", "PeerDiscoveryResponse", "DPPStatus", 63 },
447 { "MissingAttribute", "PeerDiscoveryResponse", "Connector", 64 },
Jouni Malinenae624482017-11-19 00:13:51 +0200448 { "InvalidValue", "AuthenticationRequest", "InitProtocolKey", 66 },
449 { "InvalidValue", "AuthenticationResponse", "RespProtocolKey", 67 },
450 { "InvalidValue", "AuthenticationRequest", "RespBSKeyHash", 68 },
451 { "InvalidValue", "AuthenticationRequest", "InitBSKeyHash", 69 },
452 { "InvalidValue", "AuthenticationResponse", "RespBSKeyHash", 70 },
453 { "InvalidValue", "AuthenticationResponse", "InitBSKeyHash", 71 },
454 { "InvalidValue", "AuthenticationConfirm", "RespBSKeyHash", 72 },
455 { "InvalidValue", "AuthenticationConfirm", "InitBSKeyHash", 73 },
456 { "InvalidValue", "AuthenticationResponse", "DPPStatus", 74 },
457 { "InvalidValue", "AuthenticationConfirm", "DPPStatus", 75 },
458 { "InvalidValue", "ConfigurationRequest", "ConfigAttr", 76 },
459 { "InvalidValue", "PeerDiscoveryResponse", "TransactionID", 77 },
460 { "InvalidValue", "PeerDiscoveryResponse", "DPPStatus", 78 },
461 { "InvalidValue", "PeerDiscoveryResponse", "Connector", 79 },
462 { "InvalidValue", "PeerDiscoveryRequest", "Connector", 80 },
Jouni Malinen67795a72017-11-22 16:24:43 +0200463 { "InvalidValue", "AuthenticationRequest", "InitNonce", 81 },
Jouni Malinen188839b2017-11-30 22:02:02 +0200464 { "InvalidValue", "PeerDiscoveryRequest", "TransactionID", 82 },
465 { "InvalidValue", "ConfigurationRequest", "EnrolleeNonce", 83 },
Jouni Malinen3a6b92a2017-12-05 20:22:43 +0200466 { "Timeout", "PKEXExchangeResponse", NULL, 84 },
467 { "Timeout", "PKEXCRRequest", NULL, 85 },
468 { "Timeout", "PKEXCRResponse", NULL, 86 },
469 { "Timeout", "AuthenticationRequest", NULL, 87 },
470 { "Timeout", "AuthenticationResponse", NULL, 88 },
471 { "Timeout", "AuthenticationConfirm", NULL, 89 },
472 { "Timeout", "ConfigurationRequest", NULL, 90 },
Jouni Malinen772299f2017-11-06 00:36:26 +0200473 { NULL, NULL, NULL, 0 }
474};
475
476
477static int dpp_get_test(const char *step, const char *frame, const char *attr)
478{
479 int i;
480
481 for (i = 0; dpp_tests[i].step; i++) {
482 if (strcasecmp(step, dpp_tests[i].step) == 0 &&
483 strcasecmp(frame, dpp_tests[i].frame) == 0 &&
Jouni Malinen3a6b92a2017-12-05 20:22:43 +0200484 ((!attr && dpp_tests[i].attr == NULL) ||
485 (attr && strcasecmp(attr, dpp_tests[i].attr) == 0)))
Jouni Malinen772299f2017-11-06 00:36:26 +0200486 return dpp_tests[i].value;
487 }
488
489 return -1;
490}
491
492
Jouni Malinen6792ff42018-02-13 00:25:56 +0200493static int dpp_wait_tx(struct sigma_dut *dut, struct wpa_ctrl *ctrl,
494 int frame_type)
495{
496 char buf[200], tmp[20];
497 int res;
498
499 snprintf(tmp, sizeof(tmp), "type=%d", frame_type);
500 for (;;) {
501 res = get_wpa_cli_event(dut, ctrl, "DPP-TX", buf, sizeof(buf));
502 if (res < 0)
503 return -1;
504 if (strstr(buf, tmp) != NULL)
505 break;
506 }
507
508 return 0;
509}
510
511
Jouni Malinen772299f2017-11-06 00:36:26 +0200512static int dpp_wait_tx_status(struct sigma_dut *dut, struct wpa_ctrl *ctrl,
513 int frame_type)
514{
515 char buf[200], tmp[20];
516 int res;
517
518 snprintf(tmp, sizeof(tmp), "type=%d", frame_type);
519 for (;;) {
520 res = get_wpa_cli_event(dut, ctrl, "DPP-TX", buf, sizeof(buf));
521 if (res < 0)
522 return -1;
523 if (strstr(buf, tmp) != NULL)
524 break;
525 }
526
527 res = get_wpa_cli_event(dut, ctrl, "DPP-TX-STATUS",
528 buf, sizeof(buf));
529 if (res < 0 || strstr(buf, "result=FAILED") != NULL)
530 return -1;
531
532 return 0;
533}
534
535
Jouni Malinen3a6b92a2017-12-05 20:22:43 +0200536static int dpp_wait_rx(struct sigma_dut *dut, struct wpa_ctrl *ctrl,
Jouni Malinen3e4344e2018-01-22 11:47:37 +0200537 int frame_type, unsigned int max_wait)
Jouni Malinen3a6b92a2017-12-05 20:22:43 +0200538{
539 char buf[200], tmp[20];
540 int res;
Jouni Malinen9a3415c2018-01-10 22:12:22 +0200541 unsigned int old_timeout;
542
543 old_timeout = dut->default_timeout;
544 if (max_wait > 0 && dut->default_timeout > max_wait)
545 dut->default_timeout = max_wait;
Jouni Malinen3a6b92a2017-12-05 20:22:43 +0200546
547 snprintf(tmp, sizeof(tmp), "type=%d", frame_type);
548 for (;;) {
549 res = get_wpa_cli_event(dut, ctrl, "DPP-RX", buf, sizeof(buf));
Jouni Malinen9a3415c2018-01-10 22:12:22 +0200550 if (res < 0) {
551 dut->default_timeout = old_timeout;
Jouni Malinen3a6b92a2017-12-05 20:22:43 +0200552 return -1;
Jouni Malinen9a3415c2018-01-10 22:12:22 +0200553 }
Jouni Malinen3a6b92a2017-12-05 20:22:43 +0200554 if (strstr(buf, tmp) != NULL)
555 break;
556 }
557
Jouni Malinen9a3415c2018-01-10 22:12:22 +0200558 dut->default_timeout = old_timeout;
559 return 0;
560}
561
562
563static int dpp_wait_rx_conf_req(struct sigma_dut *dut, struct wpa_ctrl *ctrl,
Jouni Malinen3e4344e2018-01-22 11:47:37 +0200564 unsigned int max_wait)
Jouni Malinen9a3415c2018-01-10 22:12:22 +0200565{
566 char buf[200];
567 int res;
568 unsigned int old_timeout;
569
570 old_timeout = dut->default_timeout;
571 if (max_wait > 0 && dut->default_timeout > max_wait)
572 dut->default_timeout = max_wait;
573
574 for (;;) {
575 res = get_wpa_cli_event(dut, ctrl, "DPP-CONF-REQ-RX",
576 buf, sizeof(buf));
577 if (res < 0) {
578 dut->default_timeout = old_timeout;
579 return -1;
580 }
581
582 break;
583 }
584
585 dut->default_timeout = old_timeout;
Jouni Malinen3a6b92a2017-12-05 20:22:43 +0200586 return 0;
587}
588
589
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530590static int dpp_scan_peer_qrcode(struct sigma_dut *dut)
Jouni Malinend86e5822017-08-29 03:55:32 +0300591{
Jouni Malinen1a38cc32018-01-05 20:59:00 +0200592#ifdef ANDROID
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530593 char buf[100];
594 char *buf2 = NULL;
595 FILE *fp = NULL;
596 uint32_t length;
597 unsigned int count;
598
599 unlink(dpp_qrcode_file);
600
601 snprintf(buf, sizeof(buf),
Jouni Malinen07458342018-02-22 19:23:40 +0200602 "am start -n w1.fi.wpadebug/w1.fi.wpadebug.QrCodeReadActivity");
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530603 if (system(buf) != 0) {
Jouni Malinen07458342018-02-22 19:23:40 +0200604 sigma_dut_print(dut, DUT_MSG_ERROR,
605 "Failed to launch QR Code scanner");
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530606 return -1;
607 }
608
609 count = 0;
610 while (!(fp = fopen(dpp_qrcode_file, "r"))) {
611 if (count > dut->default_timeout) {
612 sigma_dut_print(dut, DUT_MSG_ERROR,
613 "Failed to open dpp_qrcode_file - QR Code scanning timed out");
614 return -1;
615 }
616
617 sleep(1);
618 count++;
619 }
620
621 if (fseek(fp, 0, SEEK_END) < 0 || (length = ftell(fp)) <= 0 ||
622 fseek(fp, 0, SEEK_SET) < 0) {
623 sigma_dut_print(dut, DUT_MSG_ERROR,
624 "Failed to get QR Code result file length");
625 fclose(fp);
626 return -1;
627 }
628
629 buf2 = malloc(length + 1);
630 if (!buf2) {
631 fclose(fp);
632 return -1;
633 }
634
635 if (fread(buf2, 1, length, fp) != length) {
636 fclose(fp);
637 free(buf2);
638 return -1;
639 }
640
641 fclose(fp);
642 buf2[length] = '\0';
643
644 free(dut->dpp_peer_uri);
645 dut->dpp_peer_uri = strdup(buf2);
646 free(buf2);
647 return 0;
Jouni Malinen1a38cc32018-01-05 20:59:00 +0200648#else /* ANDROID */
649 pid_t pid;
650 int pid_status;
651 int pipe_out[2];
652 char buf[4000], *pos;
653 ssize_t len;
654 int res = -1, ret;
655 struct timeval tv;
656 fd_set rfd;
657
658 if (pipe(pipe_out) != 0) {
659 perror("pipe");
660 return -1;
661 }
662
663 pid = fork();
664 if (pid < 0) {
665 perror("fork");
666 close(pipe_out[0]);
667 close(pipe_out[1]);
668 return -1;
669 }
670
671 if (pid == 0) {
672 char *argv[4] = { "zbarcam", "--raw", "--prescale=320x240",
673 NULL };
674
675 dup2(pipe_out[1], STDOUT_FILENO);
676 close(pipe_out[0]);
677 close(pipe_out[1]);
678 execv("/usr/bin/zbarcam", argv);
679 perror("execv");
680 exit(0);
681 return -1;
682 }
683
684 close(pipe_out[1]);
685
686 FD_ZERO(&rfd);
687 FD_SET(pipe_out[0], &rfd);
688 tv.tv_sec = dut->default_timeout;
689 tv.tv_usec = 0;
690
691 ret = select(pipe_out[0] + 1, &rfd, NULL, NULL, &tv);
692 if (ret < 0) {
693 perror("select");
694 goto out;
695 }
696 if (ret == 0) {
697 sigma_dut_print(dut, DUT_MSG_DEBUG,
698 "QR Code scanning timed out");
699 goto out;
700 }
701
702 len = read(pipe_out[0], buf, sizeof(buf));
703 if (len <= 0)
704 goto out;
705 if (len == sizeof(buf))
706 len--;
707 buf[len] = '\0';
708 pos = strchr(buf, '\n');
709 if (pos)
710 *pos = '\0';
711 sigma_dut_print(dut, DUT_MSG_DEBUG, "URI from QR scanner: %s", buf);
712
713 free(dut->dpp_peer_uri);
714 dut->dpp_peer_uri = strdup(buf);
715 res = 0;
716out:
717 close(pipe_out[0]);
718 kill(pid, SIGTERM);
719 waitpid(pid, &pid_status, 0);
720
721 return res;
722#endif /* ANDROID */
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530723}
724
725
726static int dpp_display_own_qrcode(struct sigma_dut *dut)
727{
728 char buf[200], resp[2000];
729 const char *ifname = get_station_ifname();
Jouni Malinen1a38cc32018-01-05 20:59:00 +0200730#ifdef ANDROID
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530731 FILE *fp;
Jouni Malinen1a38cc32018-01-05 20:59:00 +0200732#else /* ANDROID */
733 pid_t pid;
734 int pid_status;
735#endif /* ANDROID */
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530736
737 snprintf(buf, sizeof(buf), "DPP_BOOTSTRAP_GET_URI %d",
738 dut->dpp_local_bootstrap);
739 if (wpa_command_resp(ifname, buf, resp, sizeof(resp)) < 0 ||
740 strncmp(resp, "FAIL", 4) == 0)
741 return -2;
Jouni Malinen1a38cc32018-01-05 20:59:00 +0200742 sigma_dut_print(dut, DUT_MSG_DEBUG, "Own bootstrap URI: %s", resp);
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530743
Jouni Malinen1a38cc32018-01-05 20:59:00 +0200744#ifdef ANDROID
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530745 unlink(dpp_qrcode_file);
746
747 fp = fopen(dpp_qrcode_file, "w");
748 if (!fp) {
749 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open file %s",
750 dpp_qrcode_file);
751 return -2;
752 }
753
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530754 fwrite(resp, 1, strlen(resp), fp);
755 fclose(fp);
756
757 snprintf(buf, sizeof(buf),
758 "am start -n w1.fi.wpadebug/w1.fi.wpadebug.QrCodeDisplayActivity");
759 if (system(buf) != 0) {
760 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to display QR Code");
761 return -1;
762 }
Jouni Malinen1a38cc32018-01-05 20:59:00 +0200763#else /* ANDROID */
764 pid = fork();
765 if (pid < 0) {
766 perror("fork");
767 return -1;
768 }
769
770 if (pid == 0) {
771 char *argv[3] = { "qr", resp, NULL };
772
773 execv("/usr/bin/qr", argv);
774 perror("execv");
775 exit(0);
776 return -1;
777 }
778
779 waitpid(pid, &pid_status, 0);
780#endif /* ANDROID */
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530781
782 return 0;
Jouni Malinend86e5822017-08-29 03:55:32 +0300783}
784
785
Srinivas Dasari8d88d822018-03-26 17:57:34 +0530786static int dpp_process_auth_response(struct sigma_dut *dut,
787 struct sigma_conn *conn,
788 struct wpa_ctrl *ctrl,
789 const char **auth_events,
790 const char *action_type,
791 int check_mutual, char *buf, size_t buflen)
792{
793 int res;
794
795 res = get_wpa_cli_events(dut, ctrl, auth_events, buf, buflen);
796 if (res < 0) {
797 send_resp(dut, conn, SIGMA_COMPLETE,
798 "BootstrapResult,OK,AuthResult,Timeout");
799 return res;
800 }
801 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP auth result: %s", buf);
802
803 if (strstr(buf, "DPP-RESPONSE-PENDING")) {
804 /* Display own QR code in manual mode */
805 if (action_type && strcasecmp(action_type, "ManualDPP") == 0 &&
806 dpp_display_own_qrcode(dut) < 0) {
807 send_resp(dut, conn, SIGMA_ERROR,
808 "errorCode,Failed to display own QR code");
809 return -1;
810 }
811
812 /* Wait for the actual result after the peer has scanned the
813 * QR Code. */
814 res = get_wpa_cli_events(dut, ctrl, auth_events,
815 buf, buflen);
816 if (res < 0) {
817 send_resp(dut, conn, SIGMA_COMPLETE,
818 "BootstrapResult,OK,AuthResult,Timeout");
819 return res;
820 }
821
822 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP auth result: %s", buf);
823 }
824
825 if (check_mutual) {
826 if (strstr(buf, "DPP-NOT-COMPATIBLE")) {
827 send_resp(dut, conn, SIGMA_COMPLETE,
828 "BootstrapResult,OK,AuthResult,ROLES_NOT_COMPATIBLE");
829 return -1;
830 }
831
832 if (!strstr(buf, "DPP-AUTH-DIRECTION")) {
833 send_resp(dut, conn, SIGMA_ERROR,
834 "errorCode,No event for auth direction seen");
835 return -1;
836 }
837
838 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP auth direction: %s",
839 buf);
840 if (strstr(buf, "mutual=1") == NULL) {
841 send_resp(dut, conn, SIGMA_ERROR,
842 "errorCode,Peer did not use mutual authentication");
843 return -1;
844 }
845 }
846
847 return 0;
848}
849
850
Jouni Malinend86e5822017-08-29 03:55:32 +0300851static int dpp_automatic_dpp(struct sigma_dut *dut,
852 struct sigma_conn *conn,
853 struct sigma_cmd *cmd)
854{
855 const char *bs = get_param(cmd, "DPPBS");
856 const char *auth_role = get_param(cmd, "DPPAuthRole");
857 const char *prov_role = get_param(cmd, "DPPProvisioningRole");
858 const char *pkex_code = get_param(cmd, "DPPPKEXCode");
859 const char *pkex_code_id = get_param(cmd, "DPPPKEXCodeIdentifier");
860 const char *wait_conn = get_param(cmd, "DPPWaitForConnect");
861 const char *self_conf = get_param(cmd, "DPPSelfConfigure");
Jouni Malinen772299f2017-11-06 00:36:26 +0200862 const char *step = get_param(cmd, "DPPStep");
863 const char *frametype = get_param(cmd, "DPPFrameType");
864 const char *attr = get_param(cmd, "DPPIEAttribute");
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530865 const char *action_type = get_param(cmd, "DPPActionType");
Jouni Malinend86e5822017-08-29 03:55:32 +0300866 const char *role;
867 const char *val;
868 const char *conf_role;
Jouni Malinend86e5822017-08-29 03:55:32 +0300869 int conf_index = -1;
870 char buf[2000];
871 char conf_ssid[100];
872 char conf_pass[100];
873 char pkex_identifier[200];
874 struct wpa_ctrl *ctrl;
875 int res;
876 unsigned int old_timeout;
877 int own_pkex_id = -1;
878 const char *ifname = get_station_ifname();
879 const char *auth_events[] = {
880 "DPP-AUTH-SUCCESS",
881 "DPP-NOT-COMPATIBLE",
882 "DPP-RESPONSE-PENDING",
883 "DPP-SCAN-PEER-QR-CODE",
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530884 "DPP-AUTH-DIRECTION",
Jouni Malinend86e5822017-08-29 03:55:32 +0300885 NULL
886 };
887 const char *conf_events[] = {
888 "DPP-CONF-RECEIVED",
889 "DPP-CONF-SENT",
890 "DPP-CONF-FAILED",
891 NULL
892 };
893 const char *conn_events[] = {
894 "PMKSA-CACHE-ADDED",
895 "CTRL-EVENT-CONNECTED",
896 NULL
897 };
Purushottam Kushwaha11ab72c2018-08-10 12:40:30 +0530898 const char *group_id_str = NULL;
899 char group_id[100];
Jouni Malinen772299f2017-11-06 00:36:26 +0200900 const char *result;
Jouni Malinend1e22f72017-12-05 21:12:17 +0200901 int check_mutual = 0;
Jouni Malinene89cdbf2017-12-11 20:18:24 +0200902 int enrollee_ap;
Jouni Malinenf2fa0d02018-01-11 20:51:31 +0200903 int force_gas_fragm = 0;
Jouni Malinen85a5a2e2018-04-10 21:40:18 +0300904 int not_dpp_akm = 0;
Jouni Malinend86e5822017-08-29 03:55:32 +0300905
906 if (!wait_conn)
907 wait_conn = "no";
908 if (!self_conf)
909 self_conf = "no";
910
911 if (!auth_role) {
912 send_resp(dut, conn, SIGMA_ERROR,
913 "errorCode,Missing DPPAuthRole");
914 return 0;
915 }
916
917 if (!prov_role) {
918 send_resp(dut, conn, SIGMA_ERROR,
919 "errorCode,Missing DPPProvisioningRole");
920 return 0;
921 }
922
Jouni Malinene89cdbf2017-12-11 20:18:24 +0200923 val = get_param(cmd, "DPPConfEnrolleeRole");
924 if (val)
925 enrollee_ap = strcasecmp(val, "AP") == 0;
926 else
927 enrollee_ap = sigma_dut_is_ap(dut);
928
Jouni Malinen3a6b92a2017-12-05 20:22:43 +0200929 if ((step || frametype) && (!step || !frametype)) {
Jouni Malinen772299f2017-11-06 00:36:26 +0200930 send_resp(dut, conn, SIGMA_ERROR,
931 "errorCode,Invalid DPPStep,DPPFrameType,DPPIEAttribute combination");
932 return 0;
933 }
934
Jouni Malinend86e5822017-08-29 03:55:32 +0300935 if (sigma_dut_is_ap(dut)) {
936 if (!dut->hostapd_ifname) {
937 sigma_dut_print(dut, DUT_MSG_ERROR,
938 "hostapd ifname not specified (-j)");
939 return -2;
940 }
941 ifname = dut->hostapd_ifname;
942
943 if (dpp_hostapd_run(dut) < 0) {
944 send_resp(dut, conn, SIGMA_ERROR,
945 "errorCode,Failed to start hostapd");
946 return 0;
947 }
948 }
949
Jouni Malinen67acb0c2017-11-21 01:01:54 +0200950 if (strcasecmp(prov_role, "Configurator") == 0 ||
951 strcasecmp(prov_role, "Both") == 0) {
Jouni Malinend86e5822017-08-29 03:55:32 +0300952 if (dut->dpp_conf_id < 0) {
953 snprintf(buf, sizeof(buf),
954 "DPP_CONFIGURATOR_ADD curve=%s",
955 dpp_get_curve(cmd, "DPPSigningKeyECC"));
956 if (wpa_command_resp(ifname, buf,
957 buf, sizeof(buf)) < 0) {
958 send_resp(dut, conn, SIGMA_ERROR,
959 "errorCode,Failed to set up configurator");
960 return 0;
961 }
962 dut->dpp_conf_id = atoi(buf);
963 }
Jouni Malinen67acb0c2017-11-21 01:01:54 +0200964 if (strcasecmp(prov_role, "Configurator") == 0)
965 role = "configurator";
966 else
967 role = "either";
Jouni Malinend86e5822017-08-29 03:55:32 +0300968 } else if (strcasecmp(prov_role, "Enrollee") == 0) {
969 role = "enrollee";
970 } else {
971 send_resp(dut, conn, SIGMA_ERROR,
972 "errorCode,Unknown DPPProvisioningRole");
973 return 0;
974 }
975
976 pkex_identifier[0] = '\0';
977 if (strcasecmp(bs, "PKEX") == 0) {
Jouni Malinen4f47a272017-11-04 12:29:11 +0200978 if (sigma_dut_is_ap(dut) && dut->ap_channel != 6) {
979 /* For now, have to make operating channel match DPP
980 * listen channel. This should be removed once hostapd
981 * has support for DPP listen on non-operating channel.
982 */
983 sigma_dut_print(dut, DUT_MSG_INFO,
984 "Update hostapd operating channel to match listen needs");
985 dut->ap_channel = 6;
priyadharshini gowthamanb4de1962018-01-15 12:21:04 -0800986
987 if (get_driver_type() == DRIVER_OPENWRT) {
988 snprintf(buf, sizeof(buf),
989 "iwconfig %s channel %d",
990 dut->hostapd_ifname, dut->ap_channel);
991 run_system(dut, buf);
992 }
993
Jouni Malinen4f47a272017-11-04 12:29:11 +0200994 if (wpa_command(ifname, "SET channel 6") < 0 ||
995 wpa_command(ifname, "DISABLE") < 0 ||
996 wpa_command(ifname, "ENABLE") < 0) {
997 send_resp(dut, conn, SIGMA_ERROR,
998 "errorCode,Failed to update channel");
999 return 0;
1000 }
1001 }
1002
Jouni Malinend86e5822017-08-29 03:55:32 +03001003 if (!pkex_code) {
1004 send_resp(dut, conn, SIGMA_ERROR,
1005 "errorCode,Missing DPPPKEXCode");
1006 return 0;
1007 }
1008
1009 if (pkex_code_id)
1010 snprintf(pkex_identifier, sizeof(pkex_identifier),
1011 "identifier=%s ", pkex_code_id);
1012
1013 snprintf(buf, sizeof(buf),
1014 "DPP_BOOTSTRAP_GEN type=pkex curve=%s",
1015 dpp_get_curve(cmd, "DPPCryptoIdentifier"));
1016 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0) {
1017 send_resp(dut, conn, SIGMA_ERROR,
1018 "errorCode,Failed to set up PKEX");
1019 return 0;
1020 }
1021 own_pkex_id = atoi(buf);
1022 }
1023
1024 ctrl = open_wpa_mon(ifname);
1025 if (!ctrl) {
1026 sigma_dut_print(dut, DUT_MSG_ERROR,
1027 "Failed to open wpa_supplicant monitor connection");
1028 return -2;
1029 }
1030
1031 old_timeout = dut->default_timeout;
1032 val = get_param(cmd, "DPPTimeout");
1033 if (val && atoi(val) > 0) {
1034 dut->default_timeout = atoi(val);
1035 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP timeout: %u",
1036 dut->default_timeout);
1037 }
1038
1039 conf_ssid[0] = '\0';
1040 conf_pass[0] = '\0';
Purushottam Kushwaha11ab72c2018-08-10 12:40:30 +05301041 group_id[0] = '\0';
Jouni Malinend86e5822017-08-29 03:55:32 +03001042 val = get_param(cmd, "DPPConfIndex");
1043 if (val)
1044 conf_index = atoi(val);
Jouni Malinend86e5822017-08-29 03:55:32 +03001045 switch (conf_index) {
Jouni Malinen258cc262017-10-13 00:19:56 +03001046 case -1:
1047 conf_role = NULL;
1048 break;
Jouni Malinend86e5822017-08-29 03:55:32 +03001049 case 1:
1050 ascii2hexstr("DPPNET01", buf);
1051 snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
Jouni Malinene89cdbf2017-12-11 20:18:24 +02001052 if (enrollee_ap) {
Jouni Malinend86e5822017-08-29 03:55:32 +03001053 conf_role = "ap-dpp";
Jouni Malinen3d291f72017-11-02 11:31:05 +02001054 } else {
Jouni Malinend86e5822017-08-29 03:55:32 +03001055 conf_role = "sta-dpp";
Jouni Malinen3d291f72017-11-02 11:31:05 +02001056 }
Purushottam Kushwaha11ab72c2018-08-10 12:40:30 +05301057 group_id_str = "DPPGROUP_DPP_INFRA";
Jouni Malinend86e5822017-08-29 03:55:32 +03001058 break;
1059 case 2:
1060 ascii2hexstr("DPPNET01", buf);
1061 snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
Jouni Malinen8f81cdf2017-09-15 18:15:18 +03001062 snprintf(conf_pass, sizeof(conf_pass),
1063 "psk=10506e102ad1e7f95112f6b127675bb8344dacacea60403f3fa4055aec85b0fc");
Jouni Malinene89cdbf2017-12-11 20:18:24 +02001064 if (enrollee_ap)
Jouni Malinend86e5822017-08-29 03:55:32 +03001065 conf_role = "ap-psk";
1066 else
1067 conf_role = "sta-psk";
1068 break;
1069 case 3:
1070 ascii2hexstr("DPPNET01", buf);
1071 snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
1072 ascii2hexstr("ThisIsDppPassphrase", buf);
1073 snprintf(conf_pass, sizeof(conf_pass), "pass=%s", buf);
Jouni Malinene89cdbf2017-12-11 20:18:24 +02001074 if (enrollee_ap)
Jouni Malinend86e5822017-08-29 03:55:32 +03001075 conf_role = "ap-psk";
1076 else
1077 conf_role = "sta-psk";
1078 break;
Jouni Malinen3d291f72017-11-02 11:31:05 +02001079 case 4:
1080 ascii2hexstr("DPPNET01", buf);
1081 snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
Jouni Malinene89cdbf2017-12-11 20:18:24 +02001082 if (enrollee_ap) {
Jouni Malinen3d291f72017-11-02 11:31:05 +02001083 conf_role = "ap-dpp";
Jouni Malinen3d291f72017-11-02 11:31:05 +02001084 } else {
1085 conf_role = "sta-dpp";
Jouni Malinen3d291f72017-11-02 11:31:05 +02001086 }
Purushottam Kushwaha11ab72c2018-08-10 12:40:30 +05301087 group_id_str = "DPPGROUP_DPP_INFRA2";
Jouni Malinen3d291f72017-11-02 11:31:05 +02001088 break;
Jouni Malinen7d031c72018-01-09 19:39:56 +02001089 case 5:
1090 ascii2hexstr("DPPNET01", buf);
1091 snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
1092 ascii2hexstr("ThisIsDppPassphrase", buf);
1093 snprintf(conf_pass, sizeof(conf_pass), "pass=%s", buf);
1094 if (enrollee_ap)
1095 conf_role = "ap-sae";
1096 else
1097 conf_role = "sta-sae";
1098 break;
1099 case 6:
1100 ascii2hexstr("DPPNET01", buf);
1101 snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
1102 ascii2hexstr("ThisIsDppPassphrase", buf);
1103 snprintf(conf_pass, sizeof(conf_pass), "pass=%s", buf);
1104 if (enrollee_ap)
1105 conf_role = "ap-psk-sae";
1106 else
1107 conf_role = "sta-psk-sae";
1108 break;
Jouni Malinenf2fa0d02018-01-11 20:51:31 +02001109 case 7:
1110 ascii2hexstr("DPPNET01", buf);
1111 snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
1112 if (enrollee_ap) {
1113 conf_role = "ap-dpp";
Jouni Malinenf2fa0d02018-01-11 20:51:31 +02001114 } else {
1115 conf_role = "sta-dpp";
Jouni Malinenf2fa0d02018-01-11 20:51:31 +02001116 }
Purushottam Kushwaha11ab72c2018-08-10 12:40:30 +05301117 group_id_str = "DPPGROUP_DPP_INFRA";
Jouni Malinenf2fa0d02018-01-11 20:51:31 +02001118 force_gas_fragm = 1;
1119 break;
Jouni Malinenf7490762017-10-12 00:34:37 +03001120 default:
1121 send_resp(dut, conn, SIGMA_ERROR,
1122 "errorCode,Unsupported DPPConfIndex");
1123 goto out;
Jouni Malinend86e5822017-08-29 03:55:32 +03001124 }
1125
Purushottam Kushwaha11ab72c2018-08-10 12:40:30 +05301126 if (group_id_str)
1127 snprintf(group_id, sizeof(group_id), " group_id=%s",
1128 group_id_str);
Jouni Malinen3d291f72017-11-02 11:31:05 +02001129
Jouni Malinen2b2230f2018-02-12 13:05:06 +02001130 if (force_gas_fragm) {
1131 char spaces[1500];
1132
1133 memset(spaces, ' ', sizeof(spaces));
1134 spaces[sizeof(spaces) - 1] = '\0';
1135
1136 snprintf(buf, sizeof(buf),
1137 "SET dpp_discovery_override {\"ssid\":\"DPPNET01\"}%s",
1138 spaces);
1139 if (wpa_command(ifname, buf) < 0) {
1140 send_resp(dut, conn, SIGMA_ERROR,
1141 "errorCode,Failed to set discovery override");
1142 goto out;
1143 }
1144 }
1145
Jouni Malinen772299f2017-11-06 00:36:26 +02001146 if (step) {
1147 int test;
1148
1149 test = dpp_get_test(step, frametype, attr);
1150 if (test <= 0) {
1151 send_resp(dut, conn, SIGMA_ERROR,
1152 "errorCode,Unsupported DPPStep/DPPFrameType/DPPIEAttribute");
1153 goto out;
1154 }
1155
1156 snprintf(buf, sizeof(buf), "SET dpp_test %d", test);
1157 if (wpa_command(ifname, buf) < 0) {
1158 send_resp(dut, conn, SIGMA_ERROR,
1159 "errorCode,Failed to set dpp_test");
1160 goto out;
1161 }
1162 } else {
1163 wpa_command(ifname, "SET dpp_test 0");
1164 }
1165
Jouni Malinenfbb268d2017-11-17 18:53:49 +02001166 if (strcasecmp(self_conf, "Yes") == 0) {
1167 if (strcasecmp(prov_role, "Configurator") != 0) {
1168 send_resp(dut, conn, SIGMA_ERROR,
1169 "errorCode,Invalid DPPSelfConfigure use - only allowed for Configurator role");
1170 goto out;
1171 }
1172 if (!conf_role) {
1173 send_resp(dut, conn, SIGMA_ERROR,
1174 "errorCode,Missing DPPConfIndex");
1175 goto out;
1176 }
1177
1178 snprintf(buf, sizeof(buf),
1179 "DPP_CONFIGURATOR_SIGN conf=%s %s %s configurator=%d",
1180 conf_role, conf_ssid, conf_pass, dut->dpp_conf_id);
1181 if (wpa_command(ifname, buf) < 0) {
1182 send_resp(dut, conn, SIGMA_ERROR,
1183 "errorCode,Failed to initiate DPP self-configuration");
1184 goto out;
1185 }
Jouni Malinen174db642017-11-27 20:16:29 +02001186 if (sigma_dut_is_ap(dut))
1187 goto update_ap;
Jouni Malinenfbb268d2017-11-17 18:53:49 +02001188 goto wait_connect;
1189 } else if (strcasecmp(auth_role, "Initiator") == 0) {
Jouni Malinend86e5822017-08-29 03:55:32 +03001190 char own_txt[20];
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02001191 int dpp_peer_bootstrap = -1;
Jouni Malinenb5ab8282017-11-21 01:12:22 +02001192 char neg_freq[30];
1193
Jouni Malinend1e22f72017-12-05 21:12:17 +02001194 val = get_param(cmd, "DPPAuthDirection");
1195 check_mutual = val && strcasecmp(val, "Mutual") == 0;
1196
Jouni Malinenb5ab8282017-11-21 01:12:22 +02001197 neg_freq[0] = '\0';
1198 val = get_param(cmd, "DPPSubsequentChannel");
1199 if (val) {
1200 int opclass, channel, freq;
1201
1202 opclass = atoi(val);
1203 val = strchr(val, '/');
1204 if (opclass == 0 || !val) {
1205 send_resp(dut, conn, SIGMA_ERROR,
1206 "errorCode,Invalid DPPSubsequentChannel");
1207 goto out;
1208 }
1209 val++;
1210 channel = atoi(val);
1211
1212 /* Ignoring opclass for now; could use it here for more
1213 * robust frequency determination. */
1214 freq = channel_to_freq(channel);
1215 if (!freq) {
1216 send_resp(dut, conn, SIGMA_ERROR,
1217 "errorCode,Unsupported DPPSubsequentChannel channel");
1218 goto out;
1219 }
1220 snprintf(neg_freq, sizeof(neg_freq), " neg_freq=%d",
1221 freq);
1222 }
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02001223
1224 if (strcasecmp(bs, "QR") == 0) {
1225 if (!dut->dpp_peer_uri) {
1226 send_resp(dut, conn, SIGMA_ERROR,
1227 "errorCode,Missing peer bootstrapping info");
1228 goto out;
1229 }
1230
1231 snprintf(buf, sizeof(buf), "DPP_QR_CODE %s",
1232 dut->dpp_peer_uri);
1233 if (wpa_command_resp(ifname, buf, buf,
Jouni Malinen3c27aa82018-03-21 12:04:03 +02001234 sizeof(buf)) < 0 ||
1235 strncmp(buf, "FAIL", 4) == 0) {
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02001236 send_resp(dut, conn, SIGMA_ERROR,
1237 "errorCode,Failed to parse URI");
1238 goto out;
1239 }
1240 dpp_peer_bootstrap = atoi(buf);
1241 }
Jouni Malinend86e5822017-08-29 03:55:32 +03001242
Jouni Malinen63d50412017-11-24 11:55:38 +02001243 if (dut->dpp_local_bootstrap >= 0)
Jouni Malinend86e5822017-08-29 03:55:32 +03001244 snprintf(own_txt, sizeof(own_txt), " own=%d",
1245 dut->dpp_local_bootstrap);
1246 else
1247 own_txt[0] = '\0';
1248 if (strcasecmp(bs, "QR") == 0 &&
Jouni Malinen67acb0c2017-11-21 01:01:54 +02001249 (strcasecmp(prov_role, "Configurator") == 0 ||
1250 strcasecmp(prov_role, "Both") == 0)) {
Jouni Malinen258cc262017-10-13 00:19:56 +03001251 if (!conf_role) {
1252 send_resp(dut, conn, SIGMA_ERROR,
1253 "errorCode,Missing DPPConfIndex");
1254 goto out;
1255 }
Jouni Malinend86e5822017-08-29 03:55:32 +03001256 snprintf(buf, sizeof(buf),
Purushottam Kushwaha11ab72c2018-08-10 12:40:30 +05301257 "DPP_AUTH_INIT peer=%d%s role=%s conf=%s %s %s configurator=%d%s%s",
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02001258 dpp_peer_bootstrap, own_txt, role,
Jouni Malinend86e5822017-08-29 03:55:32 +03001259 conf_role, conf_ssid, conf_pass,
Purushottam Kushwaha11ab72c2018-08-10 12:40:30 +05301260 dut->dpp_conf_id, neg_freq, group_id);
Jouni Malinend86e5822017-08-29 03:55:32 +03001261 } else if (strcasecmp(bs, "QR") == 0) {
1262 snprintf(buf, sizeof(buf),
Purushottam Kushwaha11ab72c2018-08-10 12:40:30 +05301263 "DPP_AUTH_INIT peer=%d%s role=%s%s%s",
1264 dpp_peer_bootstrap, own_txt, role,
1265 neg_freq, group_id);
Jouni Malinend86e5822017-08-29 03:55:32 +03001266 } else if (strcasecmp(bs, "PKEX") == 0 &&
Jouni Malinen67acb0c2017-11-21 01:01:54 +02001267 (strcasecmp(prov_role, "Configurator") == 0 ||
1268 strcasecmp(prov_role, "Both") == 0)) {
Jouni Malinen258cc262017-10-13 00:19:56 +03001269 if (!conf_role) {
1270 send_resp(dut, conn, SIGMA_ERROR,
1271 "errorCode,Missing DPPConfIndex");
1272 goto out;
1273 }
Jouni Malinend86e5822017-08-29 03:55:32 +03001274 snprintf(buf, sizeof(buf),
1275 "DPP_PKEX_ADD own=%d init=1 role=%s conf=%s %s %s configurator=%d %scode=%s",
1276 own_pkex_id, role, conf_role,
1277 conf_ssid, conf_pass, dut->dpp_conf_id,
1278 pkex_identifier, pkex_code);
1279 } else if (strcasecmp(bs, "PKEX") == 0) {
1280 snprintf(buf, sizeof(buf),
1281 "DPP_PKEX_ADD own=%d init=1 role=%s %scode=%s",
1282 own_pkex_id, role, pkex_identifier, pkex_code);
Jouni Malinend551c6f2017-10-12 00:32:18 +03001283 } else {
1284 send_resp(dut, conn, SIGMA_ERROR,
1285 "errorCode,Unsupported DPPBS");
1286 goto out;
Jouni Malinend86e5822017-08-29 03:55:32 +03001287 }
1288 if (wpa_command(ifname, buf) < 0) {
1289 send_resp(dut, conn, SIGMA_ERROR,
1290 "errorCode,Failed to initiate DPP authentication");
1291 goto out;
1292 }
1293 } else if (strcasecmp(auth_role, "Responder") == 0) {
Jouni Malinen67f096a2017-11-24 11:58:51 +02001294 const char *delay_qr_resp;
Jouni Malinen63d50412017-11-24 11:55:38 +02001295 int mutual;
Jouni Malinend3afc5c2017-11-13 18:39:14 +02001296 int freq = 2462; /* default: channel 11 */
1297
Jouni Malinen06cfcb32018-01-11 20:43:50 +02001298 if (strcasecmp(bs, "PKEX") == 0) {
1299 /* default: channel 6 for PKEX */
1300 freq = 2437;
1301 }
1302
Jouni Malinen67f096a2017-11-24 11:58:51 +02001303 delay_qr_resp = get_param(cmd, "DPPDelayQRResponse");
1304
Jouni Malinen63d50412017-11-24 11:55:38 +02001305 val = get_param(cmd, "DPPAuthDirection");
1306 mutual = val && strcasecmp(val, "Mutual") == 0;
1307
Jouni Malinend3afc5c2017-11-13 18:39:14 +02001308 val = get_param(cmd, "DPPListenChannel");
1309 if (val) {
1310 freq = channel_to_freq(atoi(val));
1311 if (freq == 0) {
1312 send_resp(dut, conn, SIGMA_ERROR,
1313 "errorCode,Unsupported DPPListenChannel value");
1314 goto out;
1315 }
1316 }
Jouni Malinend86e5822017-08-29 03:55:32 +03001317
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02001318 if (!delay_qr_resp && dut->dpp_peer_uri) {
1319 snprintf(buf, sizeof(buf), "DPP_QR_CODE %s",
1320 dut->dpp_peer_uri);
1321 if (wpa_command_resp(ifname, buf, buf,
1322 sizeof(buf)) < 0) {
1323 send_resp(dut, conn, SIGMA_ERROR,
1324 "errorCode,Failed to parse URI");
1325 goto out;
1326 }
1327 }
1328
Jouni Malinend86e5822017-08-29 03:55:32 +03001329 if (strcasecmp(prov_role, "Configurator") == 0) {
Jouni Malinen258cc262017-10-13 00:19:56 +03001330 if (!conf_role) {
1331 send_resp(dut, conn, SIGMA_ERROR,
1332 "errorCode,Missing DPPConfIndex");
1333 goto out;
1334 }
Jouni Malinend86e5822017-08-29 03:55:32 +03001335 snprintf(buf, sizeof(buf),
Purushottam Kushwaha11ab72c2018-08-10 12:40:30 +05301336 "SET dpp_configurator_params conf=%s %s %s configurator=%d%s",
Jouni Malinend86e5822017-08-29 03:55:32 +03001337 conf_role, conf_ssid, conf_pass,
Purushottam Kushwaha11ab72c2018-08-10 12:40:30 +05301338 dut->dpp_conf_id, group_id);
Jouni Malinend86e5822017-08-29 03:55:32 +03001339 if (wpa_command(ifname, buf) < 0) {
1340 send_resp(dut, conn, SIGMA_ERROR,
1341 "errorCode,Failed to set configurator parameters");
1342 goto out;
1343 }
1344 }
1345 if (strcasecmp(bs, "PKEX") == 0) {
Jouni Malinend86e5822017-08-29 03:55:32 +03001346 snprintf(buf, sizeof(buf),
1347 "DPP_PKEX_ADD own=%d role=%s %scode=%s",
1348 own_pkex_id, role, pkex_identifier, pkex_code);
1349 if (wpa_command(ifname, buf) < 0) {
1350 send_resp(dut, conn, SIGMA_ERROR,
1351 "errorCode,Failed to configure DPP PKEX");
1352 goto out;
1353 }
1354 }
1355
Jouni Malinenbafc1932017-11-04 11:31:16 +02001356 snprintf(buf, sizeof(buf), "DPP_LISTEN %d role=%s%s",
1357 freq, role,
1358 (strcasecmp(bs, "QR") == 0 && mutual) ?
1359 " qr=mutual" : "");
1360 if (wpa_command(ifname, buf) < 0) {
1361 send_resp(dut, conn, SIGMA_ERROR,
1362 "errorCode,Failed to start DPP listen");
1363 goto out;
Jouni Malinend86e5822017-08-29 03:55:32 +03001364 }
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02001365
priyadharshini gowthamanb4de1962018-01-15 12:21:04 -08001366 if (get_driver_type() == DRIVER_OPENWRT) {
1367 snprintf(buf, sizeof(buf), "iwconfig %s channel %d",
1368 dut->hostapd_ifname, freq_to_channel(freq));
1369 run_system(dut, buf);
1370 }
1371
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02001372 if (delay_qr_resp && mutual && dut->dpp_peer_uri) {
1373 int wait_time = atoi(delay_qr_resp);
1374
1375 res = get_wpa_cli_events(dut, ctrl, auth_events,
1376 buf, sizeof(buf));
1377 if (res < 0) {
1378 send_resp(dut, conn, SIGMA_COMPLETE,
1379 "BootstrapResult,OK,AuthResult,Timeout");
1380 goto out;
1381 }
1382 sigma_dut_print(dut, DUT_MSG_DEBUG,
1383 "DPP auth result: %s", buf);
1384 if (strstr(buf, "DPP-SCAN-PEER-QR-CODE") == NULL) {
1385 send_resp(dut, conn, SIGMA_ERROR,
1386 "errorCode,No scan request for peer QR Code seen");
1387 goto out;
1388 }
1389 sigma_dut_print(dut, DUT_MSG_INFO,
1390 "Waiting %d second(s) before processing peer URI",
1391 wait_time);
1392 sleep(wait_time);
1393
1394 snprintf(buf, sizeof(buf), "DPP_QR_CODE %s",
1395 dut->dpp_peer_uri);
1396 if (wpa_command_resp(ifname, buf, buf,
1397 sizeof(buf)) < 0) {
1398 send_resp(dut, conn, SIGMA_ERROR,
1399 "errorCode,Failed to parse URI");
1400 goto out;
1401 }
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05301402 } else if (mutual && action_type &&
1403 strcasecmp(action_type, "ManualDPP") == 0) {
1404 res = get_wpa_cli_events(dut, ctrl, auth_events,
1405 buf, sizeof(buf));
1406 if (res < 0) {
1407 send_resp(dut, conn, SIGMA_COMPLETE,
1408 "BootstrapResult,OK,AuthResult,Timeout");
1409 goto out;
1410 }
1411 sigma_dut_print(dut, DUT_MSG_DEBUG,
1412 "DPP auth result: %s", buf);
Srinivas Dasarie3b13932018-03-26 21:51:40 +05301413 if (strstr(buf, "DPP-NOT-COMPATIBLE")) {
1414 send_resp(dut, conn, SIGMA_COMPLETE,
1415 "BootstrapResult,OK,AuthResult,ROLES_NOT_COMPATIBLE");
1416 goto out;
1417 }
1418
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05301419 if (strstr(buf, "DPP-SCAN-PEER-QR-CODE") == NULL) {
1420 send_resp(dut, conn, SIGMA_ERROR,
1421 "errorCode,No scan request for peer QR Code seen");
1422 goto out;
1423 }
1424
1425 if (dpp_scan_peer_qrcode(dut) < 0) {
1426 send_resp(dut, conn, SIGMA_ERROR,
1427 "errorCode,Failed to scan peer QR Code");
1428 goto out;
1429 }
1430
1431 snprintf(buf, sizeof(buf), "DPP_QR_CODE %s",
1432 dut->dpp_peer_uri);
1433 if (wpa_command_resp(ifname, buf, buf,
1434 sizeof(buf)) < 0) {
1435 send_resp(dut, conn, SIGMA_ERROR,
1436 "errorCode,Failed to parse URI");
1437 goto out;
1438 }
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02001439 }
Jouni Malinend86e5822017-08-29 03:55:32 +03001440 } else {
1441 send_resp(dut, conn, SIGMA_ERROR,
1442 "errorCode,Unknown DPPAuthRole");
1443 goto out;
1444 }
1445
Jouni Malinen3a6b92a2017-12-05 20:22:43 +02001446 if (step && strcasecmp(step, "Timeout") == 0) {
1447 result = "errorCode,Unexpected state";
1448
1449 if (strcasecmp(frametype, "PKEXExchangeResponse") == 0) {
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001450 if (dpp_wait_rx(dut, ctrl, 8, -1) < 0)
Jouni Malinen3a6b92a2017-12-05 20:22:43 +02001451 result = "BootstrapResult,Timeout";
1452 else
1453 result = "BootstrapResult,Errorsent";
1454 }
1455
1456 if (strcasecmp(frametype, "PKEXCRRequest") == 0) {
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001457 if (dpp_wait_rx(dut, ctrl, 9, -1) < 0)
Jouni Malinen3a6b92a2017-12-05 20:22:43 +02001458 result = "BootstrapResult,Timeout";
1459 else
1460 result = "BootstrapResult,Errorsent";
1461 }
1462
1463 if (strcasecmp(frametype, "PKEXCRResponse") == 0) {
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001464 if (dpp_wait_rx(dut, ctrl, 10, -1) < 0)
Jouni Malinen3a6b92a2017-12-05 20:22:43 +02001465 result = "BootstrapResult,Timeout";
1466 else
1467 result = "BootstrapResult,Errorsent";
1468 }
1469
1470 if (strcasecmp(frametype, "AuthenticationRequest") == 0) {
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001471 if (dpp_wait_rx(dut, ctrl, 0, -1) < 0)
Jouni Malinen3a6b92a2017-12-05 20:22:43 +02001472 result = "BootstrapResult,OK,AuthResult,Timeout";
1473 else
1474 result = "BootstrapResult,OK,AuthResult,Errorsent";
1475 }
1476
1477 if (strcasecmp(frametype, "AuthenticationResponse") == 0) {
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001478 if (dpp_wait_rx(dut, ctrl, 1, -1) < 0)
Jouni Malinen3a6b92a2017-12-05 20:22:43 +02001479 result = "BootstrapResult,OK,AuthResult,Timeout";
1480 else
1481 result = "BootstrapResult,OK,AuthResult,Errorsent";
1482 }
1483
1484 if (strcasecmp(frametype, "AuthenticationConfirm") == 0) {
Deepak Dhamdhereecb49d82018-03-08 16:48:28 -08001485 if (strcasecmp(auth_role, "Initiator") == 0) {
Jouni Malinena1199882018-03-28 19:34:59 +03001486 /* This special case of DPPStep,Timeout with
1487 * DPPFrameType,AuthenticationConfirm on an
1488 * Initiator is used to cover need for stopping
1489 * the Initiator/Enrollee from sending out
1490 * Configuration Request message. */
1491 if (strcasecmp(prov_role, "Enrollee") != 0) {
1492 send_resp(dut, conn, SIGMA_ERROR,
1493 "errorCode,Unexpected use of timeout after AuthenticationConfirm TX in Configurator role");
1494 goto out;
1495 }
Srinivas Dasari671c9e12018-03-26 17:57:34 +05301496 if (check_mutual &&
1497 dpp_process_auth_response(
1498 dut, conn, ctrl, auth_events,
1499 action_type, check_mutual,
1500 buf, sizeof(buf)) < 0)
1501 goto out;
Deepak Dhamdhereecb49d82018-03-08 16:48:28 -08001502 if (dpp_wait_tx_status(dut, ctrl, 2) < 0)
1503 result = "BootstrapResult,OK,AuthResult,Timeout";
Deepak Dhamdhereecb49d82018-03-08 16:48:28 -08001504 else
Jouni Malinena1199882018-03-28 19:34:59 +03001505 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationResponse";
Deepak Dhamdhereecb49d82018-03-08 16:48:28 -08001506 } else {
1507 if (dpp_wait_rx(dut, ctrl, 2, -1) < 0)
1508 result = "BootstrapResult,OK,AuthResult,Timeout";
1509 else
1510 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationConfirm";
1511 }
Jouni Malinen3a6b92a2017-12-05 20:22:43 +02001512 }
1513
1514 if (strcasecmp(frametype, "ConfigurationRequest") == 0) {
1515 if (get_wpa_cli_event(dut, ctrl, "DPP-CONF-FAILED",
1516 buf, sizeof(buf)) < 0)
1517 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Timeout";
1518 else
1519 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Errorsent";
1520 }
1521
1522 send_resp(dut, conn, SIGMA_COMPLETE, result);
1523 goto out;
1524 }
1525
Jouni Malinen772299f2017-11-06 00:36:26 +02001526 if (frametype && strcasecmp(frametype, "PKEXExchangeRequest") == 0) {
1527 if (dpp_wait_tx_status(dut, ctrl, 7) < 0)
1528 result = "BootstrapResult,Timeout";
1529 else
1530 result = "BootstrapResult,Errorsent";
1531 send_resp(dut, conn, SIGMA_COMPLETE, result);
1532 goto out;
1533 }
1534
1535 if (frametype && strcasecmp(frametype, "PKEXExchangeResponse") == 0) {
1536 if (dpp_wait_tx_status(dut, ctrl, 8) < 0)
1537 result = "BootstrapResult,Timeout";
1538 else
1539 result = "BootstrapResult,Errorsent";
1540 send_resp(dut, conn, SIGMA_COMPLETE, result);
1541 goto out;
1542 }
1543
1544 if (frametype && strcasecmp(frametype, "PKEXCRRequest") == 0) {
1545 if (dpp_wait_tx_status(dut, ctrl, 9) < 0)
1546 result = "BootstrapResult,Timeout";
1547 else
1548 result = "BootstrapResult,Errorsent";
1549 send_resp(dut, conn, SIGMA_COMPLETE, result);
1550 goto out;
1551 }
1552
1553 if (frametype && strcasecmp(frametype, "PKEXCRResponse") == 0) {
1554 if (dpp_wait_tx_status(dut, ctrl, 10) < 0)
1555 result = "BootstrapResult,Timeout";
1556 else
1557 result = "BootstrapResult,Errorsent";
1558 send_resp(dut, conn, SIGMA_COMPLETE, result);
1559 goto out;
1560 }
1561
Jouni Malinen6792ff42018-02-13 00:25:56 +02001562 if (!frametype && strcasecmp(bs, "PKEX") == 0 &&
1563 strcasecmp(auth_role, "Responder") == 0) {
1564 if (dpp_wait_tx_status(dut, ctrl, 10) < 0) {
1565 send_resp(dut, conn, SIGMA_COMPLETE,
1566 "BootstrapResult,Timeout");
1567 goto out;
1568 }
1569 }
1570
1571 if (!frametype && strcasecmp(bs, "PKEX") == 0 &&
1572 strcasecmp(auth_role, "Initiator") == 0) {
1573 if (dpp_wait_tx(dut, ctrl, 0) < 0) {
1574 send_resp(dut, conn, SIGMA_COMPLETE,
1575 "BootstrapResult,Timeout");
1576 goto out;
1577 }
1578 }
1579
Jouni Malinen772299f2017-11-06 00:36:26 +02001580 if (frametype && strcasecmp(frametype, "AuthenticationRequest") == 0) {
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001581 if (dpp_wait_tx_status(dut, ctrl, 0) < 0) {
1582 send_resp(dut, conn, SIGMA_COMPLETE,
1583 "BootstrapResult,OK,AuthResult,Timeout");
1584 goto out;
1585 }
1586
1587 if (dpp_wait_rx(dut, ctrl, 1, 5) < 0)
1588 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,None";
Deepak Dhamdhereb9f1eb92018-03-08 16:36:22 -08001589 else if (get_wpa_cli_events(dut, ctrl, auth_events,
1590 buf, sizeof(buf)) >= 0 &&
1591 strstr(buf, "DPP-RESPONSE-PENDING") != NULL)
1592 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationResponseWithStatusPending";
Jouni Malinen772299f2017-11-06 00:36:26 +02001593 else
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001594 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationResponse";
Jouni Malinen772299f2017-11-06 00:36:26 +02001595 send_resp(dut, conn, SIGMA_COMPLETE, result);
1596 goto out;
1597 }
1598
1599 if (frametype && strcasecmp(frametype, "AuthenticationResponse") == 0) {
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001600 if (dpp_wait_tx_status(dut, ctrl, 1) < 0) {
1601 send_resp(dut, conn, SIGMA_COMPLETE,
1602 "BootstrapResult,OK,AuthResult,Timeout");
1603 goto out;
1604 }
1605
1606 if (dpp_wait_rx(dut, ctrl, 2, 5) < 0)
1607 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationRequest";
Jouni Malinen772299f2017-11-06 00:36:26 +02001608 else
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001609 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationConfirm";
Jouni Malinen772299f2017-11-06 00:36:26 +02001610 send_resp(dut, conn, SIGMA_COMPLETE, result);
1611 goto out;
1612 }
1613
Srinivas Dasari8d88d822018-03-26 17:57:34 +05301614 if (dpp_process_auth_response(dut, conn, ctrl, auth_events, action_type,
1615 check_mutual, buf, sizeof(buf)) < 0)
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05301616 goto out;
Jouni Malinend1e22f72017-12-05 21:12:17 +02001617
Jouni Malinen772299f2017-11-06 00:36:26 +02001618 if (frametype && strcasecmp(frametype, "AuthenticationConfirm") == 0) {
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001619 if (dpp_wait_tx_status(dut, ctrl, 2) < 0) {
1620 send_resp(dut, conn, SIGMA_COMPLETE,
1621 "BootstrapResult,OK,AuthResult,Timeout");
1622 goto out;
1623 }
1624
1625 if (dpp_wait_rx_conf_req(dut, ctrl, 5) < 0)
1626 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationResponse";
Jouni Malinen772299f2017-11-06 00:36:26 +02001627 else
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001628 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,ConfigurationRequest";
Jouni Malinen772299f2017-11-06 00:36:26 +02001629 send_resp(dut, conn, SIGMA_COMPLETE, result);
1630 goto out;
1631 }
1632
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05301633 if (strstr(buf, "DPP-AUTH-DIRECTION")) {
Jouni Malinen2e9c8a42017-11-19 12:06:18 +02001634 res = get_wpa_cli_events(dut, ctrl, auth_events,
1635 buf, sizeof(buf));
1636 if (res < 0) {
1637 send_resp(dut, conn, SIGMA_COMPLETE,
1638 "BootstrapResult,OK,AuthResult,Timeout");
1639 goto out;
1640 }
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05301641
1642 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP auth result: %s", buf);
Jouni Malinen2e9c8a42017-11-19 12:06:18 +02001643 }
1644
Jouni Malinend86e5822017-08-29 03:55:32 +03001645 if (strstr(buf, "DPP-NOT-COMPATIBLE")) {
1646 send_resp(dut, conn, SIGMA_COMPLETE,
1647 "BootstrapResult,OK,AuthResult,ROLES_NOT_COMPATIBLE");
1648 goto out;
1649 }
1650
1651 if (!strstr(buf, "DPP-AUTH-SUCCESS")) {
1652 send_resp(dut, conn, SIGMA_COMPLETE,
1653 "BootstrapResult,OK,AuthResult,FAILED");
1654 goto out;
1655 }
1656
Jouni Malinen772299f2017-11-06 00:36:26 +02001657 if (frametype && strcasecmp(frametype, "ConfigurationRequest") == 0) {
1658 res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE",
1659 buf, sizeof(buf));
1660 if (res < 0)
1661 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Timeout";
1662 else
1663 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Errorsent";
1664 send_resp(dut, conn, SIGMA_COMPLETE, result);
1665 goto out;
1666 }
1667
1668 if (frametype && strcasecmp(frametype, "ConfigurationResponse") == 0) {
1669 res = get_wpa_cli_event(dut, ctrl, "DPP-CONF-SENT",
1670 buf, sizeof(buf));
1671 if (res < 0)
1672 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Timeout";
1673 else
Deepak Dhamdhere9b4f2752018-03-08 16:36:22 -08001674 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Errorsent,LastFrameReceived,ConfigurationRequest";
Jouni Malinen772299f2017-11-06 00:36:26 +02001675 send_resp(dut, conn, SIGMA_COMPLETE, result);
1676 goto out;
1677 }
1678
Jouni Malinend86e5822017-08-29 03:55:32 +03001679 res = get_wpa_cli_events(dut, ctrl, conf_events, buf, sizeof(buf));
1680 if (res < 0) {
1681 send_resp(dut, conn, SIGMA_COMPLETE,
1682 "BootstrapResult,OK,AuthResult,OK,ConfResult,Timeout");
1683 goto out;
1684 }
1685 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP conf result: %s", buf);
1686
1687 if (!strstr(buf, "DPP-CONF-SENT") &&
1688 !strstr(buf, "DPP-CONF-RECEIVED")) {
1689 send_resp(dut, conn, SIGMA_COMPLETE,
1690 "BootstrapResult,OK,AuthResult,OK,ConfResult,FAILED");
1691 goto out;
1692 }
1693
1694 if (sigma_dut_is_ap(dut) &&
1695 strcasecmp(prov_role, "Enrollee") == 0) {
Jouni Malinen174db642017-11-27 20:16:29 +02001696 update_ap:
Jouni Malinend86e5822017-08-29 03:55:32 +03001697 res = dpp_hostapd_conf_update(dut, conn, ifname, ctrl);
1698 if (res == 0)
1699 goto out;
1700 if (res < 0) {
1701 send_resp(dut, conn, SIGMA_ERROR, NULL);
1702 goto out;
1703 }
1704 }
1705
1706 if (strcasecmp(wait_conn, "Yes") == 0 &&
1707 !sigma_dut_is_ap(dut) &&
1708 strcasecmp(prov_role, "Enrollee") == 0) {
Jouni Malinen85a5a2e2018-04-10 21:40:18 +03001709 int netw_id;
1710 char *pos;
1711
1712 res = get_wpa_cli_event(dut, ctrl, "DPP-NETWORK-ID",
1713 buf, sizeof(buf));
1714 if (res < 0) {
1715 send_resp(dut, conn, SIGMA_ERROR,
1716 "errorCode,No DPP-NETWORK-ID");
1717 goto out;
1718 }
1719 pos = strchr(buf, ' ');
1720 if (!pos) {
1721 send_resp(dut, conn, SIGMA_ERROR,
1722 "errorCode,Invalid DPP-NETWORK-ID");
1723 goto out;
1724 }
1725 pos++;
1726 netw_id = atoi(pos);
1727 snprintf(buf, sizeof(buf), "GET_NETWORK %d key_mgmt", netw_id);
1728 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0) {
1729 send_resp(dut, conn, SIGMA_ERROR,
1730 "errorCode,Could not fetch provisioned key_mgmt");
1731 goto out;
1732 }
1733 if (strncmp(buf, "SAE", 3) == 0) {
1734 /* SAE generates PMKSA-CACHE-ADDED event */
1735 not_dpp_akm = 1;
1736 }
Jouni Malinenfbb268d2017-11-17 18:53:49 +02001737 wait_connect:
Jouni Malinen53558e02017-11-06 12:58:28 +02001738 if (frametype && strcasecmp(frametype,
1739 "PeerDiscoveryRequest") == 0) {
1740 if (dpp_wait_tx_status(dut, ctrl, 5) < 0)
1741 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Timeout";
1742 else
1743 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Errorsent";
1744 send_resp(dut, conn, SIGMA_COMPLETE, result);
1745 goto out;
1746 }
1747
Jouni Malinend86e5822017-08-29 03:55:32 +03001748 res = get_wpa_cli_events(dut, ctrl, conn_events,
1749 buf, sizeof(buf));
1750 if (res < 0) {
1751 send_resp(dut, conn, SIGMA_COMPLETE,
1752 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Timeout,NetworkConnectResult,Timeout");
1753 goto out;
1754 }
1755 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP connect result: %s",
1756 buf);
1757
1758 if (strstr(buf, "PMKSA-CACHE-ADDED")) {
1759 res = get_wpa_cli_events(dut, ctrl, conn_events,
1760 buf, sizeof(buf));
1761 if (res < 0) {
1762 send_resp(dut, conn, SIGMA_COMPLETE,
Jouni Malinen85a5a2e2018-04-10 21:40:18 +03001763 not_dpp_akm ?
1764 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkConnectResult,Timeout" :
Jouni Malinend86e5822017-08-29 03:55:32 +03001765 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,Timeout");
1766 goto out;
1767 }
1768 sigma_dut_print(dut, DUT_MSG_DEBUG,
1769 "DPP connect result: %s", buf);
1770 if (strstr(buf, "CTRL-EVENT-CONNECTED"))
1771 send_resp(dut, conn, SIGMA_COMPLETE,
Jouni Malinen85a5a2e2018-04-10 21:40:18 +03001772 not_dpp_akm ?
1773 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkConnectResult,OK" :
Jouni Malinend86e5822017-08-29 03:55:32 +03001774 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,OK");
1775 else
1776 send_resp(dut, conn, SIGMA_COMPLETE,
Jouni Malinen85a5a2e2018-04-10 21:40:18 +03001777 not_dpp_akm ?
1778 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkConnectResult,Timeout" :
Jouni Malinend86e5822017-08-29 03:55:32 +03001779 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,Timeout");
1780 goto out;
1781 }
1782
1783 send_resp(dut, conn, SIGMA_COMPLETE,
1784 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkConnectResult,OK");
1785 goto out;
1786 }
1787
Jouni Malinen53558e02017-11-06 12:58:28 +02001788 if (strcasecmp(wait_conn, "Yes") == 0 &&
1789 frametype && strcasecmp(frametype, "PeerDiscoveryResponse") == 0) {
1790 if (dpp_wait_tx_status(dut, ctrl, 6) < 0)
1791 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Timeout";
1792 else
1793 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Errorsent";
1794 send_resp(dut, conn, SIGMA_COMPLETE, result);
1795 goto out;
1796 }
1797
Jouni Malinend86e5822017-08-29 03:55:32 +03001798 send_resp(dut, conn, SIGMA_COMPLETE,
1799 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK");
1800out:
1801 wpa_ctrl_detach(ctrl);
1802 wpa_ctrl_close(ctrl);
1803 dut->default_timeout = old_timeout;
1804 return 0;
1805}
1806
1807
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05301808static int dpp_manual_dpp(struct sigma_dut *dut,
1809 struct sigma_conn *conn,
1810 struct sigma_cmd *cmd)
1811{
1812 const char *auth_role = get_param(cmd, "DPPAuthRole");
priyadharshini gowthaman2fa651b2018-04-16 17:02:47 -07001813 const char *self_conf = get_param(cmd, "DPPSelfConfigure");
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05301814 int res = -1, success;
1815 const char *val;
1816 unsigned int old_timeout;
1817
1818 if (!auth_role) {
1819 send_resp(dut, conn, SIGMA_ERROR,
1820 "errorCode,Missing DPPAuthRole");
1821 return 0;
1822 }
1823
priyadharshini gowthaman2fa651b2018-04-16 17:02:47 -07001824 if (!self_conf)
1825 self_conf = "no";
1826
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05301827 old_timeout = dut->default_timeout;
1828 val = get_param(cmd, "DPPTimeout");
1829 if (val && atoi(val) > 0) {
1830 dut->default_timeout = atoi(val);
1831 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP timeout: %u",
1832 dut->default_timeout);
1833 }
1834
1835 res = dpp_get_local_bootstrap(dut, conn, cmd, 0, &success);
1836 if (res || !success)
1837 goto out;
1838
1839 if (strcasecmp(auth_role, "Responder") == 0) {
1840 res = dpp_display_own_qrcode(dut);
1841 if (res < 0)
1842 goto out;
1843
1844 res = dpp_automatic_dpp(dut, conn, cmd);
1845 goto out;
1846 }
1847
1848 if (strcasecmp(auth_role, "Initiator") == 0) {
priyadharshini gowthaman2fa651b2018-04-16 17:02:47 -07001849 if (strcasecmp(self_conf, "Yes") != 0) {
1850 res = dpp_scan_peer_qrcode(dut);
1851 if (res < 0) {
1852 send_resp(dut, conn, SIGMA_ERROR,
1853 "errorCode,Failed to scan peer QR Code");
1854 res = 0;
1855 goto out;
1856 }
Jouni Malinen1a38cc32018-01-05 20:59:00 +02001857 }
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05301858
1859 res = dpp_automatic_dpp(dut, conn, cmd);
1860 goto out;
1861 }
1862
1863 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unknown DPPAuthRole");
1864 res = 0;
1865out:
1866 dut->default_timeout = old_timeout;
1867 return res;
1868}
1869
1870
Jouni Malinend86e5822017-08-29 03:55:32 +03001871int dpp_dev_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
1872 struct sigma_cmd *cmd)
1873{
1874 const char *type = get_param(cmd, "DPPActionType");
1875 const char *bs = get_param(cmd, "DPPBS");
1876
1877 if (!bs) {
1878 send_resp(dut, conn, SIGMA_ERROR,
1879 "errorCode,Missing DPPBS");
1880 return 0;
1881 }
1882
1883 if (!type) {
1884 send_resp(dut, conn, SIGMA_ERROR,
1885 "errorCode,Missing DPPActionType");
1886 return 0;
1887 }
1888
1889 if (strcasecmp(type, "GetLocalBootstrap") == 0)
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05301890 return dpp_get_local_bootstrap(dut, conn, cmd, 1, NULL);
Jouni Malinend86e5822017-08-29 03:55:32 +03001891 if (strcasecmp(type, "SetPeerBootstrap") == 0)
1892 return dpp_set_peer_bootstrap(dut, conn, cmd);
1893 if (strcasecmp(type, "ManualDPP") == 0)
1894 return dpp_manual_dpp(dut, conn, cmd);
1895 if (strcasecmp(type, "AutomaticDPP") == 0)
1896 return dpp_automatic_dpp(dut, conn, cmd);
1897
1898 send_resp(dut, conn, SIGMA_ERROR,
1899 "errorCode,Unsupported DPPActionType");
1900 return 0;
1901}