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 #define WPS_WORKAROUNDS
23 static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
24 const u8 *pos, u16 len)
29 wpa_printf(MSG_DEBUG, "WPS: Invalid Version length %u",
37 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type "
43 case ATTR_ENROLLEE_NONCE:
44 if (len != WPS_NONCE_LEN) {
45 wpa_printf(MSG_DEBUG, "WPS: Invalid Enrollee Nonce "
49 attr->enrollee_nonce = pos;
51 case ATTR_REGISTRAR_NONCE:
52 if (len != WPS_NONCE_LEN) {
53 wpa_printf(MSG_DEBUG, "WPS: Invalid Registrar Nonce "
57 attr->registrar_nonce = pos;
60 if (len != WPS_UUID_LEN) {
61 wpa_printf(MSG_DEBUG, "WPS: Invalid UUID-E length %u",
68 if (len != WPS_UUID_LEN) {
69 wpa_printf(MSG_DEBUG, "WPS: Invalid UUID-R length %u",
75 case ATTR_AUTH_TYPE_FLAGS:
77 wpa_printf(MSG_DEBUG, "WPS: Invalid Authentication "
78 "Type Flags length %u", len);
81 attr->auth_type_flags = pos;
83 case ATTR_ENCR_TYPE_FLAGS:
85 wpa_printf(MSG_DEBUG, "WPS: Invalid Encryption Type "
86 "Flags length %u", len);
89 attr->encr_type_flags = pos;
91 case ATTR_CONN_TYPE_FLAGS:
93 wpa_printf(MSG_DEBUG, "WPS: Invalid Connection Type "
94 "Flags length %u", len);
97 attr->conn_type_flags = pos;
99 case ATTR_CONFIG_METHODS:
101 wpa_printf(MSG_DEBUG, "WPS: Invalid Config Methods "
105 attr->config_methods = pos;
107 case ATTR_SELECTED_REGISTRAR_CONFIG_METHODS:
109 wpa_printf(MSG_DEBUG, "WPS: Invalid Selected "
110 "Registrar Config Methods length %u", len);
113 attr->sel_reg_config_methods = pos;
115 case ATTR_PRIMARY_DEV_TYPE:
116 if (len != WPS_DEV_TYPE_LEN) {
117 wpa_printf(MSG_DEBUG, "WPS: Invalid Primary Device "
118 "Type length %u", len);
121 attr->primary_dev_type = pos;
125 wpa_printf(MSG_DEBUG, "WPS: Invalid RF Bands length "
129 attr->rf_bands = pos;
131 case ATTR_ASSOC_STATE:
133 wpa_printf(MSG_DEBUG, "WPS: Invalid Association State "
137 attr->assoc_state = pos;
139 case ATTR_CONFIG_ERROR:
141 wpa_printf(MSG_DEBUG, "WPS: Invalid Configuration "
142 "Error length %u", len);
145 attr->config_error = pos;
147 case ATTR_DEV_PASSWORD_ID:
149 wpa_printf(MSG_DEBUG, "WPS: Invalid Device Password "
150 "ID length %u", len);
153 attr->dev_password_id = pos;
155 case ATTR_OOB_DEVICE_PASSWORD:
156 if (len != WPS_OOB_DEVICE_PASSWORD_ATTR_LEN) {
157 wpa_printf(MSG_DEBUG, "WPS: Invalid OOB Device "
158 "Password length %u", len);
161 attr->oob_dev_password = pos;
163 case ATTR_OS_VERSION:
165 wpa_printf(MSG_DEBUG, "WPS: Invalid OS Version length "
169 attr->os_version = pos;
173 wpa_printf(MSG_DEBUG, "WPS: Invalid Wi-Fi Protected "
174 "Setup State length %u", len);
177 attr->wps_state = pos;
179 case ATTR_AUTHENTICATOR:
180 if (len != WPS_AUTHENTICATOR_LEN) {
181 wpa_printf(MSG_DEBUG, "WPS: Invalid Authenticator "
185 attr->authenticator = pos;
188 if (len != WPS_HASH_LEN) {
189 wpa_printf(MSG_DEBUG, "WPS: Invalid R-Hash1 length %u",
196 if (len != WPS_HASH_LEN) {
197 wpa_printf(MSG_DEBUG, "WPS: Invalid R-Hash2 length %u",
204 if (len != WPS_HASH_LEN) {
205 wpa_printf(MSG_DEBUG, "WPS: Invalid E-Hash1 length %u",
212 if (len != WPS_HASH_LEN) {
213 wpa_printf(MSG_DEBUG, "WPS: Invalid E-Hash2 length %u",
220 if (len != WPS_SECRET_NONCE_LEN) {
221 wpa_printf(MSG_DEBUG, "WPS: Invalid R-SNonce1 length "
225 attr->r_snonce1 = pos;
228 if (len != WPS_SECRET_NONCE_LEN) {
229 wpa_printf(MSG_DEBUG, "WPS: Invalid R-SNonce2 length "
233 attr->r_snonce2 = pos;
236 if (len != WPS_SECRET_NONCE_LEN) {
237 wpa_printf(MSG_DEBUG, "WPS: Invalid E-SNonce1 length "
241 attr->e_snonce1 = pos;
244 if (len != WPS_SECRET_NONCE_LEN) {
245 wpa_printf(MSG_DEBUG, "WPS: Invalid E-SNonce2 length "
249 attr->e_snonce2 = pos;
251 case ATTR_KEY_WRAP_AUTH:
252 if (len != WPS_KWA_LEN) {
253 wpa_printf(MSG_DEBUG, "WPS: Invalid Key Wrap "
254 "Authenticator length %u", len);
257 attr->key_wrap_auth = pos;
261 wpa_printf(MSG_DEBUG, "WPS: Invalid Authentication "
262 "Type length %u", len);
265 attr->auth_type = pos;
269 wpa_printf(MSG_DEBUG, "WPS: Invalid Encryption "
270 "Type length %u", len);
273 attr->encr_type = pos;
275 case ATTR_NETWORK_INDEX:
277 wpa_printf(MSG_DEBUG, "WPS: Invalid Network Index "
281 attr->network_idx = pos;
283 case ATTR_NETWORK_KEY_INDEX:
285 wpa_printf(MSG_DEBUG, "WPS: Invalid Network Key Index "
289 attr->network_key_idx = pos;
292 if (len != ETH_ALEN) {
293 wpa_printf(MSG_DEBUG, "WPS: Invalid MAC Address "
297 attr->mac_addr = pos;
299 case ATTR_KEY_PROVIDED_AUTO:
301 wpa_printf(MSG_DEBUG, "WPS: Invalid Key Provided "
302 "Automatically length %u", len);
305 attr->key_prov_auto = pos;
307 case ATTR_802_1X_ENABLED:
309 wpa_printf(MSG_DEBUG, "WPS: Invalid 802.1X Enabled "
313 attr->dot1x_enabled = pos;
315 case ATTR_SELECTED_REGISTRAR:
317 wpa_printf(MSG_DEBUG, "WPS: Invalid Selected Registrar"
321 attr->selected_registrar = pos;
323 case ATTR_REQUEST_TYPE:
325 wpa_printf(MSG_DEBUG, "WPS: Invalid Request Type "
329 attr->request_type = pos;
331 case ATTR_RESPONSE_TYPE:
333 wpa_printf(MSG_DEBUG, "WPS: Invalid Response Type "
337 attr->response_type = pos;
339 case ATTR_MANUFACTURER:
340 attr->manufacturer = pos;
341 attr->manufacturer_len = len;
343 case ATTR_MODEL_NAME:
344 attr->model_name = pos;
345 attr->model_name_len = len;
347 case ATTR_MODEL_NUMBER:
348 attr->model_number = pos;
349 attr->model_number_len = len;
351 case ATTR_SERIAL_NUMBER:
352 attr->serial_number = pos;
353 attr->serial_number_len = len;
356 attr->dev_name = pos;
357 attr->dev_name_len = len;
359 case ATTR_PUBLIC_KEY:
360 attr->public_key = pos;
361 attr->public_key_len = len;
363 case ATTR_ENCR_SETTINGS:
364 attr->encr_settings = pos;
365 attr->encr_settings_len = len;
368 if (attr->num_cred >= MAX_CRED_COUNT) {
369 wpa_printf(MSG_DEBUG, "WPS: Skipped Credential "
370 "attribute (max %d credentials)",
374 attr->cred[attr->num_cred] = pos;
375 attr->cred_len[attr->num_cred] = len;
380 attr->ssid_len = len;
382 case ATTR_NETWORK_KEY:
383 attr->network_key = pos;
384 attr->network_key_len = len;
387 attr->eap_type = pos;
388 attr->eap_type_len = len;
390 case ATTR_EAP_IDENTITY:
391 attr->eap_identity = pos;
392 attr->eap_identity_len = len;
394 case ATTR_AP_SETUP_LOCKED:
396 wpa_printf(MSG_DEBUG, "WPS: Invalid AP Setup Locked "
400 attr->ap_setup_locked = pos;
403 wpa_printf(MSG_DEBUG, "WPS: Unsupported attribute type 0x%x "
404 "len=%u", type, len);
412 int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr)
417 os_memset(attr, 0, sizeof(*attr));
418 pos = wpabuf_head(msg);
419 end = pos + wpabuf_len(msg);
423 wpa_printf(MSG_DEBUG, "WPS: Invalid message - "
424 "%lu bytes remaining",
425 (unsigned long) (end - pos));
429 type = WPA_GET_BE16(pos);
431 len = WPA_GET_BE16(pos);
433 wpa_printf(MSG_MSGDUMP, "WPS: attr type=0x%x len=%u",
435 if (len > end - pos) {
436 wpa_printf(MSG_DEBUG, "WPS: Attribute overflow");
440 #ifdef WPS_WORKAROUNDS
441 if (type == 0 && len == 0) {
443 * Mac OS X 10.6 seems to be adding 0x00 padding to the
444 * end of M1. Skip those to avoid interop issues.
447 for (i = 0; i < end - pos; i++) {
451 if (i == end - pos) {
452 wpa_printf(MSG_DEBUG, "WPS: Workaround - skip "
453 "unexpected message padding");
457 #endif /* WPS_WORKAROUNDS */
459 if (wps_set_attr(attr, type, pos, len) < 0)