⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wps_enrollee.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Wi-Fi Protected Setup - Enrollee * Copyright (c) 2008, Jouni Malinen <j@w1.fi> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Alternatively, this software may be distributed under the terms of BSD * license. * * See README and COPYING for more details. */#include "includes.h"#include "common.h"#include "sha256.h"#include "wps_i.h"#include "wps_dev_attr.h"static int wps_build_mac_addr(struct wps_data *wps, struct wpabuf *msg){	wpa_printf(MSG_DEBUG, "WPS:  * MAC Address");	wpabuf_put_be16(msg, ATTR_MAC_ADDR);	wpabuf_put_be16(msg, ETH_ALEN);	wpabuf_put_data(msg, wps->mac_addr_e, ETH_ALEN);	return 0;}static int wps_build_wps_state(struct wps_data *wps, struct wpabuf *msg){	u8 state;	if (wps->wps->ap)		state = wps->wps->wps_state;	else		state = WPS_STATE_NOT_CONFIGURED;	wpa_printf(MSG_DEBUG, "WPS:  * Wi-Fi Protected Setup State (%d)",		   state);	wpabuf_put_be16(msg, ATTR_WPS_STATE);	wpabuf_put_be16(msg, 1);	wpabuf_put_u8(msg, state);	return 0;}static int wps_build_e_hash(struct wps_data *wps, struct wpabuf *msg){	u8 *hash;	const u8 *addr[4];	size_t len[4];	if (os_get_random(wps->snonce, 2 * WPS_SECRET_NONCE_LEN) < 0)		return -1;	wpa_hexdump(MSG_DEBUG, "WPS: E-S1", wps->snonce, WPS_SECRET_NONCE_LEN);	wpa_hexdump(MSG_DEBUG, "WPS: E-S2",		    wps->snonce + WPS_SECRET_NONCE_LEN, WPS_SECRET_NONCE_LEN);	if (wps->dh_pubkey_e == NULL || wps->dh_pubkey_r == NULL) {		wpa_printf(MSG_DEBUG, "WPS: DH public keys not available for "			   "E-Hash derivation");		return -1;	}	wpa_printf(MSG_DEBUG, "WPS:  * E-Hash1");	wpabuf_put_be16(msg, ATTR_E_HASH1);	wpabuf_put_be16(msg, SHA256_MAC_LEN);	hash = wpabuf_put(msg, SHA256_MAC_LEN);	/* E-Hash1 = HMAC_AuthKey(E-S1 || PSK1 || PK_E || PK_R) */	addr[0] = wps->snonce;	len[0] = WPS_SECRET_NONCE_LEN;	addr[1] = wps->psk1;	len[1] = WPS_PSK_LEN;	addr[2] = wpabuf_head(wps->dh_pubkey_e);	len[2] = wpabuf_len(wps->dh_pubkey_e);	addr[3] = wpabuf_head(wps->dh_pubkey_r);	len[3] = wpabuf_len(wps->dh_pubkey_r);	hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);	wpa_hexdump(MSG_DEBUG, "WPS: E-Hash1", hash, SHA256_MAC_LEN);	wpa_printf(MSG_DEBUG, "WPS:  * E-Hash2");	wpabuf_put_be16(msg, ATTR_E_HASH2);	wpabuf_put_be16(msg, SHA256_MAC_LEN);	hash = wpabuf_put(msg, SHA256_MAC_LEN);	/* E-Hash2 = HMAC_AuthKey(E-S2 || PSK2 || PK_E || PK_R) */	addr[0] = wps->snonce + WPS_SECRET_NONCE_LEN;	addr[1] = wps->psk2;	hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);	wpa_hexdump(MSG_DEBUG, "WPS: E-Hash2", hash, SHA256_MAC_LEN);	return 0;}static int wps_build_e_snonce1(struct wps_data *wps, struct wpabuf *msg){	wpa_printf(MSG_DEBUG, "WPS:  * E-SNonce1");	wpabuf_put_be16(msg, ATTR_E_SNONCE1);	wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);	wpabuf_put_data(msg, wps->snonce, WPS_SECRET_NONCE_LEN);	return 0;}static int wps_build_e_snonce2(struct wps_data *wps, struct wpabuf *msg){	wpa_printf(MSG_DEBUG, "WPS:  * E-SNonce2");	wpabuf_put_be16(msg, ATTR_E_SNONCE2);	wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);	wpabuf_put_data(msg, wps->snonce + WPS_SECRET_NONCE_LEN,			WPS_SECRET_NONCE_LEN);	return 0;}static struct wpabuf * wps_build_m1(struct wps_data *wps){	struct wpabuf *msg;	u16 methods;	if (os_get_random(wps->nonce_e, WPS_NONCE_LEN) < 0)		return NULL;	wpa_hexdump(MSG_DEBUG, "WPS: Enrollee Nonce",		    wps->nonce_e, WPS_NONCE_LEN);	wpa_printf(MSG_DEBUG, "WPS: Building Message M1");	msg = wpabuf_alloc(1000);	if (msg == NULL)		return NULL;	methods = WPS_CONFIG_LABEL | WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD;	if (wps->pbc)		methods |= WPS_CONFIG_PUSHBUTTON;	if (wps_build_version(msg) ||	    wps_build_msg_type(msg, WPS_M1) ||	    wps_build_uuid_e(msg, wps->uuid_e) ||	    wps_build_mac_addr(wps, msg) ||	    wps_build_enrollee_nonce(wps, msg) ||	    wps_build_public_key(wps, msg) ||	    wps_build_auth_type_flags(wps, msg) ||	    wps_build_encr_type_flags(wps, msg) ||	    wps_build_conn_type_flags(wps, msg) ||	    wps_build_config_methods(msg, methods) ||	    wps_build_wps_state(wps, msg) ||	    wps_build_device_attrs(&wps->wps->dev, msg) ||	    wps_build_rf_bands(&wps->wps->dev, msg) ||	    wps_build_assoc_state(wps, msg) ||	    wps_build_dev_password_id(msg, wps->dev_pw_id) ||	    wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||	    wps_build_os_version(&wps->wps->dev, msg)) {		wpabuf_free(msg);		return NULL;	}	wps->state = RECV_M2;	return msg;}static struct wpabuf * wps_build_m3(struct wps_data *wps){	struct wpabuf *msg;	wpa_printf(MSG_DEBUG, "WPS: Building Message M3");	if (wps->dev_password == NULL) {		wpa_printf(MSG_DEBUG, "WPS: No Device Password available");		return NULL;	}	wps_derive_psk(wps, wps->dev_password, wps->dev_password_len);	msg = wpabuf_alloc(1000);	if (msg == NULL)		return NULL;	if (wps_build_version(msg) ||	    wps_build_msg_type(msg, WPS_M3) ||	    wps_build_registrar_nonce(wps, msg) ||	    wps_build_e_hash(wps, msg) ||	    wps_build_authenticator(wps, msg)) {		wpabuf_free(msg);		return NULL;	}	wps->state = RECV_M4;	return msg;}static struct wpabuf * wps_build_m5(struct wps_data *wps){	struct wpabuf *msg, *plain;	wpa_printf(MSG_DEBUG, "WPS: Building Message M5");	plain = wpabuf_alloc(200);	if (plain == NULL)		return NULL;	msg = wpabuf_alloc(1000);	if (msg == NULL) {		wpabuf_free(plain);		return NULL;	}	if (wps_build_version(msg) ||	    wps_build_msg_type(msg, WPS_M5) ||	    wps_build_registrar_nonce(wps, msg) ||	    wps_build_e_snonce1(wps, plain) ||	    wps_build_key_wrap_auth(wps, plain) ||	    wps_build_encr_settings(wps, msg, plain) ||	    wps_build_authenticator(wps, msg)) {		wpabuf_free(plain);		wpabuf_free(msg);		return NULL;	}	wpabuf_free(plain);	wps->state = RECV_M6;	return msg;}static int wps_build_cred_ssid(struct wps_data *wps, struct wpabuf *msg){	wpa_printf(MSG_DEBUG, "WPS:  * SSID");	wpabuf_put_be16(msg, ATTR_SSID);	wpabuf_put_be16(msg, wps->wps->ssid_len);	wpabuf_put_data(msg, wps->wps->ssid, wps->wps->ssid_len);	return 0;}static int wps_build_cred_auth_type(struct wps_data *wps, struct wpabuf *msg){	wpa_printf(MSG_DEBUG, "WPS:  * Authentication Type");	wpabuf_put_be16(msg, ATTR_AUTH_TYPE);	wpabuf_put_be16(msg, 2);	wpabuf_put_be16(msg, wps->wps->auth_types);	return 0;}static int wps_build_cred_encr_type(struct wps_data *wps, struct wpabuf *msg){	wpa_printf(MSG_DEBUG, "WPS:  * Encryption Type");	wpabuf_put_be16(msg, ATTR_ENCR_TYPE);	wpabuf_put_be16(msg, 2);	wpabuf_put_be16(msg, wps->wps->encr_types);	return 0;}static int wps_build_cred_network_key(struct wps_data *wps, struct wpabuf *msg){	wpa_printf(MSG_DEBUG, "WPS:  * Network Key");	wpabuf_put_be16(msg, ATTR_NETWORK_KEY);	wpabuf_put_be16(msg, wps->wps->network_key_len);	wpabuf_put_data(msg, wps->wps->network_key, wps->wps->network_key_len);	return 0;}static int wps_build_cred_mac_addr(struct wps_data *wps, struct wpabuf *msg){	wpa_printf(MSG_DEBUG, "WPS:  * MAC Address (AP BSSID)");	wpabuf_put_be16(msg, ATTR_MAC_ADDR);	wpabuf_put_be16(msg, ETH_ALEN);	wpabuf_put_data(msg, wps->wps->dev.mac_addr, ETH_ALEN);	return 0;}static int wps_build_ap_settings(struct wps_data *wps, struct wpabuf *plain){	if (wps->wps->ap_settings) {		wpa_printf(MSG_DEBUG, "WPS:  * AP Settings (pre-configured)");		wpabuf_put_data(plain, wps->wps->ap_settings,				wps->wps->ap_settings_len);		return 0;	}	return wps_build_cred_ssid(wps, plain) ||		wps_build_cred_mac_addr(wps, plain) ||		wps_build_cred_auth_type(wps, plain) ||		wps_build_cred_encr_type(wps, plain) ||		wps_build_cred_network_key(wps, plain);}static struct wpabuf * wps_build_m7(struct wps_data *wps){	struct wpabuf *msg, *plain;	wpa_printf(MSG_DEBUG, "WPS: Building Message M7");	plain = wpabuf_alloc(500 + wps->wps->ap_settings_len);	if (plain == NULL)		return NULL;	msg = wpabuf_alloc(1000 + wps->wps->ap_settings_len);	if (msg == NULL) {		wpabuf_free(plain);		return NULL;	}	if (wps_build_version(msg) ||	    wps_build_msg_type(msg, WPS_M7) ||	    wps_build_registrar_nonce(wps, msg) ||	    wps_build_e_snonce2(wps, plain) ||	    (wps->wps->ap && wps_build_ap_settings(wps, plain)) ||	    wps_build_key_wrap_auth(wps, plain) ||	    wps_build_encr_settings(wps, msg, plain) ||	    wps_build_authenticator(wps, msg)) {		wpabuf_free(plain);		wpabuf_free(msg);		return NULL;	}	wpabuf_free(plain);	wps->state = RECV_M8;	return msg;}static struct wpabuf * wps_build_wsc_done(struct wps_data *wps){	struct wpabuf *msg;	wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_Done");	msg = wpabuf_alloc(1000);	if (msg == NULL)		return NULL;	if (wps_build_version(msg) ||	    wps_build_msg_type(msg, WPS_WSC_DONE) ||	    wps_build_enrollee_nonce(wps, msg) ||	    wps_build_registrar_nonce(wps, msg)) {		wpabuf_free(msg);		return NULL;	}	if (wps->wps->ap)		wps->state = RECV_ACK;	else {		wps_success_event(wps->wps);		wps->state = WPS_FINISHED;	}	return msg;}static struct wpabuf * wps_build_wsc_ack(struct wps_data *wps){	struct wpabuf *msg;	wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_ACK");	msg = wpabuf_alloc(1000);	if (msg == NULL)		return NULL;	if (wps_build_version(msg) ||	    wps_build_msg_type(msg, WPS_WSC_ACK) ||	    wps_build_enrollee_nonce(wps, msg) ||	    wps_build_registrar_nonce(wps, msg)) {		wpabuf_free(msg);		return NULL;	}	return msg;}static struct wpabuf * wps_build_wsc_nack(struct wps_data *wps){	struct wpabuf *msg;	wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_NACK");	msg = wpabuf_alloc(1000);	if (msg == NULL)		return NULL;	if (wps_build_version(msg) ||	    wps_build_msg_type(msg, WPS_WSC_NACK) ||	    wps_build_enrollee_nonce(wps, msg) ||	    wps_build_registrar_nonce(wps, msg) ||	    wps_build_config_error(msg, wps->config_error)) {		wpabuf_free(msg);		return NULL;	}	return msg;}struct wpabuf * wps_enrollee_get_msg(struct wps_data *wps,				     enum wsc_op_code *op_code){	struct wpabuf *msg;	switch (wps->state) {	case SEND_M1:		msg = wps_build_m1(wps);		*op_code = WSC_MSG;		break;	case SEND_M3:		msg = wps_build_m3(wps);		*op_code = WSC_MSG;		break;	case SEND_M5:		msg = wps_build_m5(wps);		*op_code = WSC_MSG;		break;	case SEND_M7:		msg = wps_build_m7(wps);		*op_code = WSC_MSG;		break;	case RECEIVED_M2D:		if (wps->wps->ap) {			msg = wps_build_wsc_nack(wps);			*op_code = WSC_NACK;			break;		}		msg = wps_build_wsc_ack(wps);		*op_code = WSC_ACK;		if (msg) {			/* Another M2/M2D may be received */			wps->state = RECV_M2;		}		break;	case SEND_WSC_NACK:		msg = wps_build_wsc_nack(wps);		*op_code = WSC_NACK;		break;	case WPS_MSG_DONE:		msg = wps_build_wsc_done(wps);		*op_code = WSC_Done;		break;	default:		wpa_printf(MSG_DEBUG, "WPS: Unsupported state %d for building "			   "a message", wps->state);		msg = NULL;		break;	}	if (*op_code == WSC_MSG && msg) {		/* Save a copy of the last message for Authenticator derivation		 */		wpabuf_free(wps->last_msg);		wps->last_msg = wpabuf_dup(msg);	}	return msg;}static int wps_process_registrar_nonce(struct wps_data *wps, const u8 *r_nonce){	if (r_nonce == NULL) {		wpa_printf(MSG_DEBUG, "WPS: No Registrar Nonce received");		return -1;	}	os_memcpy(wps->nonce_r, r_nonce, WPS_NONCE_LEN);	wpa_hexdump(MSG_DEBUG, "WPS: Registrar Nonce",		    wps->nonce_r, WPS_NONCE_LEN);	return 0;}static int wps_process_enrollee_nonce(struct wps_data *wps, const u8 *e_nonce){	if (e_nonce == NULL) {		wpa_printf(MSG_DEBUG, "WPS: No Enrollee Nonce received");		return -1;	}	if (os_memcmp(wps->nonce_e, e_nonce, WPS_NONCE_LEN) != 0) {		wpa_printf(MSG_DEBUG, "WPS: Invalid Enrollee Nonce received");		return -1;	}	return 0;}static int wps_process_uuid_r(struct wps_data *wps, const u8 *uuid_r){	if (uuid_r == NULL) {		wpa_printf(MSG_DEBUG, "WPS: No UUID-R received");		return -1;	}	os_memcpy(wps->uuid_r, uuid_r, WPS_UUID_LEN);	wpa_hexdump(MSG_DEBUG, "WPS: UUID-R", wps->uuid_r, WPS_UUID_LEN);	return 0;}static int wps_process_pubkey(struct wps_data *wps, const u8 *pk,			      size_t pk_len){	if (pk == NULL || pk_len == 0) {		wpa_printf(MSG_DEBUG, "WPS: No Public Key received");		return -1;	}	wpabuf_free(wps->dh_pubkey_r);	wps->dh_pubkey_r = wpabuf_alloc_copy(pk, pk_len);	if (wps->dh_pubkey_r == NULL)		return -1;	if (wps_derive_keys(wps) < 0)		return -1;	if (wps->request_type == WPS_REQ_WLAN_MANAGER_REGISTRAR &&	    wps_derive_mgmt_keys(wps) < 0)		return -1;	return 0;}static int wps_process_r_hash1(struct wps_data *wps, const u8 *r_hash1){	if (r_hash1 == NULL) {		wpa_printf(MSG_DEBUG, "WPS: No R-Hash1 received");		return -1;	}	os_memcpy(wps->peer_hash1, r_hash1, WPS_HASH_LEN);	wpa_hexdump(MSG_DEBUG, "WPS: R-Hash1", wps->peer_hash1, WPS_HASH_LEN);	return 0;}static int wps_process_r_hash2(struct wps_data *wps, const u8 *r_hash2){	if (r_hash2 == NULL) {		wpa_printf(MSG_DEBUG, "WPS: No R-Hash2 received");		return -1;	}	os_memcpy(wps->peer_hash2, r_hash2, WPS_HASH_LEN);	wpa_hexdump(MSG_DEBUG, "WPS: R-Hash2", wps->peer_hash2, WPS_HASH_LEN);	return 0;}static int wps_process_r_snonce1(struct wps_data *wps, const u8 *r_snonce1){	u8 hash[SHA256_MAC_LEN];	const u8 *addr[4];	size_t len[4];	if (r_snonce1 == NULL) {		wpa_printf(MSG_DEBUG, "WPS: No R-SNonce1 received");		return -1;	}	wpa_hexdump_key(MSG_DEBUG, "WPS: R-SNonce1", r_snonce1,			WPS_SECRET_NONCE_LEN);	/* R-Hash1 = HMAC_AuthKey(R-S1 || PSK1 || PK_E || PK_R) */	addr[0] = r_snonce1;	len[0] = WPS_SECRET_NONCE_LEN;	addr[1] = wps->psk1;	len[1] = WPS_PSK_LEN;	addr[2] = wpabuf_head(wps->dh_pubkey_e);	len[2] = wpabuf_len(wps->dh_pubkey_e);	addr[3] = wpabuf_head(wps->dh_pubkey_r);	len[3] = wpabuf_len(wps->dh_pubkey_r);	hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);	if (os_memcmp(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) {		wpa_printf(MSG_DEBUG, "WPS: R-Hash1 derived from R-S1 does "			   "not match with the pre-committed value");		wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -