From 7d146f42f66738aa4a4375a9202c1d8580ebf11d Mon Sep 17 00:00:00 2001 From: christos Date: Tue, 3 May 2016 18:19:44 +0000 Subject: [PATCH] http://w1.fi/security/2016-1/0001-WPS-Reject-a-Credential-with-invalid-passphrase.patch WPA/WPA2-Personal passphrase is not allowed to include control characters. Reject a Credential received from a WPS Registrar both as STA (Credential) and AP (AP Settings) if the credential is for WPAPSK or WPA2PSK authentication type and includes an invalid passphrase. This fixes an issue where hostapd or wpa_supplicant could have updated the configuration file PSK/passphrase parameter with arbitrary data from an external device (Registrar) that may not be fully trusted. Should such data include a newline character, the resulting configuration file could become invalid and fail to be parsed. --- external/bsd/wpa/dist/src/utils/common.c | 12 ++++++++++++ external/bsd/wpa/dist/src/utils/common.h | 1 + external/bsd/wpa/dist/src/wps/wps_attr_process.c | 10 ++++++++++ 3 files changed, 23 insertions(+) diff --git a/external/bsd/wpa/dist/src/utils/common.c b/external/bsd/wpa/dist/src/utils/common.c index 5fd795f3f303..c67a643b7dbe 100644 --- a/external/bsd/wpa/dist/src/utils/common.c +++ b/external/bsd/wpa/dist/src/utils/common.c @@ -671,6 +671,18 @@ int is_hex(const u8 *data, size_t len) } +int has_ctrl_char(const u8 *data, size_t len) +{ + size_t i; + + for (i = 0; i < len; i++) { + if (data[i] < 32 || data[i] == 127) + return 1; + } + return 0; +} + + size_t merge_byte_arrays(u8 *res, size_t res_len, const u8 *src1, size_t src1_len, const u8 *src2, size_t src2_len) diff --git a/external/bsd/wpa/dist/src/utils/common.h b/external/bsd/wpa/dist/src/utils/common.h index 576e8e7e2d4e..d96e5f2a6db5 100644 --- a/external/bsd/wpa/dist/src/utils/common.h +++ b/external/bsd/wpa/dist/src/utils/common.h @@ -501,6 +501,7 @@ const char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len); char * wpa_config_parse_string(const char *value, size_t *len); int is_hex(const u8 *data, size_t len); +int has_ctrl_char(const u8 *data, size_t len); size_t merge_byte_arrays(u8 *res, size_t res_len, const u8 *src1, size_t src1_len, const u8 *src2, size_t src2_len); diff --git a/external/bsd/wpa/dist/src/wps/wps_attr_process.c b/external/bsd/wpa/dist/src/wps/wps_attr_process.c index eadb22fe2e78..e8c4579309ab 100644 --- a/external/bsd/wpa/dist/src/wps/wps_attr_process.c +++ b/external/bsd/wpa/dist/src/wps/wps_attr_process.c @@ -229,6 +229,16 @@ static int wps_workaround_cred_key(struct wps_credential *cred) cred->key_len--; #endif /* CONFIG_WPS_STRICT */ } + + + if (cred->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK) && + (cred->key_len < 8 || has_ctrl_char(cred->key, cred->key_len))) { + wpa_printf(MSG_INFO, "WPS: Reject credential with invalid WPA/WPA2-Personal passphrase"); + wpa_hexdump_ascii_key(MSG_INFO, "WPS: Network Key", + cred->key, cred->key_len); + return -1; + } + return 0; }