dpp_supplicant.c 52 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046
  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 "rsn_supp/wpa.h"
  15. #include "rsn_supp/pmksa_cache.h"
  16. #include "wpa_supplicant_i.h"
  17. #include "config.h"
  18. #include "driver_i.h"
  19. #include "offchannel.h"
  20. #include "gas_query.h"
  21. #include "bss.h"
  22. #include "scan.h"
  23. #include "notify.h"
  24. #include "dpp_supplicant.h"
  25. static int wpas_dpp_listen_start(struct wpa_supplicant *wpa_s,
  26. unsigned int freq);
  27. static void wpas_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx);
  28. static void wpas_dpp_auth_success(struct wpa_supplicant *wpa_s, int initiator);
  29. static void wpas_dpp_tx_status(struct wpa_supplicant *wpa_s,
  30. unsigned int freq, const u8 *dst,
  31. const u8 *src, const u8 *bssid,
  32. const u8 *data, size_t data_len,
  33. enum offchannel_send_action_result result);
  34. static const u8 broadcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  35. /* Use a hardcoded Transaction ID 1 in Peer Discovery frames since there is only
  36. * a single transaction in progress at any point in time. */
  37. static const u8 TRANSACTION_ID = 1;
  38. static struct dpp_configurator *
  39. dpp_configurator_get_id(struct wpa_supplicant *wpa_s, unsigned int id)
  40. {
  41. struct dpp_configurator *conf;
  42. dl_list_for_each(conf, &wpa_s->dpp_configurator,
  43. struct dpp_configurator, list) {
  44. if (conf->id == id)
  45. return conf;
  46. }
  47. return NULL;
  48. }
  49. static unsigned int wpas_dpp_next_id(struct wpa_supplicant *wpa_s)
  50. {
  51. struct dpp_bootstrap_info *bi;
  52. unsigned int max_id = 0;
  53. dl_list_for_each(bi, &wpa_s->dpp_bootstrap, struct dpp_bootstrap_info,
  54. list) {
  55. if (bi->id > max_id)
  56. max_id = bi->id;
  57. }
  58. return max_id + 1;
  59. }
  60. /**
  61. * wpas_dpp_qr_code - Parse and add DPP bootstrapping info from a QR Code
  62. * @wpa_s: Pointer to wpa_supplicant data
  63. * @cmd: DPP URI read from a QR Code
  64. * Returns: Identifier of the stored info or -1 on failure
  65. */
  66. int wpas_dpp_qr_code(struct wpa_supplicant *wpa_s, const char *cmd)
  67. {
  68. struct dpp_bootstrap_info *bi;
  69. struct dpp_authentication *auth = wpa_s->dpp_auth;
  70. bi = dpp_parse_qr_code(cmd);
  71. if (!bi)
  72. return -1;
  73. bi->id = wpas_dpp_next_id(wpa_s);
  74. dl_list_add(&wpa_s->dpp_bootstrap, &bi->list);
  75. if (auth && auth->response_pending &&
  76. dpp_notify_new_qr_code(auth, bi) == 1) {
  77. struct wpabuf *msg;
  78. wpa_printf(MSG_DEBUG,
  79. "DPP: Sending out pending authentication response");
  80. msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_RESP,
  81. wpabuf_len(auth->resp_attr));
  82. if (!msg)
  83. goto out;
  84. wpabuf_put_buf(msg, wpa_s->dpp_auth->resp_attr);
  85. offchannel_send_action(wpa_s, auth->curr_freq,
  86. auth->peer_mac_addr, wpa_s->own_addr,
  87. broadcast,
  88. wpabuf_head(msg), wpabuf_len(msg),
  89. 500, wpas_dpp_tx_status, 0);
  90. wpabuf_free(msg);
  91. }
  92. out:
  93. return bi->id;
  94. }
  95. static char * get_param(const char *cmd, const char *param)
  96. {
  97. const char *pos, *end;
  98. char *val;
  99. size_t len;
  100. pos = os_strstr(cmd, param);
  101. if (!pos)
  102. return NULL;
  103. pos += os_strlen(param);
  104. end = os_strchr(pos, ' ');
  105. if (end)
  106. len = end - pos;
  107. else
  108. len = os_strlen(pos);
  109. val = os_malloc(len + 1);
  110. if (!val)
  111. return NULL;
  112. os_memcpy(val, pos, len);
  113. val[len] = '\0';
  114. return val;
  115. }
  116. int wpas_dpp_bootstrap_gen(struct wpa_supplicant *wpa_s, const char *cmd)
  117. {
  118. char *chan = NULL, *mac = NULL, *info = NULL, *pk = NULL, *curve = NULL;
  119. char *key = NULL;
  120. u8 *privkey = NULL;
  121. size_t privkey_len = 0;
  122. size_t len;
  123. int ret = -1;
  124. struct dpp_bootstrap_info *bi;
  125. bi = os_zalloc(sizeof(*bi));
  126. if (!bi)
  127. goto fail;
  128. if (os_strstr(cmd, "type=qrcode"))
  129. bi->type = DPP_BOOTSTRAP_QR_CODE;
  130. else if (os_strstr(cmd, "type=pkex"))
  131. bi->type = DPP_BOOTSTRAP_PKEX;
  132. else
  133. goto fail;
  134. chan = get_param(cmd, " chan=");
  135. mac = get_param(cmd, " mac=");
  136. info = get_param(cmd, " info=");
  137. curve = get_param(cmd, " curve=");
  138. key = get_param(cmd, " key=");
  139. if (key) {
  140. privkey_len = os_strlen(key) / 2;
  141. privkey = os_malloc(privkey_len);
  142. if (!privkey ||
  143. hexstr2bin(key, privkey, privkey_len) < 0)
  144. goto fail;
  145. }
  146. pk = dpp_keygen(bi, curve, privkey, privkey_len);
  147. if (!pk)
  148. goto fail;
  149. len = 4; /* "DPP:" */
  150. if (chan) {
  151. if (dpp_parse_uri_chan_list(bi, chan) < 0)
  152. goto fail;
  153. len += 3 + os_strlen(chan); /* C:...; */
  154. }
  155. if (mac) {
  156. if (dpp_parse_uri_mac(bi, mac) < 0)
  157. goto fail;
  158. len += 3 + os_strlen(mac); /* M:...; */
  159. }
  160. if (info) {
  161. if (dpp_parse_uri_info(bi, info) < 0)
  162. goto fail;
  163. len += 3 + os_strlen(info); /* I:...; */
  164. }
  165. len += 4 + os_strlen(pk);
  166. bi->uri = os_malloc(len + 1);
  167. if (!bi->uri)
  168. goto fail;
  169. os_snprintf(bi->uri, len + 1, "DPP:%s%s%s%s%s%s%s%s%sK:%s;;",
  170. chan ? "C:" : "", chan ? chan : "", chan ? ";" : "",
  171. mac ? "M:" : "", mac ? mac : "", mac ? ";" : "",
  172. info ? "I:" : "", info ? info : "", info ? ";" : "",
  173. pk);
  174. bi->id = wpas_dpp_next_id(wpa_s);
  175. dl_list_add(&wpa_s->dpp_bootstrap, &bi->list);
  176. ret = bi->id;
  177. bi = NULL;
  178. fail:
  179. os_free(curve);
  180. os_free(pk);
  181. os_free(chan);
  182. os_free(mac);
  183. os_free(info);
  184. str_clear_free(key);
  185. bin_clear_free(privkey, privkey_len);
  186. dpp_bootstrap_info_free(bi);
  187. return ret;
  188. }
  189. static struct dpp_bootstrap_info *
  190. dpp_bootstrap_get_id(struct wpa_supplicant *wpa_s, unsigned int id)
  191. {
  192. struct dpp_bootstrap_info *bi;
  193. dl_list_for_each(bi, &wpa_s->dpp_bootstrap, struct dpp_bootstrap_info,
  194. list) {
  195. if (bi->id == id)
  196. return bi;
  197. }
  198. return NULL;
  199. }
  200. static int dpp_bootstrap_del(struct wpa_supplicant *wpa_s, unsigned int id)
  201. {
  202. struct dpp_bootstrap_info *bi, *tmp;
  203. int found = 0;
  204. dl_list_for_each_safe(bi, tmp, &wpa_s->dpp_bootstrap,
  205. struct dpp_bootstrap_info, list) {
  206. if (id && bi->id != id)
  207. continue;
  208. found = 1;
  209. dl_list_del(&bi->list);
  210. dpp_bootstrap_info_free(bi);
  211. }
  212. if (id == 0)
  213. return 0; /* flush succeeds regardless of entries found */
  214. return found ? 0 : -1;
  215. }
  216. int wpas_dpp_bootstrap_remove(struct wpa_supplicant *wpa_s, const char *id)
  217. {
  218. unsigned int id_val;
  219. if (os_strcmp(id, "*") == 0) {
  220. id_val = 0;
  221. } else {
  222. id_val = atoi(id);
  223. if (id_val == 0)
  224. return -1;
  225. }
  226. return dpp_bootstrap_del(wpa_s, id_val);
  227. }
  228. const char * wpas_dpp_bootstrap_get_uri(struct wpa_supplicant *wpa_s,
  229. unsigned int id)
  230. {
  231. struct dpp_bootstrap_info *bi;
  232. bi = dpp_bootstrap_get_id(wpa_s, id);
  233. if (!bi)
  234. return NULL;
  235. return bi->uri;
  236. }
  237. int wpas_dpp_bootstrap_info(struct wpa_supplicant *wpa_s, int id,
  238. char *reply, int reply_size)
  239. {
  240. struct dpp_bootstrap_info *bi;
  241. bi = dpp_bootstrap_get_id(wpa_s, id);
  242. if (!bi)
  243. return -1;
  244. return os_snprintf(reply, reply_size, "type=%s\n"
  245. "mac_addr=" MACSTR "\n"
  246. "info=%s\n"
  247. "num_freq=%u\n"
  248. "curve=%s\n",
  249. dpp_bootstrap_type_txt(bi->type),
  250. MAC2STR(bi->mac_addr),
  251. bi->info ? bi->info : "",
  252. bi->num_freq,
  253. bi->curve->name);
  254. }
  255. static void wpas_dpp_tx_status(struct wpa_supplicant *wpa_s,
  256. unsigned int freq, const u8 *dst,
  257. const u8 *src, const u8 *bssid,
  258. const u8 *data, size_t data_len,
  259. enum offchannel_send_action_result result)
  260. {
  261. wpa_printf(MSG_DEBUG, "DPP: TX status: freq=%u dst=" MACSTR
  262. " result=%s",
  263. freq, MAC2STR(dst),
  264. result == OFFCHANNEL_SEND_ACTION_SUCCESS ? "SUCCESS" :
  265. (result == OFFCHANNEL_SEND_ACTION_NO_ACK ? "no-ACK" :
  266. "FAILED"));
  267. if (!wpa_s->dpp_auth) {
  268. wpa_printf(MSG_DEBUG,
  269. "DPP: Ignore TX status since there is no ongoing authentication exchange");
  270. return;
  271. }
  272. if (wpa_s->dpp_auth->remove_on_tx_status) {
  273. wpa_printf(MSG_DEBUG,
  274. "DPP: Terminate authentication exchange due to an earlier error");
  275. eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
  276. offchannel_send_action_done(wpa_s);
  277. dpp_auth_deinit(wpa_s->dpp_auth);
  278. wpa_s->dpp_auth = NULL;
  279. return;
  280. }
  281. if (wpa_s->dpp_auth_ok_on_ack)
  282. wpas_dpp_auth_success(wpa_s, 1);
  283. if (!is_broadcast_ether_addr(dst) &&
  284. result != OFFCHANNEL_SEND_ACTION_SUCCESS) {
  285. wpa_printf(MSG_DEBUG,
  286. "DPP: Unicast DPP Action frame was not ACKed");
  287. /* TODO: In case of DPP Authentication Request frame, move to
  288. * the next channel immediately */
  289. }
  290. }
  291. static void wpas_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx)
  292. {
  293. struct wpa_supplicant *wpa_s = eloop_ctx;
  294. if (!wpa_s->dpp_auth)
  295. return;
  296. wpa_printf(MSG_DEBUG, "DPP: Continue reply wait on channel %u MHz",
  297. wpa_s->dpp_auth->curr_freq);
  298. wpas_dpp_listen_start(wpa_s, wpa_s->dpp_auth->curr_freq);
  299. }
  300. static void wpas_dpp_set_testing_options(struct wpa_supplicant *wpa_s,
  301. struct dpp_authentication *auth)
  302. {
  303. #ifdef CONFIG_TESTING_OPTIONS
  304. if (wpa_s->dpp_config_obj_override)
  305. auth->config_obj_override =
  306. os_strdup(wpa_s->dpp_config_obj_override);
  307. if (wpa_s->dpp_discovery_override)
  308. auth->discovery_override =
  309. os_strdup(wpa_s->dpp_discovery_override);
  310. if (wpa_s->dpp_groups_override)
  311. auth->groups_override =
  312. os_strdup(wpa_s->dpp_groups_override);
  313. auth->ignore_netaccesskey_mismatch =
  314. wpa_s->dpp_ignore_netaccesskey_mismatch;
  315. #endif /* CONFIG_TESTING_OPTIONS */
  316. }
  317. static void wpas_dpp_set_configurator(struct wpa_supplicant *wpa_s,
  318. struct dpp_authentication *auth,
  319. const char *cmd)
  320. {
  321. const char *pos, *end;
  322. struct dpp_configuration *conf_sta = NULL, *conf_ap = NULL;
  323. struct dpp_configurator *conf = NULL;
  324. u8 ssid[32] = { "test" };
  325. size_t ssid_len = 4;
  326. char pass[64] = { };
  327. size_t pass_len = 0;
  328. u8 psk[PMK_LEN];
  329. int psk_set = 0;
  330. if (!cmd)
  331. return;
  332. wpa_printf(MSG_DEBUG, "DPP: Set configurator parameters: %s", cmd);
  333. pos = os_strstr(cmd, " ssid=");
  334. if (pos) {
  335. pos += 6;
  336. end = os_strchr(pos, ' ');
  337. ssid_len = end ? (size_t) (end - pos) : os_strlen(pos);
  338. ssid_len /= 2;
  339. if (ssid_len > sizeof(ssid) ||
  340. hexstr2bin(pos, ssid, ssid_len) < 0)
  341. goto fail;
  342. }
  343. pos = os_strstr(cmd, " pass=");
  344. if (pos) {
  345. pos += 6;
  346. end = os_strchr(pos, ' ');
  347. pass_len = end ? (size_t) (end - pos) : os_strlen(pos);
  348. pass_len /= 2;
  349. if (pass_len > sizeof(pass) - 1 || pass_len < 8 ||
  350. hexstr2bin(pos, (u8 *) pass, pass_len) < 0)
  351. goto fail;
  352. }
  353. pos = os_strstr(cmd, " psk=");
  354. if (pos) {
  355. pos += 5;
  356. if (hexstr2bin(pos, psk, PMK_LEN) < 0)
  357. goto fail;
  358. psk_set = 1;
  359. }
  360. if (os_strstr(cmd, " conf=sta-")) {
  361. conf_sta = os_zalloc(sizeof(struct dpp_configuration));
  362. if (!conf_sta)
  363. goto fail;
  364. os_memcpy(conf_sta->ssid, ssid, ssid_len);
  365. conf_sta->ssid_len = ssid_len;
  366. if (os_strstr(cmd, " conf=sta-psk")) {
  367. conf_sta->dpp = 0;
  368. if (psk_set) {
  369. os_memcpy(conf_sta->psk, psk, PMK_LEN);
  370. } else {
  371. conf_sta->passphrase = os_strdup(pass);
  372. if (!conf_sta->passphrase)
  373. goto fail;
  374. }
  375. } else if (os_strstr(cmd, " conf=sta-dpp")) {
  376. conf_sta->dpp = 1;
  377. } else {
  378. goto fail;
  379. }
  380. }
  381. if (os_strstr(cmd, " conf=ap-")) {
  382. conf_ap = os_zalloc(sizeof(struct dpp_configuration));
  383. if (!conf_ap)
  384. goto fail;
  385. os_memcpy(conf_ap->ssid, ssid, ssid_len);
  386. conf_ap->ssid_len = ssid_len;
  387. if (os_strstr(cmd, " conf=ap-psk")) {
  388. conf_ap->dpp = 0;
  389. if (psk_set) {
  390. os_memcpy(conf_ap->psk, psk, PMK_LEN);
  391. } else {
  392. conf_ap->passphrase = os_strdup(pass);
  393. if (!conf_ap->passphrase)
  394. goto fail;
  395. }
  396. } else if (os_strstr(cmd, " conf=ap-dpp")) {
  397. conf_ap->dpp = 1;
  398. } else {
  399. goto fail;
  400. }
  401. }
  402. pos = os_strstr(cmd, " expiry=");
  403. if (pos) {
  404. long int val;
  405. pos += 8;
  406. val = strtol(pos, NULL, 0);
  407. if (val <= 0)
  408. goto fail;
  409. if (conf_sta)
  410. conf_sta->netaccesskey_expiry = val;
  411. if (conf_ap)
  412. conf_ap->netaccesskey_expiry = val;
  413. }
  414. pos = os_strstr(cmd, " configurator=");
  415. if (pos) {
  416. pos += 14;
  417. conf = dpp_configurator_get_id(wpa_s, atoi(pos));
  418. if (!conf) {
  419. wpa_printf(MSG_INFO,
  420. "DPP: Could not find the specified configurator");
  421. goto fail;
  422. }
  423. }
  424. auth->conf_sta = conf_sta;
  425. auth->conf_ap = conf_ap;
  426. auth->conf = conf;
  427. return;
  428. fail:
  429. wpa_printf(MSG_DEBUG, "DPP: Failed to set configurator parameters");
  430. dpp_configuration_free(conf_sta);
  431. dpp_configuration_free(conf_ap);
  432. }
  433. int wpas_dpp_auth_init(struct wpa_supplicant *wpa_s, const char *cmd)
  434. {
  435. const char *pos;
  436. struct dpp_bootstrap_info *peer_bi, *own_bi = NULL;
  437. struct wpabuf *msg;
  438. const u8 *dst;
  439. int res;
  440. int configurator = 1;
  441. unsigned int wait_time;
  442. wpa_s->dpp_gas_client = 0;
  443. pos = os_strstr(cmd, " peer=");
  444. if (!pos)
  445. return -1;
  446. pos += 6;
  447. peer_bi = dpp_bootstrap_get_id(wpa_s, atoi(pos));
  448. if (!peer_bi) {
  449. wpa_printf(MSG_INFO,
  450. "DPP: Could not find bootstrapping info for the identified peer");
  451. return -1;
  452. }
  453. pos = os_strstr(cmd, " own=");
  454. if (pos) {
  455. pos += 5;
  456. own_bi = dpp_bootstrap_get_id(wpa_s, atoi(pos));
  457. if (!own_bi) {
  458. wpa_printf(MSG_INFO,
  459. "DPP: Could not find bootstrapping info for the identified local entry");
  460. return -1;
  461. }
  462. if (peer_bi->curve != own_bi->curve) {
  463. wpa_printf(MSG_INFO,
  464. "DPP: Mismatching curves in bootstrapping info (peer=%s own=%s)",
  465. peer_bi->curve->name, own_bi->curve->name);
  466. return -1;
  467. }
  468. }
  469. pos = os_strstr(cmd, " role=");
  470. if (pos) {
  471. pos += 6;
  472. if (os_strncmp(pos, "configurator", 12) == 0)
  473. configurator = 1;
  474. else if (os_strncmp(pos, "enrollee", 8) == 0)
  475. configurator = 0;
  476. else
  477. goto fail;
  478. }
  479. pos = os_strstr(cmd, " netrole=");
  480. if (pos) {
  481. pos += 9;
  482. wpa_s->dpp_netrole_ap = os_strncmp(pos, "ap", 2) == 0;
  483. }
  484. if (wpa_s->dpp_auth) {
  485. eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
  486. offchannel_send_action_done(wpa_s);
  487. dpp_auth_deinit(wpa_s->dpp_auth);
  488. }
  489. wpa_s->dpp_auth = dpp_auth_init(wpa_s, peer_bi, own_bi, configurator);
  490. if (!wpa_s->dpp_auth)
  491. goto fail;
  492. wpas_dpp_set_testing_options(wpa_s, wpa_s->dpp_auth);
  493. wpas_dpp_set_configurator(wpa_s, wpa_s->dpp_auth, cmd);
  494. /* TODO: Support iteration over all frequencies and filtering of
  495. * frequencies based on locally enabled channels that allow initiation
  496. * of transmission. */
  497. if (peer_bi->num_freq > 0)
  498. wpa_s->dpp_auth->curr_freq = peer_bi->freq[0];
  499. else
  500. wpa_s->dpp_auth->curr_freq = 2412;
  501. msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_REQ,
  502. wpabuf_len(wpa_s->dpp_auth->req_attr));
  503. if (!msg)
  504. return -1;
  505. wpabuf_put_buf(msg, wpa_s->dpp_auth->req_attr);
  506. if (is_zero_ether_addr(peer_bi->mac_addr)) {
  507. dst = broadcast;
  508. } else {
  509. dst = peer_bi->mac_addr;
  510. os_memcpy(wpa_s->dpp_auth->peer_mac_addr, peer_bi->mac_addr,
  511. ETH_ALEN);
  512. }
  513. wpa_s->dpp_auth_ok_on_ack = 0;
  514. eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
  515. wait_time = wpa_s->max_remain_on_chan;
  516. if (wait_time > 2000)
  517. wait_time = 2000;
  518. eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
  519. wpas_dpp_reply_wait_timeout,
  520. wpa_s, NULL);
  521. res = offchannel_send_action(wpa_s, wpa_s->dpp_auth->curr_freq,
  522. dst, wpa_s->own_addr, broadcast,
  523. wpabuf_head(msg), wpabuf_len(msg),
  524. wait_time, wpas_dpp_tx_status, 0);
  525. wpabuf_free(msg);
  526. return res;
  527. fail:
  528. return -1;
  529. }
  530. struct wpas_dpp_listen_work {
  531. unsigned int freq;
  532. unsigned int duration;
  533. struct wpabuf *probe_resp_ie;
  534. };
  535. static void wpas_dpp_listen_work_free(struct wpas_dpp_listen_work *lwork)
  536. {
  537. if (!lwork)
  538. return;
  539. os_free(lwork);
  540. }
  541. static void wpas_dpp_listen_work_done(struct wpa_supplicant *wpa_s)
  542. {
  543. struct wpas_dpp_listen_work *lwork;
  544. if (!wpa_s->dpp_listen_work)
  545. return;
  546. lwork = wpa_s->dpp_listen_work->ctx;
  547. wpas_dpp_listen_work_free(lwork);
  548. radio_work_done(wpa_s->dpp_listen_work);
  549. wpa_s->dpp_listen_work = NULL;
  550. }
  551. static void dpp_start_listen_cb(struct wpa_radio_work *work, int deinit)
  552. {
  553. struct wpa_supplicant *wpa_s = work->wpa_s;
  554. struct wpas_dpp_listen_work *lwork = work->ctx;
  555. if (deinit) {
  556. if (work->started) {
  557. wpa_s->dpp_listen_work = NULL;
  558. wpas_dpp_listen_stop(wpa_s);
  559. }
  560. wpas_dpp_listen_work_free(lwork);
  561. return;
  562. }
  563. wpa_s->dpp_listen_work = work;
  564. wpa_s->dpp_pending_listen_freq = lwork->freq;
  565. if (wpa_drv_remain_on_channel(wpa_s, lwork->freq,
  566. wpa_s->max_remain_on_chan) < 0) {
  567. wpa_printf(MSG_DEBUG,
  568. "DPP: Failed to request the driver to remain on channel (%u MHz) for listen",
  569. lwork->freq);
  570. wpas_dpp_listen_work_done(wpa_s);
  571. wpa_s->dpp_pending_listen_freq = 0;
  572. return;
  573. }
  574. wpa_s->off_channel_freq = 0;
  575. wpa_s->roc_waiting_drv_freq = lwork->freq;
  576. }
  577. static int wpas_dpp_listen_start(struct wpa_supplicant *wpa_s,
  578. unsigned int freq)
  579. {
  580. struct wpas_dpp_listen_work *lwork;
  581. if (wpa_s->dpp_listen_work) {
  582. wpa_printf(MSG_DEBUG,
  583. "DPP: Reject start_listen since dpp_listen_work already exists");
  584. return -1;
  585. }
  586. if (wpa_s->dpp_listen_freq)
  587. wpas_dpp_listen_stop(wpa_s);
  588. wpa_s->dpp_listen_freq = freq;
  589. lwork = os_zalloc(sizeof(*lwork));
  590. if (!lwork)
  591. return -1;
  592. lwork->freq = freq;
  593. if (radio_add_work(wpa_s, freq, "dpp-listen", 0, dpp_start_listen_cb,
  594. lwork) < 0) {
  595. wpas_dpp_listen_work_free(lwork);
  596. return -1;
  597. }
  598. return 0;
  599. }
  600. int wpas_dpp_listen(struct wpa_supplicant *wpa_s, const char *cmd)
  601. {
  602. int freq;
  603. freq = atoi(cmd);
  604. if (freq <= 0)
  605. return -1;
  606. if (os_strstr(cmd, " role=configurator"))
  607. wpa_s->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR;
  608. else if (os_strstr(cmd, " role=enrollee"))
  609. wpa_s->dpp_allowed_roles = DPP_CAPAB_ENROLLEE;
  610. else
  611. wpa_s->dpp_allowed_roles = DPP_CAPAB_CONFIGURATOR |
  612. DPP_CAPAB_ENROLLEE;
  613. wpa_s->dpp_qr_mutual = os_strstr(cmd, " qr=mutual") != NULL;
  614. wpa_s->dpp_netrole_ap = os_strstr(cmd, " netrole=ap") != NULL;
  615. if (wpa_s->dpp_listen_freq == (unsigned int) freq) {
  616. wpa_printf(MSG_DEBUG, "DPP: Already listening on %u MHz",
  617. freq);
  618. return 0;
  619. }
  620. return wpas_dpp_listen_start(wpa_s, freq);
  621. }
  622. void wpas_dpp_listen_stop(struct wpa_supplicant *wpa_s)
  623. {
  624. if (!wpa_s->dpp_listen_freq)
  625. return;
  626. wpa_printf(MSG_DEBUG, "DPP: Stop listen on %u MHz",
  627. wpa_s->dpp_listen_freq);
  628. wpa_drv_cancel_remain_on_channel(wpa_s);
  629. wpa_s->dpp_listen_freq = 0;
  630. wpas_dpp_listen_work_done(wpa_s);
  631. }
  632. void wpas_dpp_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
  633. unsigned int freq)
  634. {
  635. if (!wpa_s->dpp_listen_freq && !wpa_s->dpp_pending_listen_freq)
  636. return;
  637. wpa_printf(MSG_DEBUG,
  638. "DPP: remain-on-channel callback (off_channel_freq=%u dpp_pending_listen_freq=%d roc_waiting_drv_freq=%d freq=%u)",
  639. wpa_s->off_channel_freq, wpa_s->dpp_pending_listen_freq,
  640. wpa_s->roc_waiting_drv_freq, freq);
  641. if (wpa_s->off_channel_freq &&
  642. wpa_s->off_channel_freq == wpa_s->dpp_pending_listen_freq) {
  643. wpa_printf(MSG_DEBUG, "DPP: Listen on %u MHz started", freq);
  644. wpa_s->dpp_pending_listen_freq = 0;
  645. } else {
  646. wpa_printf(MSG_DEBUG,
  647. "DPP: Ignore remain-on-channel callback (off_channel_freq=%u dpp_pending_listen_freq=%d freq=%u)",
  648. wpa_s->off_channel_freq,
  649. wpa_s->dpp_pending_listen_freq, freq);
  650. }
  651. }
  652. void wpas_dpp_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
  653. unsigned int freq)
  654. {
  655. wpas_dpp_listen_work_done(wpa_s);
  656. if (wpa_s->dpp_auth && !wpa_s->dpp_gas_client) {
  657. /* Continue listen with a new remain-on-channel */
  658. wpa_printf(MSG_DEBUG,
  659. "DPP: Continue wait on %u MHz for the ongoing DPP provisioning session",
  660. wpa_s->dpp_auth->curr_freq);
  661. wpas_dpp_listen_start(wpa_s, wpa_s->dpp_auth->curr_freq);
  662. return;
  663. }
  664. if (wpa_s->dpp_listen_freq) {
  665. /* Continue listen with a new remain-on-channel */
  666. wpas_dpp_listen_start(wpa_s, wpa_s->dpp_listen_freq);
  667. }
  668. }
  669. static void wpas_dpp_rx_auth_req(struct wpa_supplicant *wpa_s, const u8 *src,
  670. const u8 *buf, size_t len, unsigned int freq)
  671. {
  672. const u8 *r_bootstrap, *i_bootstrap, *wrapped_data;
  673. u16 r_bootstrap_len, i_bootstrap_len, wrapped_data_len;
  674. struct dpp_bootstrap_info *bi, *own_bi = NULL, *peer_bi = NULL;
  675. struct wpabuf *msg;
  676. wpa_printf(MSG_DEBUG, "DPP: Authentication Request from " MACSTR,
  677. MAC2STR(src));
  678. wrapped_data = dpp_get_attr(buf, len, DPP_ATTR_WRAPPED_DATA,
  679. &wrapped_data_len);
  680. if (!wrapped_data) {
  681. wpa_printf(MSG_DEBUG,
  682. "DPP: Missing required Wrapped data attribute");
  683. return;
  684. }
  685. wpa_hexdump(MSG_MSGDUMP, "DPP: Wrapped data",
  686. wrapped_data, wrapped_data_len);
  687. r_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH,
  688. &r_bootstrap_len);
  689. if (!r_bootstrap || r_bootstrap > wrapped_data ||
  690. r_bootstrap_len != SHA256_MAC_LEN) {
  691. wpa_printf(MSG_DEBUG,
  692. "DPP: Missing or invalid required Responder Bootstrapping Key Hash attribute");
  693. return;
  694. }
  695. wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash",
  696. r_bootstrap, r_bootstrap_len);
  697. i_bootstrap = dpp_get_attr(buf, len, DPP_ATTR_I_BOOTSTRAP_KEY_HASH,
  698. &i_bootstrap_len);
  699. if (!i_bootstrap || i_bootstrap > wrapped_data ||
  700. i_bootstrap_len != SHA256_MAC_LEN) {
  701. wpa_printf(MSG_DEBUG,
  702. "DPP: Missing or invalid required Initiator Bootstrapping Key Hash attribute");
  703. return;
  704. }
  705. wpa_hexdump(MSG_MSGDUMP, "DPP: Initiator Bootstrapping Key Hash",
  706. i_bootstrap, i_bootstrap_len);
  707. /* Try to find own and peer bootstrapping key matches based on the
  708. * received hash values */
  709. dl_list_for_each(bi, &wpa_s->dpp_bootstrap, struct dpp_bootstrap_info,
  710. list) {
  711. if (!own_bi && bi->own &&
  712. os_memcmp(bi->pubkey_hash, r_bootstrap,
  713. SHA256_MAC_LEN) == 0) {
  714. wpa_printf(MSG_DEBUG,
  715. "DPP: Found matching own bootstrapping information");
  716. own_bi = bi;
  717. }
  718. if (!peer_bi && !bi->own &&
  719. os_memcmp(bi->pubkey_hash, i_bootstrap,
  720. SHA256_MAC_LEN) == 0) {
  721. wpa_printf(MSG_DEBUG,
  722. "DPP: Found matching peer bootstrapping information");
  723. peer_bi = bi;
  724. }
  725. if (own_bi && peer_bi)
  726. break;
  727. }
  728. if (!own_bi) {
  729. wpa_printf(MSG_DEBUG,
  730. "DPP: No matching own bootstrapping key found - ignore message");
  731. return;
  732. }
  733. if (wpa_s->dpp_auth) {
  734. wpa_printf(MSG_DEBUG,
  735. "DPP: Already in DPP authentication exchange - ignore new one");
  736. return;
  737. }
  738. wpa_s->dpp_gas_client = 0;
  739. wpa_s->dpp_auth_ok_on_ack = 0;
  740. wpa_s->dpp_auth = dpp_auth_req_rx(wpa_s, wpa_s->dpp_allowed_roles,
  741. wpa_s->dpp_qr_mutual,
  742. peer_bi, own_bi, freq, buf,
  743. wrapped_data, wrapped_data_len);
  744. if (!wpa_s->dpp_auth) {
  745. wpa_printf(MSG_DEBUG, "DPP: No response generated");
  746. return;
  747. }
  748. wpas_dpp_set_testing_options(wpa_s, wpa_s->dpp_auth);
  749. wpas_dpp_set_configurator(wpa_s, wpa_s->dpp_auth,
  750. wpa_s->dpp_configurator_params);
  751. os_memcpy(wpa_s->dpp_auth->peer_mac_addr, src, ETH_ALEN);
  752. msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_RESP,
  753. wpabuf_len(wpa_s->dpp_auth->resp_attr));
  754. if (!msg)
  755. return;
  756. wpabuf_put_buf(msg, wpa_s->dpp_auth->resp_attr);
  757. offchannel_send_action(wpa_s, wpa_s->dpp_auth->curr_freq,
  758. src, wpa_s->own_addr, broadcast,
  759. wpabuf_head(msg), wpabuf_len(msg),
  760. 500, wpas_dpp_tx_status, 0);
  761. wpabuf_free(msg);
  762. }
  763. static void wpas_dpp_start_gas_server(struct wpa_supplicant *wpa_s)
  764. {
  765. /* TODO: stop wait and start ROC */
  766. }
  767. static struct wpa_ssid * wpas_dpp_add_network(struct wpa_supplicant *wpa_s,
  768. struct dpp_authentication *auth)
  769. {
  770. struct wpa_ssid *ssid;
  771. ssid = wpa_config_add_network(wpa_s->conf);
  772. if (!ssid)
  773. return NULL;
  774. wpas_notify_network_added(wpa_s, ssid);
  775. wpa_config_set_network_defaults(ssid);
  776. ssid->disabled = 1;
  777. ssid->ssid = os_malloc(auth->ssid_len);
  778. if (!ssid->ssid)
  779. goto fail;
  780. os_memcpy(ssid->ssid, auth->ssid, auth->ssid_len);
  781. ssid->ssid_len = auth->ssid_len;
  782. if (auth->connector) {
  783. ssid->key_mgmt = WPA_KEY_MGMT_DPP;
  784. ssid->dpp_connector = os_strdup(auth->connector);
  785. if (!ssid->dpp_connector)
  786. goto fail;
  787. }
  788. if (auth->c_sign_key) {
  789. ssid->dpp_csign = os_malloc(wpabuf_len(auth->c_sign_key));
  790. if (!ssid->dpp_csign)
  791. goto fail;
  792. os_memcpy(ssid->dpp_csign, wpabuf_head(auth->c_sign_key),
  793. wpabuf_len(auth->c_sign_key));
  794. ssid->dpp_csign_len = wpabuf_len(auth->c_sign_key);
  795. }
  796. if (auth->net_access_key) {
  797. ssid->dpp_netaccesskey =
  798. os_malloc(wpabuf_len(auth->net_access_key));
  799. if (!ssid->dpp_netaccesskey)
  800. goto fail;
  801. os_memcpy(ssid->dpp_netaccesskey,
  802. wpabuf_head(auth->net_access_key),
  803. wpabuf_len(auth->net_access_key));
  804. ssid->dpp_netaccesskey_len = wpabuf_len(auth->net_access_key);
  805. ssid->dpp_netaccesskey_expiry = auth->net_access_key_expiry;
  806. }
  807. if (!auth->connector) {
  808. ssid->key_mgmt = WPA_KEY_MGMT_PSK;
  809. if (auth->passphrase[0]) {
  810. if (wpa_config_set_quoted(ssid, "psk",
  811. auth->passphrase) < 0)
  812. goto fail;
  813. wpa_config_update_psk(ssid);
  814. ssid->export_keys = 1;
  815. } else {
  816. ssid->psk_set = auth->psk_set;
  817. os_memcpy(ssid->psk, auth->psk, PMK_LEN);
  818. }
  819. }
  820. return ssid;
  821. fail:
  822. wpas_notify_network_removed(wpa_s, ssid);
  823. wpa_config_remove_network(wpa_s->conf, ssid->id);
  824. return NULL;
  825. }
  826. static void wpas_dpp_process_config(struct wpa_supplicant *wpa_s,
  827. struct dpp_authentication *auth)
  828. {
  829. struct wpa_ssid *ssid;
  830. if (wpa_s->conf->dpp_config_processing < 1)
  831. return;
  832. ssid = wpas_dpp_add_network(wpa_s, auth);
  833. if (!ssid)
  834. return;
  835. wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_NETWORK_ID "%d", ssid->id);
  836. if (wpa_s->conf->dpp_config_processing < 2)
  837. return;
  838. wpa_printf(MSG_DEBUG, "DPP: Trying to connect to the new network");
  839. ssid->disabled = 0;
  840. wpa_s->disconnected = 0;
  841. wpa_s->reassociate = 1;
  842. wpa_s->scan_runs = 0;
  843. wpa_s->normal_scans = 0;
  844. wpa_supplicant_cancel_sched_scan(wpa_s);
  845. wpa_supplicant_req_scan(wpa_s, 0, 0);
  846. }
  847. static void wpas_dpp_handle_config_obj(struct wpa_supplicant *wpa_s,
  848. struct dpp_authentication *auth)
  849. {
  850. wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_RECEIVED);
  851. if (auth->ssid_len)
  852. wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONFOBJ_SSID "%s",
  853. wpa_ssid_txt(auth->ssid, auth->ssid_len));
  854. if (auth->connector) {
  855. /* TODO: Save the Connector and consider using a command
  856. * to fetch the value instead of sending an event with
  857. * it. The Connector could end up being larger than what
  858. * most clients are ready to receive as an event
  859. * message. */
  860. wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONNECTOR "%s",
  861. auth->connector);
  862. }
  863. if (auth->c_sign_key) {
  864. char *hex;
  865. size_t hexlen;
  866. hexlen = 2 * wpabuf_len(auth->c_sign_key) + 1;
  867. hex = os_malloc(hexlen);
  868. if (hex) {
  869. wpa_snprintf_hex(hex, hexlen,
  870. wpabuf_head(auth->c_sign_key),
  871. wpabuf_len(auth->c_sign_key));
  872. wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_C_SIGN_KEY "%s",
  873. hex);
  874. os_free(hex);
  875. }
  876. }
  877. if (auth->net_access_key) {
  878. char *hex;
  879. size_t hexlen;
  880. hexlen = 2 * wpabuf_len(auth->net_access_key) + 1;
  881. hex = os_malloc(hexlen);
  882. if (hex) {
  883. wpa_snprintf_hex(hex, hexlen,
  884. wpabuf_head(auth->net_access_key),
  885. wpabuf_len(auth->net_access_key));
  886. if (auth->net_access_key_expiry)
  887. wpa_msg(wpa_s, MSG_INFO,
  888. DPP_EVENT_NET_ACCESS_KEY "%s %lu", hex,
  889. (long unsigned)
  890. auth->net_access_key_expiry);
  891. else
  892. wpa_msg(wpa_s, MSG_INFO,
  893. DPP_EVENT_NET_ACCESS_KEY "%s", hex);
  894. os_free(hex);
  895. }
  896. }
  897. wpas_dpp_process_config(wpa_s, auth);
  898. }
  899. static void wpas_dpp_gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token,
  900. enum gas_query_result result,
  901. const struct wpabuf *adv_proto,
  902. const struct wpabuf *resp, u16 status_code)
  903. {
  904. struct wpa_supplicant *wpa_s = ctx;
  905. const u8 *pos;
  906. struct dpp_authentication *auth = wpa_s->dpp_auth;
  907. if (!auth || !auth->auth_success) {
  908. wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
  909. return;
  910. }
  911. if (!resp || status_code != WLAN_STATUS_SUCCESS) {
  912. wpa_printf(MSG_DEBUG, "DPP: GAS query did not succeed");
  913. goto fail;
  914. }
  915. wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response adv_proto",
  916. adv_proto);
  917. wpa_hexdump_buf(MSG_DEBUG, "DPP: Configuration Response (GAS response)",
  918. resp);
  919. if (wpabuf_len(adv_proto) != 10 ||
  920. !(pos = wpabuf_head(adv_proto)) ||
  921. pos[0] != WLAN_EID_ADV_PROTO ||
  922. pos[1] != 8 ||
  923. pos[3] != WLAN_EID_VENDOR_SPECIFIC ||
  924. pos[4] != 5 ||
  925. WPA_GET_BE24(&pos[5]) != OUI_WFA ||
  926. pos[8] != 0x1a ||
  927. pos[9] != 1) {
  928. wpa_printf(MSG_DEBUG,
  929. "DPP: Not a DPP Advertisement Protocol ID");
  930. goto fail;
  931. }
  932. if (dpp_conf_resp_rx(auth, resp) < 0) {
  933. wpa_printf(MSG_DEBUG, "DPP: Configuration attempt failed");
  934. goto fail;
  935. }
  936. wpas_dpp_handle_config_obj(wpa_s, auth);
  937. dpp_auth_deinit(wpa_s->dpp_auth);
  938. wpa_s->dpp_auth = NULL;
  939. return;
  940. fail:
  941. wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_FAILED);
  942. dpp_auth_deinit(wpa_s->dpp_auth);
  943. wpa_s->dpp_auth = NULL;
  944. }
  945. static void wpas_dpp_start_gas_client(struct wpa_supplicant *wpa_s)
  946. {
  947. struct dpp_authentication *auth = wpa_s->dpp_auth;
  948. struct wpabuf *buf, *conf_req;
  949. char json[100];
  950. int res;
  951. wpa_s->dpp_gas_client = 1;
  952. os_snprintf(json, sizeof(json),
  953. "{\"name\":\"Test\","
  954. "\"wi-fi_tech\":\"infra\","
  955. "\"netRole\":\"%s\"}",
  956. wpa_s->dpp_netrole_ap ? "ap" : "sta");
  957. wpa_printf(MSG_DEBUG, "DPP: GAS Config Attributes: %s", json);
  958. offchannel_send_action_done(wpa_s);
  959. wpas_dpp_listen_stop(wpa_s);
  960. conf_req = dpp_build_conf_req(auth, json);
  961. if (!conf_req) {
  962. wpa_printf(MSG_DEBUG,
  963. "DPP: No configuration request data available");
  964. return;
  965. }
  966. buf = gas_build_initial_req(0, 10 + 2 + wpabuf_len(conf_req));
  967. if (!buf) {
  968. wpabuf_free(conf_req);
  969. return;
  970. }
  971. /* Advertisement Protocol IE */
  972. wpabuf_put_u8(buf, WLAN_EID_ADV_PROTO);
  973. wpabuf_put_u8(buf, 8); /* Length */
  974. wpabuf_put_u8(buf, 0x7f);
  975. wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
  976. wpabuf_put_u8(buf, 5);
  977. wpabuf_put_be24(buf, OUI_WFA);
  978. wpabuf_put_u8(buf, DPP_OUI_TYPE);
  979. wpabuf_put_u8(buf, 0x01);
  980. /* GAS Query */
  981. wpabuf_put_le16(buf, wpabuf_len(conf_req));
  982. wpabuf_put_buf(buf, conf_req);
  983. wpabuf_free(conf_req);
  984. wpa_printf(MSG_DEBUG, "DPP: GAS request to " MACSTR " (freq %u MHz)",
  985. MAC2STR(auth->peer_mac_addr), auth->curr_freq);
  986. res = gas_query_req(wpa_s->gas, auth->peer_mac_addr, auth->curr_freq,
  987. buf, wpas_dpp_gas_resp_cb, wpa_s);
  988. if (res < 0) {
  989. wpa_msg(wpa_s, MSG_DEBUG, "GAS: Failed to send Query Request");
  990. wpabuf_free(buf);
  991. } else {
  992. wpa_printf(MSG_DEBUG,
  993. "DPP: GAS query started with dialog token %u", res);
  994. }
  995. }
  996. static void wpas_dpp_auth_success(struct wpa_supplicant *wpa_s, int initiator)
  997. {
  998. wpa_printf(MSG_DEBUG, "DPP: Authentication succeeded");
  999. wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_AUTH_SUCCESS "init=%d", initiator);
  1000. if (wpa_s->dpp_auth->configurator)
  1001. wpas_dpp_start_gas_server(wpa_s);
  1002. else
  1003. wpas_dpp_start_gas_client(wpa_s);
  1004. }
  1005. static void wpas_dpp_rx_auth_resp(struct wpa_supplicant *wpa_s, const u8 *src,
  1006. const u8 *buf, size_t len)
  1007. {
  1008. struct dpp_authentication *auth = wpa_s->dpp_auth;
  1009. struct wpabuf *msg, *attr;
  1010. wpa_printf(MSG_DEBUG, "DPP: Authentication Response from " MACSTR,
  1011. MAC2STR(src));
  1012. if (!auth) {
  1013. wpa_printf(MSG_DEBUG,
  1014. "DPP: No DPP Authentication in progress - drop");
  1015. return;
  1016. }
  1017. if (!is_zero_ether_addr(auth->peer_mac_addr) &&
  1018. os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
  1019. wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
  1020. MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
  1021. return;
  1022. }
  1023. eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
  1024. attr = dpp_auth_resp_rx(auth, buf, len);
  1025. if (!attr) {
  1026. if (auth->auth_resp_status == DPP_STATUS_RESPONSE_PENDING) {
  1027. wpa_printf(MSG_DEBUG,
  1028. "DPP: Start wait for full response");
  1029. offchannel_send_action_done(wpa_s);
  1030. wpas_dpp_listen_start(wpa_s, auth->curr_freq);
  1031. return;
  1032. }
  1033. wpa_printf(MSG_DEBUG, "DPP: No confirm generated");
  1034. return;
  1035. }
  1036. os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
  1037. msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_CONF, wpabuf_len(attr));
  1038. if (!msg) {
  1039. wpabuf_free(attr);
  1040. return;
  1041. }
  1042. wpabuf_put_buf(msg, attr);
  1043. wpabuf_free(attr);
  1044. offchannel_send_action(wpa_s, auth->curr_freq,
  1045. src, wpa_s->own_addr, broadcast,
  1046. wpabuf_head(msg), wpabuf_len(msg),
  1047. 500, wpas_dpp_tx_status, 0);
  1048. wpabuf_free(msg);
  1049. wpa_s->dpp_auth_ok_on_ack = 1;
  1050. }
  1051. static void wpas_dpp_rx_auth_conf(struct wpa_supplicant *wpa_s, const u8 *src,
  1052. const u8 *buf, size_t len)
  1053. {
  1054. struct dpp_authentication *auth = wpa_s->dpp_auth;
  1055. wpa_printf(MSG_DEBUG, "DPP: Authentication Confirmation from " MACSTR,
  1056. MAC2STR(src));
  1057. if (!auth) {
  1058. wpa_printf(MSG_DEBUG,
  1059. "DPP: No DPP Authentication in progress - drop");
  1060. return;
  1061. }
  1062. if (os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
  1063. wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected "
  1064. MACSTR ") - drop", MAC2STR(auth->peer_mac_addr));
  1065. return;
  1066. }
  1067. if (dpp_auth_conf_rx(auth, buf, len) < 0) {
  1068. wpa_printf(MSG_DEBUG, "DPP: Authentication failed");
  1069. return;
  1070. }
  1071. wpas_dpp_auth_success(wpa_s, 0);
  1072. }
  1073. static void wpas_dpp_rx_peer_disc_resp(struct wpa_supplicant *wpa_s,
  1074. const u8 *src,
  1075. const u8 *buf, size_t len)
  1076. {
  1077. struct wpa_ssid *ssid;
  1078. const u8 *connector, *trans_id;
  1079. u16 connector_len, trans_id_len;
  1080. struct dpp_introduction intro;
  1081. struct rsn_pmksa_cache_entry *entry;
  1082. struct os_time now;
  1083. struct os_reltime rnow;
  1084. os_time_t expiry;
  1085. unsigned int seconds;
  1086. wpa_printf(MSG_DEBUG, "DPP: Peer Discovery Response from " MACSTR,
  1087. MAC2STR(src));
  1088. if (is_zero_ether_addr(wpa_s->dpp_intro_bssid) ||
  1089. os_memcmp(src, wpa_s->dpp_intro_bssid, ETH_ALEN) != 0) {
  1090. wpa_printf(MSG_DEBUG, "DPP: Not waiting for response from "
  1091. MACSTR " - drop", MAC2STR(src));
  1092. return;
  1093. }
  1094. offchannel_send_action_done(wpa_s);
  1095. for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
  1096. if (ssid == wpa_s->dpp_intro_network)
  1097. break;
  1098. }
  1099. if (!ssid || !ssid->dpp_connector || !ssid->dpp_netaccesskey ||
  1100. !ssid->dpp_csign) {
  1101. wpa_printf(MSG_DEBUG,
  1102. "DPP: Profile not found for network introduction");
  1103. return;
  1104. }
  1105. trans_id = dpp_get_attr(buf, len, DPP_ATTR_TRANSACTION_ID,
  1106. &trans_id_len);
  1107. if (!trans_id || trans_id_len != 1) {
  1108. wpa_printf(MSG_DEBUG,
  1109. "DPP: Peer did not include Transaction ID");
  1110. goto fail;
  1111. }
  1112. if (trans_id[0] != TRANSACTION_ID) {
  1113. wpa_printf(MSG_DEBUG,
  1114. "DPP: Ignore frame with unexpected Transaction ID %u",
  1115. trans_id[0]);
  1116. goto fail;
  1117. }
  1118. connector = dpp_get_attr(buf, len, DPP_ATTR_CONNECTOR, &connector_len);
  1119. if (!connector) {
  1120. wpa_printf(MSG_DEBUG,
  1121. "DPP: Peer did not include its Connector");
  1122. return;
  1123. }
  1124. if (dpp_peer_intro(&intro, ssid->dpp_connector,
  1125. ssid->dpp_netaccesskey,
  1126. ssid->dpp_netaccesskey_len,
  1127. ssid->dpp_csign,
  1128. ssid->dpp_csign_len,
  1129. connector, connector_len, &expiry) < 0) {
  1130. wpa_printf(MSG_INFO,
  1131. "DPP: Network Introduction protocol resulted in failure");
  1132. goto fail;
  1133. }
  1134. entry = os_zalloc(sizeof(*entry));
  1135. if (!entry)
  1136. goto fail;
  1137. os_memcpy(entry->aa, src, ETH_ALEN);
  1138. os_memcpy(entry->pmkid, intro.pmkid, PMKID_LEN);
  1139. os_memcpy(entry->pmk, intro.pmk, intro.pmk_len);
  1140. entry->pmk_len = intro.pmk_len;
  1141. entry->akmp = WPA_KEY_MGMT_DPP;
  1142. if (expiry) {
  1143. os_get_time(&now);
  1144. seconds = expiry - now.sec;
  1145. } else {
  1146. seconds = 86400 * 7;
  1147. }
  1148. os_get_reltime(&rnow);
  1149. entry->expiration = rnow.sec + seconds;
  1150. entry->reauth_time = rnow.sec + seconds;
  1151. entry->network_ctx = ssid;
  1152. wpa_sm_pmksa_cache_add_entry(wpa_s->wpa, entry);
  1153. wpa_printf(MSG_DEBUG,
  1154. "DPP: Try connection again after successful network introduction");
  1155. if (wpa_supplicant_fast_associate(wpa_s) != 1) {
  1156. wpa_supplicant_cancel_sched_scan(wpa_s);
  1157. wpa_supplicant_req_scan(wpa_s, 0, 0);
  1158. }
  1159. fail:
  1160. os_memset(&intro, 0, sizeof(intro));
  1161. }
  1162. static void
  1163. wpas_dpp_tx_pkex_status(struct wpa_supplicant *wpa_s,
  1164. unsigned int freq, const u8 *dst,
  1165. const u8 *src, const u8 *bssid,
  1166. const u8 *data, size_t data_len,
  1167. enum offchannel_send_action_result result)
  1168. {
  1169. wpa_printf(MSG_DEBUG, "DPP: TX status: freq=%u dst=" MACSTR
  1170. " result=%s (PKEX)",
  1171. freq, MAC2STR(dst),
  1172. result == OFFCHANNEL_SEND_ACTION_SUCCESS ? "SUCCESS" :
  1173. (result == OFFCHANNEL_SEND_ACTION_NO_ACK ? "no-ACK" :
  1174. "FAILED"));
  1175. /* TODO: Time out wait for response more quickly in error cases? */
  1176. }
  1177. static void
  1178. wpas_dpp_rx_pkex_exchange_req(struct wpa_supplicant *wpa_s, const u8 *src,
  1179. const u8 *buf, size_t len, unsigned int freq)
  1180. {
  1181. struct wpabuf *msg;
  1182. unsigned int wait_time;
  1183. wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Request from " MACSTR,
  1184. MAC2STR(src));
  1185. /* TODO: Support multiple PKEX codes by iterating over all the enabled
  1186. * values here */
  1187. if (!wpa_s->dpp_pkex_code || !wpa_s->dpp_pkex_bi) {
  1188. wpa_printf(MSG_DEBUG,
  1189. "DPP: No PKEX code configured - ignore request");
  1190. return;
  1191. }
  1192. if (wpa_s->dpp_pkex) {
  1193. /* TODO: Support parallel operations */
  1194. wpa_printf(MSG_DEBUG,
  1195. "DPP: Already in PKEX session - ignore new request");
  1196. return;
  1197. }
  1198. wpa_s->dpp_pkex = dpp_pkex_rx_exchange_req(wpa_s->dpp_pkex_bi,
  1199. wpa_s->own_addr, src,
  1200. wpa_s->dpp_pkex_identifier,
  1201. wpa_s->dpp_pkex_code,
  1202. buf, len);
  1203. if (!wpa_s->dpp_pkex) {
  1204. wpa_printf(MSG_DEBUG,
  1205. "DPP: Failed to process the request - ignore it");
  1206. return;
  1207. }
  1208. msg = wpa_s->dpp_pkex->exchange_resp;
  1209. wait_time = wpa_s->max_remain_on_chan;
  1210. if (wait_time > 2000)
  1211. wait_time = 2000;
  1212. offchannel_send_action(wpa_s, freq, src, wpa_s->own_addr,
  1213. broadcast,
  1214. wpabuf_head(msg), wpabuf_len(msg),
  1215. wait_time, wpas_dpp_tx_pkex_status, 0);
  1216. }
  1217. static void
  1218. wpas_dpp_rx_pkex_exchange_resp(struct wpa_supplicant *wpa_s, const u8 *src,
  1219. const u8 *buf, size_t len, unsigned int freq)
  1220. {
  1221. struct wpabuf *msg;
  1222. unsigned int wait_time;
  1223. wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Response from " MACSTR,
  1224. MAC2STR(src));
  1225. /* TODO: Support multiple PKEX codes by iterating over all the enabled
  1226. * values here */
  1227. if (!wpa_s->dpp_pkex || !wpa_s->dpp_pkex->initiator ||
  1228. wpa_s->dpp_pkex->exchange_done) {
  1229. wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
  1230. return;
  1231. }
  1232. os_memcpy(wpa_s->dpp_pkex->peer_mac, src, ETH_ALEN);
  1233. msg = dpp_pkex_rx_exchange_resp(wpa_s->dpp_pkex, buf, len);
  1234. if (!msg) {
  1235. wpa_printf(MSG_DEBUG, "DPP: Failed to process the response");
  1236. return;
  1237. }
  1238. wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Request to " MACSTR,
  1239. MAC2STR(src));
  1240. wait_time = wpa_s->max_remain_on_chan;
  1241. if (wait_time > 2000)
  1242. wait_time = 2000;
  1243. offchannel_send_action(wpa_s, freq, src, wpa_s->own_addr,
  1244. broadcast,
  1245. wpabuf_head(msg), wpabuf_len(msg),
  1246. wait_time, wpas_dpp_tx_pkex_status, 0);
  1247. wpabuf_free(msg);
  1248. }
  1249. static void
  1250. wpas_dpp_rx_pkex_commit_reveal_req(struct wpa_supplicant *wpa_s, const u8 *src,
  1251. const u8 *buf, size_t len, unsigned int freq)
  1252. {
  1253. struct wpabuf *msg;
  1254. unsigned int wait_time;
  1255. struct dpp_pkex *pkex = wpa_s->dpp_pkex;
  1256. struct dpp_bootstrap_info *bi;
  1257. wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Request from " MACSTR,
  1258. MAC2STR(src));
  1259. if (!pkex || pkex->initiator || !pkex->exchange_done) {
  1260. wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
  1261. return;
  1262. }
  1263. msg = dpp_pkex_rx_commit_reveal_req(pkex, buf, len);
  1264. if (!msg) {
  1265. wpa_printf(MSG_DEBUG, "DPP: Failed to process the request");
  1266. return;
  1267. }
  1268. wpa_printf(MSG_DEBUG, "DPP: Send PKEX Commit-Reveal Response to "
  1269. MACSTR, MAC2STR(src));
  1270. wait_time = wpa_s->max_remain_on_chan;
  1271. if (wait_time > 2000)
  1272. wait_time = 2000;
  1273. offchannel_send_action(wpa_s, freq, src, wpa_s->own_addr,
  1274. broadcast,
  1275. wpabuf_head(msg), wpabuf_len(msg),
  1276. wait_time, wpas_dpp_tx_pkex_status, 0);
  1277. wpabuf_free(msg);
  1278. bi = os_zalloc(sizeof(*bi));
  1279. if (!bi)
  1280. return;
  1281. bi->id = wpas_dpp_next_id(wpa_s);
  1282. bi->type = DPP_BOOTSTRAP_PKEX;
  1283. os_memcpy(bi->mac_addr, src, ETH_ALEN);
  1284. bi->num_freq = 1;
  1285. bi->freq[0] = freq;
  1286. bi->curve = pkex->own_bi->curve;
  1287. bi->pubkey = pkex->peer_bootstrap_key;
  1288. pkex->peer_bootstrap_key = NULL;
  1289. dpp_pkex_free(pkex);
  1290. wpa_s->dpp_pkex = NULL;
  1291. if (dpp_bootstrap_key_hash(bi) < 0) {
  1292. dpp_bootstrap_info_free(bi);
  1293. return;
  1294. }
  1295. dl_list_add(&wpa_s->dpp_bootstrap, &bi->list);
  1296. }
  1297. static void
  1298. wpas_dpp_rx_pkex_commit_reveal_resp(struct wpa_supplicant *wpa_s, const u8 *src,
  1299. const u8 *buf, size_t len,
  1300. unsigned int freq)
  1301. {
  1302. int res;
  1303. struct dpp_bootstrap_info *bi, *own_bi;
  1304. struct dpp_pkex *pkex = wpa_s->dpp_pkex;
  1305. char cmd[500];
  1306. wpa_printf(MSG_DEBUG, "DPP: PKEX Commit-Reveal Response from " MACSTR,
  1307. MAC2STR(src));
  1308. if (!pkex || !pkex->initiator || !pkex->exchange_done) {
  1309. wpa_printf(MSG_DEBUG, "DPP: No matching PKEX session");
  1310. return;
  1311. }
  1312. res = dpp_pkex_rx_commit_reveal_resp(pkex, buf, len);
  1313. if (res < 0) {
  1314. wpa_printf(MSG_DEBUG, "DPP: Failed to process the response");
  1315. return;
  1316. }
  1317. own_bi = pkex->own_bi;
  1318. bi = os_zalloc(sizeof(*bi));
  1319. if (!bi)
  1320. return;
  1321. bi->id = wpas_dpp_next_id(wpa_s);
  1322. bi->type = DPP_BOOTSTRAP_PKEX;
  1323. os_memcpy(bi->mac_addr, src, ETH_ALEN);
  1324. bi->num_freq = 1;
  1325. bi->freq[0] = freq;
  1326. bi->curve = own_bi->curve;
  1327. bi->pubkey = pkex->peer_bootstrap_key;
  1328. pkex->peer_bootstrap_key = NULL;
  1329. dpp_pkex_free(pkex);
  1330. wpa_s->dpp_pkex = NULL;
  1331. if (dpp_bootstrap_key_hash(bi) < 0) {
  1332. dpp_bootstrap_info_free(bi);
  1333. return;
  1334. }
  1335. dl_list_add(&wpa_s->dpp_bootstrap, &bi->list);
  1336. os_snprintf(cmd, sizeof(cmd), " peer=%u %s",
  1337. bi->id,
  1338. wpa_s->dpp_pkex_auth_cmd ? wpa_s->dpp_pkex_auth_cmd : "");
  1339. wpa_printf(MSG_DEBUG,
  1340. "DPP: Start authentication after PKEX with parameters: %s",
  1341. cmd);
  1342. if (wpas_dpp_auth_init(wpa_s, cmd) < 0) {
  1343. wpa_printf(MSG_DEBUG,
  1344. "DPP: Authentication initialization failed");
  1345. return;
  1346. }
  1347. }
  1348. void wpas_dpp_rx_action(struct wpa_supplicant *wpa_s, const u8 *src,
  1349. const u8 *buf, size_t len, unsigned int freq)
  1350. {
  1351. u8 crypto_suite;
  1352. enum dpp_public_action_frame_type type;
  1353. if (len < 2)
  1354. return;
  1355. crypto_suite = *buf++;
  1356. type = *buf++;
  1357. len -= 2;
  1358. wpa_printf(MSG_DEBUG,
  1359. "DPP: Received DPP Public Action frame crypto suite %u type %d from "
  1360. MACSTR " freq=%u",
  1361. crypto_suite, type, MAC2STR(src), freq);
  1362. if (crypto_suite != 1) {
  1363. wpa_printf(MSG_DEBUG, "DPP: Unsupported crypto suite %u",
  1364. crypto_suite);
  1365. return;
  1366. }
  1367. wpa_hexdump(MSG_MSGDUMP, "DPP: Received message attributes", buf, len);
  1368. if (dpp_check_attrs(buf, len) < 0)
  1369. return;
  1370. switch (type) {
  1371. case DPP_PA_AUTHENTICATION_REQ:
  1372. wpas_dpp_rx_auth_req(wpa_s, src, buf, len, freq);
  1373. break;
  1374. case DPP_PA_AUTHENTICATION_RESP:
  1375. wpas_dpp_rx_auth_resp(wpa_s, src, buf, len);
  1376. break;
  1377. case DPP_PA_AUTHENTICATION_CONF:
  1378. wpas_dpp_rx_auth_conf(wpa_s, src, buf, len);
  1379. break;
  1380. case DPP_PA_PEER_DISCOVERY_RESP:
  1381. wpas_dpp_rx_peer_disc_resp(wpa_s, src, buf, len);
  1382. break;
  1383. case DPP_PA_PKEX_EXCHANGE_REQ:
  1384. wpas_dpp_rx_pkex_exchange_req(wpa_s, src, buf, len, freq);
  1385. break;
  1386. case DPP_PA_PKEX_EXCHANGE_RESP:
  1387. wpas_dpp_rx_pkex_exchange_resp(wpa_s, src, buf, len, freq);
  1388. break;
  1389. case DPP_PA_PKEX_COMMIT_REVEAL_REQ:
  1390. wpas_dpp_rx_pkex_commit_reveal_req(wpa_s, src, buf, len, freq);
  1391. break;
  1392. case DPP_PA_PKEX_COMMIT_REVEAL_RESP:
  1393. wpas_dpp_rx_pkex_commit_reveal_resp(wpa_s, src, buf, len, freq);
  1394. break;
  1395. default:
  1396. wpa_printf(MSG_DEBUG,
  1397. "DPP: Ignored unsupported frame subtype %d", type);
  1398. break;
  1399. }
  1400. }
  1401. static struct wpabuf *
  1402. wpas_dpp_gas_req_handler(void *ctx, const u8 *sa, const u8 *query,
  1403. size_t query_len)
  1404. {
  1405. struct wpa_supplicant *wpa_s = ctx;
  1406. struct dpp_authentication *auth = wpa_s->dpp_auth;
  1407. struct wpabuf *resp;
  1408. wpa_printf(MSG_DEBUG, "DPP: GAS request from " MACSTR,
  1409. MAC2STR(sa));
  1410. if (!auth || !auth->auth_success ||
  1411. os_memcmp(sa, auth->peer_mac_addr, ETH_ALEN) != 0) {
  1412. wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
  1413. return NULL;
  1414. }
  1415. wpa_hexdump(MSG_DEBUG,
  1416. "DPP: Received Configuration Request (GAS Query Request)",
  1417. query, query_len);
  1418. resp = dpp_conf_req_rx(auth, query, query_len);
  1419. if (!resp)
  1420. wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_FAILED);
  1421. return resp;
  1422. }
  1423. static void
  1424. wpas_dpp_gas_status_handler(void *ctx, struct wpabuf *resp, int ok)
  1425. {
  1426. struct wpa_supplicant *wpa_s = ctx;
  1427. struct dpp_authentication *auth = wpa_s->dpp_auth;
  1428. if (!auth) {
  1429. wpabuf_free(resp);
  1430. return;
  1431. }
  1432. wpa_printf(MSG_DEBUG, "DPP: Configuration exchange completed (ok=%d)",
  1433. ok);
  1434. eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
  1435. offchannel_send_action_done(wpa_s);
  1436. wpas_dpp_listen_stop(wpa_s);
  1437. if (ok)
  1438. wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_SENT);
  1439. else
  1440. wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_FAILED);
  1441. dpp_auth_deinit(wpa_s->dpp_auth);
  1442. wpa_s->dpp_auth = NULL;
  1443. wpabuf_free(resp);
  1444. }
  1445. static unsigned int wpas_dpp_next_configurator_id(struct wpa_supplicant *wpa_s)
  1446. {
  1447. struct dpp_configurator *conf;
  1448. unsigned int max_id = 0;
  1449. dl_list_for_each(conf, &wpa_s->dpp_configurator,
  1450. struct dpp_configurator, list) {
  1451. if (conf->id > max_id)
  1452. max_id = conf->id;
  1453. }
  1454. return max_id + 1;
  1455. }
  1456. int wpas_dpp_configurator_add(struct wpa_supplicant *wpa_s, const char *cmd)
  1457. {
  1458. char *curve = NULL;
  1459. char *key = NULL;
  1460. u8 *privkey = NULL;
  1461. size_t privkey_len = 0;
  1462. int ret = -1;
  1463. struct dpp_configurator *conf = NULL;
  1464. curve = get_param(cmd, " curve=");
  1465. key = get_param(cmd, " key=");
  1466. if (key) {
  1467. privkey_len = os_strlen(key) / 2;
  1468. privkey = os_malloc(privkey_len);
  1469. if (!privkey ||
  1470. hexstr2bin(key, privkey, privkey_len) < 0)
  1471. goto fail;
  1472. }
  1473. conf = dpp_keygen_configurator(curve, privkey, privkey_len);
  1474. if (!conf)
  1475. goto fail;
  1476. conf->id = wpas_dpp_next_configurator_id(wpa_s);
  1477. dl_list_add(&wpa_s->dpp_configurator, &conf->list);
  1478. ret = conf->id;
  1479. conf = NULL;
  1480. fail:
  1481. os_free(curve);
  1482. str_clear_free(key);
  1483. bin_clear_free(privkey, privkey_len);
  1484. dpp_configurator_free(conf);
  1485. return ret;
  1486. }
  1487. static int dpp_configurator_del(struct wpa_supplicant *wpa_s, unsigned int id)
  1488. {
  1489. struct dpp_configurator *conf, *tmp;
  1490. int found = 0;
  1491. dl_list_for_each_safe(conf, tmp, &wpa_s->dpp_configurator,
  1492. struct dpp_configurator, list) {
  1493. if (id && conf->id != id)
  1494. continue;
  1495. found = 1;
  1496. dl_list_del(&conf->list);
  1497. dpp_configurator_free(conf);
  1498. }
  1499. if (id == 0)
  1500. return 0; /* flush succeeds regardless of entries found */
  1501. return found ? 0 : -1;
  1502. }
  1503. int wpas_dpp_configurator_remove(struct wpa_supplicant *wpa_s, const char *id)
  1504. {
  1505. unsigned int id_val;
  1506. if (os_strcmp(id, "*") == 0) {
  1507. id_val = 0;
  1508. } else {
  1509. id_val = atoi(id);
  1510. if (id_val == 0)
  1511. return -1;
  1512. }
  1513. return dpp_configurator_del(wpa_s, id_val);
  1514. }
  1515. int wpas_dpp_configurator_sign(struct wpa_supplicant *wpa_s, const char *cmd)
  1516. {
  1517. struct dpp_authentication *auth;
  1518. int ret = -1;
  1519. char *curve = NULL;
  1520. auth = os_zalloc(sizeof(*auth));
  1521. if (!auth)
  1522. return -1;
  1523. curve = get_param(cmd, " curve=");
  1524. wpas_dpp_set_configurator(wpa_s, auth, cmd);
  1525. if (dpp_configurator_own_config(auth, curve) == 0) {
  1526. wpas_dpp_handle_config_obj(wpa_s, auth);
  1527. ret = 0;
  1528. }
  1529. dpp_auth_deinit(auth);
  1530. os_free(curve);
  1531. return ret;
  1532. }
  1533. static void
  1534. wpas_dpp_tx_introduction_status(struct wpa_supplicant *wpa_s,
  1535. unsigned int freq, const u8 *dst,
  1536. const u8 *src, const u8 *bssid,
  1537. const u8 *data, size_t data_len,
  1538. enum offchannel_send_action_result result)
  1539. {
  1540. wpa_printf(MSG_DEBUG, "DPP: TX status: freq=%u dst=" MACSTR
  1541. " result=%s (DPP Peer Discovery Request)",
  1542. freq, MAC2STR(dst),
  1543. result == OFFCHANNEL_SEND_ACTION_SUCCESS ? "SUCCESS" :
  1544. (result == OFFCHANNEL_SEND_ACTION_NO_ACK ? "no-ACK" :
  1545. "FAILED"));
  1546. /* TODO: Time out wait for response more quickly in error cases? */
  1547. }
  1548. int wpas_dpp_check_connect(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
  1549. struct wpa_bss *bss)
  1550. {
  1551. struct os_time now;
  1552. struct wpabuf *msg;
  1553. unsigned int wait_time;
  1554. if (!(ssid->key_mgmt & WPA_KEY_MGMT_DPP) || !bss)
  1555. return 0; /* Not using DPP AKM - continue */
  1556. if (wpa_sm_pmksa_exists(wpa_s->wpa, bss->bssid, ssid))
  1557. return 0; /* PMKSA exists for DPP AKM - continue */
  1558. if (!ssid->dpp_connector || !ssid->dpp_netaccesskey ||
  1559. !ssid->dpp_csign) {
  1560. wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_MISSING_CONNECTOR
  1561. "missing %s",
  1562. !ssid->dpp_connector ? "Connector" :
  1563. (!ssid->dpp_netaccesskey ? "netAccessKey" :
  1564. "C-sign-key"));
  1565. return -1;
  1566. }
  1567. os_get_time(&now);
  1568. if (ssid->dpp_netaccesskey_expiry &&
  1569. ssid->dpp_netaccesskey_expiry < now.sec) {
  1570. wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_MISSING_CONNECTOR
  1571. "netAccessKey expired");
  1572. return -1;
  1573. }
  1574. wpa_printf(MSG_DEBUG,
  1575. "DPP: Starting network introduction protocol to derive PMKSA for "
  1576. MACSTR, MAC2STR(bss->bssid));
  1577. msg = dpp_alloc_msg(DPP_PA_PEER_DISCOVERY_REQ,
  1578. 5 + 4 + os_strlen(ssid->dpp_connector));
  1579. if (!msg)
  1580. return -1;
  1581. /* Transaction ID */
  1582. wpabuf_put_le16(msg, DPP_ATTR_TRANSACTION_ID);
  1583. wpabuf_put_le16(msg, 1);
  1584. wpabuf_put_u8(msg, TRANSACTION_ID);
  1585. /* DPP Connector */
  1586. wpabuf_put_le16(msg, DPP_ATTR_CONNECTOR);
  1587. wpabuf_put_le16(msg, os_strlen(ssid->dpp_connector));
  1588. wpabuf_put_str(msg, ssid->dpp_connector);
  1589. /* TODO: Timeout on AP response */
  1590. wait_time = wpa_s->max_remain_on_chan;
  1591. if (wait_time > 2000)
  1592. wait_time = 2000;
  1593. offchannel_send_action(wpa_s, bss->freq, bss->bssid, wpa_s->own_addr,
  1594. broadcast,
  1595. wpabuf_head(msg), wpabuf_len(msg),
  1596. wait_time, wpas_dpp_tx_introduction_status, 0);
  1597. wpabuf_free(msg);
  1598. /* Request this connection attempt to terminate - new one will be
  1599. * started when network introduction protocol completes */
  1600. os_memcpy(wpa_s->dpp_intro_bssid, bss->bssid, ETH_ALEN);
  1601. wpa_s->dpp_intro_network = ssid;
  1602. return 1;
  1603. }
  1604. int wpas_dpp_pkex_add(struct wpa_supplicant *wpa_s, const char *cmd)
  1605. {
  1606. struct dpp_bootstrap_info *own_bi;
  1607. const char *pos, *end;
  1608. unsigned int wait_time;
  1609. pos = os_strstr(cmd, " own=");
  1610. if (!pos)
  1611. return -1;
  1612. pos += 5;
  1613. own_bi = dpp_bootstrap_get_id(wpa_s, atoi(pos));
  1614. if (!own_bi) {
  1615. wpa_printf(MSG_DEBUG,
  1616. "DPP: Identified bootstrap info not found");
  1617. return -1;
  1618. }
  1619. if (own_bi->type != DPP_BOOTSTRAP_PKEX) {
  1620. wpa_printf(MSG_DEBUG,
  1621. "DPP: Identified bootstrap info not for PKEX");
  1622. return -1;
  1623. }
  1624. wpa_s->dpp_pkex_bi = own_bi;
  1625. os_free(wpa_s->dpp_pkex_identifier);
  1626. wpa_s->dpp_pkex_identifier = NULL;
  1627. pos = os_strstr(cmd, " identifier=");
  1628. if (pos) {
  1629. pos += 12;
  1630. end = os_strchr(pos, ' ');
  1631. if (!end)
  1632. return -1;
  1633. wpa_s->dpp_pkex_identifier = os_malloc(end - pos + 1);
  1634. if (!wpa_s->dpp_pkex_identifier)
  1635. return -1;
  1636. os_memcpy(wpa_s->dpp_pkex_identifier, pos, end - pos);
  1637. wpa_s->dpp_pkex_identifier[end - pos] = '\0';
  1638. }
  1639. pos = os_strstr(cmd, " code=");
  1640. if (!pos)
  1641. return -1;
  1642. os_free(wpa_s->dpp_pkex_code);
  1643. wpa_s->dpp_pkex_code = os_strdup(pos + 6);
  1644. if (!wpa_s->dpp_pkex_code)
  1645. return -1;
  1646. if (os_strstr(cmd, " init=1")) {
  1647. struct wpabuf *msg;
  1648. wpa_printf(MSG_DEBUG, "DPP: Initiating PKEX");
  1649. dpp_pkex_free(wpa_s->dpp_pkex);
  1650. wpa_s->dpp_pkex = dpp_pkex_init(own_bi, wpa_s->own_addr,
  1651. wpa_s->dpp_pkex_identifier,
  1652. wpa_s->dpp_pkex_code);
  1653. if (!wpa_s->dpp_pkex)
  1654. return -1;
  1655. msg = wpa_s->dpp_pkex->exchange_req;
  1656. wait_time = wpa_s->max_remain_on_chan;
  1657. if (wait_time > 2000)
  1658. wait_time = 2000;
  1659. /* TODO: Which channel to use? */
  1660. offchannel_send_action(wpa_s, 2437, broadcast, wpa_s->own_addr,
  1661. broadcast,
  1662. wpabuf_head(msg), wpabuf_len(msg),
  1663. wait_time, wpas_dpp_tx_pkex_status, 0);
  1664. }
  1665. /* TODO: Support multiple PKEX info entries */
  1666. os_free(wpa_s->dpp_pkex_auth_cmd);
  1667. wpa_s->dpp_pkex_auth_cmd = os_strdup(cmd);
  1668. return 1;
  1669. }
  1670. int wpas_dpp_pkex_remove(struct wpa_supplicant *wpa_s, const char *id)
  1671. {
  1672. unsigned int id_val;
  1673. if (os_strcmp(id, "*") == 0) {
  1674. id_val = 0;
  1675. } else {
  1676. id_val = atoi(id);
  1677. if (id_val == 0)
  1678. return -1;
  1679. }
  1680. if ((id_val != 0 && id_val != 1) || !wpa_s->dpp_pkex_code)
  1681. return -1;
  1682. /* TODO: Support multiple PKEX entries */
  1683. os_free(wpa_s->dpp_pkex_code);
  1684. wpa_s->dpp_pkex_code = NULL;
  1685. os_free(wpa_s->dpp_pkex_identifier);
  1686. wpa_s->dpp_pkex_identifier = NULL;
  1687. os_free(wpa_s->dpp_pkex_auth_cmd);
  1688. wpa_s->dpp_pkex_auth_cmd = NULL;
  1689. wpa_s->dpp_pkex_bi = NULL;
  1690. /* TODO: Remove dpp_pkex only if it is for the identified PKEX code */
  1691. dpp_pkex_free(wpa_s->dpp_pkex);
  1692. wpa_s->dpp_pkex = NULL;
  1693. return 0;
  1694. }
  1695. int wpas_dpp_init(struct wpa_supplicant *wpa_s)
  1696. {
  1697. u8 adv_proto_id[7];
  1698. adv_proto_id[0] = WLAN_EID_VENDOR_SPECIFIC;
  1699. adv_proto_id[1] = 5;
  1700. WPA_PUT_BE24(&adv_proto_id[2], OUI_WFA);
  1701. adv_proto_id[5] = DPP_OUI_TYPE;
  1702. adv_proto_id[6] = 0x01;
  1703. if (gas_server_register(wpa_s->gas_server, adv_proto_id,
  1704. sizeof(adv_proto_id), wpas_dpp_gas_req_handler,
  1705. wpas_dpp_gas_status_handler, wpa_s) < 0)
  1706. return -1;
  1707. dl_list_init(&wpa_s->dpp_bootstrap);
  1708. dl_list_init(&wpa_s->dpp_configurator);
  1709. wpa_s->dpp_init_done = 1;
  1710. return 0;
  1711. }
  1712. void wpas_dpp_deinit(struct wpa_supplicant *wpa_s)
  1713. {
  1714. #ifdef CONFIG_TESTING_OPTIONS
  1715. os_free(wpa_s->dpp_config_obj_override);
  1716. wpa_s->dpp_config_obj_override = NULL;
  1717. os_free(wpa_s->dpp_discovery_override);
  1718. wpa_s->dpp_discovery_override = NULL;
  1719. os_free(wpa_s->dpp_groups_override);
  1720. wpa_s->dpp_groups_override = NULL;
  1721. wpa_s->dpp_ignore_netaccesskey_mismatch = 0;
  1722. #endif /* CONFIG_TESTING_OPTIONS */
  1723. if (!wpa_s->dpp_init_done)
  1724. return;
  1725. eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
  1726. offchannel_send_action_done(wpa_s);
  1727. wpas_dpp_listen_stop(wpa_s);
  1728. dpp_bootstrap_del(wpa_s, 0);
  1729. dpp_configurator_del(wpa_s, 0);
  1730. dpp_auth_deinit(wpa_s->dpp_auth);
  1731. wpa_s->dpp_auth = NULL;
  1732. wpas_dpp_pkex_remove(wpa_s, "*");
  1733. wpa_s->dpp_pkex = NULL;
  1734. os_memset(wpa_s->dpp_intro_bssid, 0, ETH_ALEN);
  1735. os_free(wpa_s->dpp_configurator_params);
  1736. wpa_s->dpp_configurator_params = NULL;
  1737. }