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.
21 static int wps_set_attr(struct wps_parse_attr
*attr
, u16 type
,
22 const u8
*pos
, u16 len
)
27 wpa_printf(MSG_DEBUG
, "WPS: Invalid Version length %u",
35 wpa_printf(MSG_DEBUG
, "WPS: Invalid Message Type "
41 case ATTR_ENROLLEE_NONCE
:
42 if (len
!= WPS_NONCE_LEN
) {
43 wpa_printf(MSG_DEBUG
, "WPS: Invalid Enrollee Nonce "
47 attr
->enrollee_nonce
= pos
;
49 case ATTR_REGISTRAR_NONCE
:
50 if (len
!= WPS_NONCE_LEN
) {
51 wpa_printf(MSG_DEBUG
, "WPS: Invalid Registrar Nonce "
55 attr
->registrar_nonce
= pos
;
58 if (len
!= WPS_UUID_LEN
) {
59 wpa_printf(MSG_DEBUG
, "WPS: Invalid UUID-E length %u",
66 if (len
!= WPS_UUID_LEN
) {
67 wpa_printf(MSG_DEBUG
, "WPS: Invalid UUID-R length %u",
73 case ATTR_AUTH_TYPE_FLAGS
:
75 wpa_printf(MSG_DEBUG
, "WPS: Invalid Authentication "
76 "Type Flags length %u", len
);
79 attr
->auth_type_flags
= pos
;
81 case ATTR_ENCR_TYPE_FLAGS
:
83 wpa_printf(MSG_DEBUG
, "WPS: Invalid Encryption Type "
84 "Flags length %u", len
);
87 attr
->encr_type_flags
= pos
;
89 case ATTR_CONN_TYPE_FLAGS
:
91 wpa_printf(MSG_DEBUG
, "WPS: Invalid Connection Type "
92 "Flags length %u", len
);
95 attr
->conn_type_flags
= pos
;
97 case ATTR_CONFIG_METHODS
:
99 wpa_printf(MSG_DEBUG
, "WPS: Invalid Config Methods "
103 attr
->config_methods
= pos
;
105 case ATTR_SELECTED_REGISTRAR_CONFIG_METHODS
:
107 wpa_printf(MSG_DEBUG
, "WPS: Invalid Selected "
108 "Registrar Config Methods length %u", len
);
111 attr
->sel_reg_config_methods
= pos
;
113 case ATTR_PRIMARY_DEV_TYPE
:
114 if (len
!= WPS_DEV_TYPE_LEN
) {
115 wpa_printf(MSG_DEBUG
, "WPS: Invalid Primary Device "
116 "Type length %u", len
);
119 attr
->primary_dev_type
= pos
;
123 wpa_printf(MSG_DEBUG
, "WPS: Invalid RF Bands length "
127 attr
->rf_bands
= pos
;
129 case ATTR_ASSOC_STATE
:
131 wpa_printf(MSG_DEBUG
, "WPS: Invalid Association State "
135 attr
->assoc_state
= pos
;
137 case ATTR_CONFIG_ERROR
:
139 wpa_printf(MSG_DEBUG
, "WPS: Invalid Configuration "
140 "Error length %u", len
);
143 attr
->config_error
= pos
;
145 case ATTR_DEV_PASSWORD_ID
:
147 wpa_printf(MSG_DEBUG
, "WPS: Invalid Device Password "
148 "ID length %u", len
);
151 attr
->dev_password_id
= pos
;
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
);
159 attr
->oob_dev_password
= pos
;
161 case ATTR_OS_VERSION
:
163 wpa_printf(MSG_DEBUG
, "WPS: Invalid OS Version length "
167 attr
->os_version
= pos
;
171 wpa_printf(MSG_DEBUG
, "WPS: Invalid Wi-Fi Protected "
172 "Setup State length %u", len
);
175 attr
->wps_state
= pos
;
177 case ATTR_AUTHENTICATOR
:
178 if (len
!= WPS_AUTHENTICATOR_LEN
) {
179 wpa_printf(MSG_DEBUG
, "WPS: Invalid Authenticator "
183 attr
->authenticator
= pos
;
186 if (len
!= WPS_HASH_LEN
) {
187 wpa_printf(MSG_DEBUG
, "WPS: Invalid R-Hash1 length %u",
194 if (len
!= WPS_HASH_LEN
) {
195 wpa_printf(MSG_DEBUG
, "WPS: Invalid R-Hash2 length %u",
202 if (len
!= WPS_HASH_LEN
) {
203 wpa_printf(MSG_DEBUG
, "WPS: Invalid E-Hash1 length %u",
210 if (len
!= WPS_HASH_LEN
) {
211 wpa_printf(MSG_DEBUG
, "WPS: Invalid E-Hash2 length %u",
218 if (len
!= WPS_SECRET_NONCE_LEN
) {
219 wpa_printf(MSG_DEBUG
, "WPS: Invalid R-SNonce1 length "
223 attr
->r_snonce1
= pos
;
226 if (len
!= WPS_SECRET_NONCE_LEN
) {
227 wpa_printf(MSG_DEBUG
, "WPS: Invalid R-SNonce2 length "
231 attr
->r_snonce2
= pos
;
234 if (len
!= WPS_SECRET_NONCE_LEN
) {
235 wpa_printf(MSG_DEBUG
, "WPS: Invalid E-SNonce1 length "
239 attr
->e_snonce1
= pos
;
242 if (len
!= WPS_SECRET_NONCE_LEN
) {
243 wpa_printf(MSG_DEBUG
, "WPS: Invalid E-SNonce2 length "
247 attr
->e_snonce2
= pos
;
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
);
255 attr
->key_wrap_auth
= pos
;
259 wpa_printf(MSG_DEBUG
, "WPS: Invalid Authentication "
260 "Type length %u", len
);
263 attr
->auth_type
= pos
;
267 wpa_printf(MSG_DEBUG
, "WPS: Invalid Encryption "
268 "Type length %u", len
);
271 attr
->encr_type
= pos
;
273 case ATTR_NETWORK_INDEX
:
275 wpa_printf(MSG_DEBUG
, "WPS: Invalid Network Index "
279 attr
->network_idx
= pos
;
281 case ATTR_NETWORK_KEY_INDEX
:
283 wpa_printf(MSG_DEBUG
, "WPS: Invalid Network Key Index "
287 attr
->network_key_idx
= pos
;
290 if (len
!= ETH_ALEN
) {
291 wpa_printf(MSG_DEBUG
, "WPS: Invalid MAC Address "
295 attr
->mac_addr
= pos
;
297 case ATTR_KEY_PROVIDED_AUTO
:
299 wpa_printf(MSG_DEBUG
, "WPS: Invalid Key Provided "
300 "Automatically length %u", len
);
303 attr
->key_prov_auto
= pos
;
305 case ATTR_802_1X_ENABLED
:
307 wpa_printf(MSG_DEBUG
, "WPS: Invalid 802.1X Enabled "
311 attr
->dot1x_enabled
= pos
;
313 case ATTR_SELECTED_REGISTRAR
:
315 wpa_printf(MSG_DEBUG
, "WPS: Invalid Selected Registrar"
319 attr
->selected_registrar
= pos
;
321 case ATTR_REQUEST_TYPE
:
323 wpa_printf(MSG_DEBUG
, "WPS: Invalid Request Type "
327 attr
->request_type
= pos
;
329 case ATTR_RESPONSE_TYPE
:
331 wpa_printf(MSG_DEBUG
, "WPS: Invalid Response Type "
335 attr
->request_type
= pos
;
337 case ATTR_MANUFACTURER
:
338 attr
->manufacturer
= pos
;
339 attr
->manufacturer_len
= len
;
341 case ATTR_MODEL_NAME
:
342 attr
->model_name
= pos
;
343 attr
->model_name_len
= len
;
345 case ATTR_MODEL_NUMBER
:
346 attr
->model_number
= pos
;
347 attr
->model_number_len
= len
;
349 case ATTR_SERIAL_NUMBER
:
350 attr
->serial_number
= pos
;
351 attr
->serial_number_len
= len
;
354 attr
->dev_name
= pos
;
355 attr
->dev_name_len
= len
;
357 case ATTR_PUBLIC_KEY
:
358 attr
->public_key
= pos
;
359 attr
->public_key_len
= len
;
361 case ATTR_ENCR_SETTINGS
:
362 attr
->encr_settings
= pos
;
363 attr
->encr_settings_len
= len
;
366 if (attr
->num_cred
>= MAX_CRED_COUNT
) {
367 wpa_printf(MSG_DEBUG
, "WPS: Skipped Credential "
368 "attribute (max %d credentials)",
372 attr
->cred
[attr
->num_cred
] = pos
;
373 attr
->cred_len
[attr
->num_cred
] = len
;
378 attr
->ssid_len
= len
;
380 case ATTR_NETWORK_KEY
:
381 attr
->network_key
= pos
;
382 attr
->network_key_len
= len
;
385 attr
->eap_type
= pos
;
386 attr
->eap_type_len
= len
;
388 case ATTR_EAP_IDENTITY
:
389 attr
->eap_identity
= pos
;
390 attr
->eap_identity_len
= len
;
392 case ATTR_AP_SETUP_LOCKED
:
394 wpa_printf(MSG_DEBUG
, "WPS: Invalid AP Setup Locked "
398 attr
->ap_setup_locked
= pos
;
401 wpa_printf(MSG_DEBUG
, "WPS: Unsupported attribute type 0x%x "
402 "len=%u", type
, len
);
410 int wps_parse_msg(const struct wpabuf
*msg
, struct wps_parse_attr
*attr
)
415 os_memset(attr
, 0, sizeof(*attr
));
416 pos
= wpabuf_head(msg
);
417 end
= pos
+ wpabuf_len(msg
);
421 wpa_printf(MSG_DEBUG
, "WPS: Invalid message - "
422 "%lu bytes remaining",
423 (unsigned long) (end
- pos
));
427 type
= WPA_GET_BE16(pos
);
429 len
= WPA_GET_BE16(pos
);
431 wpa_printf(MSG_MSGDUMP
, "WPS: attr type=0x%x len=%u",
433 if (len
> end
- pos
) {
434 wpa_printf(MSG_DEBUG
, "WPS: Attribute overflow");
438 if (wps_set_attr(attr
, type
, pos
, len
) < 0)