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