]> git.ipfire.org Git - thirdparty/hostap.git/blob - src/wps/wps_attr_parse.c
WPS: Add UFD support (USBA out-of-band mechanism)
[thirdparty/hostap.git] / src / wps / wps_attr_parse.c
1 /*
2 * Wi-Fi Protected Setup - attribute parsing
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 "wps_i.h"
19
20
21 static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
22 const u8 *pos, u16 len)
23 {
24 switch (type) {
25 case ATTR_VERSION:
26 if (len != 1) {
27 wpa_printf(MSG_DEBUG, "WPS: Invalid Version length %u",
28 len);
29 return -1;
30 }
31 attr->version = pos;
32 break;
33 case ATTR_MSG_TYPE:
34 if (len != 1) {
35 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type "
36 "length %u", len);
37 return -1;
38 }
39 attr->msg_type = pos;
40 break;
41 case ATTR_ENROLLEE_NONCE:
42 if (len != WPS_NONCE_LEN) {
43 wpa_printf(MSG_DEBUG, "WPS: Invalid Enrollee Nonce "
44 "length %u", len);
45 return -1;
46 }
47 attr->enrollee_nonce = pos;
48 break;
49 case ATTR_REGISTRAR_NONCE:
50 if (len != WPS_NONCE_LEN) {
51 wpa_printf(MSG_DEBUG, "WPS: Invalid Registrar Nonce "
52 "length %u", len);
53 return -1;
54 }
55 attr->registrar_nonce = pos;
56 break;
57 case ATTR_UUID_E:
58 if (len != WPS_UUID_LEN) {
59 wpa_printf(MSG_DEBUG, "WPS: Invalid UUID-E length %u",
60 len);
61 return -1;
62 }
63 attr->uuid_e = pos;
64 break;
65 case ATTR_UUID_R:
66 if (len != WPS_UUID_LEN) {
67 wpa_printf(MSG_DEBUG, "WPS: Invalid UUID-R length %u",
68 len);
69 return -1;
70 }
71 attr->uuid_r = pos;
72 break;
73 case ATTR_AUTH_TYPE_FLAGS:
74 if (len != 2) {
75 wpa_printf(MSG_DEBUG, "WPS: Invalid Authentication "
76 "Type Flags length %u", len);
77 return -1;
78 }
79 attr->auth_type_flags = pos;
80 break;
81 case ATTR_ENCR_TYPE_FLAGS:
82 if (len != 2) {
83 wpa_printf(MSG_DEBUG, "WPS: Invalid Encryption Type "
84 "Flags length %u", len);
85 return -1;
86 }
87 attr->encr_type_flags = pos;
88 break;
89 case ATTR_CONN_TYPE_FLAGS:
90 if (len != 1) {
91 wpa_printf(MSG_DEBUG, "WPS: Invalid Connection Type "
92 "Flags length %u", len);
93 return -1;
94 }
95 attr->conn_type_flags = pos;
96 break;
97 case ATTR_CONFIG_METHODS:
98 if (len != 2) {
99 wpa_printf(MSG_DEBUG, "WPS: Invalid Config Methods "
100 "length %u", len);
101 return -1;
102 }
103 attr->config_methods = pos;
104 break;
105 case ATTR_SELECTED_REGISTRAR_CONFIG_METHODS:
106 if (len != 2) {
107 wpa_printf(MSG_DEBUG, "WPS: Invalid Selected "
108 "Registrar Config Methods length %u", len);
109 return -1;
110 }
111 attr->sel_reg_config_methods = pos;
112 break;
113 case ATTR_PRIMARY_DEV_TYPE:
114 if (len != sizeof(struct wps_dev_type)) {
115 wpa_printf(MSG_DEBUG, "WPS: Invalid Primary Device "
116 "Type length %u", len);
117 return -1;
118 }
119 attr->primary_dev_type = pos;
120 break;
121 case ATTR_RF_BANDS:
122 if (len != 1) {
123 wpa_printf(MSG_DEBUG, "WPS: Invalid RF Bands length "
124 "%u", len);
125 return -1;
126 }
127 attr->rf_bands = pos;
128 break;
129 case ATTR_ASSOC_STATE:
130 if (len != 2) {
131 wpa_printf(MSG_DEBUG, "WPS: Invalid Association State "
132 "length %u", len);
133 return -1;
134 }
135 attr->assoc_state = pos;
136 break;
137 case ATTR_CONFIG_ERROR:
138 if (len != 2) {
139 wpa_printf(MSG_DEBUG, "WPS: Invalid Configuration "
140 "Error length %u", len);
141 return -1;
142 }
143 attr->config_error = pos;
144 break;
145 case ATTR_DEV_PASSWORD_ID:
146 if (len != 2) {
147 wpa_printf(MSG_DEBUG, "WPS: Invalid Device Password "
148 "ID length %u", len);
149 return -1;
150 }
151 attr->dev_password_id = pos;
152 break;
153 case ATTR_OOB_DEVICE_PASSWORD:
154 if (len != WPS_OOB_DEVICE_PASSWORD_ATTR_LEN) {
155 wpa_printf(MSG_DEBUG, "WPS: Invalid OOB Device "
156 "Password length %u", len);
157 return -1;
158 }
159 attr->oob_dev_password = pos;
160 break;
161 case ATTR_OS_VERSION:
162 if (len != 4) {
163 wpa_printf(MSG_DEBUG, "WPS: Invalid OS Version length "
164 "%u", len);
165 return -1;
166 }
167 attr->os_version = pos;
168 break;
169 case ATTR_WPS_STATE:
170 if (len != 1) {
171 wpa_printf(MSG_DEBUG, "WPS: Invalid Wi-Fi Protected "
172 "Setup State length %u", len);
173 return -1;
174 }
175 attr->wps_state = pos;
176 break;
177 case ATTR_AUTHENTICATOR:
178 if (len != WPS_AUTHENTICATOR_LEN) {
179 wpa_printf(MSG_DEBUG, "WPS: Invalid Authenticator "
180 "length %u", len);
181 return -1;
182 }
183 attr->authenticator = pos;
184 break;
185 case ATTR_R_HASH1:
186 if (len != WPS_HASH_LEN) {
187 wpa_printf(MSG_DEBUG, "WPS: Invalid R-Hash1 length %u",
188 len);
189 return -1;
190 }
191 attr->r_hash1 = pos;
192 break;
193 case ATTR_R_HASH2:
194 if (len != WPS_HASH_LEN) {
195 wpa_printf(MSG_DEBUG, "WPS: Invalid R-Hash2 length %u",
196 len);
197 return -1;
198 }
199 attr->r_hash2 = pos;
200 break;
201 case ATTR_E_HASH1:
202 if (len != WPS_HASH_LEN) {
203 wpa_printf(MSG_DEBUG, "WPS: Invalid E-Hash1 length %u",
204 len);
205 return -1;
206 }
207 attr->e_hash1 = pos;
208 break;
209 case ATTR_E_HASH2:
210 if (len != WPS_HASH_LEN) {
211 wpa_printf(MSG_DEBUG, "WPS: Invalid E-Hash2 length %u",
212 len);
213 return -1;
214 }
215 attr->e_hash2 = pos;
216 break;
217 case ATTR_R_SNONCE1:
218 if (len != WPS_SECRET_NONCE_LEN) {
219 wpa_printf(MSG_DEBUG, "WPS: Invalid R-SNonce1 length "
220 "%u", len);
221 return -1;
222 }
223 attr->r_snonce1 = pos;
224 break;
225 case ATTR_R_SNONCE2:
226 if (len != WPS_SECRET_NONCE_LEN) {
227 wpa_printf(MSG_DEBUG, "WPS: Invalid R-SNonce2 length "
228 "%u", len);
229 return -1;
230 }
231 attr->r_snonce2 = pos;
232 break;
233 case ATTR_E_SNONCE1:
234 if (len != WPS_SECRET_NONCE_LEN) {
235 wpa_printf(MSG_DEBUG, "WPS: Invalid E-SNonce1 length "
236 "%u", len);
237 return -1;
238 }
239 attr->e_snonce1 = pos;
240 break;
241 case ATTR_E_SNONCE2:
242 if (len != WPS_SECRET_NONCE_LEN) {
243 wpa_printf(MSG_DEBUG, "WPS: Invalid E-SNonce2 length "
244 "%u", len);
245 return -1;
246 }
247 attr->e_snonce2 = pos;
248 break;
249 case ATTR_KEY_WRAP_AUTH:
250 if (len != WPS_KWA_LEN) {
251 wpa_printf(MSG_DEBUG, "WPS: Invalid Key Wrap "
252 "Authenticator length %u", len);
253 return -1;
254 }
255 attr->key_wrap_auth = pos;
256 break;
257 case ATTR_AUTH_TYPE:
258 if (len != 2) {
259 wpa_printf(MSG_DEBUG, "WPS: Invalid Authentication "
260 "Type length %u", len);
261 return -1;
262 }
263 attr->auth_type = pos;
264 break;
265 case ATTR_ENCR_TYPE:
266 if (len != 2) {
267 wpa_printf(MSG_DEBUG, "WPS: Invalid Encryption "
268 "Type length %u", len);
269 return -1;
270 }
271 attr->encr_type = pos;
272 break;
273 case ATTR_NETWORK_INDEX:
274 if (len != 1) {
275 wpa_printf(MSG_DEBUG, "WPS: Invalid Network Index "
276 "length %u", len);
277 return -1;
278 }
279 attr->network_idx = pos;
280 break;
281 case ATTR_NETWORK_KEY_INDEX:
282 if (len != 1) {
283 wpa_printf(MSG_DEBUG, "WPS: Invalid Network Key Index "
284 "length %u", len);
285 return -1;
286 }
287 attr->network_key_idx = pos;
288 break;
289 case ATTR_MAC_ADDR:
290 if (len != ETH_ALEN) {
291 wpa_printf(MSG_DEBUG, "WPS: Invalid MAC Address "
292 "length %u", len);
293 return -1;
294 }
295 attr->mac_addr = pos;
296 break;
297 case ATTR_KEY_PROVIDED_AUTO:
298 if (len != 1) {
299 wpa_printf(MSG_DEBUG, "WPS: Invalid Key Provided "
300 "Automatically length %u", len);
301 return -1;
302 }
303 attr->key_prov_auto = pos;
304 break;
305 case ATTR_802_1X_ENABLED:
306 if (len != 1) {
307 wpa_printf(MSG_DEBUG, "WPS: Invalid 802.1X Enabled "
308 "length %u", len);
309 return -1;
310 }
311 attr->dot1x_enabled = pos;
312 break;
313 case ATTR_SELECTED_REGISTRAR:
314 if (len != 1) {
315 wpa_printf(MSG_DEBUG, "WPS: Invalid Selected Registrar"
316 " length %u", len);
317 return -1;
318 }
319 attr->selected_registrar = pos;
320 break;
321 case ATTR_REQUEST_TYPE:
322 if (len != 1) {
323 wpa_printf(MSG_DEBUG, "WPS: Invalid Request Type "
324 "length %u", len);
325 return -1;
326 }
327 attr->request_type = pos;
328 break;
329 case ATTR_RESPONSE_TYPE:
330 if (len != 1) {
331 wpa_printf(MSG_DEBUG, "WPS: Invalid Response Type "
332 "length %u", len);
333 return -1;
334 }
335 attr->request_type = pos;
336 break;
337 case ATTR_MANUFACTURER:
338 attr->manufacturer = pos;
339 attr->manufacturer_len = len;
340 break;
341 case ATTR_MODEL_NAME:
342 attr->model_name = pos;
343 attr->model_name_len = len;
344 break;
345 case ATTR_MODEL_NUMBER:
346 attr->model_number = pos;
347 attr->model_number_len = len;
348 break;
349 case ATTR_SERIAL_NUMBER:
350 attr->serial_number = pos;
351 attr->serial_number_len = len;
352 break;
353 case ATTR_DEV_NAME:
354 attr->dev_name = pos;
355 attr->dev_name_len = len;
356 break;
357 case ATTR_PUBLIC_KEY:
358 attr->public_key = pos;
359 attr->public_key_len = len;
360 break;
361 case ATTR_ENCR_SETTINGS:
362 attr->encr_settings = pos;
363 attr->encr_settings_len = len;
364 break;
365 case ATTR_CRED:
366 if (attr->num_cred >= MAX_CRED_COUNT) {
367 wpa_printf(MSG_DEBUG, "WPS: Skipped Credential "
368 "attribute (max %d credentials)",
369 MAX_CRED_COUNT);
370 break;
371 }
372 attr->cred[attr->num_cred] = pos;
373 attr->cred_len[attr->num_cred] = len;
374 attr->num_cred++;
375 break;
376 case ATTR_SSID:
377 attr->ssid = pos;
378 attr->ssid_len = len;
379 break;
380 case ATTR_NETWORK_KEY:
381 attr->network_key = pos;
382 attr->network_key_len = len;
383 break;
384 case ATTR_EAP_TYPE:
385 attr->eap_type = pos;
386 attr->eap_type_len = len;
387 break;
388 case ATTR_EAP_IDENTITY:
389 attr->eap_identity = pos;
390 attr->eap_identity_len = len;
391 break;
392 default:
393 wpa_printf(MSG_DEBUG, "WPS: Unsupported attribute type 0x%x "
394 "len=%u", type, len);
395 break;
396 }
397
398 return 0;
399 }
400
401
402 int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr)
403 {
404 const u8 *pos, *end;
405 u16 type, len;
406
407 os_memset(attr, 0, sizeof(*attr));
408 pos = wpabuf_head(msg);
409 end = pos + wpabuf_len(msg);
410
411 while (pos < end) {
412 if (end - pos < 4) {
413 wpa_printf(MSG_DEBUG, "WPS: Invalid message - "
414 "%lu bytes remaining",
415 (unsigned long) (end - pos));
416 return -1;
417 }
418
419 type = WPA_GET_BE16(pos);
420 pos += 2;
421 len = WPA_GET_BE16(pos);
422 pos += 2;
423 wpa_printf(MSG_MSGDUMP, "WPS: attr type=0x%x len=%u",
424 type, len);
425 if (len > end - pos) {
426 wpa_printf(MSG_DEBUG, "WPS: Attribute overflow");
427 return -1;
428 }
429
430 if (wps_set_attr(attr, type, pos, len) < 0)
431 return -1;
432
433 pos += len;
434 }
435
436 return 0;
437 }