Line data Source code
1 : /*
2 : * Wi-Fi Protected Setup - attribute parsing
3 : * Copyright (c) 2008, Jouni Malinen <j@w1.fi>
4 : *
5 : * This software may be distributed under the terms of the BSD license.
6 : * See README for more details.
7 : */
8 :
9 : #include "includes.h"
10 :
11 : #include "common.h"
12 : #include "wps_defs.h"
13 : #include "wps_attr_parse.h"
14 :
15 : #ifndef CONFIG_WPS_STRICT
16 : #define WPS_WORKAROUNDS
17 : #endif /* CONFIG_WPS_STRICT */
18 :
19 :
20 10531 : static int wps_set_vendor_ext_wfa_subelem(struct wps_parse_attr *attr,
21 : u8 id, u8 len, const u8 *pos)
22 : {
23 10531 : wpa_printf(MSG_EXCESSIVE, "WPS: WFA subelement id=%u len=%u",
24 : id, len);
25 10531 : switch (id) {
26 : case WFA_ELEM_VERSION2:
27 7327 : if (len != 1) {
28 1 : wpa_printf(MSG_DEBUG, "WPS: Invalid Version2 length "
29 : "%u", len);
30 1 : return -1;
31 : }
32 7326 : attr->version2 = pos;
33 7326 : break;
34 : case WFA_ELEM_AUTHORIZEDMACS:
35 1165 : attr->authorized_macs = pos;
36 1165 : attr->authorized_macs_len = len;
37 1165 : break;
38 : case WFA_ELEM_NETWORK_KEY_SHAREABLE:
39 2 : if (len != 1) {
40 1 : wpa_printf(MSG_DEBUG, "WPS: Invalid Network Key "
41 : "Shareable length %u", len);
42 1 : return -1;
43 : }
44 1 : attr->network_key_shareable = pos;
45 1 : break;
46 : case WFA_ELEM_REQUEST_TO_ENROLL:
47 2033 : if (len != 1) {
48 1 : wpa_printf(MSG_DEBUG, "WPS: Invalid Request to Enroll "
49 : "length %u", len);
50 1 : return -1;
51 : }
52 2032 : attr->request_to_enroll = pos;
53 2032 : break;
54 : case WFA_ELEM_SETTINGS_DELAY_TIME:
55 2 : if (len != 1) {
56 1 : wpa_printf(MSG_DEBUG, "WPS: Invalid Settings Delay "
57 : "Time length %u", len);
58 1 : return -1;
59 : }
60 1 : attr->settings_delay_time = pos;
61 1 : break;
62 : case WFA_ELEM_REGISTRAR_CONFIGURATION_METHODS:
63 0 : if (len != 2) {
64 0 : wpa_printf(MSG_DEBUG, "WPS: Invalid Registrar Configuration Methods length %u",
65 : len);
66 0 : return -1;
67 : }
68 0 : attr->registrar_configuration_methods = pos;
69 0 : break;
70 : default:
71 2 : wpa_printf(MSG_MSGDUMP, "WPS: Skipped unknown WFA Vendor "
72 : "Extension subelement %u", id);
73 2 : break;
74 : }
75 :
76 10527 : return 0;
77 : }
78 :
79 :
80 7333 : static int wps_parse_vendor_ext_wfa(struct wps_parse_attr *attr, const u8 *pos,
81 : u16 len)
82 : {
83 7333 : const u8 *end = pos + len;
84 : u8 id, elen;
85 :
86 25193 : while (pos + 2 <= end) {
87 10532 : id = *pos++;
88 10532 : elen = *pos++;
89 10532 : if (pos + elen > end)
90 1 : break;
91 10531 : if (wps_set_vendor_ext_wfa_subelem(attr, id, elen, pos) < 0)
92 4 : return -1;
93 10527 : pos += elen;
94 : }
95 :
96 7329 : return 0;
97 : }
98 :
99 :
100 7368 : static int wps_parse_vendor_ext(struct wps_parse_attr *attr, const u8 *pos,
101 : u16 len)
102 : {
103 : u32 vendor_id;
104 :
105 7368 : if (len < 3) {
106 3 : wpa_printf(MSG_DEBUG, "WPS: Skip invalid Vendor Extension");
107 3 : return 0;
108 : }
109 :
110 7365 : vendor_id = WPA_GET_BE24(pos);
111 7365 : switch (vendor_id) {
112 : case WPS_VENDOR_ID_WFA:
113 7333 : return wps_parse_vendor_ext_wfa(attr, pos + 3, len - 3);
114 : }
115 :
116 : /* Handle unknown vendor extensions */
117 :
118 32 : wpa_printf(MSG_MSGDUMP, "WPS: Unknown Vendor Extension (Vendor ID %u)",
119 : vendor_id);
120 :
121 32 : if (len > WPS_MAX_VENDOR_EXT_LEN) {
122 1 : wpa_printf(MSG_DEBUG, "WPS: Too long Vendor Extension (%u)",
123 : len);
124 1 : return -1;
125 : }
126 :
127 31 : if (attr->num_vendor_ext >= MAX_WPS_PARSE_VENDOR_EXT) {
128 1 : wpa_printf(MSG_DEBUG, "WPS: Skipped Vendor Extension "
129 : "attribute (max %d vendor extensions)",
130 : MAX_WPS_PARSE_VENDOR_EXT);
131 1 : return -1;
132 : }
133 30 : attr->vendor_ext[attr->num_vendor_ext] = pos;
134 30 : attr->vendor_ext_len[attr->num_vendor_ext] = len;
135 30 : attr->num_vendor_ext++;
136 :
137 30 : return 0;
138 : }
139 :
140 :
141 90192 : static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
142 : const u8 *pos, u16 len)
143 : {
144 90192 : switch (type) {
145 : case ATTR_VERSION:
146 7322 : if (len != 1) {
147 1 : wpa_printf(MSG_DEBUG, "WPS: Invalid Version length %u",
148 : len);
149 1 : return -1;
150 : }
151 7321 : attr->version = pos;
152 7321 : break;
153 : case ATTR_MSG_TYPE:
154 1715 : if (len != 1) {
155 1 : wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type "
156 : "length %u", len);
157 1 : return -1;
158 : }
159 1714 : attr->msg_type = pos;
160 1714 : break;
161 : case ATTR_ENROLLEE_NONCE:
162 1195 : if (len != WPS_NONCE_LEN) {
163 1 : wpa_printf(MSG_DEBUG, "WPS: Invalid Enrollee Nonce "
164 : "length %u", len);
165 1 : return -1;
166 : }
167 1194 : attr->enrollee_nonce = pos;
168 1194 : break;
169 : case ATTR_REGISTRAR_NONCE:
170 1003 : if (len != WPS_NONCE_LEN) {
171 1 : wpa_printf(MSG_DEBUG, "WPS: Invalid Registrar Nonce "
172 : "length %u", len);
173 1 : return -1;
174 : }
175 1002 : attr->registrar_nonce = pos;
176 1002 : break;
177 : case ATTR_UUID_E:
178 5105 : if (len != WPS_UUID_LEN) {
179 2 : wpa_printf(MSG_DEBUG, "WPS: Invalid UUID-E length %u",
180 : len);
181 2 : return -1;
182 : }
183 5103 : attr->uuid_e = pos;
184 5103 : break;
185 : case ATTR_UUID_R:
186 240 : if (len != WPS_UUID_LEN) {
187 2 : wpa_printf(MSG_DEBUG, "WPS: Invalid UUID-R length %u",
188 : len);
189 2 : return -1;
190 : }
191 238 : attr->uuid_r = pos;
192 238 : break;
193 : case ATTR_AUTH_TYPE_FLAGS:
194 450 : if (len != 2) {
195 1 : wpa_printf(MSG_DEBUG, "WPS: Invalid Authentication "
196 : "Type Flags length %u", len);
197 1 : return -1;
198 : }
199 449 : attr->auth_type_flags = pos;
200 449 : break;
201 : case ATTR_ENCR_TYPE_FLAGS:
202 450 : if (len != 2) {
203 1 : wpa_printf(MSG_DEBUG, "WPS: Invalid Encryption Type "
204 : "Flags length %u", len);
205 1 : return -1;
206 : }
207 449 : attr->encr_type_flags = pos;
208 449 : break;
209 : case ATTR_CONN_TYPE_FLAGS:
210 450 : if (len != 1) {
211 1 : wpa_printf(MSG_DEBUG, "WPS: Invalid Connection Type "
212 : "Flags length %u", len);
213 1 : return -1;
214 : }
215 449 : attr->conn_type_flags = pos;
216 449 : break;
217 : case ATTR_CONFIG_METHODS:
218 5405 : if (len != 2) {
219 1 : wpa_printf(MSG_DEBUG, "WPS: Invalid Config Methods "
220 : "length %u", len);
221 1 : return -1;
222 : }
223 5404 : attr->config_methods = pos;
224 5404 : break;
225 : case ATTR_SELECTED_REGISTRAR_CONFIG_METHODS:
226 1187 : if (len != 2) {
227 1 : wpa_printf(MSG_DEBUG, "WPS: Invalid Selected "
228 : "Registrar Config Methods length %u", len);
229 1 : return -1;
230 : }
231 1186 : attr->sel_reg_config_methods = pos;
232 1186 : break;
233 : case ATTR_PRIMARY_DEV_TYPE:
234 5327 : if (len != WPS_DEV_TYPE_LEN) {
235 1 : wpa_printf(MSG_DEBUG, "WPS: Invalid Primary Device "
236 : "Type length %u", len);
237 1 : return -1;
238 : }
239 5326 : attr->primary_dev_type = pos;
240 5326 : break;
241 : case ATTR_RF_BANDS:
242 2804 : if (len != 1) {
243 1 : wpa_printf(MSG_DEBUG, "WPS: Invalid RF Bands length "
244 : "%u", len);
245 1 : return -1;
246 : }
247 2803 : attr->rf_bands = pos;
248 2803 : break;
249 : case ATTR_ASSOC_STATE:
250 2700 : if (len != 2) {
251 1 : wpa_printf(MSG_DEBUG, "WPS: Invalid Association State "
252 : "length %u", len);
253 1 : return -1;
254 : }
255 2699 : attr->assoc_state = pos;
256 2699 : break;
257 : case ATTR_CONFIG_ERROR:
258 2761 : if (len != 2) {
259 1 : wpa_printf(MSG_DEBUG, "WPS: Invalid Configuration "
260 : "Error length %u", len);
261 1 : return -1;
262 : }
263 2760 : attr->config_error = pos;
264 2760 : break;
265 : case ATTR_DEV_PASSWORD_ID:
266 4053 : if (len != 2) {
267 1 : wpa_printf(MSG_DEBUG, "WPS: Invalid Device Password "
268 : "ID length %u", len);
269 1 : return -1;
270 : }
271 4052 : attr->dev_password_id = pos;
272 4052 : break;
273 : case ATTR_OOB_DEVICE_PASSWORD:
274 54 : if (len < WPS_OOB_PUBKEY_HASH_LEN + 2 ||
275 : len > WPS_OOB_PUBKEY_HASH_LEN + 2 +
276 52 : WPS_OOB_DEVICE_PASSWORD_LEN ||
277 : (len < WPS_OOB_PUBKEY_HASH_LEN + 2 +
278 39 : WPS_OOB_DEVICE_PASSWORD_MIN_LEN &&
279 39 : WPA_GET_BE16(pos + WPS_OOB_PUBKEY_HASH_LEN) !=
280 : DEV_PW_NFC_CONNECTION_HANDOVER)) {
281 3 : wpa_printf(MSG_DEBUG, "WPS: Invalid OOB Device "
282 : "Password length %u", len);
283 3 : return -1;
284 : }
285 51 : attr->oob_dev_password = pos;
286 51 : attr->oob_dev_password_len = len;
287 51 : break;
288 : case ATTR_OS_VERSION:
289 450 : if (len != 4) {
290 1 : wpa_printf(MSG_DEBUG, "WPS: Invalid OS Version length "
291 : "%u", len);
292 1 : return -1;
293 : }
294 449 : attr->os_version = pos;
295 449 : break;
296 : case ATTR_WPS_STATE:
297 2866 : if (len != 1) {
298 1 : wpa_printf(MSG_DEBUG, "WPS: Invalid Wi-Fi Protected "
299 : "Setup State length %u", len);
300 1 : return -1;
301 : }
302 2865 : attr->wps_state = pos;
303 2865 : break;
304 : case ATTR_AUTHENTICATOR:
305 1204 : if (len != WPS_AUTHENTICATOR_LEN) {
306 2 : wpa_printf(MSG_DEBUG, "WPS: Invalid Authenticator "
307 : "length %u", len);
308 2 : return -1;
309 : }
310 1202 : attr->authenticator = pos;
311 1202 : break;
312 : case ATTR_R_HASH1:
313 177 : if (len != WPS_HASH_LEN) {
314 2 : wpa_printf(MSG_DEBUG, "WPS: Invalid R-Hash1 length %u",
315 : len);
316 2 : return -1;
317 : }
318 175 : attr->r_hash1 = pos;
319 175 : break;
320 : case ATTR_R_HASH2:
321 177 : if (len != WPS_HASH_LEN) {
322 2 : wpa_printf(MSG_DEBUG, "WPS: Invalid R-Hash2 length %u",
323 : len);
324 2 : return -1;
325 : }
326 175 : attr->r_hash2 = pos;
327 175 : break;
328 : case ATTR_E_HASH1:
329 187 : if (len != WPS_HASH_LEN) {
330 2 : wpa_printf(MSG_DEBUG, "WPS: Invalid E-Hash1 length %u",
331 : len);
332 2 : return -1;
333 : }
334 185 : attr->e_hash1 = pos;
335 185 : break;
336 : case ATTR_E_HASH2:
337 187 : if (len != WPS_HASH_LEN) {
338 2 : wpa_printf(MSG_DEBUG, "WPS: Invalid E-Hash2 length %u",
339 : len);
340 2 : return -1;
341 : }
342 185 : attr->e_hash2 = pos;
343 185 : break;
344 : case ATTR_R_SNONCE1:
345 170 : if (len != WPS_SECRET_NONCE_LEN) {
346 2 : wpa_printf(MSG_DEBUG, "WPS: Invalid R-SNonce1 length "
347 : "%u", len);
348 2 : return -1;
349 : }
350 168 : attr->r_snonce1 = pos;
351 168 : break;
352 : case ATTR_R_SNONCE2:
353 161 : if (len != WPS_SECRET_NONCE_LEN) {
354 2 : wpa_printf(MSG_DEBUG, "WPS: Invalid R-SNonce2 length "
355 : "%u", len);
356 2 : return -1;
357 : }
358 159 : attr->r_snonce2 = pos;
359 159 : break;
360 : case ATTR_E_SNONCE1:
361 161 : if (len != WPS_SECRET_NONCE_LEN) {
362 2 : wpa_printf(MSG_DEBUG, "WPS: Invalid E-SNonce1 length "
363 : "%u", len);
364 2 : return -1;
365 : }
366 159 : attr->e_snonce1 = pos;
367 159 : break;
368 : case ATTR_E_SNONCE2:
369 157 : if (len != WPS_SECRET_NONCE_LEN) {
370 2 : wpa_printf(MSG_DEBUG, "WPS: Invalid E-SNonce2 length "
371 : "%u", len);
372 2 : return -1;
373 : }
374 155 : attr->e_snonce2 = pos;
375 155 : break;
376 : case ATTR_KEY_WRAP_AUTH:
377 791 : if (len != WPS_KWA_LEN) {
378 2 : wpa_printf(MSG_DEBUG, "WPS: Invalid Key Wrap "
379 : "Authenticator length %u", len);
380 2 : return -1;
381 : }
382 789 : attr->key_wrap_auth = pos;
383 789 : break;
384 : case ATTR_AUTH_TYPE:
385 182 : if (len != 2) {
386 1 : wpa_printf(MSG_DEBUG, "WPS: Invalid Authentication "
387 : "Type length %u", len);
388 1 : return -1;
389 : }
390 181 : attr->auth_type = pos;
391 181 : break;
392 : case ATTR_ENCR_TYPE:
393 182 : if (len != 2) {
394 1 : wpa_printf(MSG_DEBUG, "WPS: Invalid Encryption "
395 : "Type length %u", len);
396 1 : return -1;
397 : }
398 181 : attr->encr_type = pos;
399 181 : break;
400 : case ATTR_NETWORK_INDEX:
401 158 : if (len != 1) {
402 1 : wpa_printf(MSG_DEBUG, "WPS: Invalid Network Index "
403 : "length %u", len);
404 1 : return -1;
405 : }
406 157 : attr->network_idx = pos;
407 157 : break;
408 : case ATTR_NETWORK_KEY_INDEX:
409 3 : if (len != 1) {
410 1 : wpa_printf(MSG_DEBUG, "WPS: Invalid Network Key Index "
411 : "length %u", len);
412 1 : return -1;
413 : }
414 2 : attr->network_key_idx = pos;
415 2 : break;
416 : case ATTR_MAC_ADDR:
417 426 : if (len != ETH_ALEN) {
418 2 : wpa_printf(MSG_DEBUG, "WPS: Invalid MAC Address "
419 : "length %u", len);
420 2 : return -1;
421 : }
422 424 : attr->mac_addr = pos;
423 424 : break;
424 : case ATTR_SELECTED_REGISTRAR:
425 1187 : if (len != 1) {
426 1 : wpa_printf(MSG_DEBUG, "WPS: Invalid Selected Registrar"
427 : " length %u", len);
428 1 : return -1;
429 : }
430 1186 : attr->selected_registrar = pos;
431 1186 : break;
432 : case ATTR_REQUEST_TYPE:
433 2769 : if (len != 1) {
434 1 : wpa_printf(MSG_DEBUG, "WPS: Invalid Request Type "
435 : "length %u", len);
436 1 : return -1;
437 : }
438 2768 : attr->request_type = pos;
439 2768 : break;
440 : case ATTR_RESPONSE_TYPE:
441 2591 : if (len != 1) {
442 1 : wpa_printf(MSG_DEBUG, "WPS: Invalid Response Type "
443 : "length %u", len);
444 1 : return -1;
445 : }
446 2590 : attr->response_type = pos;
447 2590 : break;
448 : case ATTR_MANUFACTURER:
449 5311 : attr->manufacturer = pos;
450 5311 : attr->manufacturer_len = len;
451 5311 : break;
452 : case ATTR_MODEL_NAME:
453 5312 : attr->model_name = pos;
454 5312 : attr->model_name_len = len;
455 5312 : break;
456 : case ATTR_MODEL_NUMBER:
457 5311 : attr->model_number = pos;
458 5311 : attr->model_number_len = len;
459 5311 : break;
460 : case ATTR_SERIAL_NUMBER:
461 3061 : attr->serial_number = pos;
462 3061 : attr->serial_number_len = len;
463 3061 : break;
464 : case ATTR_DEV_NAME:
465 5326 : attr->dev_name = pos;
466 5326 : attr->dev_name_len = len;
467 5326 : break;
468 : case ATTR_PUBLIC_KEY:
469 428 : attr->public_key = pos;
470 428 : attr->public_key_len = len;
471 428 : break;
472 : case ATTR_ENCR_SETTINGS:
473 837 : attr->encr_settings = pos;
474 837 : attr->encr_settings_len = len;
475 837 : break;
476 : case ATTR_CRED:
477 164 : if (attr->num_cred >= MAX_CRED_COUNT) {
478 2 : wpa_printf(MSG_DEBUG, "WPS: Skipped Credential "
479 : "attribute (max %d credentials)",
480 : MAX_CRED_COUNT);
481 2 : break;
482 : }
483 162 : attr->cred[attr->num_cred] = pos;
484 162 : attr->cred_len[attr->num_cred] = len;
485 162 : attr->num_cred++;
486 162 : break;
487 : case ATTR_SSID:
488 192 : attr->ssid = pos;
489 192 : attr->ssid_len = len;
490 192 : break;
491 : case ATTR_NETWORK_KEY:
492 184 : attr->network_key = pos;
493 184 : attr->network_key_len = len;
494 184 : break;
495 : case ATTR_AP_SETUP_LOCKED:
496 27 : if (len != 1) {
497 1 : wpa_printf(MSG_DEBUG, "WPS: Invalid AP Setup Locked "
498 : "length %u", len);
499 1 : return -1;
500 : }
501 26 : attr->ap_setup_locked = pos;
502 26 : break;
503 : case ATTR_REQUESTED_DEV_TYPE:
504 39 : if (len != WPS_DEV_TYPE_LEN) {
505 2 : wpa_printf(MSG_DEBUG, "WPS: Invalid Requested Device "
506 : "Type length %u", len);
507 2 : return -1;
508 : }
509 37 : if (attr->num_req_dev_type >= MAX_REQ_DEV_TYPE_COUNT) {
510 2 : wpa_printf(MSG_DEBUG, "WPS: Skipped Requested Device "
511 : "Type attribute (max %u types)",
512 : MAX_REQ_DEV_TYPE_COUNT);
513 2 : break;
514 : }
515 35 : attr->req_dev_type[attr->num_req_dev_type] = pos;
516 35 : attr->num_req_dev_type++;
517 35 : break;
518 : case ATTR_SECONDARY_DEV_TYPE_LIST:
519 379 : if (len > WPS_SEC_DEV_TYPE_MAX_LEN ||
520 189 : (len % WPS_DEV_TYPE_LEN) > 0) {
521 2 : wpa_printf(MSG_DEBUG, "WPS: Invalid Secondary Device "
522 : "Type length %u", len);
523 2 : return -1;
524 : }
525 188 : attr->sec_dev_type_list = pos;
526 188 : attr->sec_dev_type_list_len = len;
527 188 : break;
528 : case ATTR_VENDOR_EXT:
529 7368 : if (wps_parse_vendor_ext(attr, pos, len) < 0)
530 6 : return -1;
531 7362 : break;
532 : case ATTR_AP_CHANNEL:
533 13 : if (len != 2) {
534 1 : wpa_printf(MSG_DEBUG, "WPS: Invalid AP Channel "
535 : "length %u", len);
536 1 : return -1;
537 : }
538 12 : attr->ap_channel = pos;
539 12 : break;
540 : default:
541 22 : wpa_printf(MSG_DEBUG, "WPS: Unsupported attribute type 0x%x "
542 : "len=%u", type, len);
543 22 : break;
544 : }
545 :
546 90128 : return 0;
547 : }
548 :
549 :
550 8570 : int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr)
551 : {
552 : const u8 *pos, *end;
553 : u16 type, len;
554 : #ifdef WPS_WORKAROUNDS
555 8570 : u16 prev_type = 0;
556 : #endif /* WPS_WORKAROUNDS */
557 :
558 8570 : os_memset(attr, 0, sizeof(*attr));
559 8570 : pos = wpabuf_head(msg);
560 8570 : end = pos + wpabuf_len(msg);
561 :
562 107269 : while (pos < end) {
563 90204 : if (end - pos < 4) {
564 5 : wpa_printf(MSG_DEBUG, "WPS: Invalid message - "
565 : "%lu bytes remaining",
566 5 : (unsigned long) (end - pos));
567 5 : return -1;
568 : }
569 :
570 90199 : type = WPA_GET_BE16(pos);
571 90199 : pos += 2;
572 90199 : len = WPA_GET_BE16(pos);
573 90199 : pos += 2;
574 90199 : wpa_printf(MSG_EXCESSIVE, "WPS: attr type=0x%x len=%u",
575 : type, len);
576 90199 : if (len > end - pos) {
577 6 : wpa_printf(MSG_DEBUG, "WPS: Attribute overflow");
578 6 : wpa_hexdump_buf(MSG_MSGDUMP, "WPS: Message data", msg);
579 : #ifdef WPS_WORKAROUNDS
580 : /*
581 : * Some deployed APs seem to have a bug in encoding of
582 : * Network Key attribute in the Credential attribute
583 : * where they add an extra octet after the Network Key
584 : * attribute at least when open network is being
585 : * provisioned.
586 : */
587 6 : if ((type & 0xff00) != 0x1000 &&
588 : prev_type == ATTR_NETWORK_KEY) {
589 1 : wpa_printf(MSG_DEBUG, "WPS: Workaround - try "
590 : "to skip unexpected octet after "
591 : "Network Key");
592 1 : pos -= 3;
593 1 : continue;
594 : }
595 : #endif /* WPS_WORKAROUNDS */
596 5 : return -1;
597 : }
598 :
599 : #ifdef WPS_WORKAROUNDS
600 90193 : if (type == 0 && len == 0) {
601 : /*
602 : * Mac OS X 10.6 seems to be adding 0x00 padding to the
603 : * end of M1. Skip those to avoid interop issues.
604 : */
605 : int i;
606 6 : for (i = 0; i < end - pos; i++) {
607 5 : if (pos[i])
608 1 : break;
609 : }
610 2 : if (i == end - pos) {
611 1 : wpa_printf(MSG_DEBUG, "WPS: Workaround - skip "
612 : "unexpected message padding");
613 1 : break;
614 : }
615 : }
616 : #endif /* WPS_WORKAROUNDS */
617 :
618 90192 : if (wps_set_attr(attr, type, pos, len) < 0)
619 64 : return -1;
620 :
621 : #ifdef WPS_WORKAROUNDS
622 90128 : prev_type = type;
623 : #endif /* WPS_WORKAROUNDS */
624 90128 : pos += len;
625 : }
626 :
627 8496 : return 0;
628 : }
|