Update to new version 0.8.16 from BRCM
Sync with main tree commit b8349523e460493fa0b4de36c689595109e45e91
Author: Neeraj Kumar Garg <neerajkg@broadcom.com>
Date: Tue Dec 27 23:21:45 2011 +0200
P2P: Reject p2p_group_add if forced frequency is not acceptable
Change-Id: Icb4541a371b05c270e80440d7a7fdea7f33ff61e
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/eap_peer/eap.c b/src/eap_peer/eap.c
index ecfaf30..91fa4a9 100644
--- a/src/eap_peer/eap.c
+++ b/src/eap_peer/eap.c
@@ -147,6 +147,7 @@
sm->methodState = METHOD_NONE;
sm->allowNotifications = TRUE;
sm->decision = DECISION_FAIL;
+ sm->ClientTimeout = EAP_CLIENT_TIMEOUT_DEFAULT;
eapol_set_int(sm, EAPOL_idleWhile, sm->ClientTimeout);
eapol_set_bool(sm, EAPOL_eapSuccess, FALSE);
eapol_set_bool(sm, EAPOL_eapFail, FALSE);
@@ -1242,6 +1243,7 @@
#endif /* CONFIG_FIPS */
tlsconf.event_cb = eap_peer_sm_tls_event;
tlsconf.cb_ctx = sm;
+ tlsconf.cert_in_cb = conf->cert_in_cb;
sm->ssl_ctx = tls_init(&tlsconf);
if (sm->ssl_ctx == NULL) {
wpa_printf(MSG_WARNING, "SSL: Failed to initialize TLS "
@@ -1466,16 +1468,11 @@
#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
-typedef enum {
- TYPE_IDENTITY, TYPE_PASSWORD, TYPE_OTP, TYPE_PIN, TYPE_NEW_PASSWORD,
- TYPE_PASSPHRASE
-} eap_ctrl_req_type;
-
-static void eap_sm_request(struct eap_sm *sm, eap_ctrl_req_type type,
+static void eap_sm_request(struct eap_sm *sm, enum wpa_ctrl_req_type field,
const char *msg, size_t msglen)
{
struct eap_peer_config *config;
- char *field, *txt, *tmp;
+ char *txt = NULL, *tmp;
if (sm == NULL)
return;
@@ -1483,29 +1480,20 @@
if (config == NULL)
return;
- switch (type) {
- case TYPE_IDENTITY:
- field = "IDENTITY";
- txt = "Identity";
+ switch (field) {
+ case WPA_CTRL_REQ_EAP_IDENTITY:
config->pending_req_identity++;
break;
- case TYPE_PASSWORD:
- field = "PASSWORD";
- txt = "Password";
+ case WPA_CTRL_REQ_EAP_PASSWORD:
config->pending_req_password++;
break;
- case TYPE_NEW_PASSWORD:
- field = "NEW_PASSWORD";
- txt = "New Password";
+ case WPA_CTRL_REQ_EAP_NEW_PASSWORD:
config->pending_req_new_password++;
break;
- case TYPE_PIN:
- field = "PIN";
- txt = "PIN";
+ case WPA_CTRL_REQ_EAP_PIN:
config->pending_req_pin++;
break;
- case TYPE_OTP:
- field = "OTP";
+ case WPA_CTRL_REQ_EAP_OTP:
if (msg) {
tmp = os_malloc(msglen + 3);
if (tmp == NULL)
@@ -1524,9 +1512,7 @@
txt = config->pending_req_otp;
}
break;
- case TYPE_PASSPHRASE:
- field = "PASSPHRASE";
- txt = "Private key passphrase";
+ case WPA_CTRL_REQ_EAP_PASSPHRASE:
config->pending_req_passphrase++;
break;
default:
@@ -1559,7 +1545,7 @@
*/
void eap_sm_request_identity(struct eap_sm *sm)
{
- eap_sm_request(sm, TYPE_IDENTITY, NULL, 0);
+ eap_sm_request(sm, WPA_CTRL_REQ_EAP_IDENTITY, NULL, 0);
}
@@ -1574,7 +1560,7 @@
*/
void eap_sm_request_password(struct eap_sm *sm)
{
- eap_sm_request(sm, TYPE_PASSWORD, NULL, 0);
+ eap_sm_request(sm, WPA_CTRL_REQ_EAP_PASSWORD, NULL, 0);
}
@@ -1589,7 +1575,7 @@
*/
void eap_sm_request_new_password(struct eap_sm *sm)
{
- eap_sm_request(sm, TYPE_NEW_PASSWORD, NULL, 0);
+ eap_sm_request(sm, WPA_CTRL_REQ_EAP_NEW_PASSWORD, NULL, 0);
}
@@ -1604,7 +1590,7 @@
*/
void eap_sm_request_pin(struct eap_sm *sm)
{
- eap_sm_request(sm, TYPE_PIN, NULL, 0);
+ eap_sm_request(sm, WPA_CTRL_REQ_EAP_PIN, NULL, 0);
}
@@ -1620,7 +1606,7 @@
*/
void eap_sm_request_otp(struct eap_sm *sm, const char *msg, size_t msg_len)
{
- eap_sm_request(sm, TYPE_OTP, msg, msg_len);
+ eap_sm_request(sm, WPA_CTRL_REQ_EAP_OTP, msg, msg_len);
}
@@ -1635,7 +1621,7 @@
*/
void eap_sm_request_passphrase(struct eap_sm *sm)
{
- eap_sm_request(sm, TYPE_PASSPHRASE, NULL, 0);
+ eap_sm_request(sm, WPA_CTRL_REQ_EAP_PASSPHRASE, NULL, 0);
}
diff --git a/src/eap_peer/eap.h b/src/eap_peer/eap.h
index 2a80d4e..f35197f 100644
--- a/src/eap_peer/eap.h
+++ b/src/eap_peer/eap.h
@@ -216,10 +216,10 @@
/**
* eap_param_needed - Notify that EAP parameter is needed
* @ctx: eapol_ctx from eap_peer_sm_init() call
- * @field: Field name (e.g., "IDENTITY")
+ * @field: Field indicator (e.g., WPA_CTRL_REQ_EAP_IDENTITY)
* @txt: User readable text describing the required parameter
*/
- void (*eap_param_needed)(void *ctx, const char *field,
+ void (*eap_param_needed)(void *ctx, enum wpa_ctrl_req_type field,
const char *txt);
/**
@@ -262,6 +262,11 @@
* This is only used by EAP-WSC and can be left %NULL if not available.
*/
struct wps_context *wps;
+
+ /**
+ * cert_in_cb - Include server certificates in callback
+ */
+ int cert_in_cb;
};
struct eap_sm * eap_peer_sm_init(void *eapol_ctx,
diff --git a/src/eap_peer/eap_aka.c b/src/eap_peer/eap_aka.c
index 182f01a..766764b 100644
--- a/src/eap_peer/eap_aka.c
+++ b/src/eap_peer/eap_aka.c
@@ -235,21 +235,20 @@
static void eap_aka_clear_identities(struct eap_aka_data *data, int id)
{
- wpa_printf(MSG_DEBUG, "EAP-AKA: forgetting old%s%s%s",
- id & CLEAR_PSEUDONYM ? " pseudonym" : "",
- id & CLEAR_REAUTH_ID ? " reauth_id" : "",
- id & CLEAR_EAP_ID ? " eap_id" : "");
if (id & CLEAR_PSEUDONYM) {
+ wpa_printf(MSG_DEBUG, "EAP-AKA: forgetting old pseudonym");
os_free(data->pseudonym);
data->pseudonym = NULL;
data->pseudonym_len = 0;
}
if (id & CLEAR_REAUTH_ID) {
+ wpa_printf(MSG_DEBUG, "EAP-AKA: forgetting old reauth_id");
os_free(data->reauth_id);
data->reauth_id = NULL;
data->reauth_id_len = 0;
}
if (id & CLEAR_EAP_ID) {
+ wpa_printf(MSG_DEBUG, "EAP-AKA: forgetting old eap_id");
os_free(data->last_eap_identity);
data->last_eap_identity = NULL;
data->last_eap_identity_len = 0;
@@ -880,11 +879,11 @@
EAP_AKA_UNABLE_TO_PROCESS_PACKET);
}
- /* Old reauthentication and pseudonym identities must not be used
- * anymore. In other words, if no new identities are received, full
- * authentication will be used on next reauthentication. */
- eap_aka_clear_identities(data, CLEAR_PSEUDONYM | CLEAR_REAUTH_ID |
- CLEAR_EAP_ID);
+ /* Old reauthentication identity must not be used anymore. In
+ * other words, if no new identities are received, full
+ * authentication will be used on next reauthentication (using
+ * pseudonym identity or permanent identity). */
+ eap_aka_clear_identities(data, CLEAR_REAUTH_ID | CLEAR_EAP_ID);
if (attr->encr_data) {
u8 *decrypted;
diff --git a/src/eap_peer/eap_fast.c b/src/eap_peer/eap_fast.c
index 5d3e69d..3cfb41a 100644
--- a/src/eap_peer/eap_fast.c
+++ b/src/eap_peer/eap_fast.c
@@ -444,8 +444,9 @@
return 0;
}
- if (data->phase2_priv == NULL &&
- eap_fast_init_phase2_method(sm, data) < 0) {
+ if ((data->phase2_priv == NULL &&
+ eap_fast_init_phase2_method(sm, data) < 0) ||
+ data->phase2_method == NULL) {
wpa_printf(MSG_INFO, "EAP-FAST: Failed to initialize "
"Phase 2 EAP method %d", *pos);
ret->methodState = METHOD_DONE;
@@ -542,7 +543,7 @@
static struct wpabuf * eap_fast_process_eap_payload_tlv(
struct eap_sm *sm, struct eap_fast_data *data,
- struct eap_method_ret *ret, const struct eap_hdr *req,
+ struct eap_method_ret *ret,
u8 *eap_payload_tlv, size_t eap_payload_tlv_len)
{
struct eap_hdr *hdr;
@@ -1037,11 +1038,15 @@
} else {
/*
* This is PAC refreshing, i.e., normal authentication that is
- * expected to be completed with an EAP-Success.
+ * expected to be completed with an EAP-Success. However,
+ * RFC 5422, Section 3.5 allows EAP-Failure to be sent even
+ * after protected success exchange in case of EAP-Fast
+ * provisioning, so we better use DECISION_COND_SUCC here
+ * instead of DECISION_UNCOND_SUCC.
*/
wpa_printf(MSG_DEBUG, "EAP-FAST: Send PAC-Acknowledgement TLV "
"- PAC refreshing completed successfully");
- ret->decision = DECISION_UNCOND_SUCC;
+ ret->decision = DECISION_COND_SUCC;
}
ret->methodState = METHOD_DONE;
return eap_fast_tlv_pac_ack();
@@ -1184,7 +1189,7 @@
if (tlv.eap_payload_tlv) {
tmp = eap_fast_process_eap_payload_tlv(
- sm, data, ret, req, tlv.eap_payload_tlv,
+ sm, data, ret, tlv.eap_payload_tlv,
tlv.eap_payload_tlv_len);
resp = wpabuf_concat(resp, tmp);
}
diff --git a/src/eap_peer/eap_methods.c b/src/eap_peer/eap_methods.c
index 3b0af05..937fd45 100644
--- a/src/eap_peer/eap_methods.c
+++ b/src/eap_peer/eap_methods.c
@@ -77,6 +77,8 @@
const char * eap_get_name(int vendor, EapType type)
{
struct eap_method *m;
+ if (vendor == EAP_VENDOR_IETF && type == EAP_TYPE_EXPANDED)
+ return "expanded";
for (m = eap_methods; m; m = m->next) {
if (m->vendor == vendor && m->method == type)
return m->name;
diff --git a/src/eap_peer/eap_peap.c b/src/eap_peer/eap_peap.c
index 2b72084..7cb8213 100644
--- a/src/eap_peer/eap_peap.c
+++ b/src/eap_peer/eap_peap.c
@@ -196,7 +196,7 @@
* @nak_type: TLV type (EAP_TLV_*)
* Returns: Buffer to the allocated EAP-TLV NAK message or %NULL on failure
*
- * This funtion builds an EAP-TLV NAK message. The caller is responsible for
+ * This function builds an EAP-TLV NAK message. The caller is responsible for
* freeing the returned buffer.
*/
static struct wpabuf * eap_tlv_build_nak(int id, u16 nak_type)
@@ -285,8 +285,10 @@
* in the end of the label just before ISK; is that just a typo?)
*/
wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: TempKey", tk, 40);
- peap_prfplus(data->peap_version, tk, 40, "Inner Methods Compound Keys",
- isk, sizeof(isk), imck, sizeof(imck));
+ if (peap_prfplus(data->peap_version, tk, 40,
+ "Inner Methods Compound Keys",
+ isk, sizeof(isk), imck, sizeof(imck)) < 0)
+ return -1;
wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: IMCK (IPMKj)",
imck, sizeof(imck));
@@ -346,8 +348,8 @@
* @status: Status (EAP_TLV_RESULT_SUCCESS or EAP_TLV_RESULT_FAILURE)
* Returns: Buffer to the allocated EAP-TLV Result message or %NULL on failure
*
- * This funtion builds an EAP-TLV Result message. The caller is responsible for
- * freeing the returned buffer.
+ * This function builds an EAP-TLV Result message. The caller is responsible
+ * for freeing the returned buffer.
*/
static struct wpabuf * eap_tlv_build_result(struct eap_sm *sm,
struct eap_peap_data *data,
@@ -1247,9 +1249,12 @@
* termination for this label while the one used for deriving
* IPMK|CMK did not use null termination.
*/
- peap_prfplus(data->peap_version, data->ipmk, 40,
- "Session Key Generating Function",
- (u8 *) "\00", 1, csk, sizeof(csk));
+ if (peap_prfplus(data->peap_version, data->ipmk, 40,
+ "Session Key Generating Function",
+ (u8 *) "\00", 1, csk, sizeof(csk)) < 0) {
+ os_free(key);
+ return NULL;
+ }
wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: CSK", csk, sizeof(csk));
os_memcpy(key, csk, EAP_TLS_KEY_LEN);
wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Derived key",
diff --git a/src/eap_peer/eap_pwd.c b/src/eap_peer/eap_pwd.c
index e4705b7..1957c82 100644
--- a/src/eap_peer/eap_pwd.c
+++ b/src/eap_peer/eap_pwd.c
@@ -423,8 +423,7 @@
BN_bn2bin(y, element + BN_num_bytes(data->grp->prime) + offset);
resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PWD,
- sizeof(struct eap_pwd_hdr) +
- BN_num_bytes(data->grp->order) +
+ 1 + BN_num_bytes(data->grp->order) +
(2 * BN_num_bytes(data->grp->prime)),
EAP_CODE_RESPONSE, eap_get_id(reqData));
if (resp == NULL)
@@ -465,6 +464,7 @@
u32 cs;
u16 grp;
u8 conf[SHA256_DIGEST_LENGTH], *cruft = NULL, *ptr;
+ int offset;
/*
* first build up the ciphersuite which is group | random_function |
@@ -497,7 +497,8 @@
* value may start with a few zeros and the previous one did not.
*/
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
- BN_bn2bin(data->k, cruft);
+ offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(data->k);
+ BN_bn2bin(data->k, cruft + offset);
H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
/* server element: x, y */
@@ -509,15 +510,19 @@
goto fin;
}
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
- BN_bn2bin(x, cruft);
+ offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(x);
+ BN_bn2bin(x, cruft + offset);
H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
- BN_bn2bin(y, cruft);
+ offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(y);
+ BN_bn2bin(y, cruft + offset);
H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
/* server scalar */
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
- BN_bn2bin(data->server_scalar, cruft);
+ offset = BN_num_bytes(data->grp->order) -
+ BN_num_bytes(data->server_scalar);
+ BN_bn2bin(data->server_scalar, cruft + offset);
H_Update(&ctx, cruft, BN_num_bytes(data->grp->order));
/* my element: x, y */
@@ -530,15 +535,19 @@
}
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
- BN_bn2bin(x, cruft);
+ offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(x);
+ BN_bn2bin(x, cruft + offset);
H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
- BN_bn2bin(y, cruft);
+ offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(y);
+ BN_bn2bin(y, cruft + offset);
H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
/* my scalar */
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
- BN_bn2bin(data->my_scalar, cruft);
+ offset = BN_num_bytes(data->grp->order) -
+ BN_num_bytes(data->my_scalar);
+ BN_bn2bin(data->my_scalar, cruft + offset);
H_Update(&ctx, cruft, BN_num_bytes(data->grp->order));
/* the ciphersuite */
@@ -564,7 +573,8 @@
/* k */
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
- BN_bn2bin(data->k, cruft);
+ offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(data->k);
+ BN_bn2bin(data->k, cruft + offset);
H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
/* my element */
@@ -576,15 +586,19 @@
goto fin;
}
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
- BN_bn2bin(x, cruft);
+ offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(x);
+ BN_bn2bin(x, cruft + offset);
H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
- BN_bn2bin(y, cruft);
+ offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(y);
+ BN_bn2bin(y, cruft + offset);
H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
/* my scalar */
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
- BN_bn2bin(data->my_scalar, cruft);
+ offset = BN_num_bytes(data->grp->order) -
+ BN_num_bytes(data->my_scalar);
+ BN_bn2bin(data->my_scalar, cruft + offset);
H_Update(&ctx, cruft, BN_num_bytes(data->grp->order));
/* server element: x, y */
@@ -596,15 +610,19 @@
goto fin;
}
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
- BN_bn2bin(x, cruft);
+ offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(x);
+ BN_bn2bin(x, cruft + offset);
H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
- BN_bn2bin(y, cruft);
+ offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(y);
+ BN_bn2bin(y, cruft + offset);
H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
/* server scalar */
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
- BN_bn2bin(data->server_scalar, cruft);
+ offset = BN_num_bytes(data->grp->order) -
+ BN_num_bytes(data->server_scalar);
+ BN_bn2bin(data->server_scalar, cruft + offset);
H_Update(&ctx, cruft, BN_num_bytes(data->grp->order));
/* the ciphersuite */
@@ -614,7 +632,7 @@
H_Final(&ctx, conf);
resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PWD,
- sizeof(struct eap_pwd_hdr) + SHA256_DIGEST_LENGTH,
+ 1 + SHA256_DIGEST_LENGTH,
EAP_CODE_RESPONSE, eap_get_id(reqData));
if (resp == NULL)
goto fin;
diff --git a/src/eap_peer/eap_sim.c b/src/eap_peer/eap_sim.c
index 6677063..06fbc5b 100644
--- a/src/eap_peer/eap_sim.c
+++ b/src/eap_peer/eap_sim.c
@@ -266,21 +266,20 @@
static void eap_sim_clear_identities(struct eap_sim_data *data, int id)
{
- wpa_printf(MSG_DEBUG, "EAP-SIM: forgetting old%s%s%s",
- id & CLEAR_PSEUDONYM ? " pseudonym" : "",
- id & CLEAR_REAUTH_ID ? " reauth_id" : "",
- id & CLEAR_EAP_ID ? " eap_id" : "");
- if (id & CLEAR_PSEUDONYM) {
+ if ((id & CLEAR_PSEUDONYM) && data->pseudonym) {
+ wpa_printf(MSG_DEBUG, "EAP-SIM: forgetting old pseudonym");
os_free(data->pseudonym);
data->pseudonym = NULL;
data->pseudonym_len = 0;
}
- if (id & CLEAR_REAUTH_ID) {
+ if ((id & CLEAR_REAUTH_ID) && data->reauth_id) {
+ wpa_printf(MSG_DEBUG, "EAP-SIM: forgetting old reauth_id");
os_free(data->reauth_id);
data->reauth_id = NULL;
data->reauth_id_len = 0;
}
- if (id & CLEAR_EAP_ID) {
+ if ((id & CLEAR_EAP_ID) && data->last_eap_identity) {
+ wpa_printf(MSG_DEBUG, "EAP-SIM: forgetting old eap_id");
os_free(data->last_eap_identity);
data->last_eap_identity = NULL;
data->last_eap_identity_len = 0;
@@ -649,11 +648,11 @@
EAP_SIM_UNABLE_TO_PROCESS_PACKET);
}
- /* Old reauthentication and pseudonym identities must not be used
- * anymore. In other words, if no new identities are received, full
- * authentication will be used on next reauthentication. */
- eap_sim_clear_identities(data, CLEAR_PSEUDONYM | CLEAR_REAUTH_ID |
- CLEAR_EAP_ID);
+ /* Old reauthentication identity must not be used anymore. In
+ * other words, if no new reauth identity is received, full
+ * authentication will be used on next reauthentication (using
+ * pseudonym identity or permanent identity). */
+ eap_sim_clear_identities(data, CLEAR_REAUTH_ID | CLEAR_EAP_ID);
if (attr->encr_data) {
u8 *decrypted;
diff --git a/src/eap_peer/eap_tls_common.c b/src/eap_peer/eap_tls_common.c
index d1567e9..2934ba4 100644
--- a/src/eap_peer/eap_tls_common.c
+++ b/src/eap_peer/eap_tls_common.c
@@ -112,7 +112,6 @@
wpa_printf(MSG_DEBUG, "TLS: using phase1 config options");
eap_tls_params_from_conf1(params, config);
}
- params->tls_ia = data->tls_ia;
/*
* Use blob data, if available. Otherwise, leave reference to external
@@ -295,9 +294,9 @@
os_memcpy(rnd + keys.client_random_len, keys.server_random,
keys.server_random_len);
- if (tls_prf(keys.master_key, keys.master_key_len,
- label, rnd, keys.client_random_len +
- keys.server_random_len, out, len))
+ if (tls_prf_sha1_md5(keys.master_key, keys.master_key_len,
+ label, rnd, keys.client_random_len +
+ keys.server_random_len, out, len))
goto fail;
os_free(rnd);
diff --git a/src/eap_peer/eap_tls_common.h b/src/eap_peer/eap_tls_common.h
index e9e0998..e9a07b8 100644
--- a/src/eap_peer/eap_tls_common.h
+++ b/src/eap_peer/eap_tls_common.h
@@ -66,11 +66,6 @@
int include_tls_length;
/**
- * tls_ia - Whether TLS/IA is enabled for this TLS connection
- */
- int tls_ia;
-
- /**
* eap - EAP state machine allocated with eap_peer_sm_init()
*/
struct eap_sm *eap;
diff --git a/src/eap_peer/eap_tnc.c b/src/eap_peer/eap_tnc.c
index 6c95f72..da288eb 100644
--- a/src/eap_peer/eap_tnc.c
+++ b/src/eap_peer/eap_tnc.c
@@ -15,7 +15,6 @@
#include "includes.h"
#include "common.h"
-#include "base64.h"
#include "eap_i.h"
#include "tncc.h"
diff --git a/src/eap_peer/eap_ttls.c b/src/eap_peer/eap_ttls.c
index e8f0f38..612dfa7 100644
--- a/src/eap_peer/eap_ttls.c
+++ b/src/eap_peer/eap_ttls.c
@@ -1,6 +1,6 @@
/*
* EAP peer method: EAP-TTLS (RFC 5281)
- * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2011, 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
@@ -26,17 +26,7 @@
#include "eap_config.h"
-/* Maximum supported TTLS version
- * 0 = RFC 5281
- * 1 = draft-funk-eap-ttls-v1-00.txt
- */
-#ifndef EAP_TTLS_VERSION
-#define EAP_TTLS_VERSION 0 /* TTLSv1 implementation is not yet complete */
-#endif /* EAP_TTLS_VERSION */
-
-
-#define MSCHAPV2_KEY_LEN 16
-#define MSCHAPV2_NT_RESPONSE_LEN 24
+#define EAP_TTLS_VERSION 0
static void eap_ttls_deinit(struct eap_sm *sm, void *priv);
@@ -44,9 +34,8 @@
struct eap_ttls_data {
struct eap_ssl_data ssl;
- int ssl_initialized;
- int ttls_version, force_ttls_version;
+ int ttls_version;
const struct eap_method *phase2_method;
void *phase2_priv;
@@ -91,22 +80,9 @@
if (data == NULL)
return NULL;
data->ttls_version = EAP_TTLS_VERSION;
- data->force_ttls_version = -1;
selected = "EAP";
data->phase2_type = EAP_TTLS_PHASE2_EAP;
-#if EAP_TTLS_VERSION > 0
- if (config && config->phase1) {
- const char *pos = os_strstr(config->phase1, "ttlsver=");
- if (pos) {
- data->force_ttls_version = atoi(pos + 8);
- data->ttls_version = data->force_ttls_version;
- wpa_printf(MSG_DEBUG, "EAP-TTLS: Forced TTLS version "
- "%d", data->force_ttls_version);
- }
- }
-#endif /* EAP_TTLS_VERSION */
-
if (config && config->phase2) {
if (os_strstr(config->phase2, "autheap=")) {
selected = "EAP";
@@ -140,19 +116,11 @@
data->phase2_eap_type.method = EAP_TYPE_NONE;
}
-#if EAP_TTLS_VERSION > 0
- if (!(tls_capabilities(sm->ssl_ctx) & TLS_CAPABILITY_IA) &&
- data->ttls_version > 0) {
- if (data->force_ttls_version > 0) {
- wpa_printf(MSG_INFO, "EAP-TTLS: Forced TTLSv%d and "
- "TLS library does not support TLS/IA.",
- data->force_ttls_version);
- eap_ttls_deinit(sm, data);
- return NULL;
- }
- data->ttls_version = 0;
+ if (eap_peer_tls_ssl_init(sm, &data->ssl, config)) {
+ wpa_printf(MSG_INFO, "EAP-TTLS: Failed to initialize SSL.");
+ eap_ttls_deinit(sm, data);
+ return NULL;
}
-#endif /* EAP_TTLS_VERSION */
return data;
}
@@ -176,8 +144,7 @@
return;
eap_ttls_phase2_eap_deinit(sm, data);
os_free(data->phase2_eap_types);
- if (data->ssl_initialized)
- eap_peer_tls_ssl_deinit(sm, &data->ssl);
+ eap_peer_tls_ssl_deinit(sm, &data->ssl);
os_free(data->key_data);
wpabuf_free(data->pending_phase2_req);
os_free(data);
@@ -246,39 +213,6 @@
}
-#if EAP_TTLS_VERSION > 0
-static int eap_ttls_ia_permute_inner_secret(struct eap_sm *sm,
- struct eap_ttls_data *data,
- const u8 *key, size_t key_len)
-{
- u8 *buf;
- size_t buf_len;
- int ret;
-
- if (key) {
- buf_len = 2 + key_len;
- buf = os_malloc(buf_len);
- if (buf == NULL)
- return -1;
- WPA_PUT_BE16(buf, key_len);
- os_memcpy(buf + 2, key, key_len);
- } else {
- buf = NULL;
- buf_len = 0;
- }
-
- wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Session keys for TLS/IA inner "
- "secret permutation", buf, buf_len);
- ret = tls_connection_ia_permute_inner_secret(sm->ssl_ctx,
- data->ssl.conn,
- buf, buf_len);
- os_free(buf);
-
- return ret;
-}
-#endif /* EAP_TTLS_VERSION */
-
-
static int eap_ttls_v0_derive_key(struct eap_sm *sm,
struct eap_ttls_data *data)
{
@@ -298,156 +232,10 @@
}
-#if EAP_TTLS_VERSION > 0
-static int eap_ttls_v1_derive_key(struct eap_sm *sm,
- struct eap_ttls_data *data)
-{
- struct tls_keys keys;
- u8 *rnd;
-
- os_free(data->key_data);
- data->key_data = NULL;
-
- os_memset(&keys, 0, sizeof(keys));
- if (tls_connection_get_keys(sm->ssl_ctx, data->ssl.conn, &keys) ||
- keys.client_random == NULL || keys.server_random == NULL ||
- keys.inner_secret == NULL) {
- wpa_printf(MSG_INFO, "EAP-TTLS: Could not get inner secret, "
- "client random, or server random to derive keying "
- "material");
- return -1;
- }
-
- rnd = os_malloc(keys.client_random_len + keys.server_random_len);
- data->key_data = os_malloc(EAP_TLS_KEY_LEN);
- if (rnd == NULL || data->key_data == NULL) {
- wpa_printf(MSG_INFO, "EAP-TTLS: No memory for key derivation");
- os_free(rnd);
- os_free(data->key_data);
- data->key_data = NULL;
- return -1;
- }
- os_memcpy(rnd, keys.client_random, keys.client_random_len);
- os_memcpy(rnd + keys.client_random_len, keys.server_random,
- keys.server_random_len);
-
- if (tls_prf(keys.inner_secret, keys.inner_secret_len,
- "ttls v1 keying material", rnd, keys.client_random_len +
- keys.server_random_len, data->key_data, EAP_TLS_KEY_LEN)) {
- wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to derive key");
- os_free(rnd);
- os_free(data->key_data);
- data->key_data = NULL;
- return -1;
- }
-
- wpa_hexdump(MSG_DEBUG, "EAP-TTLS: client/server random",
- rnd, keys.client_random_len + keys.server_random_len);
- wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: TLS/IA inner secret",
- keys.inner_secret, keys.inner_secret_len);
-
- os_free(rnd);
-
- wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Derived key",
- data->key_data, EAP_TLS_KEY_LEN);
-
- return 0;
-}
-#endif /* EAP_TTLS_VERSION */
-
-
static u8 * eap_ttls_implicit_challenge(struct eap_sm *sm,
struct eap_ttls_data *data, size_t len)
{
-#if EAP_TTLS_VERSION > 0
- struct tls_keys keys;
- u8 *challenge, *rnd;
-#endif /* EAP_TTLS_VERSION */
-
- if (data->ttls_version == 0) {
- return eap_peer_tls_derive_key(sm, &data->ssl,
- "ttls challenge", len);
- }
-
-#if EAP_TTLS_VERSION > 0
-
- os_memset(&keys, 0, sizeof(keys));
- if (tls_connection_get_keys(sm->ssl_ctx, data->ssl.conn, &keys) ||
- keys.client_random == NULL || keys.server_random == NULL ||
- keys.inner_secret == NULL) {
- wpa_printf(MSG_INFO, "EAP-TTLS: Could not get inner secret, "
- "client random, or server random to derive "
- "implicit challenge");
- return NULL;
- }
-
- rnd = os_malloc(keys.client_random_len + keys.server_random_len);
- challenge = os_malloc(len);
- if (rnd == NULL || challenge == NULL) {
- wpa_printf(MSG_INFO, "EAP-TTLS: No memory for implicit "
- "challenge derivation");
- os_free(rnd);
- os_free(challenge);
- return NULL;
- }
- os_memcpy(rnd, keys.server_random, keys.server_random_len);
- os_memcpy(rnd + keys.server_random_len, keys.client_random,
- keys.client_random_len);
-
- if (tls_prf(keys.inner_secret, keys.inner_secret_len,
- "inner application challenge", rnd,
- keys.client_random_len + keys.server_random_len,
- challenge, len)) {
- wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to derive implicit "
- "challenge");
- os_free(rnd);
- os_free(challenge);
- return NULL;
- }
-
- os_free(rnd);
-
- wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Derived implicit challenge",
- challenge, len);
-
- return challenge;
-
-#else /* EAP_TTLS_VERSION */
-
- return NULL;
-
-#endif /* EAP_TTLS_VERSION */
-}
-
-
-static void eap_ttlsv1_phase2_eap_finish(struct eap_sm *sm,
- struct eap_ttls_data *data,
- struct eap_method_ret *ret)
-{
-#if EAP_TTLS_VERSION > 0
- if (data->ttls_version > 0) {
- const struct eap_method *m = data->phase2_method;
- void *priv = data->phase2_priv;
-
- /* TTLSv1 requires TLS/IA FinalPhaseFinished */
- if (ret->decision == DECISION_UNCOND_SUCC)
- ret->decision = DECISION_COND_SUCC;
- ret->methodState = METHOD_CONT;
-
- if (ret->decision == DECISION_COND_SUCC &&
- m->isKeyAvailable && m->getKey &&
- m->isKeyAvailable(sm, priv)) {
- u8 *key;
- size_t key_len;
- key = m->getKey(sm, priv, &key_len);
- if (key) {
- eap_ttls_ia_permute_inner_secret(
- sm, data, key, key_len);
- os_free(key);
- }
- }
- }
-#endif /* EAP_TTLS_VERSION */
+ return eap_peer_tls_derive_key(sm, &data->ssl, "ttls challenge", len);
}
@@ -494,7 +282,6 @@
ret->methodState = iret.methodState;
ret->decision = iret.decision;
}
- eap_ttlsv1_phase2_eap_finish(sm, data, ret);
return 0;
}
@@ -615,26 +402,6 @@
}
-static void eap_ttlsv1_permute_inner(struct eap_sm *sm,
- struct eap_ttls_data *data)
-{
-#if EAP_TTLS_VERSION > 0
- u8 session_key[2 * MSCHAPV2_KEY_LEN];
-
- if (data->ttls_version == 0)
- return;
-
- get_asymetric_start_key(data->master_key, session_key,
- MSCHAPV2_KEY_LEN, 0, 0);
- get_asymetric_start_key(data->master_key,
- session_key + MSCHAPV2_KEY_LEN,
- MSCHAPV2_KEY_LEN, 1, 0);
- eap_ttls_ia_permute_inner_secret(sm, data, session_key,
- sizeof(session_key));
-#endif /* EAP_TTLS_VERSION */
-}
-
-
static int eap_ttls_phase2_request_mschapv2(struct eap_sm *sm,
struct eap_ttls_data *data,
struct eap_method_ret *ret,
@@ -702,8 +469,6 @@
}
data->auth_response_valid = 1;
- eap_ttlsv1_permute_inner(sm, data);
-
pos += 24;
os_free(challenge);
AVP_PAD(buf, pos);
@@ -711,7 +476,7 @@
wpabuf_put(msg, pos - buf);
*resp = msg;
- if (sm->workaround && data->ttls_version == 0) {
+ if (sm->workaround) {
/* At least FreeRADIUS seems to be terminating
* EAP-TTLS/MSHCAPV2 without the expected MS-CHAP-v2 Success
* packet. */
@@ -798,17 +563,10 @@
wpabuf_put(msg, pos - buf);
*resp = msg;
- if (data->ttls_version > 0) {
- /* EAP-TTLSv1 uses TLS/IA FinalPhaseFinished to report success,
- * so do not allow connection to be terminated yet. */
- ret->methodState = METHOD_CONT;
- ret->decision = DECISION_COND_SUCC;
- } else {
- /* EAP-TTLS/MSCHAP does not provide tunneled success
- * notification, so assume that Phase2 succeeds. */
- ret->methodState = METHOD_DONE;
- ret->decision = DECISION_COND_SUCC;
- }
+ /* EAP-TTLS/MSCHAP does not provide tunneled success
+ * notification, so assume that Phase2 succeeds. */
+ ret->methodState = METHOD_DONE;
+ ret->decision = DECISION_COND_SUCC;
return 0;
}
@@ -859,17 +617,10 @@
wpabuf_put(msg, pos - buf);
*resp = msg;
- if (data->ttls_version > 0) {
- /* EAP-TTLSv1 uses TLS/IA FinalPhaseFinished to report success,
- * so do not allow connection to be terminated yet. */
- ret->methodState = METHOD_CONT;
- ret->decision = DECISION_COND_SUCC;
- } else {
- /* EAP-TTLS/PAP does not provide tunneled success notification,
- * so assume that Phase2 succeeds. */
- ret->methodState = METHOD_DONE;
- ret->decision = DECISION_COND_SUCC;
- }
+ /* EAP-TTLS/PAP does not provide tunneled success notification,
+ * so assume that Phase2 succeeds. */
+ ret->methodState = METHOD_DONE;
+ ret->decision = DECISION_COND_SUCC;
return 0;
}
@@ -942,17 +693,10 @@
wpabuf_put(msg, pos - buf);
*resp = msg;
- if (data->ttls_version > 0) {
- /* EAP-TTLSv1 uses TLS/IA FinalPhaseFinished to report success,
- * so do not allow connection to be terminated yet. */
- ret->methodState = METHOD_CONT;
- ret->decision = DECISION_COND_SUCC;
- } else {
- /* EAP-TTLS/CHAP does not provide tunneled success
- * notification, so assume that Phase2 succeeds. */
- ret->methodState = METHOD_DONE;
- ret->decision = DECISION_COND_SUCC;
- }
+ /* EAP-TTLS/CHAP does not provide tunneled success
+ * notification, so assume that Phase2 succeeds. */
+ ret->methodState = METHOD_DONE;
+ ret->decision = DECISION_COND_SUCC;
return 0;
}
@@ -1027,36 +771,6 @@
}
-#if EAP_TTLS_VERSION > 0
-static struct wpabuf * eap_ttls_build_phase_finished(
- struct eap_sm *sm, struct eap_ttls_data *data, int id, int final)
-{
- struct wpabuf *req, *buf;
-
- buf = tls_connection_ia_send_phase_finished(sm->ssl_ctx,
- data->ssl.conn,
- final);
- if (buf == NULL)
- return NULL;
-
- 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_u8(req, data->ttls_version);
- wpabuf_put_buf(req, buf);
- wpabuf_free(buf);
- eap_update_len(req);
-
- return req;
-}
-#endif /* EAP_TTLS_VERSION */
-
-
struct ttls_parse_avp {
u8 *mschapv2;
u8 *eapdata;
@@ -1366,19 +1080,9 @@
wpa_printf(MSG_INFO, "EAP-TTLS: Phase 2 MSCHAPV2 "
"authentication succeeded");
- if (data->ttls_version > 0) {
- /*
- * EAP-TTLSv1 uses TLS/IA FinalPhaseFinished to report
- * success, so do not allow connection to be terminated
- * yet.
- */
- ret->methodState = METHOD_CONT;
- ret->decision = DECISION_COND_SUCC;
- } else {
- ret->methodState = METHOD_DONE;
- ret->decision = DECISION_UNCOND_SUCC;
- data->phase2_success = 1;
- }
+ ret->methodState = METHOD_DONE;
+ ret->decision = DECISION_UNCOND_SUCC;
+ data->phase2_success = 1;
/*
* Reply with empty data; authentication server will reply
@@ -1493,24 +1197,6 @@
}
-#if EAP_TTLS_VERSION > 0
-static void eap_ttls_final_phase_finished(struct eap_sm *sm,
- struct eap_ttls_data *data,
- struct eap_method_ret *ret,
- u8 identifier,
- struct wpabuf **out_data)
-{
- wpa_printf(MSG_DEBUG, "EAP-TTLS: FinalPhaseFinished received");
- wpa_printf(MSG_INFO, "EAP-TTLS: TLS/IA authentication succeeded");
- ret->methodState = METHOD_DONE;
- ret->decision = DECISION_UNCOND_SUCC;
- data->phase2_success = 1;
- *out_data = eap_ttls_build_phase_finished(sm, data, identifier, 1);
- eap_ttls_v1_derive_key(sm, data);
-}
-#endif /* EAP_TTLS_VERSION */
-
-
static int eap_ttls_implicit_identity_request(struct eap_sm *sm,
struct eap_ttls_data *data,
struct eap_method_ret *ret,
@@ -1534,6 +1220,21 @@
"processing failed");
retval = -1;
} else {
+ struct eap_peer_config *config = eap_get_config(sm);
+ if (resp == NULL &&
+ (config->pending_req_identity ||
+ config->pending_req_password ||
+ config->pending_req_otp ||
+ config->pending_req_new_password)) {
+ /*
+ * Use empty buffer to force implicit request
+ * processing when EAP request is re-processed after
+ * user input.
+ */
+ wpabuf_free(data->pending_phase2_req);
+ data->pending_phase2_req = wpabuf_alloc(0);
+ }
+
retval = eap_ttls_encrypt_response(sm, data, resp, identifier,
out_data);
}
@@ -1627,17 +1328,6 @@
if (retval)
goto done;
-#if EAP_TTLS_VERSION > 0
- if (data->ttls_version > 0 &&
- (in_decrypted == NULL || wpabuf_len(in_decrypted) == 0) &&
- tls_connection_ia_final_phase_finished(sm->ssl_ctx,
- data->ssl.conn)) {
- eap_ttls_final_phase_finished(sm, data, ret, identifier,
- out_data);
- goto done;
- }
-#endif /* EAP_TTLS_VERSION */
-
continue_req:
data->phase2_start = 0;
@@ -1662,46 +1352,6 @@
}
-static int eap_ttls_process_start(struct eap_sm *sm,
- struct eap_ttls_data *data, u8 flags,
- struct eap_method_ret *ret)
-{
- struct eap_peer_config *config = eap_get_config(sm);
-
- wpa_printf(MSG_DEBUG, "EAP-TTLS: Start (server ver=%d, own ver=%d)",
- flags & EAP_TLS_VERSION_MASK, data->ttls_version);
-#if EAP_TTLS_VERSION > 0
- 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 "
- "forced TTLS version %d",
- data->force_ttls_version);
- ret->methodState = METHOD_DONE;
- ret->decision = DECISION_FAIL;
- ret->allowNotifications = FALSE;
- return -1;
- }
- wpa_printf(MSG_DEBUG, "EAP-TTLS: Using TTLS version %d",
- data->ttls_version);
-
- if (data->ttls_version > 0)
- data->ssl.tls_ia = 1;
-#endif /* EAP_TTLS_VERSION */
- if (!data->ssl_initialized &&
- eap_peer_tls_ssl_init(sm, &data->ssl, config)) {
- wpa_printf(MSG_INFO, "EAP-TTLS: Failed to initialize SSL.");
- return -1;
- }
- data->ssl_initialized = 1;
-
- wpa_printf(MSG_DEBUG, "EAP-TTLS: Start");
-
- return 0;
-}
-
-
static int eap_ttls_process_handshake(struct eap_sm *sm,
struct eap_ttls_data *data,
struct eap_method_ret *ret,
@@ -1725,8 +1375,7 @@
ret->methodState = METHOD_MAY_CONT;
}
data->phase2_start = 1;
- if (data->ttls_version == 0)
- eap_ttls_v0_derive_key(sm, data);
+ eap_ttls_v0_derive_key(sm, data);
if (*out_data == NULL || wpabuf_len(*out_data) == 0) {
if (eap_ttls_decrypt(sm, data, ret, identifier,
@@ -1761,7 +1410,7 @@
struct eap_ttls_data *data,
struct eap_method_ret *ret)
{
- if (data->ttls_version == 0 && ret->methodState == METHOD_DONE) {
+ if (ret->methodState == METHOD_DONE) {
ret->allowNotifications = FALSE;
if (ret->decision == DECISION_UNCOND_SUCC ||
ret->decision == DECISION_COND_SUCC) {
@@ -1779,8 +1428,7 @@
}
#endif /* EAP_TNC */
}
- } else if (data->ttls_version == 0 &&
- ret->methodState == METHOD_MAY_CONT &&
+ } else if (ret->methodState == METHOD_MAY_CONT &&
(ret->decision == DECISION_UNCOND_SUCC ||
ret->decision == DECISION_COND_SUCC)) {
wpa_printf(MSG_DEBUG, "EAP-TTLS: Authentication "
@@ -1808,8 +1456,9 @@
id = eap_get_id(reqData);
if (flags & EAP_TLS_FLAGS_START) {
- if (eap_ttls_process_start(sm, data, flags, ret) < 0)
- return NULL;
+ wpa_printf(MSG_DEBUG, "EAP-TTLS: Start (server ver=%d, own "
+ "ver=%d)", flags & EAP_TLS_VERSION_MASK,
+ data->ttls_version);
/* RFC 5281, Ch. 9.2:
* "This packet MAY contain additional information in the form
@@ -1817,13 +1466,6 @@
* For now, ignore any potential extra data.
*/
left = 0;
- } else if (!data->ssl_initialized) {
- wpa_printf(MSG_DEBUG, "EAP-TTLS: First message did not "
- "include Start flag");
- ret->methodState = METHOD_DONE;
- ret->decision = DECISION_FAIL;
- ret->allowNotifications = FALSE;
- return NULL;
}
resp = NULL;
diff --git a/src/eap_peer/ikev2.c b/src/eap_peer/ikev2.c
index 1e169a0..acd7611 100644
--- a/src/eap_peer/ikev2.c
+++ b/src/eap_peer/ikev2.c
@@ -425,7 +425,7 @@
}
/* RFC 4306, Section 3.4:
- * The length of DH public value MUST be equal to the lenght of the
+ * The length of DH public value MUST be equal to the length of the
* prime modulus.
*/
if (kei_len - 4 != data->dh->prime_len) {