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