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