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