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