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