Example #1
0
static struct wpabuf * wps_build_m1(struct wps_data *wps)
{
	struct wpabuf *msg;
	u16 config_methods;

	if (random_get_bytes(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;

	config_methods = wps->wps->config_methods;
	if (wps->wps->ap && !wps->pbc_in_m1 &&
	    (wps->dev_password_len != 0 ||
	     (config_methods & WPS_CONFIG_DISPLAY))) {
		/*
		 * These are the methods that the AP supports as an Enrollee
		 * for adding external Registrars, so remove PushButton.
		 *
		 * As a workaround for Windows 7 mechanism for probing WPS
		 * capabilities from M1, leave PushButton option if no PIN
		 * method is available or if WPS configuration enables PBC
		 * workaround.
		 */
		config_methods &= ~WPS_CONFIG_PUSHBUTTON;
		config_methods &= ~(WPS_CONFIG_VIRT_PUSHBUTTON |
				    WPS_CONFIG_PHY_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(msg, wps->mac_addr_e) ||
	    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, config_methods) ||
	    wps_build_wps_state(wps, msg) ||
	    wps_build_device_attrs(&wps->wps->dev, msg) ||
	    wps_build_rf_bands(&wps->wps->dev, msg,
			       wps->wps->rf_band_cb(wps->wps->cb_ctx)) ||
	    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) ||
	    wps_build_wfa_ext(msg, 0, NULL, 0) ||
	    wps_build_vendor_ext_m1(&wps->wps->dev, msg)) {
		wpabuf_free(msg);
		return NULL;
	}

	wps->state = RECV_M2;
	return msg;
}
Example #2
0
struct wpabuf * wps_build_nfc_handover_req_p2p(struct wps_context *ctx,
					       struct wpabuf *nfc_dh_pubkey)
{
	struct wpabuf *msg;

	if (ctx == NULL)
		return NULL;

	wpa_printf(MSG_DEBUG, "WPS: Building attributes for NFC connection "
		   "handover request (P2P)");

	if (nfc_dh_pubkey == NULL) {
		wpa_printf(MSG_DEBUG, "WPS: No NFC DH Public Key configured");
		return NULL;
	}

	msg = wpabuf_alloc(1000);
	if (msg == NULL)
		return msg;

	if (wps_build_manufacturer(&ctx->dev, msg) ||
	    wps_build_model_name(&ctx->dev, msg) ||
	    wps_build_model_number(&ctx->dev, msg) ||
	    wps_build_oob_dev_pw(msg, DEV_PW_NFC_CONNECTION_HANDOVER,
				 nfc_dh_pubkey, NULL, 0) ||
	    wps_build_rf_bands(&ctx->dev, msg, 0) ||
	    wps_build_serial_number(&ctx->dev, msg) ||
	    wps_build_uuid_e(msg, ctx->uuid) ||
	    wps_build_wfa_ext(msg, 0, NULL, 0)) {
		wpabuf_free(msg);
		return NULL;
	}

	return msg;
}
Example #3
0
struct wpabuf * wps_build_nfc_handover_sel_p2p(struct wps_context *ctx,
					       int nfc_dev_pw_id,
					       struct wpabuf *nfc_dh_pubkey,
					       struct wpabuf *nfc_dev_pw)
{
	struct wpabuf *msg;
	const u8 *dev_pw;
	size_t dev_pw_len;

	if (ctx == NULL)
		return NULL;

	wpa_printf(MSG_DEBUG, "WPS: Building attributes for NFC connection "
		   "handover select (P2P)");

	if (nfc_dh_pubkey == NULL ||
	    (nfc_dev_pw_id != DEV_PW_NFC_CONNECTION_HANDOVER &&
	     nfc_dev_pw == NULL)) {
		wpa_printf(MSG_DEBUG, "WPS: No NFC OOB Device Password "
			   "configured");
		return NULL;
	}

	msg = wpabuf_alloc(1000);
	if (msg == NULL)
		return msg;

	if (nfc_dev_pw) {
		dev_pw = wpabuf_head(nfc_dev_pw);
		dev_pw_len = wpabuf_len(nfc_dev_pw);
	} else {
		dev_pw = NULL;
		dev_pw_len = 0;
	}

	if (wps_build_manufacturer(&ctx->dev, msg) ||
	    wps_build_model_name(&ctx->dev, msg) ||
	    wps_build_model_number(&ctx->dev, msg) ||
	    wps_build_oob_dev_pw(msg, nfc_dev_pw_id, nfc_dh_pubkey,
				 dev_pw, dev_pw_len) ||
	    wps_build_rf_bands(&ctx->dev, msg, 0) ||
	    wps_build_serial_number(&ctx->dev, msg) ||
	    wps_build_uuid_e(msg, ctx->uuid) ||
	    wps_build_wfa_ext(msg, 0, NULL, 0)) {
		wpabuf_free(msg);
		return NULL;
	}

	return msg;
}
Example #4
0
/**
 * wps_build_probe_req_ie - Build WPS IE for Probe Request
 * @pbc: Whether searching for PBC mode APs
 * @dev: Device attributes
 * @uuid: Own UUID
 * @req_type: Value for Request Type attribute
 * @num_req_dev_types: Number of requested device types
 * @req_dev_types: Requested device types (8 * num_req_dev_types octets) or
 *	%NULL if none
 * Returns: WPS IE or %NULL on failure
 *
 * The caller is responsible for freeing the buffer.
 */
struct wpabuf * wps_build_probe_req_ie(int pbc, struct wps_device_data *dev,
				       const u8 *uuid,
				       enum wps_request_type req_type,
				       unsigned int num_req_dev_types,
				       const u8 *req_dev_types)
{
	struct wpabuf *ie;

	wpa_printf(MSG_DEBUG, "WPS: Building WPS IE for Probe Request");

	ie = wpabuf_alloc(500);
	if (ie == NULL)
		return NULL;

	if (wps_build_version(ie) ||
	    wps_build_req_type(ie, req_type) ||
	    wps_build_config_methods(ie, dev->config_methods) ||
	    wps_build_uuid_e(ie, uuid) ||
	    wps_build_primary_dev_type(dev, ie) ||
	    wps_build_rf_bands(dev, ie) ||
	    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) ||
#ifdef CONFIG_WPS2
	    wps_build_manufacturer(dev, ie) ||
	    wps_build_model_name(dev, ie) ||
	    wps_build_model_number(dev, ie) ||
	    wps_build_dev_name(dev, ie) ||
	    wps_build_wfa_ext(ie, req_type == WPS_REQ_ENROLLEE, NULL, 0) ||
#endif /* CONFIG_WPS2 */
	    wps_build_req_dev_type(dev, ie, num_req_dev_types, req_dev_types)
	    ||
	    wps_build_secondary_dev_type(dev, ie)
		) {
		wpabuf_free(ie);
		return NULL;
	}

#ifndef CONFIG_WPS2
	if (dev->p2p && wps_build_dev_name(dev, ie)) {
		wpabuf_free(ie);
		return NULL;
	}
#endif /* CONFIG_WPS2 */

	return wps_ie_encapsulate(ie);
}
Example #5
0
/**
 * wps_build_probe_req_ie - Build WPS IE for Probe Request
 * @pbc: Whether searching for PBC mode APs
 * @dev: Device attributes
 * @uuid: Own UUID
 * @req_type: Value for Request Type attribute
 * Returns: WPS IE or %NULL on failure
 *
 * The caller is responsible for freeing the buffer.
 */
struct wpabuf * wps_build_probe_req_ie(int pbc, struct wps_device_data *dev,
        const u8 *uuid,
        enum wps_request_type req_type) {
    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;
#ifdef CONFIG_WPS_UFD
        methods |= WPS_CONFIG_USBA;
#endif /* CONFIG_WPS_UFD */
#ifdef CONFIG_WPS_NFC
        methods |= WPS_CONFIG_NFC_INTERFACE;
#endif /* CONFIG_WPS_NFC */
    }

    if (wps_build_version(ie) ||
            wps_build_req_type(ie, req_type) ||
            wps_build_config_methods(ie, methods) ||
            wps_build_uuid_e(ie, uuid) ||
            wps_build_primary_dev_type(dev, ie) ||
            wps_build_rf_bands(dev, ie) ||
            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;
}
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;
}
Example #7
0
/**
 * wps_build_probe_req_ie - Build WPS IE for Probe Request
 * @pbc: Whether searching for PBC mode APs
 * @dev: Device attributes
 * @uuid: Own UUID
 * @req_type: Value for Request Type attribute
 * @num_req_dev_types: Number of requested device types
 * @req_dev_types: Requested device types (8 * num_req_dev_types octets) or
 *	%NULL if none
 * Returns: WPS IE or %NULL on failure
 *
 * The caller is responsible for freeing the buffer.
 */
struct wpabuf * wps_build_probe_req_ie(int pbc, struct wps_device_data *dev,
				       const u8 *uuid,
				       enum wps_request_type req_type,
				       unsigned int num_req_dev_types,
				       const u8 *req_dev_types)
{
	struct wpabuf *ie;
	u16 methods = 0;

	wpa_printf(MSG_DEBUG, "WPS: Building WPS IE for Probe Request");

	ie = wpabuf_alloc(500);
	if (ie == NULL)
		return NULL;

	methods |= WPS_CONFIG_PUSHBUTTON;
#ifdef CONFIG_WPS2
	/*
	 * TODO: Should figure out whether this device has a physical or
	 * virtual pushbutton.
	 */
	methods |= WPS_CONFIG_VIRT_PUSHBUTTON;
#endif /* CONFIG_WPS2 */

	/*
	 * TODO: Should figure out whether this Probe Request was triggered
	 * using physical or virtual display. Also, if the device has a PIN on
	 * a label, that should be indicated here.
	 */
	methods |= WPS_CONFIG_DISPLAY |
#ifdef CONFIG_WPS2
		WPS_CONFIG_VIRT_DISPLAY |
#endif /* CONFIG_WPS2 */
		WPS_CONFIG_KEYPAD;
#ifdef CONFIG_WPS_UFD
	methods |= WPS_CONFIG_USBA;
#endif /* CONFIG_WPS_UFD */
#ifdef CONFIG_WPS_NFC
	methods |= WPS_CONFIG_NFC_INTERFACE;
#endif /* CONFIG_WPS_NFC */

	if (wps_build_version(ie) ||
	    wps_build_req_type(ie, req_type) ||
	    wps_build_config_methods(ie, methods) ||
	    wps_build_uuid_e(ie, uuid) ||
	    wps_build_primary_dev_type(dev, ie) ||
	    wps_build_rf_bands(dev, ie) ||
	    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) ||
#ifdef CONFIG_WPS2
	    wps_build_manufacturer(dev, ie) ||
	    wps_build_model_name(dev, ie) ||
	    wps_build_model_number(dev, ie) ||
	    wps_build_dev_name(dev, ie) ||
	    wps_build_wfa_ext(ie, req_type == WPS_REQ_ENROLLEE, NULL, 0) ||
#endif /* CONFIG_WPS2 */
	    wps_build_req_dev_type(dev, ie, num_req_dev_types, req_dev_types)
	    ||
	    wps_build_secondary_dev_type(dev, ie)
		) {
		wpabuf_free(ie);
		return NULL;
	}

#ifndef CONFIG_WPS2
	if (dev->p2p && wps_build_dev_name(dev, ie)) {
		wpabuf_free(ie);
		return NULL;
	}
#endif /* CONFIG_WPS2 */

	return wps_ie_encapsulate(ie);
}
Example #8
0
/**
 * wps_build_probe_req_ie - Build WPS IE for Probe Request
 * @pw_id: Password ID (DEV_PW_PUSHBUTTON for active PBC and DEV_PW_DEFAULT for
 * most other use cases)
 * @dev: Device attributes
 * @uuid: Own UUID
 * @req_type: Value for Request Type attribute
 * @num_req_dev_types: Number of requested device types
 * @req_dev_types: Requested device types (8 * num_req_dev_types octets) or
 *	%NULL if none
 * Returns: WPS IE or %NULL on failure
 *
 * The caller is responsible for freeing the buffer.
 */
struct wpabuf *wps_build_probe_req_ie(u16 pw_id, struct wps_device_data *dev, const u8 *uuid, enum wps_request_type req_type, unsigned int num_req_dev_types, const u8 *req_dev_types)
{
	struct wpabuf *ie;

	wpa_printf(MSG_DEBUG, "WPS: Building WPS IE for Probe Request");

	ie = wpabuf_alloc(500);
	if (ie == NULL) {
		return NULL;
	}

	if (wps_build_version(ie) || wps_build_req_type(ie, req_type) || wps_build_config_methods(ie, dev->config_methods) || wps_build_uuid_e(ie, uuid) || wps_build_primary_dev_type(dev, ie) || wps_build_rf_bands(dev, ie, 0) || wps_build_assoc_state(NULL, ie) || wps_build_config_error(ie, WPS_CFG_NO_ERROR) || wps_build_dev_password_id(ie, pw_id) || wps_build_manufacturer(dev, ie) || wps_build_model_name(dev, ie) || wps_build_model_number(dev, ie) || wps_build_dev_name(dev, ie) || wps_build_wfa_ext(ie, req_type == WPS_REQ_ENROLLEE, NULL, 0) || wps_build_req_dev_type(dev, ie, num_req_dev_types, req_dev_types)
		|| wps_build_secondary_dev_type(dev, ie)
	   ) {
		wpabuf_free(ie);
		return NULL;
	}

	return wps_ie_encapsulate(ie);
}