wps_enrollee.c

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

Generated on Sat Nov 21 23:16:54 2009 for hostapd by  doxygen 1.6.1