xref: /freebsd/contrib/wpa/src/wps/wps_attr_parse.c (revision 39beb93c3f8bdbf72a61fda42300b5ebed7390c8)
139beb93cSSam Leffler /*
239beb93cSSam Leffler  * Wi-Fi Protected Setup - attribute parsing
339beb93cSSam Leffler  * Copyright (c) 2008, Jouni Malinen <j@w1.fi>
439beb93cSSam Leffler  *
539beb93cSSam Leffler  * This program is free software; you can redistribute it and/or modify
639beb93cSSam Leffler  * it under the terms of the GNU General Public License version 2 as
739beb93cSSam Leffler  * published by the Free Software Foundation.
839beb93cSSam Leffler  *
939beb93cSSam Leffler  * Alternatively, this software may be distributed under the terms of BSD
1039beb93cSSam Leffler  * license.
1139beb93cSSam Leffler  *
1239beb93cSSam Leffler  * See README and COPYING for more details.
1339beb93cSSam Leffler  */
1439beb93cSSam Leffler 
1539beb93cSSam Leffler #include "includes.h"
1639beb93cSSam Leffler 
1739beb93cSSam Leffler #include "common.h"
1839beb93cSSam Leffler #include "wps_i.h"
1939beb93cSSam Leffler 
2039beb93cSSam Leffler 
2139beb93cSSam Leffler static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
2239beb93cSSam Leffler 			const u8 *pos, u16 len)
2339beb93cSSam Leffler {
2439beb93cSSam Leffler 	switch (type) {
2539beb93cSSam Leffler 	case ATTR_VERSION:
2639beb93cSSam Leffler 		if (len != 1) {
2739beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid Version length %u",
2839beb93cSSam Leffler 				   len);
2939beb93cSSam Leffler 			return -1;
3039beb93cSSam Leffler 		}
3139beb93cSSam Leffler 		attr->version = pos;
3239beb93cSSam Leffler 		break;
3339beb93cSSam Leffler 	case ATTR_MSG_TYPE:
3439beb93cSSam Leffler 		if (len != 1) {
3539beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type "
3639beb93cSSam Leffler 				   "length %u", len);
3739beb93cSSam Leffler 			return -1;
3839beb93cSSam Leffler 		}
3939beb93cSSam Leffler 		attr->msg_type = pos;
4039beb93cSSam Leffler 		break;
4139beb93cSSam Leffler 	case ATTR_ENROLLEE_NONCE:
4239beb93cSSam Leffler 		if (len != WPS_NONCE_LEN) {
4339beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid Enrollee Nonce "
4439beb93cSSam Leffler 				   "length %u", len);
4539beb93cSSam Leffler 			return -1;
4639beb93cSSam Leffler 		}
4739beb93cSSam Leffler 		attr->enrollee_nonce = pos;
4839beb93cSSam Leffler 		break;
4939beb93cSSam Leffler 	case ATTR_REGISTRAR_NONCE:
5039beb93cSSam Leffler 		if (len != WPS_NONCE_LEN) {
5139beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid Registrar Nonce "
5239beb93cSSam Leffler 				   "length %u", len);
5339beb93cSSam Leffler 			return -1;
5439beb93cSSam Leffler 		}
5539beb93cSSam Leffler 		attr->registrar_nonce = pos;
5639beb93cSSam Leffler 		break;
5739beb93cSSam Leffler 	case ATTR_UUID_E:
5839beb93cSSam Leffler 		if (len != WPS_UUID_LEN) {
5939beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid UUID-E length %u",
6039beb93cSSam Leffler 				   len);
6139beb93cSSam Leffler 			return -1;
6239beb93cSSam Leffler 		}
6339beb93cSSam Leffler 		attr->uuid_e = pos;
6439beb93cSSam Leffler 		break;
6539beb93cSSam Leffler 	case ATTR_UUID_R:
6639beb93cSSam Leffler 		if (len != WPS_UUID_LEN) {
6739beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid UUID-R length %u",
6839beb93cSSam Leffler 				   len);
6939beb93cSSam Leffler 			return -1;
7039beb93cSSam Leffler 		}
7139beb93cSSam Leffler 		attr->uuid_r = pos;
7239beb93cSSam Leffler 		break;
7339beb93cSSam Leffler 	case ATTR_AUTH_TYPE_FLAGS:
7439beb93cSSam Leffler 		if (len != 2) {
7539beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid Authentication "
7639beb93cSSam Leffler 				   "Type Flags length %u", len);
7739beb93cSSam Leffler 			return -1;
7839beb93cSSam Leffler 		}
7939beb93cSSam Leffler 		attr->auth_type_flags = pos;
8039beb93cSSam Leffler 		break;
8139beb93cSSam Leffler 	case ATTR_ENCR_TYPE_FLAGS:
8239beb93cSSam Leffler 		if (len != 2) {
8339beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid Encryption Type "
8439beb93cSSam Leffler 				   "Flags length %u", len);
8539beb93cSSam Leffler 			return -1;
8639beb93cSSam Leffler 		}
8739beb93cSSam Leffler 		attr->encr_type_flags = pos;
8839beb93cSSam Leffler 		break;
8939beb93cSSam Leffler 	case ATTR_CONN_TYPE_FLAGS:
9039beb93cSSam Leffler 		if (len != 1) {
9139beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid Connection Type "
9239beb93cSSam Leffler 				   "Flags length %u", len);
9339beb93cSSam Leffler 			return -1;
9439beb93cSSam Leffler 		}
9539beb93cSSam Leffler 		attr->conn_type_flags = pos;
9639beb93cSSam Leffler 		break;
9739beb93cSSam Leffler 	case ATTR_CONFIG_METHODS:
9839beb93cSSam Leffler 		if (len != 2) {
9939beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid Config Methods "
10039beb93cSSam Leffler 				   "length %u", len);
10139beb93cSSam Leffler 			return -1;
10239beb93cSSam Leffler 		}
10339beb93cSSam Leffler 		attr->config_methods = pos;
10439beb93cSSam Leffler 		break;
10539beb93cSSam Leffler 	case ATTR_SELECTED_REGISTRAR_CONFIG_METHODS:
10639beb93cSSam Leffler 		if (len != 2) {
10739beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid Selected "
10839beb93cSSam Leffler 				   "Registrar Config Methods length %u", len);
10939beb93cSSam Leffler 			return -1;
11039beb93cSSam Leffler 		}
11139beb93cSSam Leffler 		attr->sel_reg_config_methods = pos;
11239beb93cSSam Leffler 		break;
11339beb93cSSam Leffler 	case ATTR_PRIMARY_DEV_TYPE:
11439beb93cSSam Leffler 		if (len != sizeof(struct wps_dev_type)) {
11539beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid Primary Device "
11639beb93cSSam Leffler 				   "Type length %u", len);
11739beb93cSSam Leffler 			return -1;
11839beb93cSSam Leffler 		}
11939beb93cSSam Leffler 		attr->primary_dev_type = pos;
12039beb93cSSam Leffler 		break;
12139beb93cSSam Leffler 	case ATTR_RF_BANDS:
12239beb93cSSam Leffler 		if (len != 1) {
12339beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid RF Bands length "
12439beb93cSSam Leffler 				   "%u", len);
12539beb93cSSam Leffler 			return -1;
12639beb93cSSam Leffler 		}
12739beb93cSSam Leffler 		attr->rf_bands = pos;
12839beb93cSSam Leffler 		break;
12939beb93cSSam Leffler 	case ATTR_ASSOC_STATE:
13039beb93cSSam Leffler 		if (len != 2) {
13139beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid Association State "
13239beb93cSSam Leffler 				   "length %u", len);
13339beb93cSSam Leffler 			return -1;
13439beb93cSSam Leffler 		}
13539beb93cSSam Leffler 		attr->assoc_state = pos;
13639beb93cSSam Leffler 		break;
13739beb93cSSam Leffler 	case ATTR_CONFIG_ERROR:
13839beb93cSSam Leffler 		if (len != 2) {
13939beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid Configuration "
14039beb93cSSam Leffler 				   "Error length %u", len);
14139beb93cSSam Leffler 			return -1;
14239beb93cSSam Leffler 		}
14339beb93cSSam Leffler 		attr->config_error = pos;
14439beb93cSSam Leffler 		break;
14539beb93cSSam Leffler 	case ATTR_DEV_PASSWORD_ID:
14639beb93cSSam Leffler 		if (len != 2) {
14739beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid Device Password "
14839beb93cSSam Leffler 				   "ID length %u", len);
14939beb93cSSam Leffler 			return -1;
15039beb93cSSam Leffler 		}
15139beb93cSSam Leffler 		attr->dev_password_id = pos;
15239beb93cSSam Leffler 		break;
15339beb93cSSam Leffler 	case ATTR_OS_VERSION:
15439beb93cSSam Leffler 		if (len != 4) {
15539beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid OS Version length "
15639beb93cSSam Leffler 				   "%u", len);
15739beb93cSSam Leffler 			return -1;
15839beb93cSSam Leffler 		}
15939beb93cSSam Leffler 		attr->os_version = pos;
16039beb93cSSam Leffler 		break;
16139beb93cSSam Leffler 	case ATTR_WPS_STATE:
16239beb93cSSam Leffler 		if (len != 1) {
16339beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid Wi-Fi Protected "
16439beb93cSSam Leffler 				   "Setup State length %u", len);
16539beb93cSSam Leffler 			return -1;
16639beb93cSSam Leffler 		}
16739beb93cSSam Leffler 		attr->wps_state = pos;
16839beb93cSSam Leffler 		break;
16939beb93cSSam Leffler 	case ATTR_AUTHENTICATOR:
17039beb93cSSam Leffler 		if (len != WPS_AUTHENTICATOR_LEN) {
17139beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid Authenticator "
17239beb93cSSam Leffler 				   "length %u", len);
17339beb93cSSam Leffler 			return -1;
17439beb93cSSam Leffler 		}
17539beb93cSSam Leffler 		attr->authenticator = pos;
17639beb93cSSam Leffler 		break;
17739beb93cSSam Leffler 	case ATTR_R_HASH1:
17839beb93cSSam Leffler 		if (len != WPS_HASH_LEN) {
17939beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid R-Hash1 length %u",
18039beb93cSSam Leffler 				   len);
18139beb93cSSam Leffler 			return -1;
18239beb93cSSam Leffler 		}
18339beb93cSSam Leffler 		attr->r_hash1 = pos;
18439beb93cSSam Leffler 		break;
18539beb93cSSam Leffler 	case ATTR_R_HASH2:
18639beb93cSSam Leffler 		if (len != WPS_HASH_LEN) {
18739beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid R-Hash2 length %u",
18839beb93cSSam Leffler 				   len);
18939beb93cSSam Leffler 			return -1;
19039beb93cSSam Leffler 		}
19139beb93cSSam Leffler 		attr->r_hash2 = pos;
19239beb93cSSam Leffler 		break;
19339beb93cSSam Leffler 	case ATTR_E_HASH1:
19439beb93cSSam Leffler 		if (len != WPS_HASH_LEN) {
19539beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid E-Hash1 length %u",
19639beb93cSSam Leffler 				   len);
19739beb93cSSam Leffler 			return -1;
19839beb93cSSam Leffler 		}
19939beb93cSSam Leffler 		attr->e_hash1 = pos;
20039beb93cSSam Leffler 		break;
20139beb93cSSam Leffler 	case ATTR_E_HASH2:
20239beb93cSSam Leffler 		if (len != WPS_HASH_LEN) {
20339beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid E-Hash2 length %u",
20439beb93cSSam Leffler 				   len);
20539beb93cSSam Leffler 			return -1;
20639beb93cSSam Leffler 		}
20739beb93cSSam Leffler 		attr->e_hash2 = pos;
20839beb93cSSam Leffler 		break;
20939beb93cSSam Leffler 	case ATTR_R_SNONCE1:
21039beb93cSSam Leffler 		if (len != WPS_SECRET_NONCE_LEN) {
21139beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid R-SNonce1 length "
21239beb93cSSam Leffler 				   "%u", len);
21339beb93cSSam Leffler 			return -1;
21439beb93cSSam Leffler 		}
21539beb93cSSam Leffler 		attr->r_snonce1 = pos;
21639beb93cSSam Leffler 		break;
21739beb93cSSam Leffler 	case ATTR_R_SNONCE2:
21839beb93cSSam Leffler 		if (len != WPS_SECRET_NONCE_LEN) {
21939beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid R-SNonce2 length "
22039beb93cSSam Leffler 				   "%u", len);
22139beb93cSSam Leffler 			return -1;
22239beb93cSSam Leffler 		}
22339beb93cSSam Leffler 		attr->r_snonce2 = pos;
22439beb93cSSam Leffler 		break;
22539beb93cSSam Leffler 	case ATTR_E_SNONCE1:
22639beb93cSSam Leffler 		if (len != WPS_SECRET_NONCE_LEN) {
22739beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid E-SNonce1 length "
22839beb93cSSam Leffler 				   "%u", len);
22939beb93cSSam Leffler 			return -1;
23039beb93cSSam Leffler 		}
23139beb93cSSam Leffler 		attr->e_snonce1 = pos;
23239beb93cSSam Leffler 		break;
23339beb93cSSam Leffler 	case ATTR_E_SNONCE2:
23439beb93cSSam Leffler 		if (len != WPS_SECRET_NONCE_LEN) {
23539beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid E-SNonce2 length "
23639beb93cSSam Leffler 				   "%u", len);
23739beb93cSSam Leffler 			return -1;
23839beb93cSSam Leffler 		}
23939beb93cSSam Leffler 		attr->e_snonce2 = pos;
24039beb93cSSam Leffler 		break;
24139beb93cSSam Leffler 	case ATTR_KEY_WRAP_AUTH:
24239beb93cSSam Leffler 		if (len != WPS_KWA_LEN) {
24339beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid Key Wrap "
24439beb93cSSam Leffler 				   "Authenticator length %u", len);
24539beb93cSSam Leffler 			return -1;
24639beb93cSSam Leffler 		}
24739beb93cSSam Leffler 		attr->key_wrap_auth = pos;
24839beb93cSSam Leffler 		break;
24939beb93cSSam Leffler 	case ATTR_AUTH_TYPE:
25039beb93cSSam Leffler 		if (len != 2) {
25139beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid Authentication "
25239beb93cSSam Leffler 				   "Type length %u", len);
25339beb93cSSam Leffler 			return -1;
25439beb93cSSam Leffler 		}
25539beb93cSSam Leffler 		attr->auth_type = pos;
25639beb93cSSam Leffler 		break;
25739beb93cSSam Leffler 	case ATTR_ENCR_TYPE:
25839beb93cSSam Leffler 		if (len != 2) {
25939beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid Encryption "
26039beb93cSSam Leffler 				   "Type length %u", len);
26139beb93cSSam Leffler 			return -1;
26239beb93cSSam Leffler 		}
26339beb93cSSam Leffler 		attr->encr_type = pos;
26439beb93cSSam Leffler 		break;
26539beb93cSSam Leffler 	case ATTR_NETWORK_INDEX:
26639beb93cSSam Leffler 		if (len != 1) {
26739beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid Network Index "
26839beb93cSSam Leffler 				   "length %u", len);
26939beb93cSSam Leffler 			return -1;
27039beb93cSSam Leffler 		}
27139beb93cSSam Leffler 		attr->network_idx = pos;
27239beb93cSSam Leffler 		break;
27339beb93cSSam Leffler 	case ATTR_NETWORK_KEY_INDEX:
27439beb93cSSam Leffler 		if (len != 1) {
27539beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid Network Key Index "
27639beb93cSSam Leffler 				   "length %u", len);
27739beb93cSSam Leffler 			return -1;
27839beb93cSSam Leffler 		}
27939beb93cSSam Leffler 		attr->network_key_idx = pos;
28039beb93cSSam Leffler 		break;
28139beb93cSSam Leffler 	case ATTR_MAC_ADDR:
28239beb93cSSam Leffler 		if (len != ETH_ALEN) {
28339beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid MAC Address "
28439beb93cSSam Leffler 				   "length %u", len);
28539beb93cSSam Leffler 			return -1;
28639beb93cSSam Leffler 		}
28739beb93cSSam Leffler 		attr->mac_addr = pos;
28839beb93cSSam Leffler 		break;
28939beb93cSSam Leffler 	case ATTR_KEY_PROVIDED_AUTO:
29039beb93cSSam Leffler 		if (len != 1) {
29139beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid Key Provided "
29239beb93cSSam Leffler 				   "Automatically length %u", len);
29339beb93cSSam Leffler 			return -1;
29439beb93cSSam Leffler 		}
29539beb93cSSam Leffler 		attr->key_prov_auto = pos;
29639beb93cSSam Leffler 		break;
29739beb93cSSam Leffler 	case ATTR_802_1X_ENABLED:
29839beb93cSSam Leffler 		if (len != 1) {
29939beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid 802.1X Enabled "
30039beb93cSSam Leffler 				   "length %u", len);
30139beb93cSSam Leffler 			return -1;
30239beb93cSSam Leffler 		}
30339beb93cSSam Leffler 		attr->dot1x_enabled = pos;
30439beb93cSSam Leffler 		break;
30539beb93cSSam Leffler 	case ATTR_SELECTED_REGISTRAR:
30639beb93cSSam Leffler 		if (len != 1) {
30739beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid Selected Registrar"
30839beb93cSSam Leffler 				   " length %u", len);
30939beb93cSSam Leffler 			return -1;
31039beb93cSSam Leffler 		}
31139beb93cSSam Leffler 		attr->selected_registrar = pos;
31239beb93cSSam Leffler 		break;
31339beb93cSSam Leffler 	case ATTR_REQUEST_TYPE:
31439beb93cSSam Leffler 		if (len != 1) {
31539beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid Request Type "
31639beb93cSSam Leffler 				   "length %u", len);
31739beb93cSSam Leffler 			return -1;
31839beb93cSSam Leffler 		}
31939beb93cSSam Leffler 		attr->request_type = pos;
32039beb93cSSam Leffler 		break;
32139beb93cSSam Leffler 	case ATTR_RESPONSE_TYPE:
32239beb93cSSam Leffler 		if (len != 1) {
32339beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid Response Type "
32439beb93cSSam Leffler 				   "length %u", len);
32539beb93cSSam Leffler 			return -1;
32639beb93cSSam Leffler 		}
32739beb93cSSam Leffler 		attr->request_type = pos;
32839beb93cSSam Leffler 		break;
32939beb93cSSam Leffler 	case ATTR_MANUFACTURER:
33039beb93cSSam Leffler 		attr->manufacturer = pos;
33139beb93cSSam Leffler 		attr->manufacturer_len = len;
33239beb93cSSam Leffler 		break;
33339beb93cSSam Leffler 	case ATTR_MODEL_NAME:
33439beb93cSSam Leffler 		attr->model_name = pos;
33539beb93cSSam Leffler 		attr->model_name_len = len;
33639beb93cSSam Leffler 		break;
33739beb93cSSam Leffler 	case ATTR_MODEL_NUMBER:
33839beb93cSSam Leffler 		attr->model_number = pos;
33939beb93cSSam Leffler 		attr->model_number_len = len;
34039beb93cSSam Leffler 		break;
34139beb93cSSam Leffler 	case ATTR_SERIAL_NUMBER:
34239beb93cSSam Leffler 		attr->serial_number = pos;
34339beb93cSSam Leffler 		attr->serial_number_len = len;
34439beb93cSSam Leffler 		break;
34539beb93cSSam Leffler 	case ATTR_DEV_NAME:
34639beb93cSSam Leffler 		attr->dev_name = pos;
34739beb93cSSam Leffler 		attr->dev_name_len = len;
34839beb93cSSam Leffler 		break;
34939beb93cSSam Leffler 	case ATTR_PUBLIC_KEY:
35039beb93cSSam Leffler 		attr->public_key = pos;
35139beb93cSSam Leffler 		attr->public_key_len = len;
35239beb93cSSam Leffler 		break;
35339beb93cSSam Leffler 	case ATTR_ENCR_SETTINGS:
35439beb93cSSam Leffler 		attr->encr_settings = pos;
35539beb93cSSam Leffler 		attr->encr_settings_len = len;
35639beb93cSSam Leffler 		break;
35739beb93cSSam Leffler 	case ATTR_CRED:
35839beb93cSSam Leffler 		if (attr->num_cred >= MAX_CRED_COUNT) {
35939beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Skipped Credential "
36039beb93cSSam Leffler 				   "attribute (max %d credentials)",
36139beb93cSSam Leffler 				   MAX_CRED_COUNT);
36239beb93cSSam Leffler 			break;
36339beb93cSSam Leffler 		}
36439beb93cSSam Leffler 		attr->cred[attr->num_cred] = pos;
36539beb93cSSam Leffler 		attr->cred_len[attr->num_cred] = len;
36639beb93cSSam Leffler 		attr->num_cred++;
36739beb93cSSam Leffler 		break;
36839beb93cSSam Leffler 	case ATTR_SSID:
36939beb93cSSam Leffler 		attr->ssid = pos;
37039beb93cSSam Leffler 		attr->ssid_len = len;
37139beb93cSSam Leffler 		break;
37239beb93cSSam Leffler 	case ATTR_NETWORK_KEY:
37339beb93cSSam Leffler 		attr->network_key = pos;
37439beb93cSSam Leffler 		attr->network_key_len = len;
37539beb93cSSam Leffler 		break;
37639beb93cSSam Leffler 	case ATTR_EAP_TYPE:
37739beb93cSSam Leffler 		attr->eap_type = pos;
37839beb93cSSam Leffler 		attr->eap_type_len = len;
37939beb93cSSam Leffler 		break;
38039beb93cSSam Leffler 	case ATTR_EAP_IDENTITY:
38139beb93cSSam Leffler 		attr->eap_identity = pos;
38239beb93cSSam Leffler 		attr->eap_identity_len = len;
38339beb93cSSam Leffler 		break;
38439beb93cSSam Leffler 	default:
38539beb93cSSam Leffler 		wpa_printf(MSG_DEBUG, "WPS: Unsupported attribute type 0x%x "
38639beb93cSSam Leffler 			   "len=%u", type, len);
38739beb93cSSam Leffler 		break;
38839beb93cSSam Leffler 	}
38939beb93cSSam Leffler 
39039beb93cSSam Leffler 	return 0;
39139beb93cSSam Leffler }
39239beb93cSSam Leffler 
39339beb93cSSam Leffler 
39439beb93cSSam Leffler int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr)
39539beb93cSSam Leffler {
39639beb93cSSam Leffler 	const u8 *pos, *end;
39739beb93cSSam Leffler 	u16 type, len;
39839beb93cSSam Leffler 
39939beb93cSSam Leffler 	os_memset(attr, 0, sizeof(*attr));
40039beb93cSSam Leffler 	pos = wpabuf_head(msg);
40139beb93cSSam Leffler 	end = pos + wpabuf_len(msg);
40239beb93cSSam Leffler 
40339beb93cSSam Leffler 	while (pos < end) {
40439beb93cSSam Leffler 		if (end - pos < 4) {
40539beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Invalid message - "
40639beb93cSSam Leffler 				   "%lu bytes remaining",
40739beb93cSSam Leffler 				   (unsigned long) (end - pos));
40839beb93cSSam Leffler 			return -1;
40939beb93cSSam Leffler 		}
41039beb93cSSam Leffler 
41139beb93cSSam Leffler 		type = WPA_GET_BE16(pos);
41239beb93cSSam Leffler 		pos += 2;
41339beb93cSSam Leffler 		len = WPA_GET_BE16(pos);
41439beb93cSSam Leffler 		pos += 2;
41539beb93cSSam Leffler 		wpa_printf(MSG_MSGDUMP, "WPS: attr type=0x%x len=%u",
41639beb93cSSam Leffler 			   type, len);
41739beb93cSSam Leffler 		if (len > end - pos) {
41839beb93cSSam Leffler 			wpa_printf(MSG_DEBUG, "WPS: Attribute overflow");
41939beb93cSSam Leffler 			return -1;
42039beb93cSSam Leffler 		}
42139beb93cSSam Leffler 
42239beb93cSSam Leffler 		if (wps_set_attr(attr, type, pos, len) < 0)
42339beb93cSSam Leffler 			return -1;
42439beb93cSSam Leffler 
42539beb93cSSam Leffler 		pos += len;
42639beb93cSSam Leffler 	}
42739beb93cSSam Leffler 
42839beb93cSSam Leffler 	return 0;
42939beb93cSSam Leffler }
430