blob: 50e17148c5b12b35ced2daa0837bde4e91d62959 [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");
35 dut->ap_channel = 11;
36 dut->ap_is_dual = 0;
37 dut->ap_mode = AP_11ng;
38 dut->ap_key_mgmt = AP_OPEN;
39 dut->ap_cipher = AP_PLAIN;
40 return cmd_ap_config_commit(dut, NULL, NULL) == 1 ? 0 : -1;
41}
42
43
44static const char * dpp_get_curve(struct sigma_cmd *cmd, const char *arg)
45{
46 const char *val = get_param(cmd, arg);
47
48 if (!val)
49 val = "P-256";
50 else if (strcasecmp(val, "BP-256R1") == 0)
51 val = "BP-256";
52 else if (strcasecmp(val, "BP-384R1") == 0)
53 val = "BP-384";
54 else if (strcasecmp(val, "BP-512R1") == 0)
55 val = "BP-512";
56
57 return val;
58}
59
60
61static int dpp_get_local_bootstrap(struct sigma_dut *dut,
62 struct sigma_conn *conn,
Srinivas Dasaribc9e0552018-01-04 19:24:28 +053063 struct sigma_cmd *cmd, int send_result,
64 int *success)
Jouni Malinend86e5822017-08-29 03:55:32 +030065{
66 const char *curve = dpp_get_curve(cmd, "DPPCryptoIdentifier");
67 const char *bs = get_param(cmd, "DPPBS");
Jouni Malinen4161c3f2017-11-13 18:36:09 +020068 const char *chan_list = get_param(cmd, "DPPChannelList");
69 char *pos, mac[50], buf[200], resp[1000], hex[2000];
Jouni Malinend86e5822017-08-29 03:55:32 +030070 const char *ifname = get_station_ifname();
71
Srinivas Dasaribc9e0552018-01-04 19:24:28 +053072 if (success)
73 *success = 0;
Jouni Malinend86e5822017-08-29 03:55:32 +030074 if (strcasecmp(bs, "QR") != 0) {
75 send_resp(dut, conn, SIGMA_ERROR,
76 "errorCode,Unsupported DPPBS");
77 return 0;
78 }
79
80 if (sigma_dut_is_ap(dut)) {
81 u8 bssid[ETH_ALEN];
82
83 if (!dut->hostapd_ifname) {
84 sigma_dut_print(dut, DUT_MSG_ERROR,
85 "hostapd ifname not specified (-j)");
86 return -2;
87 }
88 ifname = dut->hostapd_ifname;
89 if (get_hwaddr(dut->hostapd_ifname, bssid) < 0) {
90 sigma_dut_print(dut, DUT_MSG_ERROR,
91 "Could not get MAC address for %s",
92 dut->hostapd_ifname);
93 return -2;
94 }
95 snprintf(mac, sizeof(mac), "%02x%02x%02x%02x%02x%02x",
96 bssid[0], bssid[1], bssid[2],
97 bssid[3], bssid[4], bssid[5]);
98 } else {
99 if (get_wpa_status(ifname, "address", mac, sizeof(mac)) < 0)
100 return -2;
101 }
102
103 pos = mac;
104 while (*pos) {
105 if (*pos == ':')
106 memmove(pos, pos + 1, strlen(pos));
107 else
108 pos++;
109 }
110
Jouni Malinend86e5822017-08-29 03:55:32 +0300111 if (sigma_dut_is_ap(dut) && dpp_hostapd_run(dut) < 0) {
112 send_resp(dut, conn, SIGMA_ERROR,
113 "errorCode,Failed to start hostapd");
114 return 0;
115 }
116
Jouni Malinen4161c3f2017-11-13 18:36:09 +0200117 if (chan_list &&
118 (strcmp(chan_list, "0/0") == 0 || chan_list[0] == '\0')) {
119 /* No channel list */
120 snprintf(buf, sizeof(buf),
121 "DPP_BOOTSTRAP_GEN type=qrcode curve=%s mac=%s",
122 curve, mac);
123 } else if (chan_list) {
124 /* Channel list override (CTT case) - space separated tuple(s)
125 * of OperatingClass/Channel; convert to wpa_supplicant/hostapd
126 * format: comma separated tuples */
127 strlcpy(resp, chan_list, sizeof(resp));
128 for (pos = resp; *pos; pos++) {
129 if (*pos == ' ')
130 *pos = ',';
131 }
132 snprintf(buf, sizeof(buf),
133 "DPP_BOOTSTRAP_GEN type=qrcode curve=%s chan=%s mac=%s",
134 curve, resp, mac);
135 } else {
136 /* Default channel list (normal DUT case) */
137 snprintf(buf, sizeof(buf),
138 "DPP_BOOTSTRAP_GEN type=qrcode curve=%s chan=81/11 mac=%s",
139 curve, mac);
140 }
141
Jouni Malinend86e5822017-08-29 03:55:32 +0300142 if (wpa_command_resp(ifname, buf, resp, sizeof(resp)) < 0)
143 return -2;
144 if (strncmp(resp, "FAIL", 4) == 0)
145 return -2;
146 dut->dpp_local_bootstrap = atoi(resp);
147 snprintf(buf, sizeof(buf), "DPP_BOOTSTRAP_GET_URI %d",
148 atoi(resp));
149 if (wpa_command_resp(ifname, buf, resp, sizeof(resp)) < 0)
150 return -2;
151 if (strncmp(resp, "FAIL", 4) == 0)
152 return -2;
153
154 sigma_dut_print(dut, DUT_MSG_DEBUG, "URI: %s", resp);
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530155
156 if (send_result) {
157 ascii2hexstr(resp, hex);
158 snprintf(resp, sizeof(resp), "BootstrappingData,%s", hex);
159 send_resp(dut, conn, SIGMA_COMPLETE, resp);
160 }
161
162 if (success)
163 *success = 1;
Jouni Malinend86e5822017-08-29 03:55:32 +0300164 return 0;
165}
166
167
168static int dpp_set_peer_bootstrap(struct sigma_dut *dut,
169 struct sigma_conn *conn,
170 struct sigma_cmd *cmd)
171{
172 const char *val = get_param(cmd, "DPPBootstrappingdata");
Jouni Malinenb1dd21f2017-11-13 19:14:29 +0200173 char uri[1000];
Jouni Malinend86e5822017-08-29 03:55:32 +0300174 int res;
Jouni Malinend86e5822017-08-29 03:55:32 +0300175
176 if (!val) {
177 send_resp(dut, conn, SIGMA_ERROR,
178 "errorCode,Missing DPPBootstrappingdata");
179 return 0;
180 }
181
182 res = parse_hexstr(val, (unsigned char *) uri, sizeof(uri));
183 if (res < 0 || (size_t) res >= sizeof(uri))
184 return -2;
185 uri[res] = '\0';
186 sigma_dut_print(dut, DUT_MSG_DEBUG, "URI: %s", uri);
Jouni Malinenb1dd21f2017-11-13 19:14:29 +0200187 free(dut->dpp_peer_uri);
188 dut->dpp_peer_uri = strdup(uri);
Jouni Malinend86e5822017-08-29 03:55:32 +0300189
190 return 1;
191}
192
193
194static int dpp_hostapd_conf_update(struct sigma_dut *dut,
195 struct sigma_conn *conn, const char *ifname,
196 struct wpa_ctrl *ctrl)
197{
198 int res;
199 char buf[2000], buf2[2500], *pos, *pos2;
Jouni Malinenb4c5e3b2017-09-15 17:43:20 +0300200 const char *conf_data_events[] = {
201 "DPP-CONNECTOR",
202 "DPP-CONFOBJ-PASS",
203 "DPP-CONFOBJ-PSK",
204 NULL
205 };
Jouni Malinend86e5822017-08-29 03:55:32 +0300206
207 sigma_dut_print(dut, DUT_MSG_INFO,
208 "Update hostapd configuration based on DPP Config Object");
209
210 if (wpa_command(ifname, "SET wpa 2") < 0 ||
211 wpa_command(ifname, "SET wpa_key_mgmt DPP") < 0 ||
Jouni Malinen0d347232017-11-01 17:14:00 +0200212 wpa_command(ifname, "SET ieee80211w 1") < 0 ||
Jouni Malinend86e5822017-08-29 03:55:32 +0300213 wpa_command(ifname, "SET rsn_pairwise CCMP") < 0) {
214 send_resp(dut, conn, SIGMA_ERROR,
215 "errorCode,Failed to update AP security parameters");
216 goto out;
217 }
218
219 res = get_wpa_cli_event(dut, ctrl, "DPP-CONFOBJ-SSID",
220 buf, sizeof(buf));
221 if (res < 0) {
222 send_resp(dut, conn, SIGMA_ERROR,
223 "errorCode,No DPP-CONFOBJ-SSID");
224 goto out;
225 }
226 pos = strchr(buf, ' ');
227 if (!pos)
228 return -2;
229 pos++;
230 sigma_dut_print(dut, DUT_MSG_INFO,
231 "DPP: Config Object SSID: %s", pos);
232 snprintf(buf2, sizeof(buf2), "SET ssid %s", pos);
233 if (wpa_command(ifname, buf2) < 0) {
234 send_resp(dut, conn, SIGMA_ERROR,
235 "errorCode,Failed to update AP SSID");
236 goto out;
237 }
238
Jouni Malinenb4c5e3b2017-09-15 17:43:20 +0300239 res = get_wpa_cli_events(dut, ctrl, conf_data_events, buf, sizeof(buf));
Jouni Malinend86e5822017-08-29 03:55:32 +0300240 if (res < 0) {
241 send_resp(dut, conn, SIGMA_ERROR,
Jouni Malinenb4c5e3b2017-09-15 17:43:20 +0300242 "errorCode,No DPP-CONNECTOR/DPP-CONFOBJ-PASS/PSK");
Jouni Malinend86e5822017-08-29 03:55:32 +0300243 goto out;
244 }
Jouni Malinenb4c5e3b2017-09-15 17:43:20 +0300245
246 if (!strstr(buf, "DPP-CONNECTOR")) {
247 if (wpa_command(ifname, "SET wpa_key_mgmt WPA-PSK") < 0) {
248 send_resp(dut, conn, SIGMA_ERROR,
249 "errorCode,Failed to update AP security parameters");
250 goto out;
251 }
252
253 pos = strchr(buf, ' ');
254 if (!pos)
255 return -2;
256 pos++;
257 if (strstr(buf, "DPP-CONFOBJ-PASS")) {
258 char pass[64];
259 int pass_len;
260
261 pass_len = parse_hexstr(pos, (u8 *) pass, sizeof(pass));
Jouni Malinenfddb7ea2018-01-05 21:02:50 +0200262 if (pass_len < 0 || (size_t) pass_len >= sizeof(pass))
Jouni Malinenb4c5e3b2017-09-15 17:43:20 +0300263 return -2;
264 pass[pass_len] = '\0';
265 sigma_dut_print(dut, DUT_MSG_INFO,
266 "DPP: Passphrase: %s", pass);
267 snprintf(buf2, sizeof(buf2), "SET wpa_passphrase %s",
268 pass);
269 if (wpa_command(ifname, buf2) < 0) {
270 send_resp(dut, conn, SIGMA_ERROR,
271 "errorCode,Failed to set passphrase");
272 goto out;
273 }
274 } else if (strstr(buf, "DPP-CONFOBJ-PSK")) {
275 sigma_dut_print(dut, DUT_MSG_INFO,
276 "DPP: PSK: %s", pos);
277 snprintf(buf2, sizeof(buf2), "SET wpa_psk %s", pos);
278 if (wpa_command(ifname, buf2) < 0) {
279 send_resp(dut, conn, SIGMA_ERROR,
280 "errorCode,Failed to set PSK");
281 goto out;
282 }
283 }
284
285 goto skip_dpp_akm;
286 }
287
Jouni Malinend86e5822017-08-29 03:55:32 +0300288 pos = strchr(buf, ' ');
289 if (!pos)
290 return -2;
291 pos++;
292 sigma_dut_print(dut, DUT_MSG_INFO, "DPP: Connector: %s", pos);
293 snprintf(buf2, sizeof(buf2), "SET dpp_connector %s", pos);
294 if (wpa_command(ifname, buf2) < 0) {
295 send_resp(dut, conn, SIGMA_ERROR,
296 "errorCode,Failed to update AP Connector");
297 goto out;
298 }
299
300 res = get_wpa_cli_event(dut, ctrl, "DPP-C-SIGN-KEY",
301 buf, sizeof(buf));
302 if (res < 0) {
303 send_resp(dut, conn, SIGMA_ERROR,
304 "errorCode,No DPP-C-SIGN-KEY");
305 goto out;
306 }
307 pos = strchr(buf, ' ');
308 if (!pos)
309 return -2;
310 pos++;
Jouni Malinend86e5822017-08-29 03:55:32 +0300311 sigma_dut_print(dut, DUT_MSG_INFO, "DPP: C-sign-key: %s", pos);
312 snprintf(buf2, sizeof(buf2), "SET dpp_csign %s", pos);
313 if (wpa_command(ifname, buf2) < 0) {
314 send_resp(dut, conn, SIGMA_ERROR,
315 "errorCode,Failed to update AP C-sign-key");
316 goto out;
317 }
Jouni Malinend86e5822017-08-29 03:55:32 +0300318
319 res = get_wpa_cli_event(dut, ctrl, "DPP-NET-ACCESS-KEY",
320 buf, sizeof(buf));
321 if (res < 0) {
322 send_resp(dut, conn, SIGMA_ERROR,
323 "errorCode,No DPP-NET-ACCESS-KEY");
324 goto out;
325 }
326 pos = strchr(buf, ' ');
327 if (!pos)
328 return -2;
329 pos++;
330 pos2 = strchr(pos, ' ');
331 if (pos2)
332 *pos2++ = '\0';
333 sigma_dut_print(dut, DUT_MSG_INFO, "DPP: netAccessKey: %s", pos);
334 snprintf(buf2, sizeof(buf2), "SET dpp_netaccesskey %s", pos);
335 if (wpa_command(ifname, buf2) < 0) {
336 send_resp(dut, conn, SIGMA_ERROR,
337 "errorCode,Failed to update AP netAccessKey");
338 goto out;
339 }
340 if (pos2) {
341 sigma_dut_print(dut, DUT_MSG_INFO,
342 "DPP: netAccessKey expiry: %s", pos2);
343 snprintf(buf2, sizeof(buf2), "SET dpp_netaccesskey_expiry %s",
344 pos2);
345 if (wpa_command(ifname, buf2) < 0) {
346 send_resp(dut, conn, SIGMA_ERROR,
347 "errorCode,Failed to update AP netAccessKey expiry");
348 goto out;
349 }
350 }
Jouni Malinenb4c5e3b2017-09-15 17:43:20 +0300351skip_dpp_akm:
Jouni Malinend86e5822017-08-29 03:55:32 +0300352
353 if (wpa_command(ifname, "DISABLE") < 0 ||
354 wpa_command(ifname, "ENABLE") < 0) {
355 send_resp(dut, conn, SIGMA_ERROR,
356 "errorCode,Failed to update AP configuration");
357 goto out;
358 }
359
360 res = get_wpa_cli_event(dut, ctrl, "AP-ENABLED", buf, sizeof(buf));
361 if (res < 0) {
362 send_resp(dut, conn, SIGMA_ERROR, "errorCode,No AP-ENABLED");
363 goto out;
364 }
365
366 return 1;
367out:
368 return 0;
369}
370
371
Jouni Malinen772299f2017-11-06 00:36:26 +0200372struct dpp_test_info {
373 const char *step;
374 const char *frame;
375 const char *attr;
376 int value;
377};
378
379static const struct dpp_test_info dpp_tests[] = {
380 { "InvalidValue", "AuthenticationRequest", "WrappedData", 1 },
381 { "InvalidValue", "AuthenticationResponse", "WrappedData", 2 },
Jouni Malinenf96fcee2017-11-22 16:08:35 +0200382 { "InvalidValue", "AuthenticationResponse", "PrimaryWrappedData", 2 },
Jouni Malinen772299f2017-11-06 00:36:26 +0200383 { "InvalidValue", "AuthenticationConfirm", "WrappedData", 3 },
384 { "InvalidValue", "PKEXCRRequest", "WrappedData", 4 },
385 { "InvalidValue", "PKEXCRResponse", "WrappedData", 5 },
386 { "InvalidValue", "ConfigurationRequest", "WrappedData", 6 },
387 { "InvalidValue", "ConfigurationResponse", "WrappedData", 7 },
388 { "InvalidValue", "AuthenticationRequest", "InitCapabilities", 8 },
Jouni Malinen772299f2017-11-06 00:36:26 +0200389 { "MissingAttribute", "AuthenticationRequest", "RespBSKeyHash", 10 },
390 { "MissingAttribute", "AuthenticationRequest", "InitBSKeyHash", 11 },
391 { "MissingAttribute", "AuthenticationRequest", "InitProtocolKey", 12 },
392 { "MissingAttribute", "AuthenticationRequest", "InitNonce", 13 },
393 { "MissingAttribute", "AuthenticationRequest", "InitCapabilities", 14 },
394 { "MissingAttribute", "AuthenticationRequest", "WrappedData", 15 },
395 { "MissingAttribute", "AuthenticationResponse", "DPPStatus", 16 },
396 { "MissingAttribute", "AuthenticationResponse", "RespBSKeyHash", 17 },
397 { "MissingAttribute", "AuthenticationResponse", "InitBSKeyHash", 18 },
398 { "MissingAttribute", "AuthenticationResponse", "RespProtocolKey", 19 },
399 { "MissingAttribute", "AuthenticationResponse", "RespNonce", 20 },
400 { "MissingAttribute", "AuthenticationResponse", "InitNonce", 21 },
401 { "MissingAttribute", "AuthenticationResponse", "RespCapabilities",
402 22 },
403 { "MissingAttribute", "AuthenticationResponse", "RespAuthTag", 23 },
404 { "MissingAttribute", "AuthenticationResponse", "WrappedData", 24 },
Jouni Malinenf96fcee2017-11-22 16:08:35 +0200405 { "MissingAttribute", "AuthenticationResponse", "PrimaryWrappedData",
406 24 },
Jouni Malinen772299f2017-11-06 00:36:26 +0200407 { "MissingAttribute", "AuthenticationConfirm", "DPPStatus", 25 },
408 { "MissingAttribute", "AuthenticationConfirm", "RespBSKeyHash", 26 },
409 { "MissingAttribute", "AuthenticationConfirm", "InitBSKeyHash", 27 },
410 { "MissingAttribute", "AuthenticationConfirm", "InitAuthTag", 28 },
411 { "MissingAttribute", "AuthenticationConfirm", "WrappedData", 29 },
412 { "InvalidValue", "AuthenticationResponse", "InitNonce", 30 },
413 { "InvalidValue", "AuthenticationResponse", "RespCapabilities", 31 },
414 { "InvalidValue", "AuthenticationResponse", "RespAuthTag", 32 },
415 { "InvalidValue", "AuthenticationConfirm", "InitAuthTag", 33 },
416 { "MissingAttribute", "PKEXExchangeRequest", "FiniteCyclicGroup", 34 },
417 { "MissingAttribute", "PKEXExchangeRequest", "EncryptedKey", 35 },
418 { "MissingAttribute", "PKEXExchangeResponse", "DPPStatus", 36 },
419 { "MissingAttribute", "PKEXExchangeResponse", "EncryptedKey", 37 },
420 { "MissingAttribute", "PKEXCRRequest", "BSKey", 38 },
421 { "MissingAttribute", "PKEXCRRequest", "InitAuthTag", 39 },
422 { "MissingAttribute", "PKEXCRRequest", "WrappedData", 40 },
423 { "MissingAttribute", "PKEXCRResponse", "BSKey", 41 },
424 { "MissingAttribute", "PKEXCRResponse", "RespAuthTag", 42 },
425 { "MissingAttribute", "PKEXCRResponse", "WrappedData", 43 },
426 { "InvalidValue", "PKEXExchangeRequest", "EncryptedKey", 44 },
427 { "InvalidValue", "PKEXExchangeResponse", "EncryptedKey", 45 },
428 { "InvalidValue", "PKEXExchangeResponse", "DPPStatus", 46 },
429 { "InvalidValue", "PKEXCRRequest", "BSKey", 47 },
430 { "InvalidValue", "PKEXCRResponse", "BSKey", 48 },
431 { "InvalidValue", "PKEXCRRequest", "InitAuthTag", 49 },
432 { "InvalidValue", "PKEXCRResponse", "RespAuthTag", 50 },
433 { "MissingAttribute", "ConfigurationRequest", "EnrolleeNonce", 51 },
434 { "MissingAttribute", "ConfigurationRequest", "ConfigAttr", 52 },
435 { "MissingAttribute", "ConfigurationRequest", "WrappedData", 53 },
436 { "MissingAttribute", "ConfigurationResponse", "EnrolleeNonce", 54 },
437 { "MissingAttribute", "ConfigurationResponse", "ConfigObj", 55 },
438 { "MissingAttribute", "ConfigurationResponse", "DPPStatus", 56 },
439 { "MissingAttribute", "ConfigurationResponse", "WrappedData", 57 },
440 { "InvalidValue", "ConfigurationResponse", "DPPStatus", 58 },
441 { "InvalidValue", "ConfigurationResponse", "EnrolleeNonce", 59 },
Jouni Malinen53558e02017-11-06 12:58:28 +0200442 { "MissingAttribute", "PeerDiscoveryRequest", "TransactionID", 60 },
443 { "MissingAttribute", "PeerDiscoveryRequest", "Connector", 61 },
444 { "MissingAttribute", "PeerDiscoveryResponse", "TransactionID", 62 },
445 { "MissingAttribute", "PeerDiscoveryResponse", "DPPStatus", 63 },
446 { "MissingAttribute", "PeerDiscoveryResponse", "Connector", 64 },
Jouni Malinenae624482017-11-19 00:13:51 +0200447 { "InvalidValue", "AuthenticationRequest", "InitProtocolKey", 66 },
448 { "InvalidValue", "AuthenticationResponse", "RespProtocolKey", 67 },
449 { "InvalidValue", "AuthenticationRequest", "RespBSKeyHash", 68 },
450 { "InvalidValue", "AuthenticationRequest", "InitBSKeyHash", 69 },
451 { "InvalidValue", "AuthenticationResponse", "RespBSKeyHash", 70 },
452 { "InvalidValue", "AuthenticationResponse", "InitBSKeyHash", 71 },
453 { "InvalidValue", "AuthenticationConfirm", "RespBSKeyHash", 72 },
454 { "InvalidValue", "AuthenticationConfirm", "InitBSKeyHash", 73 },
455 { "InvalidValue", "AuthenticationResponse", "DPPStatus", 74 },
456 { "InvalidValue", "AuthenticationConfirm", "DPPStatus", 75 },
457 { "InvalidValue", "ConfigurationRequest", "ConfigAttr", 76 },
458 { "InvalidValue", "PeerDiscoveryResponse", "TransactionID", 77 },
459 { "InvalidValue", "PeerDiscoveryResponse", "DPPStatus", 78 },
460 { "InvalidValue", "PeerDiscoveryResponse", "Connector", 79 },
461 { "InvalidValue", "PeerDiscoveryRequest", "Connector", 80 },
Jouni Malinen67795a72017-11-22 16:24:43 +0200462 { "InvalidValue", "AuthenticationRequest", "InitNonce", 81 },
Jouni Malinen188839b2017-11-30 22:02:02 +0200463 { "InvalidValue", "PeerDiscoveryRequest", "TransactionID", 82 },
464 { "InvalidValue", "ConfigurationRequest", "EnrolleeNonce", 83 },
Jouni Malinen3a6b92a2017-12-05 20:22:43 +0200465 { "Timeout", "PKEXExchangeResponse", NULL, 84 },
466 { "Timeout", "PKEXCRRequest", NULL, 85 },
467 { "Timeout", "PKEXCRResponse", NULL, 86 },
468 { "Timeout", "AuthenticationRequest", NULL, 87 },
469 { "Timeout", "AuthenticationResponse", NULL, 88 },
470 { "Timeout", "AuthenticationConfirm", NULL, 89 },
471 { "Timeout", "ConfigurationRequest", NULL, 90 },
Jouni Malinen772299f2017-11-06 00:36:26 +0200472 { NULL, NULL, NULL, 0 }
473};
474
475
476static int dpp_get_test(const char *step, const char *frame, const char *attr)
477{
478 int i;
479
480 for (i = 0; dpp_tests[i].step; i++) {
481 if (strcasecmp(step, dpp_tests[i].step) == 0 &&
482 strcasecmp(frame, dpp_tests[i].frame) == 0 &&
Jouni Malinen3a6b92a2017-12-05 20:22:43 +0200483 ((!attr && dpp_tests[i].attr == NULL) ||
484 (attr && strcasecmp(attr, dpp_tests[i].attr) == 0)))
Jouni Malinen772299f2017-11-06 00:36:26 +0200485 return dpp_tests[i].value;
486 }
487
488 return -1;
489}
490
491
492static int dpp_wait_tx_status(struct sigma_dut *dut, struct wpa_ctrl *ctrl,
493 int frame_type)
494{
495 char buf[200], tmp[20];
496 int res;
497
498 snprintf(tmp, sizeof(tmp), "type=%d", frame_type);
499 for (;;) {
500 res = get_wpa_cli_event(dut, ctrl, "DPP-TX", buf, sizeof(buf));
501 if (res < 0)
502 return -1;
503 if (strstr(buf, tmp) != NULL)
504 break;
505 }
506
507 res = get_wpa_cli_event(dut, ctrl, "DPP-TX-STATUS",
508 buf, sizeof(buf));
509 if (res < 0 || strstr(buf, "result=FAILED") != NULL)
510 return -1;
511
512 return 0;
513}
514
515
Jouni Malinen3a6b92a2017-12-05 20:22:43 +0200516static int dpp_wait_rx(struct sigma_dut *dut, struct wpa_ctrl *ctrl,
Jouni Malinen3e4344e2018-01-22 11:47:37 +0200517 int frame_type, unsigned int max_wait)
Jouni Malinen3a6b92a2017-12-05 20:22:43 +0200518{
519 char buf[200], tmp[20];
520 int res;
Jouni Malinen9a3415c2018-01-10 22:12:22 +0200521 unsigned int old_timeout;
522
523 old_timeout = dut->default_timeout;
524 if (max_wait > 0 && dut->default_timeout > max_wait)
525 dut->default_timeout = max_wait;
Jouni Malinen3a6b92a2017-12-05 20:22:43 +0200526
527 snprintf(tmp, sizeof(tmp), "type=%d", frame_type);
528 for (;;) {
529 res = get_wpa_cli_event(dut, ctrl, "DPP-RX", buf, sizeof(buf));
Jouni Malinen9a3415c2018-01-10 22:12:22 +0200530 if (res < 0) {
531 dut->default_timeout = old_timeout;
Jouni Malinen3a6b92a2017-12-05 20:22:43 +0200532 return -1;
Jouni Malinen9a3415c2018-01-10 22:12:22 +0200533 }
Jouni Malinen3a6b92a2017-12-05 20:22:43 +0200534 if (strstr(buf, tmp) != NULL)
535 break;
536 }
537
Jouni Malinen9a3415c2018-01-10 22:12:22 +0200538 dut->default_timeout = old_timeout;
539 return 0;
540}
541
542
543static int dpp_wait_rx_conf_req(struct sigma_dut *dut, struct wpa_ctrl *ctrl,
Jouni Malinen3e4344e2018-01-22 11:47:37 +0200544 unsigned int max_wait)
Jouni Malinen9a3415c2018-01-10 22:12:22 +0200545{
546 char buf[200];
547 int res;
548 unsigned int old_timeout;
549
550 old_timeout = dut->default_timeout;
551 if (max_wait > 0 && dut->default_timeout > max_wait)
552 dut->default_timeout = max_wait;
553
554 for (;;) {
555 res = get_wpa_cli_event(dut, ctrl, "DPP-CONF-REQ-RX",
556 buf, sizeof(buf));
557 if (res < 0) {
558 dut->default_timeout = old_timeout;
559 return -1;
560 }
561
562 break;
563 }
564
565 dut->default_timeout = old_timeout;
Jouni Malinen3a6b92a2017-12-05 20:22:43 +0200566 return 0;
567}
568
569
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530570static int dpp_scan_peer_qrcode(struct sigma_dut *dut)
Jouni Malinend86e5822017-08-29 03:55:32 +0300571{
Jouni Malinen1a38cc32018-01-05 20:59:00 +0200572#ifdef ANDROID
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530573 char buf[100];
574 char *buf2 = NULL;
575 FILE *fp = NULL;
576 uint32_t length;
577 unsigned int count;
578
579 unlink(dpp_qrcode_file);
580
581 snprintf(buf, sizeof(buf),
582 "am start -n w1.fi.wpadebug/w1.fi.wpadebug.QrCodeScannerActivity");
583 if (system(buf) != 0) {
584 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to launch Scanner");
585 return -1;
586 }
587
588 count = 0;
589 while (!(fp = fopen(dpp_qrcode_file, "r"))) {
590 if (count > dut->default_timeout) {
591 sigma_dut_print(dut, DUT_MSG_ERROR,
592 "Failed to open dpp_qrcode_file - QR Code scanning timed out");
593 return -1;
594 }
595
596 sleep(1);
597 count++;
598 }
599
600 if (fseek(fp, 0, SEEK_END) < 0 || (length = ftell(fp)) <= 0 ||
601 fseek(fp, 0, SEEK_SET) < 0) {
602 sigma_dut_print(dut, DUT_MSG_ERROR,
603 "Failed to get QR Code result file length");
604 fclose(fp);
605 return -1;
606 }
607
608 buf2 = malloc(length + 1);
609 if (!buf2) {
610 fclose(fp);
611 return -1;
612 }
613
614 if (fread(buf2, 1, length, fp) != length) {
615 fclose(fp);
616 free(buf2);
617 return -1;
618 }
619
620 fclose(fp);
621 buf2[length] = '\0';
622
623 free(dut->dpp_peer_uri);
624 dut->dpp_peer_uri = strdup(buf2);
625 free(buf2);
626 return 0;
Jouni Malinen1a38cc32018-01-05 20:59:00 +0200627#else /* ANDROID */
628 pid_t pid;
629 int pid_status;
630 int pipe_out[2];
631 char buf[4000], *pos;
632 ssize_t len;
633 int res = -1, ret;
634 struct timeval tv;
635 fd_set rfd;
636
637 if (pipe(pipe_out) != 0) {
638 perror("pipe");
639 return -1;
640 }
641
642 pid = fork();
643 if (pid < 0) {
644 perror("fork");
645 close(pipe_out[0]);
646 close(pipe_out[1]);
647 return -1;
648 }
649
650 if (pid == 0) {
651 char *argv[4] = { "zbarcam", "--raw", "--prescale=320x240",
652 NULL };
653
654 dup2(pipe_out[1], STDOUT_FILENO);
655 close(pipe_out[0]);
656 close(pipe_out[1]);
657 execv("/usr/bin/zbarcam", argv);
658 perror("execv");
659 exit(0);
660 return -1;
661 }
662
663 close(pipe_out[1]);
664
665 FD_ZERO(&rfd);
666 FD_SET(pipe_out[0], &rfd);
667 tv.tv_sec = dut->default_timeout;
668 tv.tv_usec = 0;
669
670 ret = select(pipe_out[0] + 1, &rfd, NULL, NULL, &tv);
671 if (ret < 0) {
672 perror("select");
673 goto out;
674 }
675 if (ret == 0) {
676 sigma_dut_print(dut, DUT_MSG_DEBUG,
677 "QR Code scanning timed out");
678 goto out;
679 }
680
681 len = read(pipe_out[0], buf, sizeof(buf));
682 if (len <= 0)
683 goto out;
684 if (len == sizeof(buf))
685 len--;
686 buf[len] = '\0';
687 pos = strchr(buf, '\n');
688 if (pos)
689 *pos = '\0';
690 sigma_dut_print(dut, DUT_MSG_DEBUG, "URI from QR scanner: %s", buf);
691
692 free(dut->dpp_peer_uri);
693 dut->dpp_peer_uri = strdup(buf);
694 res = 0;
695out:
696 close(pipe_out[0]);
697 kill(pid, SIGTERM);
698 waitpid(pid, &pid_status, 0);
699
700 return res;
701#endif /* ANDROID */
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530702}
703
704
705static int dpp_display_own_qrcode(struct sigma_dut *dut)
706{
707 char buf[200], resp[2000];
708 const char *ifname = get_station_ifname();
Jouni Malinen1a38cc32018-01-05 20:59:00 +0200709#ifdef ANDROID
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530710 FILE *fp;
Jouni Malinen1a38cc32018-01-05 20:59:00 +0200711#else /* ANDROID */
712 pid_t pid;
713 int pid_status;
714#endif /* ANDROID */
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530715
716 snprintf(buf, sizeof(buf), "DPP_BOOTSTRAP_GET_URI %d",
717 dut->dpp_local_bootstrap);
718 if (wpa_command_resp(ifname, buf, resp, sizeof(resp)) < 0 ||
719 strncmp(resp, "FAIL", 4) == 0)
720 return -2;
Jouni Malinen1a38cc32018-01-05 20:59:00 +0200721 sigma_dut_print(dut, DUT_MSG_DEBUG, "Own bootstrap URI: %s", resp);
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530722
Jouni Malinen1a38cc32018-01-05 20:59:00 +0200723#ifdef ANDROID
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530724 unlink(dpp_qrcode_file);
725
726 fp = fopen(dpp_qrcode_file, "w");
727 if (!fp) {
728 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open file %s",
729 dpp_qrcode_file);
730 return -2;
731 }
732
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530733 fwrite(resp, 1, strlen(resp), fp);
734 fclose(fp);
735
736 snprintf(buf, sizeof(buf),
737 "am start -n w1.fi.wpadebug/w1.fi.wpadebug.QrCodeDisplayActivity");
738 if (system(buf) != 0) {
739 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to display QR Code");
740 return -1;
741 }
Jouni Malinen1a38cc32018-01-05 20:59:00 +0200742#else /* ANDROID */
743 pid = fork();
744 if (pid < 0) {
745 perror("fork");
746 return -1;
747 }
748
749 if (pid == 0) {
750 char *argv[3] = { "qr", resp, NULL };
751
752 execv("/usr/bin/qr", argv);
753 perror("execv");
754 exit(0);
755 return -1;
756 }
757
758 waitpid(pid, &pid_status, 0);
759#endif /* ANDROID */
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530760
761 return 0;
Jouni Malinend86e5822017-08-29 03:55:32 +0300762}
763
764
765static int dpp_automatic_dpp(struct sigma_dut *dut,
766 struct sigma_conn *conn,
767 struct sigma_cmd *cmd)
768{
769 const char *bs = get_param(cmd, "DPPBS");
770 const char *auth_role = get_param(cmd, "DPPAuthRole");
771 const char *prov_role = get_param(cmd, "DPPProvisioningRole");
772 const char *pkex_code = get_param(cmd, "DPPPKEXCode");
773 const char *pkex_code_id = get_param(cmd, "DPPPKEXCodeIdentifier");
774 const char *wait_conn = get_param(cmd, "DPPWaitForConnect");
775 const char *self_conf = get_param(cmd, "DPPSelfConfigure");
Jouni Malinen772299f2017-11-06 00:36:26 +0200776 const char *step = get_param(cmd, "DPPStep");
777 const char *frametype = get_param(cmd, "DPPFrameType");
778 const char *attr = get_param(cmd, "DPPIEAttribute");
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530779 const char *action_type = get_param(cmd, "DPPActionType");
Jouni Malinend86e5822017-08-29 03:55:32 +0300780 const char *role;
781 const char *val;
782 const char *conf_role;
Jouni Malinend86e5822017-08-29 03:55:32 +0300783 int conf_index = -1;
784 char buf[2000];
785 char conf_ssid[100];
786 char conf_pass[100];
787 char pkex_identifier[200];
788 struct wpa_ctrl *ctrl;
789 int res;
790 unsigned int old_timeout;
791 int own_pkex_id = -1;
792 const char *ifname = get_station_ifname();
793 const char *auth_events[] = {
794 "DPP-AUTH-SUCCESS",
795 "DPP-NOT-COMPATIBLE",
796 "DPP-RESPONSE-PENDING",
797 "DPP-SCAN-PEER-QR-CODE",
Srinivas Dasaribc9e0552018-01-04 19:24:28 +0530798 "DPP-AUTH-DIRECTION",
Jouni Malinend86e5822017-08-29 03:55:32 +0300799 NULL
800 };
801 const char *conf_events[] = {
802 "DPP-CONF-RECEIVED",
803 "DPP-CONF-SENT",
804 "DPP-CONF-FAILED",
805 NULL
806 };
807 const char *conn_events[] = {
808 "PMKSA-CACHE-ADDED",
809 "CTRL-EVENT-CONNECTED",
810 NULL
811 };
Jouni Malinen3d291f72017-11-02 11:31:05 +0200812 const char *groups_override = NULL;
Jouni Malinen772299f2017-11-06 00:36:26 +0200813 const char *result;
Jouni Malinend1e22f72017-12-05 21:12:17 +0200814 int check_mutual = 0;
Jouni Malinene89cdbf2017-12-11 20:18:24 +0200815 int enrollee_ap;
Jouni Malinenf2fa0d02018-01-11 20:51:31 +0200816 int force_gas_fragm = 0;
Jouni Malinend86e5822017-08-29 03:55:32 +0300817
818 if (!wait_conn)
819 wait_conn = "no";
820 if (!self_conf)
821 self_conf = "no";
822
823 if (!auth_role) {
824 send_resp(dut, conn, SIGMA_ERROR,
825 "errorCode,Missing DPPAuthRole");
826 return 0;
827 }
828
829 if (!prov_role) {
830 send_resp(dut, conn, SIGMA_ERROR,
831 "errorCode,Missing DPPProvisioningRole");
832 return 0;
833 }
834
Jouni Malinene89cdbf2017-12-11 20:18:24 +0200835 val = get_param(cmd, "DPPConfEnrolleeRole");
836 if (val)
837 enrollee_ap = strcasecmp(val, "AP") == 0;
838 else
839 enrollee_ap = sigma_dut_is_ap(dut);
840
Jouni Malinen3a6b92a2017-12-05 20:22:43 +0200841 if ((step || frametype) && (!step || !frametype)) {
Jouni Malinen772299f2017-11-06 00:36:26 +0200842 send_resp(dut, conn, SIGMA_ERROR,
843 "errorCode,Invalid DPPStep,DPPFrameType,DPPIEAttribute combination");
844 return 0;
845 }
846
Jouni Malinend86e5822017-08-29 03:55:32 +0300847 if (sigma_dut_is_ap(dut)) {
848 if (!dut->hostapd_ifname) {
849 sigma_dut_print(dut, DUT_MSG_ERROR,
850 "hostapd ifname not specified (-j)");
851 return -2;
852 }
853 ifname = dut->hostapd_ifname;
854
855 if (dpp_hostapd_run(dut) < 0) {
856 send_resp(dut, conn, SIGMA_ERROR,
857 "errorCode,Failed to start hostapd");
858 return 0;
859 }
860 }
861
Jouni Malinen67acb0c2017-11-21 01:01:54 +0200862 if (strcasecmp(prov_role, "Configurator") == 0 ||
863 strcasecmp(prov_role, "Both") == 0) {
Jouni Malinend86e5822017-08-29 03:55:32 +0300864 if (dut->dpp_conf_id < 0) {
865 snprintf(buf, sizeof(buf),
866 "DPP_CONFIGURATOR_ADD curve=%s",
867 dpp_get_curve(cmd, "DPPSigningKeyECC"));
868 if (wpa_command_resp(ifname, buf,
869 buf, sizeof(buf)) < 0) {
870 send_resp(dut, conn, SIGMA_ERROR,
871 "errorCode,Failed to set up configurator");
872 return 0;
873 }
874 dut->dpp_conf_id = atoi(buf);
875 }
Jouni Malinen67acb0c2017-11-21 01:01:54 +0200876 if (strcasecmp(prov_role, "Configurator") == 0)
877 role = "configurator";
878 else
879 role = "either";
Jouni Malinend86e5822017-08-29 03:55:32 +0300880 } else if (strcasecmp(prov_role, "Enrollee") == 0) {
881 role = "enrollee";
882 } else {
883 send_resp(dut, conn, SIGMA_ERROR,
884 "errorCode,Unknown DPPProvisioningRole");
885 return 0;
886 }
887
888 pkex_identifier[0] = '\0';
889 if (strcasecmp(bs, "PKEX") == 0) {
Jouni Malinen4f47a272017-11-04 12:29:11 +0200890 if (sigma_dut_is_ap(dut) && dut->ap_channel != 6) {
891 /* For now, have to make operating channel match DPP
892 * listen channel. This should be removed once hostapd
893 * has support for DPP listen on non-operating channel.
894 */
895 sigma_dut_print(dut, DUT_MSG_INFO,
896 "Update hostapd operating channel to match listen needs");
897 dut->ap_channel = 6;
898 if (wpa_command(ifname, "SET channel 6") < 0 ||
899 wpa_command(ifname, "DISABLE") < 0 ||
900 wpa_command(ifname, "ENABLE") < 0) {
901 send_resp(dut, conn, SIGMA_ERROR,
902 "errorCode,Failed to update channel");
903 return 0;
904 }
905 }
906
Jouni Malinend86e5822017-08-29 03:55:32 +0300907 if (!pkex_code) {
908 send_resp(dut, conn, SIGMA_ERROR,
909 "errorCode,Missing DPPPKEXCode");
910 return 0;
911 }
912
913 if (pkex_code_id)
914 snprintf(pkex_identifier, sizeof(pkex_identifier),
915 "identifier=%s ", pkex_code_id);
916
917 snprintf(buf, sizeof(buf),
918 "DPP_BOOTSTRAP_GEN type=pkex curve=%s",
919 dpp_get_curve(cmd, "DPPCryptoIdentifier"));
920 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0) {
921 send_resp(dut, conn, SIGMA_ERROR,
922 "errorCode,Failed to set up PKEX");
923 return 0;
924 }
925 own_pkex_id = atoi(buf);
926 }
927
928 ctrl = open_wpa_mon(ifname);
929 if (!ctrl) {
930 sigma_dut_print(dut, DUT_MSG_ERROR,
931 "Failed to open wpa_supplicant monitor connection");
932 return -2;
933 }
934
935 old_timeout = dut->default_timeout;
936 val = get_param(cmd, "DPPTimeout");
937 if (val && atoi(val) > 0) {
938 dut->default_timeout = atoi(val);
939 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP timeout: %u",
940 dut->default_timeout);
941 }
942
943 conf_ssid[0] = '\0';
944 conf_pass[0] = '\0';
945 val = get_param(cmd, "DPPConfIndex");
946 if (val)
947 conf_index = atoi(val);
Jouni Malinend86e5822017-08-29 03:55:32 +0300948 switch (conf_index) {
Jouni Malinen258cc262017-10-13 00:19:56 +0300949 case -1:
950 conf_role = NULL;
951 break;
Jouni Malinend86e5822017-08-29 03:55:32 +0300952 case 1:
953 ascii2hexstr("DPPNET01", buf);
954 snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
Jouni Malinene89cdbf2017-12-11 20:18:24 +0200955 if (enrollee_ap) {
Jouni Malinend86e5822017-08-29 03:55:32 +0300956 conf_role = "ap-dpp";
Jouni Malinen3d291f72017-11-02 11:31:05 +0200957 groups_override = "[{\"groupId\":\"DPPGROUP_DPP_INFRA\",\"netRole\":\"ap\"}]";
958 } else {
Jouni Malinend86e5822017-08-29 03:55:32 +0300959 conf_role = "sta-dpp";
Jouni Malinen3d291f72017-11-02 11:31:05 +0200960 groups_override = "[{\"groupId\":\"DPPGROUP_DPP_INFRA\",\"netRole\":\"sta\"}]";
961 }
Jouni Malinend86e5822017-08-29 03:55:32 +0300962 break;
963 case 2:
964 ascii2hexstr("DPPNET01", buf);
965 snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
Jouni Malinen8f81cdf2017-09-15 18:15:18 +0300966 snprintf(conf_pass, sizeof(conf_pass),
967 "psk=10506e102ad1e7f95112f6b127675bb8344dacacea60403f3fa4055aec85b0fc");
Jouni Malinene89cdbf2017-12-11 20:18:24 +0200968 if (enrollee_ap)
Jouni Malinend86e5822017-08-29 03:55:32 +0300969 conf_role = "ap-psk";
970 else
971 conf_role = "sta-psk";
972 break;
973 case 3:
974 ascii2hexstr("DPPNET01", buf);
975 snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
976 ascii2hexstr("ThisIsDppPassphrase", buf);
977 snprintf(conf_pass, sizeof(conf_pass), "pass=%s", buf);
Jouni Malinene89cdbf2017-12-11 20:18:24 +0200978 if (enrollee_ap)
Jouni Malinend86e5822017-08-29 03:55:32 +0300979 conf_role = "ap-psk";
980 else
981 conf_role = "sta-psk";
982 break;
Jouni Malinen3d291f72017-11-02 11:31:05 +0200983 case 4:
984 ascii2hexstr("DPPNET01", buf);
985 snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
Jouni Malinene89cdbf2017-12-11 20:18:24 +0200986 if (enrollee_ap) {
Jouni Malinen3d291f72017-11-02 11:31:05 +0200987 conf_role = "ap-dpp";
988 groups_override = "[{\"groupId\":\"DPPGROUP_DPP_INFRA2\",\"netRole\":\"ap\"}]";
989 } else {
990 conf_role = "sta-dpp";
991 groups_override = "[{\"groupId\":\"DPPGROUP_DPP_INFRA2\",\"netRole\":\"sta\"}]";
992 }
993 break;
Jouni Malinen7d031c72018-01-09 19:39:56 +0200994 case 5:
995 ascii2hexstr("DPPNET01", buf);
996 snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
997 ascii2hexstr("ThisIsDppPassphrase", buf);
998 snprintf(conf_pass, sizeof(conf_pass), "pass=%s", buf);
999 if (enrollee_ap)
1000 conf_role = "ap-sae";
1001 else
1002 conf_role = "sta-sae";
1003 break;
1004 case 6:
1005 ascii2hexstr("DPPNET01", buf);
1006 snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
1007 ascii2hexstr("ThisIsDppPassphrase", buf);
1008 snprintf(conf_pass, sizeof(conf_pass), "pass=%s", buf);
1009 if (enrollee_ap)
1010 conf_role = "ap-psk-sae";
1011 else
1012 conf_role = "sta-psk-sae";
1013 break;
Jouni Malinenf2fa0d02018-01-11 20:51:31 +02001014 case 7:
1015 ascii2hexstr("DPPNET01", buf);
1016 snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
1017 if (enrollee_ap) {
1018 conf_role = "ap-dpp";
1019 groups_override = "[{\"groupId\":\"DPPGROUP_DPP_INFRA\",\"netRole\":\"ap\"}]";
1020 } else {
1021 conf_role = "sta-dpp";
1022 groups_override = "[{\"groupId\":\"DPPGROUP_DPP_INFRA\",\"netRole\":\"sta\"}]";
1023 }
1024 force_gas_fragm = 1;
1025 break;
Jouni Malinenf7490762017-10-12 00:34:37 +03001026 default:
1027 send_resp(dut, conn, SIGMA_ERROR,
1028 "errorCode,Unsupported DPPConfIndex");
1029 goto out;
Jouni Malinend86e5822017-08-29 03:55:32 +03001030 }
1031
Jouni Malinen3d291f72017-11-02 11:31:05 +02001032 if (groups_override) {
Jouni Malinenf2fa0d02018-01-11 20:51:31 +02001033 const char *extra = "";
1034 char spaces[1500];
1035
1036 if (force_gas_fragm) {
1037 memset(spaces, ' ', sizeof(spaces));
1038 spaces[sizeof(spaces) - 1] = '\0';
1039 extra = spaces;
1040 }
1041
1042 snprintf(buf, sizeof(buf), "SET dpp_groups_override %s%s",
1043 groups_override, extra);
Jouni Malinen3d291f72017-11-02 11:31:05 +02001044 if (wpa_command(ifname, buf) < 0) {
1045 send_resp(dut, conn, SIGMA_ERROR,
1046 "errorCode,Failed to set cred:groups");
1047 goto out;
1048 }
1049 }
1050
Jouni Malinen772299f2017-11-06 00:36:26 +02001051 if (step) {
1052 int test;
1053
1054 test = dpp_get_test(step, frametype, attr);
1055 if (test <= 0) {
1056 send_resp(dut, conn, SIGMA_ERROR,
1057 "errorCode,Unsupported DPPStep/DPPFrameType/DPPIEAttribute");
1058 goto out;
1059 }
1060
1061 snprintf(buf, sizeof(buf), "SET dpp_test %d", test);
1062 if (wpa_command(ifname, buf) < 0) {
1063 send_resp(dut, conn, SIGMA_ERROR,
1064 "errorCode,Failed to set dpp_test");
1065 goto out;
1066 }
1067 } else {
1068 wpa_command(ifname, "SET dpp_test 0");
1069 }
1070
Jouni Malinenfbb268d2017-11-17 18:53:49 +02001071 if (strcasecmp(self_conf, "Yes") == 0) {
1072 if (strcasecmp(prov_role, "Configurator") != 0) {
1073 send_resp(dut, conn, SIGMA_ERROR,
1074 "errorCode,Invalid DPPSelfConfigure use - only allowed for Configurator role");
1075 goto out;
1076 }
1077 if (!conf_role) {
1078 send_resp(dut, conn, SIGMA_ERROR,
1079 "errorCode,Missing DPPConfIndex");
1080 goto out;
1081 }
1082
1083 snprintf(buf, sizeof(buf),
1084 "DPP_CONFIGURATOR_SIGN conf=%s %s %s configurator=%d",
1085 conf_role, conf_ssid, conf_pass, dut->dpp_conf_id);
1086 if (wpa_command(ifname, buf) < 0) {
1087 send_resp(dut, conn, SIGMA_ERROR,
1088 "errorCode,Failed to initiate DPP self-configuration");
1089 goto out;
1090 }
Jouni Malinen174db642017-11-27 20:16:29 +02001091 if (sigma_dut_is_ap(dut))
1092 goto update_ap;
Jouni Malinenfbb268d2017-11-17 18:53:49 +02001093 goto wait_connect;
1094 } else if (strcasecmp(auth_role, "Initiator") == 0) {
Jouni Malinend86e5822017-08-29 03:55:32 +03001095 char own_txt[20];
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02001096 int dpp_peer_bootstrap = -1;
Jouni Malinenb5ab8282017-11-21 01:12:22 +02001097 char neg_freq[30];
1098
Jouni Malinend1e22f72017-12-05 21:12:17 +02001099 val = get_param(cmd, "DPPAuthDirection");
1100 check_mutual = val && strcasecmp(val, "Mutual") == 0;
1101
Jouni Malinenb5ab8282017-11-21 01:12:22 +02001102 neg_freq[0] = '\0';
1103 val = get_param(cmd, "DPPSubsequentChannel");
1104 if (val) {
1105 int opclass, channel, freq;
1106
1107 opclass = atoi(val);
1108 val = strchr(val, '/');
1109 if (opclass == 0 || !val) {
1110 send_resp(dut, conn, SIGMA_ERROR,
1111 "errorCode,Invalid DPPSubsequentChannel");
1112 goto out;
1113 }
1114 val++;
1115 channel = atoi(val);
1116
1117 /* Ignoring opclass for now; could use it here for more
1118 * robust frequency determination. */
1119 freq = channel_to_freq(channel);
1120 if (!freq) {
1121 send_resp(dut, conn, SIGMA_ERROR,
1122 "errorCode,Unsupported DPPSubsequentChannel channel");
1123 goto out;
1124 }
1125 snprintf(neg_freq, sizeof(neg_freq), " neg_freq=%d",
1126 freq);
1127 }
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02001128
1129 if (strcasecmp(bs, "QR") == 0) {
1130 if (!dut->dpp_peer_uri) {
1131 send_resp(dut, conn, SIGMA_ERROR,
1132 "errorCode,Missing peer bootstrapping info");
1133 goto out;
1134 }
1135
1136 snprintf(buf, sizeof(buf), "DPP_QR_CODE %s",
1137 dut->dpp_peer_uri);
1138 if (wpa_command_resp(ifname, buf, buf,
1139 sizeof(buf)) < 0) {
1140 send_resp(dut, conn, SIGMA_ERROR,
1141 "errorCode,Failed to parse URI");
1142 goto out;
1143 }
1144 dpp_peer_bootstrap = atoi(buf);
1145 }
Jouni Malinend86e5822017-08-29 03:55:32 +03001146
Jouni Malinen63d50412017-11-24 11:55:38 +02001147 if (dut->dpp_local_bootstrap >= 0)
Jouni Malinend86e5822017-08-29 03:55:32 +03001148 snprintf(own_txt, sizeof(own_txt), " own=%d",
1149 dut->dpp_local_bootstrap);
1150 else
1151 own_txt[0] = '\0';
1152 if (strcasecmp(bs, "QR") == 0 &&
Jouni Malinen67acb0c2017-11-21 01:01:54 +02001153 (strcasecmp(prov_role, "Configurator") == 0 ||
1154 strcasecmp(prov_role, "Both") == 0)) {
Jouni Malinen258cc262017-10-13 00:19:56 +03001155 if (!conf_role) {
1156 send_resp(dut, conn, SIGMA_ERROR,
1157 "errorCode,Missing DPPConfIndex");
1158 goto out;
1159 }
Jouni Malinend86e5822017-08-29 03:55:32 +03001160 snprintf(buf, sizeof(buf),
Jouni Malinenb5ab8282017-11-21 01:12:22 +02001161 "DPP_AUTH_INIT peer=%d%s role=%s conf=%s %s %s configurator=%d%s",
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02001162 dpp_peer_bootstrap, own_txt, role,
Jouni Malinend86e5822017-08-29 03:55:32 +03001163 conf_role, conf_ssid, conf_pass,
Jouni Malinenb5ab8282017-11-21 01:12:22 +02001164 dut->dpp_conf_id, neg_freq);
Jouni Malinend86e5822017-08-29 03:55:32 +03001165 } else if (strcasecmp(bs, "QR") == 0) {
1166 snprintf(buf, sizeof(buf),
Jouni Malinenb5ab8282017-11-21 01:12:22 +02001167 "DPP_AUTH_INIT peer=%d%s role=%s%s",
1168 dpp_peer_bootstrap, own_txt, role, neg_freq);
Jouni Malinend86e5822017-08-29 03:55:32 +03001169 } else if (strcasecmp(bs, "PKEX") == 0 &&
Jouni Malinen67acb0c2017-11-21 01:01:54 +02001170 (strcasecmp(prov_role, "Configurator") == 0 ||
1171 strcasecmp(prov_role, "Both") == 0)) {
Jouni Malinen258cc262017-10-13 00:19:56 +03001172 if (!conf_role) {
1173 send_resp(dut, conn, SIGMA_ERROR,
1174 "errorCode,Missing DPPConfIndex");
1175 goto out;
1176 }
Jouni Malinend86e5822017-08-29 03:55:32 +03001177 snprintf(buf, sizeof(buf),
1178 "DPP_PKEX_ADD own=%d init=1 role=%s conf=%s %s %s configurator=%d %scode=%s",
1179 own_pkex_id, role, conf_role,
1180 conf_ssid, conf_pass, dut->dpp_conf_id,
1181 pkex_identifier, pkex_code);
1182 } else if (strcasecmp(bs, "PKEX") == 0) {
1183 snprintf(buf, sizeof(buf),
1184 "DPP_PKEX_ADD own=%d init=1 role=%s %scode=%s",
1185 own_pkex_id, role, pkex_identifier, pkex_code);
Jouni Malinend551c6f2017-10-12 00:32:18 +03001186 } else {
1187 send_resp(dut, conn, SIGMA_ERROR,
1188 "errorCode,Unsupported DPPBS");
1189 goto out;
Jouni Malinend86e5822017-08-29 03:55:32 +03001190 }
1191 if (wpa_command(ifname, buf) < 0) {
1192 send_resp(dut, conn, SIGMA_ERROR,
1193 "errorCode,Failed to initiate DPP authentication");
1194 goto out;
1195 }
1196 } else if (strcasecmp(auth_role, "Responder") == 0) {
Jouni Malinen67f096a2017-11-24 11:58:51 +02001197 const char *delay_qr_resp;
Jouni Malinen63d50412017-11-24 11:55:38 +02001198 int mutual;
Jouni Malinend3afc5c2017-11-13 18:39:14 +02001199 int freq = 2462; /* default: channel 11 */
1200
Jouni Malinen06cfcb32018-01-11 20:43:50 +02001201 if (strcasecmp(bs, "PKEX") == 0) {
1202 /* default: channel 6 for PKEX */
1203 freq = 2437;
1204 }
1205
Jouni Malinen67f096a2017-11-24 11:58:51 +02001206 delay_qr_resp = get_param(cmd, "DPPDelayQRResponse");
1207
Jouni Malinen63d50412017-11-24 11:55:38 +02001208 val = get_param(cmd, "DPPAuthDirection");
1209 mutual = val && strcasecmp(val, "Mutual") == 0;
1210
Jouni Malinend3afc5c2017-11-13 18:39:14 +02001211 val = get_param(cmd, "DPPListenChannel");
1212 if (val) {
1213 freq = channel_to_freq(atoi(val));
1214 if (freq == 0) {
1215 send_resp(dut, conn, SIGMA_ERROR,
1216 "errorCode,Unsupported DPPListenChannel value");
1217 goto out;
1218 }
1219 }
Jouni Malinend86e5822017-08-29 03:55:32 +03001220
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02001221 if (!delay_qr_resp && dut->dpp_peer_uri) {
1222 snprintf(buf, sizeof(buf), "DPP_QR_CODE %s",
1223 dut->dpp_peer_uri);
1224 if (wpa_command_resp(ifname, buf, buf,
1225 sizeof(buf)) < 0) {
1226 send_resp(dut, conn, SIGMA_ERROR,
1227 "errorCode,Failed to parse URI");
1228 goto out;
1229 }
1230 }
1231
Jouni Malinend86e5822017-08-29 03:55:32 +03001232 if (strcasecmp(prov_role, "Configurator") == 0) {
Jouni Malinen258cc262017-10-13 00:19:56 +03001233 if (!conf_role) {
1234 send_resp(dut, conn, SIGMA_ERROR,
1235 "errorCode,Missing DPPConfIndex");
1236 goto out;
1237 }
Jouni Malinend86e5822017-08-29 03:55:32 +03001238 snprintf(buf, sizeof(buf),
1239 "SET dpp_configurator_params conf=%s %s %s configurator=%d",
1240 conf_role, conf_ssid, conf_pass,
1241 dut->dpp_conf_id);
1242 if (wpa_command(ifname, buf) < 0) {
1243 send_resp(dut, conn, SIGMA_ERROR,
1244 "errorCode,Failed to set configurator parameters");
1245 goto out;
1246 }
1247 }
1248 if (strcasecmp(bs, "PKEX") == 0) {
Jouni Malinend86e5822017-08-29 03:55:32 +03001249 snprintf(buf, sizeof(buf),
1250 "DPP_PKEX_ADD own=%d role=%s %scode=%s",
1251 own_pkex_id, role, pkex_identifier, pkex_code);
1252 if (wpa_command(ifname, buf) < 0) {
1253 send_resp(dut, conn, SIGMA_ERROR,
1254 "errorCode,Failed to configure DPP PKEX");
1255 goto out;
1256 }
1257 }
1258
Jouni Malinenbafc1932017-11-04 11:31:16 +02001259 snprintf(buf, sizeof(buf), "DPP_LISTEN %d role=%s%s",
1260 freq, role,
1261 (strcasecmp(bs, "QR") == 0 && mutual) ?
1262 " qr=mutual" : "");
1263 if (wpa_command(ifname, buf) < 0) {
1264 send_resp(dut, conn, SIGMA_ERROR,
1265 "errorCode,Failed to start DPP listen");
1266 goto out;
Jouni Malinend86e5822017-08-29 03:55:32 +03001267 }
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02001268
1269 if (delay_qr_resp && mutual && dut->dpp_peer_uri) {
1270 int wait_time = atoi(delay_qr_resp);
1271
1272 res = get_wpa_cli_events(dut, ctrl, auth_events,
1273 buf, sizeof(buf));
1274 if (res < 0) {
1275 send_resp(dut, conn, SIGMA_COMPLETE,
1276 "BootstrapResult,OK,AuthResult,Timeout");
1277 goto out;
1278 }
1279 sigma_dut_print(dut, DUT_MSG_DEBUG,
1280 "DPP auth result: %s", buf);
1281 if (strstr(buf, "DPP-SCAN-PEER-QR-CODE") == NULL) {
1282 send_resp(dut, conn, SIGMA_ERROR,
1283 "errorCode,No scan request for peer QR Code seen");
1284 goto out;
1285 }
1286 sigma_dut_print(dut, DUT_MSG_INFO,
1287 "Waiting %d second(s) before processing peer URI",
1288 wait_time);
1289 sleep(wait_time);
1290
1291 snprintf(buf, sizeof(buf), "DPP_QR_CODE %s",
1292 dut->dpp_peer_uri);
1293 if (wpa_command_resp(ifname, buf, buf,
1294 sizeof(buf)) < 0) {
1295 send_resp(dut, conn, SIGMA_ERROR,
1296 "errorCode,Failed to parse URI");
1297 goto out;
1298 }
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05301299 } else if (mutual && action_type &&
1300 strcasecmp(action_type, "ManualDPP") == 0) {
1301 res = get_wpa_cli_events(dut, ctrl, auth_events,
1302 buf, sizeof(buf));
1303 if (res < 0) {
1304 send_resp(dut, conn, SIGMA_COMPLETE,
1305 "BootstrapResult,OK,AuthResult,Timeout");
1306 goto out;
1307 }
1308 sigma_dut_print(dut, DUT_MSG_DEBUG,
1309 "DPP auth result: %s", buf);
1310 if (strstr(buf, "DPP-SCAN-PEER-QR-CODE") == NULL) {
1311 send_resp(dut, conn, SIGMA_ERROR,
1312 "errorCode,No scan request for peer QR Code seen");
1313 goto out;
1314 }
1315
1316 if (dpp_scan_peer_qrcode(dut) < 0) {
1317 send_resp(dut, conn, SIGMA_ERROR,
1318 "errorCode,Failed to scan peer QR Code");
1319 goto out;
1320 }
1321
1322 snprintf(buf, sizeof(buf), "DPP_QR_CODE %s",
1323 dut->dpp_peer_uri);
1324 if (wpa_command_resp(ifname, buf, buf,
1325 sizeof(buf)) < 0) {
1326 send_resp(dut, conn, SIGMA_ERROR,
1327 "errorCode,Failed to parse URI");
1328 goto out;
1329 }
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02001330 }
Jouni Malinend86e5822017-08-29 03:55:32 +03001331 } else {
1332 send_resp(dut, conn, SIGMA_ERROR,
1333 "errorCode,Unknown DPPAuthRole");
1334 goto out;
1335 }
1336
Jouni Malinen3a6b92a2017-12-05 20:22:43 +02001337 if (step && strcasecmp(step, "Timeout") == 0) {
1338 result = "errorCode,Unexpected state";
1339
1340 if (strcasecmp(frametype, "PKEXExchangeResponse") == 0) {
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001341 if (dpp_wait_rx(dut, ctrl, 8, -1) < 0)
Jouni Malinen3a6b92a2017-12-05 20:22:43 +02001342 result = "BootstrapResult,Timeout";
1343 else
1344 result = "BootstrapResult,Errorsent";
1345 }
1346
1347 if (strcasecmp(frametype, "PKEXCRRequest") == 0) {
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001348 if (dpp_wait_rx(dut, ctrl, 9, -1) < 0)
Jouni Malinen3a6b92a2017-12-05 20:22:43 +02001349 result = "BootstrapResult,Timeout";
1350 else
1351 result = "BootstrapResult,Errorsent";
1352 }
1353
1354 if (strcasecmp(frametype, "PKEXCRResponse") == 0) {
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001355 if (dpp_wait_rx(dut, ctrl, 10, -1) < 0)
Jouni Malinen3a6b92a2017-12-05 20:22:43 +02001356 result = "BootstrapResult,Timeout";
1357 else
1358 result = "BootstrapResult,Errorsent";
1359 }
1360
1361 if (strcasecmp(frametype, "AuthenticationRequest") == 0) {
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001362 if (dpp_wait_rx(dut, ctrl, 0, -1) < 0)
Jouni Malinen3a6b92a2017-12-05 20:22:43 +02001363 result = "BootstrapResult,OK,AuthResult,Timeout";
1364 else
1365 result = "BootstrapResult,OK,AuthResult,Errorsent";
1366 }
1367
1368 if (strcasecmp(frametype, "AuthenticationResponse") == 0) {
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001369 if (dpp_wait_rx(dut, ctrl, 1, -1) < 0)
Jouni Malinen3a6b92a2017-12-05 20:22:43 +02001370 result = "BootstrapResult,OK,AuthResult,Timeout";
1371 else
1372 result = "BootstrapResult,OK,AuthResult,Errorsent";
1373 }
1374
1375 if (strcasecmp(frametype, "AuthenticationConfirm") == 0) {
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001376 if (dpp_wait_rx(dut, ctrl, 2, -1) < 0)
Jouni Malinen3a6b92a2017-12-05 20:22:43 +02001377 result = "BootstrapResult,OK,AuthResult,Timeout";
1378 else
1379 result = "BootstrapResult,OK,AuthResult,Errorsent";
1380 }
1381
1382 if (strcasecmp(frametype, "ConfigurationRequest") == 0) {
1383 if (get_wpa_cli_event(dut, ctrl, "DPP-CONF-FAILED",
1384 buf, sizeof(buf)) < 0)
1385 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Timeout";
1386 else
1387 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Errorsent";
1388 }
1389
1390 send_resp(dut, conn, SIGMA_COMPLETE, result);
1391 goto out;
1392 }
1393
Jouni Malinen772299f2017-11-06 00:36:26 +02001394 if (frametype && strcasecmp(frametype, "PKEXExchangeRequest") == 0) {
1395 if (dpp_wait_tx_status(dut, ctrl, 7) < 0)
1396 result = "BootstrapResult,Timeout";
1397 else
1398 result = "BootstrapResult,Errorsent";
1399 send_resp(dut, conn, SIGMA_COMPLETE, result);
1400 goto out;
1401 }
1402
1403 if (frametype && strcasecmp(frametype, "PKEXExchangeResponse") == 0) {
1404 if (dpp_wait_tx_status(dut, ctrl, 8) < 0)
1405 result = "BootstrapResult,Timeout";
1406 else
1407 result = "BootstrapResult,Errorsent";
1408 send_resp(dut, conn, SIGMA_COMPLETE, result);
1409 goto out;
1410 }
1411
1412 if (frametype && strcasecmp(frametype, "PKEXCRRequest") == 0) {
1413 if (dpp_wait_tx_status(dut, ctrl, 9) < 0)
1414 result = "BootstrapResult,Timeout";
1415 else
1416 result = "BootstrapResult,Errorsent";
1417 send_resp(dut, conn, SIGMA_COMPLETE, result);
1418 goto out;
1419 }
1420
1421 if (frametype && strcasecmp(frametype, "PKEXCRResponse") == 0) {
1422 if (dpp_wait_tx_status(dut, ctrl, 10) < 0)
1423 result = "BootstrapResult,Timeout";
1424 else
1425 result = "BootstrapResult,Errorsent";
1426 send_resp(dut, conn, SIGMA_COMPLETE, result);
1427 goto out;
1428 }
1429
1430 if (frametype && strcasecmp(frametype, "AuthenticationRequest") == 0) {
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001431 if (dpp_wait_tx_status(dut, ctrl, 0) < 0) {
1432 send_resp(dut, conn, SIGMA_COMPLETE,
1433 "BootstrapResult,OK,AuthResult,Timeout");
1434 goto out;
1435 }
1436
1437 if (dpp_wait_rx(dut, ctrl, 1, 5) < 0)
1438 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,None";
Jouni Malinen772299f2017-11-06 00:36:26 +02001439 else
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001440 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationResponse";
Jouni Malinen772299f2017-11-06 00:36:26 +02001441 send_resp(dut, conn, SIGMA_COMPLETE, result);
1442 goto out;
1443 }
1444
1445 if (frametype && strcasecmp(frametype, "AuthenticationResponse") == 0) {
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001446 if (dpp_wait_tx_status(dut, ctrl, 1) < 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, 2, 5) < 0)
1453 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationRequest";
Jouni Malinen772299f2017-11-06 00:36:26 +02001454 else
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001455 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationConfirm";
Jouni Malinen772299f2017-11-06 00:36:26 +02001456 send_resp(dut, conn, SIGMA_COMPLETE, result);
1457 goto out;
1458 }
1459
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05301460 res = get_wpa_cli_events(dut, ctrl, auth_events, buf, sizeof(buf));
1461 if (res < 0) {
1462 send_resp(dut, conn, SIGMA_COMPLETE,
1463 "BootstrapResult,OK,AuthResult,Timeout");
1464 goto out;
1465 }
1466 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP auth result: %s", buf);
1467
1468 if (strstr(buf, "DPP-RESPONSE-PENDING")) {
1469 /* Display own QR code in manual mode */
1470 if (action_type && strcasecmp(action_type, "ManualDPP") == 0 &&
1471 dpp_display_own_qrcode(dut) < 0) {
1472 send_resp(dut, conn, SIGMA_ERROR,
1473 "errorCode,Failed to display own QR code");
1474 goto out;
1475 }
1476
1477 /* Wait for the actual result after the peer has scanned the
1478 * QR Code. */
1479 res = get_wpa_cli_events(dut, ctrl, auth_events,
1480 buf, sizeof(buf));
Jouni Malinend1e22f72017-12-05 21:12:17 +02001481 if (res < 0) {
1482 send_resp(dut, conn, SIGMA_COMPLETE,
1483 "BootstrapResult,OK,AuthResult,Timeout");
1484 goto out;
1485 }
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05301486
1487 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP auth result: %s", buf);
1488 }
1489
1490 if (check_mutual) {
1491 if (!strstr(buf, "DPP-AUTH-DIRECTION")) {
1492 send_resp(dut, conn, SIGMA_ERROR,
1493 "errorCode,No event for auth direction seen");
1494 goto out;
1495 }
1496
Jouni Malinend1e22f72017-12-05 21:12:17 +02001497 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP auth direction: %s",
1498 buf);
1499 if (strstr(buf, "mutual=1") == NULL) {
1500 send_resp(dut, conn, SIGMA_ERROR,
1501 "errorCode,Peer did not use mutual authentication");
1502 goto out;
1503 }
1504 }
1505
Jouni Malinen772299f2017-11-06 00:36:26 +02001506 if (frametype && strcasecmp(frametype, "AuthenticationConfirm") == 0) {
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001507 if (dpp_wait_tx_status(dut, ctrl, 2) < 0) {
1508 send_resp(dut, conn, SIGMA_COMPLETE,
1509 "BootstrapResult,OK,AuthResult,Timeout");
1510 goto out;
1511 }
1512
1513 if (dpp_wait_rx_conf_req(dut, ctrl, 5) < 0)
1514 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,AuthenticationResponse";
Jouni Malinen772299f2017-11-06 00:36:26 +02001515 else
Jouni Malinen9a3415c2018-01-10 22:12:22 +02001516 result = "BootstrapResult,OK,AuthResult,Errorsent,LastFrameReceived,ConfigurationRequest";
Jouni Malinen772299f2017-11-06 00:36:26 +02001517 send_resp(dut, conn, SIGMA_COMPLETE, result);
1518 goto out;
1519 }
1520
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05301521 if (strstr(buf, "DPP-AUTH-DIRECTION")) {
Jouni Malinen2e9c8a42017-11-19 12:06:18 +02001522 res = get_wpa_cli_events(dut, ctrl, auth_events,
1523 buf, sizeof(buf));
1524 if (res < 0) {
1525 send_resp(dut, conn, SIGMA_COMPLETE,
1526 "BootstrapResult,OK,AuthResult,Timeout");
1527 goto out;
1528 }
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05301529
1530 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP auth result: %s", buf);
Jouni Malinen2e9c8a42017-11-19 12:06:18 +02001531 }
1532
Jouni Malinend86e5822017-08-29 03:55:32 +03001533 if (strstr(buf, "DPP-NOT-COMPATIBLE")) {
1534 send_resp(dut, conn, SIGMA_COMPLETE,
1535 "BootstrapResult,OK,AuthResult,ROLES_NOT_COMPATIBLE");
1536 goto out;
1537 }
1538
1539 if (!strstr(buf, "DPP-AUTH-SUCCESS")) {
1540 send_resp(dut, conn, SIGMA_COMPLETE,
1541 "BootstrapResult,OK,AuthResult,FAILED");
1542 goto out;
1543 }
1544
Jouni Malinen772299f2017-11-06 00:36:26 +02001545 if (frametype && strcasecmp(frametype, "ConfigurationRequest") == 0) {
1546 res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE",
1547 buf, sizeof(buf));
1548 if (res < 0)
1549 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Timeout";
1550 else
1551 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Errorsent";
1552 send_resp(dut, conn, SIGMA_COMPLETE, result);
1553 goto out;
1554 }
1555
1556 if (frametype && strcasecmp(frametype, "ConfigurationResponse") == 0) {
1557 res = get_wpa_cli_event(dut, ctrl, "DPP-CONF-SENT",
1558 buf, sizeof(buf));
1559 if (res < 0)
1560 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Timeout";
1561 else
1562 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,Errorsent";
1563 send_resp(dut, conn, SIGMA_COMPLETE, result);
1564 goto out;
1565 }
1566
Jouni Malinend86e5822017-08-29 03:55:32 +03001567 res = get_wpa_cli_events(dut, ctrl, conf_events, buf, sizeof(buf));
1568 if (res < 0) {
1569 send_resp(dut, conn, SIGMA_COMPLETE,
1570 "BootstrapResult,OK,AuthResult,OK,ConfResult,Timeout");
1571 goto out;
1572 }
1573 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP conf result: %s", buf);
1574
1575 if (!strstr(buf, "DPP-CONF-SENT") &&
1576 !strstr(buf, "DPP-CONF-RECEIVED")) {
1577 send_resp(dut, conn, SIGMA_COMPLETE,
1578 "BootstrapResult,OK,AuthResult,OK,ConfResult,FAILED");
1579 goto out;
1580 }
1581
1582 if (sigma_dut_is_ap(dut) &&
1583 strcasecmp(prov_role, "Enrollee") == 0) {
Jouni Malinen174db642017-11-27 20:16:29 +02001584 update_ap:
Jouni Malinend86e5822017-08-29 03:55:32 +03001585 res = dpp_hostapd_conf_update(dut, conn, ifname, ctrl);
1586 if (res == 0)
1587 goto out;
1588 if (res < 0) {
1589 send_resp(dut, conn, SIGMA_ERROR, NULL);
1590 goto out;
1591 }
1592 }
1593
1594 if (strcasecmp(wait_conn, "Yes") == 0 &&
1595 !sigma_dut_is_ap(dut) &&
1596 strcasecmp(prov_role, "Enrollee") == 0) {
Jouni Malinenfbb268d2017-11-17 18:53:49 +02001597 wait_connect:
Jouni Malinen53558e02017-11-06 12:58:28 +02001598 if (frametype && strcasecmp(frametype,
1599 "PeerDiscoveryRequest") == 0) {
1600 if (dpp_wait_tx_status(dut, ctrl, 5) < 0)
1601 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Timeout";
1602 else
1603 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Errorsent";
1604 send_resp(dut, conn, SIGMA_COMPLETE, result);
1605 goto out;
1606 }
1607
Jouni Malinend86e5822017-08-29 03:55:32 +03001608 res = get_wpa_cli_events(dut, ctrl, conn_events,
1609 buf, sizeof(buf));
1610 if (res < 0) {
1611 send_resp(dut, conn, SIGMA_COMPLETE,
1612 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Timeout,NetworkConnectResult,Timeout");
1613 goto out;
1614 }
1615 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP connect result: %s",
1616 buf);
1617
1618 if (strstr(buf, "PMKSA-CACHE-ADDED")) {
1619 res = get_wpa_cli_events(dut, ctrl, conn_events,
1620 buf, sizeof(buf));
1621 if (res < 0) {
1622 send_resp(dut, conn, SIGMA_COMPLETE,
1623 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,Timeout");
1624 goto out;
1625 }
1626 sigma_dut_print(dut, DUT_MSG_DEBUG,
1627 "DPP connect result: %s", buf);
1628 if (strstr(buf, "CTRL-EVENT-CONNECTED"))
1629 send_resp(dut, conn, SIGMA_COMPLETE,
1630 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,OK");
1631 else
1632 send_resp(dut, conn, SIGMA_COMPLETE,
1633 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,Timeout");
1634 goto out;
1635 }
1636
1637 send_resp(dut, conn, SIGMA_COMPLETE,
1638 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkConnectResult,OK");
1639 goto out;
1640 }
1641
Jouni Malinen53558e02017-11-06 12:58:28 +02001642 if (strcasecmp(wait_conn, "Yes") == 0 &&
1643 frametype && strcasecmp(frametype, "PeerDiscoveryResponse") == 0) {
1644 if (dpp_wait_tx_status(dut, ctrl, 6) < 0)
1645 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Timeout";
1646 else
1647 result = "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Errorsent";
1648 send_resp(dut, conn, SIGMA_COMPLETE, result);
1649 goto out;
1650 }
1651
Jouni Malinend86e5822017-08-29 03:55:32 +03001652 send_resp(dut, conn, SIGMA_COMPLETE,
1653 "BootstrapResult,OK,AuthResult,OK,ConfResult,OK");
1654out:
1655 wpa_ctrl_detach(ctrl);
1656 wpa_ctrl_close(ctrl);
1657 dut->default_timeout = old_timeout;
1658 return 0;
1659}
1660
1661
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05301662static int dpp_manual_dpp(struct sigma_dut *dut,
1663 struct sigma_conn *conn,
1664 struct sigma_cmd *cmd)
1665{
1666 const char *auth_role = get_param(cmd, "DPPAuthRole");
1667 int res = -1, success;
1668 const char *val;
1669 unsigned int old_timeout;
1670
1671 if (!auth_role) {
1672 send_resp(dut, conn, SIGMA_ERROR,
1673 "errorCode,Missing DPPAuthRole");
1674 return 0;
1675 }
1676
1677 old_timeout = dut->default_timeout;
1678 val = get_param(cmd, "DPPTimeout");
1679 if (val && atoi(val) > 0) {
1680 dut->default_timeout = atoi(val);
1681 sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP timeout: %u",
1682 dut->default_timeout);
1683 }
1684
1685 res = dpp_get_local_bootstrap(dut, conn, cmd, 0, &success);
1686 if (res || !success)
1687 goto out;
1688
1689 if (strcasecmp(auth_role, "Responder") == 0) {
1690 res = dpp_display_own_qrcode(dut);
1691 if (res < 0)
1692 goto out;
1693
1694 res = dpp_automatic_dpp(dut, conn, cmd);
1695 goto out;
1696 }
1697
1698 if (strcasecmp(auth_role, "Initiator") == 0) {
1699 res = dpp_scan_peer_qrcode(dut);
Jouni Malinen1a38cc32018-01-05 20:59:00 +02001700 if (res < 0) {
1701 send_resp(dut, conn, SIGMA_ERROR,
1702 "errorCode,Failed to scan peer QR Code");
1703 res = 0;
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05301704 goto out;
Jouni Malinen1a38cc32018-01-05 20:59:00 +02001705 }
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05301706
1707 res = dpp_automatic_dpp(dut, conn, cmd);
1708 goto out;
1709 }
1710
1711 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unknown DPPAuthRole");
1712 res = 0;
1713out:
1714 dut->default_timeout = old_timeout;
1715 return res;
1716}
1717
1718
Jouni Malinend86e5822017-08-29 03:55:32 +03001719int dpp_dev_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
1720 struct sigma_cmd *cmd)
1721{
1722 const char *type = get_param(cmd, "DPPActionType");
1723 const char *bs = get_param(cmd, "DPPBS");
1724
1725 if (!bs) {
1726 send_resp(dut, conn, SIGMA_ERROR,
1727 "errorCode,Missing DPPBS");
1728 return 0;
1729 }
1730
1731 if (!type) {
1732 send_resp(dut, conn, SIGMA_ERROR,
1733 "errorCode,Missing DPPActionType");
1734 return 0;
1735 }
1736
1737 if (strcasecmp(type, "GetLocalBootstrap") == 0)
Srinivas Dasaribc9e0552018-01-04 19:24:28 +05301738 return dpp_get_local_bootstrap(dut, conn, cmd, 1, NULL);
Jouni Malinend86e5822017-08-29 03:55:32 +03001739 if (strcasecmp(type, "SetPeerBootstrap") == 0)
1740 return dpp_set_peer_bootstrap(dut, conn, cmd);
1741 if (strcasecmp(type, "ManualDPP") == 0)
1742 return dpp_manual_dpp(dut, conn, cmd);
1743 if (strcasecmp(type, "AutomaticDPP") == 0)
1744 return dpp_automatic_dpp(dut, conn, cmd);
1745
1746 send_resp(dut, conn, SIGMA_ERROR,
1747 "errorCode,Unsupported DPPActionType");
1748 return 0;
1749}