wps_registrar.c
Go to the documentation of this file.
00001 /*
00002  * Wi-Fi Protected Setup - Registrar
00003  * Copyright (c) 2008-2009, Jouni Malinen <j@w1.fi>
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License version 2 as
00007  * published by the Free Software Foundation.
00008  *
00009  * Alternatively, this software may be distributed under the terms of BSD
00010  * license.
00011  *
00012  * See README and COPYING for more details.
00013  */
00014 
00015 #include "utils/includes.h"
00016 
00017 #include "utils/common.h"
00018 #include "utils/base64.h"
00019 #include "utils/eloop.h"
00020 #include "utils/uuid.h"
00021 #include "utils/list.h"
00022 #include "crypto/crypto.h"
00023 #include "crypto/sha256.h"
00024 #include "common/ieee802_11_defs.h"
00025 #include "wps_i.h"
00026 #include "wps_dev_attr.h"
00027 #include "wps_upnp.h"
00028 #include "wps_upnp_i.h"
00029 
00030 #define WPS_WORKAROUNDS
00031 
00032 struct wps_uuid_pin {
00033         struct dl_list list;
00034         u8 uuid[WPS_UUID_LEN];
00035         int wildcard_uuid;
00036         u8 *pin;
00037         size_t pin_len;
00038 #define PIN_LOCKED BIT(0)
00039 #define PIN_EXPIRES BIT(1)
00040         int flags;
00041         struct os_time expiration;
00042 };
00043 
00044 
00045 static void wps_free_pin(struct wps_uuid_pin *pin)
00046 {
00047         os_free(pin->pin);
00048         os_free(pin);
00049 }
00050 
00051 
00052 static void wps_remove_pin(struct wps_uuid_pin *pin)
00053 {
00054         dl_list_del(&pin->list);
00055         wps_free_pin(pin);
00056 }
00057 
00058 
00059 static void wps_free_pins(struct dl_list *pins)
00060 {
00061         struct wps_uuid_pin *pin, *prev;
00062         dl_list_for_each_safe(pin, prev, pins, struct wps_uuid_pin, list)
00063                 wps_remove_pin(pin);
00064 }
00065 
00066 
00067 struct wps_pbc_session {
00068         struct wps_pbc_session *next;
00069         u8 addr[ETH_ALEN];
00070         u8 uuid_e[WPS_UUID_LEN];
00071         struct os_time timestamp;
00072 };
00073 
00074 
00075 static void wps_free_pbc_sessions(struct wps_pbc_session *pbc)
00076 {
00077         struct wps_pbc_session *prev;
00078 
00079         while (pbc) {
00080                 prev = pbc;
00081                 pbc = pbc->next;
00082                 os_free(prev);
00083         }
00084 }
00085 
00086 
00087 struct wps_registrar_device {
00088         struct wps_registrar_device *next;
00089         struct wps_device_data dev;
00090         u8 uuid[WPS_UUID_LEN];
00091 };
00092 
00093 
00094 struct wps_registrar {
00095         struct wps_context *wps;
00096 
00097         int pbc;
00098         int selected_registrar;
00099 
00100         int (*new_psk_cb)(void *ctx, const u8 *mac_addr, const u8 *psk,
00101                           size_t psk_len);
00102         int (*set_ie_cb)(void *ctx, struct wpabuf *beacon_ie,
00103                          struct wpabuf *probe_resp_ie);
00104         void (*pin_needed_cb)(void *ctx, const u8 *uuid_e,
00105                               const struct wps_device_data *dev);
00106         void (*reg_success_cb)(void *ctx, const u8 *mac_addr,
00107                                const u8 *uuid_e);
00108         void (*set_sel_reg_cb)(void *ctx, int sel_reg, u16 dev_passwd_id,
00109                                u16 sel_reg_config_methods);
00110         void (*enrollee_seen_cb)(void *ctx, const u8 *addr, const u8 *uuid_e,
00111                                  const u8 *pri_dev_type, u16 config_methods,
00112                                  u16 dev_password_id, u8 request_type,
00113                                  const char *dev_name);
00114         void *cb_ctx;
00115 
00116         struct dl_list pins;
00117         struct wps_pbc_session *pbc_sessions;
00118 
00119         int skip_cred_build;
00120         struct wpabuf *extra_cred;
00121         int disable_auto_conf;
00122         int sel_reg_union;
00123         int sel_reg_dev_password_id_override;
00124         int sel_reg_config_methods_override;
00125         int static_wep_only;
00126 
00127         struct wps_registrar_device *devices;
00128 
00129         int force_pbc_overlap;
00130 };
00131 
00132 
00133 static int wps_set_ie(struct wps_registrar *reg);
00134 static void wps_registrar_pbc_timeout(void *eloop_ctx, void *timeout_ctx);
00135 static void wps_registrar_set_selected_timeout(void *eloop_ctx,
00136                                                void *timeout_ctx);
00137 
00138 
00139 static void wps_free_devices(struct wps_registrar_device *dev)
00140 {
00141         struct wps_registrar_device *prev;
00142 
00143         while (dev) {
00144                 prev = dev;
00145                 dev = dev->next;
00146                 wps_device_data_free(&prev->dev);
00147                 os_free(prev);
00148         }
00149 }
00150 
00151 
00152 static struct wps_registrar_device * wps_device_get(struct wps_registrar *reg,
00153                                                     const u8 *addr)
00154 {
00155         struct wps_registrar_device *dev;
00156 
00157         for (dev = reg->devices; dev; dev = dev->next) {
00158                 if (os_memcmp(dev->dev.mac_addr, addr, ETH_ALEN) == 0)
00159                         return dev;
00160         }
00161         return NULL;
00162 }
00163 
00164 
00165 static void wps_device_clone_data(struct wps_device_data *dst,
00166                                   struct wps_device_data *src)
00167 {
00168         os_memcpy(dst->mac_addr, src->mac_addr, ETH_ALEN);
00169         os_memcpy(dst->pri_dev_type, src->pri_dev_type, WPS_DEV_TYPE_LEN);
00170 
00171 #define WPS_STRDUP(n) \
00172         os_free(dst->n); \
00173         dst->n = src->n ? os_strdup(src->n) : NULL
00174 
00175         WPS_STRDUP(device_name);
00176         WPS_STRDUP(manufacturer);
00177         WPS_STRDUP(model_name);
00178         WPS_STRDUP(model_number);
00179         WPS_STRDUP(serial_number);
00180 #undef WPS_STRDUP
00181 }
00182 
00183 
00184 int wps_device_store(struct wps_registrar *reg,
00185                      struct wps_device_data *dev, const u8 *uuid)
00186 {
00187         struct wps_registrar_device *d;
00188 
00189         d = wps_device_get(reg, dev->mac_addr);
00190         if (d == NULL) {
00191                 d = os_zalloc(sizeof(*d));
00192                 if (d == NULL)
00193                         return -1;
00194                 d->next = reg->devices;
00195                 reg->devices = d;
00196         }
00197 
00198         wps_device_clone_data(&d->dev, dev);
00199         os_memcpy(d->uuid, uuid, WPS_UUID_LEN);
00200 
00201         return 0;
00202 }
00203 
00204 
00205 static void wps_registrar_add_pbc_session(struct wps_registrar *reg,
00206                                           const u8 *addr, const u8 *uuid_e)
00207 {
00208         struct wps_pbc_session *pbc, *prev = NULL;
00209         struct os_time now;
00210 
00211         os_get_time(&now);
00212 
00213         pbc = reg->pbc_sessions;
00214         while (pbc) {
00215                 if (os_memcmp(pbc->addr, addr, ETH_ALEN) == 0 &&
00216                     os_memcmp(pbc->uuid_e, uuid_e, WPS_UUID_LEN) == 0) {
00217                         if (prev)
00218                                 prev->next = pbc->next;
00219                         else
00220                                 reg->pbc_sessions = pbc->next;
00221                         break;
00222                 }
00223                 prev = pbc;
00224                 pbc = pbc->next;
00225         }
00226 
00227         if (!pbc) {
00228                 pbc = os_zalloc(sizeof(*pbc));
00229                 if (pbc == NULL)
00230                         return;
00231                 os_memcpy(pbc->addr, addr, ETH_ALEN);
00232                 if (uuid_e)
00233                         os_memcpy(pbc->uuid_e, uuid_e, WPS_UUID_LEN);
00234         }
00235 
00236         pbc->next = reg->pbc_sessions;
00237         reg->pbc_sessions = pbc;
00238         pbc->timestamp = now;
00239 
00240         /* remove entries that have timed out */
00241         prev = pbc;
00242         pbc = pbc->next;
00243 
00244         while (pbc) {
00245                 if (now.sec > pbc->timestamp.sec + WPS_PBC_WALK_TIME) {
00246                         prev->next = NULL;
00247                         wps_free_pbc_sessions(pbc);
00248                         break;
00249                 }
00250                 prev = pbc;
00251                 pbc = pbc->next;
00252         }
00253 }
00254 
00255 
00256 static void wps_registrar_remove_pbc_session(struct wps_registrar *reg,
00257                                              const u8 *addr, const u8 *uuid_e)
00258 {
00259         struct wps_pbc_session *pbc, *prev = NULL;
00260 
00261         pbc = reg->pbc_sessions;
00262         while (pbc) {
00263                 if (os_memcmp(pbc->addr, addr, ETH_ALEN) == 0 &&
00264                     os_memcmp(pbc->uuid_e, uuid_e, WPS_UUID_LEN) == 0) {
00265                         if (prev)
00266                                 prev->next = pbc->next;
00267                         else
00268                                 reg->pbc_sessions = pbc->next;
00269                         os_free(pbc);
00270                         break;
00271                 }
00272                 prev = pbc;
00273                 pbc = pbc->next;
00274         }
00275 }
00276 
00277 
00278 static int wps_registrar_pbc_overlap(struct wps_registrar *reg,
00279                                      const u8 *addr, const u8 *uuid_e)
00280 {
00281         int count = 0;
00282         struct wps_pbc_session *pbc;
00283         struct os_time now;
00284 
00285         os_get_time(&now);
00286 
00287         for (pbc = reg->pbc_sessions; pbc; pbc = pbc->next) {
00288                 if (now.sec > pbc->timestamp.sec + WPS_PBC_WALK_TIME)
00289                         break;
00290                 if (addr == NULL || os_memcmp(addr, pbc->addr, ETH_ALEN) ||
00291                     uuid_e == NULL ||
00292                     os_memcmp(uuid_e, pbc->uuid_e, WPS_UUID_LEN))
00293                         count++;
00294         }
00295 
00296         if (addr || uuid_e)
00297                 count++;
00298 
00299         return count > 1 ? 1 : 0;
00300 }
00301 
00302 
00303 static int wps_build_wps_state(struct wps_context *wps, struct wpabuf *msg)
00304 {
00305         wpa_printf(MSG_DEBUG, "WPS:  * Wi-Fi Protected Setup State (%d)",
00306                    wps->wps_state);
00307         wpabuf_put_be16(msg, ATTR_WPS_STATE);
00308         wpabuf_put_be16(msg, 1);
00309         wpabuf_put_u8(msg, wps->wps_state);
00310         return 0;
00311 }
00312 
00313 
00314 #ifdef CONFIG_WPS_UPNP
00315 static void wps_registrar_free_pending_m2(struct wps_context *wps)
00316 {
00317         struct upnp_pending_message *p, *p2, *prev = NULL;
00318         p = wps->upnp_msgs;
00319         while (p) {
00320                 if (p->type == WPS_M2 || p->type == WPS_M2D) {
00321                         if (prev == NULL)
00322                                 wps->upnp_msgs = p->next;
00323                         else
00324                                 prev->next = p->next;
00325                         wpa_printf(MSG_DEBUG, "WPS UPnP: Drop pending M2/M2D");
00326                         p2 = p;
00327                         p = p->next;
00328                         wpabuf_free(p2->msg);
00329                         os_free(p2);
00330                         continue;
00331                 }
00332                 prev = p;
00333                 p = p->next;
00334         }
00335 }
00336 #endif /* CONFIG_WPS_UPNP */
00337 
00338 
00339 static int wps_build_ap_setup_locked(struct wps_context *wps,
00340                                      struct wpabuf *msg)
00341 {
00342         if (wps->ap_setup_locked) {
00343                 wpa_printf(MSG_DEBUG, "WPS:  * AP Setup Locked");
00344                 wpabuf_put_be16(msg, ATTR_AP_SETUP_LOCKED);
00345                 wpabuf_put_be16(msg, 1);
00346                 wpabuf_put_u8(msg, 1);
00347         }
00348         return 0;
00349 }
00350 
00351 
00352 static int wps_build_selected_registrar(struct wps_registrar *reg,
00353                                         struct wpabuf *msg)
00354 {
00355         if (!reg->sel_reg_union)
00356                 return 0;
00357         wpa_printf(MSG_DEBUG, "WPS:  * Selected Registrar");
00358         wpabuf_put_be16(msg, ATTR_SELECTED_REGISTRAR);
00359         wpabuf_put_be16(msg, 1);
00360         wpabuf_put_u8(msg, 1);
00361         return 0;
00362 }
00363 
00364 
00365 static int wps_build_sel_reg_dev_password_id(struct wps_registrar *reg,
00366                                              struct wpabuf *msg)
00367 {
00368         u16 id = reg->pbc ? DEV_PW_PUSHBUTTON : DEV_PW_DEFAULT;
00369         if (!reg->sel_reg_union)
00370                 return 0;
00371         if (reg->sel_reg_dev_password_id_override >= 0)
00372                 id = reg->sel_reg_dev_password_id_override;
00373         wpa_printf(MSG_DEBUG, "WPS:  * Device Password ID (%d)", id);
00374         wpabuf_put_be16(msg, ATTR_DEV_PASSWORD_ID);
00375         wpabuf_put_be16(msg, 2);
00376         wpabuf_put_be16(msg, id);
00377         return 0;
00378 }
00379 
00380 
00381 static int wps_build_sel_reg_config_methods(struct wps_registrar *reg,
00382                                             struct wpabuf *msg)
00383 {
00384         u16 methods;
00385         if (!reg->sel_reg_union)
00386                 return 0;
00387         methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;
00388         if (reg->pbc)
00389                 methods |= WPS_CONFIG_PUSHBUTTON;
00390         if (reg->sel_reg_config_methods_override >= 0)
00391                 methods = reg->sel_reg_config_methods_override;
00392         wpa_printf(MSG_DEBUG, "WPS:  * Selected Registrar Config Methods (%x)",
00393                    methods);
00394         wpabuf_put_be16(msg, ATTR_SELECTED_REGISTRAR_CONFIG_METHODS);
00395         wpabuf_put_be16(msg, 2);
00396         wpabuf_put_be16(msg, methods);
00397         return 0;
00398 }
00399 
00400 
00401 static int wps_build_probe_config_methods(struct wps_registrar *reg,
00402                                           struct wpabuf *msg)
00403 {
00404         u16 methods;
00405         /*
00406          * These are the methods that the AP supports as an Enrollee for adding
00407          * external Registrars.
00408          */
00409         methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;
00410         wpa_printf(MSG_DEBUG, "WPS:  * Config Methods (%x)", methods);
00411         wpabuf_put_be16(msg, ATTR_CONFIG_METHODS);
00412         wpabuf_put_be16(msg, 2);
00413         wpabuf_put_be16(msg, methods);
00414         return 0;
00415 }
00416 
00417 
00418 static int wps_build_config_methods_r(struct wps_registrar *reg,
00419                                       struct wpabuf *msg)
00420 {
00421         u16 methods;
00422         methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;
00423         if (reg->pbc)
00424                 methods |= WPS_CONFIG_PUSHBUTTON;
00425         return wps_build_config_methods(msg, methods);
00426 }
00427 
00428 
00429 static int wps_build_resp_type(struct wps_registrar *reg, struct wpabuf *msg)
00430 {
00431         u8 resp = reg->wps->ap ? WPS_RESP_AP : WPS_RESP_REGISTRAR;
00432         wpa_printf(MSG_DEBUG, "WPS:  * Response Type (%d)", resp);
00433         wpabuf_put_be16(msg, ATTR_RESPONSE_TYPE);
00434         wpabuf_put_be16(msg, 1);
00435         wpabuf_put_u8(msg, resp);
00436         return 0;
00437 }
00438 
00439 
00452 struct wps_registrar *
00453 wps_registrar_init(struct wps_context *wps,
00454                    const struct wps_registrar_config *cfg)
00455 {
00456         struct wps_registrar *reg = os_zalloc(sizeof(*reg));
00457         if (reg == NULL)
00458                 return NULL;
00459 
00460         dl_list_init(&reg->pins);
00461         reg->wps = wps;
00462         reg->new_psk_cb = cfg->new_psk_cb;
00463         reg->set_ie_cb = cfg->set_ie_cb;
00464         reg->pin_needed_cb = cfg->pin_needed_cb;
00465         reg->reg_success_cb = cfg->reg_success_cb;
00466         reg->set_sel_reg_cb = cfg->set_sel_reg_cb;
00467         reg->enrollee_seen_cb = cfg->enrollee_seen_cb;
00468         reg->cb_ctx = cfg->cb_ctx;
00469         reg->skip_cred_build = cfg->skip_cred_build;
00470         if (cfg->extra_cred) {
00471                 reg->extra_cred = wpabuf_alloc_copy(cfg->extra_cred,
00472                                                     cfg->extra_cred_len);
00473                 if (reg->extra_cred == NULL) {
00474                         os_free(reg);
00475                         return NULL;
00476                 }
00477         }
00478         reg->disable_auto_conf = cfg->disable_auto_conf;
00479         reg->sel_reg_dev_password_id_override = -1;
00480         reg->sel_reg_config_methods_override = -1;
00481         reg->static_wep_only = cfg->static_wep_only;
00482 
00483         if (wps_set_ie(reg)) {
00484                 wps_registrar_deinit(reg);
00485                 return NULL;
00486         }
00487 
00488         return reg;
00489 }
00490 
00491 
00496 void wps_registrar_deinit(struct wps_registrar *reg)
00497 {
00498         if (reg == NULL)
00499                 return;
00500         eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
00501         eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
00502         wps_free_pins(&reg->pins);
00503         wps_free_pbc_sessions(reg->pbc_sessions);
00504         wpabuf_free(reg->extra_cred);
00505         wps_free_devices(reg->devices);
00506         os_free(reg);
00507 }
00508 
00509 
00519 int wps_registrar_add_pin(struct wps_registrar *reg, const u8 *uuid,
00520                           const u8 *pin, size_t pin_len, int timeout)
00521 {
00522         struct wps_uuid_pin *p;
00523 
00524         p = os_zalloc(sizeof(*p));
00525         if (p == NULL)
00526                 return -1;
00527         if (uuid == NULL)
00528                 p->wildcard_uuid = 1;
00529         else
00530                 os_memcpy(p->uuid, uuid, WPS_UUID_LEN);
00531         p->pin = os_malloc(pin_len);
00532         if (p->pin == NULL) {
00533                 os_free(p);
00534                 return -1;
00535         }
00536         os_memcpy(p->pin, pin, pin_len);
00537         p->pin_len = pin_len;
00538 
00539         if (timeout) {
00540                 p->flags |= PIN_EXPIRES;
00541                 os_get_time(&p->expiration);
00542                 p->expiration.sec += timeout;
00543         }
00544 
00545         dl_list_add(&reg->pins, &p->list);
00546 
00547         wpa_printf(MSG_DEBUG, "WPS: A new PIN configured (timeout=%d)",
00548                    timeout);
00549         wpa_hexdump(MSG_DEBUG, "WPS: UUID", uuid, WPS_UUID_LEN);
00550         wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: PIN", pin, pin_len);
00551         reg->selected_registrar = 1;
00552         reg->pbc = 0;
00553         wps_registrar_selected_registrar_changed(reg);
00554         eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
00555         eloop_register_timeout(WPS_PBC_WALK_TIME, 0,
00556                                wps_registrar_set_selected_timeout,
00557                                reg, NULL);
00558 
00559         return 0;
00560 }
00561 
00562 
00563 static void wps_registrar_expire_pins(struct wps_registrar *reg)
00564 {
00565         struct wps_uuid_pin *pin, *prev;
00566         struct os_time now;
00567 
00568         os_get_time(&now);
00569         dl_list_for_each_safe(pin, prev, &reg->pins, struct wps_uuid_pin, list)
00570         {
00571                 if ((pin->flags & PIN_EXPIRES) &&
00572                     os_time_before(&pin->expiration, &now)) {
00573                         wpa_hexdump(MSG_DEBUG, "WPS: Expired PIN for UUID",
00574                                     pin->uuid, WPS_UUID_LEN);
00575                         wps_remove_pin(pin);
00576                 }
00577         }
00578 }
00579 
00580 
00587 int wps_registrar_invalidate_pin(struct wps_registrar *reg, const u8 *uuid)
00588 {
00589         struct wps_uuid_pin *pin, *prev;
00590 
00591         dl_list_for_each_safe(pin, prev, &reg->pins, struct wps_uuid_pin, list)
00592         {
00593                 if (os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) {
00594                         wpa_hexdump(MSG_DEBUG, "WPS: Invalidated PIN for UUID",
00595                                     pin->uuid, WPS_UUID_LEN);
00596                         wps_remove_pin(pin);
00597                         return 0;
00598                 }
00599         }
00600 
00601         return -1;
00602 }
00603 
00604 
00605 static const u8 * wps_registrar_get_pin(struct wps_registrar *reg,
00606                                         const u8 *uuid, size_t *pin_len)
00607 {
00608         struct wps_uuid_pin *pin, *found = NULL;
00609 
00610         wps_registrar_expire_pins(reg);
00611 
00612         dl_list_for_each(pin, &reg->pins, struct wps_uuid_pin, list) {
00613                 if (!pin->wildcard_uuid &&
00614                     os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) {
00615                         found = pin;
00616                         break;
00617                 }
00618         }
00619 
00620         if (!found) {
00621                 /* Check for wildcard UUIDs since none of the UUID-specific
00622                  * PINs matched */
00623                 dl_list_for_each(pin, &reg->pins, struct wps_uuid_pin, list) {
00624                         if (pin->wildcard_uuid == 1) {
00625                                 wpa_printf(MSG_DEBUG, "WPS: Found a wildcard "
00626                                            "PIN. Assigned it for this UUID-E");
00627                                 pin->wildcard_uuid = 2;
00628                                 os_memcpy(pin->uuid, uuid, WPS_UUID_LEN);
00629                                 found = pin;
00630                                 break;
00631                         }
00632                 }
00633         }
00634 
00635         if (!found)
00636                 return NULL;
00637 
00638         /*
00639          * Lock the PIN to avoid attacks based on concurrent re-use of the PIN
00640          * that could otherwise avoid PIN invalidations.
00641          */
00642         if (found->flags & PIN_LOCKED) {
00643                 wpa_printf(MSG_DEBUG, "WPS: Selected PIN locked - do not "
00644                            "allow concurrent re-use");
00645                 return NULL;
00646         }
00647         *pin_len = found->pin_len;
00648         found->flags |= PIN_LOCKED;
00649         return found->pin;
00650 }
00651 
00652 
00663 int wps_registrar_unlock_pin(struct wps_registrar *reg, const u8 *uuid)
00664 {
00665         struct wps_uuid_pin *pin;
00666 
00667         dl_list_for_each(pin, &reg->pins, struct wps_uuid_pin, list) {
00668                 if (os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) {
00669                         if (pin->wildcard_uuid == 2) {
00670                                 wpa_printf(MSG_DEBUG, "WPS: Invalidating used "
00671                                            "wildcard PIN");
00672                                 return wps_registrar_invalidate_pin(reg, uuid);
00673                         }
00674                         pin->flags &= ~PIN_LOCKED;
00675                         return 0;
00676                 }
00677         }
00678 
00679         return -1;
00680 }
00681 
00682 
00683 static void wps_registrar_stop_pbc(struct wps_registrar *reg)
00684 {
00685         reg->selected_registrar = 0;
00686         reg->pbc = 0;
00687         wps_registrar_selected_registrar_changed(reg);
00688 }
00689 
00690 
00691 static void wps_registrar_pbc_timeout(void *eloop_ctx, void *timeout_ctx)
00692 {
00693         struct wps_registrar *reg = eloop_ctx;
00694 
00695         wpa_printf(MSG_DEBUG, "WPS: PBC timed out - disable PBC mode");
00696         wps_pbc_timeout_event(reg->wps);
00697         wps_registrar_stop_pbc(reg);
00698 }
00699 
00700 
00710 int wps_registrar_button_pushed(struct wps_registrar *reg)
00711 {
00712         if (wps_registrar_pbc_overlap(reg, NULL, NULL)) {
00713                 wpa_printf(MSG_DEBUG, "WPS: PBC overlap - do not start PBC "
00714                            "mode");
00715                 wps_pbc_overlap_event(reg->wps);
00716                 return -1;
00717         }
00718         wpa_printf(MSG_DEBUG, "WPS: Button pushed - PBC mode started");
00719         reg->force_pbc_overlap = 0;
00720         reg->selected_registrar = 1;
00721         reg->pbc = 1;
00722         wps_registrar_selected_registrar_changed(reg);
00723 
00724         eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
00725         eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wps_registrar_pbc_timeout,
00726                                reg, NULL);
00727         return 0;
00728 }
00729 
00730 
00731 static void wps_registrar_pbc_completed(struct wps_registrar *reg)
00732 {
00733         wpa_printf(MSG_DEBUG, "WPS: PBC completed - stopping PBC mode");
00734         eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
00735         wps_registrar_stop_pbc(reg);
00736 }
00737 
00738 
00739 static void wps_registrar_pin_completed(struct wps_registrar *reg)
00740 {
00741         wpa_printf(MSG_DEBUG, "WPS: PIN completed using internal Registrar");
00742         eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
00743         reg->selected_registrar = 0;
00744         wps_registrar_selected_registrar_changed(reg);
00745 }
00746 
00747 
00758 void wps_registrar_probe_req_rx(struct wps_registrar *reg, const u8 *addr,
00759                                 const struct wpabuf *wps_data)
00760 {
00761         struct wps_parse_attr attr;
00762 
00763         wpa_hexdump_buf(MSG_MSGDUMP,
00764                         "WPS: Probe Request with WPS data received",
00765                         wps_data);
00766 
00767         if (wps_parse_msg(wps_data, &attr) < 0)
00768                 return;
00769         if (!wps_version_supported(attr.version)) {
00770                 wpa_printf(MSG_DEBUG, "WPS: Unsupported ProbeReq WPS IE "
00771                            "version 0x%x", attr.version ? *attr.version : 0);
00772                 return;
00773         }
00774 
00775         if (attr.config_methods == NULL) {
00776                 wpa_printf(MSG_DEBUG, "WPS: No Config Methods attribute in "
00777                            "Probe Request");
00778                 return;
00779         }
00780 
00781         if (attr.dev_password_id == NULL) {
00782                 wpa_printf(MSG_DEBUG, "WPS: No Device Password Id attribute "
00783                            "in Probe Request");
00784                 return;
00785         }
00786 
00787         if (reg->enrollee_seen_cb && attr.uuid_e &&
00788             attr.primary_dev_type && attr.request_type) {
00789                 char *dev_name = NULL;
00790                 if (attr.dev_name) {
00791                         dev_name = os_zalloc(attr.dev_name_len + 1);
00792                         if (dev_name) {
00793                                 os_memcpy(dev_name, attr.dev_name,
00794                                           attr.dev_name_len);
00795                         }
00796                 }
00797                 reg->enrollee_seen_cb(reg->cb_ctx, addr, attr.uuid_e,
00798                                       attr.primary_dev_type,
00799                                       WPA_GET_BE16(attr.config_methods),
00800                                       WPA_GET_BE16(attr.dev_password_id),
00801                                       *attr.request_type, dev_name);
00802                 os_free(dev_name);
00803         }
00804 
00805         if (WPA_GET_BE16(attr.dev_password_id) != DEV_PW_PUSHBUTTON)
00806                 return; /* Not PBC */
00807 
00808         wpa_printf(MSG_DEBUG, "WPS: Probe Request for PBC received from "
00809                    MACSTR, MAC2STR(addr));
00810         if (attr.uuid_e == NULL) {
00811                 wpa_printf(MSG_DEBUG, "WPS: Invalid Probe Request WPS IE: No "
00812                            "UUID-E included");
00813                 return;
00814         }
00815 
00816         wps_registrar_add_pbc_session(reg, addr, attr.uuid_e);
00817         if (wps_registrar_pbc_overlap(reg, addr, attr.uuid_e)) {
00818                 wpa_printf(MSG_DEBUG, "WPS: PBC session overlap detected");
00819                 reg->force_pbc_overlap = 1;
00820                 wps_pbc_overlap_event(reg->wps);
00821         }
00822 }
00823 
00824 
00825 static int wps_cb_new_psk(struct wps_registrar *reg, const u8 *mac_addr,
00826                           const u8 *psk, size_t psk_len)
00827 {
00828         if (reg->new_psk_cb == NULL)
00829                 return 0;
00830 
00831         return reg->new_psk_cb(reg->cb_ctx, mac_addr, psk, psk_len);
00832 }
00833 
00834 
00835 static void wps_cb_pin_needed(struct wps_registrar *reg, const u8 *uuid_e,
00836                               const struct wps_device_data *dev)
00837 {
00838         if (reg->pin_needed_cb == NULL)
00839                 return;
00840 
00841         reg->pin_needed_cb(reg->cb_ctx, uuid_e, dev);
00842 }
00843 
00844 
00845 static void wps_cb_reg_success(struct wps_registrar *reg, const u8 *mac_addr,
00846                                const u8 *uuid_e)
00847 {
00848         if (reg->reg_success_cb == NULL)
00849                 return;
00850 
00851         reg->reg_success_cb(reg->cb_ctx, mac_addr, uuid_e);
00852 }
00853 
00854 
00855 static int wps_cb_set_ie(struct wps_registrar *reg, struct wpabuf *beacon_ie,
00856                          struct wpabuf *probe_resp_ie)
00857 {
00858         return reg->set_ie_cb(reg->cb_ctx, beacon_ie, probe_resp_ie);
00859 }
00860 
00861 
00862 static void wps_cb_set_sel_reg(struct wps_registrar *reg)
00863 {
00864         u16 methods = 0;
00865         if (reg->set_sel_reg_cb == NULL)
00866                 return;
00867 
00868         if (reg->selected_registrar) {
00869                 methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;
00870                 if (reg->pbc)
00871                         methods |= WPS_CONFIG_PUSHBUTTON;
00872         }
00873 
00874         reg->set_sel_reg_cb(reg->cb_ctx, reg->selected_registrar,
00875                             reg->pbc ? DEV_PW_PUSHBUTTON : DEV_PW_DEFAULT,
00876                             methods);
00877 }
00878 
00879 
00880 /* Encapsulate WPS IE data with one (or more, if needed) IE headers */
00881 static struct wpabuf * wps_ie_encapsulate(struct wpabuf *data)
00882 {
00883         struct wpabuf *ie;
00884         const u8 *pos, *end;
00885 
00886         ie = wpabuf_alloc(wpabuf_len(data) + 100);
00887         if (ie == NULL) {
00888                 wpabuf_free(data);
00889                 return NULL;
00890         }
00891 
00892         pos = wpabuf_head(data);
00893         end = pos + wpabuf_len(data);
00894 
00895         while (end > pos) {
00896                 size_t frag_len = end - pos;
00897                 if (frag_len > 251)
00898                         frag_len = 251;
00899                 wpabuf_put_u8(ie, WLAN_EID_VENDOR_SPECIFIC);
00900                 wpabuf_put_u8(ie, 4 + frag_len);
00901                 wpabuf_put_be32(ie, WPS_DEV_OUI_WFA);
00902                 wpabuf_put_data(ie, pos, frag_len);
00903                 pos += frag_len;
00904         }
00905 
00906         wpabuf_free(data);
00907 
00908         return ie;
00909 }
00910 
00911 
00912 static int wps_set_ie(struct wps_registrar *reg)
00913 {
00914         struct wpabuf *beacon;
00915         struct wpabuf *probe;
00916 
00917         if (reg->set_ie_cb == NULL)
00918                 return 0;
00919 
00920         wpa_printf(MSG_DEBUG, "WPS: Build Beacon and Probe Response IEs");
00921 
00922         beacon = wpabuf_alloc(300);
00923         if (beacon == NULL)
00924                 return -1;
00925         probe = wpabuf_alloc(400);
00926         if (probe == NULL) {
00927                 wpabuf_free(beacon);
00928                 return -1;
00929         }
00930 
00931         if (wps_build_version(beacon) ||
00932             wps_build_wps_state(reg->wps, beacon) ||
00933             wps_build_ap_setup_locked(reg->wps, beacon) ||
00934             wps_build_selected_registrar(reg, beacon) ||
00935             wps_build_sel_reg_dev_password_id(reg, beacon) ||
00936             wps_build_sel_reg_config_methods(reg, beacon) ||
00937             wps_build_version(probe) ||
00938             wps_build_wps_state(reg->wps, probe) ||
00939             wps_build_ap_setup_locked(reg->wps, probe) ||
00940             wps_build_selected_registrar(reg, probe) ||
00941             wps_build_sel_reg_dev_password_id(reg, probe) ||
00942             wps_build_sel_reg_config_methods(reg, probe) ||
00943             wps_build_resp_type(reg, probe) ||
00944             wps_build_uuid_e(probe, reg->wps->uuid) ||
00945             wps_build_device_attrs(&reg->wps->dev, probe) ||
00946             wps_build_probe_config_methods(reg, probe) ||
00947             wps_build_rf_bands(&reg->wps->dev, probe)) {
00948                 wpabuf_free(beacon);
00949                 wpabuf_free(probe);
00950                 return -1;
00951         }
00952 
00953         beacon = wps_ie_encapsulate(beacon);
00954         probe = wps_ie_encapsulate(probe);
00955 
00956         if (!beacon || !probe) {
00957                 wpabuf_free(beacon);
00958                 wpabuf_free(probe);
00959                 return -1;
00960         }
00961 
00962         if (reg->static_wep_only) {
00963                 /*
00964                  * Windows XP and Vista clients can get confused about
00965                  * EAP-Identity/Request when they probe the network with
00966                  * EAPOL-Start. In such a case, they may assume the network is
00967                  * using IEEE 802.1X and prompt user for a certificate while
00968                  * the correct (non-WPS) behavior would be to ask for the
00969                  * static WEP key. As a workaround, use Microsoft Provisioning
00970                  * IE to advertise that legacy 802.1X is not supported.
00971                  */
00972                 const u8 ms_wps[7] = {
00973                         WLAN_EID_VENDOR_SPECIFIC, 5,
00974                         /* Microsoft Provisioning IE (00:50:f2:5) */
00975                         0x00, 0x50, 0xf2, 5,
00976                         0x00 /* no legacy 802.1X or MS WPS */
00977                 };
00978                 wpa_printf(MSG_DEBUG, "WPS: Add Microsoft Provisioning IE "
00979                            "into Beacon/Probe Response frames");
00980                 wpabuf_put_data(beacon, ms_wps, sizeof(ms_wps));
00981                 wpabuf_put_data(probe, ms_wps, sizeof(ms_wps));
00982         }
00983 
00984         return wps_cb_set_ie(reg, beacon, probe);
00985 }
00986 
00987 
00988 static int wps_get_dev_password(struct wps_data *wps)
00989 {
00990         const u8 *pin;
00991         size_t pin_len = 0;
00992 
00993         os_free(wps->dev_password);
00994         wps->dev_password = NULL;
00995 
00996         if (wps->pbc) {
00997                 wpa_printf(MSG_DEBUG, "WPS: Use default PIN for PBC");
00998                 pin = (const u8 *) "00000000";
00999                 pin_len = 8;
01000         } else {
01001                 pin = wps_registrar_get_pin(wps->wps->registrar, wps->uuid_e,
01002                                             &pin_len);
01003         }
01004         if (pin == NULL) {
01005                 wpa_printf(MSG_DEBUG, "WPS: No Device Password available for "
01006                            "the Enrollee");
01007                 wps_cb_pin_needed(wps->wps->registrar, wps->uuid_e,
01008                                   &wps->peer_dev);
01009                 return -1;
01010         }
01011 
01012         wps->dev_password = os_malloc(pin_len);
01013         if (wps->dev_password == NULL)
01014                 return -1;
01015         os_memcpy(wps->dev_password, pin, pin_len);
01016         wps->dev_password_len = pin_len;
01017 
01018         return 0;
01019 }
01020 
01021 
01022 static int wps_build_uuid_r(struct wps_data *wps, struct wpabuf *msg)
01023 {
01024         wpa_printf(MSG_DEBUG, "WPS:  * UUID-R");
01025         wpabuf_put_be16(msg, ATTR_UUID_R);
01026         wpabuf_put_be16(msg, WPS_UUID_LEN);
01027         wpabuf_put_data(msg, wps->uuid_r, WPS_UUID_LEN);
01028         return 0;
01029 }
01030 
01031 
01032 static int wps_build_r_hash(struct wps_data *wps, struct wpabuf *msg)
01033 {
01034         u8 *hash;
01035         const u8 *addr[4];
01036         size_t len[4];
01037 
01038         if (os_get_random(wps->snonce, 2 * WPS_SECRET_NONCE_LEN) < 0)
01039                 return -1;
01040         wpa_hexdump(MSG_DEBUG, "WPS: R-S1", wps->snonce, WPS_SECRET_NONCE_LEN);
01041         wpa_hexdump(MSG_DEBUG, "WPS: R-S2",
01042                     wps->snonce + WPS_SECRET_NONCE_LEN, WPS_SECRET_NONCE_LEN);
01043 
01044         if (wps->dh_pubkey_e == NULL || wps->dh_pubkey_r == NULL) {
01045                 wpa_printf(MSG_DEBUG, "WPS: DH public keys not available for "
01046                            "R-Hash derivation");
01047                 return -1;
01048         }
01049 
01050         wpa_printf(MSG_DEBUG, "WPS:  * R-Hash1");
01051         wpabuf_put_be16(msg, ATTR_R_HASH1);
01052         wpabuf_put_be16(msg, SHA256_MAC_LEN);
01053         hash = wpabuf_put(msg, SHA256_MAC_LEN);
01054         /* R-Hash1 = HMAC_AuthKey(R-S1 || PSK1 || PK_E || PK_R) */
01055         addr[0] = wps->snonce;
01056         len[0] = WPS_SECRET_NONCE_LEN;
01057         addr[1] = wps->psk1;
01058         len[1] = WPS_PSK_LEN;
01059         addr[2] = wpabuf_head(wps->dh_pubkey_e);
01060         len[2] = wpabuf_len(wps->dh_pubkey_e);
01061         addr[3] = wpabuf_head(wps->dh_pubkey_r);
01062         len[3] = wpabuf_len(wps->dh_pubkey_r);
01063         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
01064         wpa_hexdump(MSG_DEBUG, "WPS: R-Hash1", hash, SHA256_MAC_LEN);
01065 
01066         wpa_printf(MSG_DEBUG, "WPS:  * R-Hash2");
01067         wpabuf_put_be16(msg, ATTR_R_HASH2);
01068         wpabuf_put_be16(msg, SHA256_MAC_LEN);
01069         hash = wpabuf_put(msg, SHA256_MAC_LEN);
01070         /* R-Hash2 = HMAC_AuthKey(R-S2 || PSK2 || PK_E || PK_R) */
01071         addr[0] = wps->snonce + WPS_SECRET_NONCE_LEN;
01072         addr[1] = wps->psk2;
01073         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
01074         wpa_hexdump(MSG_DEBUG, "WPS: R-Hash2", hash, SHA256_MAC_LEN);
01075 
01076         return 0;
01077 }
01078 
01079 
01080 static int wps_build_r_snonce1(struct wps_data *wps, struct wpabuf *msg)
01081 {
01082         wpa_printf(MSG_DEBUG, "WPS:  * R-SNonce1");
01083         wpabuf_put_be16(msg, ATTR_R_SNONCE1);
01084         wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
01085         wpabuf_put_data(msg, wps->snonce, WPS_SECRET_NONCE_LEN);
01086         return 0;
01087 }
01088 
01089 
01090 static int wps_build_r_snonce2(struct wps_data *wps, struct wpabuf *msg)
01091 {
01092         wpa_printf(MSG_DEBUG, "WPS:  * R-SNonce2");
01093         wpabuf_put_be16(msg, ATTR_R_SNONCE2);
01094         wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
01095         wpabuf_put_data(msg, wps->snonce + WPS_SECRET_NONCE_LEN,
01096                         WPS_SECRET_NONCE_LEN);
01097         return 0;
01098 }
01099 
01100 
01101 static int wps_build_cred_network_idx(struct wpabuf *msg,
01102                                       const struct wps_credential *cred)
01103 {
01104         wpa_printf(MSG_DEBUG, "WPS:  * Network Index");
01105         wpabuf_put_be16(msg, ATTR_NETWORK_INDEX);
01106         wpabuf_put_be16(msg, 1);
01107         wpabuf_put_u8(msg, 1);
01108         return 0;
01109 }
01110 
01111 
01112 static int wps_build_cred_ssid(struct wpabuf *msg,
01113                                const struct wps_credential *cred)
01114 {
01115         wpa_printf(MSG_DEBUG, "WPS:  * SSID");
01116         wpabuf_put_be16(msg, ATTR_SSID);
01117         wpabuf_put_be16(msg, cred->ssid_len);
01118         wpabuf_put_data(msg, cred->ssid, cred->ssid_len);
01119         return 0;
01120 }
01121 
01122 
01123 static int wps_build_cred_auth_type(struct wpabuf *msg,
01124                                     const struct wps_credential *cred)
01125 {
01126         wpa_printf(MSG_DEBUG, "WPS:  * Authentication Type (0x%x)",
01127                    cred->auth_type);
01128         wpabuf_put_be16(msg, ATTR_AUTH_TYPE);
01129         wpabuf_put_be16(msg, 2);
01130         wpabuf_put_be16(msg, cred->auth_type);
01131         return 0;
01132 }
01133 
01134 
01135 static int wps_build_cred_encr_type(struct wpabuf *msg,
01136                                     const struct wps_credential *cred)
01137 {
01138         wpa_printf(MSG_DEBUG, "WPS:  * Encryption Type (0x%x)",
01139                    cred->encr_type);
01140         wpabuf_put_be16(msg, ATTR_ENCR_TYPE);
01141         wpabuf_put_be16(msg, 2);
01142         wpabuf_put_be16(msg, cred->encr_type);
01143         return 0;
01144 }
01145 
01146 
01147 static int wps_build_cred_network_key(struct wpabuf *msg,
01148                                       const struct wps_credential *cred)
01149 {
01150         wpa_printf(MSG_DEBUG, "WPS:  * Network Key (len=%d)",
01151                    (int) cred->key_len);
01152         wpabuf_put_be16(msg, ATTR_NETWORK_KEY);
01153         wpabuf_put_be16(msg, cred->key_len);
01154         wpabuf_put_data(msg, cred->key, cred->key_len);
01155         return 0;
01156 }
01157 
01158 
01159 static int wps_build_cred_mac_addr(struct wpabuf *msg,
01160                                    const struct wps_credential *cred)
01161 {
01162         wpa_printf(MSG_DEBUG, "WPS:  * MAC Address (" MACSTR ")",
01163                    MAC2STR(cred->mac_addr));
01164         wpabuf_put_be16(msg, ATTR_MAC_ADDR);
01165         wpabuf_put_be16(msg, ETH_ALEN);
01166         wpabuf_put_data(msg, cred->mac_addr, ETH_ALEN);
01167         return 0;
01168 }
01169 
01170 
01171 static int wps_build_credential(struct wpabuf *msg,
01172                                 const struct wps_credential *cred)
01173 {
01174         if (wps_build_cred_network_idx(msg, cred) ||
01175             wps_build_cred_ssid(msg, cred) ||
01176             wps_build_cred_auth_type(msg, cred) ||
01177             wps_build_cred_encr_type(msg, cred) ||
01178             wps_build_cred_network_key(msg, cred) ||
01179             wps_build_cred_mac_addr(msg, cred))
01180                 return -1;
01181         return 0;
01182 }
01183 
01184 
01185 int wps_build_cred(struct wps_data *wps, struct wpabuf *msg)
01186 {
01187         struct wpabuf *cred;
01188 
01189         if (wps->wps->registrar->skip_cred_build)
01190                 goto skip_cred_build;
01191 
01192         wpa_printf(MSG_DEBUG, "WPS:  * Credential");
01193         if (wps->use_cred) {
01194                 os_memcpy(&wps->cred, wps->use_cred, sizeof(wps->cred));
01195                 goto use_provided;
01196         }
01197         os_memset(&wps->cred, 0, sizeof(wps->cred));
01198 
01199         os_memcpy(wps->cred.ssid, wps->wps->ssid, wps->wps->ssid_len);
01200         wps->cred.ssid_len = wps->wps->ssid_len;
01201 
01202         /* Select the best authentication and encryption type */
01203         if (wps->auth_type & WPS_AUTH_WPA2PSK)
01204                 wps->auth_type = WPS_AUTH_WPA2PSK;
01205         else if (wps->auth_type & WPS_AUTH_WPAPSK)
01206                 wps->auth_type = WPS_AUTH_WPAPSK;
01207         else if (wps->auth_type & WPS_AUTH_OPEN)
01208                 wps->auth_type = WPS_AUTH_OPEN;
01209         else if (wps->auth_type & WPS_AUTH_SHARED)
01210                 wps->auth_type = WPS_AUTH_SHARED;
01211         else {
01212                 wpa_printf(MSG_DEBUG, "WPS: Unsupported auth_type 0x%x",
01213                            wps->auth_type);
01214                 return -1;
01215         }
01216         wps->cred.auth_type = wps->auth_type;
01217 
01218         if (wps->auth_type == WPS_AUTH_WPA2PSK ||
01219             wps->auth_type == WPS_AUTH_WPAPSK) {
01220                 if (wps->encr_type & WPS_ENCR_AES)
01221                         wps->encr_type = WPS_ENCR_AES;
01222                 else if (wps->encr_type & WPS_ENCR_TKIP)
01223                         wps->encr_type = WPS_ENCR_TKIP;
01224                 else {
01225                         wpa_printf(MSG_DEBUG, "WPS: No suitable encryption "
01226                                    "type for WPA/WPA2");
01227                         return -1;
01228                 }
01229         } else {
01230                 if (wps->encr_type & WPS_ENCR_WEP)
01231                         wps->encr_type = WPS_ENCR_WEP;
01232                 else if (wps->encr_type & WPS_ENCR_NONE)
01233                         wps->encr_type = WPS_ENCR_NONE;
01234                 else {
01235                         wpa_printf(MSG_DEBUG, "WPS: No suitable encryption "
01236                                    "type for non-WPA/WPA2 mode");
01237                         return -1;
01238                 }
01239         }
01240         wps->cred.encr_type = wps->encr_type;
01241         /*
01242          * Set MAC address in the Credential to be the Enrollee's MAC address
01243          */
01244         os_memcpy(wps->cred.mac_addr, wps->mac_addr_e, ETH_ALEN);
01245 
01246         if (wps->wps->wps_state == WPS_STATE_NOT_CONFIGURED && wps->wps->ap &&
01247             !wps->wps->registrar->disable_auto_conf) {
01248                 u8 r[16];
01249                 /* Generate a random passphrase */
01250                 if (os_get_random(r, sizeof(r)) < 0)
01251                         return -1;
01252                 os_free(wps->new_psk);
01253                 wps->new_psk = base64_encode(r, sizeof(r), &wps->new_psk_len);
01254                 if (wps->new_psk == NULL)
01255                         return -1;
01256                 wps->new_psk_len--; /* remove newline */
01257                 while (wps->new_psk_len &&
01258                        wps->new_psk[wps->new_psk_len - 1] == '=')
01259                         wps->new_psk_len--;
01260                 wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: Generated passphrase",
01261                                       wps->new_psk, wps->new_psk_len);
01262                 os_memcpy(wps->cred.key, wps->new_psk, wps->new_psk_len);
01263                 wps->cred.key_len = wps->new_psk_len;
01264         } else if (wps->use_psk_key && wps->wps->psk_set) {
01265                 char hex[65];
01266                 wpa_printf(MSG_DEBUG, "WPS: Use PSK format for Network Key");
01267                 wpa_snprintf_hex(hex, sizeof(hex), wps->wps->psk, 32);
01268                 os_memcpy(wps->cred.key, hex, 32 * 2);
01269                 wps->cred.key_len = 32 * 2;
01270         } else if (wps->wps->network_key) {
01271                 os_memcpy(wps->cred.key, wps->wps->network_key,
01272                           wps->wps->network_key_len);
01273                 wps->cred.key_len = wps->wps->network_key_len;
01274         } else if (wps->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) {
01275                 char hex[65];
01276                 /* Generate a random per-device PSK */
01277                 os_free(wps->new_psk);
01278                 wps->new_psk_len = 32;
01279                 wps->new_psk = os_malloc(wps->new_psk_len);
01280                 if (wps->new_psk == NULL)
01281                         return -1;
01282                 if (os_get_random(wps->new_psk, wps->new_psk_len) < 0) {
01283                         os_free(wps->new_psk);
01284                         wps->new_psk = NULL;
01285                         return -1;
01286                 }
01287                 wpa_hexdump_key(MSG_DEBUG, "WPS: Generated per-device PSK",
01288                                 wps->new_psk, wps->new_psk_len);
01289                 wpa_snprintf_hex(hex, sizeof(hex), wps->new_psk,
01290                                  wps->new_psk_len);
01291                 os_memcpy(wps->cred.key, hex, wps->new_psk_len * 2);
01292                 wps->cred.key_len = wps->new_psk_len * 2;
01293         }
01294 
01295 use_provided:
01296         cred = wpabuf_alloc(200);
01297         if (cred == NULL)
01298                 return -1;
01299 
01300         if (wps_build_credential(cred, &wps->cred)) {
01301                 wpabuf_free(cred);
01302                 return -1;
01303         }
01304 
01305         wpabuf_put_be16(msg, ATTR_CRED);
01306         wpabuf_put_be16(msg, wpabuf_len(cred));
01307         wpabuf_put_buf(msg, cred);
01308         wpabuf_free(cred);
01309 
01310 skip_cred_build:
01311         if (wps->wps->registrar->extra_cred) {
01312                 wpa_printf(MSG_DEBUG, "WPS:  * Credential (pre-configured)");
01313                 wpabuf_put_buf(msg, wps->wps->registrar->extra_cred);
01314         }
01315 
01316         return 0;
01317 }
01318 
01319 
01320 static int wps_build_ap_settings(struct wps_data *wps, struct wpabuf *msg)
01321 {
01322         wpa_printf(MSG_DEBUG, "WPS:  * AP Settings");
01323 
01324         if (wps_build_credential(msg, &wps->cred))
01325                 return -1;
01326 
01327         return 0;
01328 }
01329 
01330 
01331 static struct wpabuf * wps_build_m2(struct wps_data *wps)
01332 {
01333         struct wpabuf *msg;
01334 
01335         if (os_get_random(wps->nonce_r, WPS_NONCE_LEN) < 0)
01336                 return NULL;
01337         wpa_hexdump(MSG_DEBUG, "WPS: Registrar Nonce",
01338                     wps->nonce_r, WPS_NONCE_LEN);
01339         wpa_hexdump(MSG_DEBUG, "WPS: UUID-R", wps->uuid_r, WPS_UUID_LEN);
01340 
01341         wpa_printf(MSG_DEBUG, "WPS: Building Message M2");
01342         msg = wpabuf_alloc(1000);
01343         if (msg == NULL)
01344                 return NULL;
01345 
01346         if (wps_build_version(msg) ||
01347             wps_build_msg_type(msg, WPS_M2) ||
01348             wps_build_enrollee_nonce(wps, msg) ||
01349             wps_build_registrar_nonce(wps, msg) ||
01350             wps_build_uuid_r(wps, msg) ||
01351             wps_build_public_key(wps, msg) ||
01352             wps_derive_keys(wps) ||
01353             wps_build_auth_type_flags(wps, msg) ||
01354             wps_build_encr_type_flags(wps, msg) ||
01355             wps_build_conn_type_flags(wps, msg) ||
01356             wps_build_config_methods_r(wps->wps->registrar, msg) ||
01357             wps_build_device_attrs(&wps->wps->dev, msg) ||
01358             wps_build_rf_bands(&wps->wps->dev, msg) ||
01359             wps_build_assoc_state(wps, msg) ||
01360             wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
01361             wps_build_dev_password_id(msg, wps->dev_pw_id) ||
01362             wps_build_os_version(&wps->wps->dev, msg) ||
01363             wps_build_authenticator(wps, msg)) {
01364                 wpabuf_free(msg);
01365                 return NULL;
01366         }
01367 
01368         wps->int_reg = 1;
01369         wps->state = RECV_M3;
01370         return msg;
01371 }
01372 
01373 
01374 static struct wpabuf * wps_build_m2d(struct wps_data *wps)
01375 {
01376         struct wpabuf *msg;
01377         u16 err = wps->config_error;
01378 
01379         wpa_printf(MSG_DEBUG, "WPS: Building Message M2D");
01380         msg = wpabuf_alloc(1000);
01381         if (msg == NULL)
01382                 return NULL;
01383 
01384         if (wps->wps->ap && wps->wps->ap_setup_locked &&
01385             err == WPS_CFG_NO_ERROR)
01386                 err = WPS_CFG_SETUP_LOCKED;
01387 
01388         if (wps_build_version(msg) ||
01389             wps_build_msg_type(msg, WPS_M2D) ||
01390             wps_build_enrollee_nonce(wps, msg) ||
01391             wps_build_registrar_nonce(wps, msg) ||
01392             wps_build_uuid_r(wps, msg) ||
01393             wps_build_auth_type_flags(wps, msg) ||
01394             wps_build_encr_type_flags(wps, msg) ||
01395             wps_build_conn_type_flags(wps, msg) ||
01396             wps_build_config_methods_r(wps->wps->registrar, msg) ||
01397             wps_build_device_attrs(&wps->wps->dev, msg) ||
01398             wps_build_rf_bands(&wps->wps->dev, msg) ||
01399             wps_build_assoc_state(wps, msg) ||
01400             wps_build_config_error(msg, err) ||
01401             wps_build_os_version(&wps->wps->dev, msg)) {
01402                 wpabuf_free(msg);
01403                 return NULL;
01404         }
01405 
01406         wps->state = RECV_M2D_ACK;
01407         return msg;
01408 }
01409 
01410 
01411 static struct wpabuf * wps_build_m4(struct wps_data *wps)
01412 {
01413         struct wpabuf *msg, *plain;
01414 
01415         wpa_printf(MSG_DEBUG, "WPS: Building Message M4");
01416 
01417         wps_derive_psk(wps, wps->dev_password, wps->dev_password_len);
01418 
01419         plain = wpabuf_alloc(200);
01420         if (plain == NULL)
01421                 return NULL;
01422 
01423         msg = wpabuf_alloc(1000);
01424         if (msg == NULL) {
01425                 wpabuf_free(plain);
01426                 return NULL;
01427         }
01428 
01429         if (wps_build_version(msg) ||
01430             wps_build_msg_type(msg, WPS_M4) ||
01431             wps_build_enrollee_nonce(wps, msg) ||
01432             wps_build_r_hash(wps, msg) ||
01433             wps_build_r_snonce1(wps, plain) ||
01434             wps_build_key_wrap_auth(wps, plain) ||
01435             wps_build_encr_settings(wps, msg, plain) ||
01436             wps_build_authenticator(wps, msg)) {
01437                 wpabuf_free(plain);
01438                 wpabuf_free(msg);
01439                 return NULL;
01440         }
01441         wpabuf_free(plain);
01442 
01443         wps->state = RECV_M5;
01444         return msg;
01445 }
01446 
01447 
01448 static struct wpabuf * wps_build_m6(struct wps_data *wps)
01449 {
01450         struct wpabuf *msg, *plain;
01451 
01452         wpa_printf(MSG_DEBUG, "WPS: Building Message M6");
01453 
01454         plain = wpabuf_alloc(200);
01455         if (plain == NULL)
01456                 return NULL;
01457 
01458         msg = wpabuf_alloc(1000);
01459         if (msg == NULL) {
01460                 wpabuf_free(plain);
01461                 return NULL;
01462         }
01463 
01464         if (wps_build_version(msg) ||
01465             wps_build_msg_type(msg, WPS_M6) ||
01466             wps_build_enrollee_nonce(wps, msg) ||
01467             wps_build_r_snonce2(wps, plain) ||
01468             wps_build_key_wrap_auth(wps, plain) ||
01469             wps_build_encr_settings(wps, msg, plain) ||
01470             wps_build_authenticator(wps, msg)) {
01471                 wpabuf_free(plain);
01472                 wpabuf_free(msg);
01473                 return NULL;
01474         }
01475         wpabuf_free(plain);
01476 
01477         wps->wps_pin_revealed = 1;
01478         wps->state = RECV_M7;
01479         return msg;
01480 }
01481 
01482 
01483 static struct wpabuf * wps_build_m8(struct wps_data *wps)
01484 {
01485         struct wpabuf *msg, *plain;
01486 
01487         wpa_printf(MSG_DEBUG, "WPS: Building Message M8");
01488 
01489         plain = wpabuf_alloc(500);
01490         if (plain == NULL)
01491                 return NULL;
01492 
01493         msg = wpabuf_alloc(1000);
01494         if (msg == NULL) {
01495                 wpabuf_free(plain);
01496                 return NULL;
01497         }
01498 
01499         if (wps_build_version(msg) ||
01500             wps_build_msg_type(msg, WPS_M8) ||
01501             wps_build_enrollee_nonce(wps, msg) ||
01502             ((wps->wps->ap || wps->er) && wps_build_cred(wps, plain)) ||
01503             (!wps->wps->ap && !wps->er && wps_build_ap_settings(wps, plain)) ||
01504             wps_build_key_wrap_auth(wps, plain) ||
01505             wps_build_encr_settings(wps, msg, plain) ||
01506             wps_build_authenticator(wps, msg)) {
01507                 wpabuf_free(plain);
01508                 wpabuf_free(msg);
01509                 return NULL;
01510         }
01511         wpabuf_free(plain);
01512 
01513         wps->state = RECV_DONE;
01514         return msg;
01515 }
01516 
01517 
01518 static struct wpabuf * wps_build_wsc_ack(struct wps_data *wps)
01519 {
01520         struct wpabuf *msg;
01521 
01522         wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_ACK");
01523 
01524         msg = wpabuf_alloc(1000);
01525         if (msg == NULL)
01526                 return NULL;
01527 
01528         if (wps_build_version(msg) ||
01529             wps_build_msg_type(msg, WPS_WSC_ACK) ||
01530             wps_build_enrollee_nonce(wps, msg) ||
01531             wps_build_registrar_nonce(wps, msg)) {
01532                 wpabuf_free(msg);
01533                 return NULL;
01534         }
01535 
01536         return msg;
01537 }
01538 
01539 
01540 static struct wpabuf * wps_build_wsc_nack(struct wps_data *wps)
01541 {
01542         struct wpabuf *msg;
01543 
01544         wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_NACK");
01545 
01546         msg = wpabuf_alloc(1000);
01547         if (msg == NULL)
01548                 return NULL;
01549 
01550         if (wps_build_version(msg) ||
01551             wps_build_msg_type(msg, WPS_WSC_NACK) ||
01552             wps_build_enrollee_nonce(wps, msg) ||
01553             wps_build_registrar_nonce(wps, msg) ||
01554             wps_build_config_error(msg, wps->config_error)) {
01555                 wpabuf_free(msg);
01556                 return NULL;
01557         }
01558 
01559         return msg;
01560 }
01561 
01562 
01563 struct wpabuf * wps_registrar_get_msg(struct wps_data *wps,
01564                                       enum wsc_op_code *op_code)
01565 {
01566         struct wpabuf *msg;
01567 
01568 #ifdef CONFIG_WPS_UPNP
01569         if (!wps->int_reg && wps->wps->wps_upnp) {
01570                 struct upnp_pending_message *p, *prev = NULL;
01571                 if (wps->ext_reg > 1)
01572                         wps_registrar_free_pending_m2(wps->wps);
01573                 p = wps->wps->upnp_msgs;
01574                 /* TODO: check pending message MAC address */
01575                 while (p && p->next) {
01576                         prev = p;
01577                         p = p->next;
01578                 }
01579                 if (p) {
01580                         wpa_printf(MSG_DEBUG, "WPS: Use pending message from "
01581                                    "UPnP");
01582                         if (prev)
01583                                 prev->next = NULL;
01584                         else
01585                                 wps->wps->upnp_msgs = NULL;
01586                         msg = p->msg;
01587                         switch (p->type) {
01588                         case WPS_WSC_ACK:
01589                                 *op_code = WSC_ACK;
01590                                 break;
01591                         case WPS_WSC_NACK:
01592                                 *op_code = WSC_NACK;
01593                                 break;
01594                         default:
01595                                 *op_code = WSC_MSG;
01596                                 break;
01597                         }
01598                         os_free(p);
01599                         if (wps->ext_reg == 0)
01600                                 wps->ext_reg = 1;
01601                         return msg;
01602                 }
01603         }
01604         if (wps->ext_reg) {
01605                 wpa_printf(MSG_DEBUG, "WPS: Using external Registrar, but no "
01606                            "pending message available");
01607                 return NULL;
01608         }
01609 #endif /* CONFIG_WPS_UPNP */
01610 
01611         switch (wps->state) {
01612         case SEND_M2:
01613                 if (wps_get_dev_password(wps) < 0)
01614                         msg = wps_build_m2d(wps);
01615                 else
01616                         msg = wps_build_m2(wps);
01617                 *op_code = WSC_MSG;
01618                 break;
01619         case SEND_M2D:
01620                 msg = wps_build_m2d(wps);
01621                 *op_code = WSC_MSG;
01622                 break;
01623         case SEND_M4:
01624                 msg = wps_build_m4(wps);
01625                 *op_code = WSC_MSG;
01626                 break;
01627         case SEND_M6:
01628                 msg = wps_build_m6(wps);
01629                 *op_code = WSC_MSG;
01630                 break;
01631         case SEND_M8:
01632                 msg = wps_build_m8(wps);
01633                 *op_code = WSC_MSG;
01634                 break;
01635         case RECV_DONE:
01636                 msg = wps_build_wsc_ack(wps);
01637                 *op_code = WSC_ACK;
01638                 break;
01639         case SEND_WSC_NACK:
01640                 msg = wps_build_wsc_nack(wps);
01641                 *op_code = WSC_NACK;
01642                 break;
01643         default:
01644                 wpa_printf(MSG_DEBUG, "WPS: Unsupported state %d for building "
01645                            "a message", wps->state);
01646                 msg = NULL;
01647                 break;
01648         }
01649 
01650         if (*op_code == WSC_MSG && msg) {
01651                 /* Save a copy of the last message for Authenticator derivation
01652                  */
01653                 wpabuf_free(wps->last_msg);
01654                 wps->last_msg = wpabuf_dup(msg);
01655         }
01656 
01657         return msg;
01658 }
01659 
01660 
01661 static int wps_process_enrollee_nonce(struct wps_data *wps, const u8 *e_nonce)
01662 {
01663         if (e_nonce == NULL) {
01664                 wpa_printf(MSG_DEBUG, "WPS: No Enrollee Nonce received");
01665                 return -1;
01666         }
01667 
01668         os_memcpy(wps->nonce_e, e_nonce, WPS_NONCE_LEN);
01669         wpa_hexdump(MSG_DEBUG, "WPS: Enrollee Nonce",
01670                     wps->nonce_e, WPS_NONCE_LEN);
01671 
01672         return 0;
01673 }
01674 
01675 
01676 static int wps_process_registrar_nonce(struct wps_data *wps, const u8 *r_nonce)
01677 {
01678         if (r_nonce == NULL) {
01679                 wpa_printf(MSG_DEBUG, "WPS: No Registrar Nonce received");
01680                 return -1;
01681         }
01682 
01683         if (os_memcmp(wps->nonce_r, r_nonce, WPS_NONCE_LEN) != 0) {
01684                 wpa_printf(MSG_DEBUG, "WPS: Invalid Registrar Nonce received");
01685                 return -1;
01686         }
01687 
01688         return 0;
01689 }
01690 
01691 
01692 static int wps_process_uuid_e(struct wps_data *wps, const u8 *uuid_e)
01693 {
01694         if (uuid_e == NULL) {
01695                 wpa_printf(MSG_DEBUG, "WPS: No UUID-E received");
01696                 return -1;
01697         }
01698 
01699         os_memcpy(wps->uuid_e, uuid_e, WPS_UUID_LEN);
01700         wpa_hexdump(MSG_DEBUG, "WPS: UUID-E", wps->uuid_e, WPS_UUID_LEN);
01701 
01702         return 0;
01703 }
01704 
01705 
01706 static int wps_process_dev_password_id(struct wps_data *wps, const u8 *pw_id)
01707 {
01708         if (pw_id == NULL) {
01709                 wpa_printf(MSG_DEBUG, "WPS: No Device Password ID received");
01710                 return -1;
01711         }
01712 
01713         wps->dev_pw_id = WPA_GET_BE16(pw_id);
01714         wpa_printf(MSG_DEBUG, "WPS: Device Password ID %d", wps->dev_pw_id);
01715 
01716         return 0;
01717 }
01718 
01719 
01720 static int wps_process_e_hash1(struct wps_data *wps, const u8 *e_hash1)
01721 {
01722         if (e_hash1 == NULL) {
01723                 wpa_printf(MSG_DEBUG, "WPS: No E-Hash1 received");
01724                 return -1;
01725         }
01726 
01727         os_memcpy(wps->peer_hash1, e_hash1, WPS_HASH_LEN);
01728         wpa_hexdump(MSG_DEBUG, "WPS: E-Hash1", wps->peer_hash1, WPS_HASH_LEN);
01729 
01730         return 0;
01731 }
01732 
01733 
01734 static int wps_process_e_hash2(struct wps_data *wps, const u8 *e_hash2)
01735 {
01736         if (e_hash2 == NULL) {
01737                 wpa_printf(MSG_DEBUG, "WPS: No E-Hash2 received");
01738                 return -1;
01739         }
01740 
01741         os_memcpy(wps->peer_hash2, e_hash2, WPS_HASH_LEN);
01742         wpa_hexdump(MSG_DEBUG, "WPS: E-Hash2", wps->peer_hash2, WPS_HASH_LEN);
01743 
01744         return 0;
01745 }
01746 
01747 
01748 static int wps_process_e_snonce1(struct wps_data *wps, const u8 *e_snonce1)
01749 {
01750         u8 hash[SHA256_MAC_LEN];
01751         const u8 *addr[4];
01752         size_t len[4];
01753 
01754         if (e_snonce1 == NULL) {
01755                 wpa_printf(MSG_DEBUG, "WPS: No E-SNonce1 received");
01756                 return -1;
01757         }
01758 
01759         wpa_hexdump_key(MSG_DEBUG, "WPS: E-SNonce1", e_snonce1,
01760                         WPS_SECRET_NONCE_LEN);
01761 
01762         /* E-Hash1 = HMAC_AuthKey(E-S1 || PSK1 || PK_E || PK_R) */
01763         addr[0] = e_snonce1;
01764         len[0] = WPS_SECRET_NONCE_LEN;
01765         addr[1] = wps->psk1;
01766         len[1] = WPS_PSK_LEN;
01767         addr[2] = wpabuf_head(wps->dh_pubkey_e);
01768         len[2] = wpabuf_len(wps->dh_pubkey_e);
01769         addr[3] = wpabuf_head(wps->dh_pubkey_r);
01770         len[3] = wpabuf_len(wps->dh_pubkey_r);
01771         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
01772 
01773         if (os_memcmp(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) {
01774                 wpa_printf(MSG_DEBUG, "WPS: E-Hash1 derived from E-S1 does "
01775                            "not match with the pre-committed value");
01776                 wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
01777                 wps_pwd_auth_fail_event(wps->wps, 0, 1);
01778                 return -1;
01779         }
01780 
01781         wpa_printf(MSG_DEBUG, "WPS: Enrollee proved knowledge of the first "
01782                    "half of the device password");
01783 
01784         return 0;
01785 }
01786 
01787 
01788 static int wps_process_e_snonce2(struct wps_data *wps, const u8 *e_snonce2)
01789 {
01790         u8 hash[SHA256_MAC_LEN];
01791         const u8 *addr[4];
01792         size_t len[4];
01793 
01794         if (e_snonce2 == NULL) {
01795                 wpa_printf(MSG_DEBUG, "WPS: No E-SNonce2 received");
01796                 return -1;
01797         }
01798 
01799         wpa_hexdump_key(MSG_DEBUG, "WPS: E-SNonce2", e_snonce2,
01800                         WPS_SECRET_NONCE_LEN);
01801 
01802         /* E-Hash2 = HMAC_AuthKey(E-S2 || PSK2 || PK_E || PK_R) */
01803         addr[0] = e_snonce2;
01804         len[0] = WPS_SECRET_NONCE_LEN;
01805         addr[1] = wps->psk2;
01806         len[1] = WPS_PSK_LEN;
01807         addr[2] = wpabuf_head(wps->dh_pubkey_e);
01808         len[2] = wpabuf_len(wps->dh_pubkey_e);
01809         addr[3] = wpabuf_head(wps->dh_pubkey_r);
01810         len[3] = wpabuf_len(wps->dh_pubkey_r);
01811         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
01812 
01813         if (os_memcmp(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) {
01814                 wpa_printf(MSG_DEBUG, "WPS: E-Hash2 derived from E-S2 does "
01815                            "not match with the pre-committed value");
01816                 wps_registrar_invalidate_pin(wps->wps->registrar, wps->uuid_e);
01817                 wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
01818                 wps_pwd_auth_fail_event(wps->wps, 0, 2);
01819                 return -1;
01820         }
01821 
01822         wpa_printf(MSG_DEBUG, "WPS: Enrollee proved knowledge of the second "
01823                    "half of the device password");
01824         wps->wps_pin_revealed = 0;
01825         wps_registrar_unlock_pin(wps->wps->registrar, wps->uuid_e);
01826 
01827         return 0;
01828 }
01829 
01830 
01831 static int wps_process_mac_addr(struct wps_data *wps, const u8 *mac_addr)
01832 {
01833         if (mac_addr == NULL) {
01834                 wpa_printf(MSG_DEBUG, "WPS: No MAC Address received");
01835                 return -1;
01836         }
01837 
01838         wpa_printf(MSG_DEBUG, "WPS: Enrollee MAC Address " MACSTR,
01839                    MAC2STR(mac_addr));
01840         os_memcpy(wps->mac_addr_e, mac_addr, ETH_ALEN);
01841         os_memcpy(wps->peer_dev.mac_addr, mac_addr, ETH_ALEN);
01842 
01843         return 0;
01844 }
01845 
01846 
01847 static int wps_process_pubkey(struct wps_data *wps, const u8 *pk,
01848                               size_t pk_len)
01849 {
01850         if (pk == NULL || pk_len == 0) {
01851                 wpa_printf(MSG_DEBUG, "WPS: No Public Key received");
01852                 return -1;
01853         }
01854 
01855 #ifdef CONFIG_WPS_OOB
01856         if (wps->wps->oob_conf.pubkey_hash != NULL) {
01857                 const u8 *addr[1];
01858                 u8 hash[WPS_HASH_LEN];
01859 
01860                 addr[0] = pk;
01861                 sha256_vector(1, addr, &pk_len, hash);
01862                 if (os_memcmp(hash,
01863                               wpabuf_head(wps->wps->oob_conf.pubkey_hash),
01864                               WPS_OOB_PUBKEY_HASH_LEN) != 0) {
01865                         wpa_printf(MSG_ERROR, "WPS: Public Key hash error");
01866                         return -1;
01867                 }
01868         }
01869 #endif /* CONFIG_WPS_OOB */
01870 
01871         wpabuf_free(wps->dh_pubkey_e);
01872         wps->dh_pubkey_e = wpabuf_alloc_copy(pk, pk_len);
01873         if (wps->dh_pubkey_e == NULL)
01874                 return -1;
01875 
01876         return 0;
01877 }
01878 
01879 
01880 static int wps_process_auth_type_flags(struct wps_data *wps, const u8 *auth)
01881 {
01882         u16 auth_types;
01883 
01884         if (auth == NULL) {
01885                 wpa_printf(MSG_DEBUG, "WPS: No Authentication Type flags "
01886                            "received");
01887                 return -1;
01888         }
01889 
01890         auth_types = WPA_GET_BE16(auth);
01891 
01892         wpa_printf(MSG_DEBUG, "WPS: Enrollee Authentication Type flags 0x%x",
01893                    auth_types);
01894         wps->auth_type = wps->wps->auth_types & auth_types;
01895         if (wps->auth_type == 0) {
01896                 wpa_printf(MSG_DEBUG, "WPS: No match in supported "
01897                            "authentication types (own 0x%x Enrollee 0x%x)",
01898                            wps->wps->auth_types, auth_types);
01899 #ifdef WPS_WORKAROUNDS
01900                 /*
01901                  * Some deployed implementations seem to advertise incorrect
01902                  * information in this attribute. For example, Linksys WRT350N
01903                  * seems to have a byteorder bug that breaks this negotiation.
01904                  * In order to interoperate with existing implementations,
01905                  * assume that the Enrollee supports everything we do.
01906                  */
01907                 wpa_printf(MSG_DEBUG, "WPS: Workaround - assume Enrollee "
01908                            "does not advertise supported authentication types "
01909                            "correctly");
01910                 wps->auth_type = wps->wps->auth_types;
01911 #else /* WPS_WORKAROUNDS */
01912                 return -1;
01913 #endif /* WPS_WORKAROUNDS */
01914         }
01915 
01916         return 0;
01917 }
01918 
01919 
01920 static int wps_process_encr_type_flags(struct wps_data *wps, const u8 *encr)
01921 {
01922         u16 encr_types;
01923 
01924         if (encr == NULL) {
01925                 wpa_printf(MSG_DEBUG, "WPS: No Encryption Type flags "
01926                            "received");
01927                 return -1;
01928         }
01929 
01930         encr_types = WPA_GET_BE16(encr);
01931 
01932         wpa_printf(MSG_DEBUG, "WPS: Enrollee Encryption Type flags 0x%x",
01933                    encr_types);
01934         wps->encr_type = wps->wps->encr_types & encr_types;
01935         if (wps->encr_type == 0) {
01936                 wpa_printf(MSG_DEBUG, "WPS: No match in supported "
01937                            "encryption types (own 0x%x Enrollee 0x%x)",
01938                            wps->wps->encr_types, encr_types);
01939 #ifdef WPS_WORKAROUNDS
01940                 /*
01941                  * Some deployed implementations seem to advertise incorrect
01942                  * information in this attribute. For example, Linksys WRT350N
01943                  * seems to have a byteorder bug that breaks this negotiation.
01944                  * In order to interoperate with existing implementations,
01945                  * assume that the Enrollee supports everything we do.
01946                  */
01947                 wpa_printf(MSG_DEBUG, "WPS: Workaround - assume Enrollee "
01948                            "does not advertise supported encryption types "
01949                            "correctly");
01950                 wps->encr_type = wps->wps->encr_types;
01951 #else /* WPS_WORKAROUNDS */
01952                 return -1;
01953 #endif /* WPS_WORKAROUNDS */
01954         }
01955 
01956         return 0;
01957 }
01958 
01959 
01960 static int wps_process_conn_type_flags(struct wps_data *wps, const u8 *conn)
01961 {
01962         if (conn == NULL) {
01963                 wpa_printf(MSG_DEBUG, "WPS: No Connection Type flags "
01964                            "received");
01965                 return -1;
01966         }
01967 
01968         wpa_printf(MSG_DEBUG, "WPS: Enrollee Connection Type flags 0x%x",
01969                    *conn);
01970 
01971         return 0;
01972 }
01973 
01974 
01975 static int wps_process_config_methods(struct wps_data *wps, const u8 *methods)
01976 {
01977         u16 m;
01978 
01979         if (methods == NULL) {
01980                 wpa_printf(MSG_DEBUG, "WPS: No Config Methods received");
01981                 return -1;
01982         }
01983 
01984         m = WPA_GET_BE16(methods);
01985 
01986         wpa_printf(MSG_DEBUG, "WPS: Enrollee Config Methods 0x%x"
01987                    "%s%s%s%s%s%s%s%s%s", m,
01988                    m & WPS_CONFIG_USBA ? " [USBA]" : "",
01989                    m & WPS_CONFIG_ETHERNET ? " [Ethernet]" : "",
01990                    m & WPS_CONFIG_LABEL ? " [Label]" : "",
01991                    m & WPS_CONFIG_DISPLAY ? " [Display]" : "",
01992                    m & WPS_CONFIG_EXT_NFC_TOKEN ? " [Ext NFC Token]" : "",
01993                    m & WPS_CONFIG_INT_NFC_TOKEN ? " [Int NFC Token]" : "",
01994                    m & WPS_CONFIG_NFC_INTERFACE ? " [NFC]" : "",
01995                    m & WPS_CONFIG_PUSHBUTTON ? " [PBC]" : "",
01996                    m & WPS_CONFIG_KEYPAD ? " [Keypad]" : "");
01997 
01998         if (!(m & WPS_CONFIG_DISPLAY) && !wps->use_psk_key) {
01999                 /*
02000                  * The Enrollee does not have a display so it is unlikely to be
02001                  * able to show the passphrase to a user and as such, could
02002                  * benefit from receiving PSK to reduce key derivation time.
02003                  */
02004                 wpa_printf(MSG_DEBUG, "WPS: Prefer PSK format key due to "
02005                            "Enrollee not supporting display");
02006                 wps->use_psk_key = 1;
02007         }
02008 
02009         return 0;
02010 }
02011 
02012 
02013 static int wps_process_wps_state(struct wps_data *wps, const u8 *state)
02014 {
02015         if (state == NULL) {
02016                 wpa_printf(MSG_DEBUG, "WPS: No Wi-Fi Protected Setup State "
02017                            "received");
02018                 return -1;
02019         }
02020 
02021         wpa_printf(MSG_DEBUG, "WPS: Enrollee Wi-Fi Protected Setup State %d",
02022                    *state);
02023 
02024         return 0;
02025 }
02026 
02027 
02028 static int wps_process_assoc_state(struct wps_data *wps, const u8 *assoc)
02029 {
02030         u16 a;
02031 
02032         if (assoc == NULL) {
02033                 wpa_printf(MSG_DEBUG, "WPS: No Association State received");
02034                 return -1;
02035         }
02036 
02037         a = WPA_GET_BE16(assoc);
02038         wpa_printf(MSG_DEBUG, "WPS: Enrollee Association State %d", a);
02039 
02040         return 0;
02041 }
02042 
02043 
02044 static int wps_process_config_error(struct wps_data *wps, const u8 *err)
02045 {
02046         u16 e;
02047 
02048         if (err == NULL) {
02049                 wpa_printf(MSG_DEBUG, "WPS: No Configuration Error received");
02050                 return -1;
02051         }
02052 
02053         e = WPA_GET_BE16(err);
02054         wpa_printf(MSG_DEBUG, "WPS: Enrollee Configuration Error %d", e);
02055 
02056         return 0;
02057 }
02058 
02059 
02060 static enum wps_process_res wps_process_m1(struct wps_data *wps,
02061                                            struct wps_parse_attr *attr)
02062 {
02063         wpa_printf(MSG_DEBUG, "WPS: Received M1");
02064 
02065         if (wps->state != RECV_M1) {
02066                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
02067                            "receiving M1", wps->state);
02068                 return WPS_FAILURE;
02069         }
02070 
02071         if (wps_process_uuid_e(wps, attr->uuid_e) ||
02072             wps_process_mac_addr(wps, attr->mac_addr) ||
02073             wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
02074             wps_process_pubkey(wps, attr->public_key, attr->public_key_len) ||
02075             wps_process_auth_type_flags(wps, attr->auth_type_flags) ||
02076             wps_process_encr_type_flags(wps, attr->encr_type_flags) ||
02077             wps_process_conn_type_flags(wps, attr->conn_type_flags) ||
02078             wps_process_config_methods(wps, attr->config_methods) ||
02079             wps_process_wps_state(wps, attr->wps_state) ||
02080             wps_process_device_attrs(&wps->peer_dev, attr) ||
02081             wps_process_rf_bands(&wps->peer_dev, attr->rf_bands) ||
02082             wps_process_assoc_state(wps, attr->assoc_state) ||
02083             wps_process_dev_password_id(wps, attr->dev_password_id) ||
02084             wps_process_config_error(wps, attr->config_error) ||
02085             wps_process_os_version(&wps->peer_dev, attr->os_version))
02086                 return WPS_FAILURE;
02087 
02088         if (wps->dev_pw_id < 0x10 &&
02089             wps->dev_pw_id != DEV_PW_DEFAULT &&
02090             wps->dev_pw_id != DEV_PW_USER_SPECIFIED &&
02091             wps->dev_pw_id != DEV_PW_MACHINE_SPECIFIED &&
02092             wps->dev_pw_id != DEV_PW_REGISTRAR_SPECIFIED &&
02093             (wps->dev_pw_id != DEV_PW_PUSHBUTTON ||
02094              !wps->wps->registrar->pbc)) {
02095                 wpa_printf(MSG_DEBUG, "WPS: Unsupported Device Password ID %d",
02096                            wps->dev_pw_id);
02097                 wps->state = SEND_M2D;
02098                 return WPS_CONTINUE;
02099         }
02100 
02101 #ifdef CONFIG_WPS_OOB
02102         if (wps->dev_pw_id >= 0x10 &&
02103             wps->dev_pw_id != wps->wps->oob_dev_pw_id) {
02104                 wpa_printf(MSG_DEBUG, "WPS: OOB Device Password ID "
02105                            "%d mismatch", wps->dev_pw_id);
02106                 wps->state = SEND_M2D;
02107                 return WPS_CONTINUE;
02108         }
02109 #endif /* CONFIG_WPS_OOB */
02110 
02111         if (wps->dev_pw_id == DEV_PW_PUSHBUTTON) {
02112                 if (wps->wps->registrar->force_pbc_overlap ||
02113                     wps_registrar_pbc_overlap(wps->wps->registrar,
02114                                               wps->mac_addr_e, wps->uuid_e)) {
02115                         wpa_printf(MSG_DEBUG, "WPS: PBC overlap - deny PBC "
02116                                    "negotiation");
02117                         wps->state = SEND_M2D;
02118                         wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
02119                         wps_pbc_overlap_event(wps->wps);
02120                         wps->wps->registrar->force_pbc_overlap = 1;
02121                         return WPS_CONTINUE;
02122                 }
02123                 wps_registrar_add_pbc_session(wps->wps->registrar,
02124                                               wps->mac_addr_e, wps->uuid_e);
02125                 wps->pbc = 1;
02126         }
02127 
02128         wps->state = SEND_M2;
02129         return WPS_CONTINUE;
02130 }
02131 
02132 
02133 static enum wps_process_res wps_process_m3(struct wps_data *wps,
02134                                            const struct wpabuf *msg,
02135                                            struct wps_parse_attr *attr)
02136 {
02137         wpa_printf(MSG_DEBUG, "WPS: Received M3");
02138 
02139         if (wps->state != RECV_M3) {
02140                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
02141                            "receiving M3", wps->state);
02142                 wps->state = SEND_WSC_NACK;
02143                 return WPS_CONTINUE;
02144         }
02145 
02146         if (wps->pbc && wps->wps->registrar->force_pbc_overlap) {
02147                 wpa_printf(MSG_DEBUG, "WPS: Reject negotiation due to PBC "
02148                            "session overlap");
02149                 wps->state = SEND_WSC_NACK;
02150                 wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
02151                 return WPS_CONTINUE;
02152         }
02153 
02154         if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
02155             wps_process_authenticator(wps, attr->authenticator, msg) ||
02156             wps_process_e_hash1(wps, attr->e_hash1) ||
02157             wps_process_e_hash2(wps, attr->e_hash2)) {
02158                 wps->state = SEND_WSC_NACK;
02159                 return WPS_CONTINUE;
02160         }
02161 
02162         wps->state = SEND_M4;
02163         return WPS_CONTINUE;
02164 }
02165 
02166 
02167 static enum wps_process_res wps_process_m5(struct wps_data *wps,
02168                                            const struct wpabuf *msg,
02169                                            struct wps_parse_attr *attr)
02170 {
02171         struct wpabuf *decrypted;
02172         struct wps_parse_attr eattr;
02173 
02174         wpa_printf(MSG_DEBUG, "WPS: Received M5");
02175 
02176         if (wps->state != RECV_M5) {
02177                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
02178                            "receiving M5", wps->state);
02179                 wps->state = SEND_WSC_NACK;
02180                 return WPS_CONTINUE;
02181         }
02182 
02183         if (wps->pbc && wps->wps->registrar->force_pbc_overlap) {
02184                 wpa_printf(MSG_DEBUG, "WPS: Reject negotiation due to PBC "
02185                            "session overlap");
02186                 wps->state = SEND_WSC_NACK;
02187                 wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
02188                 return WPS_CONTINUE;
02189         }
02190 
02191         if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
02192             wps_process_authenticator(wps, attr->authenticator, msg)) {
02193                 wps->state = SEND_WSC_NACK;
02194                 return WPS_CONTINUE;
02195         }
02196 
02197         decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
02198                                               attr->encr_settings_len);
02199         if (decrypted == NULL) {
02200                 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
02201                            "Settings attribute");
02202                 wps->state = SEND_WSC_NACK;
02203                 return WPS_CONTINUE;
02204         }
02205 
02206         wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
02207                    "attribute");
02208         if (wps_parse_msg(decrypted, &eattr) < 0 ||
02209             wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
02210             wps_process_e_snonce1(wps, eattr.e_snonce1)) {
02211                 wpabuf_free(decrypted);
02212                 wps->state = SEND_WSC_NACK;
02213                 return WPS_CONTINUE;
02214         }
02215         wpabuf_free(decrypted);
02216 
02217         wps->state = SEND_M6;
02218         return WPS_CONTINUE;
02219 }
02220 
02221 
02222 static void wps_sta_cred_cb(struct wps_data *wps)
02223 {
02224         /*
02225          * Update credential to only include a single authentication and
02226          * encryption type in case the AP configuration includes more than one
02227          * option.
02228          */
02229         if (wps->cred.auth_type & WPS_AUTH_WPA2PSK)
02230                 wps->cred.auth_type = WPS_AUTH_WPA2PSK;
02231         else if (wps->cred.auth_type & WPS_AUTH_WPAPSK)
02232                 wps->cred.auth_type = WPS_AUTH_WPAPSK;
02233         if (wps->cred.encr_type & WPS_ENCR_AES)
02234                 wps->cred.encr_type = WPS_ENCR_AES;
02235         else if (wps->cred.encr_type & WPS_ENCR_TKIP)
02236                 wps->cred.encr_type = WPS_ENCR_TKIP;
02237         wpa_printf(MSG_DEBUG, "WPS: Update local configuration based on the "
02238                    "AP configuration");
02239         if (wps->wps->cred_cb)
02240                 wps->wps->cred_cb(wps->wps->cb_ctx, &wps->cred);
02241 }
02242 
02243 
02244 static void wps_cred_update(struct wps_credential *dst,
02245                             struct wps_credential *src)
02246 {
02247         os_memcpy(dst->ssid, src->ssid, sizeof(dst->ssid));
02248         dst->ssid_len = src->ssid_len;
02249         dst->auth_type = src->auth_type;
02250         dst->encr_type = src->encr_type;
02251         dst->key_idx = src->key_idx;
02252         os_memcpy(dst->key, src->key, sizeof(dst->key));
02253         dst->key_len = src->key_len;
02254 }
02255 
02256 
02257 static int wps_process_ap_settings_r(struct wps_data *wps,
02258                                      struct wps_parse_attr *attr)
02259 {
02260         if (wps->wps->ap || wps->er)
02261                 return 0;
02262 
02263         /* AP Settings Attributes in M7 when Enrollee is an AP */
02264         if (wps_process_ap_settings(attr, &wps->cred) < 0)
02265                 return -1;
02266 
02267         wpa_printf(MSG_INFO, "WPS: Received old AP configuration from AP");
02268 
02269         if (wps->new_ap_settings) {
02270                 wpa_printf(MSG_INFO, "WPS: Update AP configuration based on "
02271                            "new settings");
02272                 wps_cred_update(&wps->cred, wps->new_ap_settings);
02273                 return 0;
02274         } else {
02275                 /*
02276                  * Use the AP PIN only to receive the current AP settings, not
02277                  * to reconfigure the AP.
02278                  */
02279                 if (wps->ap_settings_cb) {
02280                         wps->ap_settings_cb(wps->ap_settings_cb_ctx,
02281                                             &wps->cred);
02282                         return 1;
02283                 }
02284                 wps_sta_cred_cb(wps);
02285                 return 1;
02286         }
02287 }
02288 
02289 
02290 static enum wps_process_res wps_process_m7(struct wps_data *wps,
02291                                            const struct wpabuf *msg,
02292                                            struct wps_parse_attr *attr)
02293 {
02294         struct wpabuf *decrypted;
02295         struct wps_parse_attr eattr;
02296 
02297         wpa_printf(MSG_DEBUG, "WPS: Received M7");
02298 
02299         if (wps->state != RECV_M7) {
02300                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
02301                            "receiving M7", wps->state);
02302                 wps->state = SEND_WSC_NACK;
02303                 return WPS_CONTINUE;
02304         }
02305 
02306         if (wps->pbc && wps->wps->registrar->force_pbc_overlap) {
02307                 wpa_printf(MSG_DEBUG, "WPS: Reject negotiation due to PBC "
02308                            "session overlap");
02309                 wps->state = SEND_WSC_NACK;
02310                 wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
02311                 return WPS_CONTINUE;
02312         }
02313 
02314         if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
02315             wps_process_authenticator(wps, attr->authenticator, msg)) {
02316                 wps->state = SEND_WSC_NACK;
02317                 return WPS_CONTINUE;
02318         }
02319 
02320         decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
02321                                               attr->encr_settings_len);
02322         if (decrypted == NULL) {
02323                 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypt Encrypted "
02324                            "Settings attribute");
02325                 wps->state = SEND_WSC_NACK;
02326                 return WPS_CONTINUE;
02327         }
02328 
02329         wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
02330                    "attribute");
02331         if (wps_parse_msg(decrypted, &eattr) < 0 ||
02332             wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
02333             wps_process_e_snonce2(wps, eattr.e_snonce2) ||
02334             wps_process_ap_settings_r(wps, &eattr)) {
02335                 wpabuf_free(decrypted);
02336                 wps->state = SEND_WSC_NACK;
02337                 return WPS_CONTINUE;
02338         }
02339 
02340         wpabuf_free(decrypted);
02341 
02342         wps->state = SEND_M8;
02343         return WPS_CONTINUE;
02344 }
02345 
02346 
02347 static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
02348                                                 const struct wpabuf *msg)
02349 {
02350         struct wps_parse_attr attr;
02351         enum wps_process_res ret = WPS_CONTINUE;
02352 
02353         wpa_printf(MSG_DEBUG, "WPS: Received WSC_MSG");
02354 
02355         if (wps_parse_msg(msg, &attr) < 0)
02356                 return WPS_FAILURE;
02357 
02358         if (!wps_version_supported(attr.version)) {
02359                 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
02360                            attr.version ? *attr.version : 0);
02361                 return WPS_FAILURE;
02362         }
02363 
02364         if (attr.msg_type == NULL) {
02365                 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
02366                 return WPS_FAILURE;
02367         }
02368 
02369         if (*attr.msg_type != WPS_M1 &&
02370             (attr.registrar_nonce == NULL ||
02371              os_memcmp(wps->nonce_r, attr.registrar_nonce,
02372                        WPS_NONCE_LEN != 0))) {
02373                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
02374                 return WPS_FAILURE;
02375         }
02376 
02377         switch (*attr.msg_type) {
02378         case WPS_M1:
02379 #ifdef CONFIG_WPS_UPNP
02380                 if (wps->wps->wps_upnp && attr.mac_addr) {
02381                         /* Remove old pending messages when starting new run */
02382                         wps_free_pending_msgs(wps->wps->upnp_msgs);
02383                         wps->wps->upnp_msgs = NULL;
02384 
02385                         upnp_wps_device_send_wlan_event(
02386                                 wps->wps->wps_upnp, attr.mac_addr,
02387                                 UPNP_WPS_WLANEVENT_TYPE_EAP, msg);
02388                 }
02389 #endif /* CONFIG_WPS_UPNP */
02390                 ret = wps_process_m1(wps, &attr);
02391                 break;
02392         case WPS_M3:
02393                 ret = wps_process_m3(wps, msg, &attr);
02394                 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
02395                         wps_fail_event(wps->wps, WPS_M3);
02396                 break;
02397         case WPS_M5:
02398                 ret = wps_process_m5(wps, msg, &attr);
02399                 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
02400                         wps_fail_event(wps->wps, WPS_M5);
02401                 break;
02402         case WPS_M7:
02403                 ret = wps_process_m7(wps, msg, &attr);
02404                 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
02405                         wps_fail_event(wps->wps, WPS_M7);
02406                 break;
02407         default:
02408                 wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d",
02409                            *attr.msg_type);
02410                 return WPS_FAILURE;
02411         }
02412 
02413         if (ret == WPS_CONTINUE) {
02414                 /* Save a copy of the last message for Authenticator derivation
02415                  */
02416                 wpabuf_free(wps->last_msg);
02417                 wps->last_msg = wpabuf_dup(msg);
02418         }
02419 
02420         return ret;
02421 }
02422 
02423 
02424 static enum wps_process_res wps_process_wsc_ack(struct wps_data *wps,
02425                                                 const struct wpabuf *msg)
02426 {
02427         struct wps_parse_attr attr;
02428 
02429         wpa_printf(MSG_DEBUG, "WPS: Received WSC_ACK");
02430 
02431         if (wps_parse_msg(msg, &attr) < 0)
02432                 return WPS_FAILURE;
02433 
02434         if (!wps_version_supported(attr.version)) {
02435                 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
02436                            attr.version ? *attr.version : 0);
02437                 return WPS_FAILURE;
02438         }
02439 
02440         if (attr.msg_type == NULL) {
02441                 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
02442                 return WPS_FAILURE;
02443         }
02444 
02445         if (*attr.msg_type != WPS_WSC_ACK) {
02446                 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
02447                            *attr.msg_type);
02448                 return WPS_FAILURE;
02449         }
02450 
02451 #ifdef CONFIG_WPS_UPNP
02452         if (wps->wps->wps_upnp && wps->ext_reg && wps->state == RECV_M2D_ACK &&
02453             upnp_wps_subscribers(wps->wps->wps_upnp)) {
02454                 if (wps->wps->upnp_msgs)
02455                         return WPS_CONTINUE;
02456                 wpa_printf(MSG_DEBUG, "WPS: Wait for response from an "
02457                            "external Registrar");
02458                 return WPS_PENDING;
02459         }
02460 #endif /* CONFIG_WPS_UPNP */
02461 
02462         if (attr.registrar_nonce == NULL ||
02463             os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
02464         {
02465                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
02466                 return WPS_FAILURE;
02467         }
02468 
02469         if (attr.enrollee_nonce == NULL ||
02470             os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
02471                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
02472                 return WPS_FAILURE;
02473         }
02474 
02475         if (wps->state == RECV_M2D_ACK) {
02476 #ifdef CONFIG_WPS_UPNP
02477                 if (wps->wps->wps_upnp &&
02478                     upnp_wps_subscribers(wps->wps->wps_upnp)) {
02479                         if (wps->wps->upnp_msgs)
02480                                 return WPS_CONTINUE;
02481                         if (wps->ext_reg == 0)
02482                                 wps->ext_reg = 1;
02483                         wpa_printf(MSG_DEBUG, "WPS: Wait for response from an "
02484                                    "external Registrar");
02485                         return WPS_PENDING;
02486                 }
02487 #endif /* CONFIG_WPS_UPNP */
02488 
02489                 wpa_printf(MSG_DEBUG, "WPS: No more registrars available - "
02490                            "terminate negotiation");
02491         }
02492 
02493         return WPS_FAILURE;
02494 }
02495 
02496 
02497 static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps,
02498                                                  const struct wpabuf *msg)
02499 {
02500         struct wps_parse_attr attr;
02501         int old_state;
02502 
02503         wpa_printf(MSG_DEBUG, "WPS: Received WSC_NACK");
02504 
02505         old_state = wps->state;
02506         wps->state = SEND_WSC_NACK;
02507 
02508         if (wps_parse_msg(msg, &attr) < 0)
02509                 return WPS_FAILURE;
02510 
02511         if (!wps_version_supported(attr.version)) {
02512                 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
02513                            attr.version ? *attr.version : 0);
02514                 return WPS_FAILURE;
02515         }
02516 
02517         if (attr.msg_type == NULL) {
02518                 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
02519                 return WPS_FAILURE;
02520         }
02521 
02522         if (*attr.msg_type != WPS_WSC_NACK) {
02523                 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
02524                            *attr.msg_type);
02525                 return WPS_FAILURE;
02526         }
02527 
02528 #ifdef CONFIG_WPS_UPNP
02529         if (wps->wps->wps_upnp && wps->ext_reg) {
02530                 wpa_printf(MSG_DEBUG, "WPS: Negotiation using external "
02531                            "Registrar terminated by the Enrollee");
02532                 return WPS_FAILURE;
02533         }
02534 #endif /* CONFIG_WPS_UPNP */
02535 
02536         if (attr.registrar_nonce == NULL ||
02537             os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
02538         {
02539                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
02540                 return WPS_FAILURE;
02541         }
02542 
02543         if (attr.enrollee_nonce == NULL ||
02544             os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
02545                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
02546                 return WPS_FAILURE;
02547         }
02548 
02549         if (attr.config_error == NULL) {
02550                 wpa_printf(MSG_DEBUG, "WPS: No Configuration Error attribute "
02551                            "in WSC_NACK");
02552                 return WPS_FAILURE;
02553         }
02554 
02555         wpa_printf(MSG_DEBUG, "WPS: Enrollee terminated negotiation with "
02556                    "Configuration Error %d", WPA_GET_BE16(attr.config_error));
02557 
02558         switch (old_state) {
02559         case RECV_M3:
02560                 wps_fail_event(wps->wps, WPS_M2);
02561                 break;
02562         case RECV_M5:
02563                 wps_fail_event(wps->wps, WPS_M4);
02564                 break;
02565         case RECV_M7:
02566                 wps_fail_event(wps->wps, WPS_M6);
02567                 break;
02568         case RECV_DONE:
02569                 wps_fail_event(wps->wps, WPS_M8);
02570                 break;
02571         default:
02572                 break;
02573         }
02574 
02575         return WPS_FAILURE;
02576 }
02577 
02578 
02579 static enum wps_process_res wps_process_wsc_done(struct wps_data *wps,
02580                                                  const struct wpabuf *msg)
02581 {
02582         struct wps_parse_attr attr;
02583 
02584         wpa_printf(MSG_DEBUG, "WPS: Received WSC_Done");
02585 
02586         if (wps->state != RECV_DONE &&
02587             (!wps->wps->wps_upnp || !wps->ext_reg)) {
02588                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
02589                            "receiving WSC_Done", wps->state);
02590                 return WPS_FAILURE;
02591         }
02592 
02593         if (wps_parse_msg(msg, &attr) < 0)
02594                 return WPS_FAILURE;
02595 
02596         if (!wps_version_supported(attr.version)) {
02597                 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
02598                            attr.version ? *attr.version : 0);
02599                 return WPS_FAILURE;
02600         }
02601 
02602         if (attr.msg_type == NULL) {
02603                 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
02604                 return WPS_FAILURE;
02605         }
02606 
02607         if (*attr.msg_type != WPS_WSC_DONE) {
02608                 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
02609                            *attr.msg_type);
02610                 return WPS_FAILURE;
02611         }
02612 
02613 #ifdef CONFIG_WPS_UPNP
02614         if (wps->wps->wps_upnp && wps->ext_reg) {
02615                 wpa_printf(MSG_DEBUG, "WPS: Negotiation using external "
02616                            "Registrar completed successfully");
02617                 wps_device_store(wps->wps->registrar, &wps->peer_dev,
02618                                  wps->uuid_e);
02619                 return WPS_DONE;
02620         }
02621 #endif /* CONFIG_WPS_UPNP */
02622 
02623         if (attr.registrar_nonce == NULL ||
02624             os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
02625         {
02626                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
02627                 return WPS_FAILURE;
02628         }
02629 
02630         if (attr.enrollee_nonce == NULL ||
02631             os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
02632                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
02633                 return WPS_FAILURE;
02634         }
02635 
02636         wpa_printf(MSG_DEBUG, "WPS: Negotiation completed successfully");
02637         wps_device_store(wps->wps->registrar, &wps->peer_dev,
02638                          wps->uuid_e);
02639 
02640         if (wps->wps->wps_state == WPS_STATE_NOT_CONFIGURED && wps->new_psk &&
02641             wps->wps->ap && !wps->wps->registrar->disable_auto_conf) {
02642                 struct wps_credential cred;
02643 
02644                 wpa_printf(MSG_DEBUG, "WPS: Moving to Configured state based "
02645                            "on first Enrollee connection");
02646 
02647                 os_memset(&cred, 0, sizeof(cred));
02648                 os_memcpy(cred.ssid, wps->wps->ssid, wps->wps->ssid_len);
02649                 cred.ssid_len = wps->wps->ssid_len;
02650                 cred.auth_type = WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK;
02651                 cred.encr_type = WPS_ENCR_TKIP | WPS_ENCR_AES;
02652                 os_memcpy(cred.key, wps->new_psk, wps->new_psk_len);
02653                 cred.key_len = wps->new_psk_len;
02654 
02655                 wps->wps->wps_state = WPS_STATE_CONFIGURED;
02656                 wpa_hexdump_ascii_key(MSG_DEBUG,
02657                                       "WPS: Generated random passphrase",
02658                                       wps->new_psk, wps->new_psk_len);
02659                 if (wps->wps->cred_cb)
02660                         wps->wps->cred_cb(wps->wps->cb_ctx, &cred);
02661 
02662                 os_free(wps->new_psk);
02663                 wps->new_psk = NULL;
02664         }
02665 
02666         if (!wps->wps->ap && !wps->er)
02667                 wps_sta_cred_cb(wps);
02668 
02669         if (wps->new_psk) {
02670                 if (wps_cb_new_psk(wps->wps->registrar, wps->mac_addr_e,
02671                                    wps->new_psk, wps->new_psk_len)) {
02672                         wpa_printf(MSG_DEBUG, "WPS: Failed to configure the "
02673                                    "new PSK");
02674                 }
02675                 os_free(wps->new_psk);
02676                 wps->new_psk = NULL;
02677         }
02678 
02679         wps_cb_reg_success(wps->wps->registrar, wps->mac_addr_e, wps->uuid_e);
02680 
02681         if (wps->pbc) {
02682                 wps_registrar_remove_pbc_session(wps->wps->registrar,
02683                                                  wps->mac_addr_e, wps->uuid_e);
02684                 wps_registrar_pbc_completed(wps->wps->registrar);
02685         } else {
02686                 wps_registrar_pin_completed(wps->wps->registrar);
02687         }
02688 
02689         wps_success_event(wps->wps);
02690 
02691         return WPS_DONE;
02692 }
02693 
02694 
02695 enum wps_process_res wps_registrar_process_msg(struct wps_data *wps,
02696                                                enum wsc_op_code op_code,
02697                                                const struct wpabuf *msg)
02698 {
02699         enum wps_process_res ret;
02700 
02701         wpa_printf(MSG_DEBUG, "WPS: Processing received message (len=%lu "
02702                    "op_code=%d)",
02703                    (unsigned long) wpabuf_len(msg), op_code);
02704 
02705 #ifdef CONFIG_WPS_UPNP
02706         if (wps->wps->wps_upnp && op_code == WSC_MSG && wps->ext_reg == 1) {
02707                 struct wps_parse_attr attr;
02708                 if (wps_parse_msg(msg, &attr) == 0 && attr.msg_type &&
02709                     *attr.msg_type == WPS_M3)
02710                         wps->ext_reg = 2; /* past M2/M2D phase */
02711         }
02712         if (wps->ext_reg > 1)
02713                 wps_registrar_free_pending_m2(wps->wps);
02714         if (wps->wps->wps_upnp && wps->ext_reg &&
02715             wps->wps->upnp_msgs == NULL &&
02716             (op_code == WSC_MSG || op_code == WSC_Done || op_code == WSC_NACK))
02717         {
02718                 struct wps_parse_attr attr;
02719                 int type;
02720                 if (wps_parse_msg(msg, &attr) < 0 || attr.msg_type == NULL)
02721                         type = -1;
02722                 else
02723                         type = *attr.msg_type;
02724                 wpa_printf(MSG_DEBUG, "WPS: Sending received message (type %d)"
02725                            " to external Registrar for processing", type);
02726                 upnp_wps_device_send_wlan_event(wps->wps->wps_upnp,
02727                                                 wps->mac_addr_e,
02728                                                 UPNP_WPS_WLANEVENT_TYPE_EAP,
02729                                                 msg);
02730                 if (op_code == WSC_MSG)
02731                         return WPS_PENDING;
02732         } else if (wps->wps->wps_upnp && wps->ext_reg && op_code == WSC_MSG) {
02733                 wpa_printf(MSG_DEBUG, "WPS: Skip internal processing - using "
02734                            "external Registrar");
02735                 return WPS_CONTINUE;
02736         }
02737 #endif /* CONFIG_WPS_UPNP */
02738 
02739         switch (op_code) {
02740         case WSC_MSG:
02741                 return wps_process_wsc_msg(wps, msg);
02742         case WSC_ACK:
02743                 return wps_process_wsc_ack(wps, msg);
02744         case WSC_NACK:
02745                 return wps_process_wsc_nack(wps, msg);
02746         case WSC_Done:
02747                 ret = wps_process_wsc_done(wps, msg);
02748                 if (ret == WPS_FAILURE) {
02749                         wps->state = SEND_WSC_NACK;
02750                         wps_fail_event(wps->wps, WPS_WSC_DONE);
02751                 }
02752                 return ret;
02753         default:
02754                 wpa_printf(MSG_DEBUG, "WPS: Unsupported op_code %d", op_code);
02755                 return WPS_FAILURE;
02756         }
02757 }
02758 
02759 
02760 int wps_registrar_update_ie(struct wps_registrar *reg)
02761 {
02762         return wps_set_ie(reg);
02763 }
02764 
02765 
02766 static void wps_registrar_set_selected_timeout(void *eloop_ctx,
02767                                                void *timeout_ctx)
02768 {
02769         struct wps_registrar *reg = eloop_ctx;
02770 
02771         wpa_printf(MSG_DEBUG, "WPS: Selected Registrar timeout - "
02772                    "unselect internal Registrar");
02773         reg->selected_registrar = 0;
02774         reg->pbc = 0;
02775         wps_registrar_selected_registrar_changed(reg);
02776 }
02777 
02778 
02779 #ifdef CONFIG_WPS_UPNP
02780 static void wps_registrar_sel_reg_add(struct wps_registrar *reg,
02781                                       struct subscription *s)
02782 {
02783         wpa_printf(MSG_DEBUG, "WPS: External Registrar selected (dev_pw_id=%d "
02784                    "config_methods=0x%x)",
02785                    s->dev_password_id, s->config_methods);
02786         reg->sel_reg_union = 1;
02787         if (reg->sel_reg_dev_password_id_override != DEV_PW_PUSHBUTTON)
02788                 reg->sel_reg_dev_password_id_override = s->dev_password_id;
02789         if (reg->sel_reg_config_methods_override == -1)
02790                 reg->sel_reg_config_methods_override = 0;
02791         reg->sel_reg_config_methods_override |= s->config_methods;
02792 }
02793 #endif /* CONFIG_WPS_UPNP */
02794 
02795 
02796 static void wps_registrar_sel_reg_union(struct wps_registrar *reg)
02797 {
02798 #ifdef CONFIG_WPS_UPNP
02799         struct subscription *s;
02800 
02801         if (reg->wps->wps_upnp == NULL)
02802                 return;
02803 
02804         dl_list_for_each(s, &reg->wps->wps_upnp->subscriptions,
02805                          struct subscription, list) {
02806                 struct subscr_addr *sa;
02807                 sa = dl_list_first(&s->addr_list, struct subscr_addr, list);
02808                 if (sa) {
02809                         wpa_printf(MSG_DEBUG, "WPS: External Registrar %s:%d",
02810                                    inet_ntoa(sa->saddr.sin_addr),
02811                                    ntohs(sa->saddr.sin_port));
02812                 }
02813                 if (s->selected_registrar)
02814                         wps_registrar_sel_reg_add(reg, s);
02815                 else
02816                         wpa_printf(MSG_DEBUG, "WPS: External Registrar not "
02817                                    "selected");
02818         }
02819 #endif /* CONFIG_WPS_UPNP */
02820 }
02821 
02822 
02830 void wps_registrar_selected_registrar_changed(struct wps_registrar *reg)
02831 {
02832         wpa_printf(MSG_DEBUG, "WPS: Selected registrar information changed");
02833 
02834         reg->sel_reg_union = reg->selected_registrar;
02835         reg->sel_reg_dev_password_id_override = -1;
02836         reg->sel_reg_config_methods_override = -1;
02837         if (reg->selected_registrar) {
02838                 reg->sel_reg_config_methods_override =
02839                         reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;
02840                 if (reg->pbc) {
02841                         reg->sel_reg_dev_password_id_override =
02842                                 DEV_PW_PUSHBUTTON;
02843                         reg->sel_reg_config_methods_override |=
02844                                 WPS_CONFIG_PUSHBUTTON;
02845                 }
02846                 wpa_printf(MSG_DEBUG, "WPS: Internal Registrar selected "
02847                            "(pbc=%d)", reg->pbc);
02848         } else
02849                 wpa_printf(MSG_DEBUG, "WPS: Internal Registrar not selected");
02850 
02851         wps_registrar_sel_reg_union(reg);
02852 
02853         wps_set_ie(reg);
02854         wps_cb_set_sel_reg(reg);
02855 }
02856 
02857 
02858 int wps_registrar_get_info(struct wps_registrar *reg, const u8 *addr,
02859                            char *buf, size_t buflen)
02860 {
02861         struct wps_registrar_device *d;
02862         int len = 0, ret;
02863         char uuid[40];
02864         char devtype[WPS_DEV_TYPE_BUFSIZE];
02865 
02866         d = wps_device_get(reg, addr);
02867         if (d == NULL)
02868                 return 0;
02869         if (uuid_bin2str(d->uuid, uuid, sizeof(uuid)))
02870                 return 0;
02871 
02872         ret = os_snprintf(buf + len, buflen - len,
02873                           "wpsUuid=%s\n"
02874                           "wpsPrimaryDeviceType=%s\n"
02875                           "wpsDeviceName=%s\n"
02876                           "wpsManufacturer=%s\n"
02877                           "wpsModelName=%s\n"
02878                           "wpsModelNumber=%s\n"
02879                           "wpsSerialNumber=%s\n",
02880                           uuid,
02881                           wps_dev_type_bin2str(d->dev.pri_dev_type, devtype,
02882                                                sizeof(devtype)),
02883                           d->dev.device_name ? d->dev.device_name : "",
02884                           d->dev.manufacturer ? d->dev.manufacturer : "",
02885                           d->dev.model_name ? d->dev.model_name : "",
02886                           d->dev.model_number ? d->dev.model_number : "",
02887                           d->dev.serial_number ? d->dev.serial_number : "");
02888         if (ret < 0 || (size_t) ret >= buflen - len)
02889                 return len;
02890         len += ret;
02891 
02892         return len;
02893 }


wpa_supplicant
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Jan 2 2014 11:26:39