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