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