diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index ca366e590..5f5c50ba9 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -2694,6 +2694,8 @@ static int wpa_supplicant_use_own_rsne_params(struct wpa_supplicant *wpa_s, bool found = false; struct wpa_ie_data ie; struct wpa_ssid *ssid = wpa_s->current_ssid; + struct wpa_bss *bss = wpa_s->current_bss; + int pmf; if (!ssid) return 0; @@ -2727,6 +2729,14 @@ static int wpa_supplicant_use_own_rsne_params(struct wpa_supplicant *wpa_s, "WPA: Update cipher suite selection based on IEs in driver-generated WPA/RSNE in AssocReq", p, l); + /* Update proto from (Re)Association Request frame info */ + wpa_s->wpa_proto = ie.proto; + wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PROTO, wpa_s->wpa_proto); + wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED, + !!(wpa_s->wpa_proto & + (WPA_PROTO_RSN | WPA_PROTO_OSEN))); + + /* Update AKMP suite from (Re)Association Request frame info */ sel = ie.key_mgmt; if (ssid->key_mgmt) sel &= ssid->key_mgmt; @@ -2740,36 +2750,13 @@ static int wpa_supplicant_use_own_rsne_params(struct wpa_supplicant *wpa_s, return -1; } - wpa_s->wpa_proto = ie.proto; - wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PROTO, wpa_s->wpa_proto); - wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED, - !!(wpa_s->wpa_proto & - (WPA_PROTO_RSN | WPA_PROTO_OSEN))); - wpa_s->key_mgmt = ie.key_mgmt; wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt); wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT %s and proto %d", wpa_key_mgmt_txt(wpa_s->key_mgmt, wpa_s->wpa_proto), wpa_s->wpa_proto); - sel = ie.group_cipher; - if (ssid->group_cipher) - sel &= ssid->group_cipher; - - wpa_dbg(wpa_s, MSG_DEBUG, - "WPA: AP group cipher 0x%x network group cipher 0x%x; available group cipher 0x%x", - ie.group_cipher, ssid->group_cipher, sel); - if (ie.group_cipher && !sel) { - wpa_supplicant_deauthenticate( - wpa_s, WLAN_REASON_GROUP_CIPHER_NOT_VALID); - return -1; - } - - wpa_s->group_cipher = ie.group_cipher; - wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher); - wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using GTK %s", - wpa_cipher_txt(wpa_s->group_cipher)); - + /* Update pairwise cipher from (Re)Association Request frame info */ sel = ie.pairwise_cipher; if (ssid->pairwise_cipher) sel &= ssid->pairwise_cipher; @@ -2789,7 +2776,109 @@ static int wpa_supplicant_use_own_rsne_params(struct wpa_supplicant *wpa_s, wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using PTK %s", wpa_cipher_txt(wpa_s->pairwise_cipher)); - wpas_set_mgmt_group_cipher(wpa_s, ssid, &ie); + /* Update other parameters based on AP's WPA IE/RSNE, if available */ + if (!bss) { + wpa_dbg(wpa_s, MSG_DEBUG, + "WPA: current_bss == NULL - skip AP IE check"); + return 0; + } + + /* Update GTK and IGTK from AP's RSNE */ + found = false; + + if (wpa_s->wpa_proto & (WPA_PROTO_RSN | WPA_PROTO_OSEN)) { + const u8 *bss_rsn; + + bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN); + if (bss_rsn) { + p = bss_rsn; + len = 2 + bss_rsn[1]; + found = true; + } + } else if (wpa_s->wpa_proto & WPA_PROTO_WPA) { + const u8 *bss_wpa; + + bss_wpa = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); + if (bss_wpa) { + p = bss_wpa; + len = 2 + bss_wpa[1]; + found = true; + } + } + + if (!found || wpa_parse_wpa_ie(p, len, &ie) < 0) + return 0; + + pmf = wpas_get_ssid_pmf(wpa_s, ssid); + if (!(ie.capabilities & WPA_CAPABILITY_MFPC) && + pmf == MGMT_FRAME_PROTECTION_REQUIRED) { + /* AP does not support MFP, local configuration requires it */ + wpa_supplicant_deauthenticate( + wpa_s, WLAN_REASON_INVALID_RSN_IE_CAPAB); + return -1; + } + if ((ie.capabilities & WPA_CAPABILITY_MFPR) && + pmf == NO_MGMT_FRAME_PROTECTION) { + /* AP requires MFP, local configuration disables it */ + wpa_supplicant_deauthenticate( + wpa_s, WLAN_REASON_INVALID_RSN_IE_CAPAB); + return -1; + } + + /* Update PMF from local configuration now that MFP validation was done + * above */ + wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MFP, pmf); + + /* Update GTK from AP's RSNE */ + sel = ie.group_cipher; + if (ssid->group_cipher) + sel &= ssid->group_cipher; + + wpa_dbg(wpa_s, MSG_DEBUG, + "WPA: AP group cipher 0x%x network group cipher 0x%x; available group cipher 0x%x", + ie.group_cipher, ssid->group_cipher, sel); + if (ie.group_cipher && !sel) { + wpa_supplicant_deauthenticate( + wpa_s, WLAN_REASON_GROUP_CIPHER_NOT_VALID); + return -1; + } + + wpa_s->group_cipher = ie.group_cipher; + wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher); + wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using GTK %s", + wpa_cipher_txt(wpa_s->group_cipher)); + + /* Update IGTK from AP RSN IE */ + sel = ie.mgmt_group_cipher; + if (ssid->group_mgmt_cipher) + sel &= ssid->group_mgmt_cipher; + + wpa_dbg(wpa_s, MSG_DEBUG, + "WPA: AP mgmt_group_cipher 0x%x network mgmt_group_cipher 0x%x; available mgmt_group_cipher 0x%x", + ie.mgmt_group_cipher, ssid->group_mgmt_cipher, sel); + + if (pmf == NO_MGMT_FRAME_PROTECTION || + !(ie.capabilities & WPA_CAPABILITY_MFPC)) { + wpa_dbg(wpa_s, MSG_DEBUG, + "WPA: STA/AP is not MFP capable; AP RSNE caps 0x%x", + ie.capabilities); + ie.mgmt_group_cipher = 0; + } + + if (ie.mgmt_group_cipher && !sel) { + wpa_supplicant_deauthenticate( + wpa_s, WLAN_REASON_CIPHER_SUITE_REJECTED); + return -1; + } + + wpa_s->mgmt_group_cipher = ie.mgmt_group_cipher; + wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP, + wpa_s->mgmt_group_cipher); + if (wpa_s->mgmt_group_cipher) + wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher %s", + wpa_cipher_txt(wpa_s->mgmt_group_cipher)); + else + wpa_dbg(wpa_s, MSG_DEBUG, "WPA: not using MGMT group cipher"); return 0; }