From 1a10cbf69b07b049e1e452b63d1fb333650b10ac Mon Sep 17 00:00:00 2001 From: Mike Ross Date: Sun, 15 Aug 2010 15:49:46 -0700 Subject: [PATCH] Added option for certificate logging to EAP TLS authentication --- raddb/eap.conf | 9 ++ .../rlm_eap/types/rlm_eap_tls/rlm_eap_tls.c | 97 ++++++++++++++++++- .../rlm_eap/types/rlm_eap_tls/rlm_eap_tls.h | 3 + 3 files changed, 103 insertions(+), 6 deletions(-) diff --git a/raddb/eap.conf b/raddb/eap.conf index 75098b1..cf31708 100644 --- a/raddb/eap.conf +++ b/raddb/eap.conf @@ -249,6 +249,15 @@ # # check_cert_cn = %{User-Name} # + + # + # If log_certificates is set, the Issuer, + # Serial Number, Expiration Date, and + # Subject of the client certificate are + # written to the log file. + # + # log_certificates = yes + # Set this option to specify the allowed # TLS cipher suites. The format is listed # in "man 1 ciphers". diff --git a/src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.c b/src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.c index 11ed96a..466df22 100644 --- a/src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.c +++ b/src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.c @@ -20,6 +20,7 @@ * Copyright 2001 hereUare Communications, Inc. * Copyright 2003 Alan DeKok * Copyright 2006 The FreeRADIUS server project + * Copyright 2010 The Boeing Company * */ @@ -94,6 +95,8 @@ static CONF_PARSER module_config[] = { offsetof(EAP_TLS_CONF, cipher_list), NULL, NULL}, { "check_cert_issuer", PW_TYPE_STRING_PTR, offsetof(EAP_TLS_CONF, check_cert_issuer), NULL, NULL}, + { "log_certificates", PW_TYPE_BOOLEAN, + offsetof(EAP_TLS_CONF, log_certificates), NULL, "no" }, { "make_cert_command", PW_TYPE_STRING_PTR, offsetof(EAP_TLS_CONF, make_cert_command), NULL, NULL}, @@ -102,6 +105,77 @@ static CONF_PARSER module_config[] = { { NULL, -1, 0, NULL, NULL } /* end the list */ }; +/* + * + * Write the certificate serial number, expiration + * date, issuer, and subject to the log file + */ +static int log_full_cert(int ok, X509 *cert) +{ + const int ub_serial = 20; + const int ub_time = 15; + + char serialNumber[2*ub_serial+1]; + char expiration[ub_time+1]; + char issuer[ub_name+1]; + char subject[ub_name+1]; + char *pTemp = NULL; + int local_ok = ok; + int i = 0; + ASN1_INTEGER *pSn = NULL; + ASN1_TIME *pTime = NULL; + + /* + * Get the Serial Number and format for display + */ + serialNumber[0] = '\0'; + pSn = X509_get_serialNumber(cert); + pTemp = serialNumber; + if ( pSn == NULL || pSn->length > ub_serial ) { + radlog(L_AUTH, "rlm_eap_tls: Malformed Certificate Serial Number"); + local_ok = 0; + } else { + for (i = 0; i < pSn->length; i++) { + sprintf(pTemp, "%02x", (int)pSn->data[i]); + pTemp += 2; + } + } + + /* + * Get the Expiration Date and format for display + */ + expiration[0] = '\0'; + pTime = X509_get_notAfter(cert); + if ( pTime == NULL || pTime->length > ub_time ) { + radlog(L_AUTH, "rlm_eap_tls: Malformed Certificate Expiration"); + local_ok = 0; + } else { + strncpy(expiration, (char*) pTime->data, pTime->length); + expiration[pTime->length] = '\0'; + } + + /* + * Get the Issuer + */ + issuer[0] = '\0'; + X509_NAME_oneline(X509_get_issuer_name(cert), issuer, + ub_name); + + /* + * Get the Subject + */ + subject[0] = '\0'; + X509_NAME_oneline(X509_get_subject_name(cert), subject, + ub_name); + + /* + * Log required attributes + */ + radlog(L_AUTH, "Certificate: Serial=%s; Expiration=%s; Issuer:%s; Subject:%s", + serialNumber, expiration, issuer, subject); + + return local_ok; +} /* * TODO: Check for the type of key exchange * like conf->dh_key @@ -256,12 +330,6 @@ static int cbtls_verify(int ok, X509_STORE_CTX *ctx) err = X509_STORE_CTX_get_error(ctx); depth = X509_STORE_CTX_get_error_depth(ctx); - if (!my_ok) { - radlog(L_ERR,"--> verify error:num=%d:%s\n",err, - X509_verify_cert_error_string(err)); - return my_ok; - } - /* * Retrieve the pointer to the SSL of the connection currently treated * and the application specific data stored into the SSL object. @@ -271,6 +339,15 @@ static int cbtls_verify(int ok, X509_STORE_CTX *ctx) request = handler->request; conf = (EAP_TLS_CONF *)SSL_get_ex_data(ssl, 1); + if (!my_ok) { + radlog(L_ERR,"--> verify error:num=%d:%s\n",err, + X509_verify_cert_error_string(err)); + if (conf->log_certificates) { + log_full_cert(my_ok, client_cert); + } + return my_ok; + } + /* * Get the Subject & Issuer */ @@ -346,6 +423,14 @@ static int cbtls_verify(int ok, X509_STORE_CTX *ctx) } } } /* check_cert_cn */ + + /* + * If the conf telss us to, log the certificate + */ + if (conf->log_certificates) { + my_ok = log_full_cert(my_ok, client_cert); + } + } /* depth == 0 */ if (debug_flag > 0) { diff --git a/src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.h b/src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.h index 470dbcd..7846d1e 100644 --- a/src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.h +++ b/src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.h @@ -20,6 +20,8 @@ * Copyright 2001 hereUare Communications, Inc. * Copyright 2003 Alan DeKok * Copyright 2006 The FreeRADIUS server project + * Copyright 2010 The Boeing Company + * */ #ifndef _RLM_EAP_TLS_H #define _RLM_EAP_TLS_H @@ -59,6 +61,7 @@ typedef struct eap_tls_conf { char *check_cert_cn; char *cipher_list; char *check_cert_issuer; + int log_certificates; int session_cache_enable; int session_timeout; -- 1.7.0.4