diff --git a/src/eap_peer/eap.c b/src/eap_peer/eap.c index 6a885895a..f13d2e3b9 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 + * Copyright (c) 2004-2012, Jouni Malinen * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -1321,6 +1321,13 @@ struct eap_sm * eap_peer_sm_init(void *eapol_ctx, 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 +1345,8 @@ void eap_peer_sm_deinit(struct eap_sm *sm) 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_i.h b/src/eap_peer/eap_i.h index 06d6db621..3318b8115 100644 --- a/src/eap_peer/eap_i.h +++ b/src/eap_peer/eap_i.h @@ -317,6 +317,7 @@ struct eap_sm { void *msg_ctx; void *scard_ctx; void *ssl_ctx; + void *ssl_ctx2; unsigned int workaround; diff --git a/src/eap_peer/eap_tls.c b/src/eap_peer/eap_tls.c index a3067fa64..ed52fb690 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 + * Copyright (c) 2004-2008, 2012, Jouni Malinen * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -21,6 +21,7 @@ static void eap_tls_deinit(struct eap_sm *sm, void *priv); struct eap_tls_data { struct eap_ssl_data ssl; u8 *key_data; + void *ssl_ctx; }; @@ -40,6 +41,9 @@ static void * eap_tls_init(struct eap_sm *sm) 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 @@ static struct wpabuf * eap_tls_process(struct eap_sm *sm, void *priv, 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 struct wpabuf * eap_tls_process(struct eap_sm *sm, void *priv, 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 52549f448..69e83d9ba 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 + * Copyright (c) 2004-2012, Jouni Malinen * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -136,14 +136,14 @@ static int eap_tls_init_connection(struct eap_sm *sm, { 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 @@ 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); + 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 @@ int eap_peer_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data, 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 @@ 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) { - 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 @@ u8 * eap_peer_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data, 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 @@ u8 * eap_peer_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data, * 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 @@ static int eap_tls_process_input(struct eap_sm *sm, struct eap_ssl_data *data, 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 @@ int eap_peer_tls_process_helper(struct eap_sm *sm, struct eap_ssl_data *data, 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 @@ int eap_peer_tls_reauth_init(struct eap_sm *sm, struct eap_ssl_data *data) { 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 @@ int eap_peer_tls_status(struct eap_sm *sm, struct eap_ssl_data *data, 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 @@ const u8 * eap_peer_tls_process_init(struct eap_sm *sm, 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 @@ int eap_peer_tls_decrypt(struct eap_sm *sm, struct eap_ssl_data *data, 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 @@ int eap_peer_tls_encrypt(struct eap_sm *sm, struct eap_ssl_data *data, { 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 7426467cd..771385bc8 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 + * Copyright (c) 2004-2009, 2012, Jouni Malinen * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -63,6 +63,11 @@ struct eap_ssl_data { * 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; };