mirror of
https://github.com/vanhoefm/fragattacks.git
synced 2025-02-26 13:49:35 -05:00
DPP2: GAS comeback request processing for Configurator over TCP
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
parent
68d9586a46
commit
18e013a93f
@ -38,7 +38,9 @@ struct dpp_connection {
|
|||||||
unsigned int on_tcp_tx_complete_gas_done:1;
|
unsigned int on_tcp_tx_complete_gas_done:1;
|
||||||
unsigned int on_tcp_tx_complete_remove:1;
|
unsigned int on_tcp_tx_complete_remove:1;
|
||||||
unsigned int on_tcp_tx_complete_auth_ok:1;
|
unsigned int on_tcp_tx_complete_auth_ok:1;
|
||||||
|
unsigned int gas_comeback_in_progress:1;
|
||||||
u8 gas_dialog_token;
|
u8 gas_dialog_token;
|
||||||
|
struct wpabuf *gas_resp;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Remote Controller */
|
/* Remote Controller */
|
||||||
@ -88,6 +90,7 @@ static void dpp_connection_free(struct dpp_connection *conn)
|
|||||||
eloop_cancel_timeout(dpp_tcp_gas_query_comeback, conn, NULL);
|
eloop_cancel_timeout(dpp_tcp_gas_query_comeback, conn, NULL);
|
||||||
wpabuf_free(conn->msg);
|
wpabuf_free(conn->msg);
|
||||||
wpabuf_free(conn->msg_out);
|
wpabuf_free(conn->msg_out);
|
||||||
|
wpabuf_free(conn->gas_resp);
|
||||||
dpp_auth_deinit(conn->auth);
|
dpp_auth_deinit(conn->auth);
|
||||||
os_free(conn);
|
os_free(conn);
|
||||||
}
|
}
|
||||||
@ -976,14 +979,91 @@ static int dpp_controller_rx_action(struct dpp_connection *conn, const u8 *msg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int dpp_tcp_send_comeback_delay(struct dpp_connection *conn, u8 action)
|
||||||
|
{
|
||||||
|
struct wpabuf *buf;
|
||||||
|
size_t len = 18;
|
||||||
|
|
||||||
|
if (action == WLAN_PA_GAS_COMEBACK_RESP)
|
||||||
|
len++;
|
||||||
|
|
||||||
|
buf = wpabuf_alloc(4 + len);
|
||||||
|
if (!buf)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
wpabuf_put_be32(buf, len);
|
||||||
|
|
||||||
|
wpabuf_put_u8(buf, action);
|
||||||
|
wpabuf_put_u8(buf, conn->gas_dialog_token);
|
||||||
|
wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
|
||||||
|
if (action == WLAN_PA_GAS_COMEBACK_RESP)
|
||||||
|
wpabuf_put_u8(buf, 0);
|
||||||
|
wpabuf_put_le16(buf, 500); /* GAS Comeback Delay */
|
||||||
|
|
||||||
|
dpp_write_adv_proto(buf);
|
||||||
|
wpabuf_put_le16(buf, 0); /* Query Response Length */
|
||||||
|
|
||||||
|
/* Send Config Response over TCP */
|
||||||
|
wpa_hexdump_buf(MSG_MSGDUMP, "DPP: Outgoing TCP message", buf);
|
||||||
|
wpabuf_free(conn->msg_out);
|
||||||
|
conn->msg_out_pos = 0;
|
||||||
|
conn->msg_out = buf;
|
||||||
|
dpp_tcp_send(conn);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int dpp_tcp_send_gas_resp(struct dpp_connection *conn, u8 action,
|
||||||
|
struct wpabuf *resp)
|
||||||
|
{
|
||||||
|
struct wpabuf *buf;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (!resp)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
len = 18 + wpabuf_len(resp);
|
||||||
|
if (action == WLAN_PA_GAS_COMEBACK_RESP)
|
||||||
|
len++;
|
||||||
|
|
||||||
|
buf = wpabuf_alloc(4 + len);
|
||||||
|
if (!buf) {
|
||||||
|
wpabuf_free(resp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpabuf_put_be32(buf, len);
|
||||||
|
|
||||||
|
wpabuf_put_u8(buf, action);
|
||||||
|
wpabuf_put_u8(buf, conn->gas_dialog_token);
|
||||||
|
wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
|
||||||
|
if (action == WLAN_PA_GAS_COMEBACK_RESP)
|
||||||
|
wpabuf_put_u8(buf, 0);
|
||||||
|
wpabuf_put_le16(buf, 0); /* GAS Comeback Delay */
|
||||||
|
|
||||||
|
dpp_write_adv_proto(buf);
|
||||||
|
dpp_write_gas_query(buf, resp);
|
||||||
|
wpabuf_free(resp);
|
||||||
|
|
||||||
|
/* Send Config Response over TCP; GAS fragmentation is taken care of by
|
||||||
|
* the Relay */
|
||||||
|
wpa_hexdump_buf(MSG_MSGDUMP, "DPP: Outgoing TCP message", buf);
|
||||||
|
wpabuf_free(conn->msg_out);
|
||||||
|
conn->msg_out_pos = 0;
|
||||||
|
conn->msg_out = buf;
|
||||||
|
conn->on_tcp_tx_complete_gas_done = 1;
|
||||||
|
dpp_tcp_send(conn);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int dpp_controller_rx_gas_req(struct dpp_connection *conn, const u8 *msg,
|
static int dpp_controller_rx_gas_req(struct dpp_connection *conn, const u8 *msg,
|
||||||
size_t len)
|
size_t len)
|
||||||
{
|
{
|
||||||
const u8 *pos, *end, *next;
|
const u8 *pos, *end, *next;
|
||||||
u8 dialog_token;
|
|
||||||
const u8 *adv_proto;
|
const u8 *adv_proto;
|
||||||
u16 slen;
|
u16 slen;
|
||||||
struct wpabuf *resp, *buf;
|
struct wpabuf *resp;
|
||||||
struct dpp_authentication *auth = conn->auth;
|
struct dpp_authentication *auth = conn->auth;
|
||||||
|
|
||||||
if (len < 1 + 2)
|
if (len < 1 + 2)
|
||||||
@ -1001,7 +1081,7 @@ static int dpp_controller_rx_gas_req(struct dpp_connection *conn, const u8 *msg,
|
|||||||
pos = msg;
|
pos = msg;
|
||||||
end = msg + len;
|
end = msg + len;
|
||||||
|
|
||||||
dialog_token = *pos++;
|
conn->gas_dialog_token = *pos++;
|
||||||
adv_proto = pos++;
|
adv_proto = pos++;
|
||||||
slen = *pos++;
|
slen = *pos++;
|
||||||
if (*adv_proto != WLAN_EID_ADV_PROTO ||
|
if (*adv_proto != WLAN_EID_ADV_PROTO ||
|
||||||
@ -1028,57 +1108,53 @@ static int dpp_controller_rx_gas_req(struct dpp_connection *conn, const u8 *msg,
|
|||||||
resp = dpp_conf_req_rx(auth, pos, slen);
|
resp = dpp_conf_req_rx(auth, pos, slen);
|
||||||
if (!resp && auth->waiting_cert) {
|
if (!resp && auth->waiting_cert) {
|
||||||
wpa_printf(MSG_DEBUG, "DPP: Certificate not yet ready");
|
wpa_printf(MSG_DEBUG, "DPP: Certificate not yet ready");
|
||||||
buf = wpabuf_alloc(4 + 18);
|
conn->gas_comeback_in_progress = 1;
|
||||||
if (!buf)
|
return dpp_tcp_send_comeback_delay(conn,
|
||||||
return -1;
|
WLAN_PA_GAS_INITIAL_RESP);
|
||||||
|
|
||||||
wpabuf_put_be32(buf, 18);
|
|
||||||
|
|
||||||
wpabuf_put_u8(buf, WLAN_PA_GAS_INITIAL_RESP);
|
|
||||||
wpabuf_put_u8(buf, dialog_token);
|
|
||||||
wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
|
|
||||||
wpabuf_put_le16(buf, 500); /* GAS Comeback Delay */
|
|
||||||
|
|
||||||
dpp_write_adv_proto(buf);
|
|
||||||
wpabuf_put_le16(buf, 0); /* Query Response Length */
|
|
||||||
|
|
||||||
/* Send Config Response over TCP */
|
|
||||||
wpa_hexdump_buf(MSG_MSGDUMP, "DPP: Outgoing TCP message", buf);
|
|
||||||
wpabuf_free(conn->msg_out);
|
|
||||||
conn->msg_out_pos = 0;
|
|
||||||
conn->msg_out = buf;
|
|
||||||
dpp_tcp_send(conn);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
if (!resp)
|
|
||||||
|
return dpp_tcp_send_gas_resp(conn, WLAN_PA_GAS_INITIAL_RESP, resp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int dpp_controller_rx_gas_comeback_req(struct dpp_connection *conn,
|
||||||
|
const u8 *msg, size_t len)
|
||||||
|
{
|
||||||
|
u8 dialog_token;
|
||||||
|
struct dpp_authentication *auth = conn->auth;
|
||||||
|
struct wpabuf *resp;
|
||||||
|
|
||||||
|
if (len < 1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
buf = wpabuf_alloc(4 + 18 + wpabuf_len(resp));
|
wpa_printf(MSG_DEBUG,
|
||||||
if (!buf) {
|
"DPP: Received DPP Configuration Request over TCP (comeback)");
|
||||||
wpabuf_free(resp);
|
|
||||||
|
if (!auth || (!conn->ctrl && !auth->configurator) ||
|
||||||
|
(!auth->auth_success && !auth->reconfig_success) ||
|
||||||
|
!conn->gas_comeback_in_progress) {
|
||||||
|
wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
wpabuf_put_be32(buf, 18 + wpabuf_len(resp));
|
dialog_token = msg[0];
|
||||||
|
if (dialog_token != conn->gas_dialog_token) {
|
||||||
|
wpa_printf(MSG_DEBUG, "DPP: Dialog token mismatch (%u != %u)",
|
||||||
|
dialog_token, conn->gas_dialog_token);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
wpabuf_put_u8(buf, WLAN_PA_GAS_INITIAL_RESP);
|
if (!conn->gas_resp) {
|
||||||
wpabuf_put_u8(buf, dialog_token);
|
wpa_printf(MSG_DEBUG, "DPP: Certificate not yet ready");
|
||||||
wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
|
return dpp_tcp_send_comeback_delay(conn,
|
||||||
wpabuf_put_le16(buf, 0); /* GAS Comeback Delay */
|
WLAN_PA_GAS_COMEBACK_RESP);
|
||||||
|
}
|
||||||
|
|
||||||
dpp_write_adv_proto(buf);
|
wpa_printf(MSG_DEBUG,
|
||||||
dpp_write_gas_query(buf, resp);
|
"DPP: Configuration response is ready to be sent out");
|
||||||
wpabuf_free(resp);
|
resp = conn->gas_resp;
|
||||||
|
conn->gas_resp = NULL;
|
||||||
/* Send Config Response over TCP; GAS fragmentation is taken care of by
|
return dpp_tcp_send_gas_resp(conn, WLAN_PA_GAS_COMEBACK_RESP, resp);
|
||||||
* the Relay */
|
|
||||||
wpa_hexdump_buf(MSG_MSGDUMP, "DPP: Outgoing TCP message", buf);
|
|
||||||
wpabuf_free(conn->msg_out);
|
|
||||||
conn->msg_out_pos = 0;
|
|
||||||
conn->msg_out = buf;
|
|
||||||
conn->on_tcp_tx_complete_gas_done = 1;
|
|
||||||
dpp_tcp_send(conn);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1369,6 +1445,11 @@ static void dpp_controller_rx(int sd, void *eloop_ctx, void *sock_ctx)
|
|||||||
wpabuf_len(conn->msg) - 1) < 0)
|
wpabuf_len(conn->msg) - 1) < 0)
|
||||||
dpp_connection_remove(conn);
|
dpp_connection_remove(conn);
|
||||||
break;
|
break;
|
||||||
|
case WLAN_PA_GAS_COMEBACK_REQ:
|
||||||
|
if (dpp_controller_rx_gas_comeback_req(
|
||||||
|
conn, pos + 1, wpabuf_len(conn->msg) - 1) < 0)
|
||||||
|
dpp_connection_remove(conn);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
wpa_printf(MSG_DEBUG, "DPP: Ignore unsupported message type %u",
|
wpa_printf(MSG_DEBUG, "DPP: Ignore unsupported message type %u",
|
||||||
*pos);
|
*pos);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user