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