Cumulative patch from commit f10ff62e4eda7917a8e28fe492fd98723a5e97c4
f10ff62 Describe preferred mechanism for submitting contributions
fcdb359 Use "STATUS-NO_EVENTS" instead of "STATUS" in get_wpa_status function
73ed03f wpa_supplicant: Add GTK RSC relaxation workaround
ea6030c Restore previous wpa_state in scan-only result handler
1e74ae4 WNM: Clear BSS TM data if already associated with preferred candidate
d129b02 EAP-pwd: Add support for Brainpool Elliptic Curves
a34eace dbus: Remove unused dict helper functions
cdcb2d0 wpa_cli: Add support for vendor_elem_* commands
17b7032 EAP peer: Clear ignore flag in INITIALIZE state
1f1e619 Add test programs for checking libwpa_client linking
736b7cb wpa_supplicant/Makefile: Fix libwpa_client build
2e38079 TLS: Fix memory leak with multiple TLS server instances
7b0f550 eap_sim_db: Implement eap_sim_db_expire_pending()
45c3e72 Add frequency to operating class determination for 5 GHz 100..140
e50c50d dbus: Expose interface globals via D-Bus properties
1aa0fb7 dbus: Pass property description to getters/setters
c93b7e1 RSN: Check result of EAPOL-Key frame send request
95be79f Allow -1 as value to disable frag_threshold
bc50bb0 Extend the range of values for the RTS threshold
053693d hostapd: Add feature to start all interfaces at the same time in sync
9578413 Reserve QCA vendor specific nl80211 commands 110..114
5d4c508 Assign QCA commands and attributes for Tx power scaling and OTA testing
5d1d69a P2P: Filter control chars in group client device name similarly to peer
f67d1a0 TDLS: Do not send error case of TPK M3 if TX fails
1248e58 wpa_supplicant: Reopen debug log file upon receipt of SIGHUP signal
d8fd633 Do not write ERROR level log entries if debug file is not used
67deaa5 l2_packet: Add build option to disable Linux packet socket workaround
fa46426 RSN: Do not try to connect if PMF disabled and AP requires it
8acbe7f WNM: Verify WNM Sleep Mode element length
dacd789 WNM: Mark set TFS buffer const
...
f24b979 OpenSSL: Merge error returns
84d6a17 TLS: Remove unused tls_capabilities()
7867227 ms_funcs: Merge similar return cases
3596361 hw_features: Merge similar return case in check_40mhz_2g4()
aac1efe Reject the initial 4-way handshake if initial GTK setup fails
2da5256 Add backtrace-based error path testing mechanism
55413ce P2P: Do not allow 40 MHz co-ex PRI/SEC switch to force MCC
Next patches were skipped due to explicit cherry-pick:
bddc51e RSN: Stop connection attempt on apparent PMK mismatch
3fdaaa8 Throttle control interface event message bursts
a530fe7 Add wpa_supplicant EVENT_TEST control interface command
ee1e3f5 hostapd: Global control interface notifications
2e95cfc Add debug prints for wpa_supplicant ctrl_iface socket send operations
ce7d0eb Update AP WPA/RSN IE on all associations if driver can select BSS
844dfeb QCA vendor command support to set band to driver
Change-Id: I909996c5afcd3b5d123ea1e23c0e1212021f7625
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/eap_peer/eap.c b/src/eap_peer/eap.c
index 1dbe003..28d5116 100644
--- a/src/eap_peer/eap.c
+++ b/src/eap_peer/eap.c
@@ -188,6 +188,14 @@
*/
eapol_set_bool(sm, EAPOL_eapResp, FALSE);
eapol_set_bool(sm, EAPOL_eapNoResp, FALSE);
+ /*
+ * RFC 4137 does not reset ignore here, but since it is possible for
+ * some method code paths to end up not setting ignore=FALSE, clear the
+ * value here to avoid issues if a previous authentication attempt
+ * failed with ignore=TRUE being left behind in the last
+ * m.check(eapReqData) operation.
+ */
+ sm->ignore = 0;
sm->num_rounds = 0;
sm->prev_failure = 0;
sm->expected_failure = 0;
@@ -584,7 +592,7 @@
wpa_printf(MSG_DEBUG, "EAP: Valid ERP key found %s (SEQ=%u)",
erp->keyname_nai, erp->next_seq);
- msg = eap_msg_alloc(EAP_VENDOR_IETF, EAP_ERP_TYPE_REAUTH,
+ msg = eap_msg_alloc(EAP_VENDOR_IETF, (EapType) EAP_ERP_TYPE_REAUTH,
1 + 2 + 2 + os_strlen(erp->keyname_nai) + 1 + 16,
EAP_CODE_INITIATE, hdr->identifier);
if (msg == NULL)
@@ -708,7 +716,7 @@
wpabuf_free(sm->lastRespData);
if (sm->eapRespData) {
if (sm->workaround)
- os_memcpy(sm->last_md5, sm->req_md5, 16);
+ os_memcpy(sm->last_sha1, sm->req_sha1, 20);
sm->lastId = sm->reqId;
sm->lastRespData = wpabuf_dup(sm->eapRespData);
eapol_set_bool(sm, EAPOL_eapResp, TRUE);
@@ -914,12 +922,12 @@
duplicate = (sm->reqId == sm->lastId) && sm->rxReq;
if (sm->workaround && duplicate &&
- os_memcmp(sm->req_md5, sm->last_md5, 16) != 0) {
+ os_memcmp(sm->req_sha1, sm->last_sha1, 20) != 0) {
/*
* RFC 4137 uses (reqId == lastId) as the only verification for
* duplicate EAP requests. However, this misses cases where the
* AS is incorrectly using the same id again; and
- * unfortunately, such implementations exist. Use MD5 hash as
+ * unfortunately, such implementations exist. Use SHA1 hash as
* an extra verification for the packets being duplicate to
* workaround these issues.
*/
@@ -1765,7 +1773,7 @@
if (sm->workaround) {
const u8 *addr[1];
addr[0] = wpabuf_head(req);
- md5_vector(1, addr, &plen, sm->req_md5);
+ sha1_vector(1, addr, &plen, sm->req_sha1);
}
switch (hdr->code) {
diff --git a/src/eap_peer/eap_fast.c b/src/eap_peer/eap_fast.c
index f636e74..833dcb6 100644
--- a/src/eap_peer/eap_fast.c
+++ b/src/eap_peer/eap_fast.c
@@ -1096,7 +1096,7 @@
/* Parse TLVs from the decrypted Phase 2 data */
pos = wpabuf_mhead(decrypted);
end = pos + wpabuf_len(decrypted);
- while (pos + 4 < end) {
+ while (end - pos > 4) {
mandatory = pos[0] & 0x80;
tlv_type = WPA_GET_BE16(pos) & 0x3fff;
pos += 2;
@@ -1572,6 +1572,13 @@
EAP_TYPE_FAST,
data->fast_version, id, &msg,
&resp);
+ if (res < 0) {
+ wpa_printf(MSG_DEBUG,
+ "EAP-FAST: TLS processing failed");
+ ret->methodState = METHOD_DONE;
+ ret->decision = DECISION_FAIL;
+ return resp;
+ }
if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
char cipher[80];
diff --git a/src/eap_peer/eap_fast_pac.c b/src/eap_peer/eap_fast_pac.c
index 89e604e..c0986b3 100644
--- a/src/eap_peer/eap_fast_pac.c
+++ b/src/eap_peer/eap_fast_pac.c
@@ -709,7 +709,7 @@
pos = pac->pac_info;
end = pos + pac->pac_info_len;
- while (pos + 4 < end) {
+ while (end - pos > 4) {
type = WPA_GET_BE16(pos);
pos += 2;
len = WPA_GET_BE16(pos);
diff --git a/src/eap_peer/eap_i.h b/src/eap_peer/eap_i.h
index 5f8b5fa..99b44da 100644
--- a/src/eap_peer/eap_i.h
+++ b/src/eap_peer/eap_i.h
@@ -338,9 +338,9 @@
Boolean rxResp /* LEAP only */;
Boolean leap_done;
Boolean peap_done;
- u8 req_md5[16]; /* MD5() of the current EAP packet */
- u8 last_md5[16]; /* MD5() of the previously received EAP packet; used
- * in duplicate request detection. */
+ u8 req_sha1[20]; /* SHA1() of the current EAP packet */
+ u8 last_sha1[20]; /* SHA1() of the previously received EAP packet; used
+ * in duplicate request detection. */
void *msg_ctx;
void *scard_ctx;
diff --git a/src/eap_peer/eap_mschapv2.c b/src/eap_peer/eap_mschapv2.c
index 9e486e7..6acf1e8 100644
--- a/src/eap_peer/eap_mschapv2.c
+++ b/src/eap_peer/eap_mschapv2.c
@@ -511,6 +511,11 @@
struct eap_sm *sm, struct eap_mschapv2_data *data,
struct eap_method_ret *ret, const struct eap_mschapv2_hdr *req, u8 id)
{
+#ifdef CONFIG_NO_RC4
+ wpa_printf(MSG_ERROR,
+ "EAP-MSCHAPV2: RC4 not support in the build - cannot change password");
+ return NULL;
+#else /* CONFIG_NO_RC4 */
struct wpabuf *resp;
int ms_len;
const u8 *username, *password, *new_password;
@@ -628,6 +633,7 @@
fail:
wpabuf_free(resp);
return NULL;
+#endif /* CONFIG_NO_RC4 */
}
diff --git a/src/eap_peer/eap_peap.c b/src/eap_peer/eap_peap.c
index 4f68fce..98a48a6 100644
--- a/src/eap_peer/eap_peap.c
+++ b/src/eap_peer/eap_peap.c
@@ -1011,6 +1011,13 @@
data->peap_version, id, &msg,
&resp);
+ if (res < 0) {
+ wpa_printf(MSG_DEBUG,
+ "EAP-PEAP: TLS processing failed");
+ ret->methodState = METHOD_DONE;
+ ret->decision = DECISION_FAIL;
+ return resp;
+ }
if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
char *label;
wpa_printf(MSG_DEBUG,
diff --git a/src/eap_peer/eap_pwd.c b/src/eap_peer/eap_pwd.c
index 5a60b3f..1f78544 100644
--- a/src/eap_peer/eap_pwd.c
+++ b/src/eap_peer/eap_pwd.c
@@ -288,6 +288,12 @@
}
if (id->prep == EAP_PWD_PREP_MS) {
+#ifdef CONFIG_FIPS
+ wpa_printf(MSG_ERROR,
+ "EAP-PWD (peer): MS password hash not supported in FIPS mode");
+ eap_pwd_state(data, FAILURE);
+ return;
+#else /* CONFIG_FIPS */
if (data->password_hash) {
res = hash_nt_password_hash(data->password, pwhashhash);
} else {
@@ -307,6 +313,7 @@
password = pwhashhash;
password_len = sizeof(pwhashhash);
+#endif /* CONFIG_FIPS */
} else {
password = data->password;
password_len = data->password_len;
diff --git a/src/eap_peer/eap_tls.c b/src/eap_peer/eap_tls.c
index d81b1cf..66a027a 100644
--- a/src/eap_peer/eap_tls.c
+++ b/src/eap_peer/eap_tls.c
@@ -156,20 +156,6 @@
ret->methodState = METHOD_DONE;
ret->decision = DECISION_FAIL;
- if (res == -1) {
- struct eap_peer_config *config = eap_get_config(sm);
- if (config) {
- /*
- * The TLS handshake failed. So better forget the old
- * PIN. It may be wrong, we cannot be sure but trying
- * the wrong one again might block it on the card--so
- * better ask the user again.
- */
- os_free(config->pin);
- config->pin = NULL;
- }
- }
-
if (resp) {
/*
* This is likely an alert message, so send it instead of just
diff --git a/src/eap_peer/eap_tls_common.c b/src/eap_peer/eap_tls_common.c
index fef7fdb..af2b754 100644
--- a/src/eap_peer/eap_tls_common.c
+++ b/src/eap_peer/eap_tls_common.c
@@ -68,6 +68,10 @@
params->flags |= TLS_CONN_DISABLE_SESSION_TICKET;
if (os_strstr(txt, "tls_disable_session_ticket=0"))
params->flags &= ~TLS_CONN_DISABLE_SESSION_TICKET;
+ if (os_strstr(txt, "tls_disable_tlsv1_0=1"))
+ params->flags |= TLS_CONN_DISABLE_TLSv1_0;
+ if (os_strstr(txt, "tls_disable_tlsv1_0=0"))
+ params->flags &= ~TLS_CONN_DISABLE_TLSv1_0;
if (os_strstr(txt, "tls_disable_tlsv1_1=1"))
params->flags |= TLS_CONN_DISABLE_TLSv1_1;
if (os_strstr(txt, "tls_disable_tlsv1_1=0"))
@@ -343,10 +347,10 @@
struct eap_ssl_data *data, u8 eap_type,
size_t *len)
{
- struct tls_keys keys;
+ struct tls_random keys;
u8 *out;
- if (tls_connection_get_keys(sm->ssl_ctx, data->conn, &keys))
+ if (tls_connection_get_random(sm->ssl_ctx, data->conn, &keys))
return NULL;
if (keys.client_random == NULL || keys.server_random == NULL)
@@ -678,12 +682,18 @@
if (tls_connection_get_failed(data->ssl_ctx, data->conn)) {
/* TLS processing has failed - return error */
wpa_printf(MSG_DEBUG, "SSL: Failed - tls_out available to "
- "report error");
+ "report error (len=%u)",
+ (unsigned int) wpabuf_len(data->tls_out));
ret = -1;
/* TODO: clean pin if engine used? */
+ if (wpabuf_len(data->tls_out) == 0) {
+ wpabuf_free(data->tls_out);
+ data->tls_out = NULL;
+ return -1;
+ }
}
- if (data->tls_out == NULL || wpabuf_len(data->tls_out) == 0) {
+ if (wpabuf_len(data->tls_out) == 0) {
/*
* TLS negotiation should now be complete since all other cases
* needing more data should have been caught above based on
@@ -749,20 +759,24 @@
int eap_peer_tls_status(struct eap_sm *sm, struct eap_ssl_data *data,
char *buf, size_t buflen, int verbose)
{
- char name[128];
+ char version[20], name[128];
int len = 0, ret;
- if (tls_get_cipher(data->ssl_ctx, data->conn, name, sizeof(name)) == 0)
- {
- ret = os_snprintf(buf + len, buflen - len,
- "EAP TLS cipher=%s\n"
- "tls_session_reused=%d\n",
- name, tls_connection_resumed(data->ssl_ctx,
- data->conn));
- if (os_snprintf_error(buflen - len, ret))
- return len;
- len += ret;
- }
+ if (tls_get_version(data->ssl_ctx, data->conn, version,
+ sizeof(version)) < 0)
+ version[0] = '\0';
+ if (tls_get_cipher(data->ssl_ctx, data->conn, name, sizeof(name)) < 0)
+ name[0] = '\0';
+
+ ret = os_snprintf(buf + len, buflen - len,
+ "eap_tls_version=%s\n"
+ "EAP TLS cipher=%s\n"
+ "tls_session_reused=%d\n",
+ version, name,
+ tls_connection_resumed(data->ssl_ctx, data->conn));
+ if (os_snprintf_error(buflen - len, ret))
+ return len;
+ len += ret;
return len;
}
diff --git a/src/eap_peer/eap_ttls.c b/src/eap_peer/eap_ttls.c
index 25e3cba..b186c91 100644
--- a/src/eap_peer/eap_ttls.c
+++ b/src/eap_peer/eap_ttls.c
@@ -175,7 +175,8 @@
}
avp->avp_code = host_to_be32(avp_code);
- avp->avp_length = host_to_be32((flags << 24) | (u32) (hdrlen + len));
+ avp->avp_length = host_to_be32(((u32) flags << 24) |
+ (u32) (hdrlen + len));
return avphdr + hdrlen;
}
@@ -253,11 +254,13 @@
}
+#ifndef CONFIG_FIPS
static u8 * eap_ttls_implicit_challenge(struct eap_sm *sm,
struct eap_ttls_data *data, size_t len)
{
return eap_peer_tls_derive_key(sm, &data->ssl, "ttls challenge", len);
}
+#endif /* CONFIG_FIPS */
static void eap_ttls_phase2_select_eap_method(struct eap_ttls_data *data,
@@ -428,6 +431,10 @@
struct eap_method_ret *ret,
struct wpabuf **resp)
{
+#ifdef CONFIG_FIPS
+ wpa_printf(MSG_ERROR, "EAP-TTLS: MSCHAPV2 not supported in FIPS build");
+ return -1;
+#else /* CONFIG_FIPS */
#ifdef EAP_MSCHAPv2
struct wpabuf *msg;
u8 *buf, *pos, *challenge, *peer_challenge;
@@ -510,6 +517,7 @@
wpa_printf(MSG_ERROR, "EAP-TTLS: MSCHAPv2 not included in the build");
return -1;
#endif /* EAP_MSCHAPv2 */
+#endif /* CONFIG_FIPS */
}
@@ -518,6 +526,10 @@
struct eap_method_ret *ret,
struct wpabuf **resp)
{
+#ifdef CONFIG_FIPS
+ wpa_printf(MSG_ERROR, "EAP-TTLS: MSCHAP not supported in FIPS build");
+ return -1;
+#else /* CONFIG_FIPS */
struct wpabuf *msg;
u8 *buf, *pos, *challenge;
const u8 *identity, *password;
@@ -592,6 +604,7 @@
ret->decision = DECISION_COND_SUCC;
return 0;
+#endif /* CONFIG_FIPS */
}
@@ -654,6 +667,10 @@
struct eap_method_ret *ret,
struct wpabuf **resp)
{
+#ifdef CONFIG_FIPS
+ wpa_printf(MSG_ERROR, "EAP-TTLS: CHAP not supported in FIPS build");
+ return -1;
+#else /* CONFIG_FIPS */
struct wpabuf *msg;
u8 *buf, *pos, *challenge;
const u8 *identity, *password;
@@ -722,6 +739,7 @@
ret->decision = DECISION_COND_SUCC;
return 0;
+#endif /* CONFIG_FIPS */
}
@@ -1393,6 +1411,12 @@
res = eap_peer_tls_process_helper(sm, &data->ssl, EAP_TYPE_TTLS,
data->ttls_version, identifier,
in_data, out_data);
+ if (res < 0) {
+ wpa_printf(MSG_DEBUG, "EAP-TTLS: TLS processing failed");
+ ret->methodState = METHOD_DONE;
+ ret->decision = DECISION_FAIL;
+ return -1;
+ }
if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
wpa_printf(MSG_DEBUG, "EAP-TTLS: TLS done, proceed to "
diff --git a/src/eap_peer/eap_wsc.c b/src/eap_peer/eap_wsc.c
index 7ce0a53..7ac99c7 100644
--- a/src/eap_peer/eap_wsc.c
+++ b/src/eap_peer/eap_wsc.c
@@ -557,6 +557,9 @@
if (data->out_buf == NULL) {
wpa_printf(MSG_DEBUG, "EAP-WSC: Failed to receive "
"message from WPS");
+ eap_wsc_state(data, FAIL);
+ ret->methodState = METHOD_DONE;
+ ret->decision = DECISION_FAIL;
return NULL;
}
data->out_used = 0;
diff --git a/src/eap_peer/ikev2.c b/src/eap_peer/ikev2.c
index 55ab72a..ca6502e 100644
--- a/src/eap_peer/ikev2.c
+++ b/src/eap_peer/ikev2.c
@@ -128,7 +128,7 @@
t = (const struct ikev2_transform *) pos;
transform_len = WPA_GET_BE16(t->transform_length);
- if (transform_len < (int) sizeof(*t) || pos + transform_len > end) {
+ if (transform_len < (int) sizeof(*t) || transform_len > end - pos) {
wpa_printf(MSG_INFO, "IKEV2: Invalid transform length %d",
transform_len);
return -1;
@@ -248,7 +248,7 @@
ppos = (const u8 *) (p + 1);
pend = pos + proposal_len;
- if (ppos + p->spi_size > pend) {
+ if (p->spi_size > pend - ppos) {
wpa_printf(MSG_INFO, "IKEV2: Not enough room for SPI "
"in proposal");
return -1;