00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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 }