From 3237bfb1a3cdd4d3efa34f6fa205478b38bf5b75 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Wed, 22 Sep 2010 19:17:13 -0700 Subject: [PATCH] WPS: Fix strict validation of encrypted data for WSC 2.0-only case Need to figure out whether the message is from a WSC 2.0 -based device based on the unencrypted attributes, not the contents of the encrypted data since the Version2 subelement is only included in the unencrypted area. --- src/wps/wps.h | 22 ++++++++++++---------- src/wps/wps_enrollee.c | 7 ++++--- src/wps/wps_registrar.c | 5 +++-- src/wps/wps_validate.c | 20 +++++--------------- 4 files changed, 24 insertions(+), 30 deletions(-) diff --git a/src/wps/wps.h b/src/wps/wps.h index e4150615e..f30625509 100644 --- a/src/wps/wps.h +++ b/src/wps/wps.h @@ -778,15 +778,15 @@ int wps_validate_m2(const struct wpabuf *tlvs); int wps_validate_m2d(const struct wpabuf *tlvs); int wps_validate_m3(const struct wpabuf *tlvs); int wps_validate_m4(const struct wpabuf *tlvs); -int wps_validate_m4_encr(const struct wpabuf *tlvs); +int wps_validate_m4_encr(const struct wpabuf *tlvs, int wps2); int wps_validate_m5(const struct wpabuf *tlvs); -int wps_validate_m5_encr(const struct wpabuf *tlvs); +int wps_validate_m5_encr(const struct wpabuf *tlvs, int wps2); int wps_validate_m6(const struct wpabuf *tlvs); -int wps_validate_m6_encr(const struct wpabuf *tlvs); +int wps_validate_m6_encr(const struct wpabuf *tlvs, int wps2); int wps_validate_m7(const struct wpabuf *tlvs); -int wps_validate_m7_encr(const struct wpabuf *tlvs, int ap); +int wps_validate_m7_encr(const struct wpabuf *tlvs, int ap, int wps2); int wps_validate_m8(const struct wpabuf *tlvs); -int wps_validate_m8_encr(const struct wpabuf *tlvs, int ap); +int wps_validate_m8_encr(const struct wpabuf *tlvs, int ap, int wps2); int wps_validate_wsc_ack(const struct wpabuf *tlvs); int wps_validate_wsc_nack(const struct wpabuf *tlvs); int wps_validate_wsc_done(const struct wpabuf *tlvs); @@ -843,7 +843,7 @@ static inline int wps_validate_m4(const struct wpabuf *tlvs) return 0; } -static inline int wps_validate_m4_encr(const struct wpabuf *tlvs) +static inline int wps_validate_m4_encr(const struct wpabuf *tlvs, int wps2) { return 0; } @@ -853,7 +853,7 @@ static inline int wps_validate_m5(const struct wpabuf *tlvs) return 0; } -static inline int wps_validate_m5_encr(const struct wpabuf *tlvs) +static inline int wps_validate_m5_encr(const struct wpabuf *tlvs, int wps2) { return 0; } @@ -863,7 +863,7 @@ static inline int wps_validate_m6(const struct wpabuf *tlvs) return 0; } -static inline int wps_validate_m6_encr(const struct wpabuf *tlvs) +static inline int wps_validate_m6_encr(const struct wpabuf *tlvs, int wps2) { return 0; } @@ -873,7 +873,8 @@ static inline int wps_validate_m7(const struct wpabuf *tlvs) return 0; } -static inline int wps_validate_m7_encr(const struct wpabuf *tlvs, int ap) +static inline int wps_validate_m7_encr(const struct wpabuf *tlvs, int ap, + int wps2) { return 0; } @@ -883,7 +884,8 @@ static inline int wps_validate_m8(const struct wpabuf *tlvs) return 0; } -static inline int wps_validate_m8_encr(const struct wpabuf *tlvs, int ap) +static inline int wps_validate_m8_encr(const struct wpabuf *tlvs, int ap, + int wps2) { return 0; } diff --git a/src/wps/wps_enrollee.c b/src/wps/wps_enrollee.c index b11cdb670..1db255d19 100644 --- a/src/wps/wps_enrollee.c +++ b/src/wps/wps_enrollee.c @@ -981,7 +981,7 @@ static enum wps_process_res wps_process_m4(struct wps_data *wps, return WPS_CONTINUE; } - if (wps_validate_m4_encr(decrypted) < 0) { + if (wps_validate_m4_encr(decrypted, attr->version2 != 0) < 0) { wpabuf_free(decrypted); wps->state = SEND_WSC_NACK; return WPS_CONTINUE; @@ -1034,7 +1034,7 @@ static enum wps_process_res wps_process_m6(struct wps_data *wps, return WPS_CONTINUE; } - if (wps_validate_m6_encr(decrypted) < 0) { + if (wps_validate_m6_encr(decrypted, attr->version2 != 0) < 0) { wpabuf_free(decrypted); wps->state = SEND_WSC_NACK; return WPS_CONTINUE; @@ -1087,7 +1087,8 @@ static enum wps_process_res wps_process_m8(struct wps_data *wps, return WPS_CONTINUE; } - if (wps_validate_m8_encr(decrypted, wps->wps->ap) < 0) { + if (wps_validate_m8_encr(decrypted, wps->wps->ap, attr->version2 != 0) + < 0) { wpabuf_free(decrypted); wps->state = SEND_WSC_NACK; return WPS_CONTINUE; diff --git a/src/wps/wps_registrar.c b/src/wps/wps_registrar.c index 0d8c72e68..6fed6a5ea 100644 --- a/src/wps/wps_registrar.c +++ b/src/wps/wps_registrar.c @@ -2426,7 +2426,7 @@ static enum wps_process_res wps_process_m5(struct wps_data *wps, return WPS_CONTINUE; } - if (wps_validate_m5_encr(decrypted) < 0) { + if (wps_validate_m5_encr(decrypted, attr->version2 != NULL) < 0) { wpabuf_free(decrypted); wps->state = SEND_WSC_NACK; return WPS_CONTINUE; @@ -2555,7 +2555,8 @@ static enum wps_process_res wps_process_m7(struct wps_data *wps, return WPS_CONTINUE; } - if (wps_validate_m7_encr(decrypted, wps->wps->ap || wps->er) < 0) { + if (wps_validate_m7_encr(decrypted, wps->wps->ap || wps->er, + attr->version2 != NULL) < 0) { wpabuf_free(decrypted); wps->state = SEND_WSC_NACK; return WPS_CONTINUE; diff --git a/src/wps/wps_validate.c b/src/wps/wps_validate.c index 8e3d5c147..c3071a0db 100644 --- a/src/wps/wps_validate.c +++ b/src/wps/wps_validate.c @@ -1523,10 +1523,9 @@ int wps_validate_m4(const struct wpabuf *tlvs) } -int wps_validate_m4_encr(const struct wpabuf *tlvs) +int wps_validate_m4_encr(const struct wpabuf *tlvs, int wps2) { struct wps_parse_attr attr; - int wps2; if (tlvs == NULL) { wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M4 encrypted " @@ -1539,7 +1538,6 @@ int wps_validate_m4_encr(const struct wpabuf *tlvs) return -1; } - wps2 = attr.version2 != NULL; if (wps_validate_r_snonce1(attr.r_snonce1, 1) || wps_validate_key_wrap_auth(attr.key_wrap_auth, 1)) { wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M4 encrypted " @@ -1592,10 +1590,9 @@ int wps_validate_m5(const struct wpabuf *tlvs) } -int wps_validate_m5_encr(const struct wpabuf *tlvs) +int wps_validate_m5_encr(const struct wpabuf *tlvs, int wps2) { struct wps_parse_attr attr; - int wps2; if (tlvs == NULL) { wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M5 encrypted " @@ -1608,7 +1605,6 @@ int wps_validate_m5_encr(const struct wpabuf *tlvs) return -1; } - wps2 = attr.version2 != NULL; if (wps_validate_e_snonce1(attr.e_snonce1, 1) || wps_validate_key_wrap_auth(attr.key_wrap_auth, 1)) { wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M5 encrypted " @@ -1661,10 +1657,9 @@ int wps_validate_m6(const struct wpabuf *tlvs) } -int wps_validate_m6_encr(const struct wpabuf *tlvs) +int wps_validate_m6_encr(const struct wpabuf *tlvs, int wps2) { struct wps_parse_attr attr; - int wps2; if (tlvs == NULL) { wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M6 encrypted " @@ -1677,7 +1672,6 @@ int wps_validate_m6_encr(const struct wpabuf *tlvs) return -1; } - wps2 = attr.version2 != NULL; if (wps_validate_r_snonce2(attr.r_snonce2, 1) || wps_validate_key_wrap_auth(attr.key_wrap_auth, 1)) { wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M6 encrypted " @@ -1731,10 +1725,9 @@ int wps_validate_m7(const struct wpabuf *tlvs) } -int wps_validate_m7_encr(const struct wpabuf *tlvs, int ap) +int wps_validate_m7_encr(const struct wpabuf *tlvs, int ap, int wps2) { struct wps_parse_attr attr; - int wps2; if (tlvs == NULL) { wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M7 encrypted " @@ -1747,7 +1740,6 @@ int wps_validate_m7_encr(const struct wpabuf *tlvs, int ap) return -1; } - wps2 = attr.version2 != NULL; if (wps_validate_e_snonce2(attr.e_snonce2, 1) || wps_validate_ssid(attr.ssid, attr.ssid_len, !ap) || wps_validate_mac_addr(attr.mac_addr, !ap) || @@ -1807,10 +1799,9 @@ int wps_validate_m8(const struct wpabuf *tlvs) } -int wps_validate_m8_encr(const struct wpabuf *tlvs, int ap) +int wps_validate_m8_encr(const struct wpabuf *tlvs, int ap, int wps2) { struct wps_parse_attr attr; - int wps2; if (tlvs == NULL) { wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M8 encrypted " @@ -1823,7 +1814,6 @@ int wps_validate_m8_encr(const struct wpabuf *tlvs, int ap) return -1; } - wps2 = attr.version2 != NULL; if (wps_validate_ssid(attr.ssid, attr.ssid_len, ap) || wps_validate_auth_type(attr.auth_type, ap) || wps_validate_encr_type(attr.encr_type, ap) ||