2a1dc76ac15793931ba489554b0fd29bf38cc661
[librecmc/librecmc.git] /
1 From ad3c6faca118c23cdafef418dc27b3cee7d0e06e Mon Sep 17 00:00:00 2001
2 From: "Arnout Vandecappelle (Essensium/Mind)" <arnout@mind.be>
3 Date: Wed, 9 Jan 2019 19:19:26 +0100
4 Subject: [PATCH] WPS: wps_build_wfa_ext(): add multi_ap_subelem parameter
5
6 The Multi-AP specification adds a new subelement to the WFA extension
7 element in the WPS exchange. Add an additional parameter to
8 wps_build_wfa_ext() to add this subelement. The subelement is only added
9 if the parameter is non-0. Note that we don't reuse the existing
10 MULTI_AP_SUB_ELEM_TYPE definition here, but rather define a new
11 WFA_ELEM_MULTI_AP, to make sure the enum of WFA subelement types remains
12 complete.
13
14 For now, all callers set the multi_ap_subelem parameter to 0.
15
16 Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
17 ---
18 v4: Split off from supplicant WPS patch
19
20 Since the original patch from Davina Lyu didn't have this extra
21 argument, I kept myself as the author of this patch.
22 ---
23  src/p2p/p2p_build.c      |  2 +-
24  src/wps/wps.c            |  6 +++---
25  src/wps/wps_attr_build.c | 11 ++++++++++-
26  src/wps/wps_common.c     | 16 ++++++++--------
27  src/wps/wps_defs.h       |  3 ++-
28  src/wps/wps_enrollee.c   | 10 +++++-----
29  src/wps/wps_er.c         |  4 ++--
30  src/wps/wps_i.h          |  3 ++-
31  src/wps/wps_registrar.c  | 14 +++++++-------
32  src/wps/wps_upnp.c       |  2 +-
33  10 files changed, 41 insertions(+), 30 deletions(-)
34
35 --- a/src/p2p/p2p_build.c
36 +++ b/src/p2p/p2p_build.c
37 @@ -802,7 +802,7 @@ int p2p_build_wps_ie(struct p2p_data *p2
38                 wpabuf_put_be16(buf, p2p->cfg->config_methods);
39         }
40  
41 -       if (wps_build_wfa_ext(buf, 0, NULL, 0) < 0)
42 +       if (wps_build_wfa_ext(buf, 0, NULL, 0, 0) < 0)
43                 return -1;
44  
45         if (all_attr && p2p->cfg->num_sec_dev_types) {
46 --- a/src/wps/wps.c
47 +++ b/src/wps/wps.c
48 @@ -430,7 +430,7 @@ struct wpabuf * wps_build_assoc_req_ie(e
49  
50         if (wps_build_version(ie) ||
51             wps_build_req_type(ie, req_type) ||
52 -           wps_build_wfa_ext(ie, 0, NULL, 0)) {
53 +           wps_build_wfa_ext(ie, 0, NULL, 0, 0)) {
54                 wpabuf_free(ie);
55                 return NULL;
56         }
57 @@ -464,7 +464,7 @@ struct wpabuf * wps_build_assoc_resp_ie(
58  
59         if (wps_build_version(ie) ||
60             wps_build_resp_type(ie, WPS_RESP_AP) ||
61 -           wps_build_wfa_ext(ie, 0, NULL, 0)) {
62 +           wps_build_wfa_ext(ie, 0, NULL, 0, 0)) {
63                 wpabuf_free(ie);
64                 return NULL;
65         }
66 @@ -516,7 +516,7 @@ struct wpabuf * wps_build_probe_req_ie(u
67             wps_build_model_name(dev, ie) ||
68             wps_build_model_number(dev, ie) ||
69             wps_build_dev_name(dev, ie) ||
70 -           wps_build_wfa_ext(ie, req_type == WPS_REQ_ENROLLEE, NULL, 0) ||
71 +           wps_build_wfa_ext(ie, req_type == WPS_REQ_ENROLLEE, NULL, 0, 0) ||
72             wps_build_req_dev_type(dev, ie, num_req_dev_types, req_dev_types)
73             ||
74             wps_build_secondary_dev_type(dev, ie)
75 --- a/src/wps/wps_attr_build.c
76 +++ b/src/wps/wps_attr_build.c
77 @@ -203,7 +203,8 @@ int wps_build_version(struct wpabuf *msg
78  
79  
80  int wps_build_wfa_ext(struct wpabuf *msg, int req_to_enroll,
81 -                     const u8 *auth_macs, size_t auth_macs_count)
82 +                     const u8 *auth_macs, size_t auth_macs_count,
83 +                     u8 multi_ap_subelem)
84  {
85         u8 *len;
86  
87 @@ -244,6 +245,14 @@ int wps_build_wfa_ext(struct wpabuf *msg
88                                    MAC2STR(&auth_macs[i * ETH_ALEN]));
89         }
90  
91 +       if (multi_ap_subelem) {
92 +               wpa_printf(MSG_DEBUG, "WPS:  * Multi-AP (0x%x)",
93 +                          multi_ap_subelem);
94 +               wpabuf_put_u8(msg, WFA_ELEM_MULTI_AP);
95 +               wpabuf_put_u8(msg, 1); /* length */
96 +               wpabuf_put_u8(msg, multi_ap_subelem);
97 +       }
98 +
99         WPA_PUT_BE16(len, (u8 *) wpabuf_put(msg, 0) - len - 2);
100  
101  #ifdef CONFIG_WPS_TESTING
102 --- a/src/wps/wps_common.c
103 +++ b/src/wps/wps_common.c
104 @@ -374,7 +374,7 @@ struct wpabuf * wps_get_oob_cred(struct
105             (rf_band && wps_build_rf_bands_attr(plain, rf_band)) ||
106             (channel && wps_build_ap_channel(plain, channel)) ||
107             wps_build_mac_addr(plain, wps->dev.mac_addr) ||
108 -           wps_build_wfa_ext(plain, 0, NULL, 0)) {
109 +           wps_build_wfa_ext(plain, 0, NULL, 0, 0)) {
110                 os_free(data.new_psk);
111                 wpabuf_clear_free(plain);
112                 return NULL;
113 @@ -421,7 +421,7 @@ struct wpabuf * wps_build_nfc_pw_token(u
114  
115         if (wps_build_oob_dev_pw(data, dev_pw_id, pubkey,
116                                  wpabuf_head(dev_pw), wpabuf_len(dev_pw)) ||
117 -           wps_build_wfa_ext(data, 0, NULL, 0)) {
118 +           wps_build_wfa_ext(data, 0, NULL, 0, 0)) {
119                 wpa_printf(MSG_ERROR, "WPS: Failed to build NFC password "
120                            "token");
121                 wpabuf_clear_free(data);
122 @@ -586,7 +586,7 @@ struct wpabuf * wps_build_wsc_ack(struct
123             wps_build_msg_type(msg, WPS_WSC_ACK) ||
124             wps_build_enrollee_nonce(wps, msg) ||
125             wps_build_registrar_nonce(wps, msg) ||
126 -           wps_build_wfa_ext(msg, 0, NULL, 0)) {
127 +           wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
128                 wpabuf_free(msg);
129                 return NULL;
130         }
131 @@ -610,7 +610,7 @@ struct wpabuf * wps_build_wsc_nack(struc
132             wps_build_enrollee_nonce(wps, msg) ||
133             wps_build_registrar_nonce(wps, msg) ||
134             wps_build_config_error(msg, wps->config_error) ||
135 -           wps_build_wfa_ext(msg, 0, NULL, 0)) {
136 +           wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
137                 wpabuf_free(msg);
138                 return NULL;
139         }
140 @@ -726,7 +726,7 @@ struct wpabuf * wps_build_nfc_handover_r
141         if (wps_build_oob_dev_pw(msg, DEV_PW_NFC_CONNECTION_HANDOVER,
142                                  nfc_dh_pubkey, NULL, 0) ||
143             wps_build_uuid_e(msg, ctx->uuid) ||
144 -           wps_build_wfa_ext(msg, 0, NULL, 0)) {
145 +           wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
146                 wpabuf_free(msg);
147                 return NULL;
148         }
149 @@ -809,7 +809,7 @@ struct wpabuf * wps_build_nfc_handover_s
150             wps_build_ssid(msg, ctx) ||
151             wps_build_ap_freq(msg, freq) ||
152             (bssid && wps_build_mac_addr(msg, bssid)) ||
153 -           wps_build_wfa_ext(msg, 0, NULL, 0)) {
154 +           wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
155                 wpabuf_free(msg);
156                 return NULL;
157         }
158 @@ -848,7 +848,7 @@ struct wpabuf * wps_build_nfc_handover_r
159             wps_build_rf_bands(&ctx->dev, msg, 0) ||
160             wps_build_serial_number(&ctx->dev, msg) ||
161             wps_build_uuid_e(msg, ctx->uuid) ||
162 -           wps_build_wfa_ext(msg, 0, NULL, 0)) {
163 +           wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
164                 wpabuf_free(msg);
165                 return NULL;
166         }
167 @@ -900,7 +900,7 @@ struct wpabuf * wps_build_nfc_handover_s
168             wps_build_rf_bands(&ctx->dev, msg, 0) ||
169             wps_build_serial_number(&ctx->dev, msg) ||
170             wps_build_uuid_e(msg, ctx->uuid) ||
171 -           wps_build_wfa_ext(msg, 0, NULL, 0)) {
172 +           wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
173                 wpabuf_free(msg);
174                 return NULL;
175         }
176 --- a/src/wps/wps_defs.h
177 +++ b/src/wps/wps_defs.h
178 @@ -152,7 +152,8 @@ enum {
179         WFA_ELEM_NETWORK_KEY_SHAREABLE = 0x02,
180         WFA_ELEM_REQUEST_TO_ENROLL = 0x03,
181         WFA_ELEM_SETTINGS_DELAY_TIME = 0x04,
182 -       WFA_ELEM_REGISTRAR_CONFIGURATION_METHODS = 0x05
183 +       WFA_ELEM_REGISTRAR_CONFIGURATION_METHODS = 0x05,
184 +       WFA_ELEM_MULTI_AP = 0x06
185  };
186  
187  /* Device Password ID */
188 --- a/src/wps/wps_enrollee.c
189 +++ b/src/wps/wps_enrollee.c
190 @@ -152,7 +152,7 @@ static struct wpabuf * wps_build_m1(stru
191             wps_build_dev_password_id(msg, wps->dev_pw_id) ||
192             wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
193             wps_build_os_version(&wps->wps->dev, msg) ||
194 -           wps_build_wfa_ext(msg, 0, NULL, 0) ||
195 +           wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
196             wps_build_vendor_ext_m1(&wps->wps->dev, msg)) {
197                 wpabuf_free(msg);
198                 return NULL;
199 @@ -190,7 +190,7 @@ static struct wpabuf * wps_build_m3(stru
200             wps_build_msg_type(msg, WPS_M3) ||
201             wps_build_registrar_nonce(wps, msg) ||
202             wps_build_e_hash(wps, msg) ||
203 -           wps_build_wfa_ext(msg, 0, NULL, 0) ||
204 +           wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
205             wps_build_authenticator(wps, msg)) {
206                 wpabuf_free(msg);
207                 return NULL;
208 @@ -223,7 +223,7 @@ static struct wpabuf * wps_build_m5(stru
209             wps_build_e_snonce1(wps, plain) ||
210             wps_build_key_wrap_auth(wps, plain) ||
211             wps_build_encr_settings(wps, msg, plain) ||
212 -           wps_build_wfa_ext(msg, 0, NULL, 0) ||
213 +           wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
214             wps_build_authenticator(wps, msg)) {
215                 wpabuf_clear_free(plain);
216                 wpabuf_free(msg);
217 @@ -393,7 +393,7 @@ static struct wpabuf * wps_build_m7(stru
218             (wps->wps->ap && wps_build_ap_settings(wps, plain)) ||
219             wps_build_key_wrap_auth(wps, plain) ||
220             wps_build_encr_settings(wps, msg, plain) ||
221 -           wps_build_wfa_ext(msg, 0, NULL, 0) ||
222 +           wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
223             wps_build_authenticator(wps, msg)) {
224                 wpabuf_clear_free(plain);
225                 wpabuf_free(msg);
226 @@ -430,7 +430,7 @@ static struct wpabuf * wps_build_wsc_don
227             wps_build_msg_type(msg, WPS_WSC_DONE) ||
228             wps_build_enrollee_nonce(wps, msg) ||
229             wps_build_registrar_nonce(wps, msg) ||
230 -           wps_build_wfa_ext(msg, 0, NULL, 0)) {
231 +           wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
232                 wpabuf_free(msg);
233                 return NULL;
234         }
235 --- a/src/wps/wps_er.c
236 +++ b/src/wps/wps_er.c
237 @@ -1530,7 +1530,7 @@ void wps_er_set_sel_reg(struct wps_er *e
238             wps_er_build_selected_registrar(msg, sel_reg) ||
239             wps_er_build_dev_password_id(msg, dev_passwd_id) ||
240             wps_er_build_sel_reg_config_methods(msg, sel_reg_config_methods) ||
241 -           wps_build_wfa_ext(msg, 0, auth_macs, count) ||
242 +           wps_build_wfa_ext(msg, 0, auth_macs, count, 0) ||
243             wps_er_build_uuid_r(msg, er->wps->uuid)) {
244                 wpabuf_free(msg);
245                 return;
246 @@ -2048,7 +2048,7 @@ struct wpabuf * wps_er_config_token_from
247         data.wps = wps;
248         data.use_cred = cred;
249         if (wps_build_cred(&data, ret) ||
250 -           wps_build_wfa_ext(ret, 0, NULL, 0)) {
251 +           wps_build_wfa_ext(ret, 0, NULL, 0, 0)) {
252                 wpabuf_free(ret);
253                 return NULL;
254         }
255 --- a/src/wps/wps_i.h
256 +++ b/src/wps/wps_i.h
257 @@ -163,7 +163,8 @@ int wps_build_encr_settings(struct wps_d
258                             struct wpabuf *plain);
259  int wps_build_version(struct wpabuf *msg);
260  int wps_build_wfa_ext(struct wpabuf *msg, int req_to_enroll,
261 -                     const u8 *auth_macs, size_t auth_macs_count);
262 +                     const u8 *auth_macs, size_t auth_macs_count,
263 +                     u8 multi_ap_subelem);
264  int wps_build_msg_type(struct wpabuf *msg, enum wps_msg_type msg_type);
265  int wps_build_enrollee_nonce(struct wps_data *wps, struct wpabuf *msg);
266  int wps_build_registrar_nonce(struct wps_data *wps, struct wpabuf *msg);
267 --- a/src/wps/wps_registrar.c
268 +++ b/src/wps/wps_registrar.c
269 @@ -1281,7 +1281,7 @@ static int wps_set_ie(struct wps_registr
270             wps_build_sel_reg_config_methods(reg, beacon) ||
271             wps_build_sel_pbc_reg_uuid_e(reg, beacon) ||
272             (reg->dualband && wps_build_rf_bands(&reg->wps->dev, beacon, 0)) ||
273 -           wps_build_wfa_ext(beacon, 0, auth_macs, count) ||
274 +           wps_build_wfa_ext(beacon, 0, auth_macs, count, 0) ||
275             wps_build_vendor_ext(&reg->wps->dev, beacon)) {
276                 wpabuf_free(beacon);
277                 wpabuf_free(probe);
278 @@ -1311,7 +1311,7 @@ static int wps_set_ie(struct wps_registr
279             wps_build_device_attrs(&reg->wps->dev, probe) ||
280             wps_build_probe_config_methods(reg, probe) ||
281             (reg->dualband && wps_build_rf_bands(&reg->wps->dev, probe, 0)) ||
282 -           wps_build_wfa_ext(probe, 0, auth_macs, count) ||
283 +           wps_build_wfa_ext(probe, 0, auth_macs, count, 0) ||
284             wps_build_vendor_ext(&reg->wps->dev, probe)) {
285                 wpabuf_free(beacon);
286                 wpabuf_free(probe);
287 @@ -1845,7 +1845,7 @@ static struct wpabuf * wps_build_m2(stru
288             wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
289             wps_build_dev_password_id(msg, wps->dev_pw_id) ||
290             wps_build_os_version(&wps->wps->dev, msg) ||
291 -           wps_build_wfa_ext(msg, 0, NULL, 0)) {
292 +           wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
293                 wpabuf_free(msg);
294                 return NULL;
295         }
296 @@ -1913,7 +1913,7 @@ static struct wpabuf * wps_build_m2d(str
297             wps_build_assoc_state(wps, msg) ||
298             wps_build_config_error(msg, err) ||
299             wps_build_os_version(&wps->wps->dev, msg) ||
300 -           wps_build_wfa_ext(msg, 0, NULL, 0)) {
301 +           wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
302                 wpabuf_free(msg);
303                 return NULL;
304         }
305 @@ -1949,7 +1949,7 @@ static struct wpabuf * wps_build_m4(stru
306             wps_build_r_snonce1(wps, plain) ||
307             wps_build_key_wrap_auth(wps, plain) ||
308             wps_build_encr_settings(wps, msg, plain) ||
309 -           wps_build_wfa_ext(msg, 0, NULL, 0) ||
310 +           wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
311             wps_build_authenticator(wps, msg)) {
312                 wpabuf_clear_free(plain);
313                 wpabuf_free(msg);
314 @@ -1984,7 +1984,7 @@ static struct wpabuf * wps_build_m6(stru
315             wps_build_r_snonce2(wps, plain) ||
316             wps_build_key_wrap_auth(wps, plain) ||
317             wps_build_encr_settings(wps, msg, plain) ||
318 -           wps_build_wfa_ext(msg, 0, NULL, 0) ||
319 +           wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
320             wps_build_authenticator(wps, msg)) {
321                 wpabuf_clear_free(plain);
322                 wpabuf_free(msg);
323 @@ -2021,7 +2021,7 @@ static struct wpabuf * wps_build_m8(stru
324             (!wps->wps->ap && !wps->er && wps_build_ap_settings(wps, plain)) ||
325             wps_build_key_wrap_auth(wps, plain) ||
326             wps_build_encr_settings(wps, msg, plain) ||
327 -           wps_build_wfa_ext(msg, 0, NULL, 0) ||
328 +           wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
329             wps_build_authenticator(wps, msg)) {
330                 wpabuf_clear_free(plain);
331                 wpabuf_clear_free(msg);
332 --- a/src/wps/wps_upnp.c
333 +++ b/src/wps/wps_upnp.c
334 @@ -599,7 +599,7 @@ static struct wpabuf * build_fake_wsc_ac
335         wpabuf_put_be16(msg, ATTR_REGISTRAR_NONCE);
336         wpabuf_put_be16(msg, WPS_NONCE_LEN);
337         wpabuf_put(msg, WPS_NONCE_LEN);
338 -       if (wps_build_wfa_ext(msg, 0, NULL, 0)) {
339 +       if (wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
340                 wpabuf_free(msg);
341                 return NULL;
342         }