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