iee80211: Conform to the spec and handle Anti-Clogging Token container.

My previous patch was broken and did not handle the new Anti-Clogging Token
container. It was broken because I did not realise that Table 9-42 specified
the order of elements in the SAE Fixed Field. Table 9-43 specifies when
elements will be in which type of SAE request. However, 9-42 specifies the
order.

This has been tested with captures from WFA and Jouni Malinen.

Change-Id: Icbaa53560036c421299c74867ec04d9a28ea8aa0
Reviewed-on: https://code.wireshark.org/review/36098
Petri-Dish: Richard Sharpe <realrichardsharpe@gmail.com>
Tested-by: Petri Dish Buildbot
Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
Richard Sharpe 2020-02-13 21:45:07 -05:00 committed by Anders Broman
parent 2c1d660940
commit 5d1f89f10c
1 changed files with 101 additions and 31 deletions

View File

@ -614,6 +614,7 @@ static value_string_ext tag_num_vals_ext = VALUE_STRING_EXT_INIT(ie_tag_num_vals
#define ETAG_QUIET_TIME_PERIOD_SETUP 43
#define ETAG_ESS_REPORT 44
#define ETAG_REJECTED_GROUPS 92
#define ETAG_ANTI_CLOGGING_TOKEN 93
static const value_string tag_num_vals_eid_ext[] = {
{ ETAG_ASSOC_DELAY_INFO, "Association Delay Info" },
@ -642,6 +643,7 @@ static const value_string tag_num_vals_eid_ext[] = {
{ ETAG_QUIET_TIME_PERIOD_SETUP, "Quiet Time Period Setup" },
{ ETAG_ESS_REPORT, "ESS Report" },
{ ETAG_REJECTED_GROUPS, "Rejected Groups" },
{ ETAG_ANTI_CLOGGING_TOKEN, "Anti-Clogging Token Container" },
{ 0, NULL }
};
static value_string_ext tag_num_vals_eid_ext_ext = VALUE_STRING_EXT_INIT(tag_num_vals_eid_ext);
@ -3445,12 +3447,13 @@ static int hf_ieee80211_ff_sa_query_action_code = -1;
static int hf_ieee80211_ff_transaction_id = -1;
static int hf_ieee80211_ff_send_confirm = -1;
static int hf_ieee80211_ff_anti_clogging_token = -1;
static int hf_ieee80211_ff_scalar = -1;
static int hf_ieee80211_ff_finite_field_element = -1;
static int hf_ieee80211_ff_confirm = -1;
static int hf_ieee80211_ff_finite_cyclic_group = -1;
static int hf_ieee80211_ff_sae_message_type = -1;
static int hf_ieee80211_ff_sae_anti_clogging_token = -1;
/* Vendor specific */
static int hf_ieee80211_ff_marvell_action_type = -1;
@ -5428,6 +5431,9 @@ static int hf_ieee80211_estimated_service_params = -1;
static int hf_ieee80211_fcg_new_channel_number = -1;
static int hf_ieee80211_fcg_extra_info = -1;
static int hf_ieee80211_sae_password_identifier = -1;
static int hf_ieee80211_sae_anti_clogging_token = -1;
static int hf_ieee80211_tag_fils_indication_info_nr_pk = -1;
static int hf_ieee80211_tag_fils_indication_info_nr_realm = -1;
@ -10249,7 +10255,7 @@ static guint get_scalar_len(guint group) {
}
static guint
find_anti_clogging_len(tvbuff_t *tvb, guint offset)
find_fixed_field_len(tvbuff_t *tvb, guint offset)
{
guint start_offset = offset;
guint len = tvb_reported_length(tvb);
@ -10262,11 +10268,13 @@ find_anti_clogging_len(tvbuff_t *tvb, guint offset)
if (tvb_get_guint8(tvb, offset) == 0xFF) {
/*
* Check if we have a len followed by either ETAG_REJECTED_GROUPS
* or ETAG_PASSWORD_IDENTIFIER
* or ETAG_PASSWORD_IDENTIFIER or ETAG_ANTI_CLOGGING_TOKEN
*/
if (offset < len - 3) {
if (tvb_get_guint8(tvb, offset + 2) == ETAG_REJECTED_GROUPS ||
tvb_get_guint8(tvb, offset + 2) == ETAG_PASSWORD_IDENTIFIER) {
guint8 check_byte = tvb_get_guint8(tvb, offset + 2);
if (check_byte == ETAG_REJECTED_GROUPS ||
check_byte == ETAG_PASSWORD_IDENTIFIER ||
check_byte == ETAG_ANTI_CLOGGING_TOKEN) {
break;
}
}
@ -10307,6 +10315,20 @@ add_ff_auth_sae(proto_tree *tree, tvbuff_t *tvb,
guint16 group;
guint sc_len, elt_len;
/*
* Order is: Status code,
* Finite Cyclic Group,
* Anti-Clogging Token in some cases
* Send-Confirm in some cases
* Scalar in some cases
* FFE in some cases
* Confirm in some cases
* Challenge Text in some cases
* RSNE in some cases.
* MDE in some cases.
* Fast BSS TRansition ... in some cases.
*/
/* 76: Authentication is rejected because an Anti-Clogging Token is required (cf ieee80211_status_code) */
/* These are present if status code is 0, 76, 77 or 126 */
if (status_code == 0 || status_code == 76 || status_code == 77 ||
@ -10316,11 +10338,43 @@ add_ff_auth_sae(proto_tree *tree, tvbuff_t *tvb,
proto_tree_add_item(tree, hf_ieee80211_ff_finite_cyclic_group, tvb,
offset, 2, ENC_LITTLE_ENDIAN);
offset += 2;
len = tvb_reported_length_remaining(tvb, offset);
/*
* Now, get the fixed field length remaining. It will be divided up into
* Anti-Clogging token, Scalar, FFE and some IEs.
*/
len = find_fixed_field_len(tvb, offset);
sc_len = get_scalar_len(group);
elt_len = get_group_element_len(group);
/*
* The first conditional captures the case where we have an error and
* an anti-clogging token with Scalar Field and FFE.
* The second handles the case where we have an error with only an
* anti-clogging token.
* The third conditional below is a way to avoid keeping state about
* what was in a previous response!
*/
if (((status_code == 76 || status_code == 126) &&
((len > (sc_len + elt_len)))) ||
((status_code == 76) && (len > 0) && (len < (sc_len + elt_len))) ||
((status_code == 0) && (len > (sc_len + elt_len)))) {
guint anti_clogging_len;
/*
* Handle the anti-clogging field. There is an anti-clogging token
* before the other two.
*/
if (len > (sc_len + elt_len))
anti_clogging_len = len - (sc_len + elt_len);
else
anti_clogging_len = len;
proto_tree_add_item(tree, hf_ieee80211_ff_sae_anti_clogging_token, tvb,
offset, anti_clogging_len, ENC_NA);
offset += anti_clogging_len;
}
if (sc_len == 0) {
/* assume no anti-clogging token */
if (!(len % 3))
@ -10344,26 +10398,6 @@ add_ff_auth_sae(proto_tree *tree, tvbuff_t *tvb,
offset, elt_len, ENC_NA);
offset += elt_len;
}
/*
* Do we have an anti-clogging token? To find out we have to scan the
* rest of the buffer looking for IEs with 0xFF NUM 0x5C or
* 0xFF NUM 0x21 since these can occur after the anti-clogging token.
* However, it is only present if the status code is 76 or 126.
*/
if (status_code == 76 || status_code == 126) {
guint anti_clogging_len;
if (offset >= len) { /* Nothing left, add an Expert Info */
}
anti_clogging_len = find_anti_clogging_len(tvb, offset);
if (anti_clogging_len > 0) {
proto_tree_add_item(tree, hf_ieee80211_ff_anti_clogging_token, tvb,
offset, anti_clogging_len, ENC_NA);
offset += anti_clogging_len;
}
}
}
}
/* 82: Rejected with Suggested BSS Transition (cf ieee80211_status_code) */
@ -20996,6 +21030,17 @@ dissect_ess_report(tvbuff_t *tvb, packet_info *pinfo _U_,
bss_trans_thresh, -100 + bss_trans_thresh);
}
static int
dissect_password_identifier(tvbuff_t *tvb, packet_info *pinfo _U_,
proto_tree *tree, int offset, int len _U_)
{
proto_tree_add_item(tree, hf_ieee80211_sae_password_identifier, tvb, offset,
len, ENC_NA|ENC_ASCII);
offset += len;
return offset;
}
/*
* Just a list of finite cyclic group numbers as 16-bit uints.
*/
@ -21010,6 +21055,17 @@ dissect_rejected_groups(tvbuff_t *tvb, packet_info *pinfo _U_,
}
}
/*
* Just a string of bytes
*/
static void
dissect_anti_clogging_token(tvbuff_t *tvb, packet_info *pinfo _U_,
proto_tree *tree, int offset, int len)
{
proto_tree_add_item(tree, hf_ieee80211_sae_anti_clogging_token, tvb, offset,
len, ENC_NA);
}
/*
* There will be from 1 to 4 24-bit fields in the order of AC=BK, AC=BE,
* AC=VI and AC=VO.
@ -21384,6 +21440,9 @@ ieee80211_tag_element_id_extension(tvbuff_t *tvb, packet_info *pinfo, proto_tree
case ETAG_OWE_DH_PARAMETER:
dissect_owe_dh_parameter(tvb, pinfo, tree, offset, ext_tag_len, field_data->sanity_check);
break;
case ETAG_PASSWORD_IDENTIFIER:
dissect_password_identifier(tvb, pinfo, tree, offset, ext_tag_len);
break;
case ETAG_HE_CAPABILITIES:
dissect_he_capabilities(tvb, pinfo, tree, offset, ext_tag_len);
break;
@ -21414,6 +21473,9 @@ ieee80211_tag_element_id_extension(tvbuff_t *tvb, packet_info *pinfo, proto_tree
case ETAG_REJECTED_GROUPS:
dissect_rejected_groups(tvb, pinfo, tree, offset, ext_tag_len);
break;
case ETAG_ANTI_CLOGGING_TOKEN:
dissect_anti_clogging_token(tvb, pinfo, tree, offset, ext_tag_len);
break;
default:
break;
}
@ -30290,11 +30352,6 @@ proto_register_ieee80211(void)
FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{&hf_ieee80211_ff_anti_clogging_token,
{"Anti-Clogging Token", "wlan.fixed.anti_clogging_token",
FT_BYTES, BASE_NONE, NULL, 0,
NULL, HFILL }},
{&hf_ieee80211_ff_scalar,
{"Scalar", "wlan.fixed.scalar",
FT_BYTES, BASE_NONE, NULL, 0,
@ -30320,6 +30377,10 @@ proto_register_ieee80211(void)
FT_UINT16, BASE_DEC, VALS(ff_sae_message_type_vals), 0,
NULL, HFILL }},
{&hf_ieee80211_ff_sae_anti_clogging_token,
{"Anti-Clogging Token", "wlan.fixed.anti_clogging_token",
FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
{&hf_ieee80211_anqp_wfa_subtype,
{"WFA Subtype", "wlan.anqp.wfa.subtype",
FT_UINT8, BASE_DEC, VALS(wfa_subtype_vals), 0, NULL, HFILL }},
@ -36281,6 +36342,15 @@ proto_register_ieee80211(void)
{"Extra bytes", "wlan.ext_tag.future_channel_guidance.extra_bytes",
FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{&hf_ieee80211_sae_password_identifier,
{"Password Identifier", "wlan.ext_tag.sae.password_identifier",
FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{&hf_ieee80211_sae_anti_clogging_token,
{"Anti-Clogging Token", "wlan.ext_tag.sae.anti_clogging_token",
FT_BYTES, BASE_NONE, NULL, 0,
NULL, HFILL }},
{&hf_ieee80211_tag_fils_indication_info_nr_pk,
{"Number of Public Key Identifiers", "wlan.fils_indication.info.nr_pk",
FT_UINT16, BASE_DEC, NULL, GENMASK(2,0), NULL, HFILL }},