blob: 7c327d4dc91fc386084f97ffb93b4fce7c637ce9 [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;
38 dut->ap_mode = AP_11ng;
39 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
493static int dpp_wait_tx_status(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 res = get_wpa_cli_event(dut, ctrl, "DPP-TX-STATUS",
509 buf, sizeof(buf));
510 if (res < 0 || strstr(buf, "result=FAILED") != NULL)
511 return -1;
512
513 return 0;
514}
515
516
Jouni Malinen3a6b92a2017-12-05 20:22:43 +0200517static int dpp_wait_rx(struct sigma_dut *dut, struct wpa_ctrl *ctrl,
Jouni Malinen3e4344e2018-01-22 11:47:37 +0200518 int frame_type, unsigned int max_wait)
Jouni Malinen3a6b92a2017-12-05 20:22:43 +0200519{
520 char buf[200], tmp[20];
521 int res;
Jouni Malinen9a3415c2018-01-10 22:12:22 +0200522 unsigned int old_timeout;
523
524 old_timeout = dut->default_timeout;
525 if (max_wait > 0 && dut->default_timeout > max_wait)
526 dut->default_timeout = max_wait;
Jouni Malinen3a6b92a2017-12-05 20:22:43 +0200527
528 snprintf(tmp, sizeof(tmp), "type=%d", frame_type);
529 for (;;) {
530 res = get_wpa_cli_event(dut, ctrl, "DPP-RX", buf, sizeof(buf));
Jouni Malinen9a3415c2018-01-10 22:12:22 +0200531 if (res < 0) {
532 dut->default_timeout = old_timeout;
Jouni Malinen3a6b92a2017-12-05 20:22:43 +0200533 return -1;
Jouni Malinen9a3415c2018-01-10 22:12:22 +0200534 }
Jouni Malinen3a6b92a2017-12-05 20:22:43 +0200535 if (strstr(buf, tmp) != NULL)
536 break;
537 }
538
Jouni Malinen9a3415c2018-01-10 22:12:22 +0200539 dut->default_timeout = old_timeout;
540 return 0;
541}
542
543
544static int dpp_wait_rx_conf_req(struct sigma_dut *dut, struct wpa_ctrl *ctrl,
Jouni Malinen3e4344e2018-01-22 11:47:37 +0200545 unsigned int max_wait)
Jouni Malinen9a3415c2018-01-10 22:12:22 +0200546{
547 char buf[200];
548 int res;
549 unsigned int old_timeout;
550
551 old_timeout = dut->default_timeout;
552 if (max_wait > 0 && dut->default_timeout > max_wait)
553 dut->default_timeout = max_wait;
554
555 for (;;) {
556 res = get_wpa_cli_event(dut, ctrl, "DPP-CONF-REQ-RX",
557 buf, sizeof(buf));
558 if (res < 0) {
559 dut->default_timeout = old_timeout;
560 return -1;
561 }
562
563 break;
564 }
565
566 dut->default_timeout = old_timeout;
Jouni Malinen3a6b92a2017-12-05 20:22:43 +0200567 return 0;
568}
569
570
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530571static int dpp_scan_peer_qrcode(struct sigma_dut *dut)
Jouni Malinend86e5822017-08-29 03:55:32 +0300572{
Jouni Malinen1a38cc32018-01-05 20:59:00 +0200573#ifdef ANDROID
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530574 char buf[100];
575 char *buf2 = NULL;
576 FILE *fp = NULL;
577 uint32_t length;
578 unsigned int count;
579
580 unlink(dpp_qrcode_file);
581
582 snprintf(buf, sizeof(buf),
583 "am start -n w1.fi.wpadebug/w1.fi.wpadebug.QrCodeScannerActivity");
584 if (system(buf) != 0) {
585 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to launch Scanner");
586 return -1;
587 }
588
589 count = 0;
590 while (!(fp = fopen(dpp_qrcode_file, "r"))) {
591 if (count > dut->default_timeout) {
592 sigma_dut_print(dut, DUT_MSG_ERROR,
593 "Failed to open dpp_qrcode_file - QR Code scanning timed out");
594 return -1;
595 }
596
597 sleep(1);
598 count++;
599 }
600
601 if (fseek(fp, 0, SEEK_END) < 0 || (length = ftell(fp)) <= 0 ||
602 fseek(fp, 0, SEEK_SET) < 0) {
603 sigma_dut_print(dut, DUT_MSG_ERROR,
604 "Failed to get QR Code result file length");
605 fclose(fp);
606 return -1;
607 }
608
609 buf2 = malloc(length + 1);
610 if (!buf2) {
611 fclose(fp);
612 return -1;
613 }
614
615 if (fread(buf2, 1, length, fp) != length) {
616 fclose(fp);
617 free(buf2);
618 return -1;
619 }
620
621 fclose(fp);
622 buf2[length] = '\0';
623
624 free(dut->dpp_peer_uri);
625 dut->dpp_peer_uri = strdup(buf2);
626 free(buf2);
627 return 0;
Jouni Malinen1a38cc32018-01-05 20:59:00 +0200628#else /* ANDROID */
629 pid_t pid;
630 int pid_status;
631 int pipe_out[2];
632 char buf[4000], *pos;
633 ssize_t len;
634 int res = -1, ret;
635 struct timeval tv;
636 fd_set rfd;
637
638 if (pipe(pipe_out) != 0) {
639 perror("pipe");
640 return -1;
641 }
642
643 pid = fork();
644 if (pid < 0) {
645 perror("fork");
646 close(pipe_out[0]);
647 close(pipe_out[1]);
648 return -1;
649 }
650
651 if (pid == 0) {
652 char *argv[4] = { "zbarcam", "--raw", "--prescale=320x240",
653 NULL };
654
655 dup2(pipe_out[1], STDOUT_FILENO);
656 close(pipe_out[0]);
657 close(pipe_out[1]);
658 execv("/usr/bin/zbarcam", argv);
659 perror("execv");
660 exit(0);
661 return -1;
662 }
663
664 close(pipe_out[1]);
665
666 FD_ZERO(&rfd);
667 FD_SET(pipe_out[0], &rfd);
668 tv.tv_sec = dut->default_timeout;
669 tv.tv_usec = 0;
670
671 ret = select(pipe_out[0] + 1, &rfd, NULL, NULL, &tv);
672 if (ret < 0) {
673 perror("select");
674 goto out;
675 }
676 if (ret == 0) {
677 sigma_dut_print(dut, DUT_MSG_DEBUG,
678 "QR Code scanning timed out");
679 goto out;
680 }
681
682 len = read(pipe_out[0], buf, sizeof(buf));
683 if (len <= 0)
684 goto out;
685 if (len == sizeof(buf))
686 len--;
687 buf[len] = '\0';
688 pos = strchr(buf, '\n');
689 if (pos)
690 *pos = '\0';
691 sigma_dut_print(dut, DUT_MSG_DEBUG, "URI from QR scanner: %s", buf);
692
693 free(dut->dpp_peer_uri);
694 dut->dpp_peer_uri = strdup(buf);
695 res = 0;
696out:
697 close(pipe_out[0]);
698 kill(pid, SIGTERM);
699 waitpid(pid, &pid_status, 0);
700
701 return res;
702#endif /* ANDROID */
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530703}
704
705
706static int dpp_display_own_qrcode(struct sigma_dut *dut)
707{
708 char buf[200], resp[2000];
709 const char *ifname = get_station_ifname();
Jouni Malinen1a38cc32018-01-05 20:59:00 +0200710#ifdef ANDROID
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530711 FILE *fp;
Jouni Malinen1a38cc32018-01-05 20:59:00 +0200712#else /* ANDROID */
713 pid_t pid;
714 int pid_status;
715#endif /* ANDROID */
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530716
717 snprintf(buf, sizeof(buf), "DPP_BOOTSTRAP_GET_URI %d",
718 dut->dpp_local_bootstrap);
719 if (wpa_command_resp(ifname, buf, resp, sizeof(resp)) < 0 ||
720 strncmp(resp, "FAIL", 4) == 0)
721 return -2;
Jouni Malinen1a38cc32018-01-05 20:59:00 +0200722 sigma_dut_print(dut, DUT_MSG_DEBUG, "Own bootstrap URI: %s", resp);
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530723
Jouni Malinen1a38cc32018-01-05 20:59:00 +0200724#ifdef ANDROID
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530725 unlink(dpp_qrcode_file);
726
727 fp = fopen(dpp_qrcode_file, "w");
728 if (!fp) {
729 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open file %s",
730 dpp_qrcode_file);
731 return -2;
732 }
733
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530734 fwrite(resp, 1, strlen(resp), fp);
735 fclose(fp);
736
737 snprintf(buf, sizeof(buf),
738 "am start -n w1.fi.wpadebug/w1.fi.wpadebug.QrCodeDisplayActivity");
739 if (system(buf) != 0) {
740 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to display QR Code");
741 return -1;
742 }
Jouni Malinen1a38cc32018-01-05 20:59:00 +0200743#else /* ANDROID */
744 pid = fork();
745 if (pid < 0) {
746 perror("fork");
747 return -1;
748 }
749
750 if (pid == 0) {
751 char *argv[3] = { "qr", resp, NULL };
752
753 execv("/usr/bin/qr", argv);
754 perror("execv");
755 exit(0);
756 return -1;
757 }
758
759 waitpid(pid, &pid_status, 0);
760#endif /* ANDROID */
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530761
762 return 0;
Jouni Malinend86e5822017-08-29 03:55:32 +0300763}
764
765
766static int dpp_automatic_dpp(struct sigma_dut *dut,
767 struct sigma_conn *conn,
768 struct sigma_cmd *cmd)
769{
770 const char *bs = get_param(cmd, "DPPBS");
771 const char *auth_role = get_param(cmd, "DPPAuthRole");
772 const char *prov_role = get_param(cmd, "DPPProvisioningRole");
773 const char *pkex_code = get_param(cmd, "DPPPKEXCode");
774 const char *pkex_code_id = get_param(cmd, "DPPPKEXCodeIdentifier");
775 const char *wait_conn = get_param(cmd, "DPPWaitForConnect");
776 const char *self_conf = get_param(cmd, "DPPSelfConfigure");
Jouni Malinen772299f2017-11-06 00:36:26 +0200777 const char *step = get_param(cmd, "DPPStep");
778 const char *frametype = get_param(cmd, "DPPFrameType");
779 const char *attr = get_param(cmd, "DPPIEAttribute");
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530780 const char *action_type = get_param(cmd, "DPPActionType");
Jouni Malinend86e5822017-08-29 03:55:32 +0300781 const char *role;
782 const char *val;
783 const char *conf_role;
Jouni Malinend86e5822017-08-29 03:55:32 +0300784 int conf_index = -1;
785 char buf[2000];
786 char conf_ssid[100];
787 char conf_pass[100];
788 char pkex_identifier[200];
789 struct wpa_ctrl *ctrl;
790 int res;
791 unsigned int old_timeout;
792 int own_pkex_id = -1;
793 const char *ifname = get_station_ifname();
794 const char *auth_events[] = {
795 "DPP-AUTH-SUCCESS",
796 "DPP-NOT-COMPATIBLE",
797 "DPP-RESPONSE-PENDING",
798 "DPP-SCAN-PEER-QR-CODE",
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530799 "DPP-AUTH-DIRECTION",
Jouni Malinend86e5822017-08-29 03:55:32 +0300800 NULL
801 };
802 const char *conf_events[] = {
803 "DPP-CONF-RECEIVED",
804 "DPP-CONF-SENT",
805 "DPP-CONF-FAILED",
806 NULL
807 };
808 const char *conn_events[] = {
809 "PMKSA-CACHE-ADDED",
810 "CTRL-EVENT-CONNECTED",
811 NULL
812 };
Jouni Malinen3d291f72017-11-02 11:31:05 +0200813 const char *groups_override = NULL;
Jouni Malinen772299f2017-11-06 00:36:26 +0200814 const char *result;
Jouni Malinend1e22f72017-12-05 21:12:17 +0200815 int check_mutual = 0;
Jouni Malinene89cdbf2017-12-11 20:18:24 +0200816 int enrollee_ap;
Jouni Malinenf2fa0d02018-01-11 20:51:31 +0200817 int force_gas_fragm = 0;
Jouni Malinend86e5822017-08-29 03:55:32 +0300818
819 if (!wait_conn)
820 wait_conn = "no";
821 if (!self_conf)
822 self_conf = "no";
823
824 if (!auth_role) {
825 send_resp(dut, conn, SIGMA_ERROR,
826 "errorCode,Missing DPPAuthRole");
827 return 0;
828 }
829
830 if (!prov_role) {
831 send_resp(dut, conn, SIGMA_ERROR,
832 "errorCode,Missing DPPProvisioningRole");
833 return 0;
834 }
835
Jouni Malinene89cdbf2017-12-11 20:18:24 +0200836 val = get_param(cmd, "DPPConfEnrolleeRole");
837 if (val)
838 enrollee_ap = strcasecmp(val, "AP") == 0;
839 else
840 enrollee_ap = sigma_dut_is_ap(dut);
841
Jouni Malinen3a6b92a2017-12-05 20:22:43 +0200842 if ((step || frametype) && (!step || !frametype)) {
Jouni Malinen772299f2017-11-06 00:36:26 +0200843 send_resp(dut, conn, SIGMA_ERROR,
844 "errorCode,Invalid DPPStep,DPPFrameType,DPPIEAttribute combination");
845 return 0;
846 }
847
Jouni Malinend86e5822017-08-29 03:55:32 +0300848 if (sigma_dut_is_ap(dut)) {
849 if (!dut->hostapd_ifname) {
850 sigma_dut_print(dut, DUT_MSG_ERROR,
851 "hostapd ifname not specified (-j)");
852 return -2;
853 }
854 ifname = dut->hostapd_ifname;
855
856 if (dpp_hostapd_run(dut) < 0) {
857 send_resp(dut, conn, SIGMA_ERROR,
858 "errorCode,Failed to start hostapd");
859 return 0;
860 }
861 }
862
Jouni Malinen67acb0c2017-11-21 01:01:54 +0200863 if (strcasecmp(prov_role, "Configurator") == 0 ||
864 strcasecmp(prov_role, "Both") == 0) {
Jouni Malinend86e5822017-08-29 03:55:32 +0300865 if (dut->dpp_conf_id < 0) {
866 snprintf(buf, sizeof(buf),
867 "DPP_CONFIGURATOR_ADD curve=%s",
868 dpp_get_curve(cmd, "DPPSigningKeyECC"));
869 if (wpa_command_resp(ifname, buf,
870 buf, sizeof(buf)) < 0) {
871 send_resp(dut, conn, SIGMA_ERROR,
872 "errorCode,Failed to set up configurator");
873 return 0;
874 }
875 dut->dpp_conf_id = atoi(buf);
876 }
Jouni Malinen67acb0c2017-11-21 01:01:54 +0200877 if (strcasecmp(prov_role, "Configurator") == 0)
878 role = "configurator";
879 else
880 role = "either";
Jouni Malinend86e5822017-08-29 03:55:32 +0300881 } else if (strcasecmp(prov_role, "Enrollee") == 0) {
882 role = "enrollee";
883 } else {
884 send_resp(dut, conn, SIGMA_ERROR,
885 "errorCode,Unknown DPPProvisioningRole");
886 return 0;
887 }
888
889 pkex_identifier[0] = '\0';
890 if (strcasecmp(bs, "PKEX") == 0) {
Jouni Malinen4f47a272017-11-04 12:29:11 +0200891 if (sigma_dut_is_ap(dut) && dut->ap_channel != 6) {
892 /* For now, have to make operating channel match DPP
893 * listen channel. This should be removed once hostapd
894 * has support for DPP listen on non-operating channel.
895 */
896 sigma_dut_print(dut, DUT_MSG_INFO,
897 "Update hostapd operating channel to match listen needs");
898 dut->ap_channel = 6;
priyadharshini gowthamanb4de1962018-01-15 12:21:04 -0800899
900 if (get_driver_type() == DRIVER_OPENWRT) {
901 snprintf(buf, sizeof(buf),
902 "iwconfig %s channel %d",
903 dut->hostapd_ifname, dut->ap_channel);
904 run_system(dut, buf);
905 }
906
Jouni Malinen4f47a272017-11-04 12:29:11 +0200907 if (wpa_command(ifname, "SET channel 6") < 0 ||
908 wpa_command(ifname, "DISABLE") < 0 ||
909 wpa_command(ifname, "ENABLE") < 0) {
910 send_resp(dut, conn, SIGMA_ERROR,
911 "errorCode,Failed to update channel");
912 return 0;
913 }
914 }
915
Jouni Malinend86e5822017-08-29 03:55:32 +0300916 if (!pkex_code) {
917 send_resp(dut, conn, SIGMA_ERROR,
918 "errorCode,Missing DPPPKEXCode");
919 return 0;
920 }
921
922 if (pkex_code_id)
923 snprintf(pkex_identifier, sizeof(pkex_identifier),
924 "identifier=%s ", pkex_code_id);
925
926 snprintf(buf, sizeof(buf),
927 "DPP_BOOTSTRAP_GEN type=pkex curve=%s",
928 dpp_get_curve(cmd, "DPPCryptoIdentifier"));
929 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0) {
930 send_resp(dut, conn, SIGMA_ERROR,
931 "errorCode,Failed to set up PKEX");
932 return 0;
933 }
934 own_pkex_id = atoi(buf);
935 }
936
937 ctrl = open_wpa_mon(ifname);
938 if (!ctrl) {
939 sigma_dut_print(dut, DUT_MSG_ERROR,
940 "Failed to open wpa_supplicant monitor connection");
941 return -2;
942 }
943
944 old_timeout = dut->default_timeout;
945 val = get_param(cmd, "DPPTimeout");
946 if (val && atoi(val) > 0) {
947 dut->default_timeout = atoi(val);
948 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP timeout: %u",
949 dut->default_timeout);
950 }
951
952 conf_ssid[0] = '\0';
953 conf_pass[0] = '\0';
954 val = get_param(cmd, "DPPConfIndex");
955 if (val)
956 conf_index = atoi(val);
Jouni Malinend86e5822017-08-29 03:55:32 +0300957 switch (conf_index) {
Jouni Malinen258cc262017-10-13 00:19:56 +0300958 case -1:
959 conf_role = NULL;
960 break;
Jouni Malinend86e5822017-08-29 03:55:32 +0300961 case 1:
962 ascii2hexstr("DPPNET01", buf);
963 snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
Jouni Malinene89cdbf2017-12-11 20:18:24 +0200964 if (enrollee_ap) {
Jouni Malinend86e5822017-08-29 03:55:32 +0300965 conf_role = "ap-dpp";
Jouni Malinen3d291f72017-11-02 11:31:05 +0200966 groups_override = "[{\"groupId\":\"DPPGROUP_DPP_INFRA\",\"netRole\":\"ap\"}]";
967 } else {
Jouni Malinend86e5822017-08-29 03:55:32 +0300968 conf_role = "sta-dpp";
Jouni Malinen3d291f72017-11-02 11:31:05 +0200969 groups_override = "[{\"groupId\":\"DPPGROUP_DPP_INFRA\",\"netRole\":\"sta\"}]";
970 }
Jouni Malinend86e5822017-08-29 03:55:32 +0300971 break;
972 case 2:
973 ascii2hexstr("DPPNET01", buf);
974 snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
Jouni Malinen8f81cdf2017-09-15 18:15:18 +0300975 snprintf(conf_pass, sizeof(conf_pass),
976 "psk=10506e102ad1e7f95112f6b127675bb8344dacacea60403f3fa4055aec85b0fc");
Jouni Malinene89cdbf2017-12-11 20:18:24 +0200977 if (enrollee_ap)
Jouni Malinend86e5822017-08-29 03:55:32 +0300978 conf_role = "ap-psk";
979 else
980 conf_role = "sta-psk";
981 break;
982 case 3:
983 ascii2hexstr("DPPNET01", buf);
984 snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
985 ascii2hexstr("ThisIsDppPassphrase", buf);
986 snprintf(conf_pass, sizeof(conf_pass), "pass=%s", buf);
Jouni Malinene89cdbf2017-12-11 20:18:24 +0200987 if (enrollee_ap)
Jouni Malinend86e5822017-08-29 03:55:32 +0300988 conf_role = "ap-psk";
989 else
990 conf_role = "sta-psk";
991 break;
Jouni Malinen3d291f72017-11-02 11:31:05 +0200992 case 4:
993 ascii2hexstr("DPPNET01", buf);
994 snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
Jouni Malinene89cdbf2017-12-11 20:18:24 +0200995 if (enrollee_ap) {
Jouni Malinen3d291f72017-11-02 11:31:05 +0200996 conf_role = "ap-dpp";
997 groups_override = "[{\"groupId\":\"DPPGROUP_DPP_INFRA2\",\"netRole\":\"ap\"}]";
998 } else {
999 conf_role = "sta-dpp";
1000 groups_override = "[{\"groupId\":\"DPPGROUP_DPP_INFRA2\",\"netRole\":\"sta\"}]";
1001 }
1002 break;
Jouni Malinen7d031c72018-01-09 19:39:56 +02001003 case 5:
1004 ascii2hexstr("DPPNET01", buf);
1005 snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
1006 ascii2hexstr("ThisIsDppPassphrase", buf);
1007 snprintf(conf_pass, sizeof(conf_pass), "pass=%s", buf);
1008 if (enrollee_ap)
1009 conf_role = "ap-sae";
1010 else
1011 conf_role = "sta-sae";
1012 break;
1013 case 6:
1014 ascii2hexstr("DPPNET01", buf);
1015 snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
1016 ascii2hexstr("ThisIsDppPassphrase", buf);
1017 snprintf(conf_pass, sizeof(conf_pass), "pass=%s", buf);
1018 if (enrollee_ap)
1019 conf_role = "ap-psk-sae";
1020 else
1021 conf_role = "sta-psk-sae";
1022 break;
Jouni Malinenf2fa0d02018-01-11 20:51:31 +02001023 case 7:
1024 ascii2hexstr("DPPNET01", buf);
1025 snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
1026 if (enrollee_ap) {
1027 conf_role = "ap-dpp";
1028 groups_override = "[{\"groupId\":\"DPPGROUP_DPP_INFRA\",\"netRole\":\"ap\"}]";
1029 } else {
1030 conf_role = "sta-dpp";
1031 groups_override = "[{\"groupId\":\"DPPGROUP_DPP_INFRA\",\"netRole\":\"sta\"}]";
1032 }
1033 force_gas_fragm = 1;
1034 break;
Jouni Malinenf7490762017-10-12 00:34:37 +03001035 default:
1036 send_resp(dut, conn, SIGMA_ERROR,
1037 "errorCode,Unsupported DPPConfIndex");
1038 goto out;
Jouni Malinend86e5822017-08-29 03:55:32 +03001039 }
1040
Jouni Malinen3d291f72017-11-02 11:31:05 +02001041 if (groups_override) {
Jouni Malinenf2fa0d02018-01-11 20:51:31 +02001042 const char *extra = "";
1043 char spaces[1500];
1044
1045 if (force_gas_fragm) {
1046 memset(spaces, ' ', sizeof(spaces));
1047 spaces[sizeof(spaces) - 1] = '\0';
1048 extra = spaces;
1049 }
1050
1051 snprintf(buf, sizeof(buf), "SET dpp_groups_override %s%s",
1052 groups_override, extra);
Jouni Malinen3d291f72017-11-02 11:31:05 +02001053 if (wpa_command(ifname, buf) < 0) {
1054 send_resp(dut, conn, SIGMA_ERROR,
1055 "errorCode,Failed to set cred:groups");
1056 goto out;
1057 }
1058 }
1059
Jouni Malinen772299f2017-11-06 00:36:26 +02001060 if (step) {
1061 int test;
1062
1063 test = dpp_get_test(step, frametype, attr);
1064 if (test <= 0) {
1065 send_resp(dut, conn, SIGMA_ERROR,
1066 "errorCode,Unsupported DPPStep/DPPFrameType/DPPIEAttribute");
1067 goto out;
1068 }
1069
1070 snprintf(buf, sizeof(buf), "SET dpp_test %d", test);
1071 if (wpa_command(ifname, buf) < 0) {
1072 send_resp(dut, conn, SIGMA_ERROR,
1073 "errorCode,Failed to set dpp_test");
1074 goto out;
1075 }
1076 } else {
1077 wpa_command(ifname, "SET dpp_test 0");
1078 }
1079
Jouni Malinenfbb268d2017-11-17 18:53:49 +02001080 if (strcasecmp(self_conf, "Yes") == 0) {
1081 if (strcasecmp(prov_role, "Configurator") != 0) {
1082 send_resp(dut, conn, SIGMA_ERROR,
1083 "errorCode,Invalid DPPSelfConfigure use - only allowed for Configurator role");
1084 goto out;
1085 }
1086 if (!conf_role) {
1087 send_resp(dut, conn, SIGMA_ERROR,
1088 "errorCode,Missing DPPConfIndex");
1089 goto out;
1090 }
1091
1092 snprintf(buf, sizeof(buf),
1093 "DPP_CONFIGURATOR_SIGN conf=%s %s %s configurator=%d",
1094 conf_role, conf_ssid, conf_pass, dut->dpp_conf_id);
1095 if (wpa_command(ifname, buf) < 0) {
1096 send_resp(dut, conn, SIGMA_ERROR,
1097 "errorCode,Failed to initiate DPP self-configuration");
1098 goto out;
1099 }
Jouni Malinen174db642017-11-27 20:16:29 +02001100 if (sigma_dut_is_ap(dut))
1101 goto update_ap;
Jouni Malinenfbb268d2017-11-17 18:53:49 +02001102 goto wait_connect;
1103 } else if (strcasecmp(auth_role, "Initiator") == 0) {
Jouni Malinend86e5822017-08-29 03:55:32 +03001104 char own_txt[20];
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02001105 int dpp_peer_bootstrap = -1;
Jouni Malinenb5ab8282017-11-21 01:12:22 +02001106 char neg_freq[30];
1107
Jouni Malinend1e22f72017-12-05 21:12:17 +02001108 val = get_param(cmd, "DPPAuthDirection");
1109 check_mutual = val && strcasecmp(val, "Mutual") == 0;
1110
Jouni Malinenb5ab8282017-11-21 01:12:22 +02001111 neg_freq[0] = '\0';
1112 val = get_param(cmd, "DPPSubsequentChannel");
1113 if (val) {
1114 int opclass, channel, freq;
1115
1116 opclass = atoi(val);
1117 val = strchr(val, '/');
1118 if (opclass == 0 || !val) {
1119 send_resp(dut, conn, SIGMA_ERROR,
1120 "errorCode,Invalid DPPSubsequentChannel");
1121 goto out;
1122 }
1123 val++;
1124 channel = atoi(val);
1125
1126 /* Ignoring opclass for now; could use it here for more
1127 * robust frequency determination. */
1128 freq = channel_to_freq(channel);
1129 if (!freq) {
1130 send_resp(dut, conn, SIGMA_ERROR,
1131 "errorCode,Unsupported DPPSubsequentChannel channel");
1132 goto out;
1133 }
1134 snprintf(neg_freq, sizeof(neg_freq), " neg_freq=%d",
1135 freq);
1136 }
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02001137
1138 if (strcasecmp(bs, "QR") == 0) {
1139 if (!dut->dpp_peer_uri) {
1140 send_resp(dut, conn, SIGMA_ERROR,
1141 "errorCode,Missing peer bootstrapping info");
1142 goto out;
1143 }
1144
1145 snprintf(buf, sizeof(buf), "DPP_QR_CODE %s",
1146 dut->dpp_peer_uri);
1147 if (wpa_command_resp(ifname, buf, buf,
1148 sizeof(buf)) < 0) {
1149 send_resp(dut, conn, SIGMA_ERROR,
1150 "errorCode,Failed to parse URI");
1151 goto out;
1152 }
1153 dpp_peer_bootstrap = atoi(buf);
1154 }
Jouni Malinend86e5822017-08-29 03:55:32 +03001155
Jouni Malinen63d50412017-11-24 11:55:38 +02001156 if (dut->dpp_local_bootstrap >= 0)
Jouni Malinend86e5822017-08-29 03:55:32 +03001157 snprintf(own_txt, sizeof(own_txt), " own=%d",
1158 dut->dpp_local_bootstrap);
1159 else
1160 own_txt[0] = '\0';
1161 if (strcasecmp(bs, "QR") == 0 &&
Jouni Malinen67acb0c2017-11-21 01:01:54 +02001162 (strcasecmp(prov_role, "Configurator") == 0 ||
1163 strcasecmp(prov_role, "Both") == 0)) {
Jouni Malinen258cc262017-10-13 00:19:56 +03001164 if (!conf_role) {
1165 send_resp(dut, conn, SIGMA_ERROR,
1166 "errorCode,Missing DPPConfIndex");
1167 goto out;
1168 }
Jouni Malinend86e5822017-08-29 03:55:32 +03001169 snprintf(buf, sizeof(buf),
Jouni Malinenb5ab8282017-11-21 01:12:22 +02001170 "DPP_AUTH_INIT peer=%d%s role=%s conf=%s %s %s configurator=%d%s",
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02001171 dpp_peer_bootstrap, own_txt, role,
Jouni Malinend86e5822017-08-29 03:55:32 +03001172 conf_role, conf_ssid, conf_pass,
Jouni Malinenb5ab8282017-11-21 01:12:22 +02001173 dut->dpp_conf_id, neg_freq);
Jouni Malinend86e5822017-08-29 03:55:32 +03001174 } else if (strcasecmp(bs, "QR") == 0) {
1175 snprintf(buf, sizeof(buf),
Jouni Malinenb5ab8282017-11-21 01:12:22 +02001176 "DPP_AUTH_INIT peer=%d%s role=%s%s",
1177 dpp_peer_bootstrap, own_txt, role, neg_freq);
Jouni Malinend86e5822017-08-29 03:55:32 +03001178 } else if (strcasecmp(bs, "PKEX") == 0 &&
Jouni Malinen67acb0c2017-11-21 01:01:54 +02001179 (strcasecmp(prov_role, "Configurator") == 0 ||
1180 strcasecmp(prov_role, "Both") == 0)) {
Jouni Malinen258cc262017-10-13 00:19:56 +03001181 if (!conf_role) {
1182 send_resp(dut, conn, SIGMA_ERROR,
1183 "errorCode,Missing DPPConfIndex");
1184 goto out;
1185 }
Jouni Malinend86e5822017-08-29 03:55:32 +03001186 snprintf(buf, sizeof(buf),
1187 "DPP_PKEX_ADD own=%d init=1 role=%s conf=%s %s %s configurator=%d %scode=%s",
1188 own_pkex_id, role, conf_role,
1189 conf_ssid, conf_pass, dut->dpp_conf_id,
1190 pkex_identifier, pkex_code);
1191 } else if (strcasecmp(bs, "PKEX") == 0) {
1192 snprintf(buf, sizeof(buf),
1193 "DPP_PKEX_ADD own=%d init=1 role=%s %scode=%s",
1194 own_pkex_id, role, pkex_identifier, pkex_code);
Jouni Malinend551c6f2017-10-12 00:32:18 +03001195 } else {
1196 send_resp(dut, conn, SIGMA_ERROR,
1197 "errorCode,Unsupported DPPBS");
1198 goto out;
Jouni Malinend86e5822017-08-29 03:55:32 +03001199 }
1200 if (wpa_command(ifname, buf) < 0) {
1201 send_resp(dut, conn, SIGMA_ERROR,
1202 "errorCode,Failed to initiate DPP authentication");
1203 goto out;
1204 }
1205 } else if (strcasecmp(auth_role, "Responder") == 0) {
Jouni Malinen67f096a2017-11-24 11:58:51 +02001206 const char *delay_qr_resp;
Jouni Malinen63d50412017-11-24 11:55:38 +02001207 int mutual;
Jouni Malinend3afc5c2017-11-13 18:39:14 +02001208 int freq = 2462; /* default: channel 11 */
1209
Jouni Malinen06cfcb32018-01-11 20:43:50 +02001210 if (strcasecmp(bs, "PKEX") == 0) {
1211 /* default: channel 6 for PKEX */
1212 freq = 2437;
1213 }
1214
Jouni Malinen67f096a2017-11-24 11:58:51 +02001215 delay_qr_resp = get_param(cmd, "DPPDelayQRResponse");
1216
Jouni Malinen63d50412017-11-24 11:55:38 +02001217 val = get_param(cmd, "DPPAuthDirection");
1218 mutual = val && strcasecmp(val, "Mutual") == 0;
1219
Jouni Malinend3afc5c2017-11-13 18:39:14 +02001220 val = get_param(cmd, "DPPListenChannel");
1221 if (val) {
1222 freq = channel_to_freq(atoi(val));
1223 if (freq == 0) {
1224 send_resp(dut, conn, SIGMA_ERROR,
1225 "errorCode,Unsupported DPPListenChannel value");
1226 goto out;
1227 }
1228 }
Jouni Malinend86e5822017-08-29 03:55:32 +03001229
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02001230 if (!delay_qr_resp && dut->dpp_peer_uri) {
1231 snprintf(buf, sizeof(buf), "DPP_QR_CODE %s",
1232 dut->dpp_peer_uri);
1233 if (wpa_command_resp(ifname, buf, buf,
1234 sizeof(buf)) < 0) {
1235 send_resp(dut, conn, SIGMA_ERROR,
1236 "errorCode,Failed to parse URI");
1237 goto out;
1238 }
1239 }
1240
Jouni Malinend86e5822017-08-29 03:55:32 +03001241 if (strcasecmp(prov_role, "Configurator") == 0) {
Jouni Malinen258cc262017-10-13 00:19:56 +03001242 if (!conf_role) {
1243 send_resp(dut, conn, SIGMA_ERROR,
1244 "errorCode,Missing DPPConfIndex");
1245 goto out;
1246 }
Jouni Malinend86e5822017-08-29 03:55:32 +03001247 snprintf(buf, sizeof(buf),
1248 "SET dpp_configurator_params conf=%s %s %s configurator=%d",
1249 conf_role, conf_ssid, conf_pass,
1250 dut->dpp_conf_id);
1251 if (wpa_command(ifname, buf) < 0) {
1252 send_resp(dut, conn, SIGMA_ERROR,
1253 "errorCode,Failed to set configurator parameters");
1254 goto out;
1255 }
1256 }
1257 if (strcasecmp(bs, "PKEX") == 0) {
Jouni Malinend86e5822017-08-29 03:55:32 +03001258 snprintf(buf, sizeof(buf),
1259 "DPP_PKEX_ADD own=%d role=%s %scode=%s",
1260 own_pkex_id, role, pkex_identifier, pkex_code);
1261 if (wpa_command(ifname, buf) < 0) {
1262 send_resp(dut, conn, SIGMA_ERROR,
1263 "errorCode,Failed to configure DPP PKEX");
1264 goto out;
1265 }
1266 }
1267
Jouni Malinenbafc1932017-11-04 11:31:16 +02001268 snprintf(buf, sizeof(buf), "DPP_LISTEN %d role=%s%s",
1269 freq, role,
1270 (strcasecmp(bs, "QR") == 0 && mutual) ?
1271 " qr=mutual" : "");
1272 if (wpa_command(ifname, buf) < 0) {
1273 send_resp(dut, conn, SIGMA_ERROR,
1274 "errorCode,Failed to start DPP listen");
1275 goto out;
Jouni Malinend86e5822017-08-29 03:55:32 +03001276 }
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02001277
priyadharshini gowthamanb4de1962018-01-15 12:21:04 -08001278 if (get_driver_type() == DRIVER_OPENWRT) {
1279 snprintf(buf, sizeof(buf), "iwconfig %s channel %d",
1280 dut->hostapd_ifname, freq_to_channel(freq));
1281 run_system(dut, buf);
1282 }
1283
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02001284 if (delay_qr_resp && mutual && dut->dpp_peer_uri) {
1285 int wait_time = atoi(delay_qr_resp);
1286
1287 res = get_wpa_cli_events(dut, ctrl, auth_events,
1288 buf, sizeof(buf));
1289 if (res < 0) {
1290 send_resp(dut, conn, SIGMA_COMPLETE,
1291 "BootstrapResult,OK,AuthResult,Timeout");
1292 goto out;
1293 }
1294 sigma_dut_print(dut, DUT_MSG_DEBUG,
1295 "DPP auth result: %s", buf);
1296 if (strstr(buf, "DPP-SCAN-PEER-QR-CODE") == NULL) {
1297 send_resp(dut, conn, SIGMA_ERROR,
1298 "errorCode,No scan request for peer QR Code seen");
1299 goto out;
1300 }
1301 sigma_dut_print(dut, DUT_MSG_INFO,
1302 "Waiting %d second(s) before processing peer URI",
1303 wait_time);
1304 sleep(wait_time);
1305
1306 snprintf(buf, sizeof(buf), "DPP_QR_CODE %s",
1307 dut->dpp_peer_uri);
1308 if (wpa_command_resp(ifname, buf, buf,
1309 sizeof(buf)) < 0) {
1310 send_resp(dut, conn, SIGMA_ERROR,
1311 "errorCode,Failed to parse URI");
1312 goto out;
1313 }
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05301314 } else if (mutual && action_type &&
1315 strcasecmp(action_type, "ManualDPP") == 0) {
1316 res = get_wpa_cli_events(dut, ctrl, auth_events,
1317 buf, sizeof(buf));
1318 if (res < 0) {
1319 send_resp(dut, conn, SIGMA_COMPLETE,
1320 "BootstrapResult,OK,AuthResult,Timeout");
1321 goto out;
1322 }
1323 sigma_dut_print(dut, DUT_MSG_DEBUG,
1324 "DPP auth result: %s", buf);
1325 if (strstr(buf, "DPP-SCAN-PEER-QR-CODE") == NULL) {
1326 send_resp(dut, conn, SIGMA_ERROR,
1327 "errorCode,No scan request for peer QR Code seen");
1328 goto out;
1329 }
1330
1331 if (dpp_scan_peer_qrcode(dut) < 0) {
1332 send_resp(dut, conn, SIGMA_ERROR,
1333 "errorCode,Failed to scan peer QR Code");
1334 goto out;
1335 }
1336
1337 snprintf(buf, sizeof(buf), "DPP_QR_CODE %s",
1338 dut->dpp_peer_uri);
1339 if (wpa_command_resp(ifname, buf, buf,
1340 sizeof(buf)) < 0) {
1341 send_resp(dut, conn, SIGMA_ERROR,
1342 "errorCode,Failed to parse URI");
1343 goto out;
1344 }
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02001345 }
Jouni Malinend86e5822017-08-29 03:55:32 +03001346 } else {
1347 send_resp(dut, conn, SIGMA_ERROR,
1348 "errorCode,Unknown DPPAuthRole");
1349 goto out;
1350 }
1351
Jouni Malinen3a6b92a2017-12-05 20:22:43 +02001352 if (step && strcasecmp(step, "Timeout") == 0) {
1353 result = "errorCode,Unexpected state";
1354
1355 if (strcasecmp(frametype, "PKEXExchangeResponse") == 0) {
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001356 if (dpp_wait_rx(dut, ctrl, 8, -1) < 0)
Jouni Malinen3a6b92a2017-12-05 20:22:43 +02001357 result = "BootstrapResult,Timeout";
1358 else
1359 result = "BootstrapResult,Errorsent";
1360 }
1361
1362 if (strcasecmp(frametype, "PKEXCRRequest") == 0) {
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001363 if (dpp_wait_rx(dut, ctrl, 9, -1) < 0)
Jouni Malinen3a6b92a2017-12-05 20:22:43 +02001364 result = "BootstrapResult,Timeout";
1365 else
1366 result = "BootstrapResult,Errorsent";
1367 }
1368
1369 if (strcasecmp(frametype, "PKEXCRResponse") == 0) {
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001370 if (dpp_wait_rx(dut, ctrl, 10, -1) < 0)
Jouni Malinen3a6b92a2017-12-05 20:22:43 +02001371 result = "BootstrapResult,Timeout";
1372 else
1373 result = "BootstrapResult,Errorsent";
1374 }
1375
1376 if (strcasecmp(frametype, "AuthenticationRequest") == 0) {
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001377 if (dpp_wait_rx(dut, ctrl, 0, -1) < 0)
Jouni Malinen3a6b92a2017-12-05 20:22:43 +02001378 result = "BootstrapResult,OK,AuthResult,Timeout";
1379 else
1380 result = "BootstrapResult,OK,AuthResult,Errorsent";
1381 }
1382
1383 if (strcasecmp(frametype, "AuthenticationResponse") == 0) {
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001384 if (dpp_wait_rx(dut, ctrl, 1, -1) < 0)
Jouni Malinen3a6b92a2017-12-05 20:22:43 +02001385 result = "BootstrapResult,OK,AuthResult,Timeout";
1386 else
1387 result = "BootstrapResult,OK,AuthResult,Errorsent";
1388 }
1389
1390 if (strcasecmp(frametype, "AuthenticationConfirm") == 0) {
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001391 if (dpp_wait_rx(dut, ctrl, 2, -1) < 0)
Jouni Malinen3a6b92a2017-12-05 20:22:43 +02001392 result = "BootstrapResult,OK,AuthResult,Timeout";
1393 else
1394 result = "BootstrapResult,OK,AuthResult,Errorsent";
1395 }
1396
1397 if (strcasecmp(frametype, "ConfigurationRequest") == 0) {
1398 if (get_wpa_cli_event(dut, ctrl, "DPP-CONF-FAILED",
1399 buf, sizeof(buf)) < 0)
1400 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Timeout";
1401 else
1402 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Errorsent";
1403 }
1404
1405 send_resp(dut, conn, SIGMA_COMPLETE, result);
1406 goto out;
1407 }
1408
Jouni Malinen772299f2017-11-06 00:36:26 +02001409 if (frametype && strcasecmp(frametype, "PKEXExchangeRequest") == 0) {
1410 if (dpp_wait_tx_status(dut, ctrl, 7) < 0)
1411 result = "BootstrapResult,Timeout";
1412 else
1413 result = "BootstrapResult,Errorsent";
1414 send_resp(dut, conn, SIGMA_COMPLETE, result);
1415 goto out;
1416 }
1417
1418 if (frametype && strcasecmp(frametype, "PKEXExchangeResponse") == 0) {
1419 if (dpp_wait_tx_status(dut, ctrl, 8) < 0)
1420 result = "BootstrapResult,Timeout";
1421 else
1422 result = "BootstrapResult,Errorsent";
1423 send_resp(dut, conn, SIGMA_COMPLETE, result);
1424 goto out;
1425 }
1426
1427 if (frametype && strcasecmp(frametype, "PKEXCRRequest") == 0) {
1428 if (dpp_wait_tx_status(dut, ctrl, 9) < 0)
1429 result = "BootstrapResult,Timeout";
1430 else
1431 result = "BootstrapResult,Errorsent";
1432 send_resp(dut, conn, SIGMA_COMPLETE, result);
1433 goto out;
1434 }
1435
1436 if (frametype && strcasecmp(frametype, "PKEXCRResponse") == 0) {
1437 if (dpp_wait_tx_status(dut, ctrl, 10) < 0)
1438 result = "BootstrapResult,Timeout";
1439 else
1440 result = "BootstrapResult,Errorsent";
1441 send_resp(dut, conn, SIGMA_COMPLETE, result);
1442 goto out;
1443 }
1444
1445 if (frametype && strcasecmp(frametype, "AuthenticationRequest") == 0) {
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001446 if (dpp_wait_tx_status(dut, ctrl, 0) < 0) {
1447 send_resp(dut, conn, SIGMA_COMPLETE,
1448 "BootstrapResult,OK,AuthResult,Timeout");
1449 goto out;
1450 }
1451
1452 if (dpp_wait_rx(dut, ctrl, 1, 5) < 0)
1453 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,None";
Jouni Malinen772299f2017-11-06 00:36:26 +02001454 else
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001455 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationResponse";
Jouni Malinen772299f2017-11-06 00:36:26 +02001456 send_resp(dut, conn, SIGMA_COMPLETE, result);
1457 goto out;
1458 }
1459
1460 if (frametype && strcasecmp(frametype, "AuthenticationResponse") == 0) {
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001461 if (dpp_wait_tx_status(dut, ctrl, 1) < 0) {
1462 send_resp(dut, conn, SIGMA_COMPLETE,
1463 "BootstrapResult,OK,AuthResult,Timeout");
1464 goto out;
1465 }
1466
1467 if (dpp_wait_rx(dut, ctrl, 2, 5) < 0)
1468 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationRequest";
Jouni Malinen772299f2017-11-06 00:36:26 +02001469 else
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001470 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationConfirm";
Jouni Malinen772299f2017-11-06 00:36:26 +02001471 send_resp(dut, conn, SIGMA_COMPLETE, result);
1472 goto out;
1473 }
1474
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05301475 res = get_wpa_cli_events(dut, ctrl, auth_events, buf, sizeof(buf));
1476 if (res < 0) {
1477 send_resp(dut, conn, SIGMA_COMPLETE,
1478 "BootstrapResult,OK,AuthResult,Timeout");
1479 goto out;
1480 }
1481 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP auth result: %s", buf);
1482
1483 if (strstr(buf, "DPP-RESPONSE-PENDING")) {
1484 /* Display own QR code in manual mode */
1485 if (action_type && strcasecmp(action_type, "ManualDPP") == 0 &&
1486 dpp_display_own_qrcode(dut) < 0) {
1487 send_resp(dut, conn, SIGMA_ERROR,
1488 "errorCode,Failed to display own QR code");
1489 goto out;
1490 }
1491
1492 /* Wait for the actual result after the peer has scanned the
1493 * QR Code. */
1494 res = get_wpa_cli_events(dut, ctrl, auth_events,
1495 buf, sizeof(buf));
Jouni Malinend1e22f72017-12-05 21:12:17 +02001496 if (res < 0) {
1497 send_resp(dut, conn, SIGMA_COMPLETE,
1498 "BootstrapResult,OK,AuthResult,Timeout");
1499 goto out;
1500 }
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05301501
1502 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP auth result: %s", buf);
1503 }
1504
1505 if (check_mutual) {
1506 if (!strstr(buf, "DPP-AUTH-DIRECTION")) {
1507 send_resp(dut, conn, SIGMA_ERROR,
1508 "errorCode,No event for auth direction seen");
1509 goto out;
1510 }
1511
Jouni Malinend1e22f72017-12-05 21:12:17 +02001512 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP auth direction: %s",
1513 buf);
1514 if (strstr(buf, "mutual=1") == NULL) {
1515 send_resp(dut, conn, SIGMA_ERROR,
1516 "errorCode,Peer did not use mutual authentication");
1517 goto out;
1518 }
1519 }
1520
Jouni Malinen772299f2017-11-06 00:36:26 +02001521 if (frametype && strcasecmp(frametype, "AuthenticationConfirm") == 0) {
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001522 if (dpp_wait_tx_status(dut, ctrl, 2) < 0) {
1523 send_resp(dut, conn, SIGMA_COMPLETE,
1524 "BootstrapResult,OK,AuthResult,Timeout");
1525 goto out;
1526 }
1527
1528 if (dpp_wait_rx_conf_req(dut, ctrl, 5) < 0)
1529 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationResponse";
Jouni Malinen772299f2017-11-06 00:36:26 +02001530 else
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001531 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,ConfigurationRequest";
Jouni Malinen772299f2017-11-06 00:36:26 +02001532 send_resp(dut, conn, SIGMA_COMPLETE, result);
1533 goto out;
1534 }
1535
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05301536 if (strstr(buf, "DPP-AUTH-DIRECTION")) {
Jouni Malinen2e9c8a42017-11-19 12:06:18 +02001537 res = get_wpa_cli_events(dut, ctrl, auth_events,
1538 buf, sizeof(buf));
1539 if (res < 0) {
1540 send_resp(dut, conn, SIGMA_COMPLETE,
1541 "BootstrapResult,OK,AuthResult,Timeout");
1542 goto out;
1543 }
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05301544
1545 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP auth result: %s", buf);
Jouni Malinen2e9c8a42017-11-19 12:06:18 +02001546 }
1547
Jouni Malinend86e5822017-08-29 03:55:32 +03001548 if (strstr(buf, "DPP-NOT-COMPATIBLE")) {
1549 send_resp(dut, conn, SIGMA_COMPLETE,
1550 "BootstrapResult,OK,AuthResult,ROLES_NOT_COMPATIBLE");
1551 goto out;
1552 }
1553
1554 if (!strstr(buf, "DPP-AUTH-SUCCESS")) {
1555 send_resp(dut, conn, SIGMA_COMPLETE,
1556 "BootstrapResult,OK,AuthResult,FAILED");
1557 goto out;
1558 }
1559
Jouni Malinen772299f2017-11-06 00:36:26 +02001560 if (frametype && strcasecmp(frametype, "ConfigurationRequest") == 0) {
1561 res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE",
1562 buf, sizeof(buf));
1563 if (res < 0)
1564 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Timeout";
1565 else
1566 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Errorsent";
1567 send_resp(dut, conn, SIGMA_COMPLETE, result);
1568 goto out;
1569 }
1570
1571 if (frametype && strcasecmp(frametype, "ConfigurationResponse") == 0) {
1572 res = get_wpa_cli_event(dut, ctrl, "DPP-CONF-SENT",
1573 buf, sizeof(buf));
1574 if (res < 0)
1575 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Timeout";
1576 else
1577 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Errorsent";
1578 send_resp(dut, conn, SIGMA_COMPLETE, result);
1579 goto out;
1580 }
1581
Jouni Malinend86e5822017-08-29 03:55:32 +03001582 res = get_wpa_cli_events(dut, ctrl, conf_events, buf, sizeof(buf));
1583 if (res < 0) {
1584 send_resp(dut, conn, SIGMA_COMPLETE,
1585 "BootstrapResult,OK,AuthResult,OK,ConfResult,Timeout");
1586 goto out;
1587 }
1588 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP conf result: %s", buf);
1589
1590 if (!strstr(buf, "DPP-CONF-SENT") &&
1591 !strstr(buf, "DPP-CONF-RECEIVED")) {
1592 send_resp(dut, conn, SIGMA_COMPLETE,
1593 "BootstrapResult,OK,AuthResult,OK,ConfResult,FAILED");
1594 goto out;
1595 }
1596
1597 if (sigma_dut_is_ap(dut) &&
1598 strcasecmp(prov_role, "Enrollee") == 0) {
Jouni Malinen174db642017-11-27 20:16:29 +02001599 update_ap:
Jouni Malinend86e5822017-08-29 03:55:32 +03001600 res = dpp_hostapd_conf_update(dut, conn, ifname, ctrl);
1601 if (res == 0)
1602 goto out;
1603 if (res < 0) {
1604 send_resp(dut, conn, SIGMA_ERROR, NULL);
1605 goto out;
1606 }
1607 }
1608
1609 if (strcasecmp(wait_conn, "Yes") == 0 &&
1610 !sigma_dut_is_ap(dut) &&
1611 strcasecmp(prov_role, "Enrollee") == 0) {
Jouni Malinenfbb268d2017-11-17 18:53:49 +02001612 wait_connect:
Jouni Malinen53558e02017-11-06 12:58:28 +02001613 if (frametype && strcasecmp(frametype,
1614 "PeerDiscoveryRequest") == 0) {
1615 if (dpp_wait_tx_status(dut, ctrl, 5) < 0)
1616 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Timeout";
1617 else
1618 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Errorsent";
1619 send_resp(dut, conn, SIGMA_COMPLETE, result);
1620 goto out;
1621 }
1622
Jouni Malinend86e5822017-08-29 03:55:32 +03001623 res = get_wpa_cli_events(dut, ctrl, conn_events,
1624 buf, sizeof(buf));
1625 if (res < 0) {
1626 send_resp(dut, conn, SIGMA_COMPLETE,
1627 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Timeout,NetworkConnectResult,Timeout");
1628 goto out;
1629 }
1630 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP connect result: %s",
1631 buf);
1632
1633 if (strstr(buf, "PMKSA-CACHE-ADDED")) {
1634 res = get_wpa_cli_events(dut, ctrl, conn_events,
1635 buf, sizeof(buf));
1636 if (res < 0) {
1637 send_resp(dut, conn, SIGMA_COMPLETE,
1638 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,Timeout");
1639 goto out;
1640 }
1641 sigma_dut_print(dut, DUT_MSG_DEBUG,
1642 "DPP connect result: %s", buf);
1643 if (strstr(buf, "CTRL-EVENT-CONNECTED"))
1644 send_resp(dut, conn, SIGMA_COMPLETE,
1645 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,OK");
1646 else
1647 send_resp(dut, conn, SIGMA_COMPLETE,
1648 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,Timeout");
1649 goto out;
1650 }
1651
1652 send_resp(dut, conn, SIGMA_COMPLETE,
1653 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkConnectResult,OK");
1654 goto out;
1655 }
1656
Jouni Malinen53558e02017-11-06 12:58:28 +02001657 if (strcasecmp(wait_conn, "Yes") == 0 &&
1658 frametype && strcasecmp(frametype, "PeerDiscoveryResponse") == 0) {
1659 if (dpp_wait_tx_status(dut, ctrl, 6) < 0)
1660 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Timeout";
1661 else
1662 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Errorsent";
1663 send_resp(dut, conn, SIGMA_COMPLETE, result);
1664 goto out;
1665 }
1666
Jouni Malinend86e5822017-08-29 03:55:32 +03001667 send_resp(dut, conn, SIGMA_COMPLETE,
1668 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK");
1669out:
1670 wpa_ctrl_detach(ctrl);
1671 wpa_ctrl_close(ctrl);
1672 dut->default_timeout = old_timeout;
1673 return 0;
1674}
1675
1676
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05301677static int dpp_manual_dpp(struct sigma_dut *dut,
1678 struct sigma_conn *conn,
1679 struct sigma_cmd *cmd)
1680{
1681 const char *auth_role = get_param(cmd, "DPPAuthRole");
1682 int res = -1, success;
1683 const char *val;
1684 unsigned int old_timeout;
1685
1686 if (!auth_role) {
1687 send_resp(dut, conn, SIGMA_ERROR,
1688 "errorCode,Missing DPPAuthRole");
1689 return 0;
1690 }
1691
1692 old_timeout = dut->default_timeout;
1693 val = get_param(cmd, "DPPTimeout");
1694 if (val && atoi(val) > 0) {
1695 dut->default_timeout = atoi(val);
1696 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP timeout: %u",
1697 dut->default_timeout);
1698 }
1699
1700 res = dpp_get_local_bootstrap(dut, conn, cmd, 0, &success);
1701 if (res || !success)
1702 goto out;
1703
1704 if (strcasecmp(auth_role, "Responder") == 0) {
1705 res = dpp_display_own_qrcode(dut);
1706 if (res < 0)
1707 goto out;
1708
1709 res = dpp_automatic_dpp(dut, conn, cmd);
1710 goto out;
1711 }
1712
1713 if (strcasecmp(auth_role, "Initiator") == 0) {
1714 res = dpp_scan_peer_qrcode(dut);
Jouni Malinen1a38cc32018-01-05 20:59:00 +02001715 if (res < 0) {
1716 send_resp(dut, conn, SIGMA_ERROR,
1717 "errorCode,Failed to scan peer QR Code");
1718 res = 0;
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05301719 goto out;
Jouni Malinen1a38cc32018-01-05 20:59:00 +02001720 }
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05301721
1722 res = dpp_automatic_dpp(dut, conn, cmd);
1723 goto out;
1724 }
1725
1726 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unknown DPPAuthRole");
1727 res = 0;
1728out:
1729 dut->default_timeout = old_timeout;
1730 return res;
1731}
1732
1733
Jouni Malinend86e5822017-08-29 03:55:32 +03001734int dpp_dev_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
1735 struct sigma_cmd *cmd)
1736{
1737 const char *type = get_param(cmd, "DPPActionType");
1738 const char *bs = get_param(cmd, "DPPBS");
1739
1740 if (!bs) {
1741 send_resp(dut, conn, SIGMA_ERROR,
1742 "errorCode,Missing DPPBS");
1743 return 0;
1744 }
1745
1746 if (!type) {
1747 send_resp(dut, conn, SIGMA_ERROR,
1748 "errorCode,Missing DPPActionType");
1749 return 0;
1750 }
1751
1752 if (strcasecmp(type, "GetLocalBootstrap") == 0)
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05301753 return dpp_get_local_bootstrap(dut, conn, cmd, 1, NULL);
Jouni Malinend86e5822017-08-29 03:55:32 +03001754 if (strcasecmp(type, "SetPeerBootstrap") == 0)
1755 return dpp_set_peer_bootstrap(dut, conn, cmd);
1756 if (strcasecmp(type, "ManualDPP") == 0)
1757 return dpp_manual_dpp(dut, conn, cmd);
1758 if (strcasecmp(type, "AutomaticDPP") == 0)
1759 return dpp_automatic_dpp(dut, conn, cmd);
1760
1761 send_resp(dut, conn, SIGMA_ERROR,
1762 "errorCode,Unsupported DPPActionType");
1763 return 0;
1764}