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