xref: /wlan-dirver/utils/sigma-dut/dpp.c (revision f749076814e55da0c5b0123d8f33b7c6b0abb5cf)
1d86e5828SJouni Malinen /*
2d86e5828SJouni Malinen  * Sigma Control API DUT (station/AP/sniffer)
3d86e5828SJouni Malinen  * Copyright (c) 2017, Qualcomm Atheros, Inc.
4d86e5828SJouni Malinen  * All Rights Reserved.
5d86e5828SJouni Malinen  * Licensed under the Clear BSD license. See README for more details.
6d86e5828SJouni Malinen  */
7d86e5828SJouni Malinen 
8d86e5828SJouni Malinen #include "sigma_dut.h"
9d86e5828SJouni Malinen #include "wpa_ctrl.h"
10d86e5828SJouni Malinen #include "wpa_helpers.h"
11d86e5828SJouni Malinen 
12d86e5828SJouni Malinen 
13d86e5828SJouni Malinen static int sigma_dut_is_ap(struct sigma_dut *dut)
14d86e5828SJouni Malinen {
15d86e5828SJouni Malinen 	return dut->device_type == AP_unknown ||
16d86e5828SJouni Malinen 		dut->device_type == AP_testbed ||
17d86e5828SJouni Malinen 		dut->device_type == AP_dut;
18d86e5828SJouni Malinen }
19d86e5828SJouni Malinen 
20d86e5828SJouni Malinen 
21d86e5828SJouni Malinen static int dpp_hostapd_run(struct sigma_dut *dut)
22d86e5828SJouni Malinen {
23d86e5828SJouni Malinen 	if (dut->hostapd_running)
24d86e5828SJouni Malinen 		return 0;
25d86e5828SJouni Malinen 
26d86e5828SJouni Malinen 	sigma_dut_print(dut, DUT_MSG_INFO,
27d86e5828SJouni Malinen 			"Starting hostapd in unconfigured state for DPP");
28d86e5828SJouni Malinen 	snprintf(dut->ap_ssid, sizeof(dut->ap_ssid), "unconfigured");
29d86e5828SJouni Malinen 	dut->ap_channel = 11;
30d86e5828SJouni Malinen 	dut->ap_is_dual = 0;
31d86e5828SJouni Malinen 	dut->ap_mode = AP_11ng;
32d86e5828SJouni Malinen 	dut->ap_key_mgmt = AP_OPEN;
33d86e5828SJouni Malinen 	dut->ap_cipher = AP_PLAIN;
34d86e5828SJouni Malinen 	return cmd_ap_config_commit(dut, NULL, NULL) == 1 ? 0 : -1;
35d86e5828SJouni Malinen }
36d86e5828SJouni Malinen 
37d86e5828SJouni Malinen 
38d86e5828SJouni Malinen static const char * dpp_get_curve(struct sigma_cmd *cmd, const char *arg)
39d86e5828SJouni Malinen {
40d86e5828SJouni Malinen 	const char *val = get_param(cmd, arg);
41d86e5828SJouni Malinen 
42d86e5828SJouni Malinen 	if (!val)
43d86e5828SJouni Malinen 		val = "P-256";
44d86e5828SJouni Malinen 	else if (strcasecmp(val, "BP-256R1") == 0)
45d86e5828SJouni Malinen 		val = "BP-256";
46d86e5828SJouni Malinen 	else if (strcasecmp(val, "BP-384R1") == 0)
47d86e5828SJouni Malinen 		val = "BP-384";
48d86e5828SJouni Malinen 	else if (strcasecmp(val, "BP-512R1") == 0)
49d86e5828SJouni Malinen 		val = "BP-512";
50d86e5828SJouni Malinen 
51d86e5828SJouni Malinen 	return val;
52d86e5828SJouni Malinen }
53d86e5828SJouni Malinen 
54d86e5828SJouni Malinen 
55d86e5828SJouni Malinen static int dpp_get_local_bootstrap(struct sigma_dut *dut,
56d86e5828SJouni Malinen 				   struct sigma_conn *conn,
57d86e5828SJouni Malinen 				   struct sigma_cmd *cmd)
58d86e5828SJouni Malinen {
59d86e5828SJouni Malinen 	const char *curve = dpp_get_curve(cmd, "DPPCryptoIdentifier");
60d86e5828SJouni Malinen 	const char *bs = get_param(cmd, "DPPBS");
61d86e5828SJouni Malinen 	char *pos, mac[50], buf[100], resp[1000], hex[2000];
62d86e5828SJouni Malinen 	const char *ifname = get_station_ifname();
63d86e5828SJouni Malinen 
64d86e5828SJouni Malinen 	if (strcasecmp(bs, "QR") != 0) {
65d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
66d86e5828SJouni Malinen 			  "errorCode,Unsupported DPPBS");
67d86e5828SJouni Malinen 		return 0;
68d86e5828SJouni Malinen 	}
69d86e5828SJouni Malinen 
70d86e5828SJouni Malinen 	if (sigma_dut_is_ap(dut)) {
71d86e5828SJouni Malinen 		u8 bssid[ETH_ALEN];
72d86e5828SJouni Malinen 
73d86e5828SJouni Malinen 		if (!dut->hostapd_ifname) {
74d86e5828SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_ERROR,
75d86e5828SJouni Malinen 					"hostapd ifname not specified (-j)");
76d86e5828SJouni Malinen 			return -2;
77d86e5828SJouni Malinen 		}
78d86e5828SJouni Malinen 		ifname = dut->hostapd_ifname;
79d86e5828SJouni Malinen 		if (get_hwaddr(dut->hostapd_ifname, bssid) < 0) {
80d86e5828SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_ERROR,
81d86e5828SJouni Malinen 					"Could not get MAC address for %s",
82d86e5828SJouni Malinen 					dut->hostapd_ifname);
83d86e5828SJouni Malinen 			return -2;
84d86e5828SJouni Malinen 		}
85d86e5828SJouni Malinen 		snprintf(mac, sizeof(mac), "%02x%02x%02x%02x%02x%02x",
86d86e5828SJouni Malinen 			 bssid[0], bssid[1], bssid[2],
87d86e5828SJouni Malinen 			 bssid[3], bssid[4], bssid[5]);
88d86e5828SJouni Malinen 	} else {
89d86e5828SJouni Malinen 		if (get_wpa_status(ifname, "address", mac, sizeof(mac)) < 0)
90d86e5828SJouni Malinen 			return -2;
91d86e5828SJouni Malinen 	}
92d86e5828SJouni Malinen 
93d86e5828SJouni Malinen 	pos = mac;
94d86e5828SJouni Malinen 	while (*pos) {
95d86e5828SJouni Malinen 		if (*pos == ':')
96d86e5828SJouni Malinen 			memmove(pos, pos + 1, strlen(pos));
97d86e5828SJouni Malinen 		else
98d86e5828SJouni Malinen 			pos++;
99d86e5828SJouni Malinen 	}
100d86e5828SJouni Malinen 
101d86e5828SJouni Malinen 	snprintf(buf, sizeof(buf),
102d86e5828SJouni Malinen 		 "DPP_BOOTSTRAP_GEN type=qrcode curve=%s chan=81/11 mac=%s",
103d86e5828SJouni Malinen 		 curve, mac);
104d86e5828SJouni Malinen 
105d86e5828SJouni Malinen 	if (sigma_dut_is_ap(dut) && dpp_hostapd_run(dut) < 0) {
106d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
107d86e5828SJouni Malinen 			  "errorCode,Failed to start hostapd");
108d86e5828SJouni Malinen 		return 0;
109d86e5828SJouni Malinen 	}
110d86e5828SJouni Malinen 
111d86e5828SJouni Malinen 	if (wpa_command_resp(ifname, buf, resp, sizeof(resp)) < 0)
112d86e5828SJouni Malinen 		return -2;
113d86e5828SJouni Malinen 	if (strncmp(resp, "FAIL", 4) == 0)
114d86e5828SJouni Malinen 		return -2;
115d86e5828SJouni Malinen 	dut->dpp_local_bootstrap = atoi(resp);
116d86e5828SJouni Malinen 	snprintf(buf, sizeof(buf), "DPP_BOOTSTRAP_GET_URI %d",
117d86e5828SJouni Malinen 		 atoi(resp));
118d86e5828SJouni Malinen 	if (wpa_command_resp(ifname, buf, resp, sizeof(resp)) < 0)
119d86e5828SJouni Malinen 		return -2;
120d86e5828SJouni Malinen 	if (strncmp(resp, "FAIL", 4) == 0)
121d86e5828SJouni Malinen 		return -2;
122d86e5828SJouni Malinen 
123d86e5828SJouni Malinen 	sigma_dut_print(dut, DUT_MSG_DEBUG, "URI: %s", resp);
124d86e5828SJouni Malinen 	ascii2hexstr(resp, hex);
125d86e5828SJouni Malinen 	snprintf(resp, sizeof(resp), "BootstrappingData,%s", hex);
126d86e5828SJouni Malinen 	send_resp(dut, conn, SIGMA_COMPLETE, resp);
127d86e5828SJouni Malinen 	return 0;
128d86e5828SJouni Malinen }
129d86e5828SJouni Malinen 
130d86e5828SJouni Malinen 
131d86e5828SJouni Malinen static int dpp_set_peer_bootstrap(struct sigma_dut *dut,
132d86e5828SJouni Malinen 				  struct sigma_conn *conn,
133d86e5828SJouni Malinen 				  struct sigma_cmd *cmd)
134d86e5828SJouni Malinen {
135d86e5828SJouni Malinen 	const char *val = get_param(cmd, "DPPBootstrappingdata");
136d86e5828SJouni Malinen 	char uri[1000], buf[1200];
137d86e5828SJouni Malinen 	int res;
138d86e5828SJouni Malinen 	const char *ifname = get_station_ifname();
139d86e5828SJouni Malinen 
140d86e5828SJouni Malinen 	if (!val) {
141d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
142d86e5828SJouni Malinen 			  "errorCode,Missing DPPBootstrappingdata");
143d86e5828SJouni Malinen 		return 0;
144d86e5828SJouni Malinen 	}
145d86e5828SJouni Malinen 
146d86e5828SJouni Malinen 	res = parse_hexstr(val, (unsigned char *) uri, sizeof(uri));
147d86e5828SJouni Malinen 	if (res < 0 || (size_t) res >= sizeof(uri))
148d86e5828SJouni Malinen 		return -2;
149d86e5828SJouni Malinen 	uri[res] = '\0';
150d86e5828SJouni Malinen 	sigma_dut_print(dut, DUT_MSG_DEBUG, "URI: %s", uri);
151d86e5828SJouni Malinen 
152d86e5828SJouni Malinen 	snprintf(buf, sizeof(buf), "DPP_QR_CODE %s", uri);
153d86e5828SJouni Malinen 
154d86e5828SJouni Malinen 	if (sigma_dut_is_ap(dut)) {
155d86e5828SJouni Malinen 		if (!dut->hostapd_ifname) {
156d86e5828SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_ERROR,
157d86e5828SJouni Malinen 					"hostapd ifname not specified (-j)");
158d86e5828SJouni Malinen 			return -2;
159d86e5828SJouni Malinen 		}
160d86e5828SJouni Malinen 		ifname = dut->hostapd_ifname;
161d86e5828SJouni Malinen 
162d86e5828SJouni Malinen 		if (dpp_hostapd_run(dut) < 0) {
163d86e5828SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
164d86e5828SJouni Malinen 				  "errorCode,Failed to start hostapd");
165d86e5828SJouni Malinen 			return 0;
166d86e5828SJouni Malinen 		}
167d86e5828SJouni Malinen 	}
168d86e5828SJouni Malinen 
169d86e5828SJouni Malinen 	if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0) {
170d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
171d86e5828SJouni Malinen 			  "errorCode,Failed to parse URI");
172d86e5828SJouni Malinen 		return 0;
173d86e5828SJouni Malinen 	}
174d86e5828SJouni Malinen 	dut->dpp_peer_bootstrap = atoi(buf);
175d86e5828SJouni Malinen 
176d86e5828SJouni Malinen 	return 1;
177d86e5828SJouni Malinen }
178d86e5828SJouni Malinen 
179d86e5828SJouni Malinen 
180d86e5828SJouni Malinen static int dpp_hostapd_conf_update(struct sigma_dut *dut,
181d86e5828SJouni Malinen 				   struct sigma_conn *conn, const char *ifname,
182d86e5828SJouni Malinen 				   struct wpa_ctrl *ctrl)
183d86e5828SJouni Malinen {
184d86e5828SJouni Malinen 	int res;
185d86e5828SJouni Malinen 	char buf[2000], buf2[2500], *pos, *pos2;
186b4c5e3b8SJouni Malinen 	const char *conf_data_events[] = {
187b4c5e3b8SJouni Malinen 		"DPP-CONNECTOR",
188b4c5e3b8SJouni Malinen 		"DPP-CONFOBJ-PASS",
189b4c5e3b8SJouni Malinen 		"DPP-CONFOBJ-PSK",
190b4c5e3b8SJouni Malinen 		NULL
191b4c5e3b8SJouni Malinen 	};
192d86e5828SJouni Malinen 
193d86e5828SJouni Malinen 	sigma_dut_print(dut, DUT_MSG_INFO,
194d86e5828SJouni Malinen 			"Update hostapd configuration based on DPP Config Object");
195d86e5828SJouni Malinen 
196d86e5828SJouni Malinen 	if (wpa_command(ifname, "SET wpa 2") < 0 ||
197d86e5828SJouni Malinen 	    wpa_command(ifname, "SET wpa_key_mgmt DPP") < 0 ||
198d86e5828SJouni Malinen 	    wpa_command(ifname, "SET rsn_pairwise CCMP") < 0) {
199d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
200d86e5828SJouni Malinen 			  "errorCode,Failed to update AP security parameters");
201d86e5828SJouni Malinen 		goto out;
202d86e5828SJouni Malinen 	}
203d86e5828SJouni Malinen 
204d86e5828SJouni Malinen 	res = get_wpa_cli_event(dut, ctrl, "DPP-CONFOBJ-SSID",
205d86e5828SJouni Malinen 				buf, sizeof(buf));
206d86e5828SJouni Malinen 	if (res < 0) {
207d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
208d86e5828SJouni Malinen 			  "errorCode,No DPP-CONFOBJ-SSID");
209d86e5828SJouni Malinen 		goto out;
210d86e5828SJouni Malinen 	}
211d86e5828SJouni Malinen 	pos = strchr(buf, ' ');
212d86e5828SJouni Malinen 	if (!pos)
213d86e5828SJouni Malinen 		return -2;
214d86e5828SJouni Malinen 	pos++;
215d86e5828SJouni Malinen 	sigma_dut_print(dut, DUT_MSG_INFO,
216d86e5828SJouni Malinen 			"DPP: Config Object SSID: %s", pos);
217d86e5828SJouni Malinen 	snprintf(buf2, sizeof(buf2), "SET ssid %s", pos);
218d86e5828SJouni Malinen 	if (wpa_command(ifname, buf2) < 0) {
219d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
220d86e5828SJouni Malinen 			  "errorCode,Failed to update AP SSID");
221d86e5828SJouni Malinen 		goto out;
222d86e5828SJouni Malinen 	}
223d86e5828SJouni Malinen 
224b4c5e3b8SJouni Malinen 	res = get_wpa_cli_events(dut, ctrl, conf_data_events, buf, sizeof(buf));
225d86e5828SJouni Malinen 	if (res < 0) {
226d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
227b4c5e3b8SJouni Malinen 			  "errorCode,No DPP-CONNECTOR/DPP-CONFOBJ-PASS/PSK");
228d86e5828SJouni Malinen 		goto out;
229d86e5828SJouni Malinen 	}
230b4c5e3b8SJouni Malinen 
231b4c5e3b8SJouni Malinen 	if (!strstr(buf, "DPP-CONNECTOR")) {
232b4c5e3b8SJouni Malinen 		if (wpa_command(ifname, "SET wpa_key_mgmt WPA-PSK") < 0) {
233b4c5e3b8SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
234b4c5e3b8SJouni Malinen 				  "errorCode,Failed to update AP security parameters");
235b4c5e3b8SJouni Malinen 			goto out;
236b4c5e3b8SJouni Malinen 		}
237b4c5e3b8SJouni Malinen 
238b4c5e3b8SJouni Malinen 		pos = strchr(buf, ' ');
239b4c5e3b8SJouni Malinen 		if (!pos)
240b4c5e3b8SJouni Malinen 			return -2;
241b4c5e3b8SJouni Malinen 		pos++;
242b4c5e3b8SJouni Malinen 		if (strstr(buf, "DPP-CONFOBJ-PASS")) {
243b4c5e3b8SJouni Malinen 			char pass[64];
244b4c5e3b8SJouni Malinen 			int pass_len;
245b4c5e3b8SJouni Malinen 
246b4c5e3b8SJouni Malinen 			pass_len = parse_hexstr(pos, (u8 *) pass, sizeof(pass));
247b4c5e3b8SJouni Malinen 			if (pass_len < 0 || pass_len >= sizeof(pass))
248b4c5e3b8SJouni Malinen 				return -2;
249b4c5e3b8SJouni Malinen 			pass[pass_len] = '\0';
250b4c5e3b8SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_INFO,
251b4c5e3b8SJouni Malinen 					"DPP: Passphrase: %s", pass);
252b4c5e3b8SJouni Malinen 			snprintf(buf2, sizeof(buf2), "SET wpa_passphrase %s",
253b4c5e3b8SJouni Malinen 				 pass);
254b4c5e3b8SJouni Malinen 			if (wpa_command(ifname, buf2) < 0) {
255b4c5e3b8SJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
256b4c5e3b8SJouni Malinen 					  "errorCode,Failed to set passphrase");
257b4c5e3b8SJouni Malinen 				goto out;
258b4c5e3b8SJouni Malinen 			}
259b4c5e3b8SJouni Malinen 		} else if (strstr(buf, "DPP-CONFOBJ-PSK")) {
260b4c5e3b8SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_INFO,
261b4c5e3b8SJouni Malinen 					"DPP: PSK: %s", pos);
262b4c5e3b8SJouni Malinen 			snprintf(buf2, sizeof(buf2), "SET wpa_psk %s", pos);
263b4c5e3b8SJouni Malinen 			if (wpa_command(ifname, buf2) < 0) {
264b4c5e3b8SJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
265b4c5e3b8SJouni Malinen 					  "errorCode,Failed to set PSK");
266b4c5e3b8SJouni Malinen 				goto out;
267b4c5e3b8SJouni Malinen 			}
268b4c5e3b8SJouni Malinen 		}
269b4c5e3b8SJouni Malinen 
270b4c5e3b8SJouni Malinen 		goto skip_dpp_akm;
271b4c5e3b8SJouni Malinen 	}
272b4c5e3b8SJouni Malinen 
273d86e5828SJouni Malinen 	pos = strchr(buf, ' ');
274d86e5828SJouni Malinen 	if (!pos)
275d86e5828SJouni Malinen 		return -2;
276d86e5828SJouni Malinen 	pos++;
277d86e5828SJouni Malinen 	sigma_dut_print(dut, DUT_MSG_INFO, "DPP: Connector: %s", pos);
278d86e5828SJouni Malinen 	snprintf(buf2, sizeof(buf2), "SET dpp_connector %s", pos);
279d86e5828SJouni Malinen 	if (wpa_command(ifname, buf2) < 0) {
280d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
281d86e5828SJouni Malinen 			  "errorCode,Failed to update AP Connector");
282d86e5828SJouni Malinen 		goto out;
283d86e5828SJouni Malinen 	}
284d86e5828SJouni Malinen 
285d86e5828SJouni Malinen 	res = get_wpa_cli_event(dut, ctrl, "DPP-C-SIGN-KEY",
286d86e5828SJouni Malinen 				buf, sizeof(buf));
287d86e5828SJouni Malinen 	if (res < 0) {
288d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
289d86e5828SJouni Malinen 			  "errorCode,No DPP-C-SIGN-KEY");
290d86e5828SJouni Malinen 		goto out;
291d86e5828SJouni Malinen 	}
292d86e5828SJouni Malinen 	pos = strchr(buf, ' ');
293d86e5828SJouni Malinen 	if (!pos)
294d86e5828SJouni Malinen 		return -2;
295d86e5828SJouni Malinen 	pos++;
296d86e5828SJouni Malinen 	sigma_dut_print(dut, DUT_MSG_INFO, "DPP: C-sign-key: %s", pos);
297d86e5828SJouni Malinen 	snprintf(buf2, sizeof(buf2), "SET dpp_csign %s", pos);
298d86e5828SJouni Malinen 	if (wpa_command(ifname, buf2) < 0) {
299d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
300d86e5828SJouni Malinen 			  "errorCode,Failed to update AP C-sign-key");
301d86e5828SJouni Malinen 		goto out;
302d86e5828SJouni Malinen 	}
303d86e5828SJouni Malinen 
304d86e5828SJouni Malinen 	res = get_wpa_cli_event(dut, ctrl, "DPP-NET-ACCESS-KEY",
305d86e5828SJouni Malinen 				buf, sizeof(buf));
306d86e5828SJouni Malinen 	if (res < 0) {
307d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
308d86e5828SJouni Malinen 			  "errorCode,No DPP-NET-ACCESS-KEY");
309d86e5828SJouni Malinen 		goto out;
310d86e5828SJouni Malinen 	}
311d86e5828SJouni Malinen 	pos = strchr(buf, ' ');
312d86e5828SJouni Malinen 	if (!pos)
313d86e5828SJouni Malinen 		return -2;
314d86e5828SJouni Malinen 	pos++;
315d86e5828SJouni Malinen 	pos2 = strchr(pos, ' ');
316d86e5828SJouni Malinen 	if (pos2)
317d86e5828SJouni Malinen 		*pos2++ = '\0';
318d86e5828SJouni Malinen 	sigma_dut_print(dut, DUT_MSG_INFO, "DPP: netAccessKey: %s", pos);
319d86e5828SJouni Malinen 	snprintf(buf2, sizeof(buf2), "SET dpp_netaccesskey %s", pos);
320d86e5828SJouni Malinen 	if (wpa_command(ifname, buf2) < 0) {
321d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
322d86e5828SJouni Malinen 			  "errorCode,Failed to update AP netAccessKey");
323d86e5828SJouni Malinen 		goto out;
324d86e5828SJouni Malinen 	}
325d86e5828SJouni Malinen 	if (pos2) {
326d86e5828SJouni Malinen 		sigma_dut_print(dut, DUT_MSG_INFO,
327d86e5828SJouni Malinen 				"DPP: netAccessKey expiry: %s", pos2);
328d86e5828SJouni Malinen 		snprintf(buf2, sizeof(buf2), "SET dpp_netaccesskey_expiry %s",
329d86e5828SJouni Malinen 			 pos2);
330d86e5828SJouni Malinen 		if (wpa_command(ifname, buf2) < 0) {
331d86e5828SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
332d86e5828SJouni Malinen 				  "errorCode,Failed to update AP netAccessKey expiry");
333d86e5828SJouni Malinen 			goto out;
334d86e5828SJouni Malinen 		}
335d86e5828SJouni Malinen 	}
336b4c5e3b8SJouni Malinen skip_dpp_akm:
337d86e5828SJouni Malinen 
338d86e5828SJouni Malinen 	if (wpa_command(ifname, "DISABLE") < 0 ||
339d86e5828SJouni Malinen 	    wpa_command(ifname, "ENABLE") < 0) {
340d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
341d86e5828SJouni Malinen 			  "errorCode,Failed to update AP configuration");
342d86e5828SJouni Malinen 		goto out;
343d86e5828SJouni Malinen 	}
344d86e5828SJouni Malinen 
345d86e5828SJouni Malinen 	res = get_wpa_cli_event(dut, ctrl, "AP-ENABLED", buf, sizeof(buf));
346d86e5828SJouni Malinen 	if (res < 0) {
347d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,No AP-ENABLED");
348d86e5828SJouni Malinen 		goto out;
349d86e5828SJouni Malinen 	}
350d86e5828SJouni Malinen 
351d86e5828SJouni Malinen 	return 1;
352d86e5828SJouni Malinen out:
353d86e5828SJouni Malinen 	return 0;
354d86e5828SJouni Malinen }
355d86e5828SJouni Malinen 
356d86e5828SJouni Malinen 
357d86e5828SJouni Malinen static int dpp_manual_dpp(struct sigma_dut *dut,
358d86e5828SJouni Malinen 			  struct sigma_conn *conn,
359d86e5828SJouni Malinen 			  struct sigma_cmd *cmd)
360d86e5828SJouni Malinen {
361d86e5828SJouni Malinen 	/* TODO */
362d86e5828SJouni Malinen 	return -1;
363d86e5828SJouni Malinen }
364d86e5828SJouni Malinen 
365d86e5828SJouni Malinen 
366d86e5828SJouni Malinen static int dpp_automatic_dpp(struct sigma_dut *dut,
367d86e5828SJouni Malinen 			     struct sigma_conn *conn,
368d86e5828SJouni Malinen 			     struct sigma_cmd *cmd)
369d86e5828SJouni Malinen {
370d86e5828SJouni Malinen 	const char *bs = get_param(cmd, "DPPBS");
371d86e5828SJouni Malinen 	const char *auth_role = get_param(cmd, "DPPAuthRole");
372d86e5828SJouni Malinen 	const char *prov_role = get_param(cmd, "DPPProvisioningRole");
373d86e5828SJouni Malinen 	const char *pkex_code = get_param(cmd, "DPPPKEXCode");
374d86e5828SJouni Malinen 	const char *pkex_code_id = get_param(cmd, "DPPPKEXCodeIdentifier");
375d86e5828SJouni Malinen 	const char *wait_conn = get_param(cmd, "DPPWaitForConnect");
376d86e5828SJouni Malinen 	const char *self_conf = get_param(cmd, "DPPSelfConfigure");
377d86e5828SJouni Malinen 	const char *role;
378d86e5828SJouni Malinen 	const char *val;
379d86e5828SJouni Malinen 	const char *conf_role;
380d86e5828SJouni Malinen 	int mutual;
381d86e5828SJouni Malinen 	int conf_index = -1;
382d86e5828SJouni Malinen 	char buf[2000];
383d86e5828SJouni Malinen 	char conf_ssid[100];
384d86e5828SJouni Malinen 	char conf_pass[100];
385d86e5828SJouni Malinen 	char pkex_identifier[200];
386d86e5828SJouni Malinen 	struct wpa_ctrl *ctrl;
387d86e5828SJouni Malinen 	int res;
388d86e5828SJouni Malinen 	unsigned int old_timeout;
389d86e5828SJouni Malinen 	int own_pkex_id = -1;
390d86e5828SJouni Malinen 	const char *ifname = get_station_ifname();
391d86e5828SJouni Malinen 	const char *auth_events[] = {
392d86e5828SJouni Malinen 		"DPP-AUTH-SUCCESS",
393d86e5828SJouni Malinen 		"DPP-NOT-COMPATIBLE",
394d86e5828SJouni Malinen 		"DPP-RESPONSE-PENDING",
395d86e5828SJouni Malinen 		"DPP-SCAN-PEER-QR-CODE",
396d86e5828SJouni Malinen 		NULL
397d86e5828SJouni Malinen 	};
398d86e5828SJouni Malinen 	const char *conf_events[] = {
399d86e5828SJouni Malinen 		"DPP-CONF-RECEIVED",
400d86e5828SJouni Malinen 		"DPP-CONF-SENT",
401d86e5828SJouni Malinen 		"DPP-CONF-FAILED",
402d86e5828SJouni Malinen 		NULL
403d86e5828SJouni Malinen 	};
404d86e5828SJouni Malinen 	const char *conn_events[] = {
405d86e5828SJouni Malinen 		"PMKSA-CACHE-ADDED",
406d86e5828SJouni Malinen 		"CTRL-EVENT-CONNECTED",
407d86e5828SJouni Malinen 		NULL
408d86e5828SJouni Malinen 	};
409d86e5828SJouni Malinen 
410d86e5828SJouni Malinen 	if (!wait_conn)
411d86e5828SJouni Malinen 		wait_conn = "no";
412d86e5828SJouni Malinen 	if (!self_conf)
413d86e5828SJouni Malinen 		self_conf = "no";
414d86e5828SJouni Malinen 
415d86e5828SJouni Malinen 	if (!auth_role) {
416d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
417d86e5828SJouni Malinen 			  "errorCode,Missing DPPAuthRole");
418d86e5828SJouni Malinen 		return 0;
419d86e5828SJouni Malinen 	}
420d86e5828SJouni Malinen 
421d86e5828SJouni Malinen 	if (!prov_role) {
422d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
423d86e5828SJouni Malinen 			  "errorCode,Missing DPPProvisioningRole");
424d86e5828SJouni Malinen 		return 0;
425d86e5828SJouni Malinen 	}
426d86e5828SJouni Malinen 
427d86e5828SJouni Malinen 	val = get_param(cmd, "DPPAuthDirection");
428d86e5828SJouni Malinen 	mutual = val && strcasecmp(val, "Mutual") == 0;
429d86e5828SJouni Malinen 
430d86e5828SJouni Malinen 	if (sigma_dut_is_ap(dut)) {
431d86e5828SJouni Malinen 		if (!dut->hostapd_ifname) {
432d86e5828SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_ERROR,
433d86e5828SJouni Malinen 					"hostapd ifname not specified (-j)");
434d86e5828SJouni Malinen 			return -2;
435d86e5828SJouni Malinen 		}
436d86e5828SJouni Malinen 		ifname = dut->hostapd_ifname;
437d86e5828SJouni Malinen 
438d86e5828SJouni Malinen 		if (dpp_hostapd_run(dut) < 0) {
439d86e5828SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
440d86e5828SJouni Malinen 				  "errorCode,Failed to start hostapd");
441d86e5828SJouni Malinen 			return 0;
442d86e5828SJouni Malinen 		}
443d86e5828SJouni Malinen 	}
444d86e5828SJouni Malinen 
445d86e5828SJouni Malinen 	if (strcasecmp(prov_role, "Configurator") == 0) {
446d86e5828SJouni Malinen 		if (dut->dpp_conf_id < 0) {
447d86e5828SJouni Malinen 			snprintf(buf, sizeof(buf),
448d86e5828SJouni Malinen 				 "DPP_CONFIGURATOR_ADD curve=%s",
449d86e5828SJouni Malinen 				 dpp_get_curve(cmd, "DPPSigningKeyECC"));
450d86e5828SJouni Malinen 			if (wpa_command_resp(ifname, buf,
451d86e5828SJouni Malinen 					     buf, sizeof(buf)) < 0) {
452d86e5828SJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
453d86e5828SJouni Malinen 					  "errorCode,Failed to set up configurator");
454d86e5828SJouni Malinen 				return 0;
455d86e5828SJouni Malinen 			}
456d86e5828SJouni Malinen 			dut->dpp_conf_id = atoi(buf);
457d86e5828SJouni Malinen 		}
458d86e5828SJouni Malinen 		role = "configurator";
459d86e5828SJouni Malinen 	} else if (strcasecmp(prov_role, "Enrollee") == 0) {
460d86e5828SJouni Malinen 		role = "enrollee";
461d86e5828SJouni Malinen 	} else {
462d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
463d86e5828SJouni Malinen 			  "errorCode,Unknown DPPProvisioningRole");
464d86e5828SJouni Malinen 		return 0;
465d86e5828SJouni Malinen 	}
466d86e5828SJouni Malinen 
467d86e5828SJouni Malinen 	pkex_identifier[0] = '\0';
468d86e5828SJouni Malinen 	if (strcasecmp(bs, "PKEX") == 0) {
469d86e5828SJouni Malinen 		if (!pkex_code) {
470d86e5828SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
471d86e5828SJouni Malinen 				  "errorCode,Missing DPPPKEXCode");
472d86e5828SJouni Malinen 			return 0;
473d86e5828SJouni Malinen 		}
474d86e5828SJouni Malinen 
475d86e5828SJouni Malinen 		if (pkex_code_id)
476d86e5828SJouni Malinen 			snprintf(pkex_identifier, sizeof(pkex_identifier),
477d86e5828SJouni Malinen 				 "identifier=%s ", pkex_code_id);
478d86e5828SJouni Malinen 
479d86e5828SJouni Malinen 		snprintf(buf, sizeof(buf),
480d86e5828SJouni Malinen 			 "DPP_BOOTSTRAP_GEN type=pkex curve=%s",
481d86e5828SJouni Malinen 			 dpp_get_curve(cmd, "DPPCryptoIdentifier"));
482d86e5828SJouni Malinen 		if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0) {
483d86e5828SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
484d86e5828SJouni Malinen 				  "errorCode,Failed to set up PKEX");
485d86e5828SJouni Malinen 			return 0;
486d86e5828SJouni Malinen 		}
487d86e5828SJouni Malinen 		own_pkex_id = atoi(buf);
488d86e5828SJouni Malinen 	}
489d86e5828SJouni Malinen 
490d86e5828SJouni Malinen 	ctrl = open_wpa_mon(ifname);
491d86e5828SJouni Malinen 	if (!ctrl) {
492d86e5828SJouni Malinen 		sigma_dut_print(dut, DUT_MSG_ERROR,
493d86e5828SJouni Malinen 				"Failed to open wpa_supplicant monitor connection");
494d86e5828SJouni Malinen 		return -2;
495d86e5828SJouni Malinen 	}
496d86e5828SJouni Malinen 
497d86e5828SJouni Malinen 	old_timeout = dut->default_timeout;
498d86e5828SJouni Malinen 	val = get_param(cmd, "DPPTimeout");
499d86e5828SJouni Malinen 	if (val && atoi(val) > 0) {
500d86e5828SJouni Malinen 		dut->default_timeout = atoi(val);
501d86e5828SJouni Malinen 		sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP timeout: %u",
502d86e5828SJouni Malinen 				dut->default_timeout);
503d86e5828SJouni Malinen 	}
504d86e5828SJouni Malinen 
505d86e5828SJouni Malinen 	conf_ssid[0] = '\0';
506d86e5828SJouni Malinen 	conf_pass[0] = '\0';
507d86e5828SJouni Malinen 	val = get_param(cmd, "DPPConfIndex");
508d86e5828SJouni Malinen 	if (val)
509d86e5828SJouni Malinen 		conf_index = atoi(val);
510d86e5828SJouni Malinen 	val = get_param(cmd, "DPPConfEnrolleeRole");
511d86e5828SJouni Malinen 	switch (conf_index) {
512d86e5828SJouni Malinen 	case 1:
513d86e5828SJouni Malinen 		ascii2hexstr("DPPNET01", buf);
514d86e5828SJouni Malinen 		snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
515d86e5828SJouni Malinen 		if (val && strcasecmp(val, "AP") == 0)
516d86e5828SJouni Malinen 			conf_role = "ap-dpp";
517d86e5828SJouni Malinen 		else
518d86e5828SJouni Malinen 			conf_role = "sta-dpp";
519d86e5828SJouni Malinen 		break;
520d86e5828SJouni Malinen 	case 2:
521d86e5828SJouni Malinen 		ascii2hexstr("DPPNET01", buf);
522d86e5828SJouni Malinen 		snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
5238f81cdfaSJouni Malinen 		snprintf(conf_pass, sizeof(conf_pass),
5248f81cdfaSJouni Malinen 			 "psk=10506e102ad1e7f95112f6b127675bb8344dacacea60403f3fa4055aec85b0fc");
525d86e5828SJouni Malinen 		if (val && strcasecmp(val, "AP") == 0)
526d86e5828SJouni Malinen 			conf_role = "ap-psk";
527d86e5828SJouni Malinen 		else
528d86e5828SJouni Malinen 			conf_role = "sta-psk";
529d86e5828SJouni Malinen 		break;
530d86e5828SJouni Malinen 	case 3:
531d86e5828SJouni Malinen 		ascii2hexstr("DPPNET01", buf);
532d86e5828SJouni Malinen 		snprintf(conf_ssid, sizeof(conf_ssid), "ssid=%s", buf);
533d86e5828SJouni Malinen 		ascii2hexstr("ThisIsDppPassphrase", buf);
534d86e5828SJouni Malinen 		snprintf(conf_pass, sizeof(conf_pass), "pass=%s", buf);
535d86e5828SJouni Malinen 		if (val && strcasecmp(val, "AP") == 0)
536d86e5828SJouni Malinen 			conf_role = "ap-psk";
537d86e5828SJouni Malinen 		else
538d86e5828SJouni Malinen 			conf_role = "sta-psk";
539d86e5828SJouni Malinen 		break;
540*f7490768SJouni Malinen 	default:
541*f7490768SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
542*f7490768SJouni Malinen 			  "errorCode,Unsupported DPPConfIndex");
543*f7490768SJouni Malinen 		goto out;
544d86e5828SJouni Malinen 	}
545d86e5828SJouni Malinen 
546d86e5828SJouni Malinen 	if (strcasecmp(auth_role, "Initiator") == 0) {
547d86e5828SJouni Malinen 		char own_txt[20];
548d86e5828SJouni Malinen 
549d86e5828SJouni Malinen 		if (mutual)
550d86e5828SJouni Malinen 			snprintf(own_txt, sizeof(own_txt), " own=%d",
551d86e5828SJouni Malinen 				 dut->dpp_local_bootstrap);
552d86e5828SJouni Malinen 		else
553d86e5828SJouni Malinen 			own_txt[0] = '\0';
554d86e5828SJouni Malinen 		if (strcasecmp(bs, "QR") == 0 &&
555d86e5828SJouni Malinen 		    strcasecmp(prov_role, "Configurator") == 0) {
556d86e5828SJouni Malinen 			snprintf(buf, sizeof(buf),
557d86e5828SJouni Malinen 				 "DPP_AUTH_INIT peer=%d%s role=%s conf=%s %s %s configurator=%d",
558d86e5828SJouni Malinen 				 dut->dpp_peer_bootstrap, own_txt, role,
559d86e5828SJouni Malinen 				 conf_role, conf_ssid, conf_pass,
560d86e5828SJouni Malinen 				 dut->dpp_conf_id);
561d86e5828SJouni Malinen 		} else if (strcasecmp(bs, "QR") == 0) {
562d86e5828SJouni Malinen 			snprintf(buf, sizeof(buf),
563d86e5828SJouni Malinen 				 "DPP_AUTH_INIT peer=%d%s role=%s",
564d86e5828SJouni Malinen 				 dut->dpp_peer_bootstrap, own_txt, role);
565d86e5828SJouni Malinen 		} else if (strcasecmp(bs, "PKEX") == 0 &&
566d86e5828SJouni Malinen 			   strcasecmp(prov_role, "Configurator") == 0) {
567d86e5828SJouni Malinen 			snprintf(buf, sizeof(buf),
568d86e5828SJouni Malinen 				 "DPP_PKEX_ADD own=%d init=1 role=%s conf=%s %s %s configurator=%d %scode=%s",
569d86e5828SJouni Malinen 				 own_pkex_id, role, conf_role,
570d86e5828SJouni Malinen 				 conf_ssid, conf_pass, dut->dpp_conf_id,
571d86e5828SJouni Malinen 				 pkex_identifier, pkex_code);
572d86e5828SJouni Malinen 		} else if (strcasecmp(bs, "PKEX") == 0) {
573d86e5828SJouni Malinen 			snprintf(buf, sizeof(buf),
574d86e5828SJouni Malinen 				 "DPP_PKEX_ADD own=%d init=1 role=%s %scode=%s",
575d86e5828SJouni Malinen 				 own_pkex_id, role, pkex_identifier, pkex_code);
576d551c6fcSJouni Malinen 		} else {
577d551c6fcSJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
578d551c6fcSJouni Malinen 				  "errorCode,Unsupported DPPBS");
579d551c6fcSJouni Malinen 			goto out;
580d86e5828SJouni Malinen 		}
581d86e5828SJouni Malinen 		if (wpa_command(ifname, buf) < 0) {
582d86e5828SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
583d86e5828SJouni Malinen 				  "errorCode,Failed to initiate DPP authentication");
584d86e5828SJouni Malinen 			goto out;
585d86e5828SJouni Malinen 		}
586d86e5828SJouni Malinen 	} else if (strcasecmp(auth_role, "Responder") == 0) {
587d86e5828SJouni Malinen 		int freq = 2462;
588d86e5828SJouni Malinen 
589d86e5828SJouni Malinen 		if (strcasecmp(prov_role, "Configurator") == 0) {
590d86e5828SJouni Malinen 			snprintf(buf, sizeof(buf),
591d86e5828SJouni Malinen 				 "SET dpp_configurator_params  conf=%s %s %s configurator=%d",
592d86e5828SJouni Malinen 				 conf_role, conf_ssid, conf_pass,
593d86e5828SJouni Malinen 				 dut->dpp_conf_id);
594d86e5828SJouni Malinen 			if (wpa_command(ifname, buf) < 0) {
595d86e5828SJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
596d86e5828SJouni Malinen 					  "errorCode,Failed to set configurator parameters");
597d86e5828SJouni Malinen 				goto out;
598d86e5828SJouni Malinen 			}
599d86e5828SJouni Malinen 		}
600d86e5828SJouni Malinen 		if (strcasecmp(bs, "PKEX") == 0) {
601d86e5828SJouni Malinen 			freq = 2437;
602d86e5828SJouni Malinen 
603d86e5828SJouni Malinen 			snprintf(buf, sizeof(buf),
604d86e5828SJouni Malinen 				 "DPP_PKEX_ADD own=%d role=%s %scode=%s",
605d86e5828SJouni Malinen 				 own_pkex_id, role, pkex_identifier, pkex_code);
606d86e5828SJouni Malinen 			if (wpa_command(ifname, buf) < 0) {
607d86e5828SJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
608d86e5828SJouni Malinen 					  "errorCode,Failed to configure DPP PKEX");
609d86e5828SJouni Malinen 				goto out;
610d86e5828SJouni Malinen 			}
611d86e5828SJouni Malinen 		}
612d86e5828SJouni Malinen 
613d86e5828SJouni Malinen 		if (!sigma_dut_is_ap(dut)) {
614d86e5828SJouni Malinen 			snprintf(buf, sizeof(buf), "DPP_LISTEN %d role=%s",
615d86e5828SJouni Malinen 				 freq, role);
616d86e5828SJouni Malinen 			if (wpa_command(ifname, buf) < 0) {
617d86e5828SJouni Malinen 				send_resp(dut, conn, SIGMA_ERROR,
618d86e5828SJouni Malinen 					  "errorCode,Failed to start DPP listen");
619d86e5828SJouni Malinen 				goto out;
620d86e5828SJouni Malinen 			}
621d86e5828SJouni Malinen 		}
622d86e5828SJouni Malinen 	} else {
623d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
624d86e5828SJouni Malinen 			  "errorCode,Unknown DPPAuthRole");
625d86e5828SJouni Malinen 		goto out;
626d86e5828SJouni Malinen 	}
627d86e5828SJouni Malinen 
628d86e5828SJouni Malinen 	res = get_wpa_cli_events(dut, ctrl, auth_events, buf, sizeof(buf));
629d86e5828SJouni Malinen 	if (res < 0) {
630d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE,
631d86e5828SJouni Malinen 			  "BootstrapResult,OK,AuthResult,Timeout");
632d86e5828SJouni Malinen 		goto out;
633d86e5828SJouni Malinen 	}
634d86e5828SJouni Malinen 	sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP auth result: %s", buf);
635d86e5828SJouni Malinen 
636d86e5828SJouni Malinen 	if (strstr(buf, "DPP-NOT-COMPATIBLE")) {
637d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE,
638d86e5828SJouni Malinen 			  "BootstrapResult,OK,AuthResult,ROLES_NOT_COMPATIBLE");
639d86e5828SJouni Malinen 		goto out;
640d86e5828SJouni Malinen 	}
641d86e5828SJouni Malinen 
642d86e5828SJouni Malinen 	if (!strstr(buf, "DPP-AUTH-SUCCESS")) {
643d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE,
644d86e5828SJouni Malinen 			  "BootstrapResult,OK,AuthResult,FAILED");
645d86e5828SJouni Malinen 		goto out;
646d86e5828SJouni Malinen 	}
647d86e5828SJouni Malinen 
648d86e5828SJouni Malinen 	res = get_wpa_cli_events(dut, ctrl, conf_events, buf, sizeof(buf));
649d86e5828SJouni Malinen 	if (res < 0) {
650d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE,
651d86e5828SJouni Malinen 			  "BootstrapResult,OK,AuthResult,OK,ConfResult,Timeout");
652d86e5828SJouni Malinen 		goto out;
653d86e5828SJouni Malinen 	}
654d86e5828SJouni Malinen 	sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP conf result: %s", buf);
655d86e5828SJouni Malinen 
656d86e5828SJouni Malinen 	if (!strstr(buf, "DPP-CONF-SENT") &&
657d86e5828SJouni Malinen 	    !strstr(buf, "DPP-CONF-RECEIVED")) {
658d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE,
659d86e5828SJouni Malinen 			  "BootstrapResult,OK,AuthResult,OK,ConfResult,FAILED");
660d86e5828SJouni Malinen 		goto out;
661d86e5828SJouni Malinen 	}
662d86e5828SJouni Malinen 
663d86e5828SJouni Malinen 	if (sigma_dut_is_ap(dut) &&
664d86e5828SJouni Malinen 	    strcasecmp(prov_role, "Enrollee") == 0) {
665d86e5828SJouni Malinen 		res = dpp_hostapd_conf_update(dut, conn, ifname, ctrl);
666d86e5828SJouni Malinen 		if (res == 0)
667d86e5828SJouni Malinen 			goto out;
668d86e5828SJouni Malinen 		if (res < 0) {
669d86e5828SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR, NULL);
670d86e5828SJouni Malinen 			goto out;
671d86e5828SJouni Malinen 		}
672d86e5828SJouni Malinen 	}
673d86e5828SJouni Malinen 
674d86e5828SJouni Malinen 	if (strcasecmp(wait_conn, "Yes") == 0 &&
675d86e5828SJouni Malinen 	    !sigma_dut_is_ap(dut) &&
676d86e5828SJouni Malinen 	    strcasecmp(prov_role, "Enrollee") == 0) {
677d86e5828SJouni Malinen 		res = get_wpa_cli_events(dut, ctrl, conn_events,
678d86e5828SJouni Malinen 					 buf, sizeof(buf));
679d86e5828SJouni Malinen 		if (res < 0) {
680d86e5828SJouni Malinen 			send_resp(dut, conn, SIGMA_COMPLETE,
681d86e5828SJouni Malinen 				  "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,Timeout,NetworkConnectResult,Timeout");
682d86e5828SJouni Malinen 			goto out;
683d86e5828SJouni Malinen 		}
684d86e5828SJouni Malinen 		sigma_dut_print(dut, DUT_MSG_DEBUG, "DPP connect result: %s",
685d86e5828SJouni Malinen 				buf);
686d86e5828SJouni Malinen 
687d86e5828SJouni Malinen 		if (strstr(buf, "PMKSA-CACHE-ADDED")) {
688d86e5828SJouni Malinen 			res = get_wpa_cli_events(dut, ctrl, conn_events,
689d86e5828SJouni Malinen 						 buf, sizeof(buf));
690d86e5828SJouni Malinen 			if (res < 0) {
691d86e5828SJouni Malinen 				send_resp(dut, conn, SIGMA_COMPLETE,
692d86e5828SJouni Malinen 					  "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,Timeout");
693d86e5828SJouni Malinen 				goto out;
694d86e5828SJouni Malinen 			}
695d86e5828SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_DEBUG,
696d86e5828SJouni Malinen 					"DPP connect result: %s", buf);
697d86e5828SJouni Malinen 			if (strstr(buf, "CTRL-EVENT-CONNECTED"))
698d86e5828SJouni Malinen 				send_resp(dut, conn, SIGMA_COMPLETE,
699d86e5828SJouni Malinen 					  "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,OK");
700d86e5828SJouni Malinen 			else
701d86e5828SJouni Malinen 				send_resp(dut, conn, SIGMA_COMPLETE,
702d86e5828SJouni Malinen 					  "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkIntroResult,OK,NetworkConnectResult,Timeout");
703d86e5828SJouni Malinen 			goto out;
704d86e5828SJouni Malinen 		}
705d86e5828SJouni Malinen 
706d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_COMPLETE,
707d86e5828SJouni Malinen 			  "BootstrapResult,OK,AuthResult,OK,ConfResult,OK,NetworkConnectResult,OK");
708d86e5828SJouni Malinen 		goto out;
709d86e5828SJouni Malinen 	}
710d86e5828SJouni Malinen 
711d86e5828SJouni Malinen 	send_resp(dut, conn, SIGMA_COMPLETE,
712d86e5828SJouni Malinen 		  "BootstrapResult,OK,AuthResult,OK,ConfResult,OK");
713d86e5828SJouni Malinen out:
714d86e5828SJouni Malinen 	wpa_ctrl_detach(ctrl);
715d86e5828SJouni Malinen 	wpa_ctrl_close(ctrl);
716d86e5828SJouni Malinen 	dut->default_timeout = old_timeout;
717d86e5828SJouni Malinen 	return 0;
718d86e5828SJouni Malinen }
719d86e5828SJouni Malinen 
720d86e5828SJouni Malinen 
721d86e5828SJouni Malinen int dpp_dev_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
722d86e5828SJouni Malinen 			struct sigma_cmd *cmd)
723d86e5828SJouni Malinen {
724d86e5828SJouni Malinen 	const char *type = get_param(cmd, "DPPActionType");
725d86e5828SJouni Malinen 	const char *bs = get_param(cmd, "DPPBS");
726d86e5828SJouni Malinen 
727d86e5828SJouni Malinen 	if (!bs) {
728d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
729d86e5828SJouni Malinen 			  "errorCode,Missing DPPBS");
730d86e5828SJouni Malinen 		return 0;
731d86e5828SJouni Malinen 	}
732d86e5828SJouni Malinen 
733d86e5828SJouni Malinen 	if (!type) {
734d86e5828SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
735d86e5828SJouni Malinen 			  "errorCode,Missing DPPActionType");
736d86e5828SJouni Malinen 		return 0;
737d86e5828SJouni Malinen 	}
738d86e5828SJouni Malinen 
739d86e5828SJouni Malinen 	if (strcasecmp(type, "GetLocalBootstrap") == 0)
740d86e5828SJouni Malinen 		return dpp_get_local_bootstrap(dut, conn, cmd);
741d86e5828SJouni Malinen 	if (strcasecmp(type, "SetPeerBootstrap") == 0)
742d86e5828SJouni Malinen 		return dpp_set_peer_bootstrap(dut, conn, cmd);
743d86e5828SJouni Malinen 	if (strcasecmp(type, "ManualDPP") == 0)
744d86e5828SJouni Malinen 		return dpp_manual_dpp(dut, conn, cmd);
745d86e5828SJouni Malinen 	if (strcasecmp(type, "AutomaticDPP") == 0)
746d86e5828SJouni Malinen 		return dpp_automatic_dpp(dut, conn, cmd);
747d86e5828SJouni Malinen 
748d86e5828SJouni Malinen 	send_resp(dut, conn, SIGMA_ERROR,
749d86e5828SJouni Malinen 		  "errorCode,Unsupported DPPActionType");
750d86e5828SJouni Malinen 	return 0;
751d86e5828SJouni Malinen }
752