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