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