WPS 2.0: Fix Probe Request WPS IE building to be able to fragment data

If all the device information attributes use their maximum lengths,
a single WPS IE is not enough to fit in all the data and as such,
we must be able to fragment the data. In addition, the wpabuf needs
to be allocated larger to fit in maximum data.
This commit is contained in:
Jouni Malinen 2010-05-26 19:11:55 +03:00 committed by Jouni Malinen
parent dcc4d8be75
commit 6b633b4da7
4 changed files with 36 additions and 41 deletions

View File

@ -427,19 +427,14 @@ struct wpabuf * wps_build_probe_req_ie(int pbc, struct wps_device_data *dev,
enum wps_request_type req_type) enum wps_request_type req_type)
{ {
struct wpabuf *ie; struct wpabuf *ie;
u8 *len;
u16 methods; u16 methods;
wpa_printf(MSG_DEBUG, "WPS: Building WPS IE for Probe Request"); wpa_printf(MSG_DEBUG, "WPS: Building WPS IE for Probe Request");
ie = wpabuf_alloc(200); ie = wpabuf_alloc(500);
if (ie == NULL) if (ie == NULL)
return 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) { if (pbc) {
methods = WPS_CONFIG_PUSHBUTTON; methods = WPS_CONFIG_PUSHBUTTON;
/* /*
@ -486,9 +481,7 @@ struct wpabuf * wps_build_probe_req_ie(int pbc, struct wps_device_data *dev,
return NULL; return NULL;
} }
*len = wpabuf_len(ie) - 2; return wps_ie_encapsulate(ie);
return ie;
} }

View File

@ -19,6 +19,7 @@
#include "crypto/crypto.h" #include "crypto/crypto.h"
#include "crypto/dh_group5.h" #include "crypto/dh_group5.h"
#include "crypto/sha256.h" #include "crypto/sha256.h"
#include "common/ieee802_11_defs.h"
#include "wps_i.h" #include "wps_i.h"
@ -347,3 +348,35 @@ int wps_build_req_to_enroll(struct wpabuf *msg)
wpabuf_put_u8(msg, 1); wpabuf_put_u8(msg, 1);
return 0; return 0;
} }
/* Encapsulate WPS IE data with one (or more, if needed) IE headers */
struct wpabuf * wps_ie_encapsulate(struct wpabuf *data)
{
struct wpabuf *ie;
const u8 *pos, *end;
ie = wpabuf_alloc(wpabuf_len(data) + 100);
if (ie == NULL) {
wpabuf_free(data);
return NULL;
}
pos = wpabuf_head(data);
end = pos + wpabuf_len(data);
while (end > pos) {
size_t frag_len = end - pos;
if (frag_len > 251)
frag_len = 251;
wpabuf_put_u8(ie, WLAN_EID_VENDOR_SPECIFIC);
wpabuf_put_u8(ie, 4 + frag_len);
wpabuf_put_be32(ie, WPS_DEV_OUI_WFA);
wpabuf_put_data(ie, pos, frag_len);
pos += frag_len;
}
wpabuf_free(data);
return ie;
}

View File

@ -248,6 +248,7 @@ int wps_build_conn_type_flags(struct wps_data *wps, struct wpabuf *msg);
int wps_build_assoc_state(struct wps_data *wps, struct wpabuf *msg); int wps_build_assoc_state(struct wps_data *wps, struct wpabuf *msg);
int wps_build_oob_dev_password(struct wpabuf *msg, struct wps_context *wps); int wps_build_oob_dev_password(struct wpabuf *msg, struct wps_context *wps);
int wps_build_req_to_enroll(struct wpabuf *msg); int wps_build_req_to_enroll(struct wpabuf *msg);
struct wpabuf * wps_ie_encapsulate(struct wpabuf *data);
/* wps_attr_process.c */ /* wps_attr_process.c */
int wps_process_authenticator(struct wps_data *wps, const u8 *authenticator, int wps_process_authenticator(struct wps_data *wps, const u8 *authenticator,

View File

@ -958,38 +958,6 @@ static void wps_cb_set_sel_reg(struct wps_registrar *reg)
} }
/* Encapsulate WPS IE data with one (or more, if needed) IE headers */
static struct wpabuf * wps_ie_encapsulate(struct wpabuf *data)
{
struct wpabuf *ie;
const u8 *pos, *end;
ie = wpabuf_alloc(wpabuf_len(data) + 100);
if (ie == NULL) {
wpabuf_free(data);
return NULL;
}
pos = wpabuf_head(data);
end = pos + wpabuf_len(data);
while (end > pos) {
size_t frag_len = end - pos;
if (frag_len > 251)
frag_len = 251;
wpabuf_put_u8(ie, WLAN_EID_VENDOR_SPECIFIC);
wpabuf_put_u8(ie, 4 + frag_len);
wpabuf_put_be32(ie, WPS_DEV_OUI_WFA);
wpabuf_put_data(ie, pos, frag_len);
pos += frag_len;
}
wpabuf_free(data);
return ie;
}
static int wps_set_ie(struct wps_registrar *reg) static int wps_set_ie(struct wps_registrar *reg)
{ {
struct wpabuf *beacon; struct wpabuf *beacon;