*/
EAPTLS_PACKET *eaptls_alloc(void)
{
- EAPTLS_PACKET *rp;
-
- if ((rp = malloc(sizeof(EAPTLS_PACKET))) == NULL) {
- radlog(L_ERR, "rlm_eap_tls: out of memory");
- return NULL;
- }
- memset(rp, 0, sizeof(EAPTLS_PACKET));
- return rp;
+ EAPTLS_PACKET *rp;
+
+ if ((rp = malloc(sizeof(EAPTLS_PACKET))) == NULL) {
+ radlog(L_ERR, "rlm_eap_tls: out of memory");
+ return NULL;
+ }
+ memset(rp, 0, sizeof(EAPTLS_PACKET));
+ return rp;
}
/*
*/
void eaptls_free(EAPTLS_PACKET **eaptls_packet_ptr)
{
- EAPTLS_PACKET *eaptls_packet;
+ EAPTLS_PACKET *eaptls_packet;
- if (!eaptls_packet_ptr) return;
- eaptls_packet = *eaptls_packet_ptr;
- if (eaptls_packet == NULL) return;
+ if (!eaptls_packet_ptr) return;
+ eaptls_packet = *eaptls_packet_ptr;
+ if (eaptls_packet == NULL) return;
- if (eaptls_packet->data) {
+ if (eaptls_packet->data) {
free(eaptls_packet->data);
eaptls_packet->data = NULL;
}
- *eaptls_packet_ptr = NULL;
+ *eaptls_packet_ptr = NULL;
}
/*
{
EAPTLS_PACKET reply;
-
reply.code = EAPTLS_START;
reply.id = eap_ds->response->id + 1/*Incrementor*/;
reply.length = TLS_HEADER_LEN + 1/*flags*/;
reply.data = NULL;
reply.dlen = 0;
- eaptls_compose(eap_ds, &reply);
+ eaptls_compose(eap_ds, &reply);
return 1;
}
{
EAPTLS_PACKET reply;
-
reply.code = EAPTLS_SUCCESS;
reply.id = eap_ds->response->id + 1;
reply.length = TLS_HEADER_LEN;
reply.data = NULL;
reply.dlen = 0;
- eaptls_compose(eap_ds, &reply);
+ eaptls_compose(eap_ds, &reply);
return 1;
}
{
EAPTLS_PACKET reply;
-
reply.code = EAPTLS_FAIL;
reply.id = eap_ds->response->id + 1;
reply.length = TLS_HEADER_LEN;
reply.data = NULL;
reply.dlen = 0;
- eaptls_compose(eap_ds, &reply);
+ eaptls_compose(eap_ds, &reply);
return 1;
}
memcpy(reply.data, &nlen, 4/*TLS-Length*/);
record_minus(&ssn->dirty_out, reply.data+4/*TLS-Length*/, size);
- eaptls_compose(eap_ds, &reply);
+ eaptls_compose(eap_ds, &reply);
free(reply.data);
return 1;
switch (tls_session->info.content_type) {
- case alert :
+ case alert:
eaptls_fail(handler->eap_ds);
session_free(&handler->opaque);
if(handler->opaque) printf("OPAQUE IS NOT NULL\n");
if(handler->opaque) printf("OPAQUE IS NOT NULL\n");
//handler->free_opaque = NULL;
return EAPTLS_SUCCESS;
+ } else {
+ /* Fragmentation handler, send next fragment */
+ eaptls_request(handler->eap_ds, tls_session);
+ return EAPTLS_REQUEST;
}
- return EAPTLS_NOOP;
default:
- /* Fragmentation handler, send next fragment */
- eaptls_request(handler->eap_ds, tls_session);
- return EAPTLS_REQUEST;
+ radlog(L_ERR, "rlm_eap_tls: Should never enter here\n");
+ return EAPTLS_NOOP;
}
}
reply.data = NULL;
reply.dlen = 0;
- eaptls_compose(eap_ds, &reply);
+ eaptls_compose(eap_ds, &reply);
return 1;
}
*/
eaptls_status_t eaptls_verify(EAP_DS *eap_ds, EAP_DS *prev_eap_ds)
{
- eaptls_packet_t *eaptls_packet, *eaptls_prev;
+ eaptls_packet_t *eaptls_packet, *eaptls_prev;
if ((eap_ds == NULL) ||
(eap_ds->response == NULL) ||
(eap_ds->response->length < EAP_HEADER_LEN) ||
(eap_ds->response->type.type != PW_EAP_TLS)) {
- radlog(L_ERR, "rlm_eap_tls: corrupted data");
+ radlog(L_ERR, "rlm_eap_tls: corrupted data");
return EAPTLS_INVALID;
}
/* FIXME: check for nulls before assigning */
- eaptls_packet = (eaptls_packet_t *)eap_ds->response->type.data;
- eaptls_prev = (eaptls_packet_t *)prev_eap_ds->response->type.data;
+ eaptls_packet = (eaptls_packet_t *)eap_ds->response->type.data;
+ eaptls_prev = (eaptls_packet_t *)prev_eap_ds->response->type.data;
/*
* check for ACK
* (It is because Last fragment will not have M bit set)
*/
if ((prev_eap_ds->response == NULL) ||
- (TLS_MORE_FRAGMENTS(eaptls_prev->flags) == 0)) {
+ (eaptls_prev == NULL) ||
+ (TLS_MORE_FRAGMENTS(eaptls_prev->flags) == 0)) {
radlog(L_INFO, "rlm_eap_tls: Received EAP-TLS First Fragment of the message");
return EAPTLS_FIRST_FRAGMENT;
* code = EAP-code
* id = EAP-id
* length = code + id + length + flags + tlsdata
- * = 1 + 1 + 2 + 1 + X
+ * = 1 + 1 + 2 + 1 + X
* length = EAP-length - 1(EAP-Type = 1 octet)
* flags = EAP-typedata[0] (1 octet)
* dlen = EAP-typedata[1-4] (4 octets), if L flag set
- * = length - 5(code+id+length+flags), otherwise
+ * = length - 5(code+id+length+flags), otherwise
* data = EAP-typedata[5-n], if L flag set
- * = EAP-typedata[1-n], otherwise
+ * = EAP-typedata[1-n], otherwise
* packet = EAP-typedata (complete typedata)
*
* Points to consider during EAP-TLS data extraction
*/
EAPTLS_PACKET *eaptls_extract(EAP_DS *eap_ds, eaptls_status_t status)
{
- EAPTLS_PACKET *tlspacket;
- uint32_t data_len;
+ EAPTLS_PACKET *tlspacket;
+ uint32_t data_len = 0;
uint8_t *data = NULL;
if (status == EAPTLS_INVALID)
* but eaptls_length = eap_length - 1(EAP-Type = 1 octet)
*
* length = code + id + length + flags + tlsdata
- * = 1 + 1 + 2 + 1 + X
+ * = 1 + 1 + 2 + 1 + X
*/
tlspacket->code = eap_ds->response->code;
tlspacket->id = eap_ds->response->id;
tlspacket->flags = eap_ds->response->type.data[0];
}
-
switch (status) {
/*
The TLS Message Length field is
break;
default:
- printf("Should never enter here\n");
+ radlog(L_ERR, "rlm_eap_tls: Should never enter here\n");
break;
}
* CAUTION while reinitializing this buffer.
* It should be reinitialized only when this M bit is NOT set.
*/
- record_plus(&tls_session->dirty_in, eaptls_packet->data, eaptls_packet->dlen);
+ if (eaptls_packet->dlen !=
+ record_plus(&tls_session->dirty_in, eaptls_packet->data, eaptls_packet->dlen)) {
+ radlog(L_ERR, "rlm_eap_tls: Exceeded maximum record size");
+ return;
+ }
- /* send the next fragment */
+ /* send the next fragment */
/*
if (status == EAPTLS_ACK) {
eaptls_request(handler->eap_ds, tls_session);
static CONF_PARSER module_config[] = {
{ "private_key_file", PW_TYPE_STRING_PTR, offsetof(EAP_TLS_CONF, private_key_file), NULL, "priv_key.pem" },
{ "certificate_file", PW_TYPE_STRING_PTR, offsetof(EAP_TLS_CONF, certificate_file), NULL, "certificate.pem" },
+ { "CA_file", PW_TYPE_STRING_PTR, offsetof(EAP_TLS_CONF, ca_file), NULL, "ca_list.pem" },
{ "private_key_password", PW_TYPE_STRING_PTR, offsetof(EAP_TLS_CONF, private_key_password), NULL, "pass" },
{ "dh_file", PW_TYPE_STRING_PTR, offsetof(EAP_TLS_CONF, dh_file), NULL, "dh.pem" },
{ "random_file", PW_TYPE_STRING_PTR, offsetof(EAP_TLS_CONF, random_file), NULL, "random.pem" },
/*
printf(" private_key_file --- %s\n", eaptls->conf->private_key_file);
printf(" certificate_file --- %s\n", eaptls->conf->certificate_file);
+ printf(" CA_file --- %s\n", eaptls->conf->ca_file);
printf(" private_key_password --- %s\n", eaptls->conf->private_key_password);
printf(" dh_file --- %s\n", eaptls->conf->dh_file);
printf(" random_file --- %s\n", eaptls->conf->random_file);
* send that alert to the client and then send the EAP-Failure
*/
- status = eaptls_verify(handler->eap_ds, handler->prev_eapds);
- if (status == EAPTLS_INVALID)
- return 0;
+ status = eaptls_verify(handler->eap_ds, handler->prev_eapds);
+ if (status == EAPTLS_INVALID)
+ return 0;
if (status == EAPTLS_ACK) {
if (eaptls_ack_handler(handler) != EAPTLS_NOOP)
if ((tlspacket = eaptls_extract(handler->eap_ds, status)) == NULL)
return 0;
-
eaptls_operation(tlspacket, status, handler);
return 1;
ctx = SSL_CTX_new(meth);
/* Load our keys and certificates*/
- if(!(SSL_CTX_use_certificate_file(ctx, conf->private_key_file, SSL_FILETYPE_PEM)))
+ if(!(SSL_CTX_use_certificate_file(ctx, conf->certificate_file, SSL_FILETYPE_PEM)))
err_exit("Couldn't read certificate file");
/*
SSL_CTX_set_default_passwd_cb(ctx, password_cb);
if(!(SSL_CTX_use_PrivateKey_file(ctx, conf->private_key_file, SSL_FILETYPE_PEM)))
- err_exit("Couldn't read key file");
+ err_exit("Couldn't read private key file");
/*
* ctx_options
SSL_CTX_set_verify(ctx, verify_mode, NULL);
/* Load the CAs we trust */
- if(!(SSL_CTX_load_verify_locations(ctx, conf->certificate_file, 0)))
- err_exit("Couldn't read CA list");
+ if(!(SSL_CTX_load_verify_locations(ctx, conf->ca_file, 0)))
+ err_exit("Couldn't read Trusted root CA list");
SSL_CTX_set_verify_depth(ctx, 1);
tls_session_t *new_tls_session(eap_tls_t *eaptls)
{
tls_session_t *state = NULL;
- SSL *new_tls = NULL;
+ SSL *new_tls = NULL;
int verify_mode = 0;
- if((new_tls = SSL_new(eaptls->ctx)) == NULL) {
- radlog(L_ERR, "rlm_eap_tls: Error creating new SSL");
- ERR_print_errors_fp(stderr);
- return NULL;
- }
+ if((new_tls = SSL_new(eaptls->ctx)) == NULL) {
+ radlog(L_ERR, "rlm_eap_tls: Error creating new SSL");
+ ERR_print_errors_fp(stderr);
+ return NULL;
+ }
- /* We use the SSL's "app_data" to indicate a call-back */
- SSL_set_app_data(new_tls, NULL);
+ /* We use the SSL's "app_data" to indicate a call-back */
+ SSL_set_app_data(new_tls, NULL);
state = (tls_session_t *)malloc(sizeof(tls_session_t));
session_init(state);
- state->ssl = new_tls;
+ state->ssl = new_tls;
- /*
- * Create & hook the BIOs to handle the dirty side of the SSL
+ /*
+ * Create & hook the BIOs to handle the dirty side of the SSL
* This is *very important* as we want to handle the transmission part.
* Now the only IO interface that SSL is aware of, is our defined BIO buffers.
- */
- state->into_ssl = BIO_new(BIO_s_mem());
- state->from_ssl = BIO_new(BIO_s_mem());
- SSL_set_bio(state->ssl, state->into_ssl, state->from_ssl);
+ */
+ state->into_ssl = BIO_new(BIO_s_mem());
+ state->from_ssl = BIO_new(BIO_s_mem());
+ SSL_set_bio(state->ssl, state->into_ssl, state->from_ssl);
- /*
- * Add the message callback to identify
+ /*
+ * Add the message callback to identify
* what type of message/handshake is passed
- */
+ */
state->bio_type = BIO_new_fp(stdout, BIO_NOCLOSE);
- SSL_set_msg_callback(new_tls, cbtls_msg);
- SSL_set_msg_callback_arg(new_tls, state);
+ SSL_set_msg_callback(new_tls, cbtls_msg);
+ SSL_set_msg_callback_arg(new_tls, state);
SSL_set_info_callback(new_tls, cbtls_info);
/* Always verify the peer certificate */
SSL_set_verify(state->ssl, verify_mode, NULL);
//SSL_set_verify_depth(state->ssl, verify_depth);
- /* In Server mode we only accept. */
- SSL_set_accept_state(state->ssl);
+ /* In Server mode we only accept. */
+ SSL_set_accept_state(state->ssl);
return state;
}