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)