wps_registrar.c revision 1f69aa52ea2e0a73ac502565df8c666ee49cab6a
1/* 2 * Wi-Fi Protected Setup - Registrar 3 * Copyright (c) 2008-2009, Jouni Malinen <j@w1.fi> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * Alternatively, this software may be distributed under the terms of BSD 10 * license. 11 * 12 * See README and COPYING for more details. 13 */ 14 15#include "utils/includes.h" 16 17#include "utils/common.h" 18#include "utils/base64.h" 19#include "utils/eloop.h" 20#include "utils/uuid.h" 21#include "utils/list.h" 22#include "crypto/crypto.h" 23#include "crypto/sha256.h" 24#include "crypto/random.h" 25#include "common/ieee802_11_defs.h" 26#include "wps_i.h" 27#include "wps_dev_attr.h" 28#include "wps_upnp.h" 29#include "wps_upnp_i.h" 30 31#ifndef CONFIG_WPS_STRICT 32#define WPS_WORKAROUNDS 33#endif /* CONFIG_WPS_STRICT */ 34 35struct wps_uuid_pin { 36 struct dl_list list; 37 u8 uuid[WPS_UUID_LEN]; 38 int wildcard_uuid; 39 u8 *pin; 40 size_t pin_len; 41#define PIN_LOCKED BIT(0) 42#define PIN_EXPIRES BIT(1) 43 int flags; 44 struct os_time expiration; 45 u8 enrollee_addr[ETH_ALEN]; 46}; 47 48 49static void wps_free_pin(struct wps_uuid_pin *pin) 50{ 51 os_free(pin->pin); 52 os_free(pin); 53} 54 55 56static void wps_remove_pin(struct wps_uuid_pin *pin) 57{ 58 dl_list_del(&pin->list); 59 wps_free_pin(pin); 60} 61 62 63static void wps_free_pins(struct dl_list *pins) 64{ 65 struct wps_uuid_pin *pin, *prev; 66 dl_list_for_each_safe(pin, prev, pins, struct wps_uuid_pin, list) 67 wps_remove_pin(pin); 68} 69 70 71struct wps_pbc_session { 72 struct wps_pbc_session *next; 73 u8 addr[ETH_ALEN]; 74 u8 uuid_e[WPS_UUID_LEN]; 75 struct os_time timestamp; 76}; 77 78 79static void wps_free_pbc_sessions(struct wps_pbc_session *pbc) 80{ 81 struct wps_pbc_session *prev; 82 83 while (pbc) { 84 prev = pbc; 85 pbc = pbc->next; 86 os_free(prev); 87 } 88} 89 90 91struct wps_registrar_device { 92 struct wps_registrar_device *next; 93 struct wps_device_data dev; 94 u8 uuid[WPS_UUID_LEN]; 95}; 96 97 98struct wps_registrar { 99 struct wps_context *wps; 100 101 int pbc; 102 int selected_registrar; 103 104 int (*new_psk_cb)(void *ctx, const u8 *mac_addr, const u8 *psk, 105 size_t psk_len); 106 int (*set_ie_cb)(void *ctx, struct wpabuf *beacon_ie, 107 struct wpabuf *probe_resp_ie); 108 void (*pin_needed_cb)(void *ctx, const u8 *uuid_e, 109 const struct wps_device_data *dev); 110 void (*reg_success_cb)(void *ctx, const u8 *mac_addr, 111 const u8 *uuid_e); 112 void (*set_sel_reg_cb)(void *ctx, int sel_reg, u16 dev_passwd_id, 113 u16 sel_reg_config_methods); 114 void (*enrollee_seen_cb)(void *ctx, const u8 *addr, const u8 *uuid_e, 115 const u8 *pri_dev_type, u16 config_methods, 116 u16 dev_password_id, u8 request_type, 117 const char *dev_name); 118 void *cb_ctx; 119 120 struct dl_list pins; 121 struct wps_pbc_session *pbc_sessions; 122 123 int skip_cred_build; 124 struct wpabuf *extra_cred; 125 int disable_auto_conf; 126 int sel_reg_union; 127 int sel_reg_dev_password_id_override; 128 int sel_reg_config_methods_override; 129 int static_wep_only; 130 int dualband; 131 132 struct wps_registrar_device *devices; 133 134 int force_pbc_overlap; 135 136 u8 authorized_macs[WPS_MAX_AUTHORIZED_MACS][ETH_ALEN]; 137 u8 authorized_macs_union[WPS_MAX_AUTHORIZED_MACS][ETH_ALEN]; 138 139 u8 p2p_dev_addr[ETH_ALEN]; 140}; 141 142 143static int wps_set_ie(struct wps_registrar *reg); 144static void wps_registrar_pbc_timeout(void *eloop_ctx, void *timeout_ctx); 145static void wps_registrar_set_selected_timeout(void *eloop_ctx, 146 void *timeout_ctx); 147 148 149static void wps_registrar_add_authorized_mac(struct wps_registrar *reg, 150 const u8 *addr) 151{ 152 int i; 153 wpa_printf(MSG_DEBUG, "WPS: Add authorized MAC " MACSTR, 154 MAC2STR(addr)); 155 for (i = 0; i < WPS_MAX_AUTHORIZED_MACS; i++) 156 if (os_memcmp(reg->authorized_macs[i], addr, ETH_ALEN) == 0) { 157 wpa_printf(MSG_DEBUG, "WPS: Authorized MAC was " 158 "already in the list"); 159 return; /* already in list */ 160 } 161 for (i = WPS_MAX_AUTHORIZED_MACS - 1; i > 0; i--) 162 os_memcpy(reg->authorized_macs[i], reg->authorized_macs[i - 1], 163 ETH_ALEN); 164 os_memcpy(reg->authorized_macs[0], addr, ETH_ALEN); 165 wpa_hexdump(MSG_DEBUG, "WPS: Authorized MACs", 166 (u8 *) reg->authorized_macs, sizeof(reg->authorized_macs)); 167} 168 169 170static void wps_registrar_remove_authorized_mac(struct wps_registrar *reg, 171 const u8 *addr) 172{ 173 int i; 174 wpa_printf(MSG_DEBUG, "WPS: Remove authorized MAC " MACSTR, 175 MAC2STR(addr)); 176 for (i = 0; i < WPS_MAX_AUTHORIZED_MACS; i++) { 177 if (os_memcmp(reg->authorized_macs, addr, ETH_ALEN) == 0) 178 break; 179 } 180 if (i == WPS_MAX_AUTHORIZED_MACS) { 181 wpa_printf(MSG_DEBUG, "WPS: Authorized MAC was not in the " 182 "list"); 183 return; /* not in the list */ 184 } 185 for (; i + 1 < WPS_MAX_AUTHORIZED_MACS; i++) 186 os_memcpy(reg->authorized_macs[i], reg->authorized_macs[i + 1], 187 ETH_ALEN); 188 os_memset(reg->authorized_macs[WPS_MAX_AUTHORIZED_MACS - 1], 0, 189 ETH_ALEN); 190 wpa_hexdump(MSG_DEBUG, "WPS: Authorized MACs", 191 (u8 *) reg->authorized_macs, sizeof(reg->authorized_macs)); 192} 193 194 195static void wps_free_devices(struct wps_registrar_device *dev) 196{ 197 struct wps_registrar_device *prev; 198 199 while (dev) { 200 prev = dev; 201 dev = dev->next; 202 wps_device_data_free(&prev->dev); 203 os_free(prev); 204 } 205} 206 207 208static struct wps_registrar_device * wps_device_get(struct wps_registrar *reg, 209 const u8 *addr) 210{ 211 struct wps_registrar_device *dev; 212 213 for (dev = reg->devices; dev; dev = dev->next) { 214 if (os_memcmp(dev->dev.mac_addr, addr, ETH_ALEN) == 0) 215 return dev; 216 } 217 return NULL; 218} 219 220 221static void wps_device_clone_data(struct wps_device_data *dst, 222 struct wps_device_data *src) 223{ 224 os_memcpy(dst->mac_addr, src->mac_addr, ETH_ALEN); 225 os_memcpy(dst->pri_dev_type, src->pri_dev_type, WPS_DEV_TYPE_LEN); 226 227#define WPS_STRDUP(n) \ 228 os_free(dst->n); \ 229 dst->n = src->n ? os_strdup(src->n) : NULL 230 231 WPS_STRDUP(device_name); 232 WPS_STRDUP(manufacturer); 233 WPS_STRDUP(model_name); 234 WPS_STRDUP(model_number); 235 WPS_STRDUP(serial_number); 236#undef WPS_STRDUP 237} 238 239 240int wps_device_store(struct wps_registrar *reg, 241 struct wps_device_data *dev, const u8 *uuid) 242{ 243 struct wps_registrar_device *d; 244 245 d = wps_device_get(reg, dev->mac_addr); 246 if (d == NULL) { 247 d = os_zalloc(sizeof(*d)); 248 if (d == NULL) 249 return -1; 250 d->next = reg->devices; 251 reg->devices = d; 252 } 253 254 wps_device_clone_data(&d->dev, dev); 255 os_memcpy(d->uuid, uuid, WPS_UUID_LEN); 256 257 return 0; 258} 259 260 261static void wps_registrar_add_pbc_session(struct wps_registrar *reg, 262 const u8 *addr, const u8 *uuid_e) 263{ 264 struct wps_pbc_session *pbc, *prev = NULL; 265 struct os_time now; 266 267 os_get_time(&now); 268 269 pbc = reg->pbc_sessions; 270 while (pbc) { 271 if (os_memcmp(pbc->addr, addr, ETH_ALEN) == 0 && 272 os_memcmp(pbc->uuid_e, uuid_e, WPS_UUID_LEN) == 0) { 273 if (prev) 274 prev->next = pbc->next; 275 else 276 reg->pbc_sessions = pbc->next; 277 break; 278 } 279 prev = pbc; 280 pbc = pbc->next; 281 } 282 283 if (!pbc) { 284 pbc = os_zalloc(sizeof(*pbc)); 285 if (pbc == NULL) 286 return; 287 os_memcpy(pbc->addr, addr, ETH_ALEN); 288 if (uuid_e) 289 os_memcpy(pbc->uuid_e, uuid_e, WPS_UUID_LEN); 290 } 291 292 pbc->next = reg->pbc_sessions; 293 reg->pbc_sessions = pbc; 294 pbc->timestamp = now; 295 296 /* remove entries that have timed out */ 297 prev = pbc; 298 pbc = pbc->next; 299 300 while (pbc) { 301 if (now.sec > pbc->timestamp.sec + WPS_PBC_WALK_TIME) { 302 prev->next = NULL; 303 wps_free_pbc_sessions(pbc); 304 break; 305 } 306 prev = pbc; 307 pbc = pbc->next; 308 } 309} 310 311 312static void wps_registrar_remove_pbc_session(struct wps_registrar *reg, 313 const u8 *uuid_e, 314 const u8 *p2p_dev_addr) 315{ 316 struct wps_pbc_session *pbc, *prev = NULL, *tmp; 317 318 pbc = reg->pbc_sessions; 319 while (pbc) { 320 if (os_memcmp(pbc->uuid_e, uuid_e, WPS_UUID_LEN) == 0 || 321 (p2p_dev_addr && !is_zero_ether_addr(reg->p2p_dev_addr) && 322 os_memcmp(reg->p2p_dev_addr, p2p_dev_addr, ETH_ALEN) == 323 0)) { 324 if (prev) 325 prev->next = pbc->next; 326 else 327 reg->pbc_sessions = pbc->next; 328 tmp = pbc; 329 pbc = pbc->next; 330 wpa_printf(MSG_DEBUG, "WPS: Removing PBC session for " 331 "addr=" MACSTR, MAC2STR(tmp->addr)); 332 wpa_hexdump(MSG_DEBUG, "WPS: Removed UUID-E", 333 tmp->uuid_e, WPS_UUID_LEN); 334 os_free(tmp); 335 continue; 336 } 337 prev = pbc; 338 pbc = pbc->next; 339 } 340} 341 342 343int wps_registrar_pbc_overlap(struct wps_registrar *reg, 344 const u8 *addr, const u8 *uuid_e) 345{ 346 int count = 0; 347 struct wps_pbc_session *pbc; 348 struct wps_pbc_session *first = NULL; 349 struct os_time now; 350 351 os_get_time(&now); 352 353 wpa_printf(MSG_DEBUG, "WPS: Checking active PBC sessions for overlap"); 354 355 if (uuid_e) { 356 wpa_printf(MSG_DEBUG, "WPS: Add one for the requested UUID"); 357 wpa_hexdump(MSG_DEBUG, "WPS: Requested UUID", 358 uuid_e, WPS_UUID_LEN); 359 count++; 360 } 361 362 for (pbc = reg->pbc_sessions; pbc; pbc = pbc->next) { 363 wpa_printf(MSG_DEBUG, "WPS: Consider PBC session with " MACSTR, 364 MAC2STR(pbc->addr)); 365 wpa_hexdump(MSG_DEBUG, "WPS: UUID-E", 366 pbc->uuid_e, WPS_UUID_LEN); 367 if (now.sec > pbc->timestamp.sec + WPS_PBC_WALK_TIME) { 368 wpa_printf(MSG_DEBUG, "WPS: PBC walk time has " 369 "expired"); 370 break; 371 } 372 if (first && 373 os_memcmp(pbc->uuid_e, first->uuid_e, WPS_UUID_LEN) == 0) { 374 wpa_printf(MSG_DEBUG, "WPS: Same Enrollee"); 375 continue; /* same Enrollee */ 376 } 377 if (uuid_e == NULL || 378 os_memcmp(uuid_e, pbc->uuid_e, WPS_UUID_LEN)) { 379 wpa_printf(MSG_DEBUG, "WPS: New Enrollee"); 380 count++; 381 } 382 if (first == NULL) 383 first = pbc; 384 } 385 386 wpa_printf(MSG_DEBUG, "WPS: %u active PBC session(s) found", count); 387 388 return count > 1 ? 1 : 0; 389} 390 391 392static int wps_build_wps_state(struct wps_context *wps, struct wpabuf *msg) 393{ 394 wpa_printf(MSG_DEBUG, "WPS: * Wi-Fi Protected Setup State (%d)", 395 wps->wps_state); 396 wpabuf_put_be16(msg, ATTR_WPS_STATE); 397 wpabuf_put_be16(msg, 1); 398 wpabuf_put_u8(msg, wps->wps_state); 399 return 0; 400} 401 402 403#ifdef CONFIG_WPS_UPNP 404static void wps_registrar_free_pending_m2(struct wps_context *wps) 405{ 406 struct upnp_pending_message *p, *p2, *prev = NULL; 407 p = wps->upnp_msgs; 408 while (p) { 409 if (p->type == WPS_M2 || p->type == WPS_M2D) { 410 if (prev == NULL) 411 wps->upnp_msgs = p->next; 412 else 413 prev->next = p->next; 414 wpa_printf(MSG_DEBUG, "WPS UPnP: Drop pending M2/M2D"); 415 p2 = p; 416 p = p->next; 417 wpabuf_free(p2->msg); 418 os_free(p2); 419 continue; 420 } 421 prev = p; 422 p = p->next; 423 } 424} 425#endif /* CONFIG_WPS_UPNP */ 426 427 428static int wps_build_ap_setup_locked(struct wps_context *wps, 429 struct wpabuf *msg) 430{ 431 if (wps->ap_setup_locked && wps->ap_setup_locked != 2) { 432 wpa_printf(MSG_DEBUG, "WPS: * AP Setup Locked"); 433 wpabuf_put_be16(msg, ATTR_AP_SETUP_LOCKED); 434 wpabuf_put_be16(msg, 1); 435 wpabuf_put_u8(msg, 1); 436 } 437 return 0; 438} 439 440 441static int wps_build_selected_registrar(struct wps_registrar *reg, 442 struct wpabuf *msg) 443{ 444 if (!reg->sel_reg_union) 445 return 0; 446 wpa_printf(MSG_DEBUG, "WPS: * Selected Registrar"); 447 wpabuf_put_be16(msg, ATTR_SELECTED_REGISTRAR); 448 wpabuf_put_be16(msg, 1); 449 wpabuf_put_u8(msg, 1); 450 return 0; 451} 452 453 454static int wps_build_sel_reg_dev_password_id(struct wps_registrar *reg, 455 struct wpabuf *msg) 456{ 457 u16 id = reg->pbc ? DEV_PW_PUSHBUTTON : DEV_PW_DEFAULT; 458 if (!reg->sel_reg_union) 459 return 0; 460 if (reg->sel_reg_dev_password_id_override >= 0) 461 id = reg->sel_reg_dev_password_id_override; 462 wpa_printf(MSG_DEBUG, "WPS: * Device Password ID (%d)", id); 463 wpabuf_put_be16(msg, ATTR_DEV_PASSWORD_ID); 464 wpabuf_put_be16(msg, 2); 465 wpabuf_put_be16(msg, id); 466 return 0; 467} 468 469 470static int wps_build_sel_pbc_reg_uuid_e(struct wps_registrar *reg, 471 struct wpabuf *msg) 472{ 473 u16 id = reg->pbc ? DEV_PW_PUSHBUTTON : DEV_PW_DEFAULT; 474 if (!reg->sel_reg_union) 475 return 0; 476 if (reg->sel_reg_dev_password_id_override >= 0) 477 id = reg->sel_reg_dev_password_id_override; 478 if (id != DEV_PW_PUSHBUTTON || !reg->dualband) 479 return 0; 480 return wps_build_uuid_e(msg, reg->wps->uuid); 481} 482 483 484static void wps_set_pushbutton(u16 *methods, u16 conf_methods) 485{ 486 *methods |= WPS_CONFIG_PUSHBUTTON; 487#ifdef CONFIG_WPS2 488 if (conf_methods & WPS_CONFIG_VIRT_PUSHBUTTON) 489 *methods |= WPS_CONFIG_VIRT_PUSHBUTTON; 490 if (conf_methods & WPS_CONFIG_PHY_PUSHBUTTON) 491 *methods |= WPS_CONFIG_PHY_PUSHBUTTON; 492 if (!(*methods & (WPS_CONFIG_VIRT_PUSHBUTTON | 493 WPS_CONFIG_PHY_PUSHBUTTON))) { 494 /* 495 * Required to include virtual/physical flag, but we were not 496 * configured with push button type, so have to default to one 497 * of them. 498 */ 499 *methods |= WPS_CONFIG_PHY_PUSHBUTTON; 500 } 501#endif /* CONFIG_WPS2 */ 502} 503 504 505static int wps_build_sel_reg_config_methods(struct wps_registrar *reg, 506 struct wpabuf *msg) 507{ 508 u16 methods; 509 if (!reg->sel_reg_union) 510 return 0; 511 methods = reg->wps->config_methods; 512 methods &= ~WPS_CONFIG_PUSHBUTTON; 513#ifdef CONFIG_WPS2 514 methods &= ~(WPS_CONFIG_VIRT_PUSHBUTTON | 515 WPS_CONFIG_PHY_PUSHBUTTON); 516#endif /* CONFIG_WPS2 */ 517 if (reg->pbc) 518 wps_set_pushbutton(&methods, reg->wps->config_methods); 519 if (reg->sel_reg_config_methods_override >= 0) 520 methods = reg->sel_reg_config_methods_override; 521 wpa_printf(MSG_DEBUG, "WPS: * Selected Registrar Config Methods (%x)", 522 methods); 523 wpabuf_put_be16(msg, ATTR_SELECTED_REGISTRAR_CONFIG_METHODS); 524 wpabuf_put_be16(msg, 2); 525 wpabuf_put_be16(msg, methods); 526 return 0; 527} 528 529 530static int wps_build_probe_config_methods(struct wps_registrar *reg, 531 struct wpabuf *msg) 532{ 533 u16 methods; 534 /* 535 * These are the methods that the AP supports as an Enrollee for adding 536 * external Registrars. 537 */ 538 methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON; 539#ifdef CONFIG_WPS2 540 methods &= ~(WPS_CONFIG_VIRT_PUSHBUTTON | 541 WPS_CONFIG_PHY_PUSHBUTTON); 542#endif /* CONFIG_WPS2 */ 543 wpa_printf(MSG_DEBUG, "WPS: * Config Methods (%x)", methods); 544 wpabuf_put_be16(msg, ATTR_CONFIG_METHODS); 545 wpabuf_put_be16(msg, 2); 546 wpabuf_put_be16(msg, methods); 547 return 0; 548} 549 550 551static int wps_build_config_methods_r(struct wps_registrar *reg, 552 struct wpabuf *msg) 553{ 554 return wps_build_config_methods(msg, reg->wps->config_methods); 555} 556 557 558const u8 * wps_authorized_macs(struct wps_registrar *reg, size_t *count) 559{ 560 *count = 0; 561 562#ifdef CONFIG_WPS2 563 while (*count < WPS_MAX_AUTHORIZED_MACS) { 564 if (is_zero_ether_addr(reg->authorized_macs_union[*count])) 565 break; 566 (*count)++; 567 } 568#endif /* CONFIG_WPS2 */ 569 570 return (const u8 *) reg->authorized_macs_union; 571} 572 573 574/** 575 * wps_registrar_init - Initialize WPS Registrar data 576 * @wps: Pointer to longterm WPS context 577 * @cfg: Registrar configuration 578 * Returns: Pointer to allocated Registrar data or %NULL on failure 579 * 580 * This function is used to initialize WPS Registrar functionality. It can be 581 * used for a single Registrar run (e.g., when run in a supplicant) or multiple 582 * runs (e.g., when run as an internal Registrar in an AP). Caller is 583 * responsible for freeing the returned data with wps_registrar_deinit() when 584 * Registrar functionality is not needed anymore. 585 */ 586struct wps_registrar * 587wps_registrar_init(struct wps_context *wps, 588 const struct wps_registrar_config *cfg) 589{ 590 struct wps_registrar *reg = os_zalloc(sizeof(*reg)); 591 if (reg == NULL) 592 return NULL; 593 594 dl_list_init(®->pins); 595 reg->wps = wps; 596 reg->new_psk_cb = cfg->new_psk_cb; 597 reg->set_ie_cb = cfg->set_ie_cb; 598 reg->pin_needed_cb = cfg->pin_needed_cb; 599 reg->reg_success_cb = cfg->reg_success_cb; 600 reg->set_sel_reg_cb = cfg->set_sel_reg_cb; 601 reg->enrollee_seen_cb = cfg->enrollee_seen_cb; 602 reg->cb_ctx = cfg->cb_ctx; 603 reg->skip_cred_build = cfg->skip_cred_build; 604 if (cfg->extra_cred) { 605 reg->extra_cred = wpabuf_alloc_copy(cfg->extra_cred, 606 cfg->extra_cred_len); 607 if (reg->extra_cred == NULL) { 608 os_free(reg); 609 return NULL; 610 } 611 } 612 reg->disable_auto_conf = cfg->disable_auto_conf; 613 reg->sel_reg_dev_password_id_override = -1; 614 reg->sel_reg_config_methods_override = -1; 615 reg->static_wep_only = cfg->static_wep_only; 616 reg->dualband = cfg->dualband; 617 618 if (wps_set_ie(reg)) { 619 wps_registrar_deinit(reg); 620 return NULL; 621 } 622 623 return reg; 624} 625 626 627/** 628 * wps_registrar_deinit - Deinitialize WPS Registrar data 629 * @reg: Registrar data from wps_registrar_init() 630 */ 631void wps_registrar_deinit(struct wps_registrar *reg) 632{ 633 if (reg == NULL) 634 return; 635 eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL); 636 eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL); 637 wps_free_pins(®->pins); 638 wps_free_pbc_sessions(reg->pbc_sessions); 639 wpabuf_free(reg->extra_cred); 640 wps_free_devices(reg->devices); 641 os_free(reg); 642} 643 644 645/** 646 * wps_registrar_add_pin - Configure a new PIN for Registrar 647 * @reg: Registrar data from wps_registrar_init() 648 * @addr: Enrollee MAC address or %NULL if not known 649 * @uuid: UUID-E or %NULL for wildcard (any UUID) 650 * @pin: PIN (Device Password) 651 * @pin_len: Length of pin in octets 652 * @timeout: Time (in seconds) when the PIN will be invalidated; 0 = no timeout 653 * Returns: 0 on success, -1 on failure 654 */ 655int wps_registrar_add_pin(struct wps_registrar *reg, const u8 *addr, 656 const u8 *uuid, const u8 *pin, size_t pin_len, 657 int timeout) 658{ 659 struct wps_uuid_pin *p; 660 661 p = os_zalloc(sizeof(*p)); 662 if (p == NULL) 663 return -1; 664 if (addr) 665 os_memcpy(p->enrollee_addr, addr, ETH_ALEN); 666 if (uuid == NULL) 667 p->wildcard_uuid = 1; 668 else 669 os_memcpy(p->uuid, uuid, WPS_UUID_LEN); 670 p->pin = os_malloc(pin_len); 671 if (p->pin == NULL) { 672 os_free(p); 673 return -1; 674 } 675 os_memcpy(p->pin, pin, pin_len); 676 p->pin_len = pin_len; 677 678 if (timeout) { 679 p->flags |= PIN_EXPIRES; 680 os_get_time(&p->expiration); 681 p->expiration.sec += timeout; 682 } 683 684 dl_list_add(®->pins, &p->list); 685 686 wpa_printf(MSG_DEBUG, "WPS: A new PIN configured (timeout=%d)", 687 timeout); 688 wpa_hexdump(MSG_DEBUG, "WPS: UUID", uuid, WPS_UUID_LEN); 689 wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: PIN", pin, pin_len); 690 reg->selected_registrar = 1; 691 reg->pbc = 0; 692 if (addr) 693 wps_registrar_add_authorized_mac(reg, addr); 694 else 695 wps_registrar_add_authorized_mac( 696 reg, (u8 *) "\xff\xff\xff\xff\xff\xff"); 697 wps_registrar_selected_registrar_changed(reg); 698 eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL); 699 eloop_register_timeout(WPS_PBC_WALK_TIME, 0, 700 wps_registrar_set_selected_timeout, 701 reg, NULL); 702 703 return 0; 704} 705 706 707static void wps_registrar_remove_pin(struct wps_registrar *reg, 708 struct wps_uuid_pin *pin) 709{ 710 u8 *addr; 711 u8 bcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 712 713 if (is_zero_ether_addr(pin->enrollee_addr)) 714 addr = bcast; 715 else 716 addr = pin->enrollee_addr; 717 wps_registrar_remove_authorized_mac(reg, addr); 718 wps_remove_pin(pin); 719 wps_registrar_selected_registrar_changed(reg); 720} 721 722 723static void wps_registrar_expire_pins(struct wps_registrar *reg) 724{ 725 struct wps_uuid_pin *pin, *prev; 726 struct os_time now; 727 728 os_get_time(&now); 729 dl_list_for_each_safe(pin, prev, ®->pins, struct wps_uuid_pin, list) 730 { 731 if ((pin->flags & PIN_EXPIRES) && 732 os_time_before(&pin->expiration, &now)) { 733 wpa_hexdump(MSG_DEBUG, "WPS: Expired PIN for UUID", 734 pin->uuid, WPS_UUID_LEN); 735 wps_registrar_remove_pin(reg, pin); 736 } 737 } 738} 739 740 741/** 742 * wps_registrar_invalidate_wildcard_pin - Invalidate a wildcard PIN 743 * @reg: Registrar data from wps_registrar_init() 744 * Returns: 0 on success, -1 if not wildcard PIN is enabled 745 */ 746static int wps_registrar_invalidate_wildcard_pin(struct wps_registrar *reg) 747{ 748 struct wps_uuid_pin *pin, *prev; 749 750 dl_list_for_each_safe(pin, prev, ®->pins, struct wps_uuid_pin, list) 751 { 752 if (pin->wildcard_uuid) { 753 wpa_hexdump(MSG_DEBUG, "WPS: Invalidated PIN for UUID", 754 pin->uuid, WPS_UUID_LEN); 755 wps_registrar_remove_pin(reg, pin); 756 return 0; 757 } 758 } 759 760 return -1; 761} 762 763 764/** 765 * wps_registrar_invalidate_pin - Invalidate a PIN for a specific UUID-E 766 * @reg: Registrar data from wps_registrar_init() 767 * @uuid: UUID-E 768 * Returns: 0 on success, -1 on failure (e.g., PIN not found) 769 */ 770int wps_registrar_invalidate_pin(struct wps_registrar *reg, const u8 *uuid) 771{ 772 struct wps_uuid_pin *pin, *prev; 773 774 dl_list_for_each_safe(pin, prev, ®->pins, struct wps_uuid_pin, list) 775 { 776 if (os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) { 777 wpa_hexdump(MSG_DEBUG, "WPS: Invalidated PIN for UUID", 778 pin->uuid, WPS_UUID_LEN); 779 wps_registrar_remove_pin(reg, pin); 780 return 0; 781 } 782 } 783 784 return -1; 785} 786 787 788static const u8 * wps_registrar_get_pin(struct wps_registrar *reg, 789 const u8 *uuid, size_t *pin_len) 790{ 791 struct wps_uuid_pin *pin, *found = NULL; 792 793 wps_registrar_expire_pins(reg); 794 795 dl_list_for_each(pin, ®->pins, struct wps_uuid_pin, list) { 796 if (!pin->wildcard_uuid && 797 os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) { 798 found = pin; 799 break; 800 } 801 } 802 803 if (!found) { 804 /* Check for wildcard UUIDs since none of the UUID-specific 805 * PINs matched */ 806 dl_list_for_each(pin, ®->pins, struct wps_uuid_pin, list) { 807 if (pin->wildcard_uuid == 1) { 808 wpa_printf(MSG_DEBUG, "WPS: Found a wildcard " 809 "PIN. Assigned it for this UUID-E"); 810 pin->wildcard_uuid = 2; 811 os_memcpy(pin->uuid, uuid, WPS_UUID_LEN); 812 found = pin; 813 break; 814 } 815 } 816 } 817 818 if (!found) 819 return NULL; 820 821 /* 822 * Lock the PIN to avoid attacks based on concurrent re-use of the PIN 823 * that could otherwise avoid PIN invalidations. 824 */ 825 if (found->flags & PIN_LOCKED) { 826 wpa_printf(MSG_DEBUG, "WPS: Selected PIN locked - do not " 827 "allow concurrent re-use"); 828 return NULL; 829 } 830 *pin_len = found->pin_len; 831 found->flags |= PIN_LOCKED; 832 return found->pin; 833} 834 835 836/** 837 * wps_registrar_unlock_pin - Unlock a PIN for a specific UUID-E 838 * @reg: Registrar data from wps_registrar_init() 839 * @uuid: UUID-E 840 * Returns: 0 on success, -1 on failure 841 * 842 * PINs are locked to enforce only one concurrent use. This function unlocks a 843 * PIN to allow it to be used again. If the specified PIN was configured using 844 * a wildcard UUID, it will be removed instead of allowing multiple uses. 845 */ 846int wps_registrar_unlock_pin(struct wps_registrar *reg, const u8 *uuid) 847{ 848 struct wps_uuid_pin *pin; 849 850 dl_list_for_each(pin, ®->pins, struct wps_uuid_pin, list) { 851 if (os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) { 852 if (pin->wildcard_uuid == 2) { 853 wpa_printf(MSG_DEBUG, "WPS: Invalidating used " 854 "wildcard PIN"); 855 return wps_registrar_invalidate_pin(reg, uuid); 856 } 857 pin->flags &= ~PIN_LOCKED; 858 return 0; 859 } 860 } 861 862 return -1; 863} 864 865 866static void wps_registrar_stop_pbc(struct wps_registrar *reg) 867{ 868 reg->selected_registrar = 0; 869 reg->pbc = 0; 870 os_memset(reg->p2p_dev_addr, 0, ETH_ALEN); 871 wps_registrar_remove_authorized_mac(reg, 872 (u8 *) "\xff\xff\xff\xff\xff\xff"); 873 wps_registrar_selected_registrar_changed(reg); 874} 875 876 877static void wps_registrar_pbc_timeout(void *eloop_ctx, void *timeout_ctx) 878{ 879 struct wps_registrar *reg = eloop_ctx; 880 881 wpa_printf(MSG_DEBUG, "WPS: PBC timed out - disable PBC mode"); 882 wps_pbc_timeout_event(reg->wps); 883 wps_registrar_stop_pbc(reg); 884} 885 886 887/** 888 * wps_registrar_button_pushed - Notify Registrar that AP button was pushed 889 * @reg: Registrar data from wps_registrar_init() 890 * @p2p_dev_addr: Limit allowed PBC devices to the specified P2P device, %NULL 891 * indicates no such filtering 892 * Returns: 0 on success, -1 on failure, -2 on session overlap 893 * 894 * This function is called on an AP when a push button is pushed to activate 895 * PBC mode. The PBC mode will be stopped after walk time (2 minutes) timeout 896 * or when a PBC registration is completed. If more than one Enrollee in active 897 * PBC mode has been detected during the monitor time (previous 2 minutes), the 898 * PBC mode is not activated and -2 is returned to indicate session overlap. 899 * This is skipped if a specific Enrollee is selected. 900 */ 901int wps_registrar_button_pushed(struct wps_registrar *reg, 902 const u8 *p2p_dev_addr) 903{ 904 if (p2p_dev_addr == NULL && 905 wps_registrar_pbc_overlap(reg, NULL, NULL)) { 906 wpa_printf(MSG_DEBUG, "WPS: PBC overlap - do not start PBC " 907 "mode"); 908 wps_pbc_overlap_event(reg->wps); 909 return -2; 910 } 911 wpa_printf(MSG_DEBUG, "WPS: Button pushed - PBC mode started"); 912 reg->force_pbc_overlap = 0; 913 reg->selected_registrar = 1; 914 reg->pbc = 1; 915 if (p2p_dev_addr) 916 os_memcpy(reg->p2p_dev_addr, p2p_dev_addr, ETH_ALEN); 917 else 918 os_memset(reg->p2p_dev_addr, 0, ETH_ALEN); 919 wps_registrar_add_authorized_mac(reg, 920 (u8 *) "\xff\xff\xff\xff\xff\xff"); 921 wps_registrar_selected_registrar_changed(reg); 922 923 eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL); 924 eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL); 925 eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wps_registrar_pbc_timeout, 926 reg, NULL); 927 return 0; 928} 929 930 931static void wps_registrar_pbc_completed(struct wps_registrar *reg) 932{ 933 wpa_printf(MSG_DEBUG, "WPS: PBC completed - stopping PBC mode"); 934 eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL); 935 wps_registrar_stop_pbc(reg); 936} 937 938 939static void wps_registrar_pin_completed(struct wps_registrar *reg) 940{ 941 wpa_printf(MSG_DEBUG, "WPS: PIN completed using internal Registrar"); 942 eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL); 943 reg->selected_registrar = 0; 944 wps_registrar_selected_registrar_changed(reg); 945} 946 947 948void wps_registrar_complete(struct wps_registrar *registrar, const u8 *uuid_e) 949{ 950 if (registrar->pbc) { 951 wps_registrar_remove_pbc_session(registrar, 952 uuid_e, NULL); 953 wps_registrar_pbc_completed(registrar); 954 } else { 955 wps_registrar_pin_completed(registrar); 956 } 957} 958 959 960int wps_registrar_wps_cancel(struct wps_registrar *reg) 961{ 962 if (reg->pbc) { 963 wpa_printf(MSG_DEBUG, "WPS: PBC is set - cancelling it"); 964 wps_registrar_pbc_timeout(reg, NULL); 965 return 1; 966 } else if (reg->selected_registrar) { 967 /* PIN Method */ 968 wpa_printf(MSG_DEBUG, "WPS: PIN is set - cancelling it"); 969 wps_registrar_pin_completed(reg); 970 wps_registrar_invalidate_wildcard_pin(reg); 971 return 1; 972 } 973 return 0; 974} 975 976 977/** 978 * wps_registrar_probe_req_rx - Notify Registrar of Probe Request 979 * @reg: Registrar data from wps_registrar_init() 980 * @addr: MAC address of the Probe Request sender 981 * @wps_data: WPS IE contents 982 * 983 * This function is called on an AP when a Probe Request with WPS IE is 984 * received. This is used to track PBC mode use and to detect possible overlap 985 * situation with other WPS APs. 986 */ 987void wps_registrar_probe_req_rx(struct wps_registrar *reg, const u8 *addr, 988 const struct wpabuf *wps_data, 989 int p2p_wildcard) 990{ 991 struct wps_parse_attr attr; 992 993 wpa_hexdump_buf(MSG_MSGDUMP, 994 "WPS: Probe Request with WPS data received", 995 wps_data); 996 997 if (wps_parse_msg(wps_data, &attr) < 0) 998 return; 999 1000 if (attr.config_methods == NULL) { 1001 wpa_printf(MSG_DEBUG, "WPS: No Config Methods attribute in " 1002 "Probe Request"); 1003 return; 1004 } 1005 1006 if (attr.dev_password_id == NULL) { 1007 wpa_printf(MSG_DEBUG, "WPS: No Device Password Id attribute " 1008 "in Probe Request"); 1009 return; 1010 } 1011 1012 if (reg->enrollee_seen_cb && attr.uuid_e && 1013 attr.primary_dev_type && attr.request_type && !p2p_wildcard) { 1014 char *dev_name = NULL; 1015 if (attr.dev_name) { 1016 dev_name = os_zalloc(attr.dev_name_len + 1); 1017 if (dev_name) { 1018 os_memcpy(dev_name, attr.dev_name, 1019 attr.dev_name_len); 1020 } 1021 } 1022 reg->enrollee_seen_cb(reg->cb_ctx, addr, attr.uuid_e, 1023 attr.primary_dev_type, 1024 WPA_GET_BE16(attr.config_methods), 1025 WPA_GET_BE16(attr.dev_password_id), 1026 *attr.request_type, dev_name); 1027 os_free(dev_name); 1028 } 1029 1030 if (WPA_GET_BE16(attr.dev_password_id) != DEV_PW_PUSHBUTTON) 1031 return; /* Not PBC */ 1032 1033 wpa_printf(MSG_DEBUG, "WPS: Probe Request for PBC received from " 1034 MACSTR, MAC2STR(addr)); 1035 if (attr.uuid_e == NULL) { 1036 wpa_printf(MSG_DEBUG, "WPS: Invalid Probe Request WPS IE: No " 1037 "UUID-E included"); 1038 return; 1039 } 1040 wpa_hexdump(MSG_DEBUG, "WPS: UUID-E from Probe Request", attr.uuid_e, 1041 WPS_UUID_LEN); 1042 1043 wps_registrar_add_pbc_session(reg, addr, attr.uuid_e); 1044 if (wps_registrar_pbc_overlap(reg, addr, attr.uuid_e)) { 1045 wpa_printf(MSG_DEBUG, "WPS: PBC session overlap detected"); 1046 reg->force_pbc_overlap = 1; 1047 wps_pbc_overlap_event(reg->wps); 1048 } 1049} 1050 1051 1052static int wps_cb_new_psk(struct wps_registrar *reg, const u8 *mac_addr, 1053 const u8 *psk, size_t psk_len) 1054{ 1055 if (reg->new_psk_cb == NULL) 1056 return 0; 1057 1058 return reg->new_psk_cb(reg->cb_ctx, mac_addr, psk, psk_len); 1059} 1060 1061 1062static void wps_cb_pin_needed(struct wps_registrar *reg, const u8 *uuid_e, 1063 const struct wps_device_data *dev) 1064{ 1065 if (reg->pin_needed_cb == NULL) 1066 return; 1067 1068 reg->pin_needed_cb(reg->cb_ctx, uuid_e, dev); 1069} 1070 1071 1072static void wps_cb_reg_success(struct wps_registrar *reg, const u8 *mac_addr, 1073 const u8 *uuid_e) 1074{ 1075 if (reg->reg_success_cb == NULL) 1076 return; 1077 1078 reg->reg_success_cb(reg->cb_ctx, mac_addr, uuid_e); 1079} 1080 1081 1082static int wps_cb_set_ie(struct wps_registrar *reg, struct wpabuf *beacon_ie, 1083 struct wpabuf *probe_resp_ie) 1084{ 1085 return reg->set_ie_cb(reg->cb_ctx, beacon_ie, probe_resp_ie); 1086} 1087 1088 1089static void wps_cb_set_sel_reg(struct wps_registrar *reg) 1090{ 1091 u16 methods = 0; 1092 if (reg->set_sel_reg_cb == NULL) 1093 return; 1094 1095 if (reg->selected_registrar) { 1096 methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON; 1097#ifdef CONFIG_WPS2 1098 methods &= ~(WPS_CONFIG_VIRT_PUSHBUTTON | 1099 WPS_CONFIG_PHY_PUSHBUTTON); 1100#endif /* CONFIG_WPS2 */ 1101 if (reg->pbc) 1102 wps_set_pushbutton(&methods, reg->wps->config_methods); 1103 } 1104 1105 wpa_printf(MSG_DEBUG, "WPS: wps_cb_set_sel_reg: sel_reg=%d " 1106 "config_methods=0x%x pbc=%d methods=0x%x", 1107 reg->selected_registrar, reg->wps->config_methods, 1108 reg->pbc, methods); 1109 1110 reg->set_sel_reg_cb(reg->cb_ctx, reg->selected_registrar, 1111 reg->pbc ? DEV_PW_PUSHBUTTON : DEV_PW_DEFAULT, 1112 methods); 1113} 1114 1115 1116static int wps_set_ie(struct wps_registrar *reg) 1117{ 1118 struct wpabuf *beacon; 1119 struct wpabuf *probe; 1120 const u8 *auth_macs; 1121 size_t count; 1122 size_t vendor_len = 0; 1123 int i; 1124 1125 if (reg->set_ie_cb == NULL) 1126 return 0; 1127 1128 for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++) { 1129 if (reg->wps->dev.vendor_ext[i]) { 1130 vendor_len += 2 + 2; 1131 vendor_len += wpabuf_len(reg->wps->dev.vendor_ext[i]); 1132 } 1133 } 1134 1135 beacon = wpabuf_alloc(400 + vendor_len); 1136 if (beacon == NULL) 1137 return -1; 1138 probe = wpabuf_alloc(500 + vendor_len); 1139 if (probe == NULL) { 1140 wpabuf_free(beacon); 1141 return -1; 1142 } 1143 1144 auth_macs = wps_authorized_macs(reg, &count); 1145 1146 wpa_printf(MSG_DEBUG, "WPS: Build Beacon IEs"); 1147 1148 if (wps_build_version(beacon) || 1149 wps_build_wps_state(reg->wps, beacon) || 1150 wps_build_ap_setup_locked(reg->wps, beacon) || 1151 wps_build_selected_registrar(reg, beacon) || 1152 wps_build_sel_reg_dev_password_id(reg, beacon) || 1153 wps_build_sel_reg_config_methods(reg, beacon) || 1154 wps_build_sel_pbc_reg_uuid_e(reg, beacon) || 1155 (reg->dualband && wps_build_rf_bands(®->wps->dev, beacon)) || 1156 wps_build_wfa_ext(beacon, 0, auth_macs, count) || 1157 wps_build_vendor_ext(®->wps->dev, beacon)) { 1158 wpabuf_free(beacon); 1159 wpabuf_free(probe); 1160 return -1; 1161 } 1162 1163#ifdef CONFIG_P2P 1164 if (wps_build_dev_name(®->wps->dev, beacon) || 1165 wps_build_primary_dev_type(®->wps->dev, beacon)) { 1166 wpabuf_free(beacon); 1167 wpabuf_free(probe); 1168 return -1; 1169 } 1170#endif /* CONFIG_P2P */ 1171 1172 wpa_printf(MSG_DEBUG, "WPS: Build Probe Response IEs"); 1173 1174 if (wps_build_version(probe) || 1175 wps_build_wps_state(reg->wps, probe) || 1176 wps_build_ap_setup_locked(reg->wps, probe) || 1177 wps_build_selected_registrar(reg, probe) || 1178 wps_build_sel_reg_dev_password_id(reg, probe) || 1179 wps_build_sel_reg_config_methods(reg, probe) || 1180 wps_build_resp_type(probe, reg->wps->ap ? WPS_RESP_AP : 1181 WPS_RESP_REGISTRAR) || 1182 wps_build_uuid_e(probe, reg->wps->uuid) || 1183 wps_build_device_attrs(®->wps->dev, probe) || 1184 wps_build_probe_config_methods(reg, probe) || 1185 wps_build_rf_bands(®->wps->dev, probe) || 1186 wps_build_wfa_ext(probe, 0, auth_macs, count) || 1187 wps_build_vendor_ext(®->wps->dev, probe)) { 1188 wpabuf_free(beacon); 1189 wpabuf_free(probe); 1190 return -1; 1191 } 1192 1193 beacon = wps_ie_encapsulate(beacon); 1194 probe = wps_ie_encapsulate(probe); 1195 1196 if (!beacon || !probe) { 1197 wpabuf_free(beacon); 1198 wpabuf_free(probe); 1199 return -1; 1200 } 1201 1202 if (reg->static_wep_only) { 1203 /* 1204 * Windows XP and Vista clients can get confused about 1205 * EAP-Identity/Request when they probe the network with 1206 * EAPOL-Start. In such a case, they may assume the network is 1207 * using IEEE 802.1X and prompt user for a certificate while 1208 * the correct (non-WPS) behavior would be to ask for the 1209 * static WEP key. As a workaround, use Microsoft Provisioning 1210 * IE to advertise that legacy 802.1X is not supported. 1211 */ 1212 const u8 ms_wps[7] = { 1213 WLAN_EID_VENDOR_SPECIFIC, 5, 1214 /* Microsoft Provisioning IE (00:50:f2:5) */ 1215 0x00, 0x50, 0xf2, 5, 1216 0x00 /* no legacy 802.1X or MS WPS */ 1217 }; 1218 wpa_printf(MSG_DEBUG, "WPS: Add Microsoft Provisioning IE " 1219 "into Beacon/Probe Response frames"); 1220 wpabuf_put_data(beacon, ms_wps, sizeof(ms_wps)); 1221 wpabuf_put_data(probe, ms_wps, sizeof(ms_wps)); 1222 } 1223 1224 return wps_cb_set_ie(reg, beacon, probe); 1225} 1226 1227 1228static int wps_get_dev_password(struct wps_data *wps) 1229{ 1230 const u8 *pin; 1231 size_t pin_len = 0; 1232 1233 os_free(wps->dev_password); 1234 wps->dev_password = NULL; 1235 1236 if (wps->pbc) { 1237 wpa_printf(MSG_DEBUG, "WPS: Use default PIN for PBC"); 1238 pin = (const u8 *) "00000000"; 1239 pin_len = 8; 1240 } else { 1241 pin = wps_registrar_get_pin(wps->wps->registrar, wps->uuid_e, 1242 &pin_len); 1243 } 1244 if (pin == NULL) { 1245 wpa_printf(MSG_DEBUG, "WPS: No Device Password available for " 1246 "the Enrollee"); 1247 wps_cb_pin_needed(wps->wps->registrar, wps->uuid_e, 1248 &wps->peer_dev); 1249 return -1; 1250 } 1251 1252 wps->dev_password = os_malloc(pin_len); 1253 if (wps->dev_password == NULL) 1254 return -1; 1255 os_memcpy(wps->dev_password, pin, pin_len); 1256 wps->dev_password_len = pin_len; 1257 1258 return 0; 1259} 1260 1261 1262static int wps_build_uuid_r(struct wps_data *wps, struct wpabuf *msg) 1263{ 1264 wpa_printf(MSG_DEBUG, "WPS: * UUID-R"); 1265 wpabuf_put_be16(msg, ATTR_UUID_R); 1266 wpabuf_put_be16(msg, WPS_UUID_LEN); 1267 wpabuf_put_data(msg, wps->uuid_r, WPS_UUID_LEN); 1268 return 0; 1269} 1270 1271 1272static int wps_build_r_hash(struct wps_data *wps, struct wpabuf *msg) 1273{ 1274 u8 *hash; 1275 const u8 *addr[4]; 1276 size_t len[4]; 1277 1278 if (random_get_bytes(wps->snonce, 2 * WPS_SECRET_NONCE_LEN) < 0) 1279 return -1; 1280 wpa_hexdump(MSG_DEBUG, "WPS: R-S1", wps->snonce, WPS_SECRET_NONCE_LEN); 1281 wpa_hexdump(MSG_DEBUG, "WPS: R-S2", 1282 wps->snonce + WPS_SECRET_NONCE_LEN, WPS_SECRET_NONCE_LEN); 1283 1284 if (wps->dh_pubkey_e == NULL || wps->dh_pubkey_r == NULL) { 1285 wpa_printf(MSG_DEBUG, "WPS: DH public keys not available for " 1286 "R-Hash derivation"); 1287 return -1; 1288 } 1289 1290 wpa_printf(MSG_DEBUG, "WPS: * R-Hash1"); 1291 wpabuf_put_be16(msg, ATTR_R_HASH1); 1292 wpabuf_put_be16(msg, SHA256_MAC_LEN); 1293 hash = wpabuf_put(msg, SHA256_MAC_LEN); 1294 /* R-Hash1 = HMAC_AuthKey(R-S1 || PSK1 || PK_E || PK_R) */ 1295 addr[0] = wps->snonce; 1296 len[0] = WPS_SECRET_NONCE_LEN; 1297 addr[1] = wps->psk1; 1298 len[1] = WPS_PSK_LEN; 1299 addr[2] = wpabuf_head(wps->dh_pubkey_e); 1300 len[2] = wpabuf_len(wps->dh_pubkey_e); 1301 addr[3] = wpabuf_head(wps->dh_pubkey_r); 1302 len[3] = wpabuf_len(wps->dh_pubkey_r); 1303 hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash); 1304 wpa_hexdump(MSG_DEBUG, "WPS: R-Hash1", hash, SHA256_MAC_LEN); 1305 1306 wpa_printf(MSG_DEBUG, "WPS: * R-Hash2"); 1307 wpabuf_put_be16(msg, ATTR_R_HASH2); 1308 wpabuf_put_be16(msg, SHA256_MAC_LEN); 1309 hash = wpabuf_put(msg, SHA256_MAC_LEN); 1310 /* R-Hash2 = HMAC_AuthKey(R-S2 || PSK2 || PK_E || PK_R) */ 1311 addr[0] = wps->snonce + WPS_SECRET_NONCE_LEN; 1312 addr[1] = wps->psk2; 1313 hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash); 1314 wpa_hexdump(MSG_DEBUG, "WPS: R-Hash2", hash, SHA256_MAC_LEN); 1315 1316 return 0; 1317} 1318 1319 1320static int wps_build_r_snonce1(struct wps_data *wps, struct wpabuf *msg) 1321{ 1322 wpa_printf(MSG_DEBUG, "WPS: * R-SNonce1"); 1323 wpabuf_put_be16(msg, ATTR_R_SNONCE1); 1324 wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN); 1325 wpabuf_put_data(msg, wps->snonce, WPS_SECRET_NONCE_LEN); 1326 return 0; 1327} 1328 1329 1330static int wps_build_r_snonce2(struct wps_data *wps, struct wpabuf *msg) 1331{ 1332 wpa_printf(MSG_DEBUG, "WPS: * R-SNonce2"); 1333 wpabuf_put_be16(msg, ATTR_R_SNONCE2); 1334 wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN); 1335 wpabuf_put_data(msg, wps->snonce + WPS_SECRET_NONCE_LEN, 1336 WPS_SECRET_NONCE_LEN); 1337 return 0; 1338} 1339 1340 1341static int wps_build_cred_network_idx(struct wpabuf *msg, 1342 const struct wps_credential *cred) 1343{ 1344 wpa_printf(MSG_DEBUG, "WPS: * Network Index (1)"); 1345 wpabuf_put_be16(msg, ATTR_NETWORK_INDEX); 1346 wpabuf_put_be16(msg, 1); 1347 wpabuf_put_u8(msg, 1); 1348 return 0; 1349} 1350 1351 1352static int wps_build_cred_ssid(struct wpabuf *msg, 1353 const struct wps_credential *cred) 1354{ 1355 wpa_printf(MSG_DEBUG, "WPS: * SSID"); 1356 wpa_hexdump_ascii(MSG_DEBUG, "WPS: SSID for Credential", 1357 cred->ssid, cred->ssid_len); 1358 wpabuf_put_be16(msg, ATTR_SSID); 1359 wpabuf_put_be16(msg, cred->ssid_len); 1360 wpabuf_put_data(msg, cred->ssid, cred->ssid_len); 1361 return 0; 1362} 1363 1364 1365static int wps_build_cred_auth_type(struct wpabuf *msg, 1366 const struct wps_credential *cred) 1367{ 1368 wpa_printf(MSG_DEBUG, "WPS: * Authentication Type (0x%x)", 1369 cred->auth_type); 1370 wpabuf_put_be16(msg, ATTR_AUTH_TYPE); 1371 wpabuf_put_be16(msg, 2); 1372 wpabuf_put_be16(msg, cred->auth_type); 1373 return 0; 1374} 1375 1376 1377static int wps_build_cred_encr_type(struct wpabuf *msg, 1378 const struct wps_credential *cred) 1379{ 1380 wpa_printf(MSG_DEBUG, "WPS: * Encryption Type (0x%x)", 1381 cred->encr_type); 1382 wpabuf_put_be16(msg, ATTR_ENCR_TYPE); 1383 wpabuf_put_be16(msg, 2); 1384 wpabuf_put_be16(msg, cred->encr_type); 1385 return 0; 1386} 1387 1388 1389static int wps_build_cred_network_key(struct wpabuf *msg, 1390 const struct wps_credential *cred) 1391{ 1392 wpa_printf(MSG_DEBUG, "WPS: * Network Key (len=%d)", 1393 (int) cred->key_len); 1394 wpa_hexdump_key(MSG_DEBUG, "WPS: Network Key", 1395 cred->key, cred->key_len); 1396 wpabuf_put_be16(msg, ATTR_NETWORK_KEY); 1397 wpabuf_put_be16(msg, cred->key_len); 1398 wpabuf_put_data(msg, cred->key, cred->key_len); 1399 return 0; 1400} 1401 1402 1403static int wps_build_cred_mac_addr(struct wpabuf *msg, 1404 const struct wps_credential *cred) 1405{ 1406 wpa_printf(MSG_DEBUG, "WPS: * MAC Address (" MACSTR ")", 1407 MAC2STR(cred->mac_addr)); 1408 wpabuf_put_be16(msg, ATTR_MAC_ADDR); 1409 wpabuf_put_be16(msg, ETH_ALEN); 1410 wpabuf_put_data(msg, cred->mac_addr, ETH_ALEN); 1411 return 0; 1412} 1413 1414 1415static int wps_build_credential(struct wpabuf *msg, 1416 const struct wps_credential *cred) 1417{ 1418 if (wps_build_cred_network_idx(msg, cred) || 1419 wps_build_cred_ssid(msg, cred) || 1420 wps_build_cred_auth_type(msg, cred) || 1421 wps_build_cred_encr_type(msg, cred) || 1422 wps_build_cred_network_key(msg, cred) || 1423 wps_build_cred_mac_addr(msg, cred)) 1424 return -1; 1425 return 0; 1426} 1427 1428 1429int wps_build_credential_wrap(struct wpabuf *msg, 1430 const struct wps_credential *cred) 1431{ 1432 struct wpabuf *wbuf; 1433 wbuf = wpabuf_alloc(200); 1434 if (wbuf == NULL) 1435 return -1; 1436 if (wps_build_credential(wbuf, cred)) { 1437 wpabuf_free(wbuf); 1438 return -1; 1439 } 1440 wpabuf_put_be16(msg, ATTR_CRED); 1441 wpabuf_put_be16(msg, wpabuf_len(wbuf)); 1442 wpabuf_put_buf(msg, wbuf); 1443 wpabuf_free(wbuf); 1444 return 0; 1445} 1446 1447 1448int wps_build_cred(struct wps_data *wps, struct wpabuf *msg) 1449{ 1450 struct wpabuf *cred; 1451 1452 if (wps->wps->registrar->skip_cred_build) 1453 goto skip_cred_build; 1454 1455 wpa_printf(MSG_DEBUG, "WPS: * Credential"); 1456 if (wps->use_cred) { 1457 os_memcpy(&wps->cred, wps->use_cred, sizeof(wps->cred)); 1458 goto use_provided; 1459 } 1460 os_memset(&wps->cred, 0, sizeof(wps->cred)); 1461 1462 os_memcpy(wps->cred.ssid, wps->wps->ssid, wps->wps->ssid_len); 1463 wps->cred.ssid_len = wps->wps->ssid_len; 1464 1465 /* Select the best authentication and encryption type */ 1466 if (wps->auth_type & WPS_AUTH_WPA2PSK) 1467 wps->auth_type = WPS_AUTH_WPA2PSK; 1468 else if (wps->auth_type & WPS_AUTH_WPAPSK) 1469 wps->auth_type = WPS_AUTH_WPAPSK; 1470 else if (wps->auth_type & WPS_AUTH_OPEN) 1471 wps->auth_type = WPS_AUTH_OPEN; 1472 else if (wps->auth_type & WPS_AUTH_SHARED) 1473 wps->auth_type = WPS_AUTH_SHARED; 1474 else { 1475 wpa_printf(MSG_DEBUG, "WPS: Unsupported auth_type 0x%x", 1476 wps->auth_type); 1477 return -1; 1478 } 1479 wps->cred.auth_type = wps->auth_type; 1480 1481 if (wps->auth_type == WPS_AUTH_WPA2PSK || 1482 wps->auth_type == WPS_AUTH_WPAPSK) { 1483 if (wps->encr_type & WPS_ENCR_AES) 1484 wps->encr_type = WPS_ENCR_AES; 1485 else if (wps->encr_type & WPS_ENCR_TKIP) 1486 wps->encr_type = WPS_ENCR_TKIP; 1487 else { 1488 wpa_printf(MSG_DEBUG, "WPS: No suitable encryption " 1489 "type for WPA/WPA2"); 1490 return -1; 1491 } 1492 } else { 1493 if (wps->encr_type & WPS_ENCR_WEP) 1494 wps->encr_type = WPS_ENCR_WEP; 1495 else if (wps->encr_type & WPS_ENCR_NONE) 1496 wps->encr_type = WPS_ENCR_NONE; 1497 else { 1498 wpa_printf(MSG_DEBUG, "WPS: No suitable encryption " 1499 "type for non-WPA/WPA2 mode"); 1500 return -1; 1501 } 1502 } 1503 wps->cred.encr_type = wps->encr_type; 1504 /* 1505 * Set MAC address in the Credential to be the Enrollee's MAC address 1506 */ 1507 os_memcpy(wps->cred.mac_addr, wps->mac_addr_e, ETH_ALEN); 1508 1509 if (wps->wps->wps_state == WPS_STATE_NOT_CONFIGURED && wps->wps->ap && 1510 !wps->wps->registrar->disable_auto_conf) { 1511 u8 r[16]; 1512 /* Generate a random passphrase */ 1513 if (random_get_bytes(r, sizeof(r)) < 0) 1514 return -1; 1515 os_free(wps->new_psk); 1516 wps->new_psk = base64_encode(r, sizeof(r), &wps->new_psk_len); 1517 if (wps->new_psk == NULL) 1518 return -1; 1519 wps->new_psk_len--; /* remove newline */ 1520 while (wps->new_psk_len && 1521 wps->new_psk[wps->new_psk_len - 1] == '=') 1522 wps->new_psk_len--; 1523 wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: Generated passphrase", 1524 wps->new_psk, wps->new_psk_len); 1525 os_memcpy(wps->cred.key, wps->new_psk, wps->new_psk_len); 1526 wps->cred.key_len = wps->new_psk_len; 1527 } else if (wps->use_psk_key && wps->wps->psk_set) { 1528 char hex[65]; 1529 wpa_printf(MSG_DEBUG, "WPS: Use PSK format for Network Key"); 1530 wpa_snprintf_hex(hex, sizeof(hex), wps->wps->psk, 32); 1531 os_memcpy(wps->cred.key, hex, 32 * 2); 1532 wps->cred.key_len = 32 * 2; 1533 } else if (wps->wps->network_key) { 1534 os_memcpy(wps->cred.key, wps->wps->network_key, 1535 wps->wps->network_key_len); 1536 wps->cred.key_len = wps->wps->network_key_len; 1537 } else if (wps->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) { 1538 char hex[65]; 1539 /* Generate a random per-device PSK */ 1540 os_free(wps->new_psk); 1541 wps->new_psk_len = 32; 1542 wps->new_psk = os_malloc(wps->new_psk_len); 1543 if (wps->new_psk == NULL) 1544 return -1; 1545 if (random_get_bytes(wps->new_psk, wps->new_psk_len) < 0) { 1546 os_free(wps->new_psk); 1547 wps->new_psk = NULL; 1548 return -1; 1549 } 1550 wpa_hexdump_key(MSG_DEBUG, "WPS: Generated per-device PSK", 1551 wps->new_psk, wps->new_psk_len); 1552 wpa_snprintf_hex(hex, sizeof(hex), wps->new_psk, 1553 wps->new_psk_len); 1554 os_memcpy(wps->cred.key, hex, wps->new_psk_len * 2); 1555 wps->cred.key_len = wps->new_psk_len * 2; 1556 } 1557 1558use_provided: 1559#ifdef CONFIG_WPS_TESTING 1560 if (wps_testing_dummy_cred) 1561 cred = wpabuf_alloc(200); 1562 else 1563 cred = NULL; 1564 if (cred) { 1565 struct wps_credential dummy; 1566 wpa_printf(MSG_DEBUG, "WPS: Add dummy credential"); 1567 os_memset(&dummy, 0, sizeof(dummy)); 1568 os_memcpy(dummy.ssid, "dummy", 5); 1569 dummy.ssid_len = 5; 1570 dummy.auth_type = WPS_AUTH_WPA2PSK; 1571 dummy.encr_type = WPS_ENCR_AES; 1572 os_memcpy(dummy.key, "dummy psk", 9); 1573 dummy.key_len = 9; 1574 os_memcpy(dummy.mac_addr, wps->mac_addr_e, ETH_ALEN); 1575 wps_build_credential(cred, &dummy); 1576 wpa_hexdump_buf(MSG_DEBUG, "WPS: Dummy Credential", cred); 1577 1578 wpabuf_put_be16(msg, ATTR_CRED); 1579 wpabuf_put_be16(msg, wpabuf_len(cred)); 1580 wpabuf_put_buf(msg, cred); 1581 1582 wpabuf_free(cred); 1583 } 1584#endif /* CONFIG_WPS_TESTING */ 1585 1586 cred = wpabuf_alloc(200); 1587 if (cred == NULL) 1588 return -1; 1589 1590 if (wps_build_credential(cred, &wps->cred)) { 1591 wpabuf_free(cred); 1592 return -1; 1593 } 1594 1595 wpabuf_put_be16(msg, ATTR_CRED); 1596 wpabuf_put_be16(msg, wpabuf_len(cred)); 1597 wpabuf_put_buf(msg, cred); 1598 wpabuf_free(cred); 1599 1600skip_cred_build: 1601 if (wps->wps->registrar->extra_cred) { 1602 wpa_printf(MSG_DEBUG, "WPS: * Credential (pre-configured)"); 1603 wpabuf_put_buf(msg, wps->wps->registrar->extra_cred); 1604 } 1605 1606 return 0; 1607} 1608 1609 1610static int wps_build_ap_settings(struct wps_data *wps, struct wpabuf *msg) 1611{ 1612 wpa_printf(MSG_DEBUG, "WPS: * AP Settings"); 1613 1614 if (wps_build_credential(msg, &wps->cred)) 1615 return -1; 1616 1617 return 0; 1618} 1619 1620 1621static struct wpabuf * wps_build_ap_cred(struct wps_data *wps) 1622{ 1623 struct wpabuf *msg, *plain; 1624 1625 msg = wpabuf_alloc(1000); 1626 if (msg == NULL) 1627 return NULL; 1628 1629 plain = wpabuf_alloc(200); 1630 if (plain == NULL) { 1631 wpabuf_free(msg); 1632 return NULL; 1633 } 1634 1635 if (wps_build_ap_settings(wps, plain)) { 1636 wpabuf_free(plain); 1637 wpabuf_free(msg); 1638 return NULL; 1639 } 1640 1641 wpabuf_put_be16(msg, ATTR_CRED); 1642 wpabuf_put_be16(msg, wpabuf_len(plain)); 1643 wpabuf_put_buf(msg, plain); 1644 wpabuf_free(plain); 1645 1646 return msg; 1647} 1648 1649 1650static struct wpabuf * wps_build_m2(struct wps_data *wps) 1651{ 1652 struct wpabuf *msg; 1653 1654 if (random_get_bytes(wps->nonce_r, WPS_NONCE_LEN) < 0) 1655 return NULL; 1656 wpa_hexdump(MSG_DEBUG, "WPS: Registrar Nonce", 1657 wps->nonce_r, WPS_NONCE_LEN); 1658 wpa_hexdump(MSG_DEBUG, "WPS: UUID-R", wps->uuid_r, WPS_UUID_LEN); 1659 1660 wpa_printf(MSG_DEBUG, "WPS: Building Message M2"); 1661 msg = wpabuf_alloc(1000); 1662 if (msg == NULL) 1663 return NULL; 1664 1665 if (wps_build_version(msg) || 1666 wps_build_msg_type(msg, WPS_M2) || 1667 wps_build_enrollee_nonce(wps, msg) || 1668 wps_build_registrar_nonce(wps, msg) || 1669 wps_build_uuid_r(wps, msg) || 1670 wps_build_public_key(wps, msg) || 1671 wps_derive_keys(wps) || 1672 wps_build_auth_type_flags(wps, msg) || 1673 wps_build_encr_type_flags(wps, msg) || 1674 wps_build_conn_type_flags(wps, msg) || 1675 wps_build_config_methods_r(wps->wps->registrar, msg) || 1676 wps_build_device_attrs(&wps->wps->dev, msg) || 1677 wps_build_rf_bands(&wps->wps->dev, msg) || 1678 wps_build_assoc_state(wps, msg) || 1679 wps_build_config_error(msg, WPS_CFG_NO_ERROR) || 1680 wps_build_dev_password_id(msg, wps->dev_pw_id) || 1681 wps_build_os_version(&wps->wps->dev, msg) || 1682 wps_build_wfa_ext(msg, 0, NULL, 0) || 1683 wps_build_authenticator(wps, msg)) { 1684 wpabuf_free(msg); 1685 return NULL; 1686 } 1687 1688 wps->int_reg = 1; 1689 wps->state = RECV_M3; 1690 return msg; 1691} 1692 1693 1694static struct wpabuf * wps_build_m2d(struct wps_data *wps) 1695{ 1696 struct wpabuf *msg; 1697 u16 err = wps->config_error; 1698 1699 wpa_printf(MSG_DEBUG, "WPS: Building Message M2D"); 1700 msg = wpabuf_alloc(1000); 1701 if (msg == NULL) 1702 return NULL; 1703 1704 if (wps->wps->ap && wps->wps->ap_setup_locked && 1705 err == WPS_CFG_NO_ERROR) 1706 err = WPS_CFG_SETUP_LOCKED; 1707 1708 if (wps_build_version(msg) || 1709 wps_build_msg_type(msg, WPS_M2D) || 1710 wps_build_enrollee_nonce(wps, msg) || 1711 wps_build_registrar_nonce(wps, msg) || 1712 wps_build_uuid_r(wps, msg) || 1713 wps_build_auth_type_flags(wps, msg) || 1714 wps_build_encr_type_flags(wps, msg) || 1715 wps_build_conn_type_flags(wps, msg) || 1716 wps_build_config_methods_r(wps->wps->registrar, msg) || 1717 wps_build_device_attrs(&wps->wps->dev, msg) || 1718 wps_build_rf_bands(&wps->wps->dev, msg) || 1719 wps_build_assoc_state(wps, msg) || 1720 wps_build_config_error(msg, err) || 1721 wps_build_os_version(&wps->wps->dev, msg) || 1722 wps_build_wfa_ext(msg, 0, NULL, 0)) { 1723 wpabuf_free(msg); 1724 return NULL; 1725 } 1726 1727 wps->state = RECV_M2D_ACK; 1728 return msg; 1729} 1730 1731 1732static struct wpabuf * wps_build_m4(struct wps_data *wps) 1733{ 1734 struct wpabuf *msg, *plain; 1735 1736 wpa_printf(MSG_DEBUG, "WPS: Building Message M4"); 1737 1738 wps_derive_psk(wps, wps->dev_password, wps->dev_password_len); 1739 1740 plain = wpabuf_alloc(200); 1741 if (plain == NULL) 1742 return NULL; 1743 1744 msg = wpabuf_alloc(1000); 1745 if (msg == NULL) { 1746 wpabuf_free(plain); 1747 return NULL; 1748 } 1749 1750 if (wps_build_version(msg) || 1751 wps_build_msg_type(msg, WPS_M4) || 1752 wps_build_enrollee_nonce(wps, msg) || 1753 wps_build_r_hash(wps, msg) || 1754 wps_build_r_snonce1(wps, plain) || 1755 wps_build_key_wrap_auth(wps, plain) || 1756 wps_build_encr_settings(wps, msg, plain) || 1757 wps_build_wfa_ext(msg, 0, NULL, 0) || 1758 wps_build_authenticator(wps, msg)) { 1759 wpabuf_free(plain); 1760 wpabuf_free(msg); 1761 return NULL; 1762 } 1763 wpabuf_free(plain); 1764 1765 wps->state = RECV_M5; 1766 return msg; 1767} 1768 1769 1770static struct wpabuf * wps_build_m6(struct wps_data *wps) 1771{ 1772 struct wpabuf *msg, *plain; 1773 1774 wpa_printf(MSG_DEBUG, "WPS: Building Message M6"); 1775 1776 plain = wpabuf_alloc(200); 1777 if (plain == NULL) 1778 return NULL; 1779 1780 msg = wpabuf_alloc(1000); 1781 if (msg == NULL) { 1782 wpabuf_free(plain); 1783 return NULL; 1784 } 1785 1786 if (wps_build_version(msg) || 1787 wps_build_msg_type(msg, WPS_M6) || 1788 wps_build_enrollee_nonce(wps, msg) || 1789 wps_build_r_snonce2(wps, plain) || 1790 wps_build_key_wrap_auth(wps, plain) || 1791 wps_build_encr_settings(wps, msg, plain) || 1792 wps_build_wfa_ext(msg, 0, NULL, 0) || 1793 wps_build_authenticator(wps, msg)) { 1794 wpabuf_free(plain); 1795 wpabuf_free(msg); 1796 return NULL; 1797 } 1798 wpabuf_free(plain); 1799 1800 wps->wps_pin_revealed = 1; 1801 wps->state = RECV_M7; 1802 return msg; 1803} 1804 1805 1806static struct wpabuf * wps_build_m8(struct wps_data *wps) 1807{ 1808 struct wpabuf *msg, *plain; 1809 1810 wpa_printf(MSG_DEBUG, "WPS: Building Message M8"); 1811 1812 plain = wpabuf_alloc(500); 1813 if (plain == NULL) 1814 return NULL; 1815 1816 msg = wpabuf_alloc(1000); 1817 if (msg == NULL) { 1818 wpabuf_free(plain); 1819 return NULL; 1820 } 1821 1822 if (wps_build_version(msg) || 1823 wps_build_msg_type(msg, WPS_M8) || 1824 wps_build_enrollee_nonce(wps, msg) || 1825 ((wps->wps->ap || wps->er) && wps_build_cred(wps, plain)) || 1826 (!wps->wps->ap && !wps->er && wps_build_ap_settings(wps, plain)) || 1827 wps_build_key_wrap_auth(wps, plain) || 1828 wps_build_encr_settings(wps, msg, plain) || 1829 wps_build_wfa_ext(msg, 0, NULL, 0) || 1830 wps_build_authenticator(wps, msg)) { 1831 wpabuf_free(plain); 1832 wpabuf_free(msg); 1833 return NULL; 1834 } 1835 wpabuf_free(plain); 1836 1837 wps->state = RECV_DONE; 1838 return msg; 1839} 1840 1841 1842struct wpabuf * wps_registrar_get_msg(struct wps_data *wps, 1843 enum wsc_op_code *op_code) 1844{ 1845 struct wpabuf *msg; 1846 1847#ifdef CONFIG_WPS_UPNP 1848 if (!wps->int_reg && wps->wps->wps_upnp) { 1849 struct upnp_pending_message *p, *prev = NULL; 1850 if (wps->ext_reg > 1) 1851 wps_registrar_free_pending_m2(wps->wps); 1852 p = wps->wps->upnp_msgs; 1853 /* TODO: check pending message MAC address */ 1854 while (p && p->next) { 1855 prev = p; 1856 p = p->next; 1857 } 1858 if (p) { 1859 wpa_printf(MSG_DEBUG, "WPS: Use pending message from " 1860 "UPnP"); 1861 if (prev) 1862 prev->next = NULL; 1863 else 1864 wps->wps->upnp_msgs = NULL; 1865 msg = p->msg; 1866 switch (p->type) { 1867 case WPS_WSC_ACK: 1868 *op_code = WSC_ACK; 1869 break; 1870 case WPS_WSC_NACK: 1871 *op_code = WSC_NACK; 1872 break; 1873 default: 1874 *op_code = WSC_MSG; 1875 break; 1876 } 1877 os_free(p); 1878 if (wps->ext_reg == 0) 1879 wps->ext_reg = 1; 1880 return msg; 1881 } 1882 } 1883 if (wps->ext_reg) { 1884 wpa_printf(MSG_DEBUG, "WPS: Using external Registrar, but no " 1885 "pending message available"); 1886 return NULL; 1887 } 1888#endif /* CONFIG_WPS_UPNP */ 1889 1890 switch (wps->state) { 1891 case SEND_M2: 1892 if (wps_get_dev_password(wps) < 0) 1893 msg = wps_build_m2d(wps); 1894 else 1895 msg = wps_build_m2(wps); 1896 *op_code = WSC_MSG; 1897 break; 1898 case SEND_M2D: 1899 msg = wps_build_m2d(wps); 1900 *op_code = WSC_MSG; 1901 break; 1902 case SEND_M4: 1903 msg = wps_build_m4(wps); 1904 *op_code = WSC_MSG; 1905 break; 1906 case SEND_M6: 1907 msg = wps_build_m6(wps); 1908 *op_code = WSC_MSG; 1909 break; 1910 case SEND_M8: 1911 msg = wps_build_m8(wps); 1912 *op_code = WSC_MSG; 1913 break; 1914 case RECV_DONE: 1915 msg = wps_build_wsc_ack(wps); 1916 *op_code = WSC_ACK; 1917 break; 1918 case SEND_WSC_NACK: 1919 msg = wps_build_wsc_nack(wps); 1920 *op_code = WSC_NACK; 1921 break; 1922 default: 1923 wpa_printf(MSG_DEBUG, "WPS: Unsupported state %d for building " 1924 "a message", wps->state); 1925 msg = NULL; 1926 break; 1927 } 1928 1929 if (*op_code == WSC_MSG && msg) { 1930 /* Save a copy of the last message for Authenticator derivation 1931 */ 1932 wpabuf_free(wps->last_msg); 1933 wps->last_msg = wpabuf_dup(msg); 1934 } 1935 1936 return msg; 1937} 1938 1939 1940static int wps_process_enrollee_nonce(struct wps_data *wps, const u8 *e_nonce) 1941{ 1942 if (e_nonce == NULL) { 1943 wpa_printf(MSG_DEBUG, "WPS: No Enrollee Nonce received"); 1944 return -1; 1945 } 1946 1947 os_memcpy(wps->nonce_e, e_nonce, WPS_NONCE_LEN); 1948 wpa_hexdump(MSG_DEBUG, "WPS: Enrollee Nonce", 1949 wps->nonce_e, WPS_NONCE_LEN); 1950 1951 return 0; 1952} 1953 1954 1955static int wps_process_registrar_nonce(struct wps_data *wps, const u8 *r_nonce) 1956{ 1957 if (r_nonce == NULL) { 1958 wpa_printf(MSG_DEBUG, "WPS: No Registrar Nonce received"); 1959 return -1; 1960 } 1961 1962 if (os_memcmp(wps->nonce_r, r_nonce, WPS_NONCE_LEN) != 0) { 1963 wpa_printf(MSG_DEBUG, "WPS: Invalid Registrar Nonce received"); 1964 return -1; 1965 } 1966 1967 return 0; 1968} 1969 1970 1971static int wps_process_uuid_e(struct wps_data *wps, const u8 *uuid_e) 1972{ 1973 if (uuid_e == NULL) { 1974 wpa_printf(MSG_DEBUG, "WPS: No UUID-E received"); 1975 return -1; 1976 } 1977 1978 os_memcpy(wps->uuid_e, uuid_e, WPS_UUID_LEN); 1979 wpa_hexdump(MSG_DEBUG, "WPS: UUID-E", wps->uuid_e, WPS_UUID_LEN); 1980 1981 return 0; 1982} 1983 1984 1985static int wps_process_dev_password_id(struct wps_data *wps, const u8 *pw_id) 1986{ 1987 if (pw_id == NULL) { 1988 wpa_printf(MSG_DEBUG, "WPS: No Device Password ID received"); 1989 return -1; 1990 } 1991 1992 wps->dev_pw_id = WPA_GET_BE16(pw_id); 1993 wpa_printf(MSG_DEBUG, "WPS: Device Password ID %d", wps->dev_pw_id); 1994 1995 return 0; 1996} 1997 1998 1999static int wps_process_e_hash1(struct wps_data *wps, const u8 *e_hash1) 2000{ 2001 if (e_hash1 == NULL) { 2002 wpa_printf(MSG_DEBUG, "WPS: No E-Hash1 received"); 2003 return -1; 2004 } 2005 2006 os_memcpy(wps->peer_hash1, e_hash1, WPS_HASH_LEN); 2007 wpa_hexdump(MSG_DEBUG, "WPS: E-Hash1", wps->peer_hash1, WPS_HASH_LEN); 2008 2009 return 0; 2010} 2011 2012 2013static int wps_process_e_hash2(struct wps_data *wps, const u8 *e_hash2) 2014{ 2015 if (e_hash2 == NULL) { 2016 wpa_printf(MSG_DEBUG, "WPS: No E-Hash2 received"); 2017 return -1; 2018 } 2019 2020 os_memcpy(wps->peer_hash2, e_hash2, WPS_HASH_LEN); 2021 wpa_hexdump(MSG_DEBUG, "WPS: E-Hash2", wps->peer_hash2, WPS_HASH_LEN); 2022 2023 return 0; 2024} 2025 2026 2027static int wps_process_e_snonce1(struct wps_data *wps, const u8 *e_snonce1) 2028{ 2029 u8 hash[SHA256_MAC_LEN]; 2030 const u8 *addr[4]; 2031 size_t len[4]; 2032 2033 if (e_snonce1 == NULL) { 2034 wpa_printf(MSG_DEBUG, "WPS: No E-SNonce1 received"); 2035 return -1; 2036 } 2037 2038 wpa_hexdump_key(MSG_DEBUG, "WPS: E-SNonce1", e_snonce1, 2039 WPS_SECRET_NONCE_LEN); 2040 2041 /* E-Hash1 = HMAC_AuthKey(E-S1 || PSK1 || PK_E || PK_R) */ 2042 addr[0] = e_snonce1; 2043 len[0] = WPS_SECRET_NONCE_LEN; 2044 addr[1] = wps->psk1; 2045 len[1] = WPS_PSK_LEN; 2046 addr[2] = wpabuf_head(wps->dh_pubkey_e); 2047 len[2] = wpabuf_len(wps->dh_pubkey_e); 2048 addr[3] = wpabuf_head(wps->dh_pubkey_r); 2049 len[3] = wpabuf_len(wps->dh_pubkey_r); 2050 hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash); 2051 2052 if (os_memcmp(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) { 2053 wpa_printf(MSG_DEBUG, "WPS: E-Hash1 derived from E-S1 does " 2054 "not match with the pre-committed value"); 2055 wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE; 2056 wps_pwd_auth_fail_event(wps->wps, 0, 1); 2057 return -1; 2058 } 2059 2060 wpa_printf(MSG_DEBUG, "WPS: Enrollee proved knowledge of the first " 2061 "half of the device password"); 2062 2063 return 0; 2064} 2065 2066 2067static int wps_process_e_snonce2(struct wps_data *wps, const u8 *e_snonce2) 2068{ 2069 u8 hash[SHA256_MAC_LEN]; 2070 const u8 *addr[4]; 2071 size_t len[4]; 2072 2073 if (e_snonce2 == NULL) { 2074 wpa_printf(MSG_DEBUG, "WPS: No E-SNonce2 received"); 2075 return -1; 2076 } 2077 2078 wpa_hexdump_key(MSG_DEBUG, "WPS: E-SNonce2", e_snonce2, 2079 WPS_SECRET_NONCE_LEN); 2080 2081 /* E-Hash2 = HMAC_AuthKey(E-S2 || PSK2 || PK_E || PK_R) */ 2082 addr[0] = e_snonce2; 2083 len[0] = WPS_SECRET_NONCE_LEN; 2084 addr[1] = wps->psk2; 2085 len[1] = WPS_PSK_LEN; 2086 addr[2] = wpabuf_head(wps->dh_pubkey_e); 2087 len[2] = wpabuf_len(wps->dh_pubkey_e); 2088 addr[3] = wpabuf_head(wps->dh_pubkey_r); 2089 len[3] = wpabuf_len(wps->dh_pubkey_r); 2090 hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash); 2091 2092 if (os_memcmp(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) { 2093 wpa_printf(MSG_DEBUG, "WPS: E-Hash2 derived from E-S2 does " 2094 "not match with the pre-committed value"); 2095 wps_registrar_invalidate_pin(wps->wps->registrar, wps->uuid_e); 2096 wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE; 2097 wps_pwd_auth_fail_event(wps->wps, 0, 2); 2098 return -1; 2099 } 2100 2101 wpa_printf(MSG_DEBUG, "WPS: Enrollee proved knowledge of the second " 2102 "half of the device password"); 2103 wps->wps_pin_revealed = 0; 2104 wps_registrar_unlock_pin(wps->wps->registrar, wps->uuid_e); 2105 2106 return 0; 2107} 2108 2109 2110static int wps_process_mac_addr(struct wps_data *wps, const u8 *mac_addr) 2111{ 2112 if (mac_addr == NULL) { 2113 wpa_printf(MSG_DEBUG, "WPS: No MAC Address received"); 2114 return -1; 2115 } 2116 2117 wpa_printf(MSG_DEBUG, "WPS: Enrollee MAC Address " MACSTR, 2118 MAC2STR(mac_addr)); 2119 os_memcpy(wps->mac_addr_e, mac_addr, ETH_ALEN); 2120 os_memcpy(wps->peer_dev.mac_addr, mac_addr, ETH_ALEN); 2121 2122 return 0; 2123} 2124 2125 2126static int wps_process_pubkey(struct wps_data *wps, const u8 *pk, 2127 size_t pk_len) 2128{ 2129 if (pk == NULL || pk_len == 0) { 2130 wpa_printf(MSG_DEBUG, "WPS: No Public Key received"); 2131 return -1; 2132 } 2133 2134#ifdef CONFIG_WPS_OOB 2135 if (wps->wps->oob_conf.pubkey_hash != NULL) { 2136 const u8 *addr[1]; 2137 u8 hash[WPS_HASH_LEN]; 2138 2139 addr[0] = pk; 2140 sha256_vector(1, addr, &pk_len, hash); 2141 if (os_memcmp(hash, 2142 wpabuf_head(wps->wps->oob_conf.pubkey_hash), 2143 WPS_OOB_PUBKEY_HASH_LEN) != 0) { 2144 wpa_printf(MSG_ERROR, "WPS: Public Key hash error"); 2145 return -1; 2146 } 2147 } 2148#endif /* CONFIG_WPS_OOB */ 2149 2150 wpabuf_free(wps->dh_pubkey_e); 2151 wps->dh_pubkey_e = wpabuf_alloc_copy(pk, pk_len); 2152 if (wps->dh_pubkey_e == NULL) 2153 return -1; 2154 2155 return 0; 2156} 2157 2158 2159static int wps_process_auth_type_flags(struct wps_data *wps, const u8 *auth) 2160{ 2161 u16 auth_types; 2162 2163 if (auth == NULL) { 2164 wpa_printf(MSG_DEBUG, "WPS: No Authentication Type flags " 2165 "received"); 2166 return -1; 2167 } 2168 2169 auth_types = WPA_GET_BE16(auth); 2170 2171 wpa_printf(MSG_DEBUG, "WPS: Enrollee Authentication Type flags 0x%x", 2172 auth_types); 2173 wps->auth_type = wps->wps->auth_types & auth_types; 2174 if (wps->auth_type == 0) { 2175 wpa_printf(MSG_DEBUG, "WPS: No match in supported " 2176 "authentication types (own 0x%x Enrollee 0x%x)", 2177 wps->wps->auth_types, auth_types); 2178#ifdef WPS_WORKAROUNDS 2179 /* 2180 * Some deployed implementations seem to advertise incorrect 2181 * information in this attribute. For example, Linksys WRT350N 2182 * seems to have a byteorder bug that breaks this negotiation. 2183 * In order to interoperate with existing implementations, 2184 * assume that the Enrollee supports everything we do. 2185 */ 2186 wpa_printf(MSG_DEBUG, "WPS: Workaround - assume Enrollee " 2187 "does not advertise supported authentication types " 2188 "correctly"); 2189 wps->auth_type = wps->wps->auth_types; 2190#else /* WPS_WORKAROUNDS */ 2191 return -1; 2192#endif /* WPS_WORKAROUNDS */ 2193 } 2194 2195 return 0; 2196} 2197 2198 2199static int wps_process_encr_type_flags(struct wps_data *wps, const u8 *encr) 2200{ 2201 u16 encr_types; 2202 2203 if (encr == NULL) { 2204 wpa_printf(MSG_DEBUG, "WPS: No Encryption Type flags " 2205 "received"); 2206 return -1; 2207 } 2208 2209 encr_types = WPA_GET_BE16(encr); 2210 2211 wpa_printf(MSG_DEBUG, "WPS: Enrollee Encryption Type flags 0x%x", 2212 encr_types); 2213 wps->encr_type = wps->wps->encr_types & encr_types; 2214 if (wps->encr_type == 0) { 2215 wpa_printf(MSG_DEBUG, "WPS: No match in supported " 2216 "encryption types (own 0x%x Enrollee 0x%x)", 2217 wps->wps->encr_types, encr_types); 2218#ifdef WPS_WORKAROUNDS 2219 /* 2220 * Some deployed implementations seem to advertise incorrect 2221 * information in this attribute. For example, Linksys WRT350N 2222 * seems to have a byteorder bug that breaks this negotiation. 2223 * In order to interoperate with existing implementations, 2224 * assume that the Enrollee supports everything we do. 2225 */ 2226 wpa_printf(MSG_DEBUG, "WPS: Workaround - assume Enrollee " 2227 "does not advertise supported encryption types " 2228 "correctly"); 2229 wps->encr_type = wps->wps->encr_types; 2230#else /* WPS_WORKAROUNDS */ 2231 return -1; 2232#endif /* WPS_WORKAROUNDS */ 2233 } 2234 2235 return 0; 2236} 2237 2238 2239static int wps_process_conn_type_flags(struct wps_data *wps, const u8 *conn) 2240{ 2241 if (conn == NULL) { 2242 wpa_printf(MSG_DEBUG, "WPS: No Connection Type flags " 2243 "received"); 2244 return -1; 2245 } 2246 2247 wpa_printf(MSG_DEBUG, "WPS: Enrollee Connection Type flags 0x%x", 2248 *conn); 2249 2250 return 0; 2251} 2252 2253 2254static int wps_process_config_methods(struct wps_data *wps, const u8 *methods) 2255{ 2256 u16 m; 2257 2258 if (methods == NULL) { 2259 wpa_printf(MSG_DEBUG, "WPS: No Config Methods received"); 2260 return -1; 2261 } 2262 2263 m = WPA_GET_BE16(methods); 2264 2265 wpa_printf(MSG_DEBUG, "WPS: Enrollee Config Methods 0x%x" 2266 "%s%s%s%s%s%s%s%s%s", m, 2267 m & WPS_CONFIG_USBA ? " [USBA]" : "", 2268 m & WPS_CONFIG_ETHERNET ? " [Ethernet]" : "", 2269 m & WPS_CONFIG_LABEL ? " [Label]" : "", 2270 m & WPS_CONFIG_DISPLAY ? " [Display]" : "", 2271 m & WPS_CONFIG_EXT_NFC_TOKEN ? " [Ext NFC Token]" : "", 2272 m & WPS_CONFIG_INT_NFC_TOKEN ? " [Int NFC Token]" : "", 2273 m & WPS_CONFIG_NFC_INTERFACE ? " [NFC]" : "", 2274 m & WPS_CONFIG_PUSHBUTTON ? " [PBC]" : "", 2275 m & WPS_CONFIG_KEYPAD ? " [Keypad]" : ""); 2276 2277 if (!(m & WPS_CONFIG_DISPLAY) && !wps->use_psk_key) { 2278 /* 2279 * The Enrollee does not have a display so it is unlikely to be 2280 * able to show the passphrase to a user and as such, could 2281 * benefit from receiving PSK to reduce key derivation time. 2282 */ 2283 wpa_printf(MSG_DEBUG, "WPS: Prefer PSK format key due to " 2284 "Enrollee not supporting display"); 2285 wps->use_psk_key = 1; 2286 } 2287 2288 return 0; 2289} 2290 2291 2292static int wps_process_wps_state(struct wps_data *wps, const u8 *state) 2293{ 2294 if (state == NULL) { 2295 wpa_printf(MSG_DEBUG, "WPS: No Wi-Fi Protected Setup State " 2296 "received"); 2297 return -1; 2298 } 2299 2300 wpa_printf(MSG_DEBUG, "WPS: Enrollee Wi-Fi Protected Setup State %d", 2301 *state); 2302 2303 return 0; 2304} 2305 2306 2307static int wps_process_assoc_state(struct wps_data *wps, const u8 *assoc) 2308{ 2309 u16 a; 2310 2311 if (assoc == NULL) { 2312 wpa_printf(MSG_DEBUG, "WPS: No Association State received"); 2313 return -1; 2314 } 2315 2316 a = WPA_GET_BE16(assoc); 2317 wpa_printf(MSG_DEBUG, "WPS: Enrollee Association State %d", a); 2318 2319 return 0; 2320} 2321 2322 2323static int wps_process_config_error(struct wps_data *wps, const u8 *err) 2324{ 2325 u16 e; 2326 2327 if (err == NULL) { 2328 wpa_printf(MSG_DEBUG, "WPS: No Configuration Error received"); 2329 return -1; 2330 } 2331 2332 e = WPA_GET_BE16(err); 2333 wpa_printf(MSG_DEBUG, "WPS: Enrollee Configuration Error %d", e); 2334 2335 return 0; 2336} 2337 2338 2339static int wps_registrar_p2p_dev_addr_match(struct wps_data *wps) 2340{ 2341#ifdef CONFIG_P2P 2342 struct wps_registrar *reg = wps->wps->registrar; 2343 2344 if (is_zero_ether_addr(reg->p2p_dev_addr)) 2345 return 1; /* no filtering in use */ 2346 2347 if (os_memcmp(reg->p2p_dev_addr, wps->p2p_dev_addr, ETH_ALEN) != 0) { 2348 wpa_printf(MSG_DEBUG, "WPS: No match on P2P Device Address " 2349 "filtering for PBC: expected " MACSTR " was " 2350 MACSTR " - indicate PBC session overlap", 2351 MAC2STR(reg->p2p_dev_addr), 2352 MAC2STR(wps->p2p_dev_addr)); 2353 return 0; 2354 } 2355#endif /* CONFIG_P2P */ 2356 return 1; 2357} 2358 2359 2360static int wps_registrar_skip_overlap(struct wps_data *wps) 2361{ 2362#ifdef CONFIG_P2P 2363 struct wps_registrar *reg = wps->wps->registrar; 2364 2365 if (is_zero_ether_addr(reg->p2p_dev_addr)) 2366 return 0; /* no specific Enrollee selected */ 2367 2368 if (os_memcmp(reg->p2p_dev_addr, wps->p2p_dev_addr, ETH_ALEN) == 0) { 2369 wpa_printf(MSG_DEBUG, "WPS: Skip PBC overlap due to selected " 2370 "Enrollee match"); 2371 return 1; 2372 } 2373#endif /* CONFIG_P2P */ 2374 return 0; 2375} 2376 2377 2378static enum wps_process_res wps_process_m1(struct wps_data *wps, 2379 struct wps_parse_attr *attr) 2380{ 2381 wpa_printf(MSG_DEBUG, "WPS: Received M1"); 2382 2383 if (wps->state != RECV_M1) { 2384 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for " 2385 "receiving M1", wps->state); 2386 return WPS_FAILURE; 2387 } 2388 2389 if (wps_process_uuid_e(wps, attr->uuid_e) || 2390 wps_process_mac_addr(wps, attr->mac_addr) || 2391 wps_process_enrollee_nonce(wps, attr->enrollee_nonce) || 2392 wps_process_pubkey(wps, attr->public_key, attr->public_key_len) || 2393 wps_process_auth_type_flags(wps, attr->auth_type_flags) || 2394 wps_process_encr_type_flags(wps, attr->encr_type_flags) || 2395 wps_process_conn_type_flags(wps, attr->conn_type_flags) || 2396 wps_process_config_methods(wps, attr->config_methods) || 2397 wps_process_wps_state(wps, attr->wps_state) || 2398 wps_process_device_attrs(&wps->peer_dev, attr) || 2399 wps_process_rf_bands(&wps->peer_dev, attr->rf_bands) || 2400 wps_process_assoc_state(wps, attr->assoc_state) || 2401 wps_process_dev_password_id(wps, attr->dev_password_id) || 2402 wps_process_config_error(wps, attr->config_error) || 2403 wps_process_os_version(&wps->peer_dev, attr->os_version)) 2404 return WPS_FAILURE; 2405 2406 if (wps->dev_pw_id < 0x10 && 2407 wps->dev_pw_id != DEV_PW_DEFAULT && 2408 wps->dev_pw_id != DEV_PW_USER_SPECIFIED && 2409 wps->dev_pw_id != DEV_PW_MACHINE_SPECIFIED && 2410 wps->dev_pw_id != DEV_PW_REGISTRAR_SPECIFIED && 2411 (wps->dev_pw_id != DEV_PW_PUSHBUTTON || 2412 !wps->wps->registrar->pbc)) { 2413 wpa_printf(MSG_DEBUG, "WPS: Unsupported Device Password ID %d", 2414 wps->dev_pw_id); 2415 wps->state = SEND_M2D; 2416 return WPS_CONTINUE; 2417 } 2418 2419#ifdef CONFIG_WPS_OOB 2420 if (wps->dev_pw_id >= 0x10 && 2421 wps->dev_pw_id != wps->wps->oob_dev_pw_id) { 2422 wpa_printf(MSG_DEBUG, "WPS: OOB Device Password ID " 2423 "%d mismatch", wps->dev_pw_id); 2424 wps->state = SEND_M2D; 2425 return WPS_CONTINUE; 2426 } 2427#endif /* CONFIG_WPS_OOB */ 2428 2429 if (wps->dev_pw_id == DEV_PW_PUSHBUTTON) { 2430 if ((wps->wps->registrar->force_pbc_overlap || 2431 wps_registrar_pbc_overlap(wps->wps->registrar, 2432 wps->mac_addr_e, wps->uuid_e) || 2433 !wps_registrar_p2p_dev_addr_match(wps)) && 2434 !wps_registrar_skip_overlap(wps)) { 2435 wpa_printf(MSG_DEBUG, "WPS: PBC overlap - deny PBC " 2436 "negotiation"); 2437 wps->state = SEND_M2D; 2438 wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED; 2439 wps_pbc_overlap_event(wps->wps); 2440 wps_fail_event(wps->wps, WPS_M1, 2441 WPS_CFG_MULTIPLE_PBC_DETECTED, 2442 WPS_EI_NO_ERROR); 2443 wps->wps->registrar->force_pbc_overlap = 1; 2444 return WPS_CONTINUE; 2445 } 2446 wps_registrar_add_pbc_session(wps->wps->registrar, 2447 wps->mac_addr_e, wps->uuid_e); 2448 wps->pbc = 1; 2449 } 2450 2451#ifdef WPS_WORKAROUNDS 2452 /* 2453 * It looks like Mac OS X 10.6.3 and 10.6.4 do not like Network Key in 2454 * passphrase format. To avoid interop issues, force PSK format to be 2455 * used. 2456 */ 2457 if (!wps->use_psk_key && 2458 wps->peer_dev.manufacturer && 2459 os_strncmp(wps->peer_dev.manufacturer, "Apple ", 6) == 0 && 2460 wps->peer_dev.model_name && 2461 os_strcmp(wps->peer_dev.model_name, "AirPort") == 0) { 2462 wpa_printf(MSG_DEBUG, "WPS: Workaround - Force Network Key in " 2463 "PSK format"); 2464 wps->use_psk_key = 1; 2465 } 2466#endif /* WPS_WORKAROUNDS */ 2467 2468 wps->state = SEND_M2; 2469 return WPS_CONTINUE; 2470} 2471 2472 2473static enum wps_process_res wps_process_m3(struct wps_data *wps, 2474 const struct wpabuf *msg, 2475 struct wps_parse_attr *attr) 2476{ 2477 wpa_printf(MSG_DEBUG, "WPS: Received M3"); 2478 2479 if (wps->state != RECV_M3) { 2480 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for " 2481 "receiving M3", wps->state); 2482 wps->state = SEND_WSC_NACK; 2483 return WPS_CONTINUE; 2484 } 2485 2486 if (wps->pbc && wps->wps->registrar->force_pbc_overlap && 2487 !wps_registrar_skip_overlap(wps)) { 2488 wpa_printf(MSG_DEBUG, "WPS: Reject negotiation due to PBC " 2489 "session overlap"); 2490 wps->state = SEND_WSC_NACK; 2491 wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED; 2492 return WPS_CONTINUE; 2493 } 2494 2495 if (wps_process_registrar_nonce(wps, attr->registrar_nonce) || 2496 wps_process_authenticator(wps, attr->authenticator, msg) || 2497 wps_process_e_hash1(wps, attr->e_hash1) || 2498 wps_process_e_hash2(wps, attr->e_hash2)) { 2499 wps->state = SEND_WSC_NACK; 2500 return WPS_CONTINUE; 2501 } 2502 2503 wps->state = SEND_M4; 2504 return WPS_CONTINUE; 2505} 2506 2507 2508static enum wps_process_res wps_process_m5(struct wps_data *wps, 2509 const struct wpabuf *msg, 2510 struct wps_parse_attr *attr) 2511{ 2512 struct wpabuf *decrypted; 2513 struct wps_parse_attr eattr; 2514 2515 wpa_printf(MSG_DEBUG, "WPS: Received M5"); 2516 2517 if (wps->state != RECV_M5) { 2518 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for " 2519 "receiving M5", wps->state); 2520 wps->state = SEND_WSC_NACK; 2521 return WPS_CONTINUE; 2522 } 2523 2524 if (wps->pbc && wps->wps->registrar->force_pbc_overlap && 2525 !wps_registrar_skip_overlap(wps)) { 2526 wpa_printf(MSG_DEBUG, "WPS: Reject negotiation due to PBC " 2527 "session overlap"); 2528 wps->state = SEND_WSC_NACK; 2529 wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED; 2530 return WPS_CONTINUE; 2531 } 2532 2533 if (wps_process_registrar_nonce(wps, attr->registrar_nonce) || 2534 wps_process_authenticator(wps, attr->authenticator, msg)) { 2535 wps->state = SEND_WSC_NACK; 2536 return WPS_CONTINUE; 2537 } 2538 2539 decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings, 2540 attr->encr_settings_len); 2541 if (decrypted == NULL) { 2542 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted " 2543 "Settings attribute"); 2544 wps->state = SEND_WSC_NACK; 2545 return WPS_CONTINUE; 2546 } 2547 2548 if (wps_validate_m5_encr(decrypted, attr->version2 != NULL) < 0) { 2549 wpabuf_free(decrypted); 2550 wps->state = SEND_WSC_NACK; 2551 return WPS_CONTINUE; 2552 } 2553 2554 wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings " 2555 "attribute"); 2556 if (wps_parse_msg(decrypted, &eattr) < 0 || 2557 wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) || 2558 wps_process_e_snonce1(wps, eattr.e_snonce1)) { 2559 wpabuf_free(decrypted); 2560 wps->state = SEND_WSC_NACK; 2561 return WPS_CONTINUE; 2562 } 2563 wpabuf_free(decrypted); 2564 2565 wps->state = SEND_M6; 2566 return WPS_CONTINUE; 2567} 2568 2569 2570static void wps_sta_cred_cb(struct wps_data *wps) 2571{ 2572 /* 2573 * Update credential to only include a single authentication and 2574 * encryption type in case the AP configuration includes more than one 2575 * option. 2576 */ 2577 if (wps->cred.auth_type & WPS_AUTH_WPA2PSK) 2578 wps->cred.auth_type = WPS_AUTH_WPA2PSK; 2579 else if (wps->cred.auth_type & WPS_AUTH_WPAPSK) 2580 wps->cred.auth_type = WPS_AUTH_WPAPSK; 2581 if (wps->cred.encr_type & WPS_ENCR_AES) 2582 wps->cred.encr_type = WPS_ENCR_AES; 2583 else if (wps->cred.encr_type & WPS_ENCR_TKIP) 2584 wps->cred.encr_type = WPS_ENCR_TKIP; 2585 wpa_printf(MSG_DEBUG, "WPS: Update local configuration based on the " 2586 "AP configuration"); 2587 if (wps->wps->cred_cb) 2588 wps->wps->cred_cb(wps->wps->cb_ctx, &wps->cred); 2589} 2590 2591 2592static void wps_cred_update(struct wps_credential *dst, 2593 struct wps_credential *src) 2594{ 2595 os_memcpy(dst->ssid, src->ssid, sizeof(dst->ssid)); 2596 dst->ssid_len = src->ssid_len; 2597 dst->auth_type = src->auth_type; 2598 dst->encr_type = src->encr_type; 2599 dst->key_idx = src->key_idx; 2600 os_memcpy(dst->key, src->key, sizeof(dst->key)); 2601 dst->key_len = src->key_len; 2602} 2603 2604 2605static int wps_process_ap_settings_r(struct wps_data *wps, 2606 struct wps_parse_attr *attr) 2607{ 2608 struct wpabuf *msg; 2609 2610 if (wps->wps->ap || wps->er) 2611 return 0; 2612 2613 /* AP Settings Attributes in M7 when Enrollee is an AP */ 2614 if (wps_process_ap_settings(attr, &wps->cred) < 0) 2615 return -1; 2616 2617 wpa_printf(MSG_INFO, "WPS: Received old AP configuration from AP"); 2618 2619 if (wps->new_ap_settings) { 2620 wpa_printf(MSG_INFO, "WPS: Update AP configuration based on " 2621 "new settings"); 2622 wps_cred_update(&wps->cred, wps->new_ap_settings); 2623 return 0; 2624 } else { 2625 /* 2626 * Use the AP PIN only to receive the current AP settings, not 2627 * to reconfigure the AP. 2628 */ 2629 2630 /* 2631 * Clear selected registrar here since we do not get to 2632 * WSC_Done in this protocol run. 2633 */ 2634 wps_registrar_pin_completed(wps->wps->registrar); 2635 2636 msg = wps_build_ap_cred(wps); 2637 if (msg == NULL) 2638 return -1; 2639 wps->cred.cred_attr = wpabuf_head(msg); 2640 wps->cred.cred_attr_len = wpabuf_len(msg); 2641 2642 if (wps->ap_settings_cb) { 2643 wps->ap_settings_cb(wps->ap_settings_cb_ctx, 2644 &wps->cred); 2645 wpabuf_free(msg); 2646 return 1; 2647 } 2648 wps_sta_cred_cb(wps); 2649 2650 wps->cred.cred_attr = NULL; 2651 wps->cred.cred_attr_len = 0; 2652 wpabuf_free(msg); 2653 2654 return 1; 2655 } 2656} 2657 2658 2659static enum wps_process_res wps_process_m7(struct wps_data *wps, 2660 const struct wpabuf *msg, 2661 struct wps_parse_attr *attr) 2662{ 2663 struct wpabuf *decrypted; 2664 struct wps_parse_attr eattr; 2665 2666 wpa_printf(MSG_DEBUG, "WPS: Received M7"); 2667 2668 if (wps->state != RECV_M7) { 2669 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for " 2670 "receiving M7", wps->state); 2671 wps->state = SEND_WSC_NACK; 2672 return WPS_CONTINUE; 2673 } 2674 2675 if (wps->pbc && wps->wps->registrar->force_pbc_overlap && 2676 !wps_registrar_skip_overlap(wps)) { 2677 wpa_printf(MSG_DEBUG, "WPS: Reject negotiation due to PBC " 2678 "session overlap"); 2679 wps->state = SEND_WSC_NACK; 2680 wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED; 2681 return WPS_CONTINUE; 2682 } 2683 2684 if (wps_process_registrar_nonce(wps, attr->registrar_nonce) || 2685 wps_process_authenticator(wps, attr->authenticator, msg)) { 2686 wps->state = SEND_WSC_NACK; 2687 return WPS_CONTINUE; 2688 } 2689 2690 decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings, 2691 attr->encr_settings_len); 2692 if (decrypted == NULL) { 2693 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypt Encrypted " 2694 "Settings attribute"); 2695 wps->state = SEND_WSC_NACK; 2696 return WPS_CONTINUE; 2697 } 2698 2699 if (wps_validate_m7_encr(decrypted, wps->wps->ap || wps->er, 2700 attr->version2 != NULL) < 0) { 2701 wpabuf_free(decrypted); 2702 wps->state = SEND_WSC_NACK; 2703 return WPS_CONTINUE; 2704 } 2705 2706 wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings " 2707 "attribute"); 2708 if (wps_parse_msg(decrypted, &eattr) < 0 || 2709 wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) || 2710 wps_process_e_snonce2(wps, eattr.e_snonce2) || 2711 wps_process_ap_settings_r(wps, &eattr)) { 2712 wpabuf_free(decrypted); 2713 wps->state = SEND_WSC_NACK; 2714 return WPS_CONTINUE; 2715 } 2716 2717 wpabuf_free(decrypted); 2718 2719 wps->state = SEND_M8; 2720 return WPS_CONTINUE; 2721} 2722 2723 2724static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps, 2725 const struct wpabuf *msg) 2726{ 2727 struct wps_parse_attr attr; 2728 enum wps_process_res ret = WPS_CONTINUE; 2729 2730 wpa_printf(MSG_DEBUG, "WPS: Received WSC_MSG"); 2731 2732 if (wps_parse_msg(msg, &attr) < 0) 2733 return WPS_FAILURE; 2734 2735 if (attr.msg_type == NULL) { 2736 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute"); 2737 wps->state = SEND_WSC_NACK; 2738 return WPS_CONTINUE; 2739 } 2740 2741 if (*attr.msg_type != WPS_M1 && 2742 (attr.registrar_nonce == NULL || 2743 os_memcmp(wps->nonce_r, attr.registrar_nonce, 2744 WPS_NONCE_LEN != 0))) { 2745 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce"); 2746 return WPS_FAILURE; 2747 } 2748 2749 switch (*attr.msg_type) { 2750 case WPS_M1: 2751 if (wps_validate_m1(msg) < 0) 2752 return WPS_FAILURE; 2753#ifdef CONFIG_WPS_UPNP 2754 if (wps->wps->wps_upnp && attr.mac_addr) { 2755 /* Remove old pending messages when starting new run */ 2756 wps_free_pending_msgs(wps->wps->upnp_msgs); 2757 wps->wps->upnp_msgs = NULL; 2758 2759 upnp_wps_device_send_wlan_event( 2760 wps->wps->wps_upnp, attr.mac_addr, 2761 UPNP_WPS_WLANEVENT_TYPE_EAP, msg); 2762 } 2763#endif /* CONFIG_WPS_UPNP */ 2764 ret = wps_process_m1(wps, &attr); 2765 break; 2766 case WPS_M3: 2767 if (wps_validate_m3(msg) < 0) 2768 return WPS_FAILURE; 2769 ret = wps_process_m3(wps, msg, &attr); 2770 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK) 2771 wps_fail_event(wps->wps, WPS_M3, wps->config_error, 2772 wps->error_indication); 2773 break; 2774 case WPS_M5: 2775 if (wps_validate_m5(msg) < 0) 2776 return WPS_FAILURE; 2777 ret = wps_process_m5(wps, msg, &attr); 2778 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK) 2779 wps_fail_event(wps->wps, WPS_M5, wps->config_error, 2780 wps->error_indication); 2781 break; 2782 case WPS_M7: 2783 if (wps_validate_m7(msg) < 0) 2784 return WPS_FAILURE; 2785 ret = wps_process_m7(wps, msg, &attr); 2786 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK) 2787 wps_fail_event(wps->wps, WPS_M7, wps->config_error, 2788 wps->error_indication); 2789 break; 2790 default: 2791 wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d", 2792 *attr.msg_type); 2793 return WPS_FAILURE; 2794 } 2795 2796 if (ret == WPS_CONTINUE) { 2797 /* Save a copy of the last message for Authenticator derivation 2798 */ 2799 wpabuf_free(wps->last_msg); 2800 wps->last_msg = wpabuf_dup(msg); 2801 } 2802 2803 return ret; 2804} 2805 2806 2807static enum wps_process_res wps_process_wsc_ack(struct wps_data *wps, 2808 const struct wpabuf *msg) 2809{ 2810 struct wps_parse_attr attr; 2811 2812 wpa_printf(MSG_DEBUG, "WPS: Received WSC_ACK"); 2813 2814 if (wps_parse_msg(msg, &attr) < 0) 2815 return WPS_FAILURE; 2816 2817 if (attr.msg_type == NULL) { 2818 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute"); 2819 return WPS_FAILURE; 2820 } 2821 2822 if (*attr.msg_type != WPS_WSC_ACK) { 2823 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d", 2824 *attr.msg_type); 2825 return WPS_FAILURE; 2826 } 2827 2828#ifdef CONFIG_WPS_UPNP 2829 if (wps->wps->wps_upnp && wps->ext_reg && wps->state == RECV_M2D_ACK && 2830 upnp_wps_subscribers(wps->wps->wps_upnp)) { 2831 if (wps->wps->upnp_msgs) 2832 return WPS_CONTINUE; 2833 wpa_printf(MSG_DEBUG, "WPS: Wait for response from an " 2834 "external Registrar"); 2835 return WPS_PENDING; 2836 } 2837#endif /* CONFIG_WPS_UPNP */ 2838 2839 if (attr.registrar_nonce == NULL || 2840 os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0)) 2841 { 2842 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce"); 2843 return WPS_FAILURE; 2844 } 2845 2846 if (attr.enrollee_nonce == NULL || 2847 os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) { 2848 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce"); 2849 return WPS_FAILURE; 2850 } 2851 2852 if (wps->state == RECV_M2D_ACK) { 2853#ifdef CONFIG_WPS_UPNP 2854 if (wps->wps->wps_upnp && 2855 upnp_wps_subscribers(wps->wps->wps_upnp)) { 2856 if (wps->wps->upnp_msgs) 2857 return WPS_CONTINUE; 2858 if (wps->ext_reg == 0) 2859 wps->ext_reg = 1; 2860 wpa_printf(MSG_DEBUG, "WPS: Wait for response from an " 2861 "external Registrar"); 2862 return WPS_PENDING; 2863 } 2864#endif /* CONFIG_WPS_UPNP */ 2865 2866 wpa_printf(MSG_DEBUG, "WPS: No more registrars available - " 2867 "terminate negotiation"); 2868 } 2869 2870 return WPS_FAILURE; 2871} 2872 2873 2874static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps, 2875 const struct wpabuf *msg) 2876{ 2877 struct wps_parse_attr attr; 2878 int old_state; 2879 u16 config_error; 2880 2881 wpa_printf(MSG_DEBUG, "WPS: Received WSC_NACK"); 2882 2883 old_state = wps->state; 2884 wps->state = SEND_WSC_NACK; 2885 2886 if (wps_parse_msg(msg, &attr) < 0) 2887 return WPS_FAILURE; 2888 2889 if (attr.msg_type == NULL) { 2890 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute"); 2891 return WPS_FAILURE; 2892 } 2893 2894 if (*attr.msg_type != WPS_WSC_NACK) { 2895 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d", 2896 *attr.msg_type); 2897 return WPS_FAILURE; 2898 } 2899 2900#ifdef CONFIG_WPS_UPNP 2901 if (wps->wps->wps_upnp && wps->ext_reg) { 2902 wpa_printf(MSG_DEBUG, "WPS: Negotiation using external " 2903 "Registrar terminated by the Enrollee"); 2904 return WPS_FAILURE; 2905 } 2906#endif /* CONFIG_WPS_UPNP */ 2907 2908 if (attr.registrar_nonce == NULL || 2909 os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0)) 2910 { 2911 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce"); 2912 return WPS_FAILURE; 2913 } 2914 2915 if (attr.enrollee_nonce == NULL || 2916 os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) { 2917 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce"); 2918 return WPS_FAILURE; 2919 } 2920 2921 if (attr.config_error == NULL) { 2922 wpa_printf(MSG_DEBUG, "WPS: No Configuration Error attribute " 2923 "in WSC_NACK"); 2924 return WPS_FAILURE; 2925 } 2926 2927 config_error = WPA_GET_BE16(attr.config_error); 2928 wpa_printf(MSG_DEBUG, "WPS: Enrollee terminated negotiation with " 2929 "Configuration Error %d", config_error); 2930 2931 switch (old_state) { 2932 case RECV_M3: 2933 wps_fail_event(wps->wps, WPS_M2, config_error, 2934 wps->error_indication); 2935 break; 2936 case RECV_M5: 2937 wps_fail_event(wps->wps, WPS_M4, config_error, 2938 wps->error_indication); 2939 break; 2940 case RECV_M7: 2941 wps_fail_event(wps->wps, WPS_M6, config_error, 2942 wps->error_indication); 2943 break; 2944 case RECV_DONE: 2945 wps_fail_event(wps->wps, WPS_M8, config_error, 2946 wps->error_indication); 2947 break; 2948 default: 2949 break; 2950 } 2951 2952 return WPS_FAILURE; 2953} 2954 2955 2956static enum wps_process_res wps_process_wsc_done(struct wps_data *wps, 2957 const struct wpabuf *msg) 2958{ 2959 struct wps_parse_attr attr; 2960 2961 wpa_printf(MSG_DEBUG, "WPS: Received WSC_Done"); 2962 2963 if (wps->state != RECV_DONE && 2964 (!wps->wps->wps_upnp || !wps->ext_reg)) { 2965 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for " 2966 "receiving WSC_Done", wps->state); 2967 return WPS_FAILURE; 2968 } 2969 2970 if (wps_parse_msg(msg, &attr) < 0) 2971 return WPS_FAILURE; 2972 2973 if (attr.msg_type == NULL) { 2974 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute"); 2975 return WPS_FAILURE; 2976 } 2977 2978 if (*attr.msg_type != WPS_WSC_DONE) { 2979 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d", 2980 *attr.msg_type); 2981 return WPS_FAILURE; 2982 } 2983 2984#ifdef CONFIG_WPS_UPNP 2985 if (wps->wps->wps_upnp && wps->ext_reg) { 2986 wpa_printf(MSG_DEBUG, "WPS: Negotiation using external " 2987 "Registrar completed successfully"); 2988 wps_device_store(wps->wps->registrar, &wps->peer_dev, 2989 wps->uuid_e); 2990 return WPS_DONE; 2991 } 2992#endif /* CONFIG_WPS_UPNP */ 2993 2994 if (attr.registrar_nonce == NULL || 2995 os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0)) 2996 { 2997 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce"); 2998 return WPS_FAILURE; 2999 } 3000 3001 if (attr.enrollee_nonce == NULL || 3002 os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) { 3003 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce"); 3004 return WPS_FAILURE; 3005 } 3006 3007 wpa_printf(MSG_DEBUG, "WPS: Negotiation completed successfully"); 3008 wps_device_store(wps->wps->registrar, &wps->peer_dev, 3009 wps->uuid_e); 3010 3011 if (wps->wps->wps_state == WPS_STATE_NOT_CONFIGURED && wps->new_psk && 3012 wps->wps->ap && !wps->wps->registrar->disable_auto_conf) { 3013 struct wps_credential cred; 3014 3015 wpa_printf(MSG_DEBUG, "WPS: Moving to Configured state based " 3016 "on first Enrollee connection"); 3017 3018 os_memset(&cred, 0, sizeof(cred)); 3019 os_memcpy(cred.ssid, wps->wps->ssid, wps->wps->ssid_len); 3020 cred.ssid_len = wps->wps->ssid_len; 3021 cred.auth_type = WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK; 3022 cred.encr_type = WPS_ENCR_TKIP | WPS_ENCR_AES; 3023 os_memcpy(cred.key, wps->new_psk, wps->new_psk_len); 3024 cred.key_len = wps->new_psk_len; 3025 3026 wps->wps->wps_state = WPS_STATE_CONFIGURED; 3027 wpa_hexdump_ascii_key(MSG_DEBUG, 3028 "WPS: Generated random passphrase", 3029 wps->new_psk, wps->new_psk_len); 3030 if (wps->wps->cred_cb) 3031 wps->wps->cred_cb(wps->wps->cb_ctx, &cred); 3032 3033 os_free(wps->new_psk); 3034 wps->new_psk = NULL; 3035 } 3036 3037 if (!wps->wps->ap && !wps->er) 3038 wps_sta_cred_cb(wps); 3039 3040 if (wps->new_psk) { 3041 if (wps_cb_new_psk(wps->wps->registrar, wps->mac_addr_e, 3042 wps->new_psk, wps->new_psk_len)) { 3043 wpa_printf(MSG_DEBUG, "WPS: Failed to configure the " 3044 "new PSK"); 3045 } 3046 os_free(wps->new_psk); 3047 wps->new_psk = NULL; 3048 } 3049 3050 wps_cb_reg_success(wps->wps->registrar, wps->mac_addr_e, wps->uuid_e); 3051 3052 if (wps->pbc) { 3053 wps_registrar_remove_pbc_session(wps->wps->registrar, 3054 wps->uuid_e, 3055 wps->p2p_dev_addr); 3056 wps_registrar_pbc_completed(wps->wps->registrar); 3057 } else { 3058 wps_registrar_pin_completed(wps->wps->registrar); 3059 } 3060 /* TODO: maintain AuthorizedMACs somewhere separately for each ER and 3061 * merge them into APs own list.. */ 3062 3063 wps_success_event(wps->wps); 3064 3065 return WPS_DONE; 3066} 3067 3068 3069enum wps_process_res wps_registrar_process_msg(struct wps_data *wps, 3070 enum wsc_op_code op_code, 3071 const struct wpabuf *msg) 3072{ 3073 enum wps_process_res ret; 3074 3075 wpa_printf(MSG_DEBUG, "WPS: Processing received message (len=%lu " 3076 "op_code=%d)", 3077 (unsigned long) wpabuf_len(msg), op_code); 3078 3079#ifdef CONFIG_WPS_UPNP 3080 if (wps->wps->wps_upnp && op_code == WSC_MSG && wps->ext_reg == 1) { 3081 struct wps_parse_attr attr; 3082 if (wps_parse_msg(msg, &attr) == 0 && attr.msg_type && 3083 *attr.msg_type == WPS_M3) 3084 wps->ext_reg = 2; /* past M2/M2D phase */ 3085 } 3086 if (wps->ext_reg > 1) 3087 wps_registrar_free_pending_m2(wps->wps); 3088 if (wps->wps->wps_upnp && wps->ext_reg && 3089 wps->wps->upnp_msgs == NULL && 3090 (op_code == WSC_MSG || op_code == WSC_Done || op_code == WSC_NACK)) 3091 { 3092 struct wps_parse_attr attr; 3093 int type; 3094 if (wps_parse_msg(msg, &attr) < 0 || attr.msg_type == NULL) 3095 type = -1; 3096 else 3097 type = *attr.msg_type; 3098 wpa_printf(MSG_DEBUG, "WPS: Sending received message (type %d)" 3099 " to external Registrar for processing", type); 3100 upnp_wps_device_send_wlan_event(wps->wps->wps_upnp, 3101 wps->mac_addr_e, 3102 UPNP_WPS_WLANEVENT_TYPE_EAP, 3103 msg); 3104 if (op_code == WSC_MSG) 3105 return WPS_PENDING; 3106 } else if (wps->wps->wps_upnp && wps->ext_reg && op_code == WSC_MSG) { 3107 wpa_printf(MSG_DEBUG, "WPS: Skip internal processing - using " 3108 "external Registrar"); 3109 return WPS_CONTINUE; 3110 } 3111#endif /* CONFIG_WPS_UPNP */ 3112 3113 switch (op_code) { 3114 case WSC_MSG: 3115 return wps_process_wsc_msg(wps, msg); 3116 case WSC_ACK: 3117 if (wps_validate_wsc_ack(msg) < 0) 3118 return WPS_FAILURE; 3119 return wps_process_wsc_ack(wps, msg); 3120 case WSC_NACK: 3121 if (wps_validate_wsc_nack(msg) < 0) 3122 return WPS_FAILURE; 3123 return wps_process_wsc_nack(wps, msg); 3124 case WSC_Done: 3125 if (wps_validate_wsc_done(msg) < 0) 3126 return WPS_FAILURE; 3127 ret = wps_process_wsc_done(wps, msg); 3128 if (ret == WPS_FAILURE) { 3129 wps->state = SEND_WSC_NACK; 3130 wps_fail_event(wps->wps, WPS_WSC_DONE, 3131 wps->config_error, 3132 wps->error_indication); 3133 } 3134 return ret; 3135 default: 3136 wpa_printf(MSG_DEBUG, "WPS: Unsupported op_code %d", op_code); 3137 return WPS_FAILURE; 3138 } 3139} 3140 3141 3142int wps_registrar_update_ie(struct wps_registrar *reg) 3143{ 3144 return wps_set_ie(reg); 3145} 3146 3147 3148static void wps_registrar_set_selected_timeout(void *eloop_ctx, 3149 void *timeout_ctx) 3150{ 3151 struct wps_registrar *reg = eloop_ctx; 3152 3153 wpa_printf(MSG_DEBUG, "WPS: Selected Registrar timeout - " 3154 "unselect internal Registrar"); 3155 reg->selected_registrar = 0; 3156 reg->pbc = 0; 3157 wps_registrar_selected_registrar_changed(reg); 3158} 3159 3160 3161#ifdef CONFIG_WPS_UPNP 3162static void wps_registrar_sel_reg_add(struct wps_registrar *reg, 3163 struct subscription *s) 3164{ 3165 int i, j; 3166 wpa_printf(MSG_DEBUG, "WPS: External Registrar selected (dev_pw_id=%d " 3167 "config_methods=0x%x)", 3168 s->dev_password_id, s->config_methods); 3169 reg->sel_reg_union = 1; 3170 if (reg->sel_reg_dev_password_id_override != DEV_PW_PUSHBUTTON) 3171 reg->sel_reg_dev_password_id_override = s->dev_password_id; 3172 if (reg->sel_reg_config_methods_override == -1) 3173 reg->sel_reg_config_methods_override = 0; 3174 reg->sel_reg_config_methods_override |= s->config_methods; 3175 for (i = 0; i < WPS_MAX_AUTHORIZED_MACS; i++) 3176 if (is_zero_ether_addr(reg->authorized_macs_union[i])) 3177 break; 3178 for (j = 0; i < WPS_MAX_AUTHORIZED_MACS && j < WPS_MAX_AUTHORIZED_MACS; 3179 j++) { 3180 if (is_zero_ether_addr(s->authorized_macs[j])) 3181 break; 3182 wpa_printf(MSG_DEBUG, "WPS: Add authorized MAC into union: " 3183 MACSTR, MAC2STR(s->authorized_macs[j])); 3184 os_memcpy(reg->authorized_macs_union[i], 3185 s->authorized_macs[j], ETH_ALEN); 3186 i++; 3187 } 3188 wpa_hexdump(MSG_DEBUG, "WPS: Authorized MACs union", 3189 (u8 *) reg->authorized_macs_union, 3190 sizeof(reg->authorized_macs_union)); 3191} 3192#endif /* CONFIG_WPS_UPNP */ 3193 3194 3195static void wps_registrar_sel_reg_union(struct wps_registrar *reg) 3196{ 3197#ifdef CONFIG_WPS_UPNP 3198 struct subscription *s; 3199 3200 if (reg->wps->wps_upnp == NULL) 3201 return; 3202 3203 dl_list_for_each(s, ®->wps->wps_upnp->subscriptions, 3204 struct subscription, list) { 3205 struct subscr_addr *sa; 3206 sa = dl_list_first(&s->addr_list, struct subscr_addr, list); 3207 if (sa) { 3208 wpa_printf(MSG_DEBUG, "WPS: External Registrar %s:%d", 3209 inet_ntoa(sa->saddr.sin_addr), 3210 ntohs(sa->saddr.sin_port)); 3211 } 3212 if (s->selected_registrar) 3213 wps_registrar_sel_reg_add(reg, s); 3214 else 3215 wpa_printf(MSG_DEBUG, "WPS: External Registrar not " 3216 "selected"); 3217 } 3218#endif /* CONFIG_WPS_UPNP */ 3219} 3220 3221 3222/** 3223 * wps_registrar_selected_registrar_changed - SetSelectedRegistrar change 3224 * @reg: Registrar data from wps_registrar_init() 3225 * 3226 * This function is called when selected registrar state changes, e.g., when an 3227 * AP receives a SetSelectedRegistrar UPnP message. 3228 */ 3229void wps_registrar_selected_registrar_changed(struct wps_registrar *reg) 3230{ 3231 wpa_printf(MSG_DEBUG, "WPS: Selected registrar information changed"); 3232 3233 reg->sel_reg_union = reg->selected_registrar; 3234 reg->sel_reg_dev_password_id_override = -1; 3235 reg->sel_reg_config_methods_override = -1; 3236 os_memcpy(reg->authorized_macs_union, reg->authorized_macs, 3237 WPS_MAX_AUTHORIZED_MACS * ETH_ALEN); 3238 wpa_hexdump(MSG_DEBUG, "WPS: Authorized MACs union (start with own)", 3239 (u8 *) reg->authorized_macs_union, 3240 sizeof(reg->authorized_macs_union)); 3241 if (reg->selected_registrar) { 3242 u16 methods; 3243 3244 methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON; 3245#ifdef CONFIG_WPS2 3246 methods &= ~(WPS_CONFIG_VIRT_PUSHBUTTON | 3247 WPS_CONFIG_PHY_PUSHBUTTON); 3248#endif /* CONFIG_WPS2 */ 3249 if (reg->pbc) { 3250 reg->sel_reg_dev_password_id_override = 3251 DEV_PW_PUSHBUTTON; 3252 wps_set_pushbutton(&methods, reg->wps->config_methods); 3253 } 3254 wpa_printf(MSG_DEBUG, "WPS: Internal Registrar selected " 3255 "(pbc=%d)", reg->pbc); 3256 reg->sel_reg_config_methods_override = methods; 3257 } else 3258 wpa_printf(MSG_DEBUG, "WPS: Internal Registrar not selected"); 3259 3260 wps_registrar_sel_reg_union(reg); 3261 3262 wps_set_ie(reg); 3263 wps_cb_set_sel_reg(reg); 3264} 3265 3266 3267int wps_registrar_get_info(struct wps_registrar *reg, const u8 *addr, 3268 char *buf, size_t buflen) 3269{ 3270 struct wps_registrar_device *d; 3271 int len = 0, ret; 3272 char uuid[40]; 3273 char devtype[WPS_DEV_TYPE_BUFSIZE]; 3274 3275 d = wps_device_get(reg, addr); 3276 if (d == NULL) 3277 return 0; 3278 if (uuid_bin2str(d->uuid, uuid, sizeof(uuid))) 3279 return 0; 3280 3281 ret = os_snprintf(buf + len, buflen - len, 3282 "wpsUuid=%s\n" 3283 "wpsPrimaryDeviceType=%s\n" 3284 "wpsDeviceName=%s\n" 3285 "wpsManufacturer=%s\n" 3286 "wpsModelName=%s\n" 3287 "wpsModelNumber=%s\n" 3288 "wpsSerialNumber=%s\n", 3289 uuid, 3290 wps_dev_type_bin2str(d->dev.pri_dev_type, devtype, 3291 sizeof(devtype)), 3292 d->dev.device_name ? d->dev.device_name : "", 3293 d->dev.manufacturer ? d->dev.manufacturer : "", 3294 d->dev.model_name ? d->dev.model_name : "", 3295 d->dev.model_number ? d->dev.model_number : "", 3296 d->dev.serial_number ? d->dev.serial_number : ""); 3297 if (ret < 0 || (size_t) ret >= buflen - len) 3298 return len; 3299 len += ret; 3300 3301 return len; 3302} 3303 3304 3305int wps_registrar_config_ap(struct wps_registrar *reg, 3306 struct wps_credential *cred) 3307{ 3308#ifdef CONFIG_WPS2 3309 printf("encr_type=0x%x\n", cred->encr_type); 3310 if (!(cred->encr_type & (WPS_ENCR_NONE | WPS_ENCR_TKIP | 3311 WPS_ENCR_AES))) { 3312 if (cred->encr_type & WPS_ENCR_WEP) { 3313 wpa_printf(MSG_INFO, "WPS: Reject new AP settings " 3314 "due to WEP configuration"); 3315 return -1; 3316 } 3317 3318 wpa_printf(MSG_INFO, "WPS: Reject new AP settings due to " 3319 "invalid encr_type 0x%x", cred->encr_type); 3320 return -1; 3321 } 3322 3323 if ((cred->encr_type & (WPS_ENCR_TKIP | WPS_ENCR_AES)) == 3324 WPS_ENCR_TKIP) { 3325 wpa_printf(MSG_DEBUG, "WPS: Upgrade encr_type TKIP -> " 3326 "TKIP+AES"); 3327 cred->encr_type |= WPS_ENCR_AES; 3328 } 3329 3330 if ((cred->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) == 3331 WPS_AUTH_WPAPSK) { 3332 wpa_printf(MSG_DEBUG, "WPS: Upgrade auth_type WPAPSK -> " 3333 "WPAPSK+WPA2PSK"); 3334 cred->auth_type |= WPS_AUTH_WPA2PSK; 3335 } 3336#endif /* CONFIG_WPS2 */ 3337 3338 if (reg->wps->cred_cb) 3339 return reg->wps->cred_cb(reg->wps->cb_ctx, cred); 3340 3341 return -1; 3342} 3343