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