2 * Wi-Fi Protected Setup - attribute parsing
3 * Copyright (c) 2008, Jouni Malinen <j@w1.fi>
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.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
20 #ifndef CONFIG_WPS_STRICT
21 #define WPS_WORKAROUNDS
22 #endif /* CONFIG_WPS_STRICT */
25 static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
26 const u8 *pos, u16 len)
31 wpa_printf(MSG_DEBUG, "WPS: Invalid Version length %u",
39 wpa_printf(MSG_DEBUG, "WPS: Invalid Version2 length "
47 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type "
53 case ATTR_ENROLLEE_NONCE:
54 if (len != WPS_NONCE_LEN) {
55 wpa_printf(MSG_DEBUG, "WPS: Invalid Enrollee Nonce "
59 attr->enrollee_nonce = pos;
61 case ATTR_REGISTRAR_NONCE:
62 if (len != WPS_NONCE_LEN) {
63 wpa_printf(MSG_DEBUG, "WPS: Invalid Registrar Nonce "
67 attr->registrar_nonce = pos;
70 if (len != WPS_UUID_LEN) {
71 wpa_printf(MSG_DEBUG, "WPS: Invalid UUID-E length %u",
78 if (len != WPS_UUID_LEN) {
79 wpa_printf(MSG_DEBUG, "WPS: Invalid UUID-R length %u",
85 case ATTR_AUTH_TYPE_FLAGS:
87 wpa_printf(MSG_DEBUG, "WPS: Invalid Authentication "
88 "Type Flags length %u", len);
91 attr->auth_type_flags = pos;
93 case ATTR_ENCR_TYPE_FLAGS:
95 wpa_printf(MSG_DEBUG, "WPS: Invalid Encryption Type "
96 "Flags length %u", len);
99 attr->encr_type_flags = pos;
101 case ATTR_CONN_TYPE_FLAGS:
103 wpa_printf(MSG_DEBUG, "WPS: Invalid Connection Type "
104 "Flags length %u", len);
107 attr->conn_type_flags = pos;
109 case ATTR_CONFIG_METHODS:
111 wpa_printf(MSG_DEBUG, "WPS: Invalid Config Methods "
115 attr->config_methods = pos;
117 case ATTR_SELECTED_REGISTRAR_CONFIG_METHODS:
119 wpa_printf(MSG_DEBUG, "WPS: Invalid Selected "
120 "Registrar Config Methods length %u", len);
123 attr->sel_reg_config_methods = pos;
125 case ATTR_PRIMARY_DEV_TYPE:
126 if (len != WPS_DEV_TYPE_LEN) {
127 wpa_printf(MSG_DEBUG, "WPS: Invalid Primary Device "
128 "Type length %u", len);
131 attr->primary_dev_type = pos;
135 wpa_printf(MSG_DEBUG, "WPS: Invalid RF Bands length "
139 attr->rf_bands = pos;
141 case ATTR_ASSOC_STATE:
143 wpa_printf(MSG_DEBUG, "WPS: Invalid Association State "
147 attr->assoc_state = pos;
149 case ATTR_CONFIG_ERROR:
151 wpa_printf(MSG_DEBUG, "WPS: Invalid Configuration "
152 "Error length %u", len);
155 attr->config_error = pos;
157 case ATTR_DEV_PASSWORD_ID:
159 wpa_printf(MSG_DEBUG, "WPS: Invalid Device Password "
160 "ID length %u", len);
163 attr->dev_password_id = pos;
165 case ATTR_OOB_DEVICE_PASSWORD:
166 if (len != WPS_OOB_DEVICE_PASSWORD_ATTR_LEN) {
167 wpa_printf(MSG_DEBUG, "WPS: Invalid OOB Device "
168 "Password length %u", len);
171 attr->oob_dev_password = pos;
173 case ATTR_OS_VERSION:
175 wpa_printf(MSG_DEBUG, "WPS: Invalid OS Version length "
179 attr->os_version = pos;
183 wpa_printf(MSG_DEBUG, "WPS: Invalid Wi-Fi Protected "
184 "Setup State length %u", len);
187 attr->wps_state = pos;
189 case ATTR_AUTHENTICATOR:
190 if (len != WPS_AUTHENTICATOR_LEN) {
191 wpa_printf(MSG_DEBUG, "WPS: Invalid Authenticator "
195 attr->authenticator = pos;
198 if (len != WPS_HASH_LEN) {
199 wpa_printf(MSG_DEBUG, "WPS: Invalid R-Hash1 length %u",
206 if (len != WPS_HASH_LEN) {
207 wpa_printf(MSG_DEBUG, "WPS: Invalid R-Hash2 length %u",
214 if (len != WPS_HASH_LEN) {
215 wpa_printf(MSG_DEBUG, "WPS: Invalid E-Hash1 length %u",
222 if (len != WPS_HASH_LEN) {
223 wpa_printf(MSG_DEBUG, "WPS: Invalid E-Hash2 length %u",
230 if (len != WPS_SECRET_NONCE_LEN) {
231 wpa_printf(MSG_DEBUG, "WPS: Invalid R-SNonce1 length "
235 attr->r_snonce1 = pos;
238 if (len != WPS_SECRET_NONCE_LEN) {
239 wpa_printf(MSG_DEBUG, "WPS: Invalid R-SNonce2 length "
243 attr->r_snonce2 = pos;
246 if (len != WPS_SECRET_NONCE_LEN) {
247 wpa_printf(MSG_DEBUG, "WPS: Invalid E-SNonce1 length "
251 attr->e_snonce1 = pos;
254 if (len != WPS_SECRET_NONCE_LEN) {
255 wpa_printf(MSG_DEBUG, "WPS: Invalid E-SNonce2 length "
259 attr->e_snonce2 = pos;
261 case ATTR_KEY_WRAP_AUTH:
262 if (len != WPS_KWA_LEN) {
263 wpa_printf(MSG_DEBUG, "WPS: Invalid Key Wrap "
264 "Authenticator length %u", len);
267 attr->key_wrap_auth = pos;
271 wpa_printf(MSG_DEBUG, "WPS: Invalid Authentication "
272 "Type length %u", len);
275 attr->auth_type = pos;
279 wpa_printf(MSG_DEBUG, "WPS: Invalid Encryption "
280 "Type length %u", len);
283 attr->encr_type = pos;
285 case ATTR_NETWORK_INDEX:
287 wpa_printf(MSG_DEBUG, "WPS: Invalid Network Index "
291 attr->network_idx = pos;
293 case ATTR_NETWORK_KEY_INDEX:
295 wpa_printf(MSG_DEBUG, "WPS: Invalid Network Key Index "
299 attr->network_key_idx = pos;
302 if (len != ETH_ALEN) {
303 wpa_printf(MSG_DEBUG, "WPS: Invalid MAC Address "
307 attr->mac_addr = pos;
309 case ATTR_KEY_PROVIDED_AUTO:
311 wpa_printf(MSG_DEBUG, "WPS: Invalid Key Provided "
312 "Automatically length %u", len);
315 attr->key_prov_auto = pos;
317 case ATTR_802_1X_ENABLED:
319 wpa_printf(MSG_DEBUG, "WPS: Invalid 802.1X Enabled "
323 attr->dot1x_enabled = pos;
325 case ATTR_SELECTED_REGISTRAR:
327 wpa_printf(MSG_DEBUG, "WPS: Invalid Selected Registrar"
331 attr->selected_registrar = pos;
333 case ATTR_REQUEST_TYPE:
335 wpa_printf(MSG_DEBUG, "WPS: Invalid Request Type "
339 attr->request_type = pos;
341 case ATTR_RESPONSE_TYPE:
343 wpa_printf(MSG_DEBUG, "WPS: Invalid Response Type "
347 attr->response_type = pos;
349 case ATTR_MANUFACTURER:
350 attr->manufacturer = pos;
351 attr->manufacturer_len = len;
353 case ATTR_MODEL_NAME:
354 attr->model_name = pos;
355 attr->model_name_len = len;
357 case ATTR_MODEL_NUMBER:
358 attr->model_number = pos;
359 attr->model_number_len = len;
361 case ATTR_SERIAL_NUMBER:
362 attr->serial_number = pos;
363 attr->serial_number_len = len;
366 attr->dev_name = pos;
367 attr->dev_name_len = len;
369 case ATTR_PUBLIC_KEY:
370 attr->public_key = pos;
371 attr->public_key_len = len;
373 case ATTR_ENCR_SETTINGS:
374 attr->encr_settings = pos;
375 attr->encr_settings_len = len;
378 if (attr->num_cred >= MAX_CRED_COUNT) {
379 wpa_printf(MSG_DEBUG, "WPS: Skipped Credential "
380 "attribute (max %d credentials)",
384 attr->cred[attr->num_cred] = pos;
385 attr->cred_len[attr->num_cred] = len;
390 attr->ssid_len = len;
392 case ATTR_NETWORK_KEY:
393 attr->network_key = pos;
394 attr->network_key_len = len;
397 attr->eap_type = pos;
398 attr->eap_type_len = len;
400 case ATTR_EAP_IDENTITY:
401 attr->eap_identity = pos;
402 attr->eap_identity_len = len;
404 case ATTR_AP_SETUP_LOCKED:
406 wpa_printf(MSG_DEBUG, "WPS: Invalid AP Setup Locked "
410 attr->ap_setup_locked = pos;
412 case ATTR_SETTINGS_DELAY_TIME:
414 wpa_printf(MSG_DEBUG, "WPS: Invalid Settings Delay "
415 "Time length %u", len);
418 attr->settings_delay_time = pos;
420 case ATTR_NETWORK_KEY_SHAREABLE:
422 wpa_printf(MSG_DEBUG, "WPS: Invalid Network Key "
423 "Shareable length %u", len);
426 attr->network_key_shareable = pos;
428 case ATTR_REQUEST_TO_ENROLL:
430 wpa_printf(MSG_DEBUG, "WPS: Invalid Request to Enroll "
434 attr->request_to_enroll = pos;
436 case ATTR_AUTHORIZED_MACS:
437 attr->authorized_macs = pos;
438 attr->authorized_macs_len = len;
440 case ATTR_REQUESTED_DEV_TYPE:
441 if (len != WPS_DEV_TYPE_LEN) {
442 wpa_printf(MSG_DEBUG, "WPS: Invalid Requested Device "
443 "Type length %u", len);
446 if (attr->num_req_dev_type >= MAX_REQ_DEV_TYPE_COUNT) {
447 wpa_printf(MSG_DEBUG, "WPS: Skipped Requested Device "
448 "Type attribute (max %u types)",
449 MAX_REQ_DEV_TYPE_COUNT);
452 attr->req_dev_type[attr->num_req_dev_type] = pos;
453 attr->num_req_dev_type++;
456 wpa_printf(MSG_DEBUG, "WPS: Unsupported attribute type 0x%x "
457 "len=%u", type, len);
465 int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr)
470 os_memset(attr, 0, sizeof(*attr));
471 pos = wpabuf_head(msg);
472 end = pos + wpabuf_len(msg);
476 wpa_printf(MSG_DEBUG, "WPS: Invalid message - "
477 "%lu bytes remaining",
478 (unsigned long) (end - pos));
482 type = WPA_GET_BE16(pos);
484 len = WPA_GET_BE16(pos);
486 wpa_printf(MSG_MSGDUMP, "WPS: attr type=0x%x len=%u",
488 if (len > end - pos) {
489 wpa_printf(MSG_DEBUG, "WPS: Attribute overflow");
493 #ifdef WPS_WORKAROUNDS
494 if (type == 0 && len == 0) {
496 * Mac OS X 10.6 seems to be adding 0x00 padding to the
497 * end of M1. Skip those to avoid interop issues.
500 for (i = 0; i < end - pos; i++) {
504 if (i == end - pos) {
505 wpa_printf(MSG_DEBUG, "WPS: Workaround - skip "
506 "unexpected message padding");
510 #endif /* WPS_WORKAROUNDS */
512 if (wps_set_attr(attr, type, pos, len) < 0)