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