Browse Source

FT: Verify that MDIE and FTIE matches between AssocResp and EAPOL-Key 3/4

Jouni Malinen 15 years ago
parent
commit
3b4f6dac19
1 changed files with 62 additions and 5 deletions
  1. 62 5
      src/rsn_supp/wpa.c

+ 62 - 5
src/rsn_supp/wpa.c

@@ -794,13 +794,11 @@ static void wpa_report_ie_mismatch(struct wpa_sm *sm,
 
 static int ft_validate_mdie(struct wpa_sm *sm,
 			    const unsigned char *src_addr,
-			    struct wpa_eapol_ie_parse *ie)
+			    struct wpa_eapol_ie_parse *ie,
+			    const u8 *assoc_resp_mdie)
 {
 	struct rsn_mdie *mdie;
 
-	/* TODO: verify that full MDIE matches with the one from scan
-	 * results, not only mobility domain */
-
 	mdie = (struct rsn_mdie *) (ie->mdie + 2);
 	if (ie->mdie == NULL || ie->mdie_len < 2 + sizeof(*mdie) ||
 	    os_memcmp(mdie->mobility_domain, sm->mobility_domain,
@@ -810,6 +808,44 @@ static int ft_validate_mdie(struct wpa_sm *sm,
 		return -1;
 	}
 
+	if (assoc_resp_mdie &&
+	    (assoc_resp_mdie[1] != ie->mdie[1] ||
+	     os_memcmp(assoc_resp_mdie, ie->mdie, 2 + ie->mdie[1]) != 0)) {
+		wpa_printf(MSG_DEBUG, "FT: MDIE mismatch");
+		wpa_hexdump(MSG_DEBUG, "FT: MDIE in EAPOL-Key msg 3/4",
+			    ie->mdie, 2 + ie->mdie[1]);
+		wpa_hexdump(MSG_DEBUG, "FT: MDIE in (Re)Association Response",
+			    assoc_resp_mdie, 2 + assoc_resp_mdie[1]);
+		return -1;
+	}
+
+	return 0;
+}
+
+
+static int ft_validate_ftie(struct wpa_sm *sm,
+			    const unsigned char *src_addr,
+			    struct wpa_eapol_ie_parse *ie,
+			    const u8 *assoc_resp_ftie)
+{
+	if (ie->ftie == NULL) {
+		wpa_printf(MSG_DEBUG, "FT: No FTIE in EAPOL-Key msg 3/4");
+		return -1;
+	}
+
+	if (assoc_resp_ftie == NULL)
+		return 0;
+
+	if (assoc_resp_ftie[1] != ie->ftie[1] ||
+	    os_memcmp(assoc_resp_ftie, ie->ftie, 2 + ie->ftie[1]) != 0) {
+		wpa_printf(MSG_DEBUG, "FT: FTIE mismatch");
+		wpa_hexdump(MSG_DEBUG, "FT: FTIE in EAPOL-Key msg 3/4",
+			    ie->ftie, 2 + ie->ftie[1]);
+		wpa_hexdump(MSG_DEBUG, "FT: FTIE in (Re)Association Response",
+			    assoc_resp_ftie, 2 + assoc_resp_ftie[1]);
+		return -1;
+	}
+
 	return 0;
 }
 
@@ -852,7 +888,28 @@ static int wpa_supplicant_validate_ie_ft(struct wpa_sm *sm,
 					 const unsigned char *src_addr,
 					 struct wpa_eapol_ie_parse *ie)
 {
-	if (ft_validate_mdie(sm, src_addr, ie) < 0 ||
+	const u8 *pos, *end, *mdie = NULL, *ftie = NULL;
+
+	if (sm->assoc_resp_ies) {
+		pos = sm->assoc_resp_ies;
+		end = pos + sm->assoc_resp_ies_len;
+		while (pos + 2 < end) {
+			if (pos + 2 + pos[1] > end)
+				break;
+			switch (*pos) {
+			case WLAN_EID_MOBILITY_DOMAIN:
+				mdie = pos;
+				break;
+			case WLAN_EID_FAST_BSS_TRANSITION:
+				ftie = pos;
+				break;
+			}
+			pos += 2 + pos[1];
+		}
+	}
+
+	if (ft_validate_mdie(sm, src_addr, ie, mdie) < 0 ||
+	    ft_validate_ftie(sm, src_addr, ie, ftie) < 0 ||
 	    ft_validate_rsnie(sm, src_addr, ie) < 0)
 		return -1;