Control whether or not a client certificate is required.
[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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  * Copyright 2001  hereUare Communications, Inc. <raghud@hereuare.com>
21  * Copyright 2003  Alan DeKok <aland@freeradius.org>
22  */
23
24 #include "autoconf.h"
25 #include "eap_tls.h"
26
27 #ifdef HAVE_OPENSSL_RAND_H
28 #include <openssl/rand.h>
29 #endif
30
31 static CONF_PARSER module_config[] = {
32         { "rsa_key_exchange", PW_TYPE_BOOLEAN,
33           offsetof(EAP_TLS_CONF, rsa_key), NULL, "no" },
34         { "dh_key_exchange", PW_TYPE_BOOLEAN,
35           offsetof(EAP_TLS_CONF, dh_key), NULL, "yes" },
36         { "rsa_key_length", PW_TYPE_INTEGER,
37           offsetof(EAP_TLS_CONF, rsa_key_length), NULL, "512" },
38         { "dh_key_length", PW_TYPE_INTEGER,
39           offsetof(EAP_TLS_CONF, dh_key_length), NULL, "512" },
40         { "verify_depth", PW_TYPE_INTEGER,
41           offsetof(EAP_TLS_CONF, verify_depth), NULL, "0" },
42         { "CA_path", PW_TYPE_STRING_PTR,
43           offsetof(EAP_TLS_CONF, ca_path), NULL, NULL },
44         { "pem_file_type", PW_TYPE_BOOLEAN,
45           offsetof(EAP_TLS_CONF, file_type), NULL, "yes" },
46         { "private_key_file", PW_TYPE_STRING_PTR,
47           offsetof(EAP_TLS_CONF, private_key_file), NULL, NULL },
48         { "certificate_file", PW_TYPE_STRING_PTR,
49           offsetof(EAP_TLS_CONF, certificate_file), NULL, NULL },
50         { "CA_file", PW_TYPE_STRING_PTR,
51           offsetof(EAP_TLS_CONF, ca_file), NULL, NULL },
52         { "private_key_password", PW_TYPE_STRING_PTR,
53           offsetof(EAP_TLS_CONF, private_key_password), NULL, NULL },
54         { "dh_file", PW_TYPE_STRING_PTR,
55           offsetof(EAP_TLS_CONF, dh_file), NULL, NULL },
56         { "random_file", PW_TYPE_STRING_PTR,
57           offsetof(EAP_TLS_CONF, random_file), NULL, NULL },
58         { "fragment_size", PW_TYPE_INTEGER,
59           offsetof(EAP_TLS_CONF, fragment_size), NULL, "1024" },
60         { "include_length", PW_TYPE_BOOLEAN,
61           offsetof(EAP_TLS_CONF, include_length), NULL, "yes" },
62
63         { NULL, -1, 0, NULL, NULL }           /* end the list */
64 };
65
66
67 /*
68  *      TODO: Check for the type of key exchange * like conf->dh_key
69  */
70 static int load_dh_params(SSL_CTX *ctx, char *file)
71 {
72         DH *dh = NULL;
73         BIO *bio;
74
75         if ((bio = BIO_new_file(file, "r")) == NULL) {
76                 radlog(L_ERR, "rlm_eap_tls: Unable to open DH file - %s", file);
77                 return -1;
78         }
79
80         dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
81         BIO_free(bio);
82         if (SSL_CTX_set_tmp_dh(ctx, dh) < 0) {
83                 radlog(L_ERR, "rlm_eap_tls: Unable to set DH parameters");
84                 DH_free(dh);
85                 return -1;
86         }
87
88         DH_free(dh);
89         return 0;
90 }
91
92 /*
93  *      Generte ephemeral RSA keys.
94  */
95 static int generate_eph_rsa_key(SSL_CTX *ctx)
96 {
97         RSA *rsa;
98
99         rsa = RSA_generate_key(512, RSA_F4, NULL, NULL);
100
101         if (!SSL_CTX_set_tmp_rsa(ctx, rsa)) {
102                 radlog(L_ERR, "rlm_eap_tls: Couldn't set RSA key");
103                 return -1;
104         }
105
106         RSA_free(rsa);
107         return 0;
108 }
109
110
111 /*
112  *      Create Global context SSL and use it in every new session
113  *
114  *      - Load the trusted CAs
115  *      - Load the Private key & the certificate
116  *      - Set the Context options & Verify options
117  */
118 static SSL_CTX *init_tls_ctx(EAP_TLS_CONF *conf)
119 {
120         SSL_METHOD *meth;
121         SSL_CTX *ctx;
122         int verify_mode = 0;
123         int ctx_options = 0;
124         int type;
125
126         /*
127          *      Add all the default ciphers and message digests
128          *      Create our context.
129          */
130         SSL_library_init();
131         SSL_load_error_strings();
132
133         meth = TLSv1_method();
134         ctx = SSL_CTX_new(meth);
135
136         /*
137          * Identify the type of certificates that needs to be loaded
138          */
139         if (conf->file_type) {
140                 type = SSL_FILETYPE_PEM;
141         } else {
142                 type = SSL_FILETYPE_ASN1;
143         }
144
145         /* Load the CAs we trust */
146         if (!(SSL_CTX_load_verify_locations(ctx, conf->ca_file, conf->ca_path)) ||
147             (!SSL_CTX_set_default_verify_paths(ctx))) {
148                 ERR_print_errors_fp(stderr);
149                 radlog(L_ERR, "rlm_eap_tls: Error reading Trusted root CA list");
150                 return NULL;
151         }
152         SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(conf->ca_file));
153
154         /* 
155          * Set the password to load private key
156          */
157         if (conf->private_key_password) {
158                 SSL_CTX_set_default_passwd_cb_userdata(ctx, conf->private_key_password);
159                 SSL_CTX_set_default_passwd_cb(ctx, cbtls_password);
160         }
161
162         /* Load our keys and certificates*/
163         if (!(SSL_CTX_use_certificate_file(ctx, conf->certificate_file, type))) {
164                 ERR_print_errors_fp(stderr);
165                 radlog(L_ERR, "rlm_eap_tls: Error reading certificate file");
166                 return NULL;
167         }
168
169         if (!(SSL_CTX_use_PrivateKey_file(ctx, conf->private_key_file, type))) {
170                 ERR_print_errors_fp(stderr);
171                 radlog(L_ERR, "rlm_eap_tls: Error reading private key file");
172                 return NULL;
173         }
174
175         /*
176          * Check if the loaded private key is the right one
177          */
178         if (!SSL_CTX_check_private_key(ctx)) {
179                 radlog(L_ERR, "rlm_eap_tls: Private key does not match the certificate public key");
180                 return NULL;
181         }
182
183         /*
184          *      Set ctx_options
185          */
186         ctx_options |= SSL_OP_NO_SSLv2;
187         ctx_options |= SSL_OP_NO_SSLv3;
188
189         /* 
190          *      SSL_OP_SINGLE_DH_USE must be used in order to prevent
191          *      small subgroup attacks and forward secrecy. Always
192          *      using
193          *
194          *      SSL_OP_SINGLE_DH_USE has an impact on the computer
195          *      time needed during negotiation, but it is not very
196          *      large.
197          */
198         ctx_options |= SSL_OP_SINGLE_DH_USE;
199         SSL_CTX_set_options(ctx, ctx_options);
200
201         /*
202          *      TODO: Set the RSA & DH
203          *      SSL_CTX_set_tmp_rsa_callback(ctx, cbtls_rsa);
204          *      SSL_CTX_set_tmp_dh_callback(ctx, cbtls_dh);
205          */
206
207         /*
208          *      set the message callback to identify the type of
209          *      message.  For every new session, there can be a
210          *      different callback argument.
211          *
212          *      SSL_CTX_set_msg_callback(ctx, cbtls_msg);
213          */
214
215         /* Set Info callback */
216         SSL_CTX_set_info_callback(ctx, cbtls_info);
217
218         /*
219          *      Set verify modes
220          *      Always verify the peer certificate
221          */
222         verify_mode |= SSL_VERIFY_PEER;
223         verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
224         verify_mode |= SSL_VERIFY_CLIENT_ONCE;
225         SSL_CTX_set_verify(ctx, verify_mode, cbtls_verify);
226
227         if (conf->verify_depth) {
228                 SSL_CTX_set_verify_depth(ctx, conf->verify_depth);
229         }
230
231         /* Load randomness */
232         if (!(RAND_load_file(conf->random_file, 1024*1024))) {
233                 ERR_print_errors_fp(stderr);
234                 radlog(L_ERR, "rlm_eap_tls: Error loading randomness");
235                 return NULL;
236         }
237
238         return ctx;
239 }
240
241
242 /*
243  *      Detach the EAP-TLS module.
244  */
245 static int eaptls_detach(void *arg)
246 {
247         EAP_TLS_CONF     *conf;
248         eap_tls_t        *inst;
249
250         inst = (eap_tls_t *) arg;
251         conf = inst->conf;
252
253         if (conf) {
254                 if (conf->dh_file) free(conf->dh_file);
255                 conf->dh_file = NULL;
256                 if (conf->certificate_file) free(conf->certificate_file);
257                 conf->certificate_file = NULL;
258                 if (conf->private_key_file) free(conf->private_key_file);
259                 conf->private_key_file = NULL;
260                 if (conf->private_key_password) free(conf->private_key_password);
261                 conf->private_key_password = NULL;
262                 if (conf->random_file) free(conf->random_file);
263                 conf->random_file = NULL;
264                 
265                 free(inst->conf);
266                 inst->conf = NULL;
267         }
268
269         if (inst->ctx) SSL_CTX_free(inst->ctx);
270         inst->ctx = NULL;
271
272         free(inst);
273
274         return 0;
275 }
276
277
278 /*
279  *      Attach the EAP-TLS module.
280  */
281 static int eaptls_attach(CONF_SECTION *cs, void **instance)
282 {
283         EAP_TLS_CONF     *conf;
284         eap_tls_t        *inst;
285
286         /* Store all these values in the data structure for later references */
287         inst = (eap_tls_t *)malloc(sizeof(*inst));
288         if (!inst) {
289                 radlog(L_ERR, "rlm_eap_tls: out of memory");
290                 return -1;
291         }
292         memset(inst, 0, sizeof(*inst));
293
294         /*
295          *      Parse the config file & get all the configured values
296          */
297         conf = (EAP_TLS_CONF *)malloc(sizeof(*conf));
298         if (conf == NULL) {
299                 radlog(L_ERR, "rlm_eap_tls: out of memory");
300                 return -1;
301         }
302         memset(conf, 0, sizeof(*conf));
303
304         inst->conf = conf;
305         if (cf_section_parse(cs, conf, module_config) < 0) {
306                 eaptls_detach(inst);
307                 return -1;
308         }
309
310
311         /*
312          *      Initialize TLS
313          */
314         inst->ctx = init_tls_ctx(conf);
315         if (inst->ctx == NULL) {
316                 eaptls_detach(inst);
317                 return -1;
318         }
319
320         if (load_dh_params(inst->ctx, conf->dh_file) < 0) {
321                 eaptls_detach(inst);
322                 return -1;
323         }
324         if (generate_eph_rsa_key(inst->ctx) < 0) {
325                 eaptls_detach(inst);
326                 return -1;
327         }
328
329         *instance = inst;
330
331         return 0;
332 }
333
334
335 /*
336  *      Send an initial eap-tls request to the peer.
337  *
338  *      Frame eap reply packet.
339  *      len = header + type + tls_typedata
340  *      tls_typedata = flags(Start (S) bit set, and no data)
341  *
342  *      Once having received the peer's Identity, the EAP server MUST
343  *      respond with an EAP-TLS/Start packet, which is an
344  *      EAP-Request packet with EAP-Type=EAP-TLS, the Start (S) bit
345  *      set, and no data.  The EAP-TLS conversation will then begin,
346  *      with the peer sending an EAP-Response packet with
347  *      EAP-Type = EAP-TLS.  The data field of that packet will
348  *      be the TLS data.
349  *
350  *      Fragment length is Framed-MTU - 4.
351  *
352  *      http://mail.frascone.com/pipermail/public/eap/2003-July/001426.html
353  */
354 static int eaptls_initiate(void *type_arg, EAP_HANDLER *handler)
355 {
356         int             status;
357         tls_session_t   *ssn;
358         eap_tls_t       *inst;
359         VALUE_PAIR      *vp;
360         int             client_cert = TRUE;
361
362         inst = (eap_tls_t *)type_arg;
363
364         /*
365          *      If we're TTLS or PEAP, then do NOT require a client
366          *      certificate.
367          *
368          *      FIXME: This should be more configurable.
369          */
370         if (handler->eap_type != PW_EAP_TLS) {
371                 vp = pairfind(handler->request->config_items,
372                               PW_EAP_TLS_REQUIRE_CLIENT_CERT);
373                 if (!vp) {
374                         client_cert = FALSE;
375                 } else {
376                         client_cert = vp->lvalue;
377                 }
378         }
379
380         /*
381          *      Every new session is started only from EAP-TLS-START.
382          *      Before Sending EAP-TLS-START, open a new SSL session.
383          *      Create all the required data structures & store them
384          *      in Opaque.  So that we can use these data structures
385          *      when we get the response
386          */
387         ssn = eaptls_new_session(inst->ctx, client_cert);
388         if (!ssn) {
389                 return 0;
390         }
391
392         /*
393          *      Create a structure for all the items required to be
394          *      verified for each client and set that as opaque data
395          *      structure.
396          *
397          *      NOTE: If we want to set each item sepearately then
398          *      this index should be global.
399          */
400         SSL_set_ex_data(ssn->ssl, 0, (void *)handler->identity);
401
402         ssn->length_flag = inst->conf->include_length;
403
404         /*
405          *      We set a default fragment size, unless the Framed-MTU
406          *      tells us it's too big.
407          */
408         ssn->offset = inst->conf->fragment_size;
409         vp = pairfind(handler->request->packet->vps, PW_FRAMED_MTU);
410         if (vp && ((vp->lvalue - 4) < ssn->offset)) {
411                 ssn->offset = vp->lvalue - 4;
412         }
413
414         handler->opaque = ((void *)ssn);
415         handler->free_opaque = session_free;
416
417         DEBUG2("  rlm_eap_tls: Initiate");
418
419         /*
420          *      PEAP-specific breakage.
421          */
422         if (handler->eap_type == PW_EAP_PEAP) {
423                 ssn->peap_flag = 0x02;
424         }
425
426         /*
427          *      TLS session initialization is over.  *Now handle TLS
428          *      related handshaking or application data.
429          */
430         status = eaptls_start(handler->eap_ds, ssn->peap_flag);
431         DEBUG2("  rlm_eap_tls: Start returned %d", status);
432         if (status == 0)
433                 return 0;
434
435         /*
436          *      The next stage to process the packet.
437          */
438         handler->stage = AUTHENTICATE;
439
440         return 1;
441 }
442
443 /*
444  *      Do authentication, by letting EAP-TLS do most of the work.
445  */
446 static int eaptls_authenticate(void *arg, EAP_HANDLER *handler)
447 {
448         eaptls_status_t status;
449         tls_session_t *tls_session = (tls_session_t *) handler->opaque;
450
451         DEBUG2("  rlm_eap_tls: Authenticate");
452
453         status = eaptls_process(handler);
454         DEBUG2("  eaptls_process returned %d\n", status);
455         switch (status) {
456                 /*
457                  *      EAP-TLS handshake was successful, return an
458                  *      EAP-TLS-Success packet here.
459                  */
460         case EAPTLS_SUCCESS:
461                 break;
462
463                 /*
464                  *      The TLS code is still working on the TLS
465                  *      exchange, and it's a valid TLS request.
466                  *      do nothing.
467                  */
468         case EAPTLS_HANDLED:
469                 return 1;
470
471                 /*
472                  *      Handshake is done, proceed with decoding tunneled
473                  *      data.
474                  */
475         case EAPTLS_OK:
476                 DEBUG2("  rlm_eap_tls: Received unexpected tunneled data after successful handshake.");
477                 eaptls_fail(handler->eap_ds, 0);
478                 return 0;
479                 break;
480
481                 /*
482                  *      Anything else: fail.
483                  */
484         default:
485                 return 0;
486         }
487
488         /*
489          *      Success: Return MPPE keys.
490          */
491         eaptls_success(handler->eap_ds, 0);
492         eaptls_gen_mppe_keys(&handler->request->reply->vps, 
493                              tls_session->ssl,
494                              "client EAP encryption");
495         return 1;
496 }
497
498 /*
499  *      The module name should be the only globally exported symbol.
500  *      That is, everything else should be 'static'.
501  */
502 EAP_TYPE rlm_eap_tls = {
503         "eap_tls",
504         eaptls_attach,                  /* attach */
505         eaptls_initiate,                /* Start the initial request */
506         NULL,                           /* authorization */
507         eaptls_authenticate,            /* authentication */
508         eaptls_detach                   /* detach */
509 };