WPS: Moved ProbeReq/AssocReq WPS IE building into wps_common.c

This code and the related attributes are not specific to Enrollee
functionality, so wps_common.c is the correct location for them.
This commit is contained in:
Jouni Malinen 2008-11-29 12:44:02 +02:00
parent 7d7c918d97
commit c0d041d9a7
7 changed files with 166 additions and 203 deletions

View file

@ -130,9 +130,8 @@ int wps_registrar_button_pushed(struct wps_registrar *reg);
void wps_registrar_probe_req_rx(struct wps_registrar *reg, const u8 *addr,
const struct wpabuf *wps_data);
struct wpabuf * wps_enrollee_build_assoc_req_ie(void);
struct wpabuf * wps_enrollee_build_probe_req_ie(int pbc,
struct wps_device_data *dev,
const u8 *uuid);
struct wpabuf * wps_build_assoc_req_ie(void);
struct wpabuf * wps_build_probe_req_ie(int pbc, struct wps_device_data *dev,
const u8 *uuid);
#endif /* WPS_H */

View file

@ -19,7 +19,9 @@
#include "sha256.h"
#include "aes_wrap.h"
#include "crypto.h"
#include "ieee802_11_defs.h"
#include "wps_i.h"
#include "wps_dev_attr.h"
static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
@ -499,6 +501,136 @@ int wps_build_public_key(struct wps_data *wps, struct wpabuf *msg)
}
static int wps_build_req_type(struct wpabuf *msg, enum wps_request_type type)
{
wpa_printf(MSG_DEBUG, "WPS: * Request Type");
wpabuf_put_be16(msg, ATTR_REQUEST_TYPE);
wpabuf_put_be16(msg, 1);
wpabuf_put_u8(msg, type);
return 0;
}
int wps_build_config_methods(struct wpabuf *msg, u16 methods)
{
wpa_printf(MSG_DEBUG, "WPS: * Config Methods (%x)", methods);
wpabuf_put_be16(msg, ATTR_CONFIG_METHODS);
wpabuf_put_be16(msg, 2);
wpabuf_put_be16(msg, methods);
return 0;
}
int wps_build_uuid_e(struct wpabuf *msg, const u8 *uuid)
{
wpa_printf(MSG_DEBUG, "WPS: * UUID-E");
wpabuf_put_be16(msg, ATTR_UUID_E);
wpabuf_put_be16(msg, WPS_UUID_LEN);
wpabuf_put_data(msg, uuid, WPS_UUID_LEN);
return 0;
}
int wps_build_rf_bands(struct wpabuf *msg, u8 rf_bands)
{
wpa_printf(MSG_DEBUG, "WPS: * RF Bands (%x)", rf_bands);
wpabuf_put_be16(msg, ATTR_RF_BANDS);
wpabuf_put_be16(msg, 1);
wpabuf_put_u8(msg, rf_bands);
return 0;
}
int wps_build_dev_password_id(struct wpabuf *msg, u16 id)
{
wpa_printf(MSG_DEBUG, "WPS: * Device Password ID (%d)", id);
wpabuf_put_be16(msg, ATTR_DEV_PASSWORD_ID);
wpabuf_put_be16(msg, 2);
wpabuf_put_be16(msg, id);
return 0;
}
int wps_build_config_error(struct wpabuf *msg, u16 err)
{
wpa_printf(MSG_DEBUG, "WPS: * Configuration Error (%d)", err);
wpabuf_put_be16(msg, ATTR_CONFIG_ERROR);
wpabuf_put_be16(msg, 2);
wpabuf_put_be16(msg, err);
return 0;
}
struct wpabuf * wps_build_assoc_req_ie(void)
{
struct wpabuf *ie;
u8 *len;
wpa_printf(MSG_DEBUG, "WPS: Building WPS IE for (Re)Association "
"Request");
ie = wpabuf_alloc(100);
if (ie == NULL)
return NULL;
wpabuf_put_u8(ie, WLAN_EID_VENDOR_SPECIFIC);
len = wpabuf_put(ie, 1);
wpabuf_put_be32(ie, WPS_DEV_OUI_WFA);
if (wps_build_version(ie) ||
wps_build_req_type(ie, WPS_REQ_ENROLLEE)) {
wpabuf_free(ie);
return NULL;
}
*len = wpabuf_len(ie) - 2;
return ie;
}
struct wpabuf * wps_build_probe_req_ie(int pbc, struct wps_device_data *dev,
const u8 *uuid)
{
struct wpabuf *ie;
u8 *len;
u16 methods;
wpa_printf(MSG_DEBUG, "WPS: Building WPS IE for Probe Request");
ie = wpabuf_alloc(200);
if (ie == NULL)
return NULL;
wpabuf_put_u8(ie, WLAN_EID_VENDOR_SPECIFIC);
len = wpabuf_put(ie, 1);
wpabuf_put_be32(ie, WPS_DEV_OUI_WFA);
if (pbc)
methods = WPS_CONFIG_PUSHBUTTON;
else
methods = WPS_CONFIG_LABEL | WPS_CONFIG_DISPLAY |
WPS_CONFIG_KEYPAD;
if (wps_build_version(ie) ||
wps_build_req_type(ie, WPS_REQ_ENROLLEE) ||
wps_build_config_methods(ie, methods) ||
wps_build_uuid_e(ie, uuid) ||
wps_build_primary_dev_type(dev, ie) ||
wps_build_rf_bands(ie, WPS_RF_24GHZ | WPS_RF_50GHZ) ||
wps_build_assoc_state(NULL, ie) ||
wps_build_config_error(ie, WPS_CFG_NO_ERROR) ||
wps_build_dev_password_id(ie, pbc ? DEV_PW_PUSHBUTTON :
DEV_PW_DEFAULT)) {
wpabuf_free(ie);
return NULL;
}
*len = wpabuf_len(ie) - 2;
return ie;
}
int wps_derive_keys(struct wps_data *wps)
{
struct wpabuf *pubkey, *dh_shared;

View file

@ -16,31 +16,10 @@
#include "common.h"
#include "sha256.h"
#include "ieee802_11_defs.h"
#include "wps_i.h"
#include "wps_dev_attr.h"
static int wps_build_req_type(struct wpabuf *msg, enum wps_request_type type)
{
wpa_printf(MSG_DEBUG, "WPS: * Request Type");
wpabuf_put_be16(msg, ATTR_REQUEST_TYPE);
wpabuf_put_be16(msg, 1);
wpabuf_put_u8(msg, type);
return 0;
}
static int wps_build_uuid_e(struct wpabuf *msg, const u8 *uuid)
{
wpa_printf(MSG_DEBUG, "WPS: * UUID-E");
wpabuf_put_be16(msg, ATTR_UUID_E);
wpabuf_put_be16(msg, WPS_UUID_LEN);
wpabuf_put_data(msg, uuid, WPS_UUID_LEN);
return 0;
}
static int wps_build_mac_addr(struct wps_data *wps, struct wpabuf *msg)
{
wpa_printf(MSG_DEBUG, "WPS: * MAC Address");
@ -51,16 +30,6 @@ static int wps_build_mac_addr(struct wps_data *wps, struct wpabuf *msg)
}
static int wps_build_config_methods(struct wpabuf *msg, u16 methods)
{
wpa_printf(MSG_DEBUG, "WPS: * Config Methods");
wpabuf_put_be16(msg, ATTR_CONFIG_METHODS);
wpabuf_put_be16(msg, 2);
wpabuf_put_be16(msg, methods);
return 0;
}
static int wps_build_wps_state(struct wps_data *wps, struct wpabuf *msg)
{
wpa_printf(MSG_DEBUG, "WPS: * Wi-Fi Protected Setup State");
@ -71,39 +40,6 @@ static int wps_build_wps_state(struct wps_data *wps, struct wpabuf *msg)
}
static int wps_build_rf_bands(struct wps_data *wps, struct wpabuf *msg)
{
wpa_printf(MSG_DEBUG, "WPS: * RF Bands");
wpabuf_put_be16(msg, ATTR_RF_BANDS);
wpabuf_put_be16(msg, 1);
wpabuf_put_u8(msg, WPS_RF_24GHZ | WPS_RF_50GHZ);
return 0;
}
static int wps_build_dev_password_id(struct wpabuf *msg, u16 id)
{
wpa_printf(MSG_DEBUG, "WPS: * Device Password ID");
wpabuf_put_be16(msg, ATTR_DEV_PASSWORD_ID);
wpabuf_put_be16(msg, 2);
wpabuf_put_be16(msg, id);
return 0;
}
static int wps_build_config_error(struct wps_data *wps, struct wpabuf *msg)
{
u16 err = WPS_CFG_NO_ERROR;
wpabuf_put_be16(msg, ATTR_CONFIG_ERROR);
wpabuf_put_be16(msg, 2);
if (wps && wps->authenticator && wps->wps->ap_setup_locked)
err = WPS_CFG_SETUP_LOCKED;
wpa_printf(MSG_DEBUG, "WPS: * Configuration Error (%d)", err);
wpabuf_put_be16(msg, err);
return 0;
}
static int wps_build_e_hash(struct wps_data *wps, struct wpabuf *msg)
{
u8 *hash;
@ -204,10 +140,10 @@ static struct wpabuf * wps_build_m1(struct wps_data *wps)
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, msg) ||
wps_build_rf_bands(msg, WPS_RF_24GHZ | WPS_RF_50GHZ) ||
wps_build_assoc_state(wps, msg) ||
wps_build_dev_password_id(msg, wps->dev_pw_id) ||
wps_build_config_error(wps, msg) ||
wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
wps_build_os_version(&wps->wps->dev, msg)) {
wpabuf_free(msg);
return NULL;
@ -420,6 +356,7 @@ static struct wpabuf * wps_build_wsc_ack(struct wps_data *wps)
static struct wpabuf * wps_build_wsc_nack(struct wps_data *wps)
{
struct wpabuf *msg;
u16 err = WPS_CFG_NO_ERROR;
wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_NACK");
@ -427,11 +364,14 @@ static struct wpabuf * wps_build_wsc_nack(struct wps_data *wps)
if (msg == NULL)
return NULL;
if (wps->authenticator && wps->wps->ap_setup_locked)
err = WPS_CFG_SETUP_LOCKED;
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(wps, msg)) {
wps_build_config_error(msg, err)) {
wpabuf_free(msg);
return NULL;
}
@ -1118,74 +1058,3 @@ enum wps_process_res wps_enrollee_process_msg(struct wps_data *wps, u8 op_code,
return WPS_FAILURE;
}
}
struct wpabuf * wps_enrollee_build_assoc_req_ie(void)
{
struct wpabuf *ie;
u8 *len;
wpa_printf(MSG_DEBUG, "WPS: Building WPS IE for (Re)Association "
"Request");
ie = wpabuf_alloc(100);
if (ie == NULL)
return NULL;
wpabuf_put_u8(ie, WLAN_EID_VENDOR_SPECIFIC);
len = wpabuf_put(ie, 1);
wpabuf_put_be32(ie, WPS_DEV_OUI_WFA);
if (wps_build_version(ie) ||
wps_build_req_type(ie, WPS_REQ_ENROLLEE)) {
wpabuf_free(ie);
return NULL;
}
*len = wpabuf_len(ie) - 2;
return ie;
}
struct wpabuf * wps_enrollee_build_probe_req_ie(int pbc,
struct wps_device_data *dev,
const u8 *uuid)
{
struct wpabuf *ie;
u8 *len;
u16 methods;
wpa_printf(MSG_DEBUG, "WPS: Building WPS IE for Probe Request");
ie = wpabuf_alloc(200);
if (ie == NULL)
return NULL;
wpabuf_put_u8(ie, WLAN_EID_VENDOR_SPECIFIC);
len = wpabuf_put(ie, 1);
wpabuf_put_be32(ie, WPS_DEV_OUI_WFA);
if (pbc)
methods = WPS_CONFIG_PUSHBUTTON;
else
methods = WPS_CONFIG_LABEL | WPS_CONFIG_DISPLAY |
WPS_CONFIG_KEYPAD;
if (wps_build_version(ie) ||
wps_build_req_type(ie, WPS_REQ_ENROLLEE) ||
wps_build_config_methods(ie, methods) ||
wps_build_uuid_e(ie, uuid) ||
wps_build_primary_dev_type(dev, ie) ||
wps_build_rf_bands(NULL, ie) ||
wps_build_assoc_state(NULL, ie) ||
wps_build_config_error(NULL, ie) ||
wps_build_dev_password_id(ie, pbc ? DEV_PW_PUSHBUTTON :
DEV_PW_DEFAULT)) {
wpabuf_free(ie);
return NULL;
}
*len = wpabuf_len(ie) - 2;
return ie;
}

View file

@ -159,6 +159,11 @@ int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr);
void wps_kdf(const u8 *key, const u8 *label_prefix, size_t label_prefix_len,
const char *label, u8 *res, size_t res_len);
int wps_build_public_key(struct wps_data *wps, struct wpabuf *msg);
int wps_build_config_methods(struct wpabuf *msg, u16 methods);
int wps_build_uuid_e(struct wpabuf *msg, const u8 *uuid);
int wps_build_rf_bands(struct wpabuf *msg, u8 rf_bands);
int wps_build_dev_password_id(struct wpabuf *msg, u16 id);
int wps_build_config_error(struct wpabuf *msg, u16 err);
int wps_derive_keys(struct wps_data *wps);
int wps_derive_mgmt_keys(struct wps_data *wps);
int wps_build_authenticator(struct wps_data *wps, struct wpabuf *msg);

View file

@ -275,39 +275,14 @@ static int wps_build_probe_config_methods(struct wps_registrar *reg,
}
static int wps_build_config_methods(struct wps_registrar *reg,
struct wpabuf *msg)
static int wps_build_config_methods_r(struct wps_registrar *reg,
struct wpabuf *msg)
{
u16 methods;
methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;
if (reg->pbc)
methods |= WPS_CONFIG_PUSHBUTTON;
wpa_printf(MSG_DEBUG, "WPS: * Config Methods (%x)", methods);
wpabuf_put_be16(msg, ATTR_CONFIG_METHODS);
wpabuf_put_be16(msg, 2);
wpabuf_put_be16(msg, methods);
return 0;
}
static int wps_build_rf_bands(struct wps_registrar *reg, struct wpabuf *msg)
{
u8 bands = WPS_RF_24GHZ /* TODO: | WPS_RF_50GHZ */;
wpa_printf(MSG_DEBUG, "WPS: * RF Bands (%x)", bands);
wpabuf_put_be16(msg, ATTR_RF_BANDS);
wpabuf_put_be16(msg, 1);
wpabuf_put_u8(msg, bands);
return 0;
}
static int wps_build_uuid_e(struct wps_registrar *reg, struct wpabuf *msg)
{
wpa_printf(MSG_DEBUG, "WPS: * UUID-E");
wpabuf_put_be16(msg, ATTR_UUID_E);
wpabuf_put_be16(msg, WPS_UUID_LEN);
wpabuf_put_data(msg, reg->wps->uuid, WPS_UUID_LEN);
return 0;
return wps_build_config_methods(msg, methods);
}
@ -606,10 +581,10 @@ static int wps_set_ie(struct wps_registrar *reg)
wps_build_sel_reg_dev_password_id(reg, probe) ||
wps_build_sel_reg_config_methods(reg, probe) ||
wps_build_resp_type(reg, probe) ||
wps_build_uuid_e(reg, probe) ||
wps_build_uuid_e(probe, reg->wps->uuid) ||
wps_build_device_attrs(&reg->wps->dev, probe) ||
wps_build_probe_config_methods(reg, probe) ||
wps_build_rf_bands(reg, probe)) {
wps_build_rf_bands(probe, WPS_RF_24GHZ /* TODO:|WPS_RF_50GHZ */)) {
wpabuf_free(beacon);
wpabuf_free(probe);
return -1;
@ -669,26 +644,6 @@ static int wps_build_uuid_r(struct wps_data *wps, struct wpabuf *msg)
}
static int wps_build_dev_password_id(struct wps_data *wps, struct wpabuf *msg)
{
wpa_printf(MSG_DEBUG, "WPS: * Device Password ID");
wpabuf_put_be16(msg, ATTR_DEV_PASSWORD_ID);
wpabuf_put_be16(msg, 2);
wpabuf_put_be16(msg, DEV_PW_DEFAULT);
return 0;
}
static int wps_build_config_error(struct wps_data *wps, struct wpabuf *msg)
{
wpa_printf(MSG_DEBUG, "WPS: * Configuration Error");
wpabuf_put_be16(msg, ATTR_CONFIG_ERROR);
wpabuf_put_be16(msg, 2);
wpabuf_put_be16(msg, WPS_CFG_NO_ERROR);
return 0;
}
static int wps_build_r_hash(struct wps_data *wps, struct wpabuf *msg)
{
u8 *hash;
@ -988,12 +943,12 @@ static struct wpabuf * wps_build_m2(struct wps_data *wps)
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(wps->registrar, msg) ||
wps_build_config_methods_r(wps->registrar, msg) ||
wps_build_device_attrs(&wps->wps->dev, msg) ||
wps_build_rf_bands(wps->registrar, msg) ||
wps_build_rf_bands(msg, WPS_RF_24GHZ /* TODO:|WPS_RF_50GHZ */) ||
wps_build_assoc_state(wps, msg) ||
wps_build_config_error(wps, msg) ||
wps_build_dev_password_id(wps, msg) ||
wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
wps_build_dev_password_id(msg, DEV_PW_DEFAULT) ||
wps_build_os_version(&wps->wps->dev, msg) ||
wps_build_authenticator(wps, msg)) {
wpabuf_free(msg);
@ -1008,12 +963,16 @@ static struct wpabuf * wps_build_m2(struct wps_data *wps)
static struct wpabuf * wps_build_m2d(struct wps_data *wps)
{
struct wpabuf *msg;
u16 err = WPS_CFG_NO_ERROR;
wpa_printf(MSG_DEBUG, "WPS: Building Message M2D");
msg = wpabuf_alloc(1000);
if (msg == NULL)
return NULL;
if (wps->authenticator && wps->wps->ap_setup_locked)
err = WPS_CFG_SETUP_LOCKED;
if (wps_build_version(msg) ||
wps_build_msg_type(msg, WPS_M2D) ||
wps_build_enrollee_nonce(wps, msg) ||
@ -1022,11 +981,11 @@ static struct wpabuf * wps_build_m2d(struct wps_data *wps)
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(wps->registrar, msg) ||
wps_build_config_methods_r(wps->registrar, msg) ||
wps_build_device_attrs(&wps->wps->dev, msg) ||
wps_build_rf_bands(wps->registrar, msg) ||
wps_build_rf_bands(msg, WPS_RF_24GHZ /* TODO:|WPS_RF_50GHZ */) ||
wps_build_assoc_state(wps, msg) ||
wps_build_config_error(wps, msg) ||
wps_build_config_error(msg, err) ||
wps_build_os_version(&wps->wps->dev, msg)) {
wpabuf_free(msg);
return NULL;

View file

@ -175,9 +175,8 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
#ifdef CONFIG_WPS
if (wps) {
wps_ie = wps_enrollee_build_probe_req_ie(wps == 2,
&wpa_s->wps->dev,
wpa_s->conf->uuid);
wps_ie = wps_build_probe_req_ie(wps == 2, &wpa_s->wps->dev,
wpa_s->conf->uuid);
if (wps_ie) {
extra_ie = wpabuf_head(wps_ie);
extra_ie_len = wpabuf_len(wps_ie);

View file

@ -1012,7 +1012,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
}
#ifdef CONFIG_WPS
} else if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
struct wpabuf *wps_ie = wps_enrollee_build_assoc_req_ie();
struct wpabuf *wps_ie = wps_build_assoc_req_ie();
if (wps_ie && wpabuf_len(wps_ie) <= sizeof(wpa_ie)) {
wpa_ie_len = wpabuf_len(wps_ie);
os_memcpy(wpa_ie, wpabuf_head(wps_ie), wpa_ie_len);