$search
00001 /* 00002 * Wi-Fi Protected Setup - Enrollee 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 "crypto/crypto.h" 00019 #include "crypto/sha256.h" 00020 #include "wps_i.h" 00021 #include "wps_dev_attr.h" 00022 00023 00024 static int wps_build_mac_addr(struct wps_data *wps, struct wpabuf *msg) 00025 { 00026 wpa_printf(MSG_DEBUG, "WPS: * MAC Address"); 00027 wpabuf_put_be16(msg, ATTR_MAC_ADDR); 00028 wpabuf_put_be16(msg, ETH_ALEN); 00029 wpabuf_put_data(msg, wps->mac_addr_e, ETH_ALEN); 00030 return 0; 00031 } 00032 00033 00034 static int wps_build_wps_state(struct wps_data *wps, struct wpabuf *msg) 00035 { 00036 u8 state; 00037 if (wps->wps->ap) 00038 state = wps->wps->wps_state; 00039 else 00040 state = WPS_STATE_NOT_CONFIGURED; 00041 wpa_printf(MSG_DEBUG, "WPS: * Wi-Fi Protected Setup State (%d)", 00042 state); 00043 wpabuf_put_be16(msg, ATTR_WPS_STATE); 00044 wpabuf_put_be16(msg, 1); 00045 wpabuf_put_u8(msg, state); 00046 return 0; 00047 } 00048 00049 00050 static int wps_build_e_hash(struct wps_data *wps, struct wpabuf *msg) 00051 { 00052 u8 *hash; 00053 const u8 *addr[4]; 00054 size_t len[4]; 00055 00056 if (os_get_random(wps->snonce, 2 * WPS_SECRET_NONCE_LEN) < 0) 00057 return -1; 00058 wpa_hexdump(MSG_DEBUG, "WPS: E-S1", wps->snonce, WPS_SECRET_NONCE_LEN); 00059 wpa_hexdump(MSG_DEBUG, "WPS: E-S2", 00060 wps->snonce + WPS_SECRET_NONCE_LEN, WPS_SECRET_NONCE_LEN); 00061 00062 if (wps->dh_pubkey_e == NULL || wps->dh_pubkey_r == NULL) { 00063 wpa_printf(MSG_DEBUG, "WPS: DH public keys not available for " 00064 "E-Hash derivation"); 00065 return -1; 00066 } 00067 00068 wpa_printf(MSG_DEBUG, "WPS: * E-Hash1"); 00069 wpabuf_put_be16(msg, ATTR_E_HASH1); 00070 wpabuf_put_be16(msg, SHA256_MAC_LEN); 00071 hash = wpabuf_put(msg, SHA256_MAC_LEN); 00072 /* E-Hash1 = HMAC_AuthKey(E-S1 || PSK1 || PK_E || PK_R) */ 00073 addr[0] = wps->snonce; 00074 len[0] = WPS_SECRET_NONCE_LEN; 00075 addr[1] = wps->psk1; 00076 len[1] = WPS_PSK_LEN; 00077 addr[2] = wpabuf_head(wps->dh_pubkey_e); 00078 len[2] = wpabuf_len(wps->dh_pubkey_e); 00079 addr[3] = wpabuf_head(wps->dh_pubkey_r); 00080 len[3] = wpabuf_len(wps->dh_pubkey_r); 00081 hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash); 00082 wpa_hexdump(MSG_DEBUG, "WPS: E-Hash1", hash, SHA256_MAC_LEN); 00083 00084 wpa_printf(MSG_DEBUG, "WPS: * E-Hash2"); 00085 wpabuf_put_be16(msg, ATTR_E_HASH2); 00086 wpabuf_put_be16(msg, SHA256_MAC_LEN); 00087 hash = wpabuf_put(msg, SHA256_MAC_LEN); 00088 /* E-Hash2 = HMAC_AuthKey(E-S2 || PSK2 || PK_E || PK_R) */ 00089 addr[0] = wps->snonce + WPS_SECRET_NONCE_LEN; 00090 addr[1] = wps->psk2; 00091 hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash); 00092 wpa_hexdump(MSG_DEBUG, "WPS: E-Hash2", hash, SHA256_MAC_LEN); 00093 00094 return 0; 00095 } 00096 00097 00098 static int wps_build_e_snonce1(struct wps_data *wps, struct wpabuf *msg) 00099 { 00100 wpa_printf(MSG_DEBUG, "WPS: * E-SNonce1"); 00101 wpabuf_put_be16(msg, ATTR_E_SNONCE1); 00102 wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN); 00103 wpabuf_put_data(msg, wps->snonce, WPS_SECRET_NONCE_LEN); 00104 return 0; 00105 } 00106 00107 00108 static int wps_build_e_snonce2(struct wps_data *wps, struct wpabuf *msg) 00109 { 00110 wpa_printf(MSG_DEBUG, "WPS: * E-SNonce2"); 00111 wpabuf_put_be16(msg, ATTR_E_SNONCE2); 00112 wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN); 00113 wpabuf_put_data(msg, wps->snonce + WPS_SECRET_NONCE_LEN, 00114 WPS_SECRET_NONCE_LEN); 00115 return 0; 00116 } 00117 00118 00119 static struct wpabuf * wps_build_m1(struct wps_data *wps) 00120 { 00121 struct wpabuf *msg; 00122 00123 if (os_get_random(wps->nonce_e, WPS_NONCE_LEN) < 0) 00124 return NULL; 00125 wpa_hexdump(MSG_DEBUG, "WPS: Enrollee Nonce", 00126 wps->nonce_e, WPS_NONCE_LEN); 00127 00128 wpa_printf(MSG_DEBUG, "WPS: Building Message M1"); 00129 msg = wpabuf_alloc(1000); 00130 if (msg == NULL) 00131 return NULL; 00132 00133 if (wps_build_version(msg) || 00134 wps_build_msg_type(msg, WPS_M1) || 00135 wps_build_uuid_e(msg, wps->uuid_e) || 00136 wps_build_mac_addr(wps, msg) || 00137 wps_build_enrollee_nonce(wps, msg) || 00138 wps_build_public_key(wps, msg) || 00139 wps_build_auth_type_flags(wps, msg) || 00140 wps_build_encr_type_flags(wps, msg) || 00141 wps_build_conn_type_flags(wps, msg) || 00142 wps_build_config_methods(msg, wps->wps->config_methods) || 00143 wps_build_wps_state(wps, msg) || 00144 wps_build_device_attrs(&wps->wps->dev, msg) || 00145 wps_build_rf_bands(&wps->wps->dev, msg) || 00146 wps_build_assoc_state(wps, msg) || 00147 wps_build_dev_password_id(msg, wps->dev_pw_id) || 00148 wps_build_config_error(msg, WPS_CFG_NO_ERROR) || 00149 wps_build_os_version(&wps->wps->dev, msg)) { 00150 wpabuf_free(msg); 00151 return NULL; 00152 } 00153 00154 wps->state = RECV_M2; 00155 return msg; 00156 } 00157 00158 00159 static struct wpabuf * wps_build_m3(struct wps_data *wps) 00160 { 00161 struct wpabuf *msg; 00162 00163 wpa_printf(MSG_DEBUG, "WPS: Building Message M3"); 00164 00165 if (wps->dev_password == NULL) { 00166 wpa_printf(MSG_DEBUG, "WPS: No Device Password available"); 00167 return NULL; 00168 } 00169 wps_derive_psk(wps, wps->dev_password, wps->dev_password_len); 00170 00171 msg = wpabuf_alloc(1000); 00172 if (msg == NULL) 00173 return NULL; 00174 00175 if (wps_build_version(msg) || 00176 wps_build_msg_type(msg, WPS_M3) || 00177 wps_build_registrar_nonce(wps, msg) || 00178 wps_build_e_hash(wps, msg) || 00179 wps_build_authenticator(wps, msg)) { 00180 wpabuf_free(msg); 00181 return NULL; 00182 } 00183 00184 wps->state = RECV_M4; 00185 return msg; 00186 } 00187 00188 00189 static struct wpabuf * wps_build_m5(struct wps_data *wps) 00190 { 00191 struct wpabuf *msg, *plain; 00192 00193 wpa_printf(MSG_DEBUG, "WPS: Building Message M5"); 00194 00195 plain = wpabuf_alloc(200); 00196 if (plain == NULL) 00197 return NULL; 00198 00199 msg = wpabuf_alloc(1000); 00200 if (msg == NULL) { 00201 wpabuf_free(plain); 00202 return NULL; 00203 } 00204 00205 if (wps_build_version(msg) || 00206 wps_build_msg_type(msg, WPS_M5) || 00207 wps_build_registrar_nonce(wps, msg) || 00208 wps_build_e_snonce1(wps, plain) || 00209 wps_build_key_wrap_auth(wps, plain) || 00210 wps_build_encr_settings(wps, msg, plain) || 00211 wps_build_authenticator(wps, msg)) { 00212 wpabuf_free(plain); 00213 wpabuf_free(msg); 00214 return NULL; 00215 } 00216 wpabuf_free(plain); 00217 00218 wps->state = RECV_M6; 00219 return msg; 00220 } 00221 00222 00223 static int wps_build_cred_ssid(struct wps_data *wps, struct wpabuf *msg) 00224 { 00225 wpa_printf(MSG_DEBUG, "WPS: * SSID"); 00226 wpabuf_put_be16(msg, ATTR_SSID); 00227 wpabuf_put_be16(msg, wps->wps->ssid_len); 00228 wpabuf_put_data(msg, wps->wps->ssid, wps->wps->ssid_len); 00229 return 0; 00230 } 00231 00232 00233 static int wps_build_cred_auth_type(struct wps_data *wps, struct wpabuf *msg) 00234 { 00235 wpa_printf(MSG_DEBUG, "WPS: * Authentication Type"); 00236 wpabuf_put_be16(msg, ATTR_AUTH_TYPE); 00237 wpabuf_put_be16(msg, 2); 00238 wpabuf_put_be16(msg, wps->wps->auth_types); 00239 return 0; 00240 } 00241 00242 00243 static int wps_build_cred_encr_type(struct wps_data *wps, struct wpabuf *msg) 00244 { 00245 wpa_printf(MSG_DEBUG, "WPS: * Encryption Type"); 00246 wpabuf_put_be16(msg, ATTR_ENCR_TYPE); 00247 wpabuf_put_be16(msg, 2); 00248 wpabuf_put_be16(msg, wps->wps->encr_types); 00249 return 0; 00250 } 00251 00252 00253 static int wps_build_cred_network_key(struct wps_data *wps, struct wpabuf *msg) 00254 { 00255 wpa_printf(MSG_DEBUG, "WPS: * Network Key"); 00256 wpabuf_put_be16(msg, ATTR_NETWORK_KEY); 00257 wpabuf_put_be16(msg, wps->wps->network_key_len); 00258 wpabuf_put_data(msg, wps->wps->network_key, wps->wps->network_key_len); 00259 return 0; 00260 } 00261 00262 00263 static int wps_build_cred_mac_addr(struct wps_data *wps, struct wpabuf *msg) 00264 { 00265 wpa_printf(MSG_DEBUG, "WPS: * MAC Address (AP BSSID)"); 00266 wpabuf_put_be16(msg, ATTR_MAC_ADDR); 00267 wpabuf_put_be16(msg, ETH_ALEN); 00268 wpabuf_put_data(msg, wps->wps->dev.mac_addr, ETH_ALEN); 00269 return 0; 00270 } 00271 00272 00273 static int wps_build_ap_settings(struct wps_data *wps, struct wpabuf *plain) 00274 { 00275 if (wps->wps->ap_settings) { 00276 wpa_printf(MSG_DEBUG, "WPS: * AP Settings (pre-configured)"); 00277 wpabuf_put_data(plain, wps->wps->ap_settings, 00278 wps->wps->ap_settings_len); 00279 return 0; 00280 } 00281 00282 return wps_build_cred_ssid(wps, plain) || 00283 wps_build_cred_mac_addr(wps, plain) || 00284 wps_build_cred_auth_type(wps, plain) || 00285 wps_build_cred_encr_type(wps, plain) || 00286 wps_build_cred_network_key(wps, plain); 00287 } 00288 00289 00290 static struct wpabuf * wps_build_m7(struct wps_data *wps) 00291 { 00292 struct wpabuf *msg, *plain; 00293 00294 wpa_printf(MSG_DEBUG, "WPS: Building Message M7"); 00295 00296 plain = wpabuf_alloc(500 + wps->wps->ap_settings_len); 00297 if (plain == NULL) 00298 return NULL; 00299 00300 msg = wpabuf_alloc(1000 + wps->wps->ap_settings_len); 00301 if (msg == NULL) { 00302 wpabuf_free(plain); 00303 return NULL; 00304 } 00305 00306 if (wps_build_version(msg) || 00307 wps_build_msg_type(msg, WPS_M7) || 00308 wps_build_registrar_nonce(wps, msg) || 00309 wps_build_e_snonce2(wps, plain) || 00310 (wps->wps->ap && wps_build_ap_settings(wps, plain)) || 00311 wps_build_key_wrap_auth(wps, plain) || 00312 wps_build_encr_settings(wps, msg, plain) || 00313 wps_build_authenticator(wps, msg)) { 00314 wpabuf_free(plain); 00315 wpabuf_free(msg); 00316 return NULL; 00317 } 00318 wpabuf_free(plain); 00319 00320 if (wps->wps->ap && wps->wps->registrar) { 00321 /* 00322 * If the Registrar is only learning our current configuration, 00323 * it may not continue protocol run to successful completion. 00324 * Store information here to make sure it remains available. 00325 */ 00326 wps_device_store(wps->wps->registrar, &wps->peer_dev, 00327 wps->uuid_r); 00328 } 00329 00330 wps->state = RECV_M8; 00331 return msg; 00332 } 00333 00334 00335 static struct wpabuf * wps_build_wsc_done(struct wps_data *wps) 00336 { 00337 struct wpabuf *msg; 00338 00339 wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_Done"); 00340 00341 msg = wpabuf_alloc(1000); 00342 if (msg == NULL) 00343 return NULL; 00344 00345 if (wps_build_version(msg) || 00346 wps_build_msg_type(msg, WPS_WSC_DONE) || 00347 wps_build_enrollee_nonce(wps, msg) || 00348 wps_build_registrar_nonce(wps, msg)) { 00349 wpabuf_free(msg); 00350 return NULL; 00351 } 00352 00353 if (wps->wps->ap) 00354 wps->state = RECV_ACK; 00355 else { 00356 wps_success_event(wps->wps); 00357 wps->state = WPS_FINISHED; 00358 } 00359 return msg; 00360 } 00361 00362 00363 static struct wpabuf * wps_build_wsc_ack(struct wps_data *wps) 00364 { 00365 struct wpabuf *msg; 00366 00367 wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_ACK"); 00368 00369 msg = wpabuf_alloc(1000); 00370 if (msg == NULL) 00371 return NULL; 00372 00373 if (wps_build_version(msg) || 00374 wps_build_msg_type(msg, WPS_WSC_ACK) || 00375 wps_build_enrollee_nonce(wps, msg) || 00376 wps_build_registrar_nonce(wps, msg)) { 00377 wpabuf_free(msg); 00378 return NULL; 00379 } 00380 00381 return msg; 00382 } 00383 00384 00385 static struct wpabuf * wps_build_wsc_nack(struct wps_data *wps) 00386 { 00387 struct wpabuf *msg; 00388 00389 wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_NACK"); 00390 00391 msg = wpabuf_alloc(1000); 00392 if (msg == NULL) 00393 return NULL; 00394 00395 if (wps_build_version(msg) || 00396 wps_build_msg_type(msg, WPS_WSC_NACK) || 00397 wps_build_enrollee_nonce(wps, msg) || 00398 wps_build_registrar_nonce(wps, msg) || 00399 wps_build_config_error(msg, wps->config_error)) { 00400 wpabuf_free(msg); 00401 return NULL; 00402 } 00403 00404 return msg; 00405 } 00406 00407 00408 struct wpabuf * wps_enrollee_get_msg(struct wps_data *wps, 00409 enum wsc_op_code *op_code) 00410 { 00411 struct wpabuf *msg; 00412 00413 switch (wps->state) { 00414 case SEND_M1: 00415 msg = wps_build_m1(wps); 00416 *op_code = WSC_MSG; 00417 break; 00418 case SEND_M3: 00419 msg = wps_build_m3(wps); 00420 *op_code = WSC_MSG; 00421 break; 00422 case SEND_M5: 00423 msg = wps_build_m5(wps); 00424 *op_code = WSC_MSG; 00425 break; 00426 case SEND_M7: 00427 msg = wps_build_m7(wps); 00428 *op_code = WSC_MSG; 00429 break; 00430 case RECEIVED_M2D: 00431 if (wps->wps->ap) { 00432 msg = wps_build_wsc_nack(wps); 00433 *op_code = WSC_NACK; 00434 break; 00435 } 00436 msg = wps_build_wsc_ack(wps); 00437 *op_code = WSC_ACK; 00438 if (msg) { 00439 /* Another M2/M2D may be received */ 00440 wps->state = RECV_M2; 00441 } 00442 break; 00443 case SEND_WSC_NACK: 00444 msg = wps_build_wsc_nack(wps); 00445 *op_code = WSC_NACK; 00446 break; 00447 case WPS_MSG_DONE: 00448 msg = wps_build_wsc_done(wps); 00449 *op_code = WSC_Done; 00450 break; 00451 default: 00452 wpa_printf(MSG_DEBUG, "WPS: Unsupported state %d for building " 00453 "a message", wps->state); 00454 msg = NULL; 00455 break; 00456 } 00457 00458 if (*op_code == WSC_MSG && msg) { 00459 /* Save a copy of the last message for Authenticator derivation 00460 */ 00461 wpabuf_free(wps->last_msg); 00462 wps->last_msg = wpabuf_dup(msg); 00463 } 00464 00465 return msg; 00466 } 00467 00468 00469 static int wps_process_registrar_nonce(struct wps_data *wps, const u8 *r_nonce) 00470 { 00471 if (r_nonce == NULL) { 00472 wpa_printf(MSG_DEBUG, "WPS: No Registrar Nonce received"); 00473 return -1; 00474 } 00475 00476 os_memcpy(wps->nonce_r, r_nonce, WPS_NONCE_LEN); 00477 wpa_hexdump(MSG_DEBUG, "WPS: Registrar Nonce", 00478 wps->nonce_r, WPS_NONCE_LEN); 00479 00480 return 0; 00481 } 00482 00483 00484 static int wps_process_enrollee_nonce(struct wps_data *wps, const u8 *e_nonce) 00485 { 00486 if (e_nonce == NULL) { 00487 wpa_printf(MSG_DEBUG, "WPS: No Enrollee Nonce received"); 00488 return -1; 00489 } 00490 00491 if (os_memcmp(wps->nonce_e, e_nonce, WPS_NONCE_LEN) != 0) { 00492 wpa_printf(MSG_DEBUG, "WPS: Invalid Enrollee Nonce received"); 00493 return -1; 00494 } 00495 00496 return 0; 00497 } 00498 00499 00500 static int wps_process_uuid_r(struct wps_data *wps, const u8 *uuid_r) 00501 { 00502 if (uuid_r == NULL) { 00503 wpa_printf(MSG_DEBUG, "WPS: No UUID-R received"); 00504 return -1; 00505 } 00506 00507 os_memcpy(wps->uuid_r, uuid_r, WPS_UUID_LEN); 00508 wpa_hexdump(MSG_DEBUG, "WPS: UUID-R", wps->uuid_r, WPS_UUID_LEN); 00509 00510 return 0; 00511 } 00512 00513 00514 static int wps_process_pubkey(struct wps_data *wps, const u8 *pk, 00515 size_t pk_len) 00516 { 00517 if (pk == NULL || pk_len == 0) { 00518 wpa_printf(MSG_DEBUG, "WPS: No Public Key received"); 00519 return -1; 00520 } 00521 00522 #ifdef CONFIG_WPS_OOB 00523 if (wps->dev_pw_id != DEV_PW_DEFAULT && 00524 wps->wps->oob_conf.pubkey_hash) { 00525 const u8 *addr[1]; 00526 u8 hash[WPS_HASH_LEN]; 00527 00528 addr[0] = pk; 00529 sha256_vector(1, addr, &pk_len, hash); 00530 if (os_memcmp(hash, 00531 wpabuf_head(wps->wps->oob_conf.pubkey_hash), 00532 WPS_OOB_PUBKEY_HASH_LEN) != 0) { 00533 wpa_printf(MSG_ERROR, "WPS: Public Key hash error"); 00534 return -1; 00535 } 00536 } 00537 #endif /* CONFIG_WPS_OOB */ 00538 00539 wpabuf_free(wps->dh_pubkey_r); 00540 wps->dh_pubkey_r = wpabuf_alloc_copy(pk, pk_len); 00541 if (wps->dh_pubkey_r == NULL) 00542 return -1; 00543 00544 if (wps_derive_keys(wps) < 0) 00545 return -1; 00546 00547 return 0; 00548 } 00549 00550 00551 static int wps_process_r_hash1(struct wps_data *wps, const u8 *r_hash1) 00552 { 00553 if (r_hash1 == NULL) { 00554 wpa_printf(MSG_DEBUG, "WPS: No R-Hash1 received"); 00555 return -1; 00556 } 00557 00558 os_memcpy(wps->peer_hash1, r_hash1, WPS_HASH_LEN); 00559 wpa_hexdump(MSG_DEBUG, "WPS: R-Hash1", wps->peer_hash1, WPS_HASH_LEN); 00560 00561 return 0; 00562 } 00563 00564 00565 static int wps_process_r_hash2(struct wps_data *wps, const u8 *r_hash2) 00566 { 00567 if (r_hash2 == NULL) { 00568 wpa_printf(MSG_DEBUG, "WPS: No R-Hash2 received"); 00569 return -1; 00570 } 00571 00572 os_memcpy(wps->peer_hash2, r_hash2, WPS_HASH_LEN); 00573 wpa_hexdump(MSG_DEBUG, "WPS: R-Hash2", wps->peer_hash2, WPS_HASH_LEN); 00574 00575 return 0; 00576 } 00577 00578 00579 static int wps_process_r_snonce1(struct wps_data *wps, const u8 *r_snonce1) 00580 { 00581 u8 hash[SHA256_MAC_LEN]; 00582 const u8 *addr[4]; 00583 size_t len[4]; 00584 00585 if (r_snonce1 == NULL) { 00586 wpa_printf(MSG_DEBUG, "WPS: No R-SNonce1 received"); 00587 return -1; 00588 } 00589 00590 wpa_hexdump_key(MSG_DEBUG, "WPS: R-SNonce1", r_snonce1, 00591 WPS_SECRET_NONCE_LEN); 00592 00593 /* R-Hash1 = HMAC_AuthKey(R-S1 || PSK1 || PK_E || PK_R) */ 00594 addr[0] = r_snonce1; 00595 len[0] = WPS_SECRET_NONCE_LEN; 00596 addr[1] = wps->psk1; 00597 len[1] = WPS_PSK_LEN; 00598 addr[2] = wpabuf_head(wps->dh_pubkey_e); 00599 len[2] = wpabuf_len(wps->dh_pubkey_e); 00600 addr[3] = wpabuf_head(wps->dh_pubkey_r); 00601 len[3] = wpabuf_len(wps->dh_pubkey_r); 00602 hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash); 00603 00604 if (os_memcmp(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) { 00605 wpa_printf(MSG_DEBUG, "WPS: R-Hash1 derived from R-S1 does " 00606 "not match with the pre-committed value"); 00607 wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE; 00608 wps_pwd_auth_fail_event(wps->wps, 1, 1); 00609 return -1; 00610 } 00611 00612 wpa_printf(MSG_DEBUG, "WPS: Registrar proved knowledge of the first " 00613 "half of the device password"); 00614 00615 return 0; 00616 } 00617 00618 00619 static int wps_process_r_snonce2(struct wps_data *wps, const u8 *r_snonce2) 00620 { 00621 u8 hash[SHA256_MAC_LEN]; 00622 const u8 *addr[4]; 00623 size_t len[4]; 00624 00625 if (r_snonce2 == NULL) { 00626 wpa_printf(MSG_DEBUG, "WPS: No R-SNonce2 received"); 00627 return -1; 00628 } 00629 00630 wpa_hexdump_key(MSG_DEBUG, "WPS: R-SNonce2", r_snonce2, 00631 WPS_SECRET_NONCE_LEN); 00632 00633 /* R-Hash2 = HMAC_AuthKey(R-S2 || PSK2 || PK_E || PK_R) */ 00634 addr[0] = r_snonce2; 00635 len[0] = WPS_SECRET_NONCE_LEN; 00636 addr[1] = wps->psk2; 00637 len[1] = WPS_PSK_LEN; 00638 addr[2] = wpabuf_head(wps->dh_pubkey_e); 00639 len[2] = wpabuf_len(wps->dh_pubkey_e); 00640 addr[3] = wpabuf_head(wps->dh_pubkey_r); 00641 len[3] = wpabuf_len(wps->dh_pubkey_r); 00642 hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash); 00643 00644 if (os_memcmp(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) { 00645 wpa_printf(MSG_DEBUG, "WPS: R-Hash2 derived from R-S2 does " 00646 "not match with the pre-committed value"); 00647 wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE; 00648 wps_pwd_auth_fail_event(wps->wps, 1, 2); 00649 return -1; 00650 } 00651 00652 wpa_printf(MSG_DEBUG, "WPS: Registrar proved knowledge of the second " 00653 "half of the device password"); 00654 00655 return 0; 00656 } 00657 00658 00659 static int wps_process_cred_e(struct wps_data *wps, const u8 *cred, 00660 size_t cred_len) 00661 { 00662 struct wps_parse_attr attr; 00663 struct wpabuf msg; 00664 00665 wpa_printf(MSG_DEBUG, "WPS: Received Credential"); 00666 os_memset(&wps->cred, 0, sizeof(wps->cred)); 00667 wpabuf_set(&msg, cred, cred_len); 00668 if (wps_parse_msg(&msg, &attr) < 0 || 00669 wps_process_cred(&attr, &wps->cred)) 00670 return -1; 00671 00672 if (os_memcmp(wps->cred.mac_addr, wps->wps->dev.mac_addr, ETH_ALEN) != 00673 0) { 00674 wpa_printf(MSG_DEBUG, "WPS: MAC Address in the Credential (" 00675 MACSTR ") does not match with own address (" MACSTR 00676 ")", MAC2STR(wps->cred.mac_addr), 00677 MAC2STR(wps->wps->dev.mac_addr)); 00678 /* 00679 * In theory, this could be consider fatal error, but there are 00680 * number of deployed implementations using other address here 00681 * due to unclarity in the specification. For interoperability 00682 * reasons, allow this to be processed since we do not really 00683 * use the MAC Address information for anything. 00684 */ 00685 } 00686 00687 if (wps->wps->cred_cb) { 00688 wps->cred.cred_attr = cred - 4; 00689 wps->cred.cred_attr_len = cred_len + 4; 00690 wps->wps->cred_cb(wps->wps->cb_ctx, &wps->cred); 00691 wps->cred.cred_attr = NULL; 00692 wps->cred.cred_attr_len = 0; 00693 } 00694 00695 return 0; 00696 } 00697 00698 00699 static int wps_process_creds(struct wps_data *wps, const u8 *cred[], 00700 size_t cred_len[], size_t num_cred) 00701 { 00702 size_t i; 00703 00704 if (wps->wps->ap) 00705 return 0; 00706 00707 if (num_cred == 0) { 00708 wpa_printf(MSG_DEBUG, "WPS: No Credential attributes " 00709 "received"); 00710 return -1; 00711 } 00712 00713 for (i = 0; i < num_cred; i++) { 00714 if (wps_process_cred_e(wps, cred[i], cred_len[i])) 00715 return -1; 00716 } 00717 00718 return 0; 00719 } 00720 00721 00722 static int wps_process_ap_settings_e(struct wps_data *wps, 00723 struct wps_parse_attr *attr, 00724 struct wpabuf *attrs) 00725 { 00726 struct wps_credential cred; 00727 00728 if (!wps->wps->ap) 00729 return 0; 00730 00731 if (wps_process_ap_settings(attr, &cred) < 0) 00732 return -1; 00733 00734 wpa_printf(MSG_INFO, "WPS: Received new AP configuration from " 00735 "Registrar"); 00736 00737 if (os_memcmp(cred.mac_addr, wps->wps->dev.mac_addr, ETH_ALEN) != 00738 0) { 00739 wpa_printf(MSG_DEBUG, "WPS: MAC Address in the AP Settings (" 00740 MACSTR ") does not match with own address (" MACSTR 00741 ")", MAC2STR(cred.mac_addr), 00742 MAC2STR(wps->wps->dev.mac_addr)); 00743 /* 00744 * In theory, this could be consider fatal error, but there are 00745 * number of deployed implementations using other address here 00746 * due to unclarity in the specification. For interoperability 00747 * reasons, allow this to be processed since we do not really 00748 * use the MAC Address information for anything. 00749 */ 00750 } 00751 00752 if (wps->wps->cred_cb) { 00753 cred.cred_attr = wpabuf_head(attrs); 00754 cred.cred_attr_len = wpabuf_len(attrs); 00755 wps->wps->cred_cb(wps->wps->cb_ctx, &cred); 00756 } 00757 00758 return 0; 00759 } 00760 00761 00762 static enum wps_process_res wps_process_m2(struct wps_data *wps, 00763 const struct wpabuf *msg, 00764 struct wps_parse_attr *attr) 00765 { 00766 wpa_printf(MSG_DEBUG, "WPS: Received M2"); 00767 00768 if (wps->state != RECV_M2) { 00769 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for " 00770 "receiving M2", wps->state); 00771 wps->state = SEND_WSC_NACK; 00772 return WPS_CONTINUE; 00773 } 00774 00775 if (wps_process_registrar_nonce(wps, attr->registrar_nonce) || 00776 wps_process_enrollee_nonce(wps, attr->enrollee_nonce) || 00777 wps_process_uuid_r(wps, attr->uuid_r) || 00778 wps_process_pubkey(wps, attr->public_key, attr->public_key_len) || 00779 wps_process_authenticator(wps, attr->authenticator, msg) || 00780 wps_process_device_attrs(&wps->peer_dev, attr)) { 00781 wps->state = SEND_WSC_NACK; 00782 return WPS_CONTINUE; 00783 } 00784 00785 if (wps->wps->ap && wps->wps->ap_setup_locked) { 00786 wpa_printf(MSG_DEBUG, "WPS: AP Setup is locked - refuse " 00787 "registration of a new Registrar"); 00788 wps->config_error = WPS_CFG_SETUP_LOCKED; 00789 wps->state = SEND_WSC_NACK; 00790 return WPS_CONTINUE; 00791 } 00792 00793 wps->state = SEND_M3; 00794 return WPS_CONTINUE; 00795 } 00796 00797 00798 static enum wps_process_res wps_process_m2d(struct wps_data *wps, 00799 struct wps_parse_attr *attr) 00800 { 00801 wpa_printf(MSG_DEBUG, "WPS: Received M2D"); 00802 00803 if (wps->state != RECV_M2) { 00804 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for " 00805 "receiving M2D", wps->state); 00806 wps->state = SEND_WSC_NACK; 00807 return WPS_CONTINUE; 00808 } 00809 00810 wpa_hexdump_ascii(MSG_DEBUG, "WPS: Manufacturer", 00811 attr->manufacturer, attr->manufacturer_len); 00812 wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Name", 00813 attr->model_name, attr->model_name_len); 00814 wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Number", 00815 attr->model_number, attr->model_number_len); 00816 wpa_hexdump_ascii(MSG_DEBUG, "WPS: Serial Number", 00817 attr->serial_number, attr->serial_number_len); 00818 wpa_hexdump_ascii(MSG_DEBUG, "WPS: Device Name", 00819 attr->dev_name, attr->dev_name_len); 00820 00821 if (wps->wps->event_cb) { 00822 union wps_event_data data; 00823 struct wps_event_m2d *m2d = &data.m2d; 00824 os_memset(&data, 0, sizeof(data)); 00825 if (attr->config_methods) 00826 m2d->config_methods = 00827 WPA_GET_BE16(attr->config_methods); 00828 m2d->manufacturer = attr->manufacturer; 00829 m2d->manufacturer_len = attr->manufacturer_len; 00830 m2d->model_name = attr->model_name; 00831 m2d->model_name_len = attr->model_name_len; 00832 m2d->model_number = attr->model_number; 00833 m2d->model_number_len = attr->model_number_len; 00834 m2d->serial_number = attr->serial_number; 00835 m2d->serial_number_len = attr->serial_number_len; 00836 m2d->dev_name = attr->dev_name; 00837 m2d->dev_name_len = attr->dev_name_len; 00838 m2d->primary_dev_type = attr->primary_dev_type; 00839 if (attr->config_error) 00840 m2d->config_error = 00841 WPA_GET_BE16(attr->config_error); 00842 if (attr->dev_password_id) 00843 m2d->dev_password_id = 00844 WPA_GET_BE16(attr->dev_password_id); 00845 wps->wps->event_cb(wps->wps->cb_ctx, WPS_EV_M2D, &data); 00846 } 00847 00848 wps->state = RECEIVED_M2D; 00849 return WPS_CONTINUE; 00850 } 00851 00852 00853 static enum wps_process_res wps_process_m4(struct wps_data *wps, 00854 const struct wpabuf *msg, 00855 struct wps_parse_attr *attr) 00856 { 00857 struct wpabuf *decrypted; 00858 struct wps_parse_attr eattr; 00859 00860 wpa_printf(MSG_DEBUG, "WPS: Received M4"); 00861 00862 if (wps->state != RECV_M4) { 00863 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for " 00864 "receiving M4", wps->state); 00865 wps->state = SEND_WSC_NACK; 00866 return WPS_CONTINUE; 00867 } 00868 00869 if (wps_process_enrollee_nonce(wps, attr->enrollee_nonce) || 00870 wps_process_authenticator(wps, attr->authenticator, msg) || 00871 wps_process_r_hash1(wps, attr->r_hash1) || 00872 wps_process_r_hash2(wps, attr->r_hash2)) { 00873 wps->state = SEND_WSC_NACK; 00874 return WPS_CONTINUE; 00875 } 00876 00877 decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings, 00878 attr->encr_settings_len); 00879 if (decrypted == NULL) { 00880 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted " 00881 "Settings attribute"); 00882 wps->state = SEND_WSC_NACK; 00883 return WPS_CONTINUE; 00884 } 00885 00886 wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings " 00887 "attribute"); 00888 if (wps_parse_msg(decrypted, &eattr) < 0 || 00889 wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) || 00890 wps_process_r_snonce1(wps, eattr.r_snonce1)) { 00891 wpabuf_free(decrypted); 00892 wps->state = SEND_WSC_NACK; 00893 return WPS_CONTINUE; 00894 } 00895 wpabuf_free(decrypted); 00896 00897 wps->state = SEND_M5; 00898 return WPS_CONTINUE; 00899 } 00900 00901 00902 static enum wps_process_res wps_process_m6(struct wps_data *wps, 00903 const struct wpabuf *msg, 00904 struct wps_parse_attr *attr) 00905 { 00906 struct wpabuf *decrypted; 00907 struct wps_parse_attr eattr; 00908 00909 wpa_printf(MSG_DEBUG, "WPS: Received M6"); 00910 00911 if (wps->state != RECV_M6) { 00912 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for " 00913 "receiving M6", wps->state); 00914 wps->state = SEND_WSC_NACK; 00915 return WPS_CONTINUE; 00916 } 00917 00918 if (wps_process_enrollee_nonce(wps, attr->enrollee_nonce) || 00919 wps_process_authenticator(wps, attr->authenticator, msg)) { 00920 wps->state = SEND_WSC_NACK; 00921 return WPS_CONTINUE; 00922 } 00923 00924 decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings, 00925 attr->encr_settings_len); 00926 if (decrypted == NULL) { 00927 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted " 00928 "Settings attribute"); 00929 wps->state = SEND_WSC_NACK; 00930 return WPS_CONTINUE; 00931 } 00932 00933 wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings " 00934 "attribute"); 00935 if (wps_parse_msg(decrypted, &eattr) < 0 || 00936 wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) || 00937 wps_process_r_snonce2(wps, eattr.r_snonce2)) { 00938 wpabuf_free(decrypted); 00939 wps->state = SEND_WSC_NACK; 00940 return WPS_CONTINUE; 00941 } 00942 wpabuf_free(decrypted); 00943 00944 wps->state = SEND_M7; 00945 return WPS_CONTINUE; 00946 } 00947 00948 00949 static enum wps_process_res wps_process_m8(struct wps_data *wps, 00950 const struct wpabuf *msg, 00951 struct wps_parse_attr *attr) 00952 { 00953 struct wpabuf *decrypted; 00954 struct wps_parse_attr eattr; 00955 00956 wpa_printf(MSG_DEBUG, "WPS: Received M8"); 00957 00958 if (wps->state != RECV_M8) { 00959 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for " 00960 "receiving M8", wps->state); 00961 wps->state = SEND_WSC_NACK; 00962 return WPS_CONTINUE; 00963 } 00964 00965 if (wps_process_enrollee_nonce(wps, attr->enrollee_nonce) || 00966 wps_process_authenticator(wps, attr->authenticator, msg)) { 00967 wps->state = SEND_WSC_NACK; 00968 return WPS_CONTINUE; 00969 } 00970 00971 decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings, 00972 attr->encr_settings_len); 00973 if (decrypted == NULL) { 00974 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted " 00975 "Settings attribute"); 00976 wps->state = SEND_WSC_NACK; 00977 return WPS_CONTINUE; 00978 } 00979 00980 wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings " 00981 "attribute"); 00982 if (wps_parse_msg(decrypted, &eattr) < 0 || 00983 wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) || 00984 wps_process_creds(wps, eattr.cred, eattr.cred_len, 00985 eattr.num_cred) || 00986 wps_process_ap_settings_e(wps, &eattr, decrypted)) { 00987 wpabuf_free(decrypted); 00988 wps->state = SEND_WSC_NACK; 00989 return WPS_CONTINUE; 00990 } 00991 wpabuf_free(decrypted); 00992 00993 wps->state = WPS_MSG_DONE; 00994 return WPS_CONTINUE; 00995 } 00996 00997 00998 static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps, 00999 const struct wpabuf *msg) 01000 { 01001 struct wps_parse_attr attr; 01002 enum wps_process_res ret = WPS_CONTINUE; 01003 01004 wpa_printf(MSG_DEBUG, "WPS: Received WSC_MSG"); 01005 01006 if (wps_parse_msg(msg, &attr) < 0) 01007 return WPS_FAILURE; 01008 01009 if (!wps_version_supported(attr.version)) { 01010 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x", 01011 attr.version ? *attr.version : 0); 01012 return WPS_FAILURE; 01013 } 01014 01015 if (attr.enrollee_nonce == NULL || 01016 os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) { 01017 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce"); 01018 return WPS_FAILURE; 01019 } 01020 01021 if (attr.msg_type == NULL) { 01022 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute"); 01023 return WPS_FAILURE; 01024 } 01025 01026 switch (*attr.msg_type) { 01027 case WPS_M2: 01028 ret = wps_process_m2(wps, msg, &attr); 01029 break; 01030 case WPS_M2D: 01031 ret = wps_process_m2d(wps, &attr); 01032 break; 01033 case WPS_M4: 01034 ret = wps_process_m4(wps, msg, &attr); 01035 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK) 01036 wps_fail_event(wps->wps, WPS_M4); 01037 break; 01038 case WPS_M6: 01039 ret = wps_process_m6(wps, msg, &attr); 01040 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK) 01041 wps_fail_event(wps->wps, WPS_M6); 01042 break; 01043 case WPS_M8: 01044 ret = wps_process_m8(wps, msg, &attr); 01045 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK) 01046 wps_fail_event(wps->wps, WPS_M8); 01047 break; 01048 default: 01049 wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d", 01050 *attr.msg_type); 01051 return WPS_FAILURE; 01052 } 01053 01054 /* 01055 * Save a copy of the last message for Authenticator derivation if we 01056 * are continuing. However, skip M2D since it is not authenticated and 01057 * neither is the ACK/NACK response frame. This allows the possibly 01058 * following M2 to be processed correctly by using the previously sent 01059 * M1 in Authenticator derivation. 01060 */ 01061 if (ret == WPS_CONTINUE && *attr.msg_type != WPS_M2D) { 01062 /* Save a copy of the last message for Authenticator derivation 01063 */ 01064 wpabuf_free(wps->last_msg); 01065 wps->last_msg = wpabuf_dup(msg); 01066 } 01067 01068 return ret; 01069 } 01070 01071 01072 static enum wps_process_res wps_process_wsc_ack(struct wps_data *wps, 01073 const struct wpabuf *msg) 01074 { 01075 struct wps_parse_attr attr; 01076 01077 wpa_printf(MSG_DEBUG, "WPS: Received WSC_ACK"); 01078 01079 if (wps_parse_msg(msg, &attr) < 0) 01080 return WPS_FAILURE; 01081 01082 if (!wps_version_supported(attr.version)) { 01083 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x", 01084 attr.version ? *attr.version : 0); 01085 return WPS_FAILURE; 01086 } 01087 01088 if (attr.msg_type == NULL) { 01089 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute"); 01090 return WPS_FAILURE; 01091 } 01092 01093 if (*attr.msg_type != WPS_WSC_ACK) { 01094 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d", 01095 *attr.msg_type); 01096 return WPS_FAILURE; 01097 } 01098 01099 if (attr.registrar_nonce == NULL || 01100 os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0)) 01101 { 01102 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce"); 01103 return WPS_FAILURE; 01104 } 01105 01106 if (attr.enrollee_nonce == NULL || 01107 os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) { 01108 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce"); 01109 return WPS_FAILURE; 01110 } 01111 01112 if (wps->state == RECV_ACK && wps->wps->ap) { 01113 wpa_printf(MSG_DEBUG, "WPS: External Registrar registration " 01114 "completed successfully"); 01115 wps_success_event(wps->wps); 01116 wps->state = WPS_FINISHED; 01117 return WPS_DONE; 01118 } 01119 01120 return WPS_FAILURE; 01121 } 01122 01123 01124 static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps, 01125 const struct wpabuf *msg) 01126 { 01127 struct wps_parse_attr attr; 01128 01129 wpa_printf(MSG_DEBUG, "WPS: Received WSC_NACK"); 01130 01131 if (wps_parse_msg(msg, &attr) < 0) 01132 return WPS_FAILURE; 01133 01134 if (!wps_version_supported(attr.version)) { 01135 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x", 01136 attr.version ? *attr.version : 0); 01137 return WPS_FAILURE; 01138 } 01139 01140 if (attr.msg_type == NULL) { 01141 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute"); 01142 return WPS_FAILURE; 01143 } 01144 01145 if (*attr.msg_type != WPS_WSC_NACK) { 01146 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d", 01147 *attr.msg_type); 01148 return WPS_FAILURE; 01149 } 01150 01151 if (attr.registrar_nonce == NULL || 01152 os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0)) 01153 { 01154 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce"); 01155 wpa_hexdump(MSG_DEBUG, "WPS: Received Registrar Nonce", 01156 attr.registrar_nonce, WPS_NONCE_LEN); 01157 wpa_hexdump(MSG_DEBUG, "WPS: Expected Registrar Nonce", 01158 wps->nonce_r, WPS_NONCE_LEN); 01159 return WPS_FAILURE; 01160 } 01161 01162 if (attr.enrollee_nonce == NULL || 01163 os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) { 01164 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce"); 01165 wpa_hexdump(MSG_DEBUG, "WPS: Received Enrollee Nonce", 01166 attr.enrollee_nonce, WPS_NONCE_LEN); 01167 wpa_hexdump(MSG_DEBUG, "WPS: Expected Enrollee Nonce", 01168 wps->nonce_e, WPS_NONCE_LEN); 01169 return WPS_FAILURE; 01170 } 01171 01172 if (attr.config_error == NULL) { 01173 wpa_printf(MSG_DEBUG, "WPS: No Configuration Error attribute " 01174 "in WSC_NACK"); 01175 return WPS_FAILURE; 01176 } 01177 01178 wpa_printf(MSG_DEBUG, "WPS: Registrar terminated negotiation with " 01179 "Configuration Error %d", WPA_GET_BE16(attr.config_error)); 01180 01181 switch (wps->state) { 01182 case RECV_M4: 01183 wps_fail_event(wps->wps, WPS_M3); 01184 break; 01185 case RECV_M6: 01186 wps_fail_event(wps->wps, WPS_M5); 01187 break; 01188 case RECV_M8: 01189 wps_fail_event(wps->wps, WPS_M7); 01190 break; 01191 default: 01192 break; 01193 } 01194 01195 /* Followed by NACK if Enrollee is Supplicant or EAP-Failure if 01196 * Enrollee is Authenticator */ 01197 wps->state = SEND_WSC_NACK; 01198 01199 return WPS_FAILURE; 01200 } 01201 01202 01203 enum wps_process_res wps_enrollee_process_msg(struct wps_data *wps, 01204 enum wsc_op_code op_code, 01205 const struct wpabuf *msg) 01206 { 01207 01208 wpa_printf(MSG_DEBUG, "WPS: Processing received message (len=%lu " 01209 "op_code=%d)", 01210 (unsigned long) wpabuf_len(msg), op_code); 01211 01212 if (op_code == WSC_UPnP) { 01213 /* Determine the OpCode based on message type attribute */ 01214 struct wps_parse_attr attr; 01215 if (wps_parse_msg(msg, &attr) == 0 && attr.msg_type) { 01216 if (*attr.msg_type == WPS_WSC_ACK) 01217 op_code = WSC_ACK; 01218 else if (*attr.msg_type == WPS_WSC_NACK) 01219 op_code = WSC_NACK; 01220 } 01221 } 01222 01223 switch (op_code) { 01224 case WSC_MSG: 01225 case WSC_UPnP: 01226 return wps_process_wsc_msg(wps, msg); 01227 case WSC_ACK: 01228 return wps_process_wsc_ack(wps, msg); 01229 case WSC_NACK: 01230 return wps_process_wsc_nack(wps, msg); 01231 default: 01232 wpa_printf(MSG_DEBUG, "WPS: Unsupported op_code %d", op_code); 01233 return WPS_FAILURE; 01234 } 01235 }