diff options
Diffstat (limited to 'src/eap_peer')
-rw-r--r-- | src/eap_peer/Makefile | 1 | ||||
-rw-r--r-- | src/eap_peer/eap.c | 77 | ||||
-rw-r--r-- | src/eap_peer/eap.h | 2 | ||||
-rw-r--r-- | src/eap_peer/eap_aka.c | 14 | ||||
-rw-r--r-- | src/eap_peer/eap_config.h | 9 | ||||
-rw-r--r-- | src/eap_peer/eap_fast.c | 12 | ||||
-rw-r--r-- | src/eap_peer/eap_fast_pac.c | 29 | ||||
-rw-r--r-- | src/eap_peer/eap_leap.c | 32 | ||||
-rw-r--r-- | src/eap_peer/eap_md5.c | 2 | ||||
-rw-r--r-- | src/eap_peer/eap_methods.c | 155 | ||||
-rw-r--r-- | src/eap_peer/eap_methods.h | 23 | ||||
-rw-r--r-- | src/eap_peer/eap_mschapv2.c | 19 | ||||
-rw-r--r-- | src/eap_peer/eap_pax.c | 4 | ||||
-rw-r--r-- | src/eap_peer/eap_peap.c | 12 | ||||
-rw-r--r-- | src/eap_peer/eap_psk.c | 4 | ||||
-rw-r--r-- | src/eap_peer/eap_sim.c | 6 | ||||
-rw-r--r-- | src/eap_peer/eap_tls.c | 2 | ||||
-rw-r--r-- | src/eap_peer/eap_tls_common.c | 164 | ||||
-rw-r--r-- | src/eap_peer/eap_tls_common.h | 23 | ||||
-rw-r--r-- | src/eap_peer/eap_tnc.c | 5 | ||||
-rw-r--r-- | src/eap_peer/eap_ttls.c | 63 | ||||
-rw-r--r-- | src/eap_peer/eap_wsc.c | 94 | ||||
-rw-r--r-- | src/eap_peer/ikev2.c | 2 | ||||
-rw-r--r-- | src/eap_peer/mschapv2.c | 26 | ||||
-rw-r--r-- | src/eap_peer/mschapv2.h | 14 |
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); |