2
2
* rlm_eap_tls.c contains the interfaces that are called from eap
4
* Version: $Id: rlm_eap_tls.c,v 1.54 2008/03/22 08:31:03 aland Exp $
6
6
* This program is free software; you can redistribute it and/or modify
7
7
* it under the terms of the GNU General Public License as published by
38
38
#include <sys/stat.h>
41
static CONF_PARSER cache_config[] = {
42
{ "enable", PW_TYPE_BOOLEAN,
43
offsetof(EAP_TLS_CONF, session_cache_enable), NULL, "no" },
44
{ "lifetime", PW_TYPE_INTEGER,
45
offsetof(EAP_TLS_CONF, session_timeout), NULL, "24" },
46
{ "max_entries", PW_TYPE_INTEGER,
47
offsetof(EAP_TLS_CONF, session_cache_size), NULL, "255" },
48
{ "name", PW_TYPE_STRING_PTR,
49
offsetof(EAP_TLS_CONF, session_id_name), NULL, NULL},
50
{ NULL, -1, 0, NULL, NULL } /* end the list */
41
53
static CONF_PARSER module_config[] = {
42
54
{ "rsa_key_exchange", PW_TYPE_BOOLEAN,
43
55
offsetof(EAP_TLS_CONF, rsa_key), NULL, "no" },
80
92
{ "make_cert_command", PW_TYPE_STRING_PTR,
81
93
offsetof(EAP_TLS_CONF, make_cert_command), NULL, NULL},
95
{ "cache", PW_TYPE_SUBSECTION, 0, NULL, (const void *) cache_config },
83
97
{ NULL, -1, 0, NULL, NULL } /* end the list */
134
* Generate ephemeral RSA keys.
136
static int generate_eph_rsa_key(SSL_CTX *ctx)
140
rsa = RSA_generate_key(512, RSA_F4, NULL, NULL);
142
if (!SSL_CTX_set_tmp_rsa(ctx, rsa)) {
143
radlog(L_ERR, "rlm_eap_tls: Couldn't set ephemeral RSA key");
153
* These functions don't do anything other than print debugging
156
* FIXME: Write sessions to some long-term storage, so that
157
* session resumption can still occur after the server
160
#define MAX_SESSION_SIZE (256)
162
static void cbtls_remove_session(UNUSED SSL_CTX *ctx, SSL_SESSION *sess)
165
char buffer[2 * MAX_SESSION_SIZE + 1];
167
size = sess->session_id_length;
168
if (size > MAX_SESSION_SIZE) size = MAX_SESSION_SIZE;
170
fr_bin2hex(sess->session_id, buffer, size);
172
DEBUG2(" SSL: Removing session %s from the cache", buffer);
173
SSL_SESSION_free(sess);
178
static int cbtls_new_session(UNUSED SSL *s, SSL_SESSION *sess)
181
char buffer[2 * MAX_SESSION_SIZE + 1];
183
size = sess->session_id_length;
184
if (size > MAX_SESSION_SIZE) size = MAX_SESSION_SIZE;
186
fr_bin2hex(sess->session_id, buffer, size);
188
DEBUG2(" SSL: adding session %s to cache", buffer);
193
static SSL_SESSION *cbtls_get_session(UNUSED SSL *s,
194
unsigned char *data, int len,
198
char buffer[2 * MAX_SESSION_SIZE + 1];
201
if (size > MAX_SESSION_SIZE) size = MAX_SESSION_SIZE;
203
fr_bin2hex(data, buffer, size);
205
DEBUG2(" SSL: Client requested nonexistent cached session %s",
119
212
* Before trusting a certificate, you must make sure that the
120
213
* certificate is 'valid'. There are several steps that your
170
264
ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
171
265
handler = (EAP_HANDLER *)SSL_get_ex_data(ssl, 0);
266
request = handler->request;
172
267
conf = (EAP_TLS_CONF *)SSL_get_ex_data(ssl, 1);
239
334
/* if this fails, fail the verification */
242
DEBUG2(" rlm_eap_tls: checking certificate CN (%s) with xlat'ed value (%s)", common_name, cn_str);
337
RDEBUG2("checking certificate CN (%s) with xlat'ed value (%s)", common_name, cn_str);
243
338
if (strcmp(cn_str, common_name) != 0) {
244
339
radlog(L_AUTH, "rlm_eap_tls: Certificate CN (%s) does not match specified value (%s)!", common_name, cn_str);
249
344
} /* depth == 0 */
251
346
if (debug_flag > 0) {
252
DEBUG2("chain-depth=%d, ", depth);
253
DEBUG2("error=%d", err);
347
RDEBUG2("chain-depth=%d, ", depth);
348
RDEBUG2("error=%d", err);
255
DEBUG2("--> User-Name = %s", handler->identity);
256
DEBUG2("--> BUF-Name = %s", common_name);
257
DEBUG2("--> subject = %s", subject);
258
DEBUG2("--> issuer = %s", issuer);
259
DEBUG2("--> verify return:%d", my_ok);
350
RDEBUG2("--> User-Name = %s", handler->identity);
351
RDEBUG2("--> BUF-Name = %s", common_name);
352
RDEBUG2("--> subject = %s", subject);
353
RDEBUG2("--> issuer = %s", issuer);
354
RDEBUG2("--> verify return:%d", my_ok);
361
* Free cached session data, which is always a list of VALUE_PAIRs
363
static void eaptls_session_free(UNUSED void *parent, void *data_ptr,
364
UNUSED CRYPTO_EX_DATA *ad, UNUSED int idx,
365
UNUSED long argl, UNUSED void *argp)
367
VALUE_PAIR *vp = data_ptr;
368
if (!data_ptr) return;
266
375
* Create Global context SSL and use it in every new session
268
377
* - Load the trusted CAs
330
439
/* Load the CAs we trust */
331
if (!SSL_CTX_load_verify_locations(ctx, conf->ca_file, conf->ca_path)) {
332
radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL));
333
radlog(L_ERR, "rlm_eap_tls: Error reading Trusted root CA list %s",conf->ca_file );
440
if (conf->ca_file || conf->ca_path) {
441
if (!SSL_CTX_load_verify_locations(ctx, conf->ca_file, conf->ca_path)) {
442
radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL));
443
radlog(L_ERR, "rlm_eap_tls: Error reading Trusted root CA list %s",conf->ca_file );
336
447
if (conf->ca_file && *conf->ca_file) SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(conf->ca_file));
337
448
if (!(SSL_CTX_use_PrivateKey_file(ctx, conf->private_key_file, type))) {
393
504
SSL_CTX_set_info_callback(ctx, cbtls_info);
507
* Callbacks, etc. for session resumption.
509
if (conf->session_cache_enable) {
510
SSL_CTX_sess_set_new_cb(ctx, cbtls_new_session);
511
SSL_CTX_sess_set_get_cb(ctx, cbtls_get_session);
512
SSL_CTX_sess_set_remove_cb(ctx, cbtls_remove_session);
514
SSL_CTX_set_quiet_shutdown(ctx, 1);
396
518
* Check the certificates for revocation.
398
520
#ifdef X509_V_FLAG_CRL_CHECK
563
* Setup session caching
565
if (conf->session_cache_enable) {
567
* Create a unique context Id per EAP-TLS configuration.
569
if (conf->session_id_name) {
570
snprintf(conf->session_context_id,
571
sizeof(conf->session_context_id),
572
"FreeRADIUS EAP-TLS %s",
573
conf->session_id_name);
575
snprintf(conf->session_context_id,
576
sizeof(conf->session_context_id),
577
"FreeRADIUS EAP-TLS %p", conf);
581
* Cache it, and DON'T auto-clear it.
583
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER | SSL_SESS_CACHE_NO_AUTO_CLEAR);
585
SSL_CTX_set_session_id_context(ctx,
586
(unsigned char *) conf->session_context_id,
587
(unsigned int) strlen(conf->session_context_id));
590
* Our timeout is in hours, this is in seconds.
592
SSL_CTX_set_timeout(ctx, conf->session_timeout * 3600);
595
* Set the maximum number of entries in the
598
SSL_CTX_sess_set_cache_size(ctx, conf->session_cache_size);
601
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
605
* Register the application indices. We can't use
606
* hard-coded "0" and "1" as before, because we need to
607
* set up a "free" handler for the cached session
610
if (eaptls_handle_idx < 0) {
611
eaptls_handle_idx = SSL_get_ex_new_index(0, "eaptls_handle_idx",
615
if (eaptls_conf_idx < 0) {
616
eaptls_conf_idx = SSL_get_ex_new_index(0, "eaptls_conf_idx",
620
if (eaptls_session_idx < 0) {
621
eaptls_session_idx = SSL_get_ex_new_index(0, "eaptls_session_idx",
623
eaptls_session_free);
598
788
int client_cert = TRUE;
599
789
int verify_mode = 0;
790
REQUEST *request = handler->request;
601
792
inst = (eap_tls_t *)type_arg;
795
* Manually flush the sessions every so often. If HALF
796
* of the session lifetime has passed since we last
797
* flushed, then flush it again.
799
* FIXME: Also do it every N sessions?
801
if (inst->conf->session_cache_enable &&
802
((inst->conf->session_last_flushed + (inst->conf->session_timeout * 1800)) <= request->timestamp)) {
803
RDEBUG2("Flushing SSL sessions (of #%ld)",
804
SSL_CTX_sess_number(inst->ctx));
806
SSL_CTX_flush_sessions(inst->ctx, request->timestamp);
807
inst->conf->session_last_flushed = request->timestamp;
604
811
* If we're TTLS or PEAP, then do NOT require a client
632
839
* Verify the peer certificate, if asked.
634
841
if (client_cert) {
635
DEBUG2(" rlm_eap_tls: Requiring client certificate");
842
RDEBUG2("Requiring client certificate");
636
843
verify_mode = SSL_VERIFY_PEER;
637
844
verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
638
845
verify_mode |= SSL_VERIFY_CLIENT_ONCE;
685
892
handler->opaque = ((void *)ssn);
686
893
handler->free_opaque = session_free;
688
DEBUG2(" rlm_eap_tls: Initiate");
691
* PEAP-specific breakage.
898
* Set up type-specific information.
693
if (handler->eap_type == PW_EAP_PEAP) {
900
switch (handler->eap_type) {
903
ssn->prf_label = "client EAP encryption";
907
ssn->prf_label = "ttls keying material";
911
* PEAP-specific breakage.
695
915
* As it is a poorly designed protocol, PEAP uses
696
916
* bits in the TLS header to indicate PEAP
715
942
* related handshaking or application data.
717
944
status = eaptls_start(handler->eap_ds, ssn->peap_flag);
718
DEBUG2(" rlm_eap_tls: Start returned %d", status);
945
RDEBUG2("Start returned %d", status);
731
958
* Do authentication, by letting EAP-TLS do most of the work.
733
static int eaptls_authenticate(void *arg UNUSED, EAP_HANDLER *handler)
960
static int eaptls_authenticate(void *arg, EAP_HANDLER *handler)
735
962
eaptls_status_t status;
736
963
tls_session_t *tls_session = (tls_session_t *) handler->opaque;
964
REQUEST *request = handler->request;
965
eap_tls_t *inst = (eap_tls_t *) arg;
738
DEBUG2(" rlm_eap_tls: Authenticate");
967
RDEBUG2("Authenticate");
740
969
status = eaptls_process(handler);
741
DEBUG2(" eaptls_process returned %d\n", status);
970
RDEBUG2("eaptls_process returned %d\n", status);
742
971
switch (status) {
744
973
* EAP-TLS handshake was successful, return an
783
eaptls_fail(handler->eap_ds, 0);
1012
eaptls_fail(handler, 0);
788
1017
* Anything else: fail.
1019
* Also, remove the session from the cache so that
1020
* the client can't re-use it.
1023
if (inst->conf->session_cache_enable) {
1024
SSL_CTX_remove_session(inst->ctx,
1025
tls_session->ssl->session);
795
* Success: Return MPPE keys.
797
eaptls_success(handler->eap_ds, 0);
798
eaptls_gen_mppe_keys(&handler->request->reply->vps,
800
"client EAP encryption");
1032
* New sessions cause some additional information to be
1035
if (!SSL_session_reused(tls_session->ssl)) {
1037
* FIXME: Store miscellaneous data.
1039
RDEBUG2("Adding user data to cached session");
1042
SSL_SESSION_set_ex_data(tls_session->ssl->session,
1043
ssl_session_idx_user_session, session_data);
1047
* FIXME: Retrieve miscellaneous data.
1050
data = SSL_SESSION_get_ex_data(tls_session->ssl->session,
1051
ssl_session_idx_user_session);
1053
if (!session_data) {
1054
radlog_request(L_ERR, 0, request,
1055
"No user session data in cached session - "
1061
RDEBUG2("Retrieved session data from cached session");
1065
* Success: Automatically return MPPE keys.
1067
return eaptls_success(handler, 0);