Hi All, I successfully tested session resumption of my EAP-TLS and EAP-TTLS clients using FreeRADIUS version 1.1.0. The following files were modified to make session resumption work. freeradius-1.1.0/src/modules/rlm_eap/types/rlm_eap_tls/tls.c , freeradius-1.1.0/src/modules/rlm_eap/types/rlm_eap_tls/eap_tls.c and freeradius-1.1.0/src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.c. Here is the patch to be applied to freeRADIUS 1.1.0 to make fast re-authentication work. diff -Naur freeradius-1.1.0/src/modules/rlm_eap/types/rlm_eap_tls/eap_tls.c freeradius-1.1.0_reauth/src/modules/rlm_eap/types/rlm_eap_tls/eap_tls.c --- freeradius-1.1.0/src/modules/rlm_eap/types/rlm_eap_tls/eap_tls.c 2004-09-02 01:00:48.000000000 +0530 +++ freeradius-1.1.0_reauth/src/modules/rlm_eap/types/rlm_eap_tls/eap_tls.c 2007-11-01 09:49:09.000000000 +0530 @@ -609,43 +609,61 @@ static void eaptls_operation(EAPTLS_PACKET *eaptls_packet UNUSED, eaptls_status_t status, EAP_HANDLER *handler) { - tls_session_t *tls_session; + int ret = 0; + tls_session_t *tls_session; - tls_session = (tls_session_t *)handler->opaque; + tls_session = (tls_session_t *)handler->opaque; - if ((status == EAPTLS_MORE_FRAGMENTS) || - (status == EAPTLS_MORE_FRAGMENTS_WITH_LENGTH) || - (status == EAPTLS_FIRST_FRAGMENT)) { - /* - * Send the ACK. - */ - eaptls_send_ack(handler->eap_ds, tls_session->peap_flag); - } else { - /* - * We have the complete TLS-data or TLS-message. - * - * Clean the dirty message. - * - * Authenticate the user and send - * Success/Failure. - * - * If more info - * is required then send another request. */ - if (tls_handshake_recv(tls_session)) { - /* - * FIXME: return success/fail. - * - * TLS proper can decide what to do, then. - */ - eaptls_request(handler->eap_ds, tls_session); - } else { - eaptls_fail(handler->eap_ds, tls_session->peap_flag); - } - } - return; + if ((status == EAPTLS_MORE_FRAGMENTS) || + (status == EAPTLS_MORE_FRAGMENTS_WITH_LENGTH) || + (status == EAPTLS_FIRST_FRAGMENT)) + { + /* + * Send the ACK. + */ + eaptls_send_ack(handler->eap_ds, tls_session->peap_flag); + } + else + { + /* + * We have the complete TLS-data or TLS-message. + * + * Clean the dirty message. + * + * Authenticate the user and send + * Success/Failure. + * + * If more info + * is required then send another request. */ + ret = tls_handshake_recv(tls_session); + /* + * TLS returns 1 on normal case. + * 7 (it can be any value otherthan 0 and 1. TLS should know this value) + * on fast re-auth completion. + */ + if (1 == ret) + { + eaptls_request(handler->eap_ds, tls_session); + } + else if(7 == ret) + { + /* + * Success: Return MPPE keys. + */ + eaptls_success(handler->eap_ds, 0); + eaptls_gen_mppe_keys(&handler->request->reply->vps, + tls_session->ssl, + "client EAP encryption"); + + } + else + { + eaptls_fail(handler->eap_ds, tls_session->peap_flag); + } + } + return; } - /* * In the actual authentication first verify the packet and then create the data structure */ @@ -778,6 +796,7 @@ { uint8_t *ptr; + /* * Don't set eap_ds->request->type.type, as the main EAP * handler will do that for us. This allows the TLS @@ -820,6 +839,7 @@ break; case EAPTLS_SUCCESS: eap_ds->request->code = PW_EAP_SUCCESS; + break; case EAPTLS_FAIL: eap_ds->request->code = PW_EAP_FAILURE; diff -Naur freeradius-1.1.0/src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.c freeradius-1.1.0_reauth/src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.c --- freeradius-1.1.0/src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.c 2005-12-15 05:36:26.000000000 +0530 +++ freeradius-1.1.0_reauth/src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.c 2007-11-01 09:49:12.000000000 +0530 @@ -503,6 +503,7 @@ DEBUG2(" rlm_eap_tls: Authenticate"); + status = eaptls_process(handler); DEBUG2(" eaptls_process returned %d\n", status); switch (status) { @@ -546,6 +547,7 @@ } #endif + printf("CALLING FAIL in authenticate.\n"); eaptls_fail(handler->eap_ds, 0); return 0; break; @@ -564,6 +566,7 @@ eaptls_gen_mppe_keys(&handler->request->reply->vps, tls_session->ssl, "client EAP encryption"); + return 1; } diff -Naur freeradius-1.1.0/src/modules/rlm_eap/types/rlm_eap_tls/tls.c freeradius-1.1.0_reauth/src/modules/rlm_eap/types/rlm_eap_tls/tls.c --- freeradius-1.1.0/src/modules/rlm_eap/types/rlm_eap_tls/tls.c 2004-02-27 00:34:31.000000000 +0530 +++ freeradius-1.1.0_reauth/src/modules/rlm_eap/types/rlm_eap_tls/tls.c 2007-11-01 09:49:10.000000000 +0530 @@ -22,11 +22,24 @@ */ #include "eap_tls.h" +static long ctx_num = 0; + tls_session_t *eaptls_new_session(SSL_CTX *ssl_ctx, int client_cert) { tls_session_t *state = NULL; SSL *new_tls = NULL; int verify_mode = SSL_VERIFY_NONE; + int ret = 0; + + if(0 == ctx_num++) + { + ret = SSL_CTX_set_session_id_context(ssl_ctx, + (const unsigned char *)&ctx_num, sizeof(long)); + if(!ret) + { + printf("FR : pblm in set session id context\n"); + } + } if ((new_tls = SSL_new(ssl_ctx)) == NULL) { radlog(L_ERR, "rlm_eap_tls: Error creating new SSL"); @@ -39,9 +52,14 @@ state = (tls_session_t *)malloc(sizeof(*state)); memset(state, 0, sizeof(*state)); + + SSL_CTX_set_session_cache_mode(ssl_ctx, SSL_SESS_CACHE_NO_AUTO_CLEAR|SSL_SESS_CACHE_SERVER); + session_init(state); state->ssl = new_tls; + state->ssl->new_session = 1; + /* * Create & hook the BIOs to handle the dirty side of the * SSL. This is *very important* as we want to handle @@ -83,6 +101,8 @@ return state; } + + /* * Print out some text describing the error. */ @@ -169,7 +189,8 @@ } /* Some Extra STATE information for easy debugging */ - if (SSL_is_init_finished(ssn->ssl)) { + if (SSL_is_init_finished(ssn->ssl)) + { DEBUG2("SSL Connection Established\n"); } if (SSL_in_init(ssn->ssl)) { @@ -185,6 +206,18 @@ DEBUG2("In SSL Connect mode \n"); } + if (SSL_is_init_finished(ssn->ssl) && 1 == ssn->ssl->hit) + { + /* Session Resumption : CCS and Finish received, parsed + * and validated successfully. Time to wind up handshake. */ + record_init(&ssn->dirty_in); + + /* This can return any value otherthan 0 and 1. Check for + * this ret value in the lower layer for reauth completion */ + return 7; + + } + if (ssn->info.content_type != application_data) { err = BIO_read(ssn->from_ssl, ssn->dirty_out.data, sizeof(ssn->dirty_out.data)); @@ -260,8 +293,19 @@ void session_close(tls_session_t *ssn) { + int index = 0; + static int flag = 0; + int ret = 0; + SSL *ssl_bk = ssn->ssl; + SSL_SESSION *pSession; + pSession = malloc(sizeof(SSL_SESSION)); + + if(ssn->ssl) + { + SSL_shutdown(ssn->ssl); SSL_free(ssn->ssl); + } #if 0 /* * WARNING: SSL_free seems to decrement the reference counts already, @@ -271,11 +315,11 @@ BIO_free(ssn->into_ssl); if(ssn->from_ssl) BIO_free(ssn->from_ssl); -#endif record_close(&ssn->clean_in); record_close(&ssn->clean_out); record_close(&ssn->dirty_in); record_close(&ssn->dirty_out); +#endif session_init(ssn); } Thanks and Regards, -Sujith ----- Original Message ----- From: "Alan DeKok" <aland@deployingradius.com> To: "FreeRadius developers mailing list" <freeradius-devel@lists.freeradius.org> Sent: Wednesday, October 17, 2007 7:27 PM Subject: Re: Testing EAP-TLS session resumption
sujithsankar wrote:
I am working on EAP-TLS client. The normal functionality testing was done by interoperating with FreeRADIUS.
Now, I would like to test fast re-authentication feature of my EAP-TLS client. It is learnt that FreeRADIUS does not support this feature.
Has anyone of you tried to test such a feature?
I haven't tested it.
Does anyone know about any patch for FreeRADIUS to support session resumption?
Nope. Feel free to send a patch, if you figure out how to get it to work.
Alan DeKok. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/devel.html
The information contained in this electronic message and any attachments to this message are intended for the exclusive use of the addressee(s) and may contain proprietary, confidential or privileged information. If you are not the intended recipient, you should not disseminate, distribute or copy this e-mail. Please notify the sender immediately and destroy all copies of this message and any attachments contained in it. Contact your Administrator for further information.