summaryrefslogtreecommitdiffstats
path: root/src/eap_peer
diff options
context:
space:
mode:
Diffstat (limited to 'src/eap_peer')
-rw-r--r--src/eap_peer/Makefile1
-rw-r--r--src/eap_peer/eap.c77
-rw-r--r--src/eap_peer/eap.h2
-rw-r--r--src/eap_peer/eap_aka.c14
-rw-r--r--src/eap_peer/eap_config.h9
-rw-r--r--src/eap_peer/eap_fast.c12
-rw-r--r--src/eap_peer/eap_fast_pac.c29
-rw-r--r--src/eap_peer/eap_leap.c32
-rw-r--r--src/eap_peer/eap_md5.c2
-rw-r--r--src/eap_peer/eap_methods.c155
-rw-r--r--src/eap_peer/eap_methods.h23
-rw-r--r--src/eap_peer/eap_mschapv2.c19
-rw-r--r--src/eap_peer/eap_pax.c4
-rw-r--r--src/eap_peer/eap_peap.c12
-rw-r--r--src/eap_peer/eap_psk.c4
-rw-r--r--src/eap_peer/eap_sim.c6
-rw-r--r--src/eap_peer/eap_tls.c2
-rw-r--r--src/eap_peer/eap_tls_common.c164
-rw-r--r--src/eap_peer/eap_tls_common.h23
-rw-r--r--src/eap_peer/eap_tnc.c5
-rw-r--r--src/eap_peer/eap_ttls.c63
-rw-r--r--src/eap_peer/eap_wsc.c94
-rw-r--r--src/eap_peer/ikev2.c2
-rw-r--r--src/eap_peer/mschapv2.c26
-rw-r--r--src/eap_peer/mschapv2.h14
25 files changed, 393 insertions, 401 deletions
diff --git a/src/eap_peer/Makefile b/src/eap_peer/Makefile
index d9449a2..3651056 100644
--- a/src/eap_peer/Makefile
+++ b/src/eap_peer/Makefile
@@ -2,7 +2,6 @@ all:
@echo Nothing to be made.
clean:
- for d in $(SUBDIRS); do make -C $$d clean; done
rm -f *~ *.o *.so *.d
install:
diff --git a/src/eap_peer/eap.c b/src/eap_peer/eap.c
index e8e504a..b9f186b 100644
--- a/src/eap_peer/eap.c
+++ b/src/eap_peer/eap.c
@@ -1,6 +1,6 @@
/*
* EAP peer state machines (RFC 4137)
- * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -24,14 +24,14 @@
#include "includes.h"
#include "common.h"
-#include "eap_i.h"
-#include "eap_config.h"
-#include "tls.h"
-#include "crypto.h"
#include "pcsc_funcs.h"
-#include "wpa_ctrl.h"
#include "state_machine.h"
+#include "crypto/crypto.h"
+#include "crypto/tls.h"
+#include "common/wpa_ctrl.h"
#include "eap_common/eap_wsc_common.h"
+#include "eap_i.h"
+#include "eap_config.h"
#define STATE_MACHINE_DATA struct eap_sm
#define STATE_MACHINE_DEBUG_PREFIX "EAP"
@@ -228,9 +228,15 @@ SM_STATE(EAP, GET_METHOD)
if (!eap_sm_allowMethod(sm, sm->reqVendor, method)) {
wpa_printf(MSG_DEBUG, "EAP: vendor %u method %u not allowed",
sm->reqVendor, method);
+ wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_PROPOSED_METHOD
+ "vendor=%u method=%u -> NAK",
+ sm->reqVendor, method);
goto nak;
}
+ wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_PROPOSED_METHOD
+ "vendor=%u method=%u", sm->reqVendor, method);
+
/*
* RFC 4137 does not define specific operation for fast
* re-authentication (session resumption). The design here is to allow
@@ -1154,6 +1160,60 @@ static void eap_sm_parseEapReq(struct eap_sm *sm, const struct wpabuf *req)
}
+static void eap_peer_sm_tls_event(void *ctx, enum tls_event ev,
+ union tls_event_data *data)
+{
+ struct eap_sm *sm = ctx;
+ char *hash_hex = NULL;
+ char *cert_hex = NULL;
+
+ switch (ev) {
+ case TLS_CERT_CHAIN_FAILURE:
+ wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_TLS_CERT_ERROR
+ "reason=%d depth=%d subject='%s' err='%s'",
+ data->cert_fail.reason,
+ data->cert_fail.depth,
+ data->cert_fail.subject,
+ data->cert_fail.reason_txt);
+ break;
+ case TLS_PEER_CERTIFICATE:
+ if (data->peer_cert.hash) {
+ size_t len = data->peer_cert.hash_len * 2 + 1;
+ hash_hex = os_malloc(len);
+ if (hash_hex) {
+ wpa_snprintf_hex(hash_hex, len,
+ data->peer_cert.hash,
+ data->peer_cert.hash_len);
+ }
+ }
+ wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_PEER_CERT
+ "depth=%d subject='%s'%s%s",
+ data->peer_cert.depth, data->peer_cert.subject,
+ hash_hex ? " hash=" : "", hash_hex ? hash_hex : "");
+
+ if (data->peer_cert.cert) {
+ size_t len = wpabuf_len(data->peer_cert.cert) * 2 + 1;
+ cert_hex = os_malloc(len);
+ if (cert_hex == NULL)
+ break;
+ wpa_snprintf_hex(cert_hex, len,
+ wpabuf_head(data->peer_cert.cert),
+ wpabuf_len(data->peer_cert.cert));
+ wpa_msg_ctrl(sm->msg_ctx, MSG_INFO,
+ WPA_EVENT_EAP_PEER_CERT
+ "depth=%d subject='%s' cert=%s",
+ data->peer_cert.depth,
+ data->peer_cert.subject,
+ cert_hex);
+ }
+ break;
+ }
+
+ os_free(hash_hex);
+ os_free(cert_hex);
+}
+
+
/**
* eap_peer_sm_init - Allocate and initialize EAP peer state machine
* @eapol_ctx: Context data to be used with eapol_cb calls
@@ -1188,6 +1248,11 @@ struct eap_sm * eap_peer_sm_init(void *eapol_ctx,
tlsconf.opensc_engine_path = conf->opensc_engine_path;
tlsconf.pkcs11_engine_path = conf->pkcs11_engine_path;
tlsconf.pkcs11_module_path = conf->pkcs11_module_path;
+#ifdef CONFIG_FIPS
+ tlsconf.fips_mode = 1;
+#endif /* CONFIG_FIPS */
+ tlsconf.event_cb = eap_peer_sm_tls_event;
+ tlsconf.cb_ctx = sm;
sm->ssl_ctx = tls_init(&tlsconf);
if (sm->ssl_ctx == NULL) {
wpa_printf(MSG_WARNING, "SSL: Failed to initialize TLS "
diff --git a/src/eap_peer/eap.h b/src/eap_peer/eap.h
index d7a5628..40d0b69 100644
--- a/src/eap_peer/eap.h
+++ b/src/eap_peer/eap.h
@@ -15,7 +15,7 @@
#ifndef EAP_H
#define EAP_H
-#include "defs.h"
+#include "common/defs.h"
#include "eap_common/eap_defs.h"
#include "eap_peer/eap_methods.h"
diff --git a/src/eap_peer/eap_aka.c b/src/eap_peer/eap_aka.c
index f237141..182f01a 100644
--- a/src/eap_peer/eap_aka.c
+++ b/src/eap_peer/eap_aka.c
@@ -15,16 +15,14 @@
#include "includes.h"
#include "common.h"
-#include "eap_peer/eap_i.h"
#include "pcsc_funcs.h"
+#include "crypto/crypto.h"
+#include "crypto/sha1.h"
+#include "crypto/sha256.h"
+#include "crypto/milenage.h"
#include "eap_common/eap_sim_common.h"
-#include "sha1.h"
-#include "sha256.h"
-#include "crypto.h"
-#include "eap_peer/eap_config.h"
-#ifdef CONFIG_USIM_SIMULATOR
-#include "hlr_auc_gw/milenage.h"
-#endif /* CONFIG_USIM_SIMULATOR */
+#include "eap_config.h"
+#include "eap_i.h"
struct eap_aka_data {
diff --git a/src/eap_peer/eap_config.h b/src/eap_peer/eap_config.h
index 94245c3..b64b68f 100644
--- a/src/eap_peer/eap_config.h
+++ b/src/eap_peer/eap_config.h
@@ -85,6 +85,15 @@ struct eap_peer_config {
* Alternatively, a named configuration blob can be used by setting
* this to blob://blob_name.
*
+ * Alternatively, this can be used to only perform matching of the
+ * server certificate (SHA-256 hash of the DER encoded X.509
+ * certificate). In this case, the possible CA certificates in the
+ * server certificate chain are ignored and only the server certificate
+ * is verified. This is configured with the following format:
+ * hash:://server/sha256/cert_hash_in_hex
+ * For example: "hash://server/sha256/
+ * 5a1bc1296205e6fdbe3979728efe3920798885c1c4590b5f90f43222d239ca6a"
+ *
* On Windows, trusted CA certificates can be loaded from the system
* certificate store by setting this to cert_store://name, e.g.,
* ca_cert="cert_store://CA" or ca_cert="cert_store://ROOT".
diff --git a/src/eap_peer/eap_fast.c b/src/eap_peer/eap_fast.c
index d008670..5d3e69d 100644
--- a/src/eap_peer/eap_fast.c
+++ b/src/eap_peer/eap_fast.c
@@ -15,12 +15,12 @@
#include "includes.h"
#include "common.h"
+#include "crypto/tls.h"
+#include "crypto/sha1.h"
+#include "eap_common/eap_tlv_common.h"
#include "eap_i.h"
#include "eap_tls_common.h"
#include "eap_config.h"
-#include "tls.h"
-#include "eap_common/eap_tlv_common.h"
-#include "sha1.h"
#include "eap_fast_pac.h"
#ifdef EAP_FAST_DYNAMIC
@@ -1445,9 +1445,9 @@ static int eap_fast_process_start(struct eap_sm *sm,
/* EAP-FAST Version negotiation (section 3.1) */
wpa_printf(MSG_DEBUG, "EAP-FAST: Start (server ver=%d, own ver=%d)",
- flags & EAP_PEAP_VERSION_MASK, data->fast_version);
- if ((flags & EAP_PEAP_VERSION_MASK) < data->fast_version)
- data->fast_version = flags & EAP_PEAP_VERSION_MASK;
+ flags & EAP_TLS_VERSION_MASK, data->fast_version);
+ if ((flags & EAP_TLS_VERSION_MASK) < data->fast_version)
+ data->fast_version = flags & EAP_TLS_VERSION_MASK;
wpa_printf(MSG_DEBUG, "EAP-FAST: Using FAST version %d",
data->fast_version);
diff --git a/src/eap_peer/eap_fast_pac.c b/src/eap_peer/eap_fast_pac.c
index 77893d6..541cce5 100644
--- a/src/eap_peer/eap_fast_pac.c
+++ b/src/eap_peer/eap_fast_pac.c
@@ -480,8 +480,10 @@ static void eap_fast_write(char **buf, char **pos, size_t *buf_len,
{
size_t i, need;
int ret;
+ char *end;
- if (data == NULL || *buf == NULL)
+ if (data == NULL || buf == NULL || *buf == NULL ||
+ pos == NULL || *pos == NULL || *pos < *buf)
return;
need = os_strlen(field) + len * 2 + 30;
@@ -498,32 +500,31 @@ static void eap_fast_write(char **buf, char **pos, size_t *buf_len,
*buf = nbuf;
*buf_len += need;
}
+ end = *buf + *buf_len;
- ret = os_snprintf(*pos, *buf + *buf_len - *pos, "%s=", field);
- if (ret < 0 || ret >= *buf + *buf_len - *pos)
+ ret = os_snprintf(*pos, end - *pos, "%s=", field);
+ if (ret < 0 || ret >= end - *pos)
return;
*pos += ret;
- *pos += wpa_snprintf_hex(*pos, *buf + *buf_len - *pos, data, len);
- ret = os_snprintf(*pos, *buf + *buf_len - *pos, "\n");
- if (ret < 0 || ret >= *buf + *buf_len - *pos)
+ *pos += wpa_snprintf_hex(*pos, end - *pos, data, len);
+ ret = os_snprintf(*pos, end - *pos, "\n");
+ if (ret < 0 || ret >= end - *pos)
return;
*pos += ret;
if (txt) {
- ret = os_snprintf(*pos, *buf + *buf_len - *pos,
- "%s-txt=", field);
- if (ret < 0 || ret >= *buf + *buf_len - *pos)
+ ret = os_snprintf(*pos, end - *pos, "%s-txt=", field);
+ if (ret < 0 || ret >= end - *pos)
return;
*pos += ret;
for (i = 0; i < len; i++) {
- ret = os_snprintf(*pos, *buf + *buf_len - *pos,
- "%c", data[i]);
- if (ret < 0 || ret >= *buf + *buf_len - *pos)
+ ret = os_snprintf(*pos, end - *pos, "%c", data[i]);
+ if (ret < 0 || ret >= end - *pos)
return;
*pos += ret;
}
- ret = os_snprintf(*pos, *buf + *buf_len - *pos, "\n");
- if (ret < 0 || ret >= *buf + *buf_len - *pos)
+ ret = os_snprintf(*pos, end - *pos, "\n");
+ if (ret < 0 || ret >= end - *pos)
return;
*pos += ret;
}
diff --git a/src/eap_peer/eap_leap.c b/src/eap_peer/eap_leap.c
index 01c1f16..a7c94a4 100644
--- a/src/eap_peer/eap_leap.c
+++ b/src/eap_peer/eap_leap.c
@@ -15,9 +15,9 @@
#include "includes.h"
#include "common.h"
+#include "crypto/ms_funcs.h"
+#include "crypto/crypto.h"
#include "eap_i.h"
-#include "ms_funcs.h"
-#include "crypto.h"
#define LEAP_VERSION 1
#define LEAP_CHALLENGE_LEN 8
@@ -233,10 +233,16 @@ static struct wpabuf * eap_leap_process_response(struct eap_sm *sm, void *priv,
os_memcpy(data->ap_response, pos, LEAP_RESPONSE_LEN);
if (pwhash) {
- hash_nt_password_hash(password, pw_hash_hash);
+ if (hash_nt_password_hash(password, pw_hash_hash)) {
+ ret->ignore = TRUE;
+ return NULL;
+ }
} else {
- nt_password_hash(password, password_len, pw_hash);
- hash_nt_password_hash(pw_hash, pw_hash_hash);
+ if (nt_password_hash(password, password_len, pw_hash) ||
+ hash_nt_password_hash(pw_hash, pw_hash_hash)) {
+ ret->ignore = TRUE;
+ return NULL;
+ }
}
challenge_response(data->ap_challenge, pw_hash_hash, expected);
@@ -345,11 +351,17 @@ static u8 * eap_leap_getKey(struct eap_sm *sm, void *priv, size_t *len)
if (key == NULL)
return NULL;
- if (pwhash)
- hash_nt_password_hash(password, pw_hash_hash);
- else {
- nt_password_hash(password, password_len, pw_hash);
- hash_nt_password_hash(pw_hash, pw_hash_hash);
+ if (pwhash) {
+ if (hash_nt_password_hash(password, pw_hash_hash)) {
+ os_free(key);
+ return NULL;
+ }
+ } else {
+ if (nt_password_hash(password, password_len, pw_hash) ||
+ hash_nt_password_hash(pw_hash, pw_hash_hash)) {
+ os_free(key);
+ return NULL;
+ }
}
wpa_hexdump_key(MSG_DEBUG, "EAP-LEAP: pw_hash_hash",
pw_hash_hash, 16);
diff --git a/src/eap_peer/eap_md5.c b/src/eap_peer/eap_md5.c
index 7961143..0edbae8 100644
--- a/src/eap_peer/eap_md5.c
+++ b/src/eap_peer/eap_md5.c
@@ -76,7 +76,7 @@ static struct wpabuf * eap_md5_process(struct eap_sm *sm, void *priv,
wpa_printf(MSG_DEBUG, "EAP-MD5: Generating Challenge Response");
ret->methodState = METHOD_DONE;
- ret->decision = DECISION_UNCOND_SUCC;
+ ret->decision = DECISION_COND_SUCC;
ret->allowNotifications = TRUE;
resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MD5, 1 + CHAP_MD5_LEN,
diff --git a/src/eap_peer/eap_methods.c b/src/eap_peer/eap_methods.c
index 2374e5e..3b0af05 100644
--- a/src/eap_peer/eap_methods.c
+++ b/src/eap_peer/eap_methods.c
@@ -340,161 +340,6 @@ int eap_peer_method_register(struct eap_method *method)
/**
- * eap_peer_register_methods - Register statically linked EAP peer methods
- * Returns: 0 on success, -1 on failure
- *
- * This function is called at program initialization to register all EAP peer
- * methods that were linked in statically.
- */
-int eap_peer_register_methods(void)
-{
- int ret = 0;
-
-#ifdef EAP_MD5
- if (ret == 0) {
- int eap_peer_md5_register(void);
- ret = eap_peer_md5_register();
- }
-#endif /* EAP_MD5 */
-
-#ifdef EAP_TLS
- if (ret == 0) {
- int eap_peer_tls_register(void);
- ret = eap_peer_tls_register();
- }
-#endif /* EAP_TLS */
-
-#ifdef EAP_MSCHAPv2
- if (ret == 0) {
- int eap_peer_mschapv2_register(void);
- ret = eap_peer_mschapv2_register();
- }
-#endif /* EAP_MSCHAPv2 */
-
-#ifdef EAP_PEAP
- if (ret == 0) {
- int eap_peer_peap_register(void);
- ret = eap_peer_peap_register();
- }
-#endif /* EAP_PEAP */
-
-#ifdef EAP_TTLS
- if (ret == 0) {
- int eap_peer_ttls_register(void);
- ret = eap_peer_ttls_register();
- }
-#endif /* EAP_TTLS */
-
-#ifdef EAP_GTC
- if (ret == 0) {
- int eap_peer_gtc_register(void);
- ret = eap_peer_gtc_register();
- }
-#endif /* EAP_GTC */
-
-#ifdef EAP_OTP
- if (ret == 0) {
- int eap_peer_otp_register(void);
- ret = eap_peer_otp_register();
- }
-#endif /* EAP_OTP */
-
-#ifdef EAP_SIM
- if (ret == 0) {
- int eap_peer_sim_register(void);
- ret = eap_peer_sim_register();
- }
-#endif /* EAP_SIM */
-
-#ifdef EAP_LEAP
- if (ret == 0) {
- int eap_peer_leap_register(void);
- ret = eap_peer_leap_register();
- }
-#endif /* EAP_LEAP */
-
-#ifdef EAP_PSK
- if (ret == 0) {
- int eap_peer_psk_register(void);
- ret = eap_peer_psk_register();
- }
-#endif /* EAP_PSK */
-
-#ifdef EAP_AKA
- if (ret == 0) {
- int eap_peer_aka_register(void);
- ret = eap_peer_aka_register();
- }
-#endif /* EAP_AKA */
-
-#ifdef EAP_AKA_PRIME
- if (ret == 0) {
- int eap_peer_aka_prime_register(void);
- ret = eap_peer_aka_prime_register();
- }
-#endif /* EAP_AKA_PRIME */
-
-#ifdef EAP_FAST
- if (ret == 0) {
- int eap_peer_fast_register(void);
- ret = eap_peer_fast_register();
- }
-#endif /* EAP_FAST */
-
-#ifdef EAP_PAX
- if (ret == 0) {
- int eap_peer_pax_register(void);
- ret = eap_peer_pax_register();
- }
-#endif /* EAP_PAX */
-
-#ifdef EAP_SAKE
- if (ret == 0) {
- int eap_peer_sake_register(void);
- ret = eap_peer_sake_register();
- }
-#endif /* EAP_SAKE */
-
-#ifdef EAP_GPSK
- if (ret == 0) {
- int eap_peer_gpsk_register(void);
- ret = eap_peer_gpsk_register();
- }
-#endif /* EAP_GPSK */
-
-#ifdef EAP_WSC
- if (ret == 0) {
- int eap_peer_wsc_register(void);
- ret = eap_peer_wsc_register();
- }
-#endif /* EAP_WSC */
-
-#ifdef EAP_IKEV2
- if (ret == 0) {
- int eap_peer_ikev2_register(void);
- ret = eap_peer_ikev2_register();
- }
-#endif /* EAP_IKEV2 */
-
-#ifdef EAP_VENDOR_TEST
- if (ret == 0) {
- int eap_peer_vendor_test_register(void);
- ret = eap_peer_vendor_test_register();
- }
-#endif /* EAP_VENDOR_TEST */
-
-#ifdef EAP_TNC
- if (ret == 0) {
- int eap_peer_tnc_register(void);
- ret = eap_peer_tnc_register();
- }
-#endif /* EAP_TNC */
-
- return ret;
-}
-
-
-/**
* eap_peer_unregister_methods - Unregister EAP peer methods
*
* This function is called at program termination to unregister all EAP peer
diff --git a/src/eap_peer/eap_methods.h b/src/eap_peer/eap_methods.h
index 9fd9b51..384c61b 100644
--- a/src/eap_peer/eap_methods.h
+++ b/src/eap_peer/eap_methods.h
@@ -32,7 +32,6 @@ EapType eap_peer_get_type(const char *name, int *vendor);
const char * eap_get_name(int vendor, EapType type);
size_t eap_get_names(char *buf, size_t buflen);
char ** eap_get_names_as_string_array(size_t *num);
-int eap_peer_register_methods(void);
void eap_peer_unregister_methods(void);
#else /* IEEE8021X_EAPOL */
@@ -89,4 +88,26 @@ static inline int eap_peer_method_unload(struct eap_method *method)
#endif /* CONFIG_DYNAMIC_EAP_METHODS */
+/* EAP peer method registration calls for statically linked in methods */
+int eap_peer_md5_register(void);
+int eap_peer_tls_register(void);
+int eap_peer_mschapv2_register(void);
+int eap_peer_peap_register(void);
+int eap_peer_ttls_register(void);
+int eap_peer_gtc_register(void);
+int eap_peer_otp_register(void);
+int eap_peer_sim_register(void);
+int eap_peer_leap_register(void);
+int eap_peer_psk_register(void);
+int eap_peer_aka_register(void);
+int eap_peer_aka_prime_register(void);
+int eap_peer_fast_register(void);
+int eap_peer_pax_register(void);
+int eap_peer_sake_register(void);
+int eap_peer_gpsk_register(void);
+int eap_peer_wsc_register(void);
+int eap_peer_ikev2_register(void);
+int eap_peer_vendor_test_register(void);
+int eap_peer_tnc_register(void);
+
#endif /* EAP_METHODS_H */
diff --git a/src/eap_peer/eap_mschapv2.c b/src/eap_peer/eap_mschapv2.c
index b0c3ab7..cd410d9 100644
--- a/src/eap_peer/eap_mschapv2.c
+++ b/src/eap_peer/eap_mschapv2.c
@@ -22,11 +22,11 @@
#include "includes.h"
#include "common.h"
+#include "crypto/ms_funcs.h"
+#include "common/wpa_ctrl.h"
+#include "mschapv2.h"
#include "eap_i.h"
#include "eap_config.h"
-#include "ms_funcs.h"
-#include "wpa_ctrl.h"
-#include "mschapv2.h"
#ifdef _MSC_VER
@@ -209,10 +209,15 @@ static struct wpabuf * eap_mschapv2_challenge_reply(
"in Phase 1");
auth_challenge = data->auth_challenge;
}
- mschapv2_derive_response(identity, identity_len, password,
- password_len, pwhash, auth_challenge,
- peer_challenge, r->nt_response,
- data->auth_response, data->master_key);
+ if (mschapv2_derive_response(identity, identity_len, password,
+ password_len, pwhash, auth_challenge,
+ peer_challenge, r->nt_response,
+ data->auth_response, data->master_key)) {
+ wpa_printf(MSG_ERROR, "EAP-MSCHAPV2: Failed to derive "
+ "response");
+ wpabuf_free(resp);
+ return NULL;
+ }
data->auth_response_valid = 1;
data->master_key_valid = 1;
diff --git a/src/eap_peer/eap_pax.c b/src/eap_peer/eap_pax.c
index afd56dd..2e04831 100644
--- a/src/eap_peer/eap_pax.c
+++ b/src/eap_peer/eap_pax.c
@@ -15,10 +15,8 @@
#include "includes.h"
#include "common.h"
-#include "eap_peer/eap_i.h"
#include "eap_common/eap_pax_common.h"
-#include "sha1.h"
-#include "crypto.h"
+#include "eap_i.h"
/*
* Note: only PAX_STD subprotocol is currently supported
diff --git a/src/eap_peer/eap_peap.c b/src/eap_peer/eap_peap.c
index 894fc63..2b72084 100644
--- a/src/eap_peer/eap_peap.c
+++ b/src/eap_peer/eap_peap.c
@@ -16,12 +16,12 @@
#include "common.h"
#include "crypto/sha1.h"
+#include "crypto/tls.h"
+#include "eap_common/eap_tlv_common.h"
+#include "eap_common/eap_peap_common.h"
#include "eap_i.h"
#include "eap_tls_common.h"
#include "eap_config.h"
-#include "tls.h"
-#include "eap_common/eap_tlv_common.h"
-#include "eap_common/eap_peap_common.h"
#include "tncc.h"
@@ -1048,10 +1048,10 @@ static struct wpabuf * eap_peap_process(struct eap_sm *sm, void *priv,
if (flags & EAP_TLS_FLAGS_START) {
wpa_printf(MSG_DEBUG, "EAP-PEAP: Start (server ver=%d, own "
- "ver=%d)", flags & EAP_PEAP_VERSION_MASK,
+ "ver=%d)", flags & EAP_TLS_VERSION_MASK,
data->peap_version);
- if ((flags & EAP_PEAP_VERSION_MASK) < data->peap_version)
- data->peap_version = flags & EAP_PEAP_VERSION_MASK;
+ if ((flags & EAP_TLS_VERSION_MASK) < data->peap_version)
+ data->peap_version = flags & EAP_TLS_VERSION_MASK;
if (data->force_peap_version >= 0 &&
data->force_peap_version != data->peap_version) {
wpa_printf(MSG_WARNING, "EAP-PEAP: Failed to select "
diff --git a/src/eap_peer/eap_psk.c b/src/eap_peer/eap_psk.c
index 1ce63566..ccf871e 100644
--- a/src/eap_peer/eap_psk.c
+++ b/src/eap_peer/eap_psk.c
@@ -18,9 +18,9 @@
#include "includes.h"
#include "common.h"
-#include "eap_peer/eap_i.h"
-#include "aes_wrap.h"
+#include "crypto/aes_wrap.h"
#include "eap_common/eap_psk_common.h"
+#include "eap_i.h"
struct eap_psk_data {
diff --git a/src/eap_peer/eap_sim.c b/src/eap_peer/eap_sim.c
index 5e30d1f..3d8afb2 100644
--- a/src/eap_peer/eap_sim.c
+++ b/src/eap_peer/eap_sim.c
@@ -15,13 +15,11 @@
#include "includes.h"
#include "common.h"
+#include "pcsc_funcs.h"
+#include "crypto/milenage.h"
#include "eap_peer/eap_i.h"
#include "eap_config.h"
-#include "pcsc_funcs.h"
#include "eap_common/eap_sim_common.h"
-#ifdef CONFIG_SIM_SIMULATOR
-#include "hlr_auc_gw/milenage.h"
-#endif /* CONFIG_SIM_SIMULATOR */
struct eap_sim_data {
diff --git a/src/eap_peer/eap_tls.c b/src/eap_peer/eap_tls.c
index 31344a9..20b2212 100644
--- a/src/eap_peer/eap_tls.c
+++ b/src/eap_peer/eap_tls.c
@@ -15,10 +15,10 @@
#include "includes.h"
#include "common.h"
+#include "crypto/tls.h"
#include "eap_i.h"
#include "eap_tls_common.h"
#include "eap_config.h"
-#include "tls.h"
static void eap_tls_deinit(struct eap_sm *sm, void *priv);
diff --git a/src/eap_peer/eap_tls_common.c b/src/eap_peer/eap_tls_common.c
index 186feaa..7bd50f6 100644
--- a/src/eap_peer/eap_tls_common.c
+++ b/src/eap_peer/eap_tls_common.c
@@ -1,6 +1,6 @@
/*
* EAP peer: EAP-TLS/PEAP/TTLS/FAST common functions
- * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -15,11 +15,11 @@
#include "includes.h"
#include "common.h"
+#include "crypto/sha1.h"
+#include "crypto/tls.h"
#include "eap_i.h"
#include "eap_tls_common.h"
#include "eap_config.h"
-#include "sha1.h"
-#include "tls.h"
static int eap_tls_check_blob(struct eap_sm *sm, const char **name,
@@ -169,10 +169,14 @@ static int eap_tls_init_connection(struct eap_sm *sm,
config->pin = NULL;
eap_sm_request_pin(sm);
sm->ignore = TRUE;
+ tls_connection_deinit(sm->ssl_ctx, data->conn);
+ data->conn = NULL;
return -1;
} else if (res) {
wpa_printf(MSG_INFO, "TLS: Failed to set TLS connection "
"parameters");
+ tls_connection_deinit(sm->ssl_ctx, data->conn);
+ data->conn = NULL;
return -1;
}
@@ -310,27 +314,29 @@ fail:
* eap_peer_tls_reassemble_fragment - Reassemble a received fragment
* @data: Data for TLS processing
* @in_data: Next incoming TLS segment
- * @in_len: Length of in_data
* Returns: 0 on success, 1 if more data is needed for the full message, or
* -1 on error
*/
static int eap_peer_tls_reassemble_fragment(struct eap_ssl_data *data,
- const u8 *in_data, size_t in_len)
+ const struct wpabuf *in_data)
{
- u8 *buf;
+ size_t tls_in_len, in_len;
+
+ tls_in_len = data->tls_in ? wpabuf_len(data->tls_in) : 0;
+ in_len = in_data ? wpabuf_len(in_data) : 0;
- if (data->tls_in_len + in_len == 0) {
+ if (tls_in_len + in_len == 0) {
/* No message data received?! */
wpa_printf(MSG_WARNING, "SSL: Invalid reassembly state: "
"tls_in_left=%lu tls_in_len=%lu in_len=%lu",
(unsigned long) data->tls_in_left,
- (unsigned long) data->tls_in_len,
+ (unsigned long) tls_in_len,
(unsigned long) in_len);
eap_peer_tls_reset_input(data);
return -1;
}
- if (data->tls_in_len + in_len > 65536) {
+ if (tls_in_len + in_len > 65536) {
/*
* Limit length to avoid rogue servers from causing large
* memory allocations.
@@ -349,16 +355,13 @@ static int eap_peer_tls_reassemble_fragment(struct eap_ssl_data *data,
return -1;
}
- buf = os_realloc(data->tls_in, data->tls_in_len + in_len);
- if (buf == NULL) {
+ if (wpabuf_resize(&data->tls_in, in_len) < 0) {
wpa_printf(MSG_INFO, "SSL: Could not allocate memory for TLS "
"data");
eap_peer_tls_reset_input(data);
return -1;
}
- os_memcpy(buf + data->tls_in_len, in_data, in_len);
- data->tls_in = buf;
- data->tls_in_len += in_len;
+ wpabuf_put_buf(data->tls_in, in_data);
data->tls_in_left -= in_len;
if (data->tls_in_left > 0) {
@@ -375,8 +378,6 @@ static int eap_peer_tls_reassemble_fragment(struct eap_ssl_data *data,
* eap_peer_tls_data_reassemble - Reassemble TLS data
* @data: Data for TLS processing
* @in_data: Next incoming TLS segment
- * @in_len: Length of in_data
- * @out_len: Variable for returning length of the reassembled message
* @need_more_input: Variable for returning whether more input data is needed
* to reassemble this TLS packet
* Returns: Pointer to output data, %NULL on error or when more data is needed
@@ -385,16 +386,15 @@ static int eap_peer_tls_reassemble_fragment(struct eap_ssl_data *data,
* This function reassembles TLS fragments. Caller must not free the returned
* data buffer since an internal pointer to it is maintained.
*/
-const u8 * eap_peer_tls_data_reassemble(
- struct eap_ssl_data *data, const u8 *in_data, size_t in_len,
- size_t *out_len, int *need_more_input)
+static const struct wpabuf * eap_peer_tls_data_reassemble(
+ struct eap_ssl_data *data, const struct wpabuf *in_data,
+ int *need_more_input)
{
*need_more_input = 0;
- if (data->tls_in_left > in_len || data->tls_in) {
+ if (data->tls_in_left > wpabuf_len(in_data) || data->tls_in) {
/* Message has fragments */
- int res = eap_peer_tls_reassemble_fragment(data, in_data,
- in_len);
+ int res = eap_peer_tls_reassemble_fragment(data, in_data);
if (res) {
if (res == 1)
*need_more_input = 1;
@@ -405,14 +405,11 @@ const u8 * eap_peer_tls_data_reassemble(
} else {
/* No fragments in this message, so just make a copy of it. */
data->tls_in_left = 0;
- data->tls_in = os_malloc(in_len ? in_len : 1);
+ data->tls_in = wpabuf_dup(in_data);
if (data->tls_in == NULL)
return NULL;
- os_memcpy(data->tls_in, in_data, in_len);
- data->tls_in_len = in_len;
}
- *out_len = data->tls_in_len;
return data->tls_in;
}
@@ -431,14 +428,13 @@ static int eap_tls_process_input(struct eap_sm *sm, struct eap_ssl_data *data,
const u8 *in_data, size_t in_len,
struct wpabuf **out_data)
{
- const u8 *msg;
- size_t msg_len;
+ const struct wpabuf *msg;
int need_more_input;
- u8 *appl_data;
- size_t appl_data_len;
+ struct wpabuf *appl_data;
+ struct wpabuf buf;
- msg = eap_peer_tls_data_reassemble(data, in_data, in_len,
- &msg_len, &need_more_input);
+ wpabuf_set(&buf, in_data, in_len);
+ msg = eap_peer_tls_data_reassemble(data, &buf, &need_more_input);
if (msg == NULL)
return need_more_input ? 1 : -1;
@@ -447,31 +443,25 @@ static int eap_tls_process_input(struct eap_sm *sm, struct eap_ssl_data *data,
/* This should not happen.. */
wpa_printf(MSG_INFO, "SSL: eap_tls_process_input - pending "
"tls_out data even though tls_out_len = 0");
- os_free(data->tls_out);
+ wpabuf_free(data->tls_out);
WPA_ASSERT(data->tls_out == NULL);
}
appl_data = NULL;
data->tls_out = tls_connection_handshake(sm->ssl_ctx, data->conn,
- msg, msg_len,
- &data->tls_out_len,
- &appl_data, &appl_data_len);
+ msg, &appl_data);
eap_peer_tls_reset_input(data);
if (appl_data &&
tls_connection_established(sm->ssl_ctx, data->conn) &&
!tls_connection_get_failed(sm->ssl_ctx, data->conn)) {
- wpa_hexdump_key(MSG_MSGDUMP, "SSL: Application data",
- appl_data, appl_data_len);
- *out_data = wpabuf_alloc_ext_data(appl_data, appl_data_len);
- if (*out_data == NULL) {
- os_free(appl_data);
- return -1;
- }
+ wpa_hexdump_buf_key(MSG_MSGDUMP, "SSL: Application data",
+ appl_data);
+ *out_data = appl_data;
return 2;
}
- os_free(appl_data);
+ wpabuf_free(appl_data);
return 0;
}
@@ -494,11 +484,14 @@ static int eap_tls_process_output(struct eap_ssl_data *data, EapType eap_type,
size_t len;
u8 *flags;
int more_fragments, length_included;
-
- len = data->tls_out_len - data->tls_out_pos;
+
+ if (data->tls_out == NULL)
+ return -1;
+ len = wpabuf_len(data->tls_out) - data->tls_out_pos;
wpa_printf(MSG_DEBUG, "SSL: %lu bytes left to be sent out (of total "
"%lu bytes)",
- (unsigned long) len, (unsigned long) data->tls_out_len);
+ (unsigned long) len,
+ (unsigned long) wpabuf_len(data->tls_out));
/*
* Limit outgoing message to the configured maximum size. Fragment
@@ -513,7 +506,7 @@ static int eap_tls_process_output(struct eap_ssl_data *data, EapType eap_type,
more_fragments = 0;
length_included = data->tls_out_pos == 0 &&
- (data->tls_out_len > data->tls_out_limit ||
+ (wpabuf_len(data->tls_out) > data->tls_out_limit ||
data->include_tls_length);
if (!length_included &&
eap_type == EAP_TYPE_PEAP && peap_version == 0 &&
@@ -539,10 +532,12 @@ static int eap_tls_process_output(struct eap_ssl_data *data, EapType eap_type,
*flags |= EAP_TLS_FLAGS_MORE_FRAGMENTS;
if (length_included) {
*flags |= EAP_TLS_FLAGS_LENGTH_INCLUDED;
- wpabuf_put_be32(*out_data, data->tls_out_len);
+ wpabuf_put_be32(*out_data, wpabuf_len(data->tls_out));
}
- wpabuf_put_data(*out_data, &data->tls_out[data->tls_out_pos], len);
+ wpabuf_put_data(*out_data,
+ wpabuf_head_u8(data->tls_out) + data->tls_out_pos,
+ len);
data->tls_out_pos += len;
if (!more_fragments)
@@ -590,13 +585,13 @@ int eap_peer_tls_process_helper(struct eap_sm *sm, struct eap_ssl_data *data,
*out_data = NULL;
- if (data->tls_out_len > 0 && in_len > 0) {
+ if (data->tls_out && wpabuf_len(data->tls_out) > 0 && in_len > 0) {
wpa_printf(MSG_DEBUG, "SSL: Received non-ACK when output "
"fragments are waiting to be sent out");
return -1;
}
- if (data->tls_out_len == 0) {
+ if (data->tls_out == NULL || wpabuf_len(data->tls_out) == 0) {
/*
* No more data to send out - expect to receive more data from
* the AS.
@@ -635,14 +630,14 @@ int eap_peer_tls_process_helper(struct eap_sm *sm, struct eap_ssl_data *data,
/* TODO: clean pin if engine used? */
}
- if (data->tls_out_len == 0) {
+ if (data->tls_out == NULL || 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
* the TLS Message Length field.
*/
wpa_printf(MSG_DEBUG, "SSL: No data to be sent out");
- os_free(data->tls_out);
+ wpabuf_free(data->tls_out);
data->tls_out = NULL;
return 1;
}
@@ -794,9 +789,8 @@ const u8 * eap_peer_tls_process_init(struct eap_sm *sm,
if (data->tls_in_left == 0) {
data->tls_in_total = tls_msg_len;
data->tls_in_left = tls_msg_len;
- os_free(data->tls_in);
+ wpabuf_free(data->tls_in);
data->tls_in = NULL;
- data->tls_in_len = 0;
}
pos += 4;
left -= 4;
@@ -821,8 +815,8 @@ const u8 * eap_peer_tls_process_init(struct eap_sm *sm,
*/
void eap_peer_tls_reset_input(struct eap_ssl_data *data)
{
- data->tls_in_left = data->tls_in_total = data->tls_in_len = 0;
- os_free(data->tls_in);
+ data->tls_in_left = data->tls_in_total = 0;
+ wpabuf_free(data->tls_in);
data->tls_in = NULL;
}
@@ -836,9 +830,8 @@ void eap_peer_tls_reset_input(struct eap_ssl_data *data)
*/
void eap_peer_tls_reset_output(struct eap_ssl_data *data)
{
- data->tls_out_len = 0;
data->tls_out_pos = 0;
- os_free(data->tls_out);
+ wpabuf_free(data->tls_out);
data->tls_out = NULL;
}
@@ -855,44 +848,19 @@ int eap_peer_tls_decrypt(struct eap_sm *sm, struct eap_ssl_data *data,
const struct wpabuf *in_data,
struct wpabuf **in_decrypted)
{
- int res;
- const u8 *msg;
- size_t msg_len, buf_len;
+ const struct wpabuf *msg;
int need_more_input;
- msg = eap_peer_tls_data_reassemble(data, wpabuf_head(in_data),
- wpabuf_len(in_data), &msg_len,
- &need_more_input);
+ msg = eap_peer_tls_data_reassemble(data, in_data, &need_more_input);
if (msg == NULL)
return need_more_input ? 1 : -1;
- buf_len = wpabuf_len(in_data);
- if (data->tls_in_total > buf_len)
- buf_len = data->tls_in_total;
- /*
- * Even though we try to disable TLS compression, it is possible that
- * this cannot be done with all TLS libraries. Add extra buffer space
- * to handle the possibility of the decrypted data being longer than
- * input data.
- */
- buf_len += 500;
- buf_len *= 3;
- *in_decrypted = wpabuf_alloc(buf_len ? buf_len : 1);
- if (*in_decrypted == NULL) {
- eap_peer_tls_reset_input(data);
- wpa_printf(MSG_WARNING, "SSL: Failed to allocate memory for "
- "decryption");
- return -1;
- }
-
- res = tls_connection_decrypt(sm->ssl_ctx, data->conn, msg, msg_len,
- wpabuf_mhead(*in_decrypted), buf_len);
+ *in_decrypted = tls_connection_decrypt(sm->ssl_ctx, data->conn, msg);
eap_peer_tls_reset_input(data);
- if (res < 0) {
+ if (*in_decrypted == NULL) {
wpa_printf(MSG_INFO, "SSL: Failed to decrypt Phase 2 data");
return -1;
}
- wpabuf_put(*in_decrypted, res);
return 0;
}
@@ -913,29 +881,17 @@ int eap_peer_tls_encrypt(struct eap_sm *sm, struct eap_ssl_data *data,
const struct wpabuf *in_data,
struct wpabuf **out_data)
{
- int res;
- size_t len;
-
if (in_data) {
eap_peer_tls_reset_output(data);
- len = wpabuf_len(in_data) + 300;
- data->tls_out = os_malloc(len);
- if (data->tls_out == NULL)
- return -1;
-
- res = tls_connection_encrypt(sm->ssl_ctx, data->conn,
- wpabuf_head(in_data),
- wpabuf_len(in_data),
- data->tls_out, len);
- if (res < 0) {
+ data->tls_out = tls_connection_encrypt(sm->ssl_ctx, data->conn,
+ in_data);
+ if (data->tls_out == NULL) {
wpa_printf(MSG_INFO, "SSL: Failed to encrypt Phase 2 "
"data (in_len=%lu)",
(unsigned long) wpabuf_len(in_data));
eap_peer_tls_reset_output(data);
return -1;
}
-
- data->tls_out_len = res;
}
return eap_tls_process_output(data, eap_type, peap_version, id, 0,
diff --git a/src/eap_peer/eap_tls_common.h b/src/eap_peer/eap_tls_common.h
index 2c87427..e9e0998 100644
--- a/src/eap_peer/eap_tls_common.h
+++ b/src/eap_peer/eap_tls_common.h
@@ -1,6 +1,6 @@
/*
* EAP peer: EAP-TLS/PEAP/TTLS/FAST common functions
- * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -27,12 +27,7 @@ struct eap_ssl_data {
/**
* tls_out - TLS message to be sent out in fragments
*/
- u8 *tls_out;
-
- /**
- * tls_out_len - Total length of the outgoing TLS message
- */
- size_t tls_out_len;
+ struct wpabuf *tls_out;
/**
* tls_out_pos - The current position in the outgoing TLS message
@@ -47,12 +42,7 @@ struct eap_ssl_data {
/**
* tls_in - Received TLS message buffer for re-assembly
*/
- u8 *tls_in;
-
- /**
- * tls_in_len - Number of bytes of the received TLS message in tls_in
- */
- size_t tls_in_len;
+ struct wpabuf *tls_in;
/**
* tls_in_left - Number of remaining bytes in the incoming TLS message
@@ -81,7 +71,7 @@ struct eap_ssl_data {
int tls_ia;
/**
- * eap - Pointer to EAP state machine allocated with eap_peer_sm_init()
+ * eap - EAP state machine allocated with eap_peer_sm_init()
*/
struct eap_sm *eap;
};
@@ -91,7 +81,7 @@ struct eap_ssl_data {
#define EAP_TLS_FLAGS_LENGTH_INCLUDED 0x80
#define EAP_TLS_FLAGS_MORE_FRAGMENTS 0x40
#define EAP_TLS_FLAGS_START 0x20
-#define EAP_PEAP_VERSION_MASK 0x07
+#define EAP_TLS_VERSION_MASK 0x07
/* could be up to 128 bytes, but only the first 64 bytes are used */
#define EAP_TLS_KEY_LEN 64
@@ -102,9 +92,6 @@ int eap_peer_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data,
void eap_peer_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data);
u8 * eap_peer_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data,
const char *label, size_t len);
-const u8 * eap_peer_tls_data_reassemble(
- struct eap_ssl_data *data, const u8 *in_data, size_t in_len,
- size_t *out_len, int *need_more_input);
int eap_peer_tls_process_helper(struct eap_sm *sm, struct eap_ssl_data *data,
EapType eap_type, int peap_version,
u8 id, const u8 *in_data, size_t in_len,
diff --git a/src/eap_peer/eap_tnc.c b/src/eap_peer/eap_tnc.c
index c560015..6c95f72 100644
--- a/src/eap_peer/eap_tnc.c
+++ b/src/eap_peer/eap_tnc.c
@@ -73,12 +73,13 @@ static struct wpabuf * eap_tnc_build_frag_ack(u8 id, u8 code)
{
struct wpabuf *msg;
- msg = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TNC, 0, code, id);
+ msg = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TNC, 1, code, id);
if (msg == NULL) {
wpa_printf(MSG_ERROR, "EAP-TNC: Failed to allocate memory "
"for fragment ack");
return NULL;
}
+ wpabuf_put_u8(msg, EAP_TNC_VERSION); /* Flags */
wpa_printf(MSG_DEBUG, "EAP-TNC: Send fragment ack");
@@ -262,7 +263,7 @@ static struct wpabuf * eap_tnc_process(struct eap_sm *sm, void *priv,
"Message Length %u", flags, message_length);
if (data->state == WAIT_FRAG_ACK) {
- if (len != 0) {
+ if (len > 1) {
wpa_printf(MSG_DEBUG, "EAP-TNC: Unexpected payload in "
"WAIT_FRAG_ACK state");
ret->ignore = TRUE;
diff --git a/src/eap_peer/eap_ttls.c b/src/eap_peer/eap_ttls.c
index 0851f8b..2573780 100644
--- a/src/eap_peer/eap_ttls.c
+++ b/src/eap_peer/eap_ttls.c
@@ -15,15 +15,15 @@
#include "includes.h"
#include "common.h"
-#include "eap_peer/eap_i.h"
-#include "eap_peer/eap_tls_common.h"
-#include "eap_peer/eap_config.h"
-#include "ms_funcs.h"
-#include "sha1.h"
+#include "crypto/ms_funcs.h"
+#include "crypto/sha1.h"
+#include "crypto/tls.h"
#include "eap_common/chap.h"
-#include "tls.h"
-#include "mschapv2.h"
#include "eap_common/eap_ttls.h"
+#include "mschapv2.h"
+#include "eap_i.h"
+#include "eap_tls_common.h"
+#include "eap_config.h"
/* Maximum supported TTLS version
@@ -691,10 +691,15 @@ static int eap_ttls_phase2_request_mschapv2(struct eap_sm *sm,
pos += EAP_TTLS_MSCHAPV2_CHALLENGE_LEN;
os_memset(pos, 0, 8); /* Reserved, must be zero */
pos += 8;
- mschapv2_derive_response(identity, identity_len, password,
- password_len, pwhash, challenge,
- peer_challenge, pos, data->auth_response,
- data->master_key);
+ if (mschapv2_derive_response(identity, identity_len, password,
+ password_len, pwhash, challenge,
+ peer_challenge, pos, data->auth_response,
+ data->master_key)) {
+ wpabuf_free(msg);
+ wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAPV2: Failed to derive "
+ "response");
+ return -1;
+ }
data->auth_response_valid = 1;
eap_ttlsv1_permute_inner(sm, data);
@@ -1026,27 +1031,25 @@ static int eap_ttls_phase2_request(struct eap_sm *sm,
static struct wpabuf * eap_ttls_build_phase_finished(
struct eap_sm *sm, struct eap_ttls_data *data, int id, int final)
{
- int len;
- struct wpabuf *req;
- u8 *pos;
- const int max_len = 300;
+ struct wpabuf *req, *buf;
- req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TTLS, 1 + max_len,
- EAP_CODE_RESPONSE, id);
- if (req == NULL)
+ buf = tls_connection_ia_send_phase_finished(sm->ssl_ctx,
+ data->ssl.conn,
+ final);
+ if (buf == NULL)
return NULL;
- wpabuf_put_u8(req, data->ttls_version);
-
- pos = wpabuf_put(req, 0);
- len = tls_connection_ia_send_phase_finished(sm->ssl_ctx,
- data->ssl.conn,
- final, pos, max_len);
- if (len < 0) {
- wpabuf_free(req);
+ req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TTLS,
+ 1 + wpabuf_len(buf),
+ EAP_CODE_RESPONSE, id);
+ if (req == NULL) {
+ wpabuf_free(buf);
return NULL;
}
- wpabuf_put(req, len);
+
+ wpabuf_put_u8(req, data->ttls_version);
+ wpabuf_put_buf(req, buf);
+ wpabuf_free(buf);
eap_update_len(req);
return req;
@@ -1666,10 +1669,10 @@ static int eap_ttls_process_start(struct eap_sm *sm,
struct eap_peer_config *config = eap_get_config(sm);
wpa_printf(MSG_DEBUG, "EAP-TTLS: Start (server ver=%d, own ver=%d)",
- flags & EAP_PEAP_VERSION_MASK, data->ttls_version);
+ flags & EAP_TLS_VERSION_MASK, data->ttls_version);
#if EAP_TTLS_VERSION > 0
- if ((flags & EAP_PEAP_VERSION_MASK) < data->ttls_version)
- data->ttls_version = flags & EAP_PEAP_VERSION_MASK;
+ if ((flags & EAP_TLS_VERSION_MASK) < data->ttls_version)
+ data->ttls_version = flags & EAP_TLS_VERSION_MASK;
if (data->force_ttls_version >= 0 &&
data->force_ttls_version != data->ttls_version) {
wpa_printf(MSG_WARNING, "EAP-TTLS: Failed to select "
diff --git a/src/eap_peer/eap_wsc.c b/src/eap_peer/eap_wsc.c
index 7c8ad2f..8317f72 100644
--- a/src/eap_peer/eap_wsc.c
+++ b/src/eap_peer/eap_wsc.c
@@ -1,6 +1,6 @@
/*
* EAP-WSC peer for Wi-Fi Protected Setup
- * Copyright (c) 2007-2008, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2007-2009, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -65,6 +65,72 @@ static void eap_wsc_state(struct eap_wsc_data *data, int state)
}
+static int eap_wsc_new_ap_settings(struct wps_credential *cred,
+ const char *params)
+{
+ const char *pos, *end;
+ size_t len;
+
+ os_memset(cred, 0, sizeof(*cred));
+
+ pos = os_strstr(params, "new_ssid=");
+ if (pos == NULL)
+ return 0;
+ pos += 9;
+ end = os_strchr(pos, ' ');
+ if (end == NULL)
+ len = os_strlen(pos);
+ else
+ len = end - pos;
+ if ((len & 1) || len > 2 * sizeof(cred->ssid) ||
+ hexstr2bin(pos, cred->ssid, len / 2))
+ return -1;
+ cred->ssid_len = len / 2;
+
+ pos = os_strstr(params, "new_auth=");
+ if (pos == NULL)
+ return -1;
+ if (os_strncmp(pos + 9, "OPEN", 4) == 0)
+ cred->auth_type = WPS_AUTH_OPEN;
+ else if (os_strncmp(pos + 9, "WPAPSK", 6) == 0)
+ cred->auth_type = WPS_AUTH_WPAPSK;
+ else if (os_strncmp(pos + 9, "WPA2PSK", 7) == 0)
+ cred->auth_type = WPS_AUTH_WPA2PSK;
+ else
+ return -1;
+
+ pos = os_strstr(params, "new_encr=");
+ if (pos == NULL)
+ return -1;
+ if (os_strncmp(pos + 9, "NONE", 4) == 0)
+ cred->encr_type = WPS_ENCR_NONE;
+ else if (os_strncmp(pos + 9, "WEP", 3) == 0)
+ cred->encr_type = WPS_ENCR_WEP;
+ else if (os_strncmp(pos + 9, "TKIP", 4) == 0)
+ cred->encr_type = WPS_ENCR_TKIP;
+ else if (os_strncmp(pos + 9, "CCMP", 4) == 0)
+ cred->encr_type = WPS_ENCR_AES;
+ else
+ return -1;
+
+ pos = os_strstr(params, "new_key=");
+ if (pos == NULL)
+ return 0;
+ pos += 8;
+ end = os_strchr(pos, ' ');
+ if (end == NULL)
+ len = os_strlen(pos);
+ else
+ len = end - pos;
+ if ((len & 1) || len > 2 * sizeof(cred->key) ||
+ hexstr2bin(pos, cred->key, len / 2))
+ return -1;
+ cred->key_len = len / 2;
+
+ return 1;
+}
+
+
static void * eap_wsc_init(struct eap_sm *sm)
{
struct eap_wsc_data *data;
@@ -75,6 +141,8 @@ static void * eap_wsc_init(struct eap_sm *sm)
const char *pos;
const char *phase1;
struct wps_context *wps;
+ struct wps_credential new_ap_settings;
+ int res;
wps = sm->wps;
if (wps == NULL) {
@@ -135,6 +203,17 @@ static void * eap_wsc_init(struct eap_sm *sm)
return NULL;
}
+ res = eap_wsc_new_ap_settings(&new_ap_settings, phase1);
+ if (res < 0) {
+ os_free(data);
+ return NULL;
+ }
+ if (res == 1) {
+ wpa_printf(MSG_DEBUG, "EAP-WSC: Provide new AP settings for "
+ "WPS");
+ cfg.new_ap_settings = &new_ap_settings;
+ }
+
data->wps = wps_init(&cfg);
if (data->wps == NULL) {
os_free(data);
@@ -147,6 +226,10 @@ static void * eap_wsc_init(struct eap_sm *sm)
cfg.pin, cfg.pin_len, 0);
}
+ /* Use reduced client timeout for WPS to avoid long wait */
+ if (sm->ClientTimeout > 30)
+ sm->ClientTimeout = 30;
+
return data;
}
@@ -302,6 +385,7 @@ static struct wpabuf * eap_wsc_process(struct eap_sm *sm, void *priv,
u16 message_length = 0;
enum wps_process_res res;
struct wpabuf tmpbuf;
+ struct wpabuf *r;
pos = eap_hdr_validate(EAP_VENDOR_WFA, EAP_VENDOR_TYPE_WSC, reqData,
&len);
@@ -427,7 +511,13 @@ send_msg:
}
eap_wsc_state(data, MESG);
- return eap_wsc_build_msg(data, ret, id);
+ r = eap_wsc_build_msg(data, ret, id);
+ if (data->state == FAIL && ret->methodState == METHOD_DONE) {
+ /* Use reduced client timeout for WPS to avoid long wait */
+ if (sm->ClientTimeout > 2)
+ sm->ClientTimeout = 2;
+ }
+ return r;
}
diff --git a/src/eap_peer/ikev2.c b/src/eap_peer/ikev2.c
index 9172e1f..309a331 100644
--- a/src/eap_peer/ikev2.c
+++ b/src/eap_peer/ikev2.c
@@ -15,7 +15,7 @@
#include "includes.h"
#include "common.h"
-#include "dh_groups.h"
+#include "crypto/dh_groups.h"
#include "ikev2.h"
diff --git a/src/eap_peer/mschapv2.c b/src/eap_peer/mschapv2.c
index 01c22d8..b8fb075 100644
--- a/src/eap_peer/mschapv2.c
+++ b/src/eap_peer/mschapv2.c
@@ -15,7 +15,7 @@
#include "includes.h"
#include "common.h"
-#include "ms_funcs.h"
+#include "crypto/ms_funcs.h"
#include "mschapv2.h"
const u8 * mschapv2_remove_domain(const u8 *username, size_t *len)
@@ -39,13 +39,13 @@ const u8 * mschapv2_remove_domain(const u8 *username, size_t *len)
}
-void mschapv2_derive_response(const u8 *identity, size_t identity_len,
- const u8 *password, size_t password_len,
- int pwhash,
- const u8 *auth_challenge,
- const u8 *peer_challenge,
- u8 *nt_response, u8 *auth_response,
- u8 *master_key)
+int mschapv2_derive_response(const u8 *identity, size_t identity_len,
+ const u8 *password, size_t password_len,
+ int pwhash,
+ const u8 *auth_challenge,
+ const u8 *peer_challenge,
+ u8 *nt_response, u8 *auth_response,
+ u8 *master_key)
{
const u8 *username;
size_t username_len;
@@ -93,14 +93,18 @@ void mschapv2_derive_response(const u8 *identity, size_t identity_len,
/* Generate master_key here since we have the needed data available. */
if (pwhash) {
- hash_nt_password_hash(password, password_hash_hash);
+ if (hash_nt_password_hash(password, password_hash_hash))
+ return -1;
} else {
- nt_password_hash(password, password_len, password_hash);
- hash_nt_password_hash(password_hash, password_hash_hash);
+ if (nt_password_hash(password, password_len, password_hash) ||
+ hash_nt_password_hash(password_hash, password_hash_hash))
+ return -1;
}
get_master_key(password_hash_hash, nt_response, master_key);
wpa_hexdump_key(MSG_DEBUG, "MSCHAPV2: Master Key",
master_key, MSCHAPV2_MASTER_KEY_LEN);
+
+ return 0;
}
diff --git a/src/eap_peer/mschapv2.h b/src/eap_peer/mschapv2.h
index c7c36f7..90dad31 100644
--- a/src/eap_peer/mschapv2.h
+++ b/src/eap_peer/mschapv2.h
@@ -21,13 +21,13 @@
#define MSCHAPV2_MASTER_KEY_LEN 16
const u8 * mschapv2_remove_domain(const u8 *username, size_t *len);
-void mschapv2_derive_response(const u8 *username, size_t username_len,
- const u8 *password, size_t password_len,
- int pwhash,
- const u8 *auth_challenge,
- const u8 *peer_challenge,
- u8 *nt_response, u8 *auth_response,
- u8 *master_key);
+int mschapv2_derive_response(const u8 *username, size_t username_len,
+ const u8 *password, size_t password_len,
+ int pwhash,
+ const u8 *auth_challenge,
+ const u8 *peer_challenge,
+ u8 *nt_response, u8 *auth_response,
+ u8 *master_key);
int mschapv2_verify_auth_response(const u8 *auth_response,
const u8 *buf, size_t buf_len);
OpenPOWER on IntegriCloud