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