summaryrefslogtreecommitdiffstats
path: root/freebsd/contrib/wpa/src/eap_peer/eap_peap.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/contrib/wpa/src/eap_peer/eap_peap.c')
-rw-r--r--freebsd/contrib/wpa/src/eap_peer/eap_peap.c76
1 files changed, 58 insertions, 18 deletions
diff --git a/freebsd/contrib/wpa/src/eap_peer/eap_peap.c b/freebsd/contrib/wpa/src/eap_peer/eap_peap.c
index 19afa1cf..ab270bbc 100644
--- a/freebsd/contrib/wpa/src/eap_peer/eap_peap.c
+++ b/freebsd/contrib/wpa/src/eap_peer/eap_peap.c
@@ -2,7 +2,7 @@
/*
* EAP peer method: EAP-PEAP (draft-josefsson-pppext-eap-tls-eap-10.txt)
- * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -61,6 +61,7 @@ struct eap_peap_data {
size_t id_len;
struct wpabuf *pending_phase2_req;
+ struct wpabuf *pending_resp;
enum { NO_BINDING, OPTIONAL_BINDING, REQUIRE_BINDING } crypto_binding;
int crypto_binding_used;
u8 binding_nonce[32];
@@ -71,8 +72,8 @@ struct eap_peap_data {
};
-static int eap_peap_parse_phase1(struct eap_peap_data *data,
- const char *phase1)
+static void eap_peap_parse_phase1(struct eap_peap_data *data,
+ const char *phase1)
{
const char *pos;
@@ -127,8 +128,6 @@ static int eap_peap_parse_phase1(struct eap_peap_data *data,
wpa_printf(MSG_DEBUG, "EAP-PEAP: SoH version 2 enabled");
}
#endif /* EAP_TNC */
-
- return 0;
}
@@ -146,11 +145,8 @@ static void * eap_peap_init(struct eap_sm *sm)
data->peap_outer_success = 2;
data->crypto_binding = OPTIONAL_BINDING;
- if (config && config->phase1 &&
- eap_peap_parse_phase1(data, config->phase1) < 0) {
- eap_peap_deinit(sm, data);
- return NULL;
- }
+ if (config && config->phase1)
+ eap_peap_parse_phase1(data, config->phase1);
if (eap_peer_select_phase2_methods(config, "auth=",
&data->phase2_types,
@@ -193,6 +189,7 @@ static void eap_peap_deinit(struct eap_sm *sm, void *priv)
eap_peap_free_key(data);
os_free(data->session_id);
wpabuf_free(data->pending_phase2_req);
+ wpabuf_free(data->pending_resp);
os_free(data);
}
@@ -258,6 +255,7 @@ static int eap_peap_derive_cmk(struct eap_sm *sm, struct eap_peap_data *data)
{
u8 *tk;
u8 isk[32], imck[60];
+ int resumed;
/*
* Tunnel key (TK) is the first 60 octets of the key generated by
@@ -268,8 +266,12 @@ static int eap_peap_derive_cmk(struct eap_sm *sm, struct eap_peap_data *data)
return -1;
wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: TK", tk, 60);
- if (data->reauth &&
- tls_connection_resumed(sm->ssl_ctx, data->ssl.conn)) {
+ resumed = tls_connection_resumed(sm->ssl_ctx, data->ssl.conn);
+ wpa_printf(MSG_DEBUG,
+ "EAP-PEAP: CMK derivation - reauth=%d resumed=%d phase2_eap_started=%d phase2_success=%d",
+ data->reauth, resumed, data->phase2_eap_started,
+ data->phase2_success);
+ if (data->reauth && !data->phase2_eap_started && resumed) {
/* Fast-connect: IPMK|CMK = TK */
os_memcpy(data->ipmk, tk, 40);
wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: IPMK from TK",
@@ -339,7 +341,8 @@ static int eap_tlv_add_cryptobinding(struct eap_sm *sm,
addr[0], len[0]);
wpa_hexdump(MSG_MSGDUMP, "EAP-PEAP: Compound_MAC data 2",
addr[1], len[1]);
- hmac_sha1_vector(data->cmk, 20, 2, addr, len, mac);
+ if (hmac_sha1_vector(data->cmk, 20, 2, addr, len, mac) < 0)
+ return -1;
wpa_hexdump(MSG_MSGDUMP, "EAP-PEAP: Compound_MAC", mac, SHA1_MAC_LEN);
data->crypto_binding_used = 1;
@@ -650,6 +653,7 @@ static int eap_peap_phase2_request(struct eap_sm *sm,
if (*resp == NULL) {
ret->methodState = METHOD_DONE;
ret->decision = DECISION_FAIL;
+ wpabuf_free(buf);
return -1;
}
wpabuf_put_buf(*resp, buf);
@@ -1008,6 +1012,34 @@ static struct wpabuf * eap_peap_process(struct eap_sm *sm, void *priv,
!data->resuming) {
res = eap_peap_decrypt(sm, data, ret, req, &msg, &resp);
} else {
+ if (sm->waiting_ext_cert_check && data->pending_resp) {
+ struct eap_peer_config *config = eap_get_config(sm);
+
+ if (config->pending_ext_cert_check ==
+ EXT_CERT_CHECK_GOOD) {
+ wpa_printf(MSG_DEBUG,
+ "EAP-PEAP: External certificate check succeeded - continue handshake");
+ resp = data->pending_resp;
+ data->pending_resp = NULL;
+ sm->waiting_ext_cert_check = 0;
+ return resp;
+ }
+
+ if (config->pending_ext_cert_check ==
+ EXT_CERT_CHECK_BAD) {
+ wpa_printf(MSG_DEBUG,
+ "EAP-PEAP: External certificate check failed - force authentication failure");
+ ret->methodState = METHOD_DONE;
+ ret->decision = DECISION_FAIL;
+ sm->waiting_ext_cert_check = 0;
+ return NULL;
+ }
+
+ wpa_printf(MSG_DEBUG,
+ "EAP-PEAP: Continuing to wait external server certificate validation");
+ return NULL;
+ }
+
res = eap_peer_tls_process_helper(sm, &data->ssl,
EAP_TYPE_PEAP,
data->peap_version, id, &msg,
@@ -1020,6 +1052,16 @@ static struct wpabuf * eap_peap_process(struct eap_sm *sm, void *priv,
ret->decision = DECISION_FAIL;
return resp;
}
+
+
+ if (sm->waiting_ext_cert_check) {
+ wpa_printf(MSG_DEBUG,
+ "EAP-PEAP: Waiting external server certificate validation");
+ wpabuf_free(data->pending_resp);
+ data->pending_resp = resp;
+ return NULL;
+ }
+
if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
char *label;
wpa_printf(MSG_DEBUG,
@@ -1125,6 +1167,8 @@ static void eap_peap_deinit_for_reauth(struct eap_sm *sm, void *priv)
struct eap_peap_data *data = priv;
wpabuf_free(data->pending_phase2_req);
data->pending_phase2_req = NULL;
+ wpabuf_free(data->pending_resp);
+ data->pending_resp = NULL;
data->crypto_binding_used = 0;
}
@@ -1239,7 +1283,6 @@ static u8 * eap_peap_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
int eap_peer_peap_register(void)
{
struct eap_method *eap;
- int ret;
eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
EAP_VENDOR_IETF, EAP_TYPE_PEAP, "PEAP");
@@ -1257,8 +1300,5 @@ int eap_peer_peap_register(void)
eap->init_for_reauth = eap_peap_init_for_reauth;
eap->getSessionId = eap_peap_get_session_id;
- ret = eap_peer_method_register(eap);
- if (ret)
- eap_peer_method_free(eap);
- return ret;
+ return eap_peer_method_register(eap);
}