wps_validate.c 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977
  1. /*
  2. * Wi-Fi Protected Setup - Strict protocol validation routines
  3. * Copyright (c) 2010, Atheros Communications, 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 "wps_i.h"
  11. #include "wps.h"
  12. #ifndef WPS_STRICT_ALL
  13. #define WPS_STRICT_WPS2
  14. #endif /* WPS_STRICT_ALL */
  15. static int wps_validate_version(const u8 *version, int mandatory)
  16. {
  17. if (version == NULL) {
  18. if (mandatory) {
  19. wpa_printf(MSG_INFO, "WPS-STRICT: Version attribute "
  20. "missing");
  21. return -1;
  22. }
  23. return 0;
  24. }
  25. if (*version != 0x10) {
  26. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Version attribute "
  27. "value 0x%x", *version);
  28. return -1;
  29. }
  30. return 0;
  31. }
  32. static int wps_validate_version2(const u8 *version2, int mandatory)
  33. {
  34. if (version2 == NULL) {
  35. if (mandatory) {
  36. wpa_printf(MSG_INFO, "WPS-STRICT: Version2 attribute "
  37. "missing");
  38. return -1;
  39. }
  40. return 0;
  41. }
  42. if (*version2 < 0x20) {
  43. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Version2 attribute "
  44. "value 0x%x", *version2);
  45. return -1;
  46. }
  47. return 0;
  48. }
  49. static int wps_validate_request_type(const u8 *request_type, int mandatory)
  50. {
  51. if (request_type == NULL) {
  52. if (mandatory) {
  53. wpa_printf(MSG_INFO, "WPS-STRICT: Request Type "
  54. "attribute missing");
  55. return -1;
  56. }
  57. return 0;
  58. }
  59. if (*request_type > 0x03) {
  60. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Request Type "
  61. "attribute value 0x%x", *request_type);
  62. return -1;
  63. }
  64. return 0;
  65. }
  66. static int wps_validate_response_type(const u8 *response_type, int mandatory)
  67. {
  68. if (response_type == NULL) {
  69. if (mandatory) {
  70. wpa_printf(MSG_INFO, "WPS-STRICT: Response Type "
  71. "attribute missing");
  72. return -1;
  73. }
  74. return 0;
  75. }
  76. if (*response_type > 0x03) {
  77. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Response Type "
  78. "attribute value 0x%x", *response_type);
  79. return -1;
  80. }
  81. return 0;
  82. }
  83. static int valid_config_methods(u16 val, int wps2)
  84. {
  85. if (wps2) {
  86. if ((val & 0x6000) && !(val & WPS_CONFIG_DISPLAY)) {
  87. wpa_printf(MSG_INFO, "WPS-STRICT: Physical/Virtual "
  88. "Display flag without old Display flag "
  89. "set");
  90. return 0;
  91. }
  92. if (!(val & 0x6000) && (val & WPS_CONFIG_DISPLAY)) {
  93. wpa_printf(MSG_INFO, "WPS-STRICT: Display flag "
  94. "without Physical/Virtual Display flag");
  95. return 0;
  96. }
  97. if ((val & 0x0600) && !(val & WPS_CONFIG_PUSHBUTTON)) {
  98. wpa_printf(MSG_INFO, "WPS-STRICT: Physical/Virtual "
  99. "PushButton flag without old PushButton "
  100. "flag set");
  101. return 0;
  102. }
  103. if (!(val & 0x0600) && (val & WPS_CONFIG_PUSHBUTTON)) {
  104. wpa_printf(MSG_INFO, "WPS-STRICT: PushButton flag "
  105. "without Physical/Virtual PushButton flag");
  106. return 0;
  107. }
  108. }
  109. return 1;
  110. }
  111. static int wps_validate_config_methods(const u8 *config_methods, int wps2,
  112. int mandatory)
  113. {
  114. u16 val;
  115. if (config_methods == NULL) {
  116. if (mandatory) {
  117. wpa_printf(MSG_INFO, "WPS-STRICT: Configuration "
  118. "Methods attribute missing");
  119. return -1;
  120. }
  121. return 0;
  122. }
  123. val = WPA_GET_BE16(config_methods);
  124. if (!valid_config_methods(val, wps2)) {
  125. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Configuration "
  126. "Methods attribute value 0x%04x", val);
  127. return -1;
  128. }
  129. return 0;
  130. }
  131. static int wps_validate_ap_config_methods(const u8 *config_methods, int wps2,
  132. int mandatory)
  133. {
  134. u16 val;
  135. if (wps_validate_config_methods(config_methods, wps2, mandatory) < 0)
  136. return -1;
  137. if (config_methods == NULL)
  138. return 0;
  139. val = WPA_GET_BE16(config_methods);
  140. if (val & WPS_CONFIG_PUSHBUTTON) {
  141. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Configuration "
  142. "Methods attribute value 0x%04x in AP info "
  143. "(PushButton not allowed for registering new ER)",
  144. val);
  145. return -1;
  146. }
  147. return 0;
  148. }
  149. static int wps_validate_uuid_e(const u8 *uuid_e, int mandatory)
  150. {
  151. if (uuid_e == NULL) {
  152. if (mandatory) {
  153. wpa_printf(MSG_INFO, "WPS-STRICT: UUID-E "
  154. "attribute missing");
  155. return -1;
  156. }
  157. return 0;
  158. }
  159. return 0;
  160. }
  161. static int wps_validate_uuid_r(const u8 *uuid_r, int mandatory)
  162. {
  163. if (uuid_r == NULL) {
  164. if (mandatory) {
  165. wpa_printf(MSG_INFO, "WPS-STRICT: UUID-R "
  166. "attribute missing");
  167. return -1;
  168. }
  169. return 0;
  170. }
  171. return 0;
  172. }
  173. static int wps_validate_primary_dev_type(const u8 *primary_dev_type,
  174. int mandatory)
  175. {
  176. if (primary_dev_type == NULL) {
  177. if (mandatory) {
  178. wpa_printf(MSG_INFO, "WPS-STRICT: Primary Device Type "
  179. "attribute missing");
  180. return -1;
  181. }
  182. return 0;
  183. }
  184. return 0;
  185. }
  186. static int wps_validate_rf_bands(const u8 *rf_bands, int mandatory)
  187. {
  188. if (rf_bands == NULL) {
  189. if (mandatory) {
  190. wpa_printf(MSG_INFO, "WPS-STRICT: RF Bands "
  191. "attribute missing");
  192. return -1;
  193. }
  194. return 0;
  195. }
  196. if (*rf_bands != WPS_RF_24GHZ && *rf_bands != WPS_RF_50GHZ &&
  197. *rf_bands != WPS_RF_60GHZ &&
  198. *rf_bands != (WPS_RF_24GHZ | WPS_RF_50GHZ | WPS_RF_60GHZ) &&
  199. *rf_bands != (WPS_RF_24GHZ | WPS_RF_50GHZ)) {
  200. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Rf Bands "
  201. "attribute value 0x%x", *rf_bands);
  202. return -1;
  203. }
  204. return 0;
  205. }
  206. static int wps_validate_assoc_state(const u8 *assoc_state, int mandatory)
  207. {
  208. u16 val;
  209. if (assoc_state == NULL) {
  210. if (mandatory) {
  211. wpa_printf(MSG_INFO, "WPS-STRICT: Association State "
  212. "attribute missing");
  213. return -1;
  214. }
  215. return 0;
  216. }
  217. val = WPA_GET_BE16(assoc_state);
  218. if (val > 4) {
  219. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Association State "
  220. "attribute value 0x%04x", val);
  221. return -1;
  222. }
  223. return 0;
  224. }
  225. static int wps_validate_config_error(const u8 *config_error, int mandatory)
  226. {
  227. u16 val;
  228. if (config_error == NULL) {
  229. if (mandatory) {
  230. wpa_printf(MSG_INFO, "WPS-STRICT: Configuration Error "
  231. "attribute missing");
  232. return -1;
  233. }
  234. return 0;
  235. }
  236. val = WPA_GET_BE16(config_error);
  237. if (val > 20) {
  238. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Configuration Error "
  239. "attribute value 0x%04x", val);
  240. return -1;
  241. }
  242. return 0;
  243. }
  244. static int wps_validate_dev_password_id(const u8 *dev_password_id,
  245. int mandatory)
  246. {
  247. u16 val;
  248. if (dev_password_id == NULL) {
  249. if (mandatory) {
  250. wpa_printf(MSG_INFO, "WPS-STRICT: Device Password ID "
  251. "attribute missing");
  252. return -1;
  253. }
  254. return 0;
  255. }
  256. val = WPA_GET_BE16(dev_password_id);
  257. if (val >= 0x0008 && val <= 0x000f) {
  258. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Device Password ID "
  259. "attribute value 0x%04x", val);
  260. return -1;
  261. }
  262. return 0;
  263. }
  264. static int wps_validate_manufacturer(const u8 *manufacturer, size_t len,
  265. int mandatory)
  266. {
  267. if (manufacturer == NULL) {
  268. if (mandatory) {
  269. wpa_printf(MSG_INFO, "WPS-STRICT: Manufacturer "
  270. "attribute missing");
  271. return -1;
  272. }
  273. return 0;
  274. }
  275. if (len > 0 && manufacturer[len - 1] == 0) {
  276. wpa_hexdump_ascii(MSG_INFO, "WPS-STRICT: Invalid Manufacturer "
  277. "attribute value", manufacturer, len);
  278. return -1;
  279. }
  280. return 0;
  281. }
  282. static int wps_validate_model_name(const u8 *model_name, size_t len,
  283. int mandatory)
  284. {
  285. if (model_name == NULL) {
  286. if (mandatory) {
  287. wpa_printf(MSG_INFO, "WPS-STRICT: Model Name "
  288. "attribute missing");
  289. return -1;
  290. }
  291. return 0;
  292. }
  293. if (len > 0 && model_name[len - 1] == 0) {
  294. wpa_hexdump_ascii(MSG_INFO, "WPS-STRICT: Invalid Model Name "
  295. "attribute value", model_name, len);
  296. return -1;
  297. }
  298. return 0;
  299. }
  300. static int wps_validate_model_number(const u8 *model_number, size_t len,
  301. int mandatory)
  302. {
  303. if (model_number == NULL) {
  304. if (mandatory) {
  305. wpa_printf(MSG_INFO, "WPS-STRICT: Model Number "
  306. "attribute missing");
  307. return -1;
  308. }
  309. return 0;
  310. }
  311. if (len > 0 && model_number[len - 1] == 0) {
  312. wpa_hexdump_ascii(MSG_INFO, "WPS-STRICT: Invalid Model Number "
  313. "attribute value", model_number, len);
  314. return -1;
  315. }
  316. return 0;
  317. }
  318. static int wps_validate_serial_number(const u8 *serial_number, size_t len,
  319. int mandatory)
  320. {
  321. if (serial_number == NULL) {
  322. if (mandatory) {
  323. wpa_printf(MSG_INFO, "WPS-STRICT: Serial Number "
  324. "attribute missing");
  325. return -1;
  326. }
  327. return 0;
  328. }
  329. if (len > 0 && serial_number[len - 1] == 0) {
  330. wpa_hexdump_ascii(MSG_INFO, "WPS-STRICT: Invalid Serial "
  331. "Number attribute value",
  332. serial_number, len);
  333. return -1;
  334. }
  335. return 0;
  336. }
  337. static int wps_validate_dev_name(const u8 *dev_name, size_t len,
  338. int mandatory)
  339. {
  340. if (dev_name == NULL) {
  341. if (mandatory) {
  342. wpa_printf(MSG_INFO, "WPS-STRICT: Device Name "
  343. "attribute missing");
  344. return -1;
  345. }
  346. return 0;
  347. }
  348. if (len > 0 && dev_name[len - 1] == 0) {
  349. wpa_hexdump_ascii(MSG_INFO, "WPS-STRICT: Invalid Device Name "
  350. "attribute value", dev_name, len);
  351. return -1;
  352. }
  353. return 0;
  354. }
  355. static int wps_validate_request_to_enroll(const u8 *request_to_enroll,
  356. int mandatory)
  357. {
  358. if (request_to_enroll == NULL) {
  359. if (mandatory) {
  360. wpa_printf(MSG_INFO, "WPS-STRICT: Request to Enroll "
  361. "attribute missing");
  362. return -1;
  363. }
  364. return 0;
  365. }
  366. if (*request_to_enroll > 0x01) {
  367. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Request to Enroll "
  368. "attribute value 0x%x", *request_to_enroll);
  369. return -1;
  370. }
  371. return 0;
  372. }
  373. static int wps_validate_req_dev_type(const u8 *req_dev_type[], size_t num,
  374. int mandatory)
  375. {
  376. if (num == 0) {
  377. if (mandatory) {
  378. wpa_printf(MSG_INFO, "WPS-STRICT: Requested Device "
  379. "Type attribute missing");
  380. return -1;
  381. }
  382. return 0;
  383. }
  384. return 0;
  385. }
  386. static int wps_validate_wps_state(const u8 *wps_state, int mandatory)
  387. {
  388. if (wps_state == NULL) {
  389. if (mandatory) {
  390. wpa_printf(MSG_INFO, "WPS-STRICT: Wi-Fi Protected "
  391. "Setup State attribute missing");
  392. return -1;
  393. }
  394. return 0;
  395. }
  396. if (*wps_state != WPS_STATE_NOT_CONFIGURED &&
  397. *wps_state != WPS_STATE_CONFIGURED) {
  398. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Wi-Fi Protected "
  399. "Setup State attribute value 0x%x", *wps_state);
  400. return -1;
  401. }
  402. return 0;
  403. }
  404. static int wps_validate_ap_setup_locked(const u8 *ap_setup_locked,
  405. int mandatory)
  406. {
  407. if (ap_setup_locked == NULL) {
  408. if (mandatory) {
  409. wpa_printf(MSG_INFO, "WPS-STRICT: AP Setup Locked "
  410. "attribute missing");
  411. return -1;
  412. }
  413. return 0;
  414. }
  415. if (*ap_setup_locked > 1) {
  416. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid AP Setup Locked "
  417. "attribute value 0x%x", *ap_setup_locked);
  418. return -1;
  419. }
  420. return 0;
  421. }
  422. static int wps_validate_selected_registrar(const u8 *selected_registrar,
  423. int mandatory)
  424. {
  425. if (selected_registrar == NULL) {
  426. if (mandatory) {
  427. wpa_printf(MSG_INFO, "WPS-STRICT: Selected Registrar "
  428. "attribute missing");
  429. return -1;
  430. }
  431. return 0;
  432. }
  433. if (*selected_registrar > 1) {
  434. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Selected Registrar "
  435. "attribute value 0x%x", *selected_registrar);
  436. return -1;
  437. }
  438. return 0;
  439. }
  440. static int wps_validate_sel_reg_config_methods(const u8 *config_methods,
  441. int wps2, int mandatory)
  442. {
  443. u16 val;
  444. if (config_methods == NULL) {
  445. if (mandatory) {
  446. wpa_printf(MSG_INFO, "WPS-STRICT: Selected Registrar "
  447. "Configuration Methods attribute missing");
  448. return -1;
  449. }
  450. return 0;
  451. }
  452. val = WPA_GET_BE16(config_methods);
  453. if (!valid_config_methods(val, wps2)) {
  454. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Selected Registrar "
  455. "Configuration Methods attribute value 0x%04x",
  456. val);
  457. return -1;
  458. }
  459. return 0;
  460. }
  461. static int wps_validate_authorized_macs(const u8 *authorized_macs, size_t len,
  462. int mandatory)
  463. {
  464. if (authorized_macs == NULL) {
  465. if (mandatory) {
  466. wpa_printf(MSG_INFO, "WPS-STRICT: Authorized MACs "
  467. "attribute missing");
  468. return -1;
  469. }
  470. return 0;
  471. }
  472. if (len > 30 && (len % ETH_ALEN) != 0) {
  473. wpa_hexdump(MSG_INFO, "WPS-STRICT: Invalid Authorized "
  474. "MACs attribute value", authorized_macs, len);
  475. return -1;
  476. }
  477. return 0;
  478. }
  479. static int wps_validate_msg_type(const u8 *msg_type, int mandatory)
  480. {
  481. if (msg_type == NULL) {
  482. if (mandatory) {
  483. wpa_printf(MSG_INFO, "WPS-STRICT: Message Type "
  484. "attribute missing");
  485. return -1;
  486. }
  487. return 0;
  488. }
  489. if (*msg_type < WPS_Beacon || *msg_type > WPS_WSC_DONE) {
  490. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Message Type "
  491. "attribute value 0x%x", *msg_type);
  492. return -1;
  493. }
  494. return 0;
  495. }
  496. static int wps_validate_mac_addr(const u8 *mac_addr, int mandatory)
  497. {
  498. if (mac_addr == NULL) {
  499. if (mandatory) {
  500. wpa_printf(MSG_INFO, "WPS-STRICT: MAC Address "
  501. "attribute missing");
  502. return -1;
  503. }
  504. return 0;
  505. }
  506. if (mac_addr[0] & 0x01) {
  507. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid MAC Address "
  508. "attribute value " MACSTR, MAC2STR(mac_addr));
  509. return -1;
  510. }
  511. return 0;
  512. }
  513. static int wps_validate_enrollee_nonce(const u8 *enrollee_nonce, int mandatory)
  514. {
  515. if (enrollee_nonce == NULL) {
  516. if (mandatory) {
  517. wpa_printf(MSG_INFO, "WPS-STRICT: Enrollee Nonce "
  518. "attribute missing");
  519. return -1;
  520. }
  521. return 0;
  522. }
  523. return 0;
  524. }
  525. static int wps_validate_registrar_nonce(const u8 *registrar_nonce,
  526. int mandatory)
  527. {
  528. if (registrar_nonce == NULL) {
  529. if (mandatory) {
  530. wpa_printf(MSG_INFO, "WPS-STRICT: Registrar Nonce "
  531. "attribute missing");
  532. return -1;
  533. }
  534. return 0;
  535. }
  536. return 0;
  537. }
  538. static int wps_validate_public_key(const u8 *public_key, size_t len,
  539. int mandatory)
  540. {
  541. if (public_key == NULL) {
  542. if (mandatory) {
  543. wpa_printf(MSG_INFO, "WPS-STRICT: Public Key "
  544. "attribute missing");
  545. return -1;
  546. }
  547. return 0;
  548. }
  549. if (len != 192) {
  550. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Public Key "
  551. "attribute length %d", (int) len);
  552. return -1;
  553. }
  554. return 0;
  555. }
  556. static int num_bits_set(u16 val)
  557. {
  558. int c;
  559. for (c = 0; val; c++)
  560. val &= val - 1;
  561. return c;
  562. }
  563. static int wps_validate_auth_type_flags(const u8 *flags, int mandatory)
  564. {
  565. u16 val;
  566. if (flags == NULL) {
  567. if (mandatory) {
  568. wpa_printf(MSG_INFO, "WPS-STRICT: Authentication Type "
  569. "Flags attribute missing");
  570. return -1;
  571. }
  572. return 0;
  573. }
  574. val = WPA_GET_BE16(flags);
  575. if ((val & ~WPS_AUTH_TYPES) || !(val & WPS_AUTH_WPA2PSK)) {
  576. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Authentication Type "
  577. "Flags attribute value 0x%04x", val);
  578. return -1;
  579. }
  580. return 0;
  581. }
  582. static int wps_validate_auth_type(const u8 *type, int mandatory)
  583. {
  584. u16 val;
  585. if (type == NULL) {
  586. if (mandatory) {
  587. wpa_printf(MSG_INFO, "WPS-STRICT: Authentication Type "
  588. "attribute missing");
  589. return -1;
  590. }
  591. return 0;
  592. }
  593. val = WPA_GET_BE16(type);
  594. if ((val & ~WPS_AUTH_TYPES) || val == 0 ||
  595. (num_bits_set(val) > 1 &&
  596. val != (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK))) {
  597. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Authentication Type "
  598. "attribute value 0x%04x", val);
  599. return -1;
  600. }
  601. return 0;
  602. }
  603. static int wps_validate_encr_type_flags(const u8 *flags, int mandatory)
  604. {
  605. u16 val;
  606. if (flags == NULL) {
  607. if (mandatory) {
  608. wpa_printf(MSG_INFO, "WPS-STRICT: Encryption Type "
  609. "Flags attribute missing");
  610. return -1;
  611. }
  612. return 0;
  613. }
  614. val = WPA_GET_BE16(flags);
  615. if ((val & ~WPS_ENCR_TYPES) || !(val & WPS_ENCR_AES)) {
  616. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Encryption Type "
  617. "Flags attribute value 0x%04x", val);
  618. return -1;
  619. }
  620. return 0;
  621. }
  622. static int wps_validate_encr_type(const u8 *type, int mandatory)
  623. {
  624. u16 val;
  625. if (type == NULL) {
  626. if (mandatory) {
  627. wpa_printf(MSG_INFO, "WPS-STRICT: Encryption Type "
  628. "attribute missing");
  629. return -1;
  630. }
  631. return 0;
  632. }
  633. val = WPA_GET_BE16(type);
  634. if ((val & ~WPS_ENCR_TYPES) || val == 0 ||
  635. (num_bits_set(val) > 1 && val != (WPS_ENCR_TKIP | WPS_ENCR_AES))) {
  636. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Encryption Type "
  637. "attribute value 0x%04x", val);
  638. return -1;
  639. }
  640. return 0;
  641. }
  642. static int wps_validate_conn_type_flags(const u8 *flags, int mandatory)
  643. {
  644. if (flags == NULL) {
  645. if (mandatory) {
  646. wpa_printf(MSG_INFO, "WPS-STRICT: Connection Type "
  647. "Flags attribute missing");
  648. return -1;
  649. }
  650. return 0;
  651. }
  652. if ((*flags & ~(WPS_CONN_ESS | WPS_CONN_IBSS)) ||
  653. !(*flags & WPS_CONN_ESS)) {
  654. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Connection Type "
  655. "Flags attribute value 0x%02x", *flags);
  656. return -1;
  657. }
  658. return 0;
  659. }
  660. static int wps_validate_os_version(const u8 *os_version, int mandatory)
  661. {
  662. if (os_version == NULL) {
  663. if (mandatory) {
  664. wpa_printf(MSG_INFO, "WPS-STRICT: OS Version "
  665. "attribute missing");
  666. return -1;
  667. }
  668. return 0;
  669. }
  670. return 0;
  671. }
  672. static int wps_validate_authenticator(const u8 *authenticator, int mandatory)
  673. {
  674. if (authenticator == NULL) {
  675. if (mandatory) {
  676. wpa_printf(MSG_INFO, "WPS-STRICT: Authenticator "
  677. "attribute missing");
  678. return -1;
  679. }
  680. return 0;
  681. }
  682. return 0;
  683. }
  684. static int wps_validate_e_hash1(const u8 *hash, int mandatory)
  685. {
  686. if (hash == NULL) {
  687. if (mandatory) {
  688. wpa_printf(MSG_INFO, "WPS-STRICT: E-Hash1 "
  689. "attribute missing");
  690. return -1;
  691. }
  692. return 0;
  693. }
  694. return 0;
  695. }
  696. static int wps_validate_e_hash2(const u8 *hash, int mandatory)
  697. {
  698. if (hash == NULL) {
  699. if (mandatory) {
  700. wpa_printf(MSG_INFO, "WPS-STRICT: E-Hash2 "
  701. "attribute missing");
  702. return -1;
  703. }
  704. return 0;
  705. }
  706. return 0;
  707. }
  708. static int wps_validate_r_hash1(const u8 *hash, int mandatory)
  709. {
  710. if (hash == NULL) {
  711. if (mandatory) {
  712. wpa_printf(MSG_INFO, "WPS-STRICT: R-Hash1 "
  713. "attribute missing");
  714. return -1;
  715. }
  716. return 0;
  717. }
  718. return 0;
  719. }
  720. static int wps_validate_r_hash2(const u8 *hash, int mandatory)
  721. {
  722. if (hash == NULL) {
  723. if (mandatory) {
  724. wpa_printf(MSG_INFO, "WPS-STRICT: R-Hash2 "
  725. "attribute missing");
  726. return -1;
  727. }
  728. return 0;
  729. }
  730. return 0;
  731. }
  732. static int wps_validate_encr_settings(const u8 *encr_settings, size_t len,
  733. int mandatory)
  734. {
  735. if (encr_settings == NULL) {
  736. if (mandatory) {
  737. wpa_printf(MSG_INFO, "WPS-STRICT: Encrypted Settings "
  738. "attribute missing");
  739. return -1;
  740. }
  741. return 0;
  742. }
  743. if (len < 16) {
  744. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Encrypted Settings "
  745. "attribute length %d", (int) len);
  746. return -1;
  747. }
  748. return 0;
  749. }
  750. static int wps_validate_settings_delay_time(const u8 *delay, int mandatory)
  751. {
  752. if (delay == NULL) {
  753. if (mandatory) {
  754. wpa_printf(MSG_INFO, "WPS-STRICT: Settings Delay Time "
  755. "attribute missing");
  756. return -1;
  757. }
  758. return 0;
  759. }
  760. return 0;
  761. }
  762. static int wps_validate_r_snonce1(const u8 *nonce, int mandatory)
  763. {
  764. if (nonce == NULL) {
  765. if (mandatory) {
  766. wpa_printf(MSG_INFO, "WPS-STRICT: R-SNonce1 "
  767. "attribute missing");
  768. return -1;
  769. }
  770. return 0;
  771. }
  772. return 0;
  773. }
  774. static int wps_validate_r_snonce2(const u8 *nonce, int mandatory)
  775. {
  776. if (nonce == NULL) {
  777. if (mandatory) {
  778. wpa_printf(MSG_INFO, "WPS-STRICT: R-SNonce2 "
  779. "attribute missing");
  780. return -1;
  781. }
  782. return 0;
  783. }
  784. return 0;
  785. }
  786. static int wps_validate_e_snonce1(const u8 *nonce, int mandatory)
  787. {
  788. if (nonce == NULL) {
  789. if (mandatory) {
  790. wpa_printf(MSG_INFO, "WPS-STRICT: E-SNonce1 "
  791. "attribute missing");
  792. return -1;
  793. }
  794. return 0;
  795. }
  796. return 0;
  797. }
  798. static int wps_validate_e_snonce2(const u8 *nonce, int mandatory)
  799. {
  800. if (nonce == NULL) {
  801. if (mandatory) {
  802. wpa_printf(MSG_INFO, "WPS-STRICT: E-SNonce2 "
  803. "attribute missing");
  804. return -1;
  805. }
  806. return 0;
  807. }
  808. return 0;
  809. }
  810. static int wps_validate_key_wrap_auth(const u8 *auth, int mandatory)
  811. {
  812. if (auth == NULL) {
  813. if (mandatory) {
  814. wpa_printf(MSG_INFO, "WPS-STRICT: Key Wrap "
  815. "Authenticator attribute missing");
  816. return -1;
  817. }
  818. return 0;
  819. }
  820. return 0;
  821. }
  822. static int wps_validate_ssid(const u8 *ssid, size_t ssid_len, int mandatory)
  823. {
  824. if (ssid == NULL) {
  825. if (mandatory) {
  826. wpa_printf(MSG_INFO, "WPS-STRICT: SSID "
  827. "attribute missing");
  828. return -1;
  829. }
  830. return 0;
  831. }
  832. if (ssid_len == 0 || ssid[ssid_len - 1] == 0) {
  833. wpa_hexdump_ascii(MSG_INFO, "WPS-STRICT: Invalid SSID "
  834. "attribute value", ssid, ssid_len);
  835. return -1;
  836. }
  837. return 0;
  838. }
  839. static int wps_validate_network_key_index(const u8 *idx, int mandatory)
  840. {
  841. if (idx == NULL) {
  842. if (mandatory) {
  843. wpa_printf(MSG_INFO, "WPS-STRICT: Network Key Index "
  844. "attribute missing");
  845. return -1;
  846. }
  847. return 0;
  848. }
  849. return 0;
  850. }
  851. static int wps_validate_network_idx(const u8 *idx, int mandatory)
  852. {
  853. if (idx == NULL) {
  854. if (mandatory) {
  855. wpa_printf(MSG_INFO, "WPS-STRICT: Network Index "
  856. "attribute missing");
  857. return -1;
  858. }
  859. return 0;
  860. }
  861. return 0;
  862. }
  863. static int wps_validate_network_key(const u8 *key, size_t key_len,
  864. const u8 *encr_type, int mandatory)
  865. {
  866. if (key == NULL) {
  867. if (mandatory) {
  868. wpa_printf(MSG_INFO, "WPS-STRICT: Network Key "
  869. "attribute missing");
  870. return -1;
  871. }
  872. return 0;
  873. }
  874. if (((encr_type == NULL || WPA_GET_BE16(encr_type) != WPS_ENCR_WEP) &&
  875. key_len > 8 && key_len < 64 && key[key_len - 1] == 0) ||
  876. key_len > 64) {
  877. wpa_hexdump_ascii_key(MSG_INFO, "WPS-STRICT: Invalid Network "
  878. "Key attribute value", key, key_len);
  879. return -1;
  880. }
  881. return 0;
  882. }
  883. static int wps_validate_network_key_shareable(const u8 *val, int mandatory)
  884. {
  885. if (val == NULL) {
  886. if (mandatory) {
  887. wpa_printf(MSG_INFO, "WPS-STRICT: Network Key "
  888. "Shareable attribute missing");
  889. return -1;
  890. }
  891. return 0;
  892. }
  893. if (*val > 1) {
  894. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Network Key "
  895. "Shareable attribute value 0x%x", *val);
  896. return -1;
  897. }
  898. return 0;
  899. }
  900. static int wps_validate_cred(const u8 *cred, size_t len)
  901. {
  902. struct wps_parse_attr attr;
  903. struct wpabuf buf;
  904. if (cred == NULL)
  905. return -1;
  906. wpabuf_set(&buf, cred, len);
  907. if (wps_parse_msg(&buf, &attr) < 0) {
  908. wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse Credential");
  909. return -1;
  910. }
  911. if (wps_validate_network_idx(attr.network_idx, 1) ||
  912. wps_validate_ssid(attr.ssid, attr.ssid_len, 1) ||
  913. wps_validate_auth_type(attr.auth_type, 1) ||
  914. wps_validate_encr_type(attr.encr_type, 1) ||
  915. wps_validate_network_key_index(attr.network_key_idx, 0) ||
  916. wps_validate_network_key(attr.network_key, attr.network_key_len,
  917. attr.encr_type, 1) ||
  918. wps_validate_mac_addr(attr.mac_addr, 1) ||
  919. wps_validate_network_key_shareable(attr.network_key_shareable, 0))
  920. {
  921. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Credential");
  922. return -1;
  923. }
  924. return 0;
  925. }
  926. static int wps_validate_credential(const u8 *cred[], size_t len[], size_t num,
  927. int mandatory)
  928. {
  929. size_t i;
  930. if (num == 0) {
  931. if (mandatory) {
  932. wpa_printf(MSG_INFO, "WPS-STRICT: Credential "
  933. "attribute missing");
  934. return -1;
  935. }
  936. return 0;
  937. }
  938. for (i = 0; i < num; i++) {
  939. if (wps_validate_cred(cred[i], len[i]) < 0)
  940. return -1;
  941. }
  942. return 0;
  943. }
  944. int wps_validate_beacon(const struct wpabuf *wps_ie)
  945. {
  946. struct wps_parse_attr attr;
  947. int wps2, sel_reg;
  948. if (wps_ie == NULL) {
  949. wpa_printf(MSG_INFO, "WPS-STRICT: No WPS IE in Beacon frame");
  950. return -1;
  951. }
  952. if (wps_parse_msg(wps_ie, &attr) < 0) {
  953. wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse WPS IE in "
  954. "Beacon frame");
  955. return -1;
  956. }
  957. wps2 = attr.version2 != NULL;
  958. sel_reg = attr.selected_registrar != NULL &&
  959. *attr.selected_registrar != 0;
  960. if (wps_validate_version(attr.version, 1) ||
  961. wps_validate_wps_state(attr.wps_state, 1) ||
  962. wps_validate_ap_setup_locked(attr.ap_setup_locked, 0) ||
  963. wps_validate_selected_registrar(attr.selected_registrar, 0) ||
  964. wps_validate_dev_password_id(attr.dev_password_id, sel_reg) ||
  965. wps_validate_sel_reg_config_methods(attr.sel_reg_config_methods,
  966. wps2, sel_reg) ||
  967. wps_validate_uuid_e(attr.uuid_e, 0) ||
  968. wps_validate_rf_bands(attr.rf_bands, 0) ||
  969. wps_validate_version2(attr.version2, wps2) ||
  970. wps_validate_authorized_macs(attr.authorized_macs,
  971. attr.authorized_macs_len, 0)) {
  972. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Beacon frame");
  973. return -1;
  974. }
  975. return 0;
  976. }
  977. int wps_validate_beacon_probe_resp(const struct wpabuf *wps_ie, int probe,
  978. const u8 *addr)
  979. {
  980. struct wps_parse_attr attr;
  981. int wps2, sel_reg;
  982. if (wps_ie == NULL) {
  983. wpa_printf(MSG_INFO, "WPS-STRICT: No WPS IE in "
  984. "%sProbe Response frame", probe ? "" : "Beacon/");
  985. return -1;
  986. }
  987. if (wps_parse_msg(wps_ie, &attr) < 0) {
  988. wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse WPS IE in "
  989. "%sProbe Response frame", probe ? "" : "Beacon/");
  990. return -1;
  991. }
  992. wps2 = attr.version2 != NULL;
  993. sel_reg = attr.selected_registrar != NULL &&
  994. *attr.selected_registrar != 0;
  995. if (wps_validate_version(attr.version, 1) ||
  996. wps_validate_wps_state(attr.wps_state, 1) ||
  997. wps_validate_ap_setup_locked(attr.ap_setup_locked, 0) ||
  998. wps_validate_selected_registrar(attr.selected_registrar, 0) ||
  999. wps_validate_dev_password_id(attr.dev_password_id, sel_reg) ||
  1000. wps_validate_sel_reg_config_methods(attr.sel_reg_config_methods,
  1001. wps2, sel_reg) ||
  1002. wps_validate_response_type(attr.response_type, probe) ||
  1003. wps_validate_uuid_e(attr.uuid_e, probe) ||
  1004. wps_validate_manufacturer(attr.manufacturer, attr.manufacturer_len,
  1005. probe) ||
  1006. wps_validate_model_name(attr.model_name, attr.model_name_len,
  1007. probe) ||
  1008. wps_validate_model_number(attr.model_number, attr.model_number_len,
  1009. probe) ||
  1010. wps_validate_serial_number(attr.serial_number,
  1011. attr.serial_number_len, probe) ||
  1012. wps_validate_primary_dev_type(attr.primary_dev_type, probe) ||
  1013. wps_validate_dev_name(attr.dev_name, attr.dev_name_len, probe) ||
  1014. wps_validate_ap_config_methods(attr.config_methods, wps2, probe) ||
  1015. wps_validate_rf_bands(attr.rf_bands, 0) ||
  1016. wps_validate_version2(attr.version2, wps2) ||
  1017. wps_validate_authorized_macs(attr.authorized_macs,
  1018. attr.authorized_macs_len, 0)) {
  1019. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid %sProbe Response "
  1020. "frame from " MACSTR, probe ? "" : "Beacon/",
  1021. MAC2STR(addr));
  1022. #ifdef WPS_STRICT_WPS2
  1023. if (wps2)
  1024. return -1;
  1025. #else /* WPS_STRICT_WPS2 */
  1026. return -1;
  1027. #endif /* WPS_STRICT_WPS2 */
  1028. }
  1029. return 0;
  1030. }
  1031. int wps_validate_probe_req(const struct wpabuf *wps_ie, const u8 *addr)
  1032. {
  1033. struct wps_parse_attr attr;
  1034. int wps2;
  1035. if (wps_ie == NULL) {
  1036. wpa_printf(MSG_INFO, "WPS-STRICT: No WPS IE in "
  1037. "Probe Request frame");
  1038. return -1;
  1039. }
  1040. if (wps_parse_msg(wps_ie, &attr) < 0) {
  1041. wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse WPS IE in "
  1042. "Probe Request frame");
  1043. return -1;
  1044. }
  1045. wps2 = attr.version2 != NULL;
  1046. if (wps_validate_version(attr.version, 1) ||
  1047. wps_validate_request_type(attr.request_type, 1) ||
  1048. wps_validate_config_methods(attr.config_methods, wps2, 1) ||
  1049. wps_validate_uuid_e(attr.uuid_e, attr.uuid_r == NULL) ||
  1050. wps_validate_uuid_r(attr.uuid_r, attr.uuid_e == NULL) ||
  1051. wps_validate_primary_dev_type(attr.primary_dev_type, 1) ||
  1052. wps_validate_rf_bands(attr.rf_bands, 1) ||
  1053. wps_validate_assoc_state(attr.assoc_state, 1) ||
  1054. wps_validate_config_error(attr.config_error, 1) ||
  1055. wps_validate_dev_password_id(attr.dev_password_id, 1) ||
  1056. wps_validate_version2(attr.version2, wps2) ||
  1057. wps_validate_manufacturer(attr.manufacturer, attr.manufacturer_len,
  1058. wps2) ||
  1059. wps_validate_model_name(attr.model_name, attr.model_name_len,
  1060. wps2) ||
  1061. wps_validate_model_number(attr.model_number, attr.model_number_len,
  1062. wps2) ||
  1063. wps_validate_dev_name(attr.dev_name, attr.dev_name_len, wps2) ||
  1064. wps_validate_request_to_enroll(attr.request_to_enroll, 0) ||
  1065. wps_validate_req_dev_type(attr.req_dev_type, attr.num_req_dev_type,
  1066. 0)) {
  1067. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Probe Request "
  1068. "frame from " MACSTR, MAC2STR(addr));
  1069. return -1;
  1070. }
  1071. return 0;
  1072. }
  1073. int wps_validate_assoc_req(const struct wpabuf *wps_ie)
  1074. {
  1075. struct wps_parse_attr attr;
  1076. int wps2;
  1077. if (wps_ie == NULL) {
  1078. wpa_printf(MSG_INFO, "WPS-STRICT: No WPS IE in "
  1079. "(Re)Association Request frame");
  1080. return -1;
  1081. }
  1082. if (wps_parse_msg(wps_ie, &attr) < 0) {
  1083. wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse WPS IE in "
  1084. "(Re)Association Request frame");
  1085. return -1;
  1086. }
  1087. wps2 = attr.version2 != NULL;
  1088. if (wps_validate_version(attr.version, 1) ||
  1089. wps_validate_request_type(attr.request_type, 1) ||
  1090. wps_validate_version2(attr.version2, wps2)) {
  1091. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid (Re)Association "
  1092. "Request frame");
  1093. return -1;
  1094. }
  1095. return 0;
  1096. }
  1097. int wps_validate_assoc_resp(const struct wpabuf *wps_ie)
  1098. {
  1099. struct wps_parse_attr attr;
  1100. int wps2;
  1101. if (wps_ie == NULL) {
  1102. wpa_printf(MSG_INFO, "WPS-STRICT: No WPS IE in "
  1103. "(Re)Association Response frame");
  1104. return -1;
  1105. }
  1106. if (wps_parse_msg(wps_ie, &attr) < 0) {
  1107. wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse WPS IE in "
  1108. "(Re)Association Response frame");
  1109. return -1;
  1110. }
  1111. wps2 = attr.version2 != NULL;
  1112. if (wps_validate_version(attr.version, 1) ||
  1113. wps_validate_response_type(attr.response_type, 1) ||
  1114. wps_validate_version2(attr.version2, wps2)) {
  1115. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid (Re)Association "
  1116. "Response frame");
  1117. return -1;
  1118. }
  1119. return 0;
  1120. }
  1121. int wps_validate_m1(const struct wpabuf *tlvs)
  1122. {
  1123. struct wps_parse_attr attr;
  1124. int wps2;
  1125. if (tlvs == NULL) {
  1126. wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M1");
  1127. return -1;
  1128. }
  1129. if (wps_parse_msg(tlvs, &attr) < 0) {
  1130. wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
  1131. "in M1");
  1132. return -1;
  1133. }
  1134. wps2 = attr.version2 != NULL;
  1135. if (wps_validate_version(attr.version, 1) ||
  1136. wps_validate_msg_type(attr.msg_type, 1) ||
  1137. wps_validate_uuid_e(attr.uuid_e, 1) ||
  1138. wps_validate_mac_addr(attr.mac_addr, 1) ||
  1139. wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
  1140. wps_validate_public_key(attr.public_key, attr.public_key_len, 1) ||
  1141. wps_validate_auth_type_flags(attr.auth_type_flags, 1) ||
  1142. wps_validate_encr_type_flags(attr.encr_type_flags, 1) ||
  1143. wps_validate_conn_type_flags(attr.conn_type_flags, 1) ||
  1144. wps_validate_config_methods(attr.config_methods, wps2, 1) ||
  1145. wps_validate_wps_state(attr.wps_state, 1) ||
  1146. wps_validate_manufacturer(attr.manufacturer, attr.manufacturer_len,
  1147. 1) ||
  1148. wps_validate_model_name(attr.model_name, attr.model_name_len, 1) ||
  1149. wps_validate_model_number(attr.model_number, attr.model_number_len,
  1150. 1) ||
  1151. wps_validate_serial_number(attr.serial_number,
  1152. attr.serial_number_len, 1) ||
  1153. wps_validate_primary_dev_type(attr.primary_dev_type, 1) ||
  1154. wps_validate_dev_name(attr.dev_name, attr.dev_name_len, 1) ||
  1155. wps_validate_rf_bands(attr.rf_bands, 1) ||
  1156. wps_validate_assoc_state(attr.assoc_state, 1) ||
  1157. wps_validate_dev_password_id(attr.dev_password_id, 1) ||
  1158. wps_validate_config_error(attr.config_error, 1) ||
  1159. wps_validate_os_version(attr.os_version, 1) ||
  1160. wps_validate_version2(attr.version2, wps2) ||
  1161. wps_validate_request_to_enroll(attr.request_to_enroll, 0)) {
  1162. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M1");
  1163. #ifdef WPS_STRICT_WPS2
  1164. if (wps2)
  1165. return -1;
  1166. #else /* WPS_STRICT_WPS2 */
  1167. return -1;
  1168. #endif /* WPS_STRICT_WPS2 */
  1169. }
  1170. return 0;
  1171. }
  1172. int wps_validate_m2(const struct wpabuf *tlvs)
  1173. {
  1174. struct wps_parse_attr attr;
  1175. int wps2;
  1176. if (tlvs == NULL) {
  1177. wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M2");
  1178. return -1;
  1179. }
  1180. if (wps_parse_msg(tlvs, &attr) < 0) {
  1181. wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
  1182. "in M2");
  1183. return -1;
  1184. }
  1185. wps2 = attr.version2 != NULL;
  1186. if (wps_validate_version(attr.version, 1) ||
  1187. wps_validate_msg_type(attr.msg_type, 1) ||
  1188. wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
  1189. wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
  1190. wps_validate_uuid_r(attr.uuid_r, 1) ||
  1191. wps_validate_public_key(attr.public_key, attr.public_key_len, 1) ||
  1192. wps_validate_auth_type_flags(attr.auth_type_flags, 1) ||
  1193. wps_validate_encr_type_flags(attr.encr_type_flags, 1) ||
  1194. wps_validate_conn_type_flags(attr.conn_type_flags, 1) ||
  1195. wps_validate_config_methods(attr.config_methods, wps2, 1) ||
  1196. wps_validate_manufacturer(attr.manufacturer, attr.manufacturer_len,
  1197. 1) ||
  1198. wps_validate_model_name(attr.model_name, attr.model_name_len, 1) ||
  1199. wps_validate_model_number(attr.model_number, attr.model_number_len,
  1200. 1) ||
  1201. wps_validate_serial_number(attr.serial_number,
  1202. attr.serial_number_len, 1) ||
  1203. wps_validate_primary_dev_type(attr.primary_dev_type, 1) ||
  1204. wps_validate_dev_name(attr.dev_name, attr.dev_name_len, 1) ||
  1205. wps_validate_rf_bands(attr.rf_bands, 1) ||
  1206. wps_validate_assoc_state(attr.assoc_state, 1) ||
  1207. wps_validate_config_error(attr.config_error, 1) ||
  1208. wps_validate_dev_password_id(attr.dev_password_id, 1) ||
  1209. wps_validate_os_version(attr.os_version, 1) ||
  1210. wps_validate_version2(attr.version2, wps2) ||
  1211. wps_validate_authenticator(attr.authenticator, 1)) {
  1212. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M2");
  1213. #ifdef WPS_STRICT_WPS2
  1214. if (wps2)
  1215. return -1;
  1216. #else /* WPS_STRICT_WPS2 */
  1217. return -1;
  1218. #endif /* WPS_STRICT_WPS2 */
  1219. }
  1220. return 0;
  1221. }
  1222. int wps_validate_m2d(const struct wpabuf *tlvs)
  1223. {
  1224. struct wps_parse_attr attr;
  1225. int wps2;
  1226. if (tlvs == NULL) {
  1227. wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M2D");
  1228. return -1;
  1229. }
  1230. if (wps_parse_msg(tlvs, &attr) < 0) {
  1231. wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
  1232. "in M2D");
  1233. return -1;
  1234. }
  1235. wps2 = attr.version2 != NULL;
  1236. if (wps_validate_version(attr.version, 1) ||
  1237. wps_validate_msg_type(attr.msg_type, 1) ||
  1238. wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
  1239. wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
  1240. wps_validate_uuid_r(attr.uuid_r, 1) ||
  1241. wps_validate_auth_type_flags(attr.auth_type_flags, 1) ||
  1242. wps_validate_encr_type_flags(attr.encr_type_flags, 1) ||
  1243. wps_validate_conn_type_flags(attr.conn_type_flags, 1) ||
  1244. wps_validate_config_methods(attr.config_methods, wps2, 1) ||
  1245. wps_validate_manufacturer(attr.manufacturer, attr.manufacturer_len,
  1246. 1) ||
  1247. wps_validate_model_name(attr.model_name, attr.model_name_len, 1) ||
  1248. wps_validate_model_number(attr.model_number, attr.model_number_len,
  1249. 1) ||
  1250. wps_validate_serial_number(attr.serial_number,
  1251. attr.serial_number_len, 1) ||
  1252. wps_validate_primary_dev_type(attr.primary_dev_type, 1) ||
  1253. wps_validate_dev_name(attr.dev_name, attr.dev_name_len, 1) ||
  1254. wps_validate_rf_bands(attr.rf_bands, 1) ||
  1255. wps_validate_assoc_state(attr.assoc_state, 1) ||
  1256. wps_validate_config_error(attr.config_error, 1) ||
  1257. wps_validate_os_version(attr.os_version, 1) ||
  1258. wps_validate_version2(attr.version2, wps2)) {
  1259. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M2D");
  1260. #ifdef WPS_STRICT_WPS2
  1261. if (wps2)
  1262. return -1;
  1263. #else /* WPS_STRICT_WPS2 */
  1264. return -1;
  1265. #endif /* WPS_STRICT_WPS2 */
  1266. }
  1267. return 0;
  1268. }
  1269. int wps_validate_m3(const struct wpabuf *tlvs)
  1270. {
  1271. struct wps_parse_attr attr;
  1272. int wps2;
  1273. if (tlvs == NULL) {
  1274. wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M3");
  1275. return -1;
  1276. }
  1277. if (wps_parse_msg(tlvs, &attr) < 0) {
  1278. wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
  1279. "in M3");
  1280. return -1;
  1281. }
  1282. wps2 = attr.version2 != NULL;
  1283. if (wps_validate_version(attr.version, 1) ||
  1284. wps_validate_msg_type(attr.msg_type, 1) ||
  1285. wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
  1286. wps_validate_e_hash1(attr.e_hash1, 1) ||
  1287. wps_validate_e_hash2(attr.e_hash2, 1) ||
  1288. wps_validate_version2(attr.version2, wps2) ||
  1289. wps_validate_authenticator(attr.authenticator, 1)) {
  1290. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M3");
  1291. #ifdef WPS_STRICT_WPS2
  1292. if (wps2)
  1293. return -1;
  1294. #else /* WPS_STRICT_WPS2 */
  1295. return -1;
  1296. #endif /* WPS_STRICT_WPS2 */
  1297. }
  1298. return 0;
  1299. }
  1300. int wps_validate_m4(const struct wpabuf *tlvs)
  1301. {
  1302. struct wps_parse_attr attr;
  1303. int wps2;
  1304. if (tlvs == NULL) {
  1305. wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M4");
  1306. return -1;
  1307. }
  1308. if (wps_parse_msg(tlvs, &attr) < 0) {
  1309. wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
  1310. "in M4");
  1311. return -1;
  1312. }
  1313. wps2 = attr.version2 != NULL;
  1314. if (wps_validate_version(attr.version, 1) ||
  1315. wps_validate_msg_type(attr.msg_type, 1) ||
  1316. wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
  1317. wps_validate_r_hash1(attr.r_hash1, 1) ||
  1318. wps_validate_r_hash2(attr.r_hash2, 1) ||
  1319. wps_validate_encr_settings(attr.encr_settings,
  1320. attr.encr_settings_len, 1) ||
  1321. wps_validate_version2(attr.version2, wps2) ||
  1322. wps_validate_authenticator(attr.authenticator, 1)) {
  1323. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M4");
  1324. #ifdef WPS_STRICT_WPS2
  1325. if (wps2)
  1326. return -1;
  1327. #else /* WPS_STRICT_WPS2 */
  1328. return -1;
  1329. #endif /* WPS_STRICT_WPS2 */
  1330. }
  1331. return 0;
  1332. }
  1333. int wps_validate_m4_encr(const struct wpabuf *tlvs, int wps2)
  1334. {
  1335. struct wps_parse_attr attr;
  1336. if (tlvs == NULL) {
  1337. wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M4 encrypted "
  1338. "settings");
  1339. return -1;
  1340. }
  1341. if (wps_parse_msg(tlvs, &attr) < 0) {
  1342. wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
  1343. "in M4 encrypted settings");
  1344. return -1;
  1345. }
  1346. if (wps_validate_r_snonce1(attr.r_snonce1, 1) ||
  1347. wps_validate_key_wrap_auth(attr.key_wrap_auth, 1)) {
  1348. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M4 encrypted "
  1349. "settings");
  1350. #ifdef WPS_STRICT_WPS2
  1351. if (wps2)
  1352. return -1;
  1353. #else /* WPS_STRICT_WPS2 */
  1354. return -1;
  1355. #endif /* WPS_STRICT_WPS2 */
  1356. }
  1357. return 0;
  1358. }
  1359. int wps_validate_m5(const struct wpabuf *tlvs)
  1360. {
  1361. struct wps_parse_attr attr;
  1362. int wps2;
  1363. if (tlvs == NULL) {
  1364. wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M5");
  1365. return -1;
  1366. }
  1367. if (wps_parse_msg(tlvs, &attr) < 0) {
  1368. wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
  1369. "in M5");
  1370. return -1;
  1371. }
  1372. wps2 = attr.version2 != NULL;
  1373. if (wps_validate_version(attr.version, 1) ||
  1374. wps_validate_msg_type(attr.msg_type, 1) ||
  1375. wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
  1376. wps_validate_encr_settings(attr.encr_settings,
  1377. attr.encr_settings_len, 1) ||
  1378. wps_validate_version2(attr.version2, wps2) ||
  1379. wps_validate_authenticator(attr.authenticator, 1)) {
  1380. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M5");
  1381. #ifdef WPS_STRICT_WPS2
  1382. if (wps2)
  1383. return -1;
  1384. #else /* WPS_STRICT_WPS2 */
  1385. return -1;
  1386. #endif /* WPS_STRICT_WPS2 */
  1387. }
  1388. return 0;
  1389. }
  1390. int wps_validate_m5_encr(const struct wpabuf *tlvs, int wps2)
  1391. {
  1392. struct wps_parse_attr attr;
  1393. if (tlvs == NULL) {
  1394. wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M5 encrypted "
  1395. "settings");
  1396. return -1;
  1397. }
  1398. if (wps_parse_msg(tlvs, &attr) < 0) {
  1399. wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
  1400. "in M5 encrypted settings");
  1401. return -1;
  1402. }
  1403. if (wps_validate_e_snonce1(attr.e_snonce1, 1) ||
  1404. wps_validate_key_wrap_auth(attr.key_wrap_auth, 1)) {
  1405. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M5 encrypted "
  1406. "settings");
  1407. #ifdef WPS_STRICT_WPS2
  1408. if (wps2)
  1409. return -1;
  1410. #else /* WPS_STRICT_WPS2 */
  1411. return -1;
  1412. #endif /* WPS_STRICT_WPS2 */
  1413. }
  1414. return 0;
  1415. }
  1416. int wps_validate_m6(const struct wpabuf *tlvs)
  1417. {
  1418. struct wps_parse_attr attr;
  1419. int wps2;
  1420. if (tlvs == NULL) {
  1421. wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M6");
  1422. return -1;
  1423. }
  1424. if (wps_parse_msg(tlvs, &attr) < 0) {
  1425. wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
  1426. "in M6");
  1427. return -1;
  1428. }
  1429. wps2 = attr.version2 != NULL;
  1430. if (wps_validate_version(attr.version, 1) ||
  1431. wps_validate_msg_type(attr.msg_type, 1) ||
  1432. wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
  1433. wps_validate_encr_settings(attr.encr_settings,
  1434. attr.encr_settings_len, 1) ||
  1435. wps_validate_version2(attr.version2, wps2) ||
  1436. wps_validate_authenticator(attr.authenticator, 1)) {
  1437. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M6");
  1438. #ifdef WPS_STRICT_WPS2
  1439. if (wps2)
  1440. return -1;
  1441. #else /* WPS_STRICT_WPS2 */
  1442. return -1;
  1443. #endif /* WPS_STRICT_WPS2 */
  1444. }
  1445. return 0;
  1446. }
  1447. int wps_validate_m6_encr(const struct wpabuf *tlvs, int wps2)
  1448. {
  1449. struct wps_parse_attr attr;
  1450. if (tlvs == NULL) {
  1451. wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M6 encrypted "
  1452. "settings");
  1453. return -1;
  1454. }
  1455. if (wps_parse_msg(tlvs, &attr) < 0) {
  1456. wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
  1457. "in M6 encrypted settings");
  1458. return -1;
  1459. }
  1460. if (wps_validate_r_snonce2(attr.r_snonce2, 1) ||
  1461. wps_validate_key_wrap_auth(attr.key_wrap_auth, 1)) {
  1462. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M6 encrypted "
  1463. "settings");
  1464. #ifdef WPS_STRICT_WPS2
  1465. if (wps2)
  1466. return -1;
  1467. #else /* WPS_STRICT_WPS2 */
  1468. return -1;
  1469. #endif /* WPS_STRICT_WPS2 */
  1470. }
  1471. return 0;
  1472. }
  1473. int wps_validate_m7(const struct wpabuf *tlvs)
  1474. {
  1475. struct wps_parse_attr attr;
  1476. int wps2;
  1477. if (tlvs == NULL) {
  1478. wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M7");
  1479. return -1;
  1480. }
  1481. if (wps_parse_msg(tlvs, &attr) < 0) {
  1482. wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
  1483. "in M7");
  1484. return -1;
  1485. }
  1486. wps2 = attr.version2 != NULL;
  1487. if (wps_validate_version(attr.version, 1) ||
  1488. wps_validate_msg_type(attr.msg_type, 1) ||
  1489. wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
  1490. wps_validate_encr_settings(attr.encr_settings,
  1491. attr.encr_settings_len, 1) ||
  1492. wps_validate_settings_delay_time(attr.settings_delay_time, 0) ||
  1493. wps_validate_version2(attr.version2, wps2) ||
  1494. wps_validate_authenticator(attr.authenticator, 1)) {
  1495. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M7");
  1496. #ifdef WPS_STRICT_WPS2
  1497. if (wps2)
  1498. return -1;
  1499. #else /* WPS_STRICT_WPS2 */
  1500. return -1;
  1501. #endif /* WPS_STRICT_WPS2 */
  1502. }
  1503. return 0;
  1504. }
  1505. int wps_validate_m7_encr(const struct wpabuf *tlvs, int ap, int wps2)
  1506. {
  1507. struct wps_parse_attr attr;
  1508. if (tlvs == NULL) {
  1509. wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M7 encrypted "
  1510. "settings");
  1511. return -1;
  1512. }
  1513. if (wps_parse_msg(tlvs, &attr) < 0) {
  1514. wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
  1515. "in M7 encrypted settings");
  1516. return -1;
  1517. }
  1518. if (wps_validate_e_snonce2(attr.e_snonce2, 1) ||
  1519. wps_validate_ssid(attr.ssid, attr.ssid_len, !ap) ||
  1520. wps_validate_mac_addr(attr.mac_addr, !ap) ||
  1521. wps_validate_auth_type(attr.auth_type, !ap) ||
  1522. wps_validate_encr_type(attr.encr_type, !ap) ||
  1523. wps_validate_network_key_index(attr.network_key_idx, 0) ||
  1524. wps_validate_network_key(attr.network_key, attr.network_key_len,
  1525. attr.encr_type, !ap) ||
  1526. wps_validate_key_wrap_auth(attr.key_wrap_auth, 1)) {
  1527. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M7 encrypted "
  1528. "settings");
  1529. #ifdef WPS_STRICT_WPS2
  1530. if (wps2)
  1531. return -1;
  1532. #else /* WPS_STRICT_WPS2 */
  1533. return -1;
  1534. #endif /* WPS_STRICT_WPS2 */
  1535. }
  1536. return 0;
  1537. }
  1538. int wps_validate_m8(const struct wpabuf *tlvs)
  1539. {
  1540. struct wps_parse_attr attr;
  1541. int wps2;
  1542. if (tlvs == NULL) {
  1543. wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M8");
  1544. return -1;
  1545. }
  1546. if (wps_parse_msg(tlvs, &attr) < 0) {
  1547. wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
  1548. "in M8");
  1549. return -1;
  1550. }
  1551. wps2 = attr.version2 != NULL;
  1552. if (wps_validate_version(attr.version, 1) ||
  1553. wps_validate_msg_type(attr.msg_type, 1) ||
  1554. wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
  1555. wps_validate_encr_settings(attr.encr_settings,
  1556. attr.encr_settings_len, 1) ||
  1557. wps_validate_version2(attr.version2, wps2) ||
  1558. wps_validate_authenticator(attr.authenticator, 1)) {
  1559. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M8");
  1560. #ifdef WPS_STRICT_WPS2
  1561. if (wps2)
  1562. return -1;
  1563. #else /* WPS_STRICT_WPS2 */
  1564. return -1;
  1565. #endif /* WPS_STRICT_WPS2 */
  1566. }
  1567. return 0;
  1568. }
  1569. int wps_validate_m8_encr(const struct wpabuf *tlvs, int ap, int wps2)
  1570. {
  1571. struct wps_parse_attr attr;
  1572. if (tlvs == NULL) {
  1573. wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M8 encrypted "
  1574. "settings");
  1575. return -1;
  1576. }
  1577. if (wps_parse_msg(tlvs, &attr) < 0) {
  1578. wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
  1579. "in M8 encrypted settings");
  1580. return -1;
  1581. }
  1582. if (wps_validate_ssid(attr.ssid, attr.ssid_len, ap) ||
  1583. wps_validate_auth_type(attr.auth_type, ap) ||
  1584. wps_validate_encr_type(attr.encr_type, ap) ||
  1585. wps_validate_network_key_index(attr.network_key_idx, 0) ||
  1586. wps_validate_mac_addr(attr.mac_addr, ap) ||
  1587. wps_validate_credential(attr.cred, attr.cred_len, attr.num_cred,
  1588. !ap) ||
  1589. wps_validate_key_wrap_auth(attr.key_wrap_auth, 1)) {
  1590. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M8 encrypted "
  1591. "settings");
  1592. #ifdef WPS_STRICT_WPS2
  1593. if (wps2)
  1594. return -1;
  1595. #else /* WPS_STRICT_WPS2 */
  1596. return -1;
  1597. #endif /* WPS_STRICT_WPS2 */
  1598. }
  1599. return 0;
  1600. }
  1601. int wps_validate_wsc_ack(const struct wpabuf *tlvs)
  1602. {
  1603. struct wps_parse_attr attr;
  1604. int wps2;
  1605. if (tlvs == NULL) {
  1606. wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in WSC_ACK");
  1607. return -1;
  1608. }
  1609. if (wps_parse_msg(tlvs, &attr) < 0) {
  1610. wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
  1611. "in WSC_ACK");
  1612. return -1;
  1613. }
  1614. wps2 = attr.version2 != NULL;
  1615. if (wps_validate_version(attr.version, 1) ||
  1616. wps_validate_msg_type(attr.msg_type, 1) ||
  1617. wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
  1618. wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
  1619. wps_validate_version2(attr.version2, wps2)) {
  1620. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid WSC_ACK");
  1621. #ifdef WPS_STRICT_WPS2
  1622. if (wps2)
  1623. return -1;
  1624. #else /* WPS_STRICT_WPS2 */
  1625. return -1;
  1626. #endif /* WPS_STRICT_WPS2 */
  1627. }
  1628. return 0;
  1629. }
  1630. int wps_validate_wsc_nack(const struct wpabuf *tlvs)
  1631. {
  1632. struct wps_parse_attr attr;
  1633. int wps2;
  1634. if (tlvs == NULL) {
  1635. wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in WSC_NACK");
  1636. return -1;
  1637. }
  1638. if (wps_parse_msg(tlvs, &attr) < 0) {
  1639. wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
  1640. "in WSC_NACK");
  1641. return -1;
  1642. }
  1643. wps2 = attr.version2 != NULL;
  1644. if (wps_validate_version(attr.version, 1) ||
  1645. wps_validate_msg_type(attr.msg_type, 1) ||
  1646. wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
  1647. wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
  1648. wps_validate_config_error(attr.config_error, 1) ||
  1649. wps_validate_version2(attr.version2, wps2)) {
  1650. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid WSC_NACK");
  1651. #ifdef WPS_STRICT_WPS2
  1652. if (wps2)
  1653. return -1;
  1654. #else /* WPS_STRICT_WPS2 */
  1655. return -1;
  1656. #endif /* WPS_STRICT_WPS2 */
  1657. }
  1658. return 0;
  1659. }
  1660. int wps_validate_wsc_done(const struct wpabuf *tlvs)
  1661. {
  1662. struct wps_parse_attr attr;
  1663. int wps2;
  1664. if (tlvs == NULL) {
  1665. wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in WSC_Done");
  1666. return -1;
  1667. }
  1668. if (wps_parse_msg(tlvs, &attr) < 0) {
  1669. wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
  1670. "in WSC_Done");
  1671. return -1;
  1672. }
  1673. wps2 = attr.version2 != NULL;
  1674. if (wps_validate_version(attr.version, 1) ||
  1675. wps_validate_msg_type(attr.msg_type, 1) ||
  1676. wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
  1677. wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
  1678. wps_validate_version2(attr.version2, wps2)) {
  1679. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid WSC_Done");
  1680. #ifdef WPS_STRICT_WPS2
  1681. if (wps2)
  1682. return -1;
  1683. #else /* WPS_STRICT_WPS2 */
  1684. return -1;
  1685. #endif /* WPS_STRICT_WPS2 */
  1686. }
  1687. return 0;
  1688. }
  1689. int wps_validate_upnp_set_selected_registrar(const struct wpabuf *tlvs)
  1690. {
  1691. struct wps_parse_attr attr;
  1692. int wps2;
  1693. int sel_reg;
  1694. if (tlvs == NULL) {
  1695. wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in "
  1696. "SetSelectedRegistrar");
  1697. return -1;
  1698. }
  1699. if (wps_parse_msg(tlvs, &attr) < 0) {
  1700. wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
  1701. "in SetSelectedRegistrar");
  1702. return -1;
  1703. }
  1704. wps2 = attr.version2 != NULL;
  1705. sel_reg = attr.selected_registrar != NULL &&
  1706. *attr.selected_registrar != 0;
  1707. if (wps_validate_version(attr.version, 1) ||
  1708. wps_validate_dev_password_id(attr.dev_password_id, sel_reg) ||
  1709. wps_validate_sel_reg_config_methods(attr.sel_reg_config_methods,
  1710. wps2, sel_reg) ||
  1711. wps_validate_version2(attr.version2, wps2) ||
  1712. wps_validate_authorized_macs(attr.authorized_macs,
  1713. attr.authorized_macs_len, wps2) ||
  1714. wps_validate_uuid_r(attr.uuid_r, wps2)) {
  1715. wpa_printf(MSG_INFO, "WPS-STRICT: Invalid "
  1716. "SetSelectedRegistrar");
  1717. #ifdef WPS_STRICT_WPS2
  1718. if (wps2)
  1719. return -1;
  1720. #else /* WPS_STRICT_WPS2 */
  1721. return -1;
  1722. #endif /* WPS_STRICT_WPS2 */
  1723. }
  1724. return 0;
  1725. }