wpa_supplicant: Update to 07-Jul-2012 TOT
commit a5ed45586c63ffd8f9d2b44e27c251d7bacbeaf4
Author: Jouni Malinen <j@w1.fi>
Date: Sat Jul 7 13:01:45 2012 +0300
WPS SSDP: Fix socket leaks on error paths
Change-Id: I0864aac7fc88fa2a60f5cca7d524b94363410c85
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/eap_peer/eap.c b/src/eap_peer/eap.c
index 6a88589..8b43be4 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-2010, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -81,6 +81,16 @@
}
+static void eap_notify_status(struct eap_sm *sm, const char *status,
+ const char *parameter)
+{
+ wpa_printf(MSG_DEBUG, "EAP: Status notification: %s (param=%s)",
+ status, parameter);
+ if (sm->eapol_cb->notify_status)
+ sm->eapol_cb->notify_status(sm->eapol_ctx, status, parameter);
+}
+
+
static void eap_deinit_prev_method(struct eap_sm *sm, const char *txt)
{
if (sm->m == NULL || sm->eap_method_priv == NULL)
@@ -213,6 +223,7 @@
{
int reinit;
EapType method;
+ const struct eap_method *eap_method;
SM_ENTRY(EAP, GET_METHOD);
@@ -221,18 +232,24 @@
else
method = sm->reqMethod;
+ eap_method = eap_peer_get_eap_method(sm->reqVendor, 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);
+ eap_notify_status(sm, "refuse proposed method",
+ eap_method ? eap_method->name : "unknown");
goto nak;
}
wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_PROPOSED_METHOD
"vendor=%u method=%u", sm->reqVendor, method);
+ eap_notify_status(sm, "accept proposed method",
+ eap_method ? eap_method->name : "unknown");
/*
* RFC 4137 does not define specific operation for fast
* re-authentication (session resumption). The design here is to allow
@@ -256,7 +273,7 @@
sm->selectedMethod = sm->reqMethod;
if (sm->m == NULL)
- sm->m = eap_peer_get_eap_method(sm->reqVendor, method);
+ sm->m = eap_method;
if (!sm->m) {
wpa_printf(MSG_DEBUG, "EAP: Could not find selected method: "
"vendor %d method %d",
@@ -938,7 +955,7 @@
static int eap_sm_imsi_identity(struct eap_sm *sm,
struct eap_peer_config *conf)
{
- int aka = 0;
+ enum { EAP_SM_SIM, EAP_SM_AKA, EAP_SM_AKA_PRIME } method = EAP_SM_SIM;
char imsi[100];
size_t imsi_len;
struct eap_method_type *m = conf->eap_methods;
@@ -966,8 +983,14 @@
for (i = 0; m && (m[i].vendor != EAP_VENDOR_IETF ||
m[i].method != EAP_TYPE_NONE); i++) {
if (m[i].vendor == EAP_VENDOR_IETF &&
+ m[i].method == EAP_TYPE_AKA_PRIME) {
+ method = EAP_SM_AKA_PRIME;
+ break;
+ }
+
+ if (m[i].vendor == EAP_VENDOR_IETF &&
m[i].method == EAP_TYPE_AKA) {
- aka = 1;
+ method = EAP_SM_AKA;
break;
}
}
@@ -980,7 +1003,17 @@
return -1;
}
- conf->identity[0] = aka ? '0' : '1';
+ switch (method) {
+ case EAP_SM_SIM:
+ conf->identity[0] = '1';
+ break;
+ case EAP_SM_AKA:
+ conf->identity[0] = '0';
+ break;
+ case EAP_SM_AKA_PRIME:
+ conf->identity[0] = '6';
+ break;
+ }
os_memcpy(conf->identity + 1, imsi, imsi_len);
conf->identity_len = 1 + imsi_len;
@@ -1219,10 +1252,12 @@
break;
case EAP_CODE_SUCCESS:
wpa_printf(MSG_DEBUG, "EAP: Received EAP-Success");
+ eap_notify_status(sm, "completion", "success");
sm->rxSuccess = TRUE;
break;
case EAP_CODE_FAILURE:
wpa_printf(MSG_DEBUG, "EAP: Received EAP-Failure");
+ eap_notify_status(sm, "completion", "failure");
sm->rxFailure = TRUE;
break;
default:
@@ -1240,6 +1275,10 @@
char *hash_hex = NULL;
switch (ev) {
+ case TLS_CERT_CHAIN_SUCCESS:
+ eap_notify_status(sm, "remote certificate verification",
+ "success");
+ break;
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'",
@@ -1247,6 +1286,8 @@
data->cert_fail.depth,
data->cert_fail.subject,
data->cert_fail.reason_txt);
+ eap_notify_status(sm, "remote certificate verification",
+ data->cert_fail.reason_txt);
break;
case TLS_PEER_CERTIFICATE:
if (!sm->eapol_cb->notify_cert)
@@ -1267,6 +1308,14 @@
data->peer_cert.subject,
hash_hex, data->peer_cert.cert);
break;
+ case TLS_ALERT:
+ if (data->alert.is_local)
+ eap_notify_status(sm, "local TLS alert",
+ data->alert.description);
+ else
+ eap_notify_status(sm, "remote TLS alert",
+ data->alert.description);
+ break;
}
os_free(hash_hex);
@@ -1321,6 +1370,13 @@
return NULL;
}
+ sm->ssl_ctx2 = tls_init(&tlsconf);
+ if (sm->ssl_ctx2 == NULL) {
+ wpa_printf(MSG_INFO, "SSL: Failed to initialize TLS "
+ "context (2).");
+ /* Run without separate TLS context within TLS tunnel */
+ }
+
return sm;
}
@@ -1338,6 +1394,8 @@
return;
eap_deinit_prev_method(sm, "EAP deinit");
eap_sm_abort(sm);
+ if (sm->ssl_ctx2)
+ tls_deinit(sm->ssl_ctx2);
tls_deinit(sm->ssl_ctx);
os_free(sm);
}
diff --git a/src/eap_peer/eap.h b/src/eap_peer/eap.h
index b95a285..6e87475 100644
--- a/src/eap_peer/eap.h
+++ b/src/eap_peer/eap.h
@@ -226,6 +226,15 @@
*/
void (*notify_cert)(void *ctx, int depth, const char *subject,
const char *cert_hash, const struct wpabuf *cert);
+
+ /**
+ * notify_status - Notification of the current EAP state
+ * @ctx: eapol_ctx from eap_peer_sm_init() call
+ * @status: Step in the process of EAP authentication
+ * @parameter: Step-specific parameter, e.g., EAP method name
+ */
+ void (*notify_status)(void *ctx, const char *status,
+ const char *parameter);
};
/**
diff --git a/src/eap_peer/eap_aka.c b/src/eap_peer/eap_aka.c
index 7e37e44..1cec4d8 100644
--- a/src/eap_peer/eap_aka.c
+++ b/src/eap_peer/eap_aka.c
@@ -1,6 +1,6 @@
/*
- * EAP peer method: EAP-AKA (RFC 4187) and EAP-AKA' (draft-arkko-eap-aka-kdf)
- * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
+ * EAP peer method: EAP-AKA (RFC 4187) and EAP-AKA' (RFC 5448)
+ * Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -229,19 +229,19 @@
static void eap_aka_clear_identities(struct eap_aka_data *data, int id)
{
- if (id & CLEAR_PSEUDONYM) {
+ if ((id & CLEAR_PSEUDONYM) && data->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) {
+ if ((id & CLEAR_REAUTH_ID) && data->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) {
+ if ((id & CLEAR_EAP_ID) && data->last_eap_identity) {
wpa_printf(MSG_DEBUG, "EAP-AKA: forgetting old eap_id");
os_free(data->last_eap_identity);
data->last_eap_identity = NULL;
diff --git a/src/eap_peer/eap_i.h b/src/eap_peer/eap_i.h
index 06d6db6..3318b81 100644
--- a/src/eap_peer/eap_i.h
+++ b/src/eap_peer/eap_i.h
@@ -317,6 +317,7 @@
void *msg_ctx;
void *scard_ctx;
void *ssl_ctx;
+ void *ssl_ctx2;
unsigned int workaround;
diff --git a/src/eap_peer/eap_pwd.c b/src/eap_peer/eap_pwd.c
index 37e9234..267d0a5 100644
--- a/src/eap_peer/eap_pwd.c
+++ b/src/eap_peer/eap_pwd.c
@@ -9,6 +9,7 @@
#include "includes.h"
#include "common.h"
+#include "crypto/sha256.h"
#include "eap_peer/eap_i.h"
#include "eap_common/eap_pwd_common.h"
@@ -459,10 +460,10 @@
const u8 *payload, size_t payload_len)
{
BIGNUM *x = NULL, *y = NULL;
- HMAC_CTX ctx;
+ struct crypto_hash *hash;
u32 cs;
u16 grp;
- u8 conf[SHA256_DIGEST_LENGTH], *cruft = NULL, *ptr;
+ u8 conf[SHA256_MAC_LEN], *cruft = NULL, *ptr;
int offset;
/*
@@ -489,7 +490,9 @@
* server's commit is H(k | server_element | server_scalar |
* peer_element | peer_scalar | ciphersuite)
*/
- H_Init(&ctx);
+ hash = eap_pwd_h_init();
+ if (hash == NULL)
+ goto fin;
/*
* zero the memory each time because this is mod prime math and some
@@ -498,7 +501,7 @@
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
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));
+ eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
/* server element: x, y */
if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group,
@@ -511,18 +514,18 @@
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
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));
+ eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
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));
+ eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
/* server scalar */
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
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));
+ eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->order));
/* my element: x, y */
if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group,
@@ -536,27 +539,27 @@
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
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));
+ eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
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));
+ eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
/* my scalar */
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
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));
+ eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->order));
/* the ciphersuite */
- H_Update(&ctx, (u8 *) &cs, sizeof(u32));
+ eap_pwd_h_update(hash, (u8 *) &cs, sizeof(u32));
/* random function fin */
- H_Final(&ctx, conf);
+ eap_pwd_h_final(hash, conf);
ptr = (u8 *) payload;
- if (os_memcmp(conf, ptr, SHA256_DIGEST_LENGTH)) {
+ if (os_memcmp(conf, ptr, SHA256_MAC_LEN)) {
wpa_printf(MSG_INFO, "EAP-PWD (peer): confirm did not verify");
goto fin;
}
@@ -568,13 +571,15 @@
* H(k | peer_element | peer_scalar | server_element | server_scalar |
* ciphersuite)
*/
- H_Init(&ctx);
+ hash = eap_pwd_h_init();
+ if (hash == NULL)
+ goto fin;
/* k */
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
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));
+ eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
/* my element */
if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group,
@@ -587,18 +592,18 @@
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
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));
+ eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
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));
+ eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
/* my scalar */
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
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));
+ eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->order));
/* server element: x, y */
if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group,
@@ -611,24 +616,24 @@
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
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));
+ eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
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));
+ eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
/* server scalar */
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
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));
+ eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->order));
/* the ciphersuite */
- H_Update(&ctx, (u8 *) &cs, sizeof(u32));
+ eap_pwd_h_update(hash, (u8 *) &cs, sizeof(u32));
/* all done */
- H_Final(&ctx, conf);
+ eap_pwd_h_final(hash, conf);
if (compute_keys(data->grp, data->bnctx, data->k,
data->my_scalar, data->server_scalar, conf, ptr,
@@ -638,11 +643,11 @@
goto fin;
}
- data->outbuf = wpabuf_alloc(SHA256_DIGEST_LENGTH);
+ data->outbuf = wpabuf_alloc(SHA256_MAC_LEN);
if (data->outbuf == NULL)
goto fin;
- wpabuf_put_data(data->outbuf, conf, SHA256_DIGEST_LENGTH);
+ wpabuf_put_data(data->outbuf, conf, SHA256_MAC_LEN);
fin:
os_free(cruft);
@@ -725,6 +730,7 @@
*/
if (data->out_frag_pos >= wpabuf_len(data->outbuf)) {
wpabuf_free(data->outbuf);
+ data->outbuf = NULL;
data->out_frag_pos = 0;
}
wpa_printf(MSG_DEBUG, "EAP-pwd: Send %s fragment of %d bytes",
@@ -856,8 +862,11 @@
/*
* if we're not fragmenting then there's no need to carry this around
*/
- if (data->out_frag_pos == 0)
+ if (data->out_frag_pos == 0) {
wpabuf_free(data->outbuf);
+ data->outbuf = NULL;
+ data->out_frag_pos = 0;
+ }
return resp;
}
diff --git a/src/eap_peer/eap_tls.c b/src/eap_peer/eap_tls.c
index a3067fa..ed52fb6 100644
--- a/src/eap_peer/eap_tls.c
+++ b/src/eap_peer/eap_tls.c
@@ -1,6 +1,6 @@
/*
* EAP peer method: EAP-TLS (RFC 2716)
- * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2008, 2012, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -21,6 +21,7 @@
struct eap_tls_data {
struct eap_ssl_data ssl;
u8 *key_data;
+ void *ssl_ctx;
};
@@ -40,6 +41,9 @@
if (data == NULL)
return NULL;
+ data->ssl_ctx = sm->init_phase2 && sm->ssl_ctx2 ? sm->ssl_ctx2 :
+ sm->ssl_ctx;
+
if (eap_peer_tls_ssl_init(sm, &data->ssl, config)) {
wpa_printf(MSG_INFO, "EAP-TLS: Failed to initialize SSL.");
eap_tls_deinit(sm, data);
@@ -165,7 +169,7 @@
return eap_tls_failure(sm, data, ret, res, resp, id);
}
- if (tls_connection_established(sm->ssl_ctx, data->ssl.conn))
+ if (tls_connection_established(data->ssl_ctx, data->ssl.conn))
eap_tls_success(sm, data, ret);
if (res == 1) {
@@ -180,7 +184,7 @@
static Boolean eap_tls_has_reauth_data(struct eap_sm *sm, void *priv)
{
struct eap_tls_data *data = priv;
- return tls_connection_established(sm->ssl_ctx, data->ssl.conn);
+ return tls_connection_established(data->ssl_ctx, data->ssl.conn);
}
diff --git a/src/eap_peer/eap_tls_common.c b/src/eap_peer/eap_tls_common.c
index 52549f4..69e83d9 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-2009, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -136,14 +136,14 @@
{
int res;
- data->conn = tls_connection_init(sm->ssl_ctx);
+ data->conn = tls_connection_init(data->ssl_ctx);
if (data->conn == NULL) {
wpa_printf(MSG_INFO, "SSL: Failed to initialize new TLS "
"connection");
return -1;
}
- res = tls_connection_set_params(sm->ssl_ctx, data->conn, params);
+ res = tls_connection_set_params(data->ssl_ctx, data->conn, params);
if (res == TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED) {
/*
* At this point with the pkcs11 engine the PIN might be wrong.
@@ -162,13 +162,13 @@
config->pin = NULL;
eap_sm_request_pin(sm);
sm->ignore = TRUE;
- tls_connection_deinit(sm->ssl_ctx, data->conn);
+ tls_connection_deinit(data->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);
+ tls_connection_deinit(data->ssl_ctx, data->conn);
data->conn = NULL;
return -1;
}
@@ -197,6 +197,8 @@
data->eap = sm;
data->phase2 = sm->init_phase2;
+ data->ssl_ctx = sm->init_phase2 && sm->ssl_ctx2 ? sm->ssl_ctx2 :
+ sm->ssl_ctx;
if (eap_tls_params_from_conf(sm, data, ¶ms, config, data->phase2) <
0)
return -1;
@@ -234,7 +236,7 @@
*/
void eap_peer_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data)
{
- tls_connection_deinit(sm->ssl_ctx, data->conn);
+ tls_connection_deinit(data->ssl_ctx, data->conn);
eap_peer_tls_reset_input(data);
eap_peer_tls_reset_output(data);
}
@@ -265,8 +267,8 @@
return NULL;
/* First, try to use TLS library function for PRF, if available. */
- if (tls_connection_prf(sm->ssl_ctx, data->conn, label, 0, out, len) ==
- 0)
+ if (tls_connection_prf(data->ssl_ctx, data->conn, label, 0, out, len)
+ == 0)
return out;
/*
@@ -274,7 +276,7 @@
* session parameters and use an internal implementation of TLS PRF to
* derive the key.
*/
- if (tls_connection_get_keys(sm->ssl_ctx, data->conn, &keys))
+ if (tls_connection_get_keys(data->ssl_ctx, data->conn, &keys))
goto fail;
if (keys.client_random == NULL || keys.server_random == NULL ||
@@ -441,14 +443,14 @@
WPA_ASSERT(data->tls_out == NULL);
}
appl_data = NULL;
- data->tls_out = tls_connection_handshake(sm->ssl_ctx, data->conn,
+ data->tls_out = tls_connection_handshake(data->ssl_ctx, data->conn,
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)) {
+ tls_connection_established(data->ssl_ctx, data->conn) &&
+ !tls_connection_get_failed(data->ssl_ctx, data->conn)) {
wpa_hexdump_buf_key(MSG_MSGDUMP, "SSL: Application data",
appl_data);
*out_data = appl_data;
@@ -616,7 +618,7 @@
return -1;
}
- if (tls_connection_get_failed(sm->ssl_ctx, data->conn)) {
+ if (tls_connection_get_failed(data->ssl_ctx, data->conn)) {
/* TLS processing has failed - return error */
wpa_printf(MSG_DEBUG, "SSL: Failed - tls_out available to "
"report error");
@@ -675,7 +677,7 @@
{
eap_peer_tls_reset_input(data);
eap_peer_tls_reset_output(data);
- return tls_connection_shutdown(sm->ssl_ctx, data->conn);
+ return tls_connection_shutdown(data->ssl_ctx, data->conn);
}
@@ -694,7 +696,8 @@
char name[128];
int len = 0, ret;
- if (tls_get_cipher(sm->ssl_ctx, data->conn, name, sizeof(name)) == 0) {
+ if (tls_get_cipher(data->ssl_ctx, data->conn, name, sizeof(name)) == 0)
+ {
ret = os_snprintf(buf + len, buflen - len,
"EAP TLS cipher=%s\n", name);
if (ret < 0 || (size_t) ret >= buflen - len)
@@ -741,7 +744,7 @@
size_t left;
unsigned int tls_msg_len;
- if (tls_get_errors(sm->ssl_ctx)) {
+ if (tls_get_errors(data->ssl_ctx)) {
wpa_printf(MSG_INFO, "SSL: TLS errors detected");
ret->ignore = TRUE;
return NULL;
@@ -849,7 +852,7 @@
if (msg == NULL)
return need_more_input ? 1 : -1;
- *in_decrypted = tls_connection_decrypt(sm->ssl_ctx, data->conn, msg);
+ *in_decrypted = tls_connection_decrypt(data->ssl_ctx, data->conn, msg);
eap_peer_tls_reset_input(data);
if (*in_decrypted == NULL) {
wpa_printf(MSG_INFO, "SSL: Failed to decrypt Phase 2 data");
@@ -877,8 +880,8 @@
{
if (in_data) {
eap_peer_tls_reset_output(data);
- data->tls_out = tls_connection_encrypt(sm->ssl_ctx, data->conn,
- in_data);
+ data->tls_out = tls_connection_encrypt(data->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)",
diff --git a/src/eap_peer/eap_tls_common.h b/src/eap_peer/eap_tls_common.h
index 7426467..771385b 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-2009, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2009, 2012, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -63,6 +63,11 @@
* eap - EAP state machine allocated with eap_peer_sm_init()
*/
struct eap_sm *eap;
+
+ /**
+ * ssl_ctx - TLS library context to use for the connection
+ */
+ void *ssl_ctx;
};
diff --git a/src/eap_peer/eap_ttls.c b/src/eap_peer/eap_ttls.c
index 0204ba2..e09f5e5 100644
--- a/src/eap_peer/eap_ttls.c
+++ b/src/eap_peer/eap_ttls.c
@@ -435,7 +435,6 @@
"implicit challenge");
return -1;
}
- peer_challenge = challenge + 1 + EAP_TTLS_MSCHAPV2_CHALLENGE_LEN;
pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_MS_CHAP_CHALLENGE,
RADIUS_VENDOR_ID_MICROSOFT, 1,
@@ -448,7 +447,14 @@
data->ident = challenge[EAP_TTLS_MSCHAPV2_CHALLENGE_LEN];
*pos++ = data->ident;
*pos++ = 0; /* Flags */
- os_memcpy(pos, peer_challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN);
+ if (os_get_random(pos, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN) < 0) {
+ os_free(challenge);
+ wpabuf_free(msg);
+ wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAPV2: Failed to get "
+ "random data for peer challenge");
+ return -1;
+ }
+ peer_challenge = pos;
pos += EAP_TTLS_MSCHAPV2_CHALLENGE_LEN;
os_memset(pos, 0, 8); /* Reserved, must be zero */
pos += 8;
@@ -456,6 +462,7 @@
password_len, pwhash, challenge,
peer_challenge, pos, data->auth_response,
data->master_key)) {
+ os_free(challenge);
wpabuf_free(msg);
wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAPV2: Failed to derive "
"response");
diff --git a/src/eap_peer/eap_wsc.c b/src/eap_peer/eap_wsc.c
index 4473b90..d007a57 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-2009, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2007-2009, 2012, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -137,6 +137,8 @@
struct wps_context *wps;
struct wps_credential new_ap_settings;
int res;
+ u8 dev_pw[WPS_OOB_DEVICE_PASSWORD_LEN];
+ int nfc = 0;
wps = sm->wps;
if (wps == NULL) {
@@ -184,13 +186,26 @@
while (*pos != '\0' && *pos != ' ')
pos++;
cfg.pin_len = pos - (const char *) cfg.pin;
+ if (cfg.pin_len >= WPS_OOB_DEVICE_PASSWORD_MIN_LEN * 2 &&
+ cfg.pin_len <= WPS_OOB_DEVICE_PASSWORD_LEN * 2 &&
+ hexstr2bin((const char *) cfg.pin, dev_pw,
+ cfg.pin_len / 2) == 0) {
+ /* Convert OOB Device Password to binary */
+ cfg.pin = dev_pw;
+ cfg.pin_len /= 2;
+ }
+ if (cfg.pin_len == 6 && os_strncmp(pos, "nfc-pw", 6) == 0) {
+ cfg.pin = NULL;
+ cfg.pin_len = 0;
+ nfc = 1;
+ }
} else {
pos = os_strstr(phase1, "pbc=1");
if (pos)
cfg.pbc = 1;
}
- if (cfg.pin == NULL && !cfg.pbc) {
+ if (cfg.pin == NULL && !cfg.pbc && !nfc) {
wpa_printf(MSG_INFO, "EAP-WSC: PIN or PBC not set in phase1 "
"configuration data");
os_free(data);