$search
00001 /* 00002 * Wi-Fi Protected Setup - attribute parsing 00003 * Copyright (c) 2008, Jouni Malinen <j@w1.fi> 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License version 2 as 00007 * published by the Free Software Foundation. 00008 * 00009 * Alternatively, this software may be distributed under the terms of BSD 00010 * license. 00011 * 00012 * See README and COPYING for more details. 00013 */ 00014 00015 #include "includes.h" 00016 00017 #include "common.h" 00018 #include "wps_i.h" 00019 00020 00021 static int wps_set_attr(struct wps_parse_attr *attr, u16 type, 00022 const u8 *pos, u16 len) 00023 { 00024 switch (type) { 00025 case ATTR_VERSION: 00026 if (len != 1) { 00027 wpa_printf(MSG_DEBUG, "WPS: Invalid Version length %u", 00028 len); 00029 return -1; 00030 } 00031 attr->version = pos; 00032 break; 00033 case ATTR_MSG_TYPE: 00034 if (len != 1) { 00035 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type " 00036 "length %u", len); 00037 return -1; 00038 } 00039 attr->msg_type = pos; 00040 break; 00041 case ATTR_ENROLLEE_NONCE: 00042 if (len != WPS_NONCE_LEN) { 00043 wpa_printf(MSG_DEBUG, "WPS: Invalid Enrollee Nonce " 00044 "length %u", len); 00045 return -1; 00046 } 00047 attr->enrollee_nonce = pos; 00048 break; 00049 case ATTR_REGISTRAR_NONCE: 00050 if (len != WPS_NONCE_LEN) { 00051 wpa_printf(MSG_DEBUG, "WPS: Invalid Registrar Nonce " 00052 "length %u", len); 00053 return -1; 00054 } 00055 attr->registrar_nonce = pos; 00056 break; 00057 case ATTR_UUID_E: 00058 if (len != WPS_UUID_LEN) { 00059 wpa_printf(MSG_DEBUG, "WPS: Invalid UUID-E length %u", 00060 len); 00061 return -1; 00062 } 00063 attr->uuid_e = pos; 00064 break; 00065 case ATTR_UUID_R: 00066 if (len != WPS_UUID_LEN) { 00067 wpa_printf(MSG_DEBUG, "WPS: Invalid UUID-R length %u", 00068 len); 00069 return -1; 00070 } 00071 attr->uuid_r = pos; 00072 break; 00073 case ATTR_AUTH_TYPE_FLAGS: 00074 if (len != 2) { 00075 wpa_printf(MSG_DEBUG, "WPS: Invalid Authentication " 00076 "Type Flags length %u", len); 00077 return -1; 00078 } 00079 attr->auth_type_flags = pos; 00080 break; 00081 case ATTR_ENCR_TYPE_FLAGS: 00082 if (len != 2) { 00083 wpa_printf(MSG_DEBUG, "WPS: Invalid Encryption Type " 00084 "Flags length %u", len); 00085 return -1; 00086 } 00087 attr->encr_type_flags = pos; 00088 break; 00089 case ATTR_CONN_TYPE_FLAGS: 00090 if (len != 1) { 00091 wpa_printf(MSG_DEBUG, "WPS: Invalid Connection Type " 00092 "Flags length %u", len); 00093 return -1; 00094 } 00095 attr->conn_type_flags = pos; 00096 break; 00097 case ATTR_CONFIG_METHODS: 00098 if (len != 2) { 00099 wpa_printf(MSG_DEBUG, "WPS: Invalid Config Methods " 00100 "length %u", len); 00101 return -1; 00102 } 00103 attr->config_methods = pos; 00104 break; 00105 case ATTR_SELECTED_REGISTRAR_CONFIG_METHODS: 00106 if (len != 2) { 00107 wpa_printf(MSG_DEBUG, "WPS: Invalid Selected " 00108 "Registrar Config Methods length %u", len); 00109 return -1; 00110 } 00111 attr->sel_reg_config_methods = pos; 00112 break; 00113 case ATTR_PRIMARY_DEV_TYPE: 00114 if (len != WPS_DEV_TYPE_LEN) { 00115 wpa_printf(MSG_DEBUG, "WPS: Invalid Primary Device " 00116 "Type length %u", len); 00117 return -1; 00118 } 00119 attr->primary_dev_type = pos; 00120 break; 00121 case ATTR_RF_BANDS: 00122 if (len != 1) { 00123 wpa_printf(MSG_DEBUG, "WPS: Invalid RF Bands length " 00124 "%u", len); 00125 return -1; 00126 } 00127 attr->rf_bands = pos; 00128 break; 00129 case ATTR_ASSOC_STATE: 00130 if (len != 2) { 00131 wpa_printf(MSG_DEBUG, "WPS: Invalid Association State " 00132 "length %u", len); 00133 return -1; 00134 } 00135 attr->assoc_state = pos; 00136 break; 00137 case ATTR_CONFIG_ERROR: 00138 if (len != 2) { 00139 wpa_printf(MSG_DEBUG, "WPS: Invalid Configuration " 00140 "Error length %u", len); 00141 return -1; 00142 } 00143 attr->config_error = pos; 00144 break; 00145 case ATTR_DEV_PASSWORD_ID: 00146 if (len != 2) { 00147 wpa_printf(MSG_DEBUG, "WPS: Invalid Device Password " 00148 "ID length %u", len); 00149 return -1; 00150 } 00151 attr->dev_password_id = pos; 00152 break; 00153 case ATTR_OOB_DEVICE_PASSWORD: 00154 if (len != WPS_OOB_DEVICE_PASSWORD_ATTR_LEN) { 00155 wpa_printf(MSG_DEBUG, "WPS: Invalid OOB Device " 00156 "Password length %u", len); 00157 return -1; 00158 } 00159 attr->oob_dev_password = pos; 00160 break; 00161 case ATTR_OS_VERSION: 00162 if (len != 4) { 00163 wpa_printf(MSG_DEBUG, "WPS: Invalid OS Version length " 00164 "%u", len); 00165 return -1; 00166 } 00167 attr->os_version = pos; 00168 break; 00169 case ATTR_WPS_STATE: 00170 if (len != 1) { 00171 wpa_printf(MSG_DEBUG, "WPS: Invalid Wi-Fi Protected " 00172 "Setup State length %u", len); 00173 return -1; 00174 } 00175 attr->wps_state = pos; 00176 break; 00177 case ATTR_AUTHENTICATOR: 00178 if (len != WPS_AUTHENTICATOR_LEN) { 00179 wpa_printf(MSG_DEBUG, "WPS: Invalid Authenticator " 00180 "length %u", len); 00181 return -1; 00182 } 00183 attr->authenticator = pos; 00184 break; 00185 case ATTR_R_HASH1: 00186 if (len != WPS_HASH_LEN) { 00187 wpa_printf(MSG_DEBUG, "WPS: Invalid R-Hash1 length %u", 00188 len); 00189 return -1; 00190 } 00191 attr->r_hash1 = pos; 00192 break; 00193 case ATTR_R_HASH2: 00194 if (len != WPS_HASH_LEN) { 00195 wpa_printf(MSG_DEBUG, "WPS: Invalid R-Hash2 length %u", 00196 len); 00197 return -1; 00198 } 00199 attr->r_hash2 = pos; 00200 break; 00201 case ATTR_E_HASH1: 00202 if (len != WPS_HASH_LEN) { 00203 wpa_printf(MSG_DEBUG, "WPS: Invalid E-Hash1 length %u", 00204 len); 00205 return -1; 00206 } 00207 attr->e_hash1 = pos; 00208 break; 00209 case ATTR_E_HASH2: 00210 if (len != WPS_HASH_LEN) { 00211 wpa_printf(MSG_DEBUG, "WPS: Invalid E-Hash2 length %u", 00212 len); 00213 return -1; 00214 } 00215 attr->e_hash2 = pos; 00216 break; 00217 case ATTR_R_SNONCE1: 00218 if (len != WPS_SECRET_NONCE_LEN) { 00219 wpa_printf(MSG_DEBUG, "WPS: Invalid R-SNonce1 length " 00220 "%u", len); 00221 return -1; 00222 } 00223 attr->r_snonce1 = pos; 00224 break; 00225 case ATTR_R_SNONCE2: 00226 if (len != WPS_SECRET_NONCE_LEN) { 00227 wpa_printf(MSG_DEBUG, "WPS: Invalid R-SNonce2 length " 00228 "%u", len); 00229 return -1; 00230 } 00231 attr->r_snonce2 = pos; 00232 break; 00233 case ATTR_E_SNONCE1: 00234 if (len != WPS_SECRET_NONCE_LEN) { 00235 wpa_printf(MSG_DEBUG, "WPS: Invalid E-SNonce1 length " 00236 "%u", len); 00237 return -1; 00238 } 00239 attr->e_snonce1 = pos; 00240 break; 00241 case ATTR_E_SNONCE2: 00242 if (len != WPS_SECRET_NONCE_LEN) { 00243 wpa_printf(MSG_DEBUG, "WPS: Invalid E-SNonce2 length " 00244 "%u", len); 00245 return -1; 00246 } 00247 attr->e_snonce2 = pos; 00248 break; 00249 case ATTR_KEY_WRAP_AUTH: 00250 if (len != WPS_KWA_LEN) { 00251 wpa_printf(MSG_DEBUG, "WPS: Invalid Key Wrap " 00252 "Authenticator length %u", len); 00253 return -1; 00254 } 00255 attr->key_wrap_auth = pos; 00256 break; 00257 case ATTR_AUTH_TYPE: 00258 if (len != 2) { 00259 wpa_printf(MSG_DEBUG, "WPS: Invalid Authentication " 00260 "Type length %u", len); 00261 return -1; 00262 } 00263 attr->auth_type = pos; 00264 break; 00265 case ATTR_ENCR_TYPE: 00266 if (len != 2) { 00267 wpa_printf(MSG_DEBUG, "WPS: Invalid Encryption " 00268 "Type length %u", len); 00269 return -1; 00270 } 00271 attr->encr_type = pos; 00272 break; 00273 case ATTR_NETWORK_INDEX: 00274 if (len != 1) { 00275 wpa_printf(MSG_DEBUG, "WPS: Invalid Network Index " 00276 "length %u", len); 00277 return -1; 00278 } 00279 attr->network_idx = pos; 00280 break; 00281 case ATTR_NETWORK_KEY_INDEX: 00282 if (len != 1) { 00283 wpa_printf(MSG_DEBUG, "WPS: Invalid Network Key Index " 00284 "length %u", len); 00285 return -1; 00286 } 00287 attr->network_key_idx = pos; 00288 break; 00289 case ATTR_MAC_ADDR: 00290 if (len != ETH_ALEN) { 00291 wpa_printf(MSG_DEBUG, "WPS: Invalid MAC Address " 00292 "length %u", len); 00293 return -1; 00294 } 00295 attr->mac_addr = pos; 00296 break; 00297 case ATTR_KEY_PROVIDED_AUTO: 00298 if (len != 1) { 00299 wpa_printf(MSG_DEBUG, "WPS: Invalid Key Provided " 00300 "Automatically length %u", len); 00301 return -1; 00302 } 00303 attr->key_prov_auto = pos; 00304 break; 00305 case ATTR_802_1X_ENABLED: 00306 if (len != 1) { 00307 wpa_printf(MSG_DEBUG, "WPS: Invalid 802.1X Enabled " 00308 "length %u", len); 00309 return -1; 00310 } 00311 attr->dot1x_enabled = pos; 00312 break; 00313 case ATTR_SELECTED_REGISTRAR: 00314 if (len != 1) { 00315 wpa_printf(MSG_DEBUG, "WPS: Invalid Selected Registrar" 00316 " length %u", len); 00317 return -1; 00318 } 00319 attr->selected_registrar = pos; 00320 break; 00321 case ATTR_REQUEST_TYPE: 00322 if (len != 1) { 00323 wpa_printf(MSG_DEBUG, "WPS: Invalid Request Type " 00324 "length %u", len); 00325 return -1; 00326 } 00327 attr->request_type = pos; 00328 break; 00329 case ATTR_RESPONSE_TYPE: 00330 if (len != 1) { 00331 wpa_printf(MSG_DEBUG, "WPS: Invalid Response Type " 00332 "length %u", len); 00333 return -1; 00334 } 00335 attr->request_type = pos; 00336 break; 00337 case ATTR_MANUFACTURER: 00338 attr->manufacturer = pos; 00339 attr->manufacturer_len = len; 00340 break; 00341 case ATTR_MODEL_NAME: 00342 attr->model_name = pos; 00343 attr->model_name_len = len; 00344 break; 00345 case ATTR_MODEL_NUMBER: 00346 attr->model_number = pos; 00347 attr->model_number_len = len; 00348 break; 00349 case ATTR_SERIAL_NUMBER: 00350 attr->serial_number = pos; 00351 attr->serial_number_len = len; 00352 break; 00353 case ATTR_DEV_NAME: 00354 attr->dev_name = pos; 00355 attr->dev_name_len = len; 00356 break; 00357 case ATTR_PUBLIC_KEY: 00358 attr->public_key = pos; 00359 attr->public_key_len = len; 00360 break; 00361 case ATTR_ENCR_SETTINGS: 00362 attr->encr_settings = pos; 00363 attr->encr_settings_len = len; 00364 break; 00365 case ATTR_CRED: 00366 if (attr->num_cred >= MAX_CRED_COUNT) { 00367 wpa_printf(MSG_DEBUG, "WPS: Skipped Credential " 00368 "attribute (max %d credentials)", 00369 MAX_CRED_COUNT); 00370 break; 00371 } 00372 attr->cred[attr->num_cred] = pos; 00373 attr->cred_len[attr->num_cred] = len; 00374 attr->num_cred++; 00375 break; 00376 case ATTR_SSID: 00377 attr->ssid = pos; 00378 attr->ssid_len = len; 00379 break; 00380 case ATTR_NETWORK_KEY: 00381 attr->network_key = pos; 00382 attr->network_key_len = len; 00383 break; 00384 case ATTR_EAP_TYPE: 00385 attr->eap_type = pos; 00386 attr->eap_type_len = len; 00387 break; 00388 case ATTR_EAP_IDENTITY: 00389 attr->eap_identity = pos; 00390 attr->eap_identity_len = len; 00391 break; 00392 case ATTR_AP_SETUP_LOCKED: 00393 if (len != 1) { 00394 wpa_printf(MSG_DEBUG, "WPS: Invalid AP Setup Locked " 00395 "length %u", len); 00396 return -1; 00397 } 00398 attr->ap_setup_locked = pos; 00399 break; 00400 default: 00401 wpa_printf(MSG_DEBUG, "WPS: Unsupported attribute type 0x%x " 00402 "len=%u", type, len); 00403 break; 00404 } 00405 00406 return 0; 00407 } 00408 00409 00410 int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr) 00411 { 00412 const u8 *pos, *end; 00413 u16 type, len; 00414 00415 os_memset(attr, 0, sizeof(*attr)); 00416 pos = wpabuf_head(msg); 00417 end = pos + wpabuf_len(msg); 00418 00419 while (pos < end) { 00420 if (end - pos < 4) { 00421 wpa_printf(MSG_DEBUG, "WPS: Invalid message - " 00422 "%lu bytes remaining", 00423 (unsigned long) (end - pos)); 00424 return -1; 00425 } 00426 00427 type = WPA_GET_BE16(pos); 00428 pos += 2; 00429 len = WPA_GET_BE16(pos); 00430 pos += 2; 00431 wpa_printf(MSG_MSGDUMP, "WPS: attr type=0x%x len=%u", 00432 type, len); 00433 if (len > end - pos) { 00434 wpa_printf(MSG_DEBUG, "WPS: Attribute overflow"); 00435 return -1; 00436 } 00437 00438 if (wps_set_attr(attr, type, pos, len) < 0) 00439 return -1; 00440 00441 pos += len; 00442 } 00443 00444 return 0; 00445 }