dpp_supplicant.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311
  1. /*
  2. * wpa_supplicant - DPP
  3. * Copyright (c) 2017, Qualcomm Atheros, Inc.
  4. *
  5. * This software may be distributed under the terms of the BSD license.
  6. * See README for more details.
  7. */
  8. #include "utils/includes.h"
  9. #include "utils/common.h"
  10. #include "utils/eloop.h"
  11. #include "common/dpp.h"
  12. #include "common/gas.h"
  13. #include "common/gas_server.h"
  14. #include "wpa_supplicant_i.h"
  15. #include "driver_i.h"
  16. #include "offchannel.h"
  17. #include "gas_query.h"
  18. #include "dpp_supplicant.h"
  19. static int wpas_dpp_listen_start(struct wpa_supplicant *wpa_s,
  20. unsigned int freq);
  21. static void wpas_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx);
  22. static void wpas_dpp_auth_success(struct wpa_supplicant *wpa_s, int initiator);
  23. static void wpas_dpp_tx_status(struct wpa_supplicant *wpa_s,
  24. unsigned int freq, const u8 *dst,
  25. const u8 *src, const u8 *bssid,
  26. const u8 *data, size_t data_len,
  27. enum offchannel_send_action_result result);
  28. static const u8 broadcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  29. static struct dpp_configurator *
  30. dpp_configurator_get_id(struct wpa_supplicant *wpa_s, unsigned int id)
  31. {
  32. struct dpp_configurator *conf;
  33. dl_list_for_each(conf, &wpa_s->dpp_configurator,
  34. struct dpp_configurator, list) {
  35. if (conf->id == id)
  36. return conf;
  37. }
  38. return NULL;
  39. }
  40. static unsigned int wpas_dpp_next_id(struct wpa_supplicant *wpa_s)
  41. {
  42. struct dpp_bootstrap_info *bi;
  43. unsigned int max_id = 0;
  44. dl_list_for_each(bi, &wpa_s->dpp_bootstrap, struct dpp_bootstrap_info,
  45. list) {
  46. if (bi->id > max_id)
  47. max_id = bi->id;
  48. }
  49. return max_id + 1;
  50. }
  51. /**
  52. * wpas_dpp_qr_code - Parse and add DPP bootstrapping info from a QR Code
  53. * @wpa_s: Pointer to wpa_supplicant data
  54. * @cmd: DPP URI read from a QR Code
  55. * Returns: Identifier of the stored info or -1 on failure
  56. */
  57. int wpas_dpp_qr_code(struct wpa_supplicant *wpa_s, const char *cmd)
  58. {
  59. struct dpp_bootstrap_info *bi;
  60. struct dpp_authentication *auth = wpa_s->dpp_auth;
  61. bi = dpp_parse_qr_code(cmd);
  62. if (!bi)
  63. return -1;
  64. bi->id = wpas_dpp_next_id(wpa_s);
  65. dl_list_add(&wpa_s->dpp_bootstrap, &bi->list);
  66. if (auth && auth->response_pending &&
  67. dpp_notify_new_qr_code(auth, bi) == 1) {
  68. struct wpabuf *msg;
  69. wpa_printf(MSG_DEBUG,
  70. "DPP: Sending out pending authentication response");
  71. msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_RESP,
  72. wpabuf_len(auth->resp_attr));
  73. if (!msg)
  74. goto out;
  75. wpabuf_put_buf(msg, wpa_s->dpp_auth->resp_attr);
  76. offchannel_send_action(wpa_s, auth->curr_freq,
  77. auth->peer_mac_addr, wpa_s->own_addr,
  78. broadcast,
  79. wpabuf_head(msg), wpabuf_len(msg),
  80. 500, wpas_dpp_tx_status, 0);
  81. wpabuf_free(msg);
  82. }
  83. out:
  84. return bi->id;
  85. }
  86. static char * get_param(const char *cmd, const char *param)
  87. {
  88. const char *pos, *end;
  89. char *val;
  90. size_t len;
  91. pos = os_strstr(cmd, param);
  92. if (!pos)
  93. return NULL;
  94. pos += os_strlen(param);
  95. end = os_strchr(pos, ' ');
  96. if (end)
  97. len = end - pos;
  98. else
  99. len = os_strlen(pos);
  100. val = os_malloc(len + 1);
  101. if (!val)
  102. return NULL;
  103. os_memcpy(val, pos, len);
  104. val[len] = '\0';
  105. return val;
  106. }
  107. int wpas_dpp_bootstrap_gen(struct wpa_supplicant *wpa_s, const char *cmd)
  108. {
  109. char *chan = NULL, *mac = NULL, *info = NULL, *pk = NULL, *curve = NULL;
  110. char *key = NULL;
  111. u8 *privkey = NULL;
  112. size_t privkey_len = 0;
  113. size_t len;
  114. int ret = -1;
  115. struct dpp_bootstrap_info *bi;
  116. bi = os_zalloc(sizeof(*bi));
  117. if (!bi)
  118. goto fail;
  119. if (os_strstr(cmd, "type=qrcode"))
  120. bi->type = DPP_BOOTSTRAP_QR_CODE;
  121. else
  122. goto fail;
  123. chan = get_param(cmd, " chan=");
  124. mac = get_param(cmd, " mac=");
  125. info = get_param(cmd, " info=");
  126. curve = get_param(cmd, " curve=");
  127. key = get_param(cmd, " key=");
  128. if (key) {
  129. privkey_len = os_strlen(key) / 2;
  130. privkey = os_malloc(privkey_len);
  131. if (!privkey ||
  132. hexstr2bin(key, privkey, privkey_len) < 0)
  133. goto fail;
  134. }
  135. pk = dpp_keygen(bi, curve, privkey, privkey_len);
  136. if (!pk)
  137. goto fail;
  138. len = 4; /* "DPP:" */
  139. if (chan) {
  140. if (dpp_parse_uri_chan_list(bi, chan) < 0)
  141. goto fail;
  142. len += 3 + os_strlen(chan); /* C:...; */
  143. }
  144. if (mac) {
  145. if (dpp_parse_uri_mac(bi, mac) < 0)
  146. goto fail;
  147. len += 3 + os_strlen(mac); /* M:...; */
  148. }
  149. if (info) {
  150. if (dpp_parse_uri_info(bi, info) < 0)
  151. goto fail;
  152. len += 3 + os_strlen(info); /* I:...; */
  153. }
  154. len += 4 + os_strlen(pk);
  155. bi->uri = os_malloc(len + 1);
  156. if (!bi->uri)
  157. goto fail;
  158. os_snprintf(bi->uri, len + 1, "DPP:%s%s%s%s%s%s%s%s%sK:%s;;",
  159. chan ? "C:" : "", chan ? chan : "", chan ? ";" : "",
  160. mac ? "M:" : "", mac ? mac : "", mac ? ";" : "",
  161. info ? "I:" : "", info ? info : "", info ? ";" : "",
  162. pk);
  163. bi->id = wpas_dpp_next_id(wpa_s);
  164. dl_list_add(&wpa_s->dpp_bootstrap, &bi->list);
  165. ret = bi->id;
  166. bi = NULL;
  167. fail:
  168. os_free(curve);
  169. os_free(pk);
  170. os_free(chan);
  171. os_free(mac);
  172. os_free(info);
  173. str_clear_free(key);
  174. bin_clear_free(privkey, privkey_len);
  175. dpp_bootstrap_info_free(bi);
  176. return ret;
  177. }
  178. static struct dpp_bootstrap_info *
  179. dpp_bootstrap_get_id(struct wpa_supplicant *wpa_s, unsigned int id)
  180. {
  181. struct dpp_bootstrap_info *bi;
  182. dl_list_for_each(bi, &wpa_s->dpp_bootstrap, struct dpp_bootstrap_info,
  183. list) {
  184. if (bi->id == id)
  185. return bi;
  186. }
  187. return NULL;
  188. }
  189. static int dpp_bootstrap_del(struct wpa_supplicant *wpa_s, unsigned int id)
  190. {
  191. struct dpp_bootstrap_info *bi, *tmp;
  192. int found = 0;
  193. dl_list_for_each_safe(bi, tmp, &wpa_s->dpp_bootstrap,
  194. struct dpp_bootstrap_info, list) {
  195. if (id && bi->id != id)
  196. continue;
  197. found = 1;
  198. dl_list_del(&bi->list);
  199. dpp_bootstrap_info_free(bi);
  200. }
  201. if (id == 0)
  202. return 0; /* flush succeeds regardless of entries found */
  203. return found ? 0 : -1;
  204. }
  205. int wpas_dpp_bootstrap_remove(struct wpa_supplicant *wpa_s, const char *id)
  206. {
  207. unsigned int id_val;
  208. if (os_strcmp(id, "*") == 0) {
  209. id_val = 0;
  210. } else {
  211. id_val = atoi(id);
  212. if (id_val == 0)
  213. return -1;
  214. }
  215. return dpp_bootstrap_del(wpa_s, id_val);
  216. }
  217. const char * wpas_dpp_bootstrap_get_uri(struct wpa_supplicant *wpa_s,
  218. unsigned int id)
  219. {
  220. struct dpp_bootstrap_info *bi;
  221. bi = dpp_bootstrap_get_id(wpa_s, id);
  222. if (!bi)
  223. return NULL;
  224. return bi->uri;
  225. }
  226. static void wpas_dpp_tx_status(struct wpa_supplicant *wpa_s,
  227. unsigned int freq, const u8 *dst,
  228. const u8 *src, const u8 *bssid,
  229. const u8 *data, size_t data_len,
  230. enum offchannel_send_action_result result)
  231. {
  232. wpa_printf(MSG_DEBUG, "DPP: TX status: freq=%u dst=" MACSTR
  233. " result=%s",
  234. freq, MAC2STR(dst),
  235. result == OFFCHANNEL_SEND_ACTION_SUCCESS ? "SUCCESS" :
  236. (result == OFFCHANNEL_SEND_ACTION_NO_ACK ? "no-ACK" :
  237. "FAILED"));
  238. if (!wpa_s->dpp_auth) {
  239. wpa_printf(MSG_DEBUG,
  240. "DPP: Ignore TX status since there is no ongoing authentication exchange");
  241. return;
  242. }
  243. if (wpa_s->dpp_auth->remove_on_tx_status) {
  244. wpa_printf(MSG_DEBUG,
  245. "DPP: Terminate authentication exchange due to an earlier error");
  246. eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
  247. offchannel_send_action_done(wpa_s);
  248. dpp_auth_deinit(wpa_s->dpp_auth);
  249. wpa_s->dpp_auth = NULL;
  250. return;
  251. }
  252. if (wpa_s->dpp_auth_ok_on_ack)
  253. wpas_dpp_auth_success(wpa_s, 1);
  254. if (!is_broadcast_ether_addr(dst) &&
  255. result != OFFCHANNEL_SEND_ACTION_SUCCESS) {
  256. wpa_printf(MSG_DEBUG,
  257. "DPP: Unicast DPP Action frame was not ACKed");
  258. /* TODO: In case of DPP Authentication Request frame, move to
  259. * the next channel immediately */
  260. }
  261. }
  262. static void wpas_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx)
  263. {
  264. struct wpa_supplicant *wpa_s = eloop_ctx;
  265. if (!wpa_s->dpp_auth)
  266. return;
  267. wpa_printf(MSG_DEBUG, "DPP: Continue reply wait on channel %u MHz",
  268. wpa_s->dpp_auth->curr_freq);
  269. wpas_dpp_listen_start(wpa_s, wpa_s->dpp_auth->curr_freq);
  270. }
  271. static void wpas_dpp_set_testing_options(struct wpa_supplicant *wpa_s,
  272. struct dpp_authentication *auth)
  273. {
  274. #ifdef CONFIG_TESTING_OPTIONS
  275. if (wpa_s->dpp_config_obj_override)
  276. auth->config_obj_override =
  277. os_strdup(wpa_s->dpp_config_obj_override);
  278. if (wpa_s->dpp_discovery_override)
  279. auth->discovery_override =
  280. os_strdup(wpa_s->dpp_discovery_override);
  281. if (wpa_s->dpp_groups_override)
  282. auth->groups_override =
  283. os_strdup(wpa_s->dpp_groups_override);
  284. if (wpa_s->dpp_devices_override)
  285. auth->devices_override =
  286. os_strdup(wpa_s->dpp_devices_override);
  287. auth->ignore_netaccesskey_mismatch =
  288. wpa_s->dpp_ignore_netaccesskey_mismatch;
  289. #endif /* CONFIG_TESTING_OPTIONS */
  290. }
  291. int wpas_dpp_auth_init(struct wpa_supplicant *wpa_s, const char *cmd)
  292. {
  293. const char *pos;
  294. struct dpp_bootstrap_info *peer_bi, *own_bi = NULL;
  295. struct wpabuf *msg;
  296. const u8 *dst;
  297. int res;
  298. int configurator = 1;
  299. unsigned int wait_time;
  300. struct dpp_configuration *conf_sta = NULL, *conf_ap = NULL;
  301. struct dpp_configurator *conf = NULL;
  302. wpa_s->dpp_gas_client = 0;
  303. pos = os_strstr(cmd, " peer=");
  304. if (!pos)
  305. return -1;
  306. pos += 6;
  307. peer_bi = dpp_bootstrap_get_id(wpa_s, atoi(pos));
  308. if (!peer_bi) {
  309. wpa_printf(MSG_INFO,
  310. "DPP: Could not find bootstrapping info for the identified peer");
  311. return -1;
  312. }
  313. pos = os_strstr(cmd, " own=");
  314. if (pos) {
  315. pos += 5;
  316. own_bi = dpp_bootstrap_get_id(wpa_s, atoi(pos));
  317. if (!own_bi) {
  318. wpa_printf(MSG_INFO,
  319. "DPP: Could not find bootstrapping info for the identified local entry");
  320. return -1;
  321. }
  322. if (peer_bi->curve != own_bi->curve) {
  323. wpa_printf(MSG_INFO,
  324. "DPP: Mismatching curves in bootstrapping info (peer=%s own=%s)",
  325. peer_bi->curve->name, own_bi->curve->name);
  326. return -1;
  327. }
  328. }
  329. pos = os_strstr(cmd, " role=");
  330. if (pos) {
  331. pos += 6;
  332. if (os_strncmp(pos, "configurator", 12) == 0)
  333. configurator = 1;
  334. else if (os_strncmp(pos, "enrollee", 8) == 0)
  335. configurator = 0;
  336. else
  337. goto fail;
  338. }
  339. pos = os_strstr(cmd, " netrole=");
  340. if (pos) {
  341. pos += 9;
  342. wpa_s->dpp_netrole_ap = os_strncmp(pos, "ap", 2) == 0;
  343. }
  344. if (os_strstr(cmd, " conf=sta-")) {
  345. conf_sta = os_zalloc(sizeof(struct dpp_configuration));
  346. if (!conf_sta)
  347. goto fail;
  348. /* TODO: Configuration of network parameters from upper layers
  349. */
  350. os_memcpy(conf_sta->ssid, "test", 4);
  351. conf_sta->ssid_len = 4;
  352. if (os_strstr(cmd, " conf=sta-psk")) {
  353. conf_sta->dpp = 0;
  354. conf_sta->passphrase = os_strdup("secret passphrase");
  355. if (!conf_sta->passphrase)
  356. goto fail;
  357. } else if (os_strstr(cmd, " conf=sta-dpp")) {
  358. conf_sta->dpp = 1;
  359. } else {
  360. goto fail;
  361. }
  362. }
  363. if (os_strstr(cmd, " conf=ap-")) {
  364. conf_ap = os_zalloc(sizeof(struct dpp_configuration));
  365. if (!conf_ap)
  366. goto fail;
  367. /* TODO: Configuration of network parameters from upper layers
  368. */
  369. os_memcpy(conf_ap->ssid, "test", 4);
  370. conf_ap->ssid_len = 4;
  371. if (os_strstr(cmd, " conf=ap-psk")) {
  372. conf_ap->dpp = 0;
  373. conf_ap->passphrase = os_strdup("secret passphrase");
  374. if (!conf_ap->passphrase)
  375. goto fail;
  376. } else if (os_strstr(cmd, " conf=ap-dpp")) {
  377. conf_ap->dpp = 1;
  378. } else {
  379. goto fail;
  380. }
  381. }
  382. pos = os_strstr(cmd, " expiry=");
  383. if (pos) {
  384. long int val;
  385. pos += 8;
  386. val = strtol(pos, NULL, 0);
  387. if (val <= 0)
  388. goto fail;
  389. if (conf_sta)
  390. conf_sta->netaccesskey_expiry = val;
  391. if (conf_ap)
  392. conf_ap->netaccesskey_expiry = val;
  393. }
  394. pos = os_strstr(cmd, " configurator=");
  395. if (pos) {
  396. pos += 14;
  397. conf = dpp_configurator_get_id(wpa_s, atoi(pos));
  398. if (!conf) {
  399. wpa_printf(MSG_INFO,
  400. "DPP: Could not find the specified configurator");
  401. goto fail;
  402. }
  403. }
  404. if (wpa_s->dpp_auth) {
  405. eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
  406. offchannel_send_action_done(wpa_s);
  407. dpp_auth_deinit(wpa_s->dpp_auth);
  408. }
  409. wpa_s->dpp_auth = dpp_auth_init(wpa_s, peer_bi, own_bi, configurator);
  410. if (!wpa_s->dpp_auth)
  411. goto fail;
  412. wpas_dpp_set_testing_options(wpa_s, wpa_s->dpp_auth);
  413. wpa_s->dpp_auth->conf_sta = conf_sta;
  414. wpa_s->dpp_auth->conf_ap = conf_ap;
  415. wpa_s->dpp_auth->conf = conf;
  416. /* TODO: Support iteration over all frequencies and filtering of
  417. * frequencies based on locally enabled channels that allow initiation
  418. * of transmission. */
  419. if (peer_bi->num_freq > 0)
  420. wpa_s->dpp_auth->curr_freq = peer_bi->freq[0];
  421. else
  422. wpa_s->dpp_auth->curr_freq = 2412;
  423. msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_REQ,
  424. wpabuf_len(wpa_s->dpp_auth->req_attr));
  425. if (!msg)
  426. return -1;
  427. wpabuf_put_buf(msg, wpa_s->dpp_auth->req_attr);
  428. if (is_zero_ether_addr(peer_bi->mac_addr)) {
  429. dst = broadcast;
  430. } else {
  431. dst = peer_bi->mac_addr;
  432. os_memcpy(wpa_s->dpp_auth->peer_mac_addr, peer_bi->mac_addr,
  433. ETH_ALEN);
  434. }
  435. wpa_s->dpp_auth_ok_on_ack = 0;
  436. eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
  437. wait_time = wpa_s->max_remain_on_chan;
  438. if (wait_time > 2000)
  439. wait_time = 2000;
  440. eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
  441. wpas_dpp_reply_wait_timeout,
  442. wpa_s, NULL);
  443. res = offchannel_send_action(wpa_s, wpa_s->dpp_auth->curr_freq,
  444. dst, wpa_s->own_addr, broadcast,
  445. wpabuf_head(msg), wpabuf_len(msg),
  446. wait_time, wpas_dpp_tx_status, 0);
  447. wpabuf_free(msg);
  448. return res;
  449. fail:
  450. dpp_configuration_free(conf_sta);
  451. dpp_configuration_free(conf_ap);
  452. return -1;
  453. }
  454. struct wpas_dpp_listen_work {
  455. unsigned int freq;
  456. unsigned int duration;
  457. struct wpabuf *probe_resp_ie;
  458. };
  459. static void wpas_dpp_listen_work_free(struct wpas_dpp_listen_work *lwork)
  460. {
  461. if (!lwork)
  462. return;
  463. os_free(lwork);
  464. }
  465. static void wpas_dpp_listen_work_done(struct wpa_supplicant *wpa_s)
  466. {
  467. struct wpas_dpp_listen_work *lwork;
  468. if (!wpa_s->dpp_listen_work)
  469. return;
  470. lwork = wpa_s->dpp_listen_work->ctx;
  471. wpas_dpp_listen_work_free(lwork);
  472. radio_work_done(wpa_s->dpp_listen_work);
  473. wpa_s->dpp_listen_work = NULL;
  474. }
  475. static void dpp_start_listen_cb(struct wpa_radio_work *work, int deinit)
  476. {
  477. struct wpa_supplicant *wpa_s = work->wpa_s;
  478. struct wpas_dpp_listen_work *lwork = work->ctx;
  479. if (deinit) {
  480. if (work->started) {
  481. wpa_s->dpp_listen_work = NULL;
  482. wpas_dpp_listen_stop(wpa_s);
  483. }
  484. wpas_dpp_listen_work_free(lwork);
  485. return;
  486. }
  487. wpa_s->dpp_listen_work = work;
  488. wpa_s->dpp_pending_listen_freq = lwork->freq;
  489. if (wpa_drv_remain_on_channel(wpa_s, lwork->freq,
  490. wpa_s->max_remain_on_chan) < 0) {
  491. wpa_printf(MSG_DEBUG,
  492. "DPP: Failed to request the driver to remain on channel (%u MHz) for listen",
  493. lwork->freq);
  494. wpas_dpp_listen_work_done(wpa_s);
  495. wpa_s->dpp_pending_listen_freq = 0;
  496. return;
  497. }
  498. wpa_s->off_channel_freq = 0;
  499. wpa_s->roc_waiting_drv_freq = lwork->freq;
  500. }
  501. static int wpas_dpp_listen_start(struct wpa_supplicant *wpa_s,
  502. unsigned int freq)
  503. {
  504. struct wpas_dpp_listen_work *lwork;
  505. if (wpa_s->dpp_listen_work) {
  506. wpa_printf(MSG_DEBUG,
  507. "DPP: Reject start_listen since dpp_listen_work already exists");
  508. return -1;
  509. }
  510. if (wpa_s->dpp_listen_freq)
  511. wpas_dpp_listen_stop(wpa_s);
  512. wpa_s->dpp_listen_freq = freq;
  513. lwork = os_zalloc(sizeof(*lwork));
  514. if (!lwork)
  515. return -1;
  516. lwork->freq = freq;
  517. if (radio_add_work(wpa_s, freq, "dpp-listen", 0, dpp_start_listen_cb,
  518. lwork) < 0) {
  519. wpas_dpp_listen_work_free(lwork);
  520. return -1;
  521. }
  522. return 0;
  523. }
  524. int wpas_dpp_listen(struct wpa_supplicant *wpa_s, const char *cmd)
  525. {
  526. int freq;
  527. freq = atoi(cmd);
  528. if (freq <= 0)
  529. return -1;
  530. if (os_strstr(cmd, " role=configurator"))
  531. wpa_s->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR;
  532. else if (os_strstr(cmd, " role=enrollee"))
  533. wpa_s->dpp_allowed_roles = DPP_CAPAB_ENROLLEE;
  534. else
  535. wpa_s->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR |
  536. DPP_CAPAB_ENROLLEE;
  537. wpa_s->dpp_qr_mutual = os_strstr(cmd, " qr=mutual") != NULL;
  538. wpa_s->dpp_netrole_ap = os_strstr(cmd, " netrole=ap") != NULL;
  539. if (wpa_s->dpp_listen_freq == (unsigned int) freq) {
  540. wpa_printf(MSG_DEBUG, "DPP: Already listening on %u MHz",
  541. freq);
  542. return 0;
  543. }
  544. return wpas_dpp_listen_start(wpa_s, freq);
  545. }
  546. void wpas_dpp_listen_stop(struct wpa_supplicant *wpa_s)
  547. {
  548. if (!wpa_s->dpp_listen_freq)
  549. return;
  550. wpa_printf(MSG_DEBUG, "DPP: Stop listen on %u MHz",
  551. wpa_s->dpp_listen_freq);
  552. wpa_drv_cancel_remain_on_channel(wpa_s);
  553. wpa_s->dpp_listen_freq = 0;
  554. wpas_dpp_listen_work_done(wpa_s);
  555. }
  556. void wpas_dpp_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
  557. unsigned int freq)
  558. {
  559. if (!wpa_s->dpp_listen_freq && !wpa_s->dpp_pending_listen_freq)
  560. return;
  561. wpa_printf(MSG_DEBUG,
  562. "DPP: remain-on-channel callback (off_channel_freq=%u dpp_pending_listen_freq=%d roc_waiting_drv_freq=%d freq=%u)",
  563. wpa_s->off_channel_freq, wpa_s->dpp_pending_listen_freq,
  564. wpa_s->roc_waiting_drv_freq, freq);
  565. if (wpa_s->off_channel_freq &&
  566. wpa_s->off_channel_freq == wpa_s->dpp_pending_listen_freq) {
  567. wpa_printf(MSG_DEBUG, "DPP: Listen on %u MHz started", freq);
  568. wpa_s->dpp_pending_listen_freq = 0;
  569. } else {
  570. wpa_printf(MSG_DEBUG,
  571. "DPP: Ignore remain-on-channel callback (off_channel_freq=%u dpp_pending_listen_freq=%d freq=%u)",
  572. wpa_s->off_channel_freq,
  573. wpa_s->dpp_pending_listen_freq, freq);
  574. }
  575. }
  576. void wpas_dpp_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
  577. unsigned int freq)
  578. {
  579. wpas_dpp_listen_work_done(wpa_s);
  580. if (wpa_s->dpp_auth && !wpa_s->dpp_gas_client) {
  581. /* Continue listen with a new remain-on-channel */
  582. wpa_printf(MSG_DEBUG,
  583. "DPP: Continue wait on %u MHz for the ongoing DPP provisioning session",
  584. wpa_s->dpp_auth->curr_freq);
  585. wpas_dpp_listen_start(wpa_s, wpa_s->dpp_auth->curr_freq);
  586. return;
  587. }
  588. if (wpa_s->dpp_listen_freq) {
  589. /* Continue listen with a new remain-on-channel */
  590. wpas_dpp_listen_start(wpa_s, wpa_s->dpp_listen_freq);
  591. }
  592. }
  593. static void wpas_dpp_rx_auth_req(struct wpa_supplicant *wpa_s, const u8 *src,
  594. const u8 *buf, size_t len, unsigned int freq)
  595. {
  596. const u8 *r_bootstrap, *i_bootstrap, *wrapped_data;
  597. u16 r_bootstrap_len, i_bootstrap_len, wrapped_data_len;
  598. struct dpp_bootstrap_info *bi, *own_bi = NULL, *peer_bi = NULL;
  599. struct wpabuf *msg;
  600. wpa_printf(MSG_DEBUG, "DPP: Authentication Request from " MACSTR,
  601. MAC2STR(src));
  602. wrapped_data = dpp_get_attr(buf, len, DPP_ATTR_WRAPPED_DATA,
  603. &wrapped_data_len);
  604. if (!wrapped_data) {
  605. wpa_printf(MSG_DEBUG,
  606. "DPP: Missing required Wrapped data attribute");
  607. return;
  608. }
  609. wpa_hexdump(MSG_MSGDUMP, "DPP: Wrapped data",
  610. wrapped_data, wrapped_data_len);
  611. r_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
  612. &r_bootstrap_len);
  613. if (!r_bootstrap || r_bootstrap > wrapped_data ||
  614. r_bootstrap_len != SHA256_MAC_LEN) {
  615. wpa_printf(MSG_DEBUG,
  616. "DPP: Missing or invalid required Responder Bootstrapping Key Hash attribute");
  617. return;
  618. }
  619. wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash",
  620. r_bootstrap, r_bootstrap_len);
  621. i_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_I_BOOTSTRAP_KEY_HASH,
  622. &i_bootstrap_len);
  623. if (!i_bootstrap || i_bootstrap > wrapped_data ||
  624. i_bootstrap_len != SHA256_MAC_LEN) {
  625. wpa_printf(MSG_DEBUG,
  626. "DPP: Missing or invalid required Initiator Bootstrapping Key Hash attribute");
  627. return;
  628. }
  629. wpa_hexdump(MSG_MSGDUMP, "DPP: Initiator Bootstrapping Key Hash",
  630. i_bootstrap, i_bootstrap_len);
  631. /* Try to find own and peer bootstrapping key matches based on the
  632. * received hash values */
  633. dl_list_for_each(bi, &wpa_s->dpp_bootstrap, struct dpp_bootstrap_info,
  634. list) {
  635. if (!own_bi && bi->own &&
  636. os_memcmp(bi->pubkey_hash, r_bootstrap,
  637. SHA256_MAC_LEN) == 0) {
  638. wpa_printf(MSG_DEBUG,
  639. "DPP: Found matching own bootstrapping information");
  640. own_bi = bi;
  641. }
  642. if (!peer_bi && !bi->own &&
  643. os_memcmp(bi->pubkey_hash, i_bootstrap,
  644. SHA256_MAC_LEN) == 0) {
  645. wpa_printf(MSG_DEBUG,
  646. "DPP: Found matching peer bootstrapping information");
  647. peer_bi = bi;
  648. }
  649. if (own_bi && peer_bi)
  650. break;
  651. }
  652. if (!own_bi) {
  653. wpa_printf(MSG_DEBUG,
  654. "DPP: No matching own bootstrapping key found - ignore message");
  655. return;
  656. }
  657. if (wpa_s->dpp_auth) {
  658. wpa_printf(MSG_DEBUG,
  659. "DPP: Already in DPP authentication exchange - ignore new one");
  660. return;
  661. }
  662. wpa_s->dpp_gas_client = 0;
  663. wpa_s->dpp_auth_ok_on_ack = 0;
  664. wpa_s->dpp_auth = dpp_auth_req_rx(wpa_s, wpa_s->dpp_allowed_roles,
  665. wpa_s->dpp_qr_mutual,
  666. peer_bi, own_bi, freq, buf,
  667. wrapped_data, wrapped_data_len);
  668. if (!wpa_s->dpp_auth) {
  669. wpa_printf(MSG_DEBUG, "DPP: No response generated");
  670. return;
  671. }
  672. wpas_dpp_set_testing_options(wpa_s, wpa_s->dpp_auth);
  673. os_memcpy(wpa_s->dpp_auth->peer_mac_addr, src, ETH_ALEN);
  674. msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_RESP,
  675. wpabuf_len(wpa_s->dpp_auth->resp_attr));
  676. if (!msg)
  677. return;
  678. wpabuf_put_buf(msg, wpa_s->dpp_auth->resp_attr);
  679. offchannel_send_action(wpa_s, wpa_s->dpp_auth->curr_freq,
  680. src, wpa_s->own_addr, broadcast,
  681. wpabuf_head(msg), wpabuf_len(msg),
  682. 500, wpas_dpp_tx_status, 0);
  683. wpabuf_free(msg);
  684. }
  685. static void wpas_dpp_start_gas_server(struct wpa_supplicant *wpa_s)
  686. {
  687. /* TODO: stop wait and start ROC */
  688. }
  689. static void wpas_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token,
  690. enum gas_query_result result,
  691. const struct wpabuf *adv_proto,
  692. const struct wpabuf *resp, u16 status_code)
  693. {
  694. struct wpa_supplicant *wpa_s = ctx;
  695. const u8 *pos;
  696. struct dpp_authentication *auth = wpa_s->dpp_auth;
  697. if (!auth || !auth->auth_success) {
  698. wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
  699. return;
  700. }
  701. if (!resp || status_code != WLAN_STATUS_SUCCESS) {
  702. wpa_printf(MSG_DEBUG, "DPP: GAS query did not succeed");
  703. goto fail;
  704. }
  705. wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response adv_proto",
  706. adv_proto);
  707. wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response (GAS response)",
  708. resp);
  709. if (wpabuf_len(adv_proto) != 10 ||
  710. !(pos = wpabuf_head(adv_proto)) ||
  711. pos[0] != WLAN_EID_ADV_PROTO ||
  712. pos[1] != 8 ||
  713. pos[3] != WLAN_EID_VENDOR_SPECIFIC ||
  714. pos[4] != 5 ||
  715. WPA_GET_BE24(&pos[5]) != OUI_WFA ||
  716. pos[8] != 0x1a ||
  717. pos[9] != 1) {
  718. wpa_printf(MSG_DEBUG,
  719. "DPP: Not a DPP Advertisement Protocol ID");
  720. goto fail;
  721. }
  722. if (dpp_conf_resp_rx(auth, resp) < 0) {
  723. wpa_printf(MSG_DEBUG, "DPP: Configuration attempt failed");
  724. goto fail;
  725. }
  726. wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_RECEIVED);
  727. if (auth->ssid_len)
  728. wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONFOBJ_SSID "%s",
  729. wpa_ssid_txt(auth->ssid, auth->ssid_len));
  730. if (auth->connector) {
  731. /* TODO: Save the Connector and consider using a command
  732. * to fetch the value instead of sending an event with
  733. * it. The Connector could end up being larger than what
  734. * most clients are ready to receive as an event
  735. * message. */
  736. wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONNECTOR "%s",
  737. auth->connector);
  738. }
  739. if (auth->c_sign_key) {
  740. char *hex;
  741. size_t hexlen;
  742. hexlen = 2 * wpabuf_len(auth->c_sign_key) + 1;
  743. hex = os_malloc(hexlen);
  744. if (hex) {
  745. wpa_snprintf_hex(hex, hexlen,
  746. wpabuf_head(auth->c_sign_key),
  747. wpabuf_len(auth->c_sign_key));
  748. if (auth->c_sign_key_expiry)
  749. wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_C_SIGN_KEY
  750. "%s %lu", hex,
  751. (long unsigned)
  752. auth->c_sign_key_expiry);
  753. else
  754. wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_C_SIGN_KEY
  755. "%s", hex);
  756. os_free(hex);
  757. }
  758. }
  759. if (auth->net_access_key) {
  760. char *hex;
  761. size_t hexlen;
  762. hexlen = 2 * wpabuf_len(auth->net_access_key) + 1;
  763. hex = os_malloc(hexlen);
  764. if (hex) {
  765. wpa_snprintf_hex(hex, hexlen,
  766. wpabuf_head(auth->net_access_key),
  767. wpabuf_len(auth->net_access_key));
  768. if (auth->net_access_key_expiry)
  769. wpa_msg(wpa_s, MSG_INFO,
  770. DPP_EVENT_NET_ACCESS_KEY "%s %lu", hex,
  771. (long unsigned)
  772. auth->net_access_key_expiry);
  773. else
  774. wpa_msg(wpa_s, MSG_INFO,
  775. DPP_EVENT_NET_ACCESS_KEY "%s", hex);
  776. os_free(hex);
  777. }
  778. }
  779. dpp_auth_deinit(wpa_s->dpp_auth);
  780. wpa_s->dpp_auth = NULL;
  781. return;
  782. fail:
  783. wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_FAILED);
  784. dpp_auth_deinit(wpa_s->dpp_auth);
  785. wpa_s->dpp_auth = NULL;
  786. }
  787. static void wpas_dpp_start_gas_client(struct wpa_supplicant *wpa_s)
  788. {
  789. struct dpp_authentication *auth = wpa_s->dpp_auth;
  790. struct wpabuf *buf, *conf_req;
  791. char json[100];
  792. int res;
  793. wpa_s->dpp_gas_client = 1;
  794. os_snprintf(json, sizeof(json),
  795. "{\"name\":\"Test\","
  796. "\"wi-fi_tech\":\"infra\","
  797. "\"netRole\":\"%s\"}",
  798. wpa_s->dpp_netrole_ap ? "ap" : "sta");
  799. wpa_printf(MSG_DEBUG, "DPP: GAS Config Attributes: %s", json);
  800. offchannel_send_action_done(wpa_s);
  801. wpas_dpp_listen_stop(wpa_s);
  802. conf_req = dpp_build_conf_req(auth, json);
  803. if (!conf_req) {
  804. wpa_printf(MSG_DEBUG,
  805. "DPP: No configuration request data available");
  806. return;
  807. }
  808. buf = gas_build_initial_req(0, 10 + 2 + wpabuf_len(conf_req));
  809. if (!buf) {
  810. wpabuf_free(conf_req);
  811. return;
  812. }
  813. /* Advertisement Protocol IE */
  814. wpabuf_put_u8(buf, WLAN_EID_ADV_PROTO);
  815. wpabuf_put_u8(buf, 8); /* Length */
  816. wpabuf_put_u8(buf, 0x7f);
  817. wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
  818. wpabuf_put_u8(buf, 5);
  819. wpabuf_put_be24(buf, OUI_WFA);
  820. wpabuf_put_u8(buf, DPP_OUI_TYPE);
  821. wpabuf_put_u8(buf, 0x01);
  822. /* GAS Query */
  823. wpabuf_put_le16(buf, wpabuf_len(conf_req));
  824. wpabuf_put_buf(buf, conf_req);
  825. wpabuf_free(conf_req);
  826. wpa_printf(MSG_DEBUG, "DPP: GAS request to " MACSTR " (freq %u MHz)",
  827. MAC2STR(auth->peer_mac_addr), auth->curr_freq);
  828. res = gas_query_req(wpa_s->gas, auth->peer_mac_addr, auth->curr_freq,
  829. buf, wpas_dpp_gas_resp_cb, wpa_s);
  830. if (res < 0) {
  831. wpa_msg(wpa_s, MSG_DEBUG, "GAS: Failed to send Query Request");
  832. wpabuf_free(buf);
  833. } else {
  834. wpa_printf(MSG_DEBUG,
  835. "DPP: GAS query started with dialog token %u", res);
  836. }
  837. }
  838. static void wpas_dpp_auth_success(struct wpa_supplicant *wpa_s, int initiator)
  839. {
  840. wpa_printf(MSG_DEBUG, "DPP: Authentication succeeded");
  841. wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_AUTH_SUCCESS "init=%d", initiator);
  842. if (wpa_s->dpp_auth->configurator)
  843. wpas_dpp_start_gas_server(wpa_s);
  844. else
  845. wpas_dpp_start_gas_client(wpa_s);
  846. }
  847. static void wpas_dpp_rx_auth_resp(struct wpa_supplicant *wpa_s, const u8 *src,
  848. const u8 *buf, size_t len)
  849. {
  850. struct dpp_authentication *auth = wpa_s->dpp_auth;
  851. struct wpabuf *msg, *attr;
  852. wpa_printf(MSG_DEBUG, "DPP: Authentication Response from " MACSTR,
  853. MAC2STR(src));
  854. if (!auth) {
  855. wpa_printf(MSG_DEBUG,
  856. "DPP: No DPP Authentication in progress - drop");
  857. return;
  858. }
  859. if (!is_zero_ether_addr(auth->peer_mac_addr) &&
  860. os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
  861. wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
  862. MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
  863. return;
  864. }
  865. eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
  866. attr = dpp_auth_resp_rx(auth, buf, len);
  867. if (!attr) {
  868. if (auth->auth_resp_status == DPP_STATUS_RESPONSE_PENDING) {
  869. wpa_printf(MSG_DEBUG,
  870. "DPP: Start wait for full response");
  871. offchannel_send_action_done(wpa_s);
  872. wpas_dpp_listen_start(wpa_s, auth->curr_freq);
  873. return;
  874. }
  875. wpa_printf(MSG_DEBUG, "DPP: No confirm generated");
  876. return;
  877. }
  878. os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
  879. msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_CONF, wpabuf_len(attr));
  880. if (!msg) {
  881. wpabuf_free(attr);
  882. return;
  883. }
  884. wpabuf_put_buf(msg, attr);
  885. wpabuf_free(attr);
  886. offchannel_send_action(wpa_s, auth->curr_freq,
  887. src, wpa_s->own_addr, broadcast,
  888. wpabuf_head(msg), wpabuf_len(msg),
  889. 500, wpas_dpp_tx_status, 0);
  890. wpabuf_free(msg);
  891. wpa_s->dpp_auth_ok_on_ack = 1;
  892. }
  893. static void wpas_dpp_rx_auth_conf(struct wpa_supplicant *wpa_s, const u8 *src,
  894. const u8 *buf, size_t len)
  895. {
  896. struct dpp_authentication *auth = wpa_s->dpp_auth;
  897. wpa_printf(MSG_DEBUG, "DPP: Authentication Confirmation from " MACSTR,
  898. MAC2STR(src));
  899. if (!auth) {
  900. wpa_printf(MSG_DEBUG,
  901. "DPP: No DPP Authentication in progress - drop");
  902. return;
  903. }
  904. if (os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
  905. wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
  906. MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
  907. return;
  908. }
  909. if (dpp_auth_conf_rx(auth, buf, len) < 0) {
  910. wpa_printf(MSG_DEBUG, "DPP: Authentication failed");
  911. return;
  912. }
  913. wpas_dpp_auth_success(wpa_s, 0);
  914. }
  915. void wpas_dpp_rx_action(struct wpa_supplicant *wpa_s, const u8 *src,
  916. const u8 *buf, size_t len, unsigned int freq)
  917. {
  918. enum dpp_public_action_frame_type type;
  919. if (len < 1)
  920. return;
  921. type = buf[0];
  922. buf++;
  923. len--;
  924. wpa_printf(MSG_DEBUG,
  925. "DPP: Received DPP Public Action frame type %d from "
  926. MACSTR " freq=%u",
  927. type, MAC2STR(src), freq);
  928. wpa_hexdump(MSG_MSGDUMP, "DPP: Received message attributes", buf, len);
  929. if (dpp_check_attrs(buf, len) < 0)
  930. return;
  931. switch (type) {
  932. case DPP_PA_AUTHENTICATION_REQ:
  933. wpas_dpp_rx_auth_req(wpa_s, src, buf, len, freq);
  934. break;
  935. case DPP_PA_AUTHENTICATION_RESP:
  936. wpas_dpp_rx_auth_resp(wpa_s, src, buf, len);
  937. break;
  938. case DPP_PA_AUTHENTICATION_CONF:
  939. wpas_dpp_rx_auth_conf(wpa_s, src, buf, len);
  940. break;
  941. default:
  942. wpa_printf(MSG_DEBUG,
  943. "DPP: Ignored unsupported frame subtype %d", type);
  944. break;
  945. }
  946. }
  947. static struct wpabuf *
  948. wpas_dpp_gas_req_handler(void *ctx, const u8 *sa, const u8 *query,
  949. size_t query_len)
  950. {
  951. struct wpa_supplicant *wpa_s = ctx;
  952. struct dpp_authentication *auth = wpa_s->dpp_auth;
  953. struct wpabuf *resp;
  954. wpa_printf(MSG_DEBUG, "DPP: GAS request from " MACSTR,
  955. MAC2STR(sa));
  956. if (!auth || !auth->auth_success ||
  957. os_memcmp(sa, auth->peer_mac_addr, ETH_ALEN) != 0) {
  958. wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
  959. return NULL;
  960. }
  961. wpa_hexdump(MSG_DEBUG,
  962. "DPP: Received Configuration Request (GAS Query Request)",
  963. query, query_len);
  964. resp = dpp_conf_req_rx(auth, query, query_len);
  965. if (!resp)
  966. wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_FAILED);
  967. return resp;
  968. }
  969. static void
  970. wpas_dpp_gas_status_handler(void *ctx, struct wpabuf *resp, int ok)
  971. {
  972. struct wpa_supplicant *wpa_s = ctx;
  973. struct dpp_authentication *auth = wpa_s->dpp_auth;
  974. if (!auth) {
  975. wpabuf_free(resp);
  976. return;
  977. }
  978. wpa_printf(MSG_DEBUG, "DPP: Configuration exchange completed (ok=%d)",
  979. ok);
  980. eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
  981. offchannel_send_action_done(wpa_s);
  982. wpas_dpp_listen_stop(wpa_s);
  983. if (ok)
  984. wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_SENT);
  985. else
  986. wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_FAILED);
  987. dpp_auth_deinit(wpa_s->dpp_auth);
  988. wpa_s->dpp_auth = NULL;
  989. wpabuf_free(resp);
  990. }
  991. static unsigned int wpas_dpp_next_configurator_id(struct wpa_supplicant *wpa_s)
  992. {
  993. struct dpp_configurator *conf;
  994. unsigned int max_id = 0;
  995. dl_list_for_each(conf, &wpa_s->dpp_configurator,
  996. struct dpp_configurator, list) {
  997. if (conf->id > max_id)
  998. max_id = conf->id;
  999. }
  1000. return max_id + 1;
  1001. }
  1002. int wpas_dpp_configurator_add(struct wpa_supplicant *wpa_s, const char *cmd)
  1003. {
  1004. char *expiry = NULL, *curve = NULL;
  1005. char *key = NULL;
  1006. u8 *privkey = NULL;
  1007. size_t privkey_len = 0;
  1008. int ret = -1;
  1009. struct dpp_configurator *conf = NULL;
  1010. expiry = get_param(cmd, " expiry=");
  1011. curve = get_param(cmd, " curve=");
  1012. key = get_param(cmd, " key=");
  1013. if (key) {
  1014. privkey_len = os_strlen(key) / 2;
  1015. privkey = os_malloc(privkey_len);
  1016. if (!privkey ||
  1017. hexstr2bin(key, privkey, privkey_len) < 0)
  1018. goto fail;
  1019. }
  1020. conf = dpp_keygen_configurator(curve, privkey, privkey_len);
  1021. if (!conf)
  1022. goto fail;
  1023. if (expiry) {
  1024. long int val;
  1025. val = strtol(expiry, NULL, 0);
  1026. if (val <= 0)
  1027. goto fail;
  1028. conf->csign_expiry = val;
  1029. }
  1030. conf->id = wpas_dpp_next_configurator_id(wpa_s);
  1031. dl_list_add(&wpa_s->dpp_configurator, &conf->list);
  1032. ret = conf->id;
  1033. conf = NULL;
  1034. fail:
  1035. os_free(curve);
  1036. os_free(expiry);
  1037. str_clear_free(key);
  1038. bin_clear_free(privkey, privkey_len);
  1039. dpp_configurator_free(conf);
  1040. return ret;
  1041. }
  1042. static int dpp_configurator_del(struct wpa_supplicant *wpa_s, unsigned int id)
  1043. {
  1044. struct dpp_configurator *conf, *tmp;
  1045. int found = 0;
  1046. dl_list_for_each_safe(conf, tmp, &wpa_s->dpp_configurator,
  1047. struct dpp_configurator, list) {
  1048. if (id && conf->id != id)
  1049. continue;
  1050. found = 1;
  1051. dl_list_del(&conf->list);
  1052. dpp_configurator_free(conf);
  1053. }
  1054. if (id == 0)
  1055. return 0; /* flush succeeds regardless of entries found */
  1056. return found ? 0 : -1;
  1057. }
  1058. int wpas_dpp_configurator_remove(struct wpa_supplicant *wpa_s, const char *id)
  1059. {
  1060. unsigned int id_val;
  1061. if (os_strcmp(id, "*") == 0) {
  1062. id_val = 0;
  1063. } else {
  1064. id_val = atoi(id);
  1065. if (id_val == 0)
  1066. return -1;
  1067. }
  1068. return dpp_configurator_del(wpa_s, id_val);
  1069. }
  1070. int wpas_dpp_init(struct wpa_supplicant *wpa_s)
  1071. {
  1072. u8 adv_proto_id[7];
  1073. adv_proto_id[0] = WLAN_EID_VENDOR_SPECIFIC;
  1074. adv_proto_id[1] = 5;
  1075. WPA_PUT_BE24(&adv_proto_id[2], OUI_WFA);
  1076. adv_proto_id[5] = DPP_OUI_TYPE;
  1077. adv_proto_id[6] = 0x01;
  1078. if (gas_server_register(wpa_s->gas_server, adv_proto_id,
  1079. sizeof(adv_proto_id), wpas_dpp_gas_req_handler,
  1080. wpas_dpp_gas_status_handler, wpa_s) < 0)
  1081. return -1;
  1082. dl_list_init(&wpa_s->dpp_bootstrap);
  1083. dl_list_init(&wpa_s->dpp_configurator);
  1084. wpa_s->dpp_init_done = 1;
  1085. return 0;
  1086. }
  1087. void wpas_dpp_deinit(struct wpa_supplicant *wpa_s)
  1088. {
  1089. #ifdef CONFIG_TESTING_OPTIONS
  1090. os_free(wpa_s->dpp_config_obj_override);
  1091. wpa_s->dpp_config_obj_override = NULL;
  1092. os_free(wpa_s->dpp_discovery_override);
  1093. wpa_s->dpp_discovery_override = NULL;
  1094. os_free(wpa_s->dpp_groups_override);
  1095. wpa_s->dpp_groups_override = NULL;
  1096. os_free(wpa_s->dpp_devices_override);
  1097. wpa_s->dpp_devices_override = NULL;
  1098. wpa_s->dpp_ignore_netaccesskey_mismatch = 0;
  1099. #endif /* CONFIG_TESTING_OPTIONS */
  1100. if (!wpa_s->dpp_init_done)
  1101. return;
  1102. eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
  1103. offchannel_send_action_done(wpa_s);
  1104. wpas_dpp_listen_stop(wpa_s);
  1105. dpp_bootstrap_del(wpa_s, 0);
  1106. dpp_configurator_del(wpa_s, 0);
  1107. dpp_auth_deinit(wpa_s->dpp_auth);
  1108. wpa_s->dpp_auth = NULL;
  1109. }