Add OCSP softfail option
[freeradius.git] / src / modules / rlm_eap / types / rlm_eap_tls / rlm_eap_tls.c
1 /*
2  * rlm_eap_tls.c  contains the interfaces that are called from eap
3  *
4  * Version:     $Id$
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU General Public License as published by
8  *   the Free Software Foundation; either version 2 of the License, or
9  *   (at your option) any later version.
10  *
11  *   This program is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *   GNU General Public License for more details.
15  *
16  *   You should have received a copy of the GNU General Public License
17  *   along with this program; if not, write to the Free Software
18  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  * Copyright 2001  hereUare Communications, Inc. <raghud@hereuare.com>
21  * Copyright 2003  Alan DeKok <aland@freeradius.org>
22  * Copyright 2006  The FreeRADIUS server project
23  *
24  */
25
26 #include <freeradius-devel/ident.h>
27 RCSID("$Id$")
28
29 #include <freeradius-devel/autoconf.h>
30
31 #ifdef HAVE_OPENSSL_RAND_H
32 #include <openssl/rand.h>
33 #endif
34
35 #ifdef HAVE_OPENSSL_EVP_H
36 #include <openssl/evp.h>
37 #endif
38
39 #include <openssl/x509.h>
40
41 #include "rlm_eap_tls.h"
42 #include "config.h"
43
44 #ifdef HAVE_SYS_STAT_H
45 #include <sys/stat.h>
46 #endif
47
48 #ifdef HAVE_OPENSSL_OCSP_H
49 #include <openssl/ocsp.h>
50 #endif
51
52 static CONF_PARSER cache_config[] = {
53         { "enable", PW_TYPE_BOOLEAN,
54           offsetof(EAP_TLS_CONF, session_cache_enable), NULL, "no" },
55         { "lifetime", PW_TYPE_INTEGER,
56           offsetof(EAP_TLS_CONF, session_timeout), NULL, "24" },
57         { "max_entries", PW_TYPE_INTEGER,
58           offsetof(EAP_TLS_CONF, session_cache_size), NULL, "255" },
59         { "name", PW_TYPE_STRING_PTR,
60           offsetof(EAP_TLS_CONF, session_id_name), NULL, NULL},
61         { NULL, -1, 0, NULL, NULL }           /* end the list */
62 };
63
64 static CONF_PARSER verify_config[] = {
65         { "tmpdir", PW_TYPE_STRING_PTR,
66           offsetof(EAP_TLS_CONF, verify_tmp_dir), NULL, NULL},
67         { "client", PW_TYPE_STRING_PTR,
68           offsetof(EAP_TLS_CONF, verify_client_cert_cmd), NULL, NULL},
69         { NULL, -1, 0, NULL, NULL }           /* end the list */
70 };
71
72 #ifdef HAVE_OPENSSL_OCSP_H
73 static CONF_PARSER ocsp_config[] = {
74         { "enable", PW_TYPE_BOOLEAN,
75           offsetof(EAP_TLS_CONF, ocsp_enable), NULL, "no"},
76         { "override_cert_url", PW_TYPE_BOOLEAN,
77           offsetof(EAP_TLS_CONF, ocsp_override_url), NULL, "no"},
78         { "url", PW_TYPE_STRING_PTR,
79           offsetof(EAP_TLS_CONF, ocsp_url), NULL, NULL },
80         { "use_nonce", PW_TYPE_BOOLEAN,
81           offsetof(EAP_TLS_CONF, ocsp_use_nonce), NULL, "yes"},
82         { "timeout", PW_TYPE_INTEGER,
83           offsetof(EAP_TLS_CONF, ocsp_timeout), NULL, "0" },
84         { "softfail", PW_TYPE_BOOLEAN,
85           offsetof(EAP_TLS_CONF, ocsp_softfail), NULL, "no"},
86         { NULL, -1, 0, NULL, NULL }           /* end the list */
87 };
88 #endif
89
90 static CONF_PARSER module_config[] = {
91         { "rsa_key_exchange", PW_TYPE_BOOLEAN,
92           offsetof(EAP_TLS_CONF, rsa_key), NULL, "no" },
93         { "dh_key_exchange", PW_TYPE_BOOLEAN,
94           offsetof(EAP_TLS_CONF, dh_key), NULL, "yes" },
95         { "rsa_key_length", PW_TYPE_INTEGER,
96           offsetof(EAP_TLS_CONF, rsa_key_length), NULL, "512" },
97         { "dh_key_length", PW_TYPE_INTEGER,
98           offsetof(EAP_TLS_CONF, dh_key_length), NULL, "512" },
99         { "verify_depth", PW_TYPE_INTEGER,
100           offsetof(EAP_TLS_CONF, verify_depth), NULL, "0" },
101         { "CA_path", PW_TYPE_FILENAME,
102           offsetof(EAP_TLS_CONF, ca_path), NULL, NULL },
103         { "pem_file_type", PW_TYPE_BOOLEAN,
104           offsetof(EAP_TLS_CONF, file_type), NULL, "yes" },
105         { "private_key_file", PW_TYPE_FILENAME,
106           offsetof(EAP_TLS_CONF, private_key_file), NULL, NULL },
107         { "certificate_file", PW_TYPE_FILENAME,
108           offsetof(EAP_TLS_CONF, certificate_file), NULL, NULL },
109         { "CA_file", PW_TYPE_FILENAME,
110           offsetof(EAP_TLS_CONF, ca_file), NULL, NULL },
111         { "private_key_password", PW_TYPE_STRING_PTR,
112           offsetof(EAP_TLS_CONF, private_key_password), NULL, NULL },
113         { "dh_file", PW_TYPE_STRING_PTR,
114           offsetof(EAP_TLS_CONF, dh_file), NULL, NULL },
115         { "random_file", PW_TYPE_STRING_PTR,
116           offsetof(EAP_TLS_CONF, random_file), NULL, NULL },
117         { "fragment_size", PW_TYPE_INTEGER,
118           offsetof(EAP_TLS_CONF, fragment_size), NULL, "1024" },
119         { "include_length", PW_TYPE_BOOLEAN,
120           offsetof(EAP_TLS_CONF, include_length), NULL, "yes" },
121         { "check_crl", PW_TYPE_BOOLEAN,
122           offsetof(EAP_TLS_CONF, check_crl), NULL, "no"},
123         { "allow_expired_crl", PW_TYPE_BOOLEAN,
124           offsetof(EAP_TLS_CONF, allow_expired_crl), NULL, NULL},
125         { "check_cert_cn", PW_TYPE_STRING_PTR,
126           offsetof(EAP_TLS_CONF, check_cert_cn), NULL, NULL},
127         { "cipher_list", PW_TYPE_STRING_PTR,
128           offsetof(EAP_TLS_CONF, cipher_list), NULL, NULL},
129         { "check_cert_issuer", PW_TYPE_STRING_PTR,
130           offsetof(EAP_TLS_CONF, check_cert_issuer), NULL, NULL},
131         { "make_cert_command", PW_TYPE_STRING_PTR,
132           offsetof(EAP_TLS_CONF, make_cert_command), NULL, NULL},
133
134 #if OPENSSL_VERSION_NUMBER >= 0x0090800fL
135 #ifndef OPENSSL_NO_ECDH
136         { "ecdh_curve", PW_TYPE_STRING_PTR,
137           offsetof(EAP_TLS_CONF, ecdh_curve), NULL, "prime256v1"},
138 #endif
139 #endif
140
141         { "cache", PW_TYPE_SUBSECTION, 0, NULL, (const void *) cache_config },
142
143         { "verify", PW_TYPE_SUBSECTION, 0, NULL, (const void *) verify_config },
144
145 #ifdef HAVE_OPENSSL_OCSP_H
146         { "ocsp", PW_TYPE_SUBSECTION, 0, NULL, (const void *) ocsp_config },
147 #endif
148
149         { NULL, -1, 0, NULL, NULL }           /* end the list */
150 };
151
152
153 /*
154  *      TODO: Check for the type of key exchange * like conf->dh_key
155  */
156 static int load_dh_params(SSL_CTX *ctx, char *file)
157 {
158         DH *dh = NULL;
159         BIO *bio;
160
161         if ((bio = BIO_new_file(file, "r")) == NULL) {
162                 radlog(L_ERR, "rlm_eap_tls: Unable to open DH file - %s", file);
163                 return -1;
164         }
165
166         dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
167         BIO_free(bio);
168         if (!dh) {
169                 DEBUG2("WARNING: rlm_eap_tls: Unable to set DH parameters.  DH cipher suites may not work!");
170                 DEBUG2("WARNING: Fix this by running the OpenSSL command listed in eap.conf");
171                 return 0;
172         }
173
174         if (SSL_CTX_set_tmp_dh(ctx, dh) < 0) {
175                 radlog(L_ERR, "rlm_eap_tls: Unable to set DH parameters");
176                 DH_free(dh);
177                 return -1;
178         }
179
180         DH_free(dh);
181         return 0;
182 }
183
184
185 /*
186  *      Generate ephemeral RSA keys.
187  */
188 static int generate_eph_rsa_key(SSL_CTX *ctx)
189 {
190         RSA *rsa;
191
192         rsa = RSA_generate_key(512, RSA_F4, NULL, NULL);
193
194         if (!SSL_CTX_set_tmp_rsa(ctx, rsa)) {
195                 radlog(L_ERR, "rlm_eap_tls: Couldn't set ephemeral RSA key");
196                 return -1;
197         }
198
199         RSA_free(rsa);
200         return 0;
201 }
202
203
204 /*
205  *      FIXME: Write sessions to some long-term storage, so that
206  *             session resumption can still occur after the server
207  *             restarts.
208  */
209 #define MAX_SESSION_SIZE (256)
210
211 static void cbtls_remove_session(UNUSED SSL_CTX *ctx, SSL_SESSION *sess)
212 {
213         size_t size;
214         VALUE_PAIR *vp;
215         char buffer[2 * MAX_SESSION_SIZE + 1];
216
217         size = sess->session_id_length;
218         if (size > MAX_SESSION_SIZE) size = MAX_SESSION_SIZE;
219
220         fr_bin2hex(sess->session_id, buffer, size);
221
222         DEBUG2("  SSL: Removing session %s from the cache", buffer);
223         SSL_SESSION_free(sess);
224
225         return;
226 }
227
228 static int cbtls_new_session(UNUSED SSL *s, SSL_SESSION *sess)
229 {
230         size_t size;
231         char buffer[2 * MAX_SESSION_SIZE + 1];
232
233         size = sess->session_id_length;
234         if (size > MAX_SESSION_SIZE) size = MAX_SESSION_SIZE;
235
236         fr_bin2hex(sess->session_id, buffer, size);
237
238         DEBUG2("  SSL: adding session %s to cache", buffer);
239
240         return 1;
241 }
242
243 static SSL_SESSION *cbtls_get_session(UNUSED SSL *s,
244                                       unsigned char *data, int len,
245                                       UNUSED int *copy)
246 {
247         size_t size;
248         char buffer[2 * MAX_SESSION_SIZE + 1];
249
250         size = len;
251         if (size > MAX_SESSION_SIZE) size = MAX_SESSION_SIZE;
252
253         fr_bin2hex(data, buffer, size);
254
255         DEBUG2("  SSL: Client requested nonexistent cached session %s",
256                buffer);
257
258         return NULL;
259 }
260
261 #ifdef HAVE_OPENSSL_OCSP_H
262 /*
263  * This function extracts the OCSP Responder URL 
264  * from an existing x509 certificate.
265  */
266 static int ocsp_parse_cert_url(X509 *cert, char **phost, char **pport,
267                                char **ppath, int *pssl)
268 {
269         int i;
270         
271         AUTHORITY_INFO_ACCESS *aia;
272         ACCESS_DESCRIPTION *ad;
273         
274         aia = X509_get_ext_d2i(cert, NID_info_access, NULL, NULL);
275
276         for (i = 0; i < sk_ACCESS_DESCRIPTION_num(aia); i++) {
277                 ad = sk_ACCESS_DESCRIPTION_value(aia, 0);
278                 if (OBJ_obj2nid(ad->method) == NID_ad_OCSP) {
279                         if (ad->location->type == GEN_URI) {
280                                 if(OCSP_parse_url(ad->location->d.ia5->data, 
281                                         phost, pport, ppath, pssl))
282                                         return 1;
283                         }
284                 }
285         }
286         return 0;
287 }
288
289 /*
290  * This function sends a OCSP request to a defined OCSP responder
291  * and checks the OCSP response for correctness.
292  */
293
294 /* Maximum leeway in validity period: default 5 minutes */
295 #define MAX_VALIDITY_PERIOD     (5 * 60)
296
297 static int ocsp_check(X509_STORE *store, X509 *issuer_cert, X509 *client_cert,
298                       EAP_TLS_CONF *conf)
299 {
300         OCSP_CERTID *certid;
301         OCSP_REQUEST *req;
302         OCSP_RESPONSE *resp = NULL;
303         OCSP_BASICRESP *bresp = NULL;
304         char *host = NULL;
305         char *port = NULL;
306         char *path = NULL;
307         int use_ssl = -1;
308         long nsec = MAX_VALIDITY_PERIOD, maxage = -1;
309         BIO *cbio, *bio_out;
310         int ocsp_ok = 0;
311         int status ;
312         ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
313         int reason;
314         OCSP_REQ_CTX *ctx;
315         int rc;
316         struct timeval now;
317         struct timeval when;
318
319         /* 
320          * Create OCSP Request 
321          */
322         certid = OCSP_cert_to_id(NULL, client_cert, issuer_cert);
323         req = OCSP_REQUEST_new();
324         OCSP_request_add0_id(req, certid);
325         if(conf->ocsp_use_nonce){
326                 OCSP_request_add1_nonce(req, NULL, 8);
327         }
328         
329         /* 
330          * Send OCSP Request and get OCSP Response
331          */
332
333         /* Get OCSP responder URL */ 
334         if(conf->ocsp_override_url) {
335                 OCSP_parse_url(conf->ocsp_url, &host, &port, &path, &use_ssl);
336         }
337         else {
338                 ocsp_parse_cert_url(client_cert, &host, &port, &path, &use_ssl);
339         }
340         
341         DEBUG2("[ocsp] --> Responder URL = http://%s:%s%s", host, port, path);
342
343         /* Setup BIO socket to OCSP responder */
344         cbio = BIO_new_connect(host);
345
346         bio_out = BIO_new_fp(stdout, BIO_NOCLOSE);
347
348         BIO_set_conn_port(cbio, port);
349
350         if (conf->ocsp_timeout)
351                 BIO_set_nbio(cbio, 1);
352
353         rc = BIO_do_connect(cbio);
354         if ((rc <= 0) && ((!conf->ocsp_timeout) || !BIO_should_retry(cbio))) {
355                 radlog(L_ERR, "Error: Couldn't connect to OCSP responder");
356                 ocsp_ok = 2;
357                 goto ocsp_end;
358         }
359
360         ctx = OCSP_sendreq_new(cbio, path, req, -1);
361         if (!ctx) {
362                 radlog(L_ERR, "Error: Couldn't send OCSP request");
363                 ocsp_ok = 2;
364                 goto ocsp_end;
365         }
366
367         gettimeofday(&when, NULL);
368         when.tv_sec += conf->ocsp_timeout;
369
370         do {
371                 rc = OCSP_sendreq_nbio(&resp, ctx);
372                 if (conf->ocsp_timeout) {
373                         gettimeofday(&now, NULL);
374                         if (!timercmp(&now, &when, <))
375                                 break;
376                 }
377         } while ((rc == -1) && BIO_should_retry(cbio));
378
379         if (conf->ocsp_timeout && (rc == -1) && BIO_should_retry(cbio)) {
380                 radlog(L_ERR, "Error: OCSP response timed out");
381                 ocsp_ok = 2;
382                 goto ocsp_end;
383         }
384
385         OCSP_REQ_CTX_free(ctx);
386
387         if (rc == 0) {
388                 radlog(L_ERR, "Error: Couldn't get OCSP response");
389                 ocsp_ok = 2;
390                 goto ocsp_end;
391         }
392
393         /* Verify OCSP response status */
394         status = OCSP_response_status(resp);
395         DEBUG2("[ocsp] --> Response status: %s",OCSP_response_status_str(status));
396         if(status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
397                 radlog(L_ERR, "Error: OCSP response status: %s", OCSP_response_status_str(status));
398                 goto ocsp_end;
399         }
400         bresp = OCSP_response_get1_basic(resp);
401         if(conf->ocsp_use_nonce && OCSP_check_nonce(req, bresp)!=1) {
402                 radlog(L_ERR, "Error: OCSP response has wrong nonce value");
403                 goto ocsp_end;
404         }
405         if(OCSP_basic_verify(bresp, NULL, store, 0)!=1){
406                 radlog(L_ERR, "Error: Couldn't verify OCSP basic response");
407                 goto ocsp_end;
408         }
409         /*      Verify OCSP cert status */
410         if(!OCSP_resp_find_status(bresp, certid, &status, &reason,
411                                                       &rev, &thisupd, &nextupd)) {
412                 radlog(L_ERR, "ERROR: No Status found.\n");
413                 goto ocsp_end;
414         }
415
416         if (!OCSP_check_validity(thisupd, nextupd, nsec, maxage)) {
417                 BIO_puts(bio_out, "WARNING: Status times invalid.\n");
418                 ERR_print_errors(bio_out);
419                 goto ocsp_end;
420         }
421         BIO_puts(bio_out, "\tThis Update: ");
422         ASN1_GENERALIZEDTIME_print(bio_out, thisupd);
423         BIO_puts(bio_out, "\n");
424         BIO_puts(bio_out, "\tNext Update: ");
425         ASN1_GENERALIZEDTIME_print(bio_out, nextupd);
426         BIO_puts(bio_out, "\n");
427
428         switch (status) {
429         case V_OCSP_CERTSTATUS_GOOD:
430                 DEBUG2("[oscp] --> Cert status: good");
431                 ocsp_ok = 1; 
432                 break;
433
434         default:
435                 /* REVOKED / UNKNOWN */
436                 DEBUG2("[ocsp] --> Cert status: %s",OCSP_cert_status_str(status));
437                 if (reason != -1)
438                         DEBUG2("[ocsp] --> Reason: %s", OCSP_crl_reason_str(reason));
439                 BIO_puts(bio_out, "\tRevocation Time: ");
440                 ASN1_GENERALIZEDTIME_print(bio_out, rev);
441                 BIO_puts(bio_out, "\n"); 
442                 break;
443         }
444
445 ocsp_end:
446         /* Free OCSP Stuff */
447         OCSP_REQUEST_free(req);
448         OCSP_RESPONSE_free(resp);
449         free(host);
450         free(port);
451         free(path);
452         BIO_free_all(cbio);
453         OCSP_BASICRESP_free(bresp);
454
455         switch (ocsp_ok) {
456         case 1:
457                 DEBUG2("[ocsp] --> Certificate is valid!");
458                 break;
459         case 2:
460                 if (conf->ocsp_softfail) {
461                         DEBUG2("[ocsp] --> Unable to check certificate; assuming valid.");
462                         DEBUG2("[ocsp] --> Warning! This may be insecure.");
463                         ocsp_ok = 1;
464                 } else {
465                         DEBUG2("[ocsp] --> Unable to check certificate; failing!");
466                         ocsp_ok = 0;
467                 }
468                 break;
469         default:
470                 DEBUG2("[ocsp] --> Certificate has been expired/revoked!");
471                 break;
472         }
473
474         return ocsp_ok;
475 }
476 #endif  /* HAVE_OPENSSL_OCSP_H */
477
478 /*
479  *      For creating certificate attributes.
480  */
481 static const char *cert_attr_names[6][2] = {
482   { "TLS-Client-Cert-Serial",           "TLS-Cert-Serial" },
483   { "TLS-Client-Cert-Expiration",       "TLS-Cert-Expiration" },
484   { "TLS-Client-Cert-Subject",          "TLS-Cert-Subject" },
485   { "TLS-Client-Cert-Issuer",           "TLS-Cert-Issuer" },
486   { "TLS-Client-Cert-Common-Name",      "TLS-Cert-Common-Name" },
487   { "TLS-Client-Cert-Subject-Alt-Name-Email",   "TLS-Cert-Subject-Alt-Name-Email" }
488 };
489
490 #define EAPTLS_SERIAL           (0)
491 #define EAPTLS_EXPIRATION       (1)
492 #define EAPTLS_SUBJECT          (2)
493 #define EAPTLS_ISSUER           (3)
494 #define EAPTLS_CN               (4)
495 #define EAPTLS_SAN_EMAIL        (5)
496
497 /*
498  *      Before trusting a certificate, you must make sure that the
499  *      certificate is 'valid'. There are several steps that your
500  *      application can take in determining if a certificate is
501  *      valid. Commonly used steps are:
502  *
503  *      1.Verifying the certificate's signature, and verifying that
504  *      the certificate has been issued by a trusted Certificate
505  *      Authority.
506  *
507  *      2.Verifying that the certificate is valid for the present date
508  *      (i.e. it is being presented within its validity dates).
509  *
510  *      3.Verifying that the certificate has not been revoked by its
511  *      issuing Certificate Authority, by checking with respect to a
512  *      Certificate Revocation List (CRL).
513  *
514  *      4.Verifying that the credentials presented by the certificate
515  *      fulfill additional requirements specific to the application,
516  *      such as with respect to access control lists or with respect
517  *      to OCSP (Online Certificate Status Processing).
518  *
519  *      NOTE: This callback will be called multiple times based on the
520  *      depth of the root certificate chain
521  */
522 static int cbtls_verify(int ok, X509_STORE_CTX *ctx)
523 {
524         char subject[1024]; /* Used for the subject name */
525         char issuer[1024]; /* Used for the issuer name */
526         char common_name[1024];
527         char cn_str[1024];
528         char buf[64];
529         EAP_HANDLER *handler = NULL;
530         X509 *client_cert;
531         X509 *issuer_cert;
532         SSL *ssl;
533         int err, depth, lookup, loc;
534         EAP_TLS_CONF *conf;
535         int my_ok = ok;
536         REQUEST *request;
537         ASN1_INTEGER *sn = NULL;
538         ASN1_TIME *asn_time = NULL;
539 #ifdef HAVE_OPENSSL_OCSP_H
540         X509_STORE *ocsp_store = NULL;
541 #endif
542
543         client_cert = X509_STORE_CTX_get_current_cert(ctx);
544         err = X509_STORE_CTX_get_error(ctx);
545         depth = X509_STORE_CTX_get_error_depth(ctx);
546
547         lookup = depth;
548
549         /*
550          *      Log client/issuing cert.  If there's an error, log
551          *      issuing cert.
552          */
553         if ((lookup > 1) && !my_ok) lookup = 1;
554
555         /*
556          * Retrieve the pointer to the SSL of the connection currently treated
557          * and the application specific data stored into the SSL object.
558          */
559         ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
560         handler = (EAP_HANDLER *)SSL_get_ex_data(ssl, 0);
561         request = handler->request;
562         conf = (EAP_TLS_CONF *)SSL_get_ex_data(ssl, 1);
563 #ifdef HAVE_OPENSSL_OCSP_H
564         ocsp_store = (X509_STORE *)SSL_get_ex_data(ssl, 2);
565 #endif
566
567
568         /*
569          *      Get the Serial Number
570          */
571         buf[0] = '\0';
572         sn = X509_get_serialNumber(client_cert);
573
574         /*
575          *      For this next bit, we create the attributes *only* if
576          *      we're at the client or issuing certificate.
577          */
578         if ((lookup <= 1) && sn && (sn->length < (sizeof(buf) / 2))) {
579                 char *p = buf;
580                 int i;
581
582                 for (i = 0; i < sn->length; i++) {
583                         sprintf(p, "%02x", (unsigned int)sn->data[i]);
584                         p += 2;
585                 }
586                 pairadd(&handler->certs,
587                         pairmake(cert_attr_names[EAPTLS_SERIAL][lookup], buf, T_OP_SET));
588         }
589
590
591         /*
592          *      Get the Expiration Date
593          */
594         buf[0] = '\0';
595         asn_time = X509_get_notAfter(client_cert);
596         if ((lookup <= 1) && asn_time && (asn_time->length < MAX_STRING_LEN)) {
597                 memcpy(buf, (char*) asn_time->data, asn_time->length);
598                 buf[asn_time->length] = '\0';
599                 pairadd(&handler->certs,
600                         pairmake(cert_attr_names[EAPTLS_EXPIRATION][lookup], buf, T_OP_SET));
601         }
602
603         /*
604          *      Get the Subject & Issuer
605          */
606         subject[0] = issuer[0] = '\0';
607         X509_NAME_oneline(X509_get_subject_name(client_cert), subject,
608                           sizeof(subject));
609         subject[sizeof(subject) - 1] = '\0';
610         if ((lookup <= 1) && subject[0] && (strlen(subject) < MAX_STRING_LEN)) {
611                 pairadd(&handler->certs,
612                         pairmake(cert_attr_names[EAPTLS_SUBJECT][lookup], subject, T_OP_SET));
613         }
614
615         X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), issuer,
616                           sizeof(issuer));
617         issuer[sizeof(issuer) - 1] = '\0';
618         if ((lookup <= 1) && issuer[0] && (strlen(issuer) < MAX_STRING_LEN)) {
619                 pairadd(&handler->certs,
620                         pairmake(cert_attr_names[EAPTLS_ISSUER][lookup], issuer, T_OP_SET));
621         }
622
623         /*
624          *      Get the Common Name
625          */
626         X509_NAME_get_text_by_NID(X509_get_subject_name(client_cert),
627                                   NID_commonName, common_name, sizeof(common_name));
628         common_name[sizeof(common_name) - 1] = '\0';
629         if ((lookup <= 1) && common_name[0] && (strlen(common_name) < MAX_STRING_LEN)) {
630                 pairadd(&handler->certs,
631                         pairmake(cert_attr_names[EAPTLS_CN][lookup], common_name, T_OP_SET));
632         }
633
634 #ifdef GEN_EMAIL
635         /*
636          *      Get the RFC822 Subject Alternative Name
637          */
638         loc = X509_get_ext_by_NID(client_cert, NID_subject_alt_name, 0);
639         if (lookup <= 1 && loc >= 0) {
640                 X509_EXTENSION *ext = NULL;
641                 GENERAL_NAMES *names = NULL;
642                 int i;
643
644                 if ((ext = X509_get_ext(client_cert, loc)) &&
645                     (names = X509V3_EXT_d2i(ext))) {
646                         for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
647                                 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
648
649                                 switch (name->type) {
650                                 case GEN_EMAIL:
651                                         if (ASN1_STRING_length(name->d.rfc822Name) >= MAX_STRING_LEN)
652                                                 break;
653
654                                         pairadd(&handler->certs,
655                                                 pairmake(cert_attr_names[EAPTLS_SAN_EMAIL][lookup],
656                                                          ASN1_STRING_data(name->d.rfc822Name), T_OP_SET));
657                                         break;
658                                 default:
659                                         /* XXX TODO handle other SAN types */
660                                         break;
661                                 }
662                         }
663                 }
664                 if (names != NULL)
665                         sk_GENERAL_NAME_free(names);
666         }
667 #endif  /* GEN_EMAIL */
668
669         /*
670          *      If the CRL has expired, that might still be OK.
671          */
672         if (!my_ok &&
673             (conf->allow_expired_crl) &&
674             (err == X509_V_ERR_CRL_HAS_EXPIRED)) {
675                 my_ok = 1;
676                 X509_STORE_CTX_set_error( ctx, 0 );
677         }
678
679         if (!my_ok) {
680                 const char *p = X509_verify_cert_error_string(err);
681                 radlog(L_ERR,"--> verify error:num=%d:%s\n",err, p);
682                 radius_pairmake(request, &request->packet->vps,
683                                 "Module-Failure-Message", p, T_OP_SET);
684                 return my_ok;
685         }
686
687         switch (ctx->error) {
688
689         case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
690                 radlog(L_ERR, "issuer= %s\n", issuer);
691                 break;
692         case X509_V_ERR_CERT_NOT_YET_VALID:
693         case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
694                 radlog(L_ERR, "notBefore=");
695 #if 0
696                 ASN1_TIME_print(bio_err, X509_get_notBefore(ctx->current_cert));
697 #endif
698                 break;
699         case X509_V_ERR_CERT_HAS_EXPIRED:
700         case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
701                 radlog(L_ERR, "notAfter=");
702 #if 0
703                 ASN1_TIME_print(bio_err, X509_get_notAfter(ctx->current_cert));
704 #endif
705                 break;
706         }
707
708         /*
709          *      If we're at the actual client cert, apply additional
710          *      checks.
711          */
712         if (depth == 0) {
713                 /*
714                  *      If the conf tells us to, check cert issuer
715                  *      against the specified value and fail
716                  *      verification if they don't match.
717                  */
718                 if (conf->check_cert_issuer &&
719                     (strcmp(issuer, conf->check_cert_issuer) != 0)) {
720                         radlog(L_AUTH, "rlm_eap_tls: Certificate issuer (%s) does not match specified value (%s)!", issuer, conf->check_cert_issuer);
721                         my_ok = 0;
722                 }
723
724                 /*
725                  *      If the conf tells us to, check the CN in the
726                  *      cert against xlat'ed value, but only if the
727                  *      previous checks passed.
728                  */
729                 if (my_ok && conf->check_cert_cn) {
730                         if (!radius_xlat(cn_str, sizeof(cn_str), conf->check_cert_cn, handler->request, NULL)) {
731                                 radlog(L_ERR, "rlm_eap_tls (%s): xlat failed.",
732                                        conf->check_cert_cn);
733                                 /* if this fails, fail the verification */
734                                 my_ok = 0;
735                         } else {
736                                 RDEBUG2("checking certificate CN (%s) with xlat'ed value (%s)", common_name, cn_str);
737                                 if (strcmp(cn_str, common_name) != 0) {
738                                         radlog(L_AUTH, "rlm_eap_tls: Certificate CN (%s) does not match specified value (%s)!", common_name, cn_str);
739                                         my_ok = 0;
740                                 }
741                         }
742                 } /* check_cert_cn */
743
744 #ifdef HAVE_OPENSSL_OCSP_H
745                 if (my_ok && conf->ocsp_enable){
746                         RDEBUG2("--> Starting OCSP Request");
747                         if(X509_STORE_CTX_get1_issuer(&issuer_cert, ctx, client_cert)!=1) {
748                                 radlog(L_ERR, "Error: Couldn't get issuer_cert for %s", common_name);
749                         }
750                         my_ok = ocsp_check(ocsp_store, issuer_cert, client_cert, conf);
751                 }
752 #endif
753
754                 while (conf->verify_client_cert_cmd) {
755                         char filename[256];
756                         int fd;
757                         FILE *fp;
758
759                         snprintf(filename, sizeof(filename), "%s/%s.client.XXXXXXXX",
760                                  conf->verify_tmp_dir, progname);
761                         fd = mkstemp(filename);
762                         if (fd < 0) {
763                                 RDEBUG("Failed creating file in %s: %s",
764                                        conf->verify_tmp_dir, strerror(errno));
765                                 break;                                 
766                         }
767
768                         fp = fdopen(fd, "w");
769                         if (!fp) {
770                                 RDEBUG("Failed opening file %s: %s",
771                                        filename, strerror(errno));
772                                 break;
773                         }
774
775                         if (!PEM_write_X509(fp, client_cert)) {
776                                 fclose(fp);
777                                 RDEBUG("Failed writing certificate to file");
778                                 goto do_unlink;
779                         }
780                         fclose(fp);
781
782                         if (!radius_pairmake(request, &request->packet->vps,
783                                              "TLS-Client-Cert-Filename",
784                                              filename, T_OP_SET)) {
785                                 RDEBUG("Failed creating TLS-Client-Cert-Filename");
786                                 
787                                 goto do_unlink;
788                         }
789
790                         RDEBUG("Verifying client certificate: %s",
791                                conf->verify_client_cert_cmd);
792                         if (radius_exec_program(conf->verify_client_cert_cmd,
793                                                 request, 1, NULL, 0, 
794                                                 request->packet->vps,
795                                                 NULL, 1) != 0) {
796                                 radlog(L_AUTH, "rlm_eap_tls: Certificate CN (%s) fails external verification!", common_name);
797                                 my_ok = 0;
798                         } else {
799                                 RDEBUG("Client certificate CN %s passed external validation", common_name);
800                         }
801
802                 do_unlink:
803                         unlink(filename);
804                         break;
805                 }
806
807
808         } /* depth == 0 */
809
810         if (debug_flag > 0) {
811                 RDEBUG2("chain-depth=%d, ", depth);
812                 RDEBUG2("error=%d", err);
813
814                 RDEBUG2("--> User-Name = %s", handler->identity);
815                 RDEBUG2("--> BUF-Name = %s", common_name);
816                 RDEBUG2("--> subject = %s", subject);
817                 RDEBUG2("--> issuer  = %s", issuer);
818                 RDEBUG2("--> verify return:%d", my_ok);
819         }
820         return my_ok;
821 }
822
823
824 /*
825  *      Free cached session data, which is always a list of VALUE_PAIRs
826  */
827 static void eaptls_session_free(UNUSED void *parent, void *data_ptr,
828                                 UNUSED CRYPTO_EX_DATA *ad, UNUSED int idx,
829                                 UNUSED long argl, UNUSED void *argp)
830 {
831         VALUE_PAIR *vp = data_ptr;
832         if (!data_ptr) return;
833
834         pairfree(&vp);
835 }
836
837 #ifdef HAVE_OPENSSL_OCSP_H
838 /*
839  *      Create Global X509 revocation store and use it to verify
840  *      OCSP responses
841  *
842  *      - Load the trusted CAs
843  *      - Load the trusted issuer certificates
844  */
845 static X509_STORE *init_revocation_store(EAP_TLS_CONF *conf)
846 {
847         X509_STORE *store = NULL;
848         
849         store = X509_STORE_new();
850
851         /* Load the CAs we trust */
852         if (conf->ca_file || conf->ca_path)
853                 if(!X509_STORE_load_locations(store, conf->ca_file, conf->ca_path)) {
854                         radlog(L_ERR, "rlm_eap: X509_STORE error %s", ERR_error_string(ERR_get_error(), NULL));
855                         radlog(L_ERR, "rlm_eap_tls: Error reading Trusted root CA list %s",conf->ca_file );
856                         return NULL;
857                 }
858
859 #ifdef X509_V_FLAG_CRL_CHECK
860         if (conf->check_crl) 
861                 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK);
862 #endif
863         return store;
864 }
865 #endif  /* HAVE_OPENSSL_OCSP_H */
866
867 #if OPENSSL_VERSION_NUMBER >= 0x0090800fL
868 #ifndef OPENSSL_NO_ECDH
869 static int set_ecdh_curve(SSL_CTX *ctx, const char *ecdh_curve)
870 {
871         int      nid; 
872         EC_KEY  *ecdh; 
873
874         if (!ecdh_curve || !*ecdh_curve) return 0;
875
876         nid = OBJ_sn2nid(ecdh_curve); 
877         if (!nid) { 
878                 radlog(L_ERR, "Unknown ecdh_curve \"%s\"", ecdh_curve);
879                 return -1;
880         }
881
882         ecdh = EC_KEY_new_by_curve_name(nid); 
883         if (!ecdh) { 
884                 radlog(L_ERR, "Unable to create new curve \"%s\"", ecdh_curve);
885                 return -1;
886         } 
887
888         SSL_CTX_set_tmp_ecdh(ctx, ecdh); 
889
890         SSL_CTX_set_options(ctx, SSL_OP_SINGLE_ECDH_USE); 
891
892         EC_KEY_free(ecdh);
893
894         return 0;
895 }
896 #endif
897 #endif
898
899 /*
900  *      Create Global context SSL and use it in every new session
901  *
902  *      - Load the trusted CAs
903  *      - Load the Private key & the certificate
904  *      - Set the Context options & Verify options
905  */
906 static SSL_CTX *init_tls_ctx(EAP_TLS_CONF *conf)
907 {
908         SSL_METHOD *meth;
909         SSL_CTX *ctx;
910         X509_STORE *certstore;
911         int verify_mode = SSL_VERIFY_NONE;
912         int ctx_options = 0;
913         int type;
914
915         /*
916          *      Add all the default ciphers and message digests
917          *      Create our context.
918          */
919         SSL_library_init();
920         SSL_load_error_strings();
921
922         /*
923          *      SHA256 is in all versions of OpenSSL, but isn't
924          *      initialized by default.  It's needed for WiMAX
925          *      certificates.
926          */
927 #ifdef HAVE_OPENSSL_EVP_SHA256
928         EVP_add_digest(EVP_sha256());
929 #endif
930
931         meth = TLSv1_method();
932         ctx = SSL_CTX_new(meth);
933
934         /*
935          * Identify the type of certificates that needs to be loaded
936          */
937         if (conf->file_type) {
938                 type = SSL_FILETYPE_PEM;
939         } else {
940                 type = SSL_FILETYPE_ASN1;
941         }
942
943         /*
944          * Set the password to load private key
945          */
946         if (conf->private_key_password) {
947 #ifdef __APPLE__
948                 /*
949                  * We don't want to put the private key password in eap.conf, so  check
950                  * for our special string which indicates we should get the password
951                  * programmatically. 
952                  */
953                 const char* special_string = "Apple:UseCertAdmin";
954                 if (strncmp(conf->private_key_password,
955                                         special_string,
956                                         strlen(special_string)) == 0)
957                 {
958                         char cmd[256];
959                         const long max_password_len = 128;
960                         snprintf(cmd, sizeof(cmd) - 1,
961                                          "/usr/sbin/certadmin --get-private-key-passphrase \"%s\"",
962                                          conf->private_key_file);
963
964                         DEBUG2("rlm_eap: Getting private key passphrase using command \"%s\"", cmd);
965
966                         FILE* cmd_pipe = popen(cmd, "r");
967                         if (!cmd_pipe) {
968                                 radlog(L_ERR, "rlm_eap: %s command failed.      Unable to get private_key_password", cmd);
969                                 radlog(L_ERR, "rlm_eap: Error reading private_key_file %s", conf->private_key_file);
970                                 return NULL;
971                         }
972
973                         free(conf->private_key_password);
974                         conf->private_key_password = malloc(max_password_len * sizeof(char));
975                         if (!conf->private_key_password) {
976                                 radlog(L_ERR, "rlm_eap: Can't malloc space for private_key_password");
977                                 radlog(L_ERR, "rlm_eap: Error reading private_key_file %s", conf->private_key_file);
978                                 pclose(cmd_pipe);
979                                 return NULL;
980                         }
981
982                         fgets(conf->private_key_password, max_password_len, cmd_pipe);
983                         pclose(cmd_pipe);
984
985                         /* Get rid of newline at end of password. */
986                         conf->private_key_password[strlen(conf->private_key_password) - 1] = '\0';
987                         DEBUG2("rlm_eap:  Password from command = \"%s\"", conf->private_key_password);
988                 }
989 #endif
990                 SSL_CTX_set_default_passwd_cb_userdata(ctx, conf->private_key_password);
991                 SSL_CTX_set_default_passwd_cb(ctx, cbtls_password);
992         }
993
994         /*
995          *      Load our keys and certificates
996          *
997          *      If certificates are of type PEM then we can make use
998          *      of cert chain authentication using openssl api call
999          *      SSL_CTX_use_certificate_chain_file.  Please see how
1000          *      the cert chain needs to be given in PEM from
1001          *      openSSL.org
1002          */
1003         if (type == SSL_FILETYPE_PEM) {
1004                 if (!(SSL_CTX_use_certificate_chain_file(ctx, conf->certificate_file))) {
1005                         radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL));
1006                         radlog(L_ERR, "rlm_eap_tls: Error reading certificate file %s", conf->certificate_file);
1007                         return NULL;
1008                 }
1009
1010         } else if (!(SSL_CTX_use_certificate_file(ctx, conf->certificate_file, type))) {
1011                 radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL));
1012                 radlog(L_ERR, "rlm_eap_tls: Error reading certificate file %s", conf->certificate_file);
1013                 return NULL;
1014         }
1015
1016         /* Load the CAs we trust */
1017         if (conf->ca_file || conf->ca_path) {
1018                 if (!SSL_CTX_load_verify_locations(ctx, conf->ca_file, conf->ca_path)) {
1019                         radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL));
1020                         radlog(L_ERR, "rlm_eap_tls: Error reading Trusted root CA list %s",conf->ca_file );
1021                         return NULL;
1022                 }
1023         }
1024         if (conf->ca_file && *conf->ca_file) SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(conf->ca_file));
1025         if (!(SSL_CTX_use_PrivateKey_file(ctx, conf->private_key_file, type))) {
1026                 radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL));
1027                 radlog(L_ERR, "rlm_eap_tls: Error reading private key file %s", conf->private_key_file);
1028                 return NULL;
1029         }
1030
1031         /*
1032          * Check if the loaded private key is the right one
1033          */
1034         if (!SSL_CTX_check_private_key(ctx)) {
1035                 radlog(L_ERR, "rlm_eap_tls: Private key does not match the certificate public key");
1036                 return NULL;
1037         }
1038
1039         /*
1040          *      Set ctx_options
1041          */
1042         ctx_options |= SSL_OP_NO_SSLv2;
1043         ctx_options |= SSL_OP_NO_SSLv3;
1044 #ifdef SSL_OP_NO_TICKET
1045         ctx_options |= SSL_OP_NO_TICKET ;
1046 #endif
1047
1048         /*
1049          *      SSL_OP_SINGLE_DH_USE must be used in order to prevent
1050          *      small subgroup attacks and forward secrecy. Always
1051          *      using
1052          *
1053          *      SSL_OP_SINGLE_DH_USE has an impact on the computer
1054          *      time needed during negotiation, but it is not very
1055          *      large.
1056          */
1057         ctx_options |= SSL_OP_SINGLE_DH_USE;
1058
1059         /*
1060          *      SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS to work around issues
1061          *      in Windows Vista client.
1062          *      http://www.openssl.org/~bodo/tls-cbc.txt
1063          *      http://www.nabble.com/(RADIATOR)-Radiator-Version-3.16-released-t2600070.html
1064          */
1065         ctx_options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
1066
1067         SSL_CTX_set_options(ctx, ctx_options);
1068
1069         /*
1070          *      TODO: Set the RSA & DH
1071          *      SSL_CTX_set_tmp_rsa_callback(ctx, cbtls_rsa);
1072          *      SSL_CTX_set_tmp_dh_callback(ctx, cbtls_dh);
1073          */
1074
1075         /*
1076          *      Set eliptical curve crypto configuration.
1077          */
1078 #if OPENSSL_VERSION_NUMBER >= 0x0090800fL
1079 #ifndef OPENSSL_NO_ECDH
1080         if (set_ecdh_curve(ctx, conf->ecdh_curve) < 0) {
1081                 return NULL;
1082         }
1083 #endif
1084 #endif
1085
1086         /*
1087          *      set the message callback to identify the type of
1088          *      message.  For every new session, there can be a
1089          *      different callback argument.
1090          *
1091          *      SSL_CTX_set_msg_callback(ctx, cbtls_msg);
1092          */
1093
1094         /* Set Info callback */
1095         SSL_CTX_set_info_callback(ctx, cbtls_info);
1096
1097         /*
1098          *      Callbacks, etc. for session resumption.
1099          */                                                   
1100         if (conf->session_cache_enable) {
1101                 SSL_CTX_sess_set_new_cb(ctx, cbtls_new_session);
1102                 SSL_CTX_sess_set_get_cb(ctx, cbtls_get_session);
1103                 SSL_CTX_sess_set_remove_cb(ctx, cbtls_remove_session);
1104
1105                 SSL_CTX_set_quiet_shutdown(ctx, 1);
1106         }
1107
1108         /*
1109          *      Check the certificates for revocation.
1110          */
1111 #ifdef X509_V_FLAG_CRL_CHECK
1112         if (conf->check_crl) {
1113           certstore = SSL_CTX_get_cert_store(ctx);
1114           if (certstore == NULL) {
1115             radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL));
1116             radlog(L_ERR, "rlm_eap_tls: Error reading Certificate Store");
1117             return NULL;
1118           }
1119           X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK);
1120         }
1121 #endif
1122
1123         /*
1124          *      Set verify modes
1125          *      Always verify the peer certificate
1126          */
1127         verify_mode |= SSL_VERIFY_PEER;
1128         verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1129         verify_mode |= SSL_VERIFY_CLIENT_ONCE;
1130         SSL_CTX_set_verify(ctx, verify_mode, cbtls_verify);
1131
1132         if (conf->verify_depth) {
1133                 SSL_CTX_set_verify_depth(ctx, conf->verify_depth);
1134         }
1135
1136         /* Load randomness */
1137         if (!(RAND_load_file(conf->random_file, 1024*1024))) {
1138                 radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL));
1139                 radlog(L_ERR, "rlm_eap_tls: Error loading randomness");
1140                 return NULL;
1141         }
1142
1143         /*
1144          * Set the cipher list if we were told to
1145          */
1146         if (conf->cipher_list) {
1147                 if (!SSL_CTX_set_cipher_list(ctx, conf->cipher_list)) {
1148                         radlog(L_ERR, "rlm_eap_tls: Error setting cipher list");
1149                         return NULL;
1150                 }
1151         }
1152
1153         /*
1154          *      Setup session caching
1155          */
1156         if (conf->session_cache_enable) {
1157                 /*
1158                  *      Create a unique context Id per EAP-TLS configuration.
1159                  */
1160                 if (conf->session_id_name) {
1161                         snprintf(conf->session_context_id,
1162                                  sizeof(conf->session_context_id),
1163                                  "FR eap %s",
1164                                  conf->session_id_name);
1165                 } else {
1166                         snprintf(conf->session_context_id,
1167                                  sizeof(conf->session_context_id),
1168                                  "FR eap %p", conf);
1169                 }
1170
1171                 /*
1172                  *      Cache it, and DON'T auto-clear it.
1173                  */
1174                 SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER | SSL_SESS_CACHE_NO_AUTO_CLEAR);
1175                                                
1176                 SSL_CTX_set_session_id_context(ctx,
1177                                                (unsigned char *) conf->session_context_id,
1178                                                (unsigned int) strlen(conf->session_context_id));
1179
1180                 /*
1181                  *      Our timeout is in hours, this is in seconds.
1182                  */
1183                 SSL_CTX_set_timeout(ctx, conf->session_timeout * 3600);
1184                 
1185                 /*
1186                  *      Set the maximum number of entries in the
1187                  *      session cache.
1188                  */
1189                 SSL_CTX_sess_set_cache_size(ctx, conf->session_cache_size);
1190
1191         } else {
1192                 SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
1193         }
1194
1195         /*
1196          *      Register the application indices.  We can't use
1197          *      hard-coded "0" and "1" as before, because we need to
1198          *      set up a "free" handler for the cached session
1199          *      information.
1200          */
1201         if (eaptls_handle_idx < 0) {
1202                 eaptls_handle_idx = SSL_get_ex_new_index(0, "eaptls_handle_idx",
1203                                                           NULL, NULL, NULL);
1204         }
1205         
1206         if (eaptls_conf_idx < 0) {
1207                 eaptls_conf_idx = SSL_get_ex_new_index(0, "eaptls_conf_idx",
1208                                                           NULL, NULL, NULL);
1209         }
1210
1211         if (eaptls_store_idx < 0) {
1212                 eaptls_store_idx = SSL_get_ex_new_index(0, "eaptls_store_idx",
1213                                                           NULL, NULL, NULL);
1214         }
1215
1216         if (eaptls_session_idx < 0) {
1217                 eaptls_session_idx = SSL_SESSION_get_ex_new_index(0, "eaptls_session_idx",
1218                                                           NULL, NULL,
1219                                                           eaptls_session_free);
1220         }
1221
1222         return ctx;
1223 }
1224
1225
1226 /*
1227  *      Detach the EAP-TLS module.
1228  */
1229 static int eaptls_detach(void *arg)
1230 {
1231         EAP_TLS_CONF     *conf;
1232         eap_tls_t        *inst;
1233
1234         inst = (eap_tls_t *) arg;
1235         conf = inst->conf;
1236
1237         if (conf) {
1238                 memset(conf, 0, sizeof(*conf));
1239                 free(inst->conf);
1240                 inst->conf = NULL;
1241         }
1242
1243         if (inst->ctx) SSL_CTX_free(inst->ctx);
1244         inst->ctx = NULL;
1245
1246 #ifdef HAVE_OPENSSL_OCSP_H
1247         if (inst->store) X509_STORE_free(inst->store);
1248         inst->store = NULL;
1249 #endif
1250
1251         free(inst);
1252
1253         return 0;
1254 }
1255
1256
1257 /*
1258  *      Attach the EAP-TLS module.
1259  */
1260 static int eaptls_attach(CONF_SECTION *cs, void **instance)
1261 {
1262         EAP_TLS_CONF     *conf;
1263         eap_tls_t        *inst;
1264
1265         /* Store all these values in the data structure for later references */
1266         inst = (eap_tls_t *)malloc(sizeof(*inst));
1267         if (!inst) {
1268                 radlog(L_ERR, "rlm_eap_tls: out of memory");
1269                 return -1;
1270         }
1271         memset(inst, 0, sizeof(*inst));
1272
1273         /*
1274          *      Parse the config file & get all the configured values
1275          */
1276         conf = (EAP_TLS_CONF *)malloc(sizeof(*conf));
1277         if (conf == NULL) {
1278                 free(inst);
1279                 radlog(L_ERR, "rlm_eap_tls: out of memory");
1280                 return -1;
1281         }
1282         memset(conf, 0, sizeof(*conf));
1283
1284         inst->conf = conf;
1285         if (cf_section_parse(cs, conf, module_config) < 0) {
1286                 eaptls_detach(inst);
1287                 return -1;
1288         }
1289
1290         /*
1291          *      The EAP RFC's say 1020, but we're less picky.
1292          */
1293         if (conf->fragment_size < 100) {
1294                 radlog(L_ERR, "rlm_eap_tls: Fragment size is too small.");
1295                 eaptls_detach(inst);
1296                 return -1;
1297         }
1298
1299         /*
1300          *      The maximum size for a RADIUS packet is 4096,
1301          *      minus the header (20), Message-Authenticator (18),
1302          *      and State (18), etc. results in about 4000 bytes of data
1303          *      that can be devoted *solely* to EAP.
1304          */
1305         if (conf->fragment_size > 4000) {
1306                 radlog(L_ERR, "rlm_eap_tls: Fragment size is too large.");
1307                 eaptls_detach(inst);
1308                 return -1;
1309         }
1310
1311         /*
1312          *      Account for the EAP header (4), and the EAP-TLS header
1313          *      (6), as per Section 4.2 of RFC 2716.  What's left is
1314          *      the maximum amount of data we read from a TLS buffer.
1315          */
1316         conf->fragment_size -= 10;
1317
1318         /*
1319          *      This magic makes the administrators life HUGELY easier
1320          *      on initial deployments.
1321          *
1322          *      If the server starts up in debugging mode, AND the
1323          *      bootstrap command is configured, AND it exists, AND
1324          *      there is no server certificate
1325          */
1326         if (conf->make_cert_command && (debug_flag >= 2)) {
1327                 struct stat buf;
1328
1329                 if ((stat(conf->make_cert_command, &buf) == 0) &&
1330                     (stat(conf->certificate_file, &buf) < 0) &&
1331                     (errno == ENOENT) &&
1332                     (radius_exec_program(conf->make_cert_command, NULL, 1,
1333                                          NULL, 0, NULL, NULL, 0) != 0)) {
1334                         eaptls_detach(inst);
1335                         return -1;
1336                 }
1337         }
1338
1339
1340         /*
1341          *      Initialize TLS
1342          */
1343         inst->ctx = init_tls_ctx(conf);
1344         if (inst->ctx == NULL) {
1345                 eaptls_detach(inst);
1346                 return -1;
1347         }
1348
1349 #ifdef HAVE_OPENSSL_OCSP_H
1350         /*
1351          *      Initialize OCSP Revocation Store
1352          */
1353         if (conf->ocsp_enable) {
1354                 inst->store = init_revocation_store(conf);
1355                 if (inst->store == NULL) {
1356                         eaptls_detach(inst);
1357                   return -1;
1358                 }
1359         }
1360 #endif /*HAVE_OPENSSL_OCSP_H*/
1361
1362         if (load_dh_params(inst->ctx, conf->dh_file) < 0) {
1363                 eaptls_detach(inst);
1364                 return -1;
1365         }
1366
1367         if (generate_eph_rsa_key(inst->ctx) < 0) {
1368                 eaptls_detach(inst);
1369                 return -1;
1370         }
1371
1372         if (conf->verify_tmp_dir) {
1373                 if (chmod(conf->verify_tmp_dir, S_IRWXU) < 0) {
1374                         radlog(L_ERR, "rlm_eap_tls: Failed changing permissions on %s: %s", conf->verify_tmp_dir, strerror(errno));
1375                         eaptls_detach(inst);
1376                         return -1;
1377                 }
1378         }
1379
1380         if (conf->verify_client_cert_cmd && !conf->verify_tmp_dir) {
1381                 radlog(L_ERR, "rlm_eap_tls: You MUST set the verify directory in order to use verify_client_cmd");
1382                 eaptls_detach(inst);
1383                 return -1;
1384         }
1385
1386         *instance = inst;
1387
1388         return 0;
1389 }
1390
1391
1392 /*
1393  *      Send an initial eap-tls request to the peer.
1394  *
1395  *      Frame eap reply packet.
1396  *      len = header + type + tls_typedata
1397  *      tls_typedata = flags(Start (S) bit set, and no data)
1398  *
1399  *      Once having received the peer's Identity, the EAP server MUST
1400  *      respond with an EAP-TLS/Start packet, which is an
1401  *      EAP-Request packet with EAP-Type=EAP-TLS, the Start (S) bit
1402  *      set, and no data.  The EAP-TLS conversation will then begin,
1403  *      with the peer sending an EAP-Response packet with
1404  *      EAP-Type = EAP-TLS.  The data field of that packet will
1405  *      be the TLS data.
1406  *
1407  *      Fragment length is Framed-MTU - 4.
1408  *
1409  *      http://mail.frascone.com/pipermail/public/eap/2003-July/001426.html
1410  */
1411 static int eaptls_initiate(void *type_arg, EAP_HANDLER *handler)
1412 {
1413         int             status;
1414         tls_session_t   *ssn;
1415         eap_tls_t       *inst;
1416         VALUE_PAIR      *vp;
1417         int             client_cert = TRUE;
1418         int             verify_mode = 0;
1419         REQUEST         *request = handler->request;
1420
1421         inst = (eap_tls_t *)type_arg;
1422
1423         handler->tls = TRUE;
1424         handler->finished = FALSE;
1425
1426         /*
1427          *      Manually flush the sessions every so often.  If HALF
1428          *      of the session lifetime has passed since we last
1429          *      flushed, then flush it again.
1430          *
1431          *      FIXME: Also do it every N sessions?
1432          */
1433         if (inst->conf->session_cache_enable &&
1434             ((inst->conf->session_last_flushed + (inst->conf->session_timeout * 1800)) <= request->timestamp)) {
1435                 RDEBUG2("Flushing SSL sessions (of #%ld)",
1436                         SSL_CTX_sess_number(inst->ctx));
1437
1438                 SSL_CTX_flush_sessions(inst->ctx, request->timestamp);
1439                 inst->conf->session_last_flushed = request->timestamp;
1440         }
1441
1442         /*
1443          *      If we're TTLS or PEAP, then do NOT require a client
1444          *      certificate.
1445          *
1446          *      FIXME: This should be more configurable.
1447          */
1448         if (handler->eap_type != PW_EAP_TLS) {
1449                 vp = pairfind(handler->request->config_items,
1450                               PW_EAP_TLS_REQUIRE_CLIENT_CERT);
1451                 if (!vp) {
1452                         client_cert = FALSE;
1453                 } else {
1454                         client_cert = vp->vp_integer;
1455                 }
1456         }
1457
1458         /*
1459          *      Every new session is started only from EAP-TLS-START.
1460          *      Before Sending EAP-TLS-START, open a new SSL session.
1461          *      Create all the required data structures & store them
1462          *      in Opaque.  So that we can use these data structures
1463          *      when we get the response
1464          */
1465         ssn = eaptls_new_session(inst->ctx, client_cert);
1466         if (!ssn) {
1467                 return 0;
1468         }
1469
1470         /*
1471          *      Verify the peer certificate, if asked.
1472          */
1473         if (client_cert) {
1474                 RDEBUG2("Requiring client certificate");
1475                 verify_mode = SSL_VERIFY_PEER;
1476                 verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1477                 verify_mode |= SSL_VERIFY_CLIENT_ONCE;
1478         }
1479         SSL_set_verify(ssn->ssl, verify_mode, cbtls_verify);
1480
1481         /*
1482          *      Create a structure for all the items required to be
1483          *      verified for each client and set that as opaque data
1484          *      structure.
1485          *
1486          *      NOTE: If we want to set each item sepearately then
1487          *      this index should be global.
1488          */
1489         SSL_set_ex_data(ssn->ssl, 0, (void *)handler);
1490         SSL_set_ex_data(ssn->ssl, 1, (void *)inst->conf);
1491 #ifdef HAVE_OPENSSL_OCSP_H
1492         SSL_set_ex_data(ssn->ssl, 2, (void *)inst->store);
1493 #endif
1494
1495         ssn->length_flag = inst->conf->include_length;
1496
1497         /*
1498          *      We use default fragment size, unless the Framed-MTU
1499          *      tells us it's too big.  Note that we do NOT account
1500          *      for the EAP-TLS headers if conf->fragment_size is
1501          *      large, because that config item looks to be confusing.
1502          *
1503          *      i.e. it should REALLY be called MTU, and the code here
1504          *      should figure out what that means for TLS fragment size.
1505          *      asking the administrator to know the internal details
1506          *      of EAP-TLS in order to calculate fragment sizes is
1507          *      just too much.
1508          */
1509         ssn->offset = inst->conf->fragment_size;
1510         vp = pairfind(handler->request->packet->vps, PW_FRAMED_MTU);
1511         if (vp && ((vp->vp_integer - 14) < ssn->offset)) {
1512                 /*
1513                  *      Discount the Framed-MTU by:
1514                  *       4 : EAPOL header
1515                  *       4 : EAP header (code + id + length)
1516                  *       1 : EAP type == EAP-TLS
1517                  *       1 : EAP-TLS Flags
1518                  *       4 : EAP-TLS Message length
1519                  *          (even if conf->include_length == 0,
1520                  *           just to be lazy).
1521                  *      ---
1522                  *      14
1523                  */
1524                 ssn->offset = vp->vp_integer - 14;
1525         }
1526
1527         handler->opaque = ((void *)ssn);
1528         handler->free_opaque = session_free;
1529
1530         RDEBUG2("Initiate");
1531
1532         /*
1533          *      Set up type-specific information.
1534          */
1535         switch (handler->eap_type) {
1536         case PW_EAP_TLS:
1537         default:
1538                 ssn->prf_label = "client EAP encryption";
1539                 break;
1540
1541         case PW_EAP_TTLS:
1542                 ssn->prf_label = "ttls keying material";
1543                 break;
1544
1545                 /*
1546                  *      PEAP-specific breakage.
1547                  */
1548         case PW_EAP_PEAP:
1549                 /*
1550                  *      As it is a poorly designed protocol, PEAP uses
1551                  *      bits in the TLS header to indicate PEAP
1552                  *      version numbers.  For now, we only support
1553                  *      PEAP version 0, so it doesn't matter too much.
1554                  *      However, if we support later versions of PEAP,
1555                  *      we will need this flag to indicate which
1556                  *      version we're currently dealing with.
1557                  */
1558                 ssn->peap_flag = 0x00;
1559
1560                 /*
1561                  *      PEAP version 0 requires 'include_length = no',
1562                  *      so rather than hoping the user figures it out,
1563                  *      we force it here.
1564                  */
1565                 ssn->length_flag = 0;
1566
1567                 ssn->prf_label = "client EAP encryption";
1568                 break;
1569         }
1570
1571         if (inst->conf->session_cache_enable) {
1572                 ssn->allow_session_resumption = 1; /* otherwise it's zero */
1573         }
1574
1575         /*
1576          *      TLS session initialization is over.  Now handle TLS
1577          *      related handshaking or application data.
1578          */
1579         status = eaptls_start(handler->eap_ds, ssn->peap_flag);
1580         RDEBUG2("Start returned %d", status);
1581         if (status == 0)
1582                 return 0;
1583
1584         /*
1585          *      The next stage to process the packet.
1586          */
1587         handler->stage = AUTHENTICATE;
1588
1589         return 1;
1590 }
1591
1592 /*
1593  *      Do authentication, by letting EAP-TLS do most of the work.
1594  */
1595 static int eaptls_authenticate(void *arg, EAP_HANDLER *handler)
1596 {
1597         eaptls_status_t status;
1598         tls_session_t *tls_session = (tls_session_t *) handler->opaque;
1599         REQUEST *request = handler->request;
1600         eap_tls_t *inst = (eap_tls_t *) arg;
1601
1602         RDEBUG2("Authenticate");
1603
1604         status = eaptls_process(handler);
1605         RDEBUG2("eaptls_process returned %d\n", status);
1606         switch (status) {
1607                 /*
1608                  *      EAP-TLS handshake was successful, return an
1609                  *      EAP-TLS-Success packet here.
1610                  */
1611         case EAPTLS_SUCCESS:
1612                 break;
1613
1614                 /*
1615                  *      The TLS code is still working on the TLS
1616                  *      exchange, and it's a valid TLS request.
1617                  *      do nothing.
1618                  */
1619         case EAPTLS_HANDLED:
1620                 return 1;
1621
1622                 /*
1623                  *      Handshake is done, proceed with decoding tunneled
1624                  *      data.
1625                  */
1626         case EAPTLS_OK:
1627                 RDEBUG2("Received unexpected tunneled data after successful handshake.");
1628 #ifndef NDEBUG
1629                 if ((debug_flag > 2) && fr_log_fp) {
1630                         unsigned int i;
1631                         unsigned int data_len;
1632                         unsigned char buffer[1024];
1633
1634                         data_len = (tls_session->record_minus)(&tls_session->dirty_in,
1635                                                 buffer, sizeof(buffer));
1636                         log_debug("  Tunneled data (%u bytes)\n", data_len);
1637                         for (i = 0; i < data_len; i++) {
1638                                 if ((i & 0x0f) == 0x00) fprintf(fr_log_fp, "  %x: ", i);
1639                                 if ((i & 0x0f) == 0x0f) fprintf(fr_log_fp, "\n");
1640
1641                                 fprintf(fr_log_fp, "%02x ", buffer[i]);
1642                         }
1643                         fprintf(fr_log_fp, "\n");
1644                 }
1645 #endif
1646
1647                 eaptls_fail(handler, 0);
1648                 return 0;
1649                 break;
1650
1651                 /*
1652                  *      Anything else: fail.
1653                  *
1654                  *      Also, remove the session from the cache so that
1655                  *      the client can't re-use it.
1656                  */
1657         default:
1658                 if (inst->conf->session_cache_enable) { 
1659                         SSL_CTX_remove_session(inst->ctx,
1660                                                tls_session->ssl->session);
1661                 }
1662
1663                 return 0;
1664         }
1665
1666         /*
1667          *      New sessions cause some additional information to be
1668          *      cached.
1669          */
1670         if (!SSL_session_reused(tls_session->ssl)) {
1671                 /*
1672                  *      FIXME: Store miscellaneous data.
1673                  */
1674                 RDEBUG2("Adding user data to cached session");
1675                 
1676 #if 0
1677                 SSL_SESSION_set_ex_data(tls_session->ssl->session,
1678                                         ssl_session_idx_user_session, session_data);
1679 #endif
1680         } else {
1681                 /*
1682                  *      FIXME: Retrieve miscellaneous data.
1683                  */
1684 #if 0
1685                 data = SSL_SESSION_get_ex_data(tls_session->ssl->session,
1686                                                ssl_session_idx_user_session);
1687
1688                 if (!session_data) {
1689                         radlog_request(L_ERR, 0, request,
1690                                        "No user session data in cached session - "
1691                                        " REJECTING");
1692                         return 0;
1693                 }
1694 #endif
1695
1696                 RDEBUG2("Retrieved session data from cached session");
1697         }
1698
1699         /*
1700          *      Success: Automatically return MPPE keys.
1701          */
1702         return eaptls_success(handler, 0);
1703 }
1704
1705 /*
1706  *      The module name should be the only globally exported symbol.
1707  *      That is, everything else should be 'static'.
1708  */
1709 EAP_TYPE rlm_eap_tls = {
1710         "eap_tls",
1711         eaptls_attach,                  /* attach */
1712         eaptls_initiate,                /* Start the initial request */
1713         NULL,                           /* authorization */
1714         eaptls_authenticate,            /* authentication */
1715         eaptls_detach                   /* detach */
1716 };