1 /* * eap-tls.c - EAP-TLS implementation for PPP
2 *
3 * Copyright (c) Beniamino Galvani 2005 All rights reserved.
4 * Jan Just Keijser 2006-2019 All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 *
18 * 3. The name(s) of the authors of this software must not be used to
19 * endorse or promote products derived from this software without
20 * prior written permission.
21 *
22 * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
23 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
24 * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
25 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
26 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
27 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
28 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
29 *
30 */
31
32 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
35
36 #include <string.h>
37 #include <strings.h>
38 #include <unistd.h>
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 #include <fcntl.h>
42
43 #include <openssl/conf.h>
44 #ifndef OPENSSL_NO_ENGINE
45 #include <openssl/engine.h>
46 #endif
47 #include <openssl/ssl.h>
48 #include <openssl/hmac.h>
49 #include <openssl/err.h>
50 #include <openssl/ui.h>
51 #include <openssl/x509v3.h>
52 #include <openssl/pkcs12.h>
53
54 #include "pppd-private.h"
55 #include "tls.h"
56 #include "eap.h"
57 #include "eap-tls.h"
58 #include "fsm.h"
59 #include "lcp.h"
60 #include "chap_ms.h"
61 #include "mppe.h"
62 #include "pathnames.h"
63
64 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
65 #define SSL3_RT_HEADER 0x100
66 #endif
67
68 typedef struct pw_cb_data
69 {
70 const void *password;
71 const char *prompt_info;
72 } PW_CB_DATA;
73
74 #ifndef OPENSSL_NO_ENGINE
75 /* The openssl configuration file and engines can be loaded only once */
76 static CONF *ssl_config = NULL;
77 static ENGINE *cert_engine = NULL;
78 static ENGINE *pkey_engine = NULL;
79 #endif
80
81 /* TLSv1.3 do we have a session ticket ? */
82 static int have_session_ticket = 0;
83
84 void ssl_msg_callback(int write_p, int version, int ct, const void *buf,
85 size_t len, SSL * ssl, void *arg);
86 int ssl_new_session_cb(SSL *s, SSL_SESSION *sess);
87
88 #ifdef PPP_WITH_MPPE
89 #define EAPTLS_MPPE_KEY_LEN 32
90
91 /*
92 * Generate keys according to RFC 2716 and add to reply
93 */
eaptls_gen_mppe_keys(struct eaptls_session * ets,int client)94 void eaptls_gen_mppe_keys(struct eaptls_session *ets, int client)
95 {
96 unsigned char out[4*EAPTLS_MPPE_KEY_LEN];
97 const char *prf_label;
98 size_t prf_size;
99 unsigned char eap_tls13_context[] = { EAPT_TLS };
100 unsigned char *context = NULL;
101 size_t context_len = 0;
102
103 dbglog("EAP-TLS generating MPPE keys");
104 if (ets->tls_v13)
105 {
106 prf_label = "EXPORTER_EAP_TLS_Key_Material";
107 context = eap_tls13_context;
108 context_len = 1;
109 }
110 else
111 {
112 prf_label = "client EAP encryption";
113 }
114
115 dbglog("EAP-TLS PRF label = %s", prf_label);
116 prf_size = strlen(prf_label);
117 if (SSL_export_keying_material(ets->ssl, out, sizeof(out), prf_label, prf_size,
118 context, context_len, 0) != 1)
119 {
120 warn( "EAP-TLS: Failed generating keying material" );
121 return;
122 }
123
124 /*
125 * We now have the master send and receive keys.
126 * From these, generate the session send and receive keys.
127 * (see RFC3079 / draft-ietf-pppext-mppe-keys-03.txt for details)
128 */
129 if (client)
130 {
131 mppe_set_keys(out, out + EAPTLS_MPPE_KEY_LEN, EAPTLS_MPPE_KEY_LEN);
132 }
133 else
134 {
135 mppe_set_keys(out + EAPTLS_MPPE_KEY_LEN, out, EAPTLS_MPPE_KEY_LEN);
136 }
137 }
138
139 #endif /* PPP_WITH_MPPE */
140
password_callback(char * buf,int size,int rwflag,void * u)141 static int password_callback (char *buf, int size, int rwflag, void *u)
142 {
143 if (buf)
144 {
145 strlcpy (buf, passwd, size);
146 return strlen (buf);
147 }
148 return 0;
149 }
150
151
eaptls_ssl_load_config(void)152 static CONF *eaptls_ssl_load_config( void )
153 {
154 CONF *config;
155 int ret_code;
156 long error_line = 33;
157
158 config = NCONF_new( NULL );
159 dbglog( "Loading OpenSSL config file" );
160 ret_code = NCONF_load( config, PPP_PATH_OPENSSLCONFFILE, &error_line );
161 if (ret_code == 0)
162 {
163 warn( "EAP-TLS: Error in OpenSSL config file %s at line %d", PPP_PATH_OPENSSLCONFFILE, error_line );
164 NCONF_free( config );
165 config = NULL;
166 ERR_clear_error();
167 }
168
169 dbglog( "Loading OpenSSL built-ins" );
170 #ifndef OPENSSL_NO_ENGINE
171 ENGINE_load_builtin_engines();
172 #endif
173 #if !defined(LIBRESSL_VERSION_NUMBER) || (LIBRESSL_VERSION_NUMBER < 0x4000000fL)
174 OPENSSL_load_builtin_modules();
175 #endif
176
177 dbglog( "Loading OpenSSL configured modules" );
178 if (CONF_modules_load( config, NULL, 0 ) <= 0 )
179 {
180 warn( "EAP-TLS: Error loading OpenSSL modules" );
181 tls_log_sslerr();
182 config = NULL;
183 }
184
185 return config;
186 }
187
188 #ifndef OPENSSL_NO_ENGINE
eaptls_ssl_load_engine(char * engine_name)189 static ENGINE *eaptls_ssl_load_engine( char *engine_name )
190 {
191 ENGINE *e = NULL;
192
193 dbglog( "Enabling OpenSSL auto engines" );
194 ENGINE_register_all_complete();
195
196 dbglog( "Loading OpenSSL '%s' engine support", engine_name );
197 e = ENGINE_by_id( engine_name );
198 if (!e)
199 {
200 dbglog( "EAP-TLS: Cannot load '%s' engine support, trying 'dynamic'", engine_name );
201 e = ENGINE_by_id( "dynamic" );
202 if (e)
203 {
204 if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine_name, 0)
205 || !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0))
206 {
207 warn( "EAP-TLS: Error loading dynamic engine '%s'", engine_name );
208 tls_log_sslerr();
209 ENGINE_free(e);
210 e = NULL;
211 }
212 }
213 else
214 {
215 warn( "EAP-TLS: Cannot load dynamic engine support" );
216 }
217 }
218
219 if (e)
220 {
221 dbglog( "Initialising engine" );
222 if(!ENGINE_set_default(e, ENGINE_METHOD_ALL))
223 {
224 warn( "EAP-TLS: Cannot use that engine" );
225 tls_log_sslerr();
226 ENGINE_free(e);
227 e = NULL;
228 }
229 }
230
231 return e;
232 }
233 #endif
234
235
236 #ifndef OPENSSL_NO_ENGINE
eaptls_UI_writer(UI * ui,UI_STRING * uis)237 static int eaptls_UI_writer(UI *ui, UI_STRING *uis)
238 {
239 PW_CB_DATA* cb_data = (PW_CB_DATA*)UI_get0_user_data(ui);
240 UI_set_result(ui, uis, cb_data->password);
241 return 1;
242 }
243
eaptls_UI_stub(UI * ui)244 static int eaptls_UI_stub(UI* ui) {
245 return 1;
246 }
247
eaptls_UI_reader(UI * ui,UI_STRING * uis)248 static int eaptls_UI_reader(UI *ui, UI_STRING *uis) {
249 return 1;
250 }
251 #endif
252
253 /*
254 * Initialize the SSL stacks and tests if certificates, key and crl
255 * for client or server use can be loaded.
256 */
eaptls_init_ssl(int init_server,char * cacertfile,char * capath,char * certfile,char * privkeyfile,char * pkcs12)257 SSL_CTX *eaptls_init_ssl(int init_server, char *cacertfile, char *capath,
258 char *certfile, char *privkeyfile, char *pkcs12)
259 {
260 #ifndef OPENSSL_NO_ENGINE
261 char *cert_engine_name = NULL;
262 char *pkey_engine_name = NULL;
263 char *idx;
264 #endif
265 SSL_CTX *ctx;
266 SSL *ssl;
267 X509 *tmp;
268 X509 *cert = NULL;
269 PKCS12 *p12 = NULL;
270 EVP_PKEY *pkey = NULL;
271 STACK_OF(X509) *chain = NULL;
272 BIO *input;
273 int ret;
274
275 /*
276 * Without these can't continue
277 */
278 if (!pkcs12[0])
279 {
280 if (!(cacertfile[0] || capath[0]))
281 {
282 error("EAP-TLS: CA certificate file or path missing");
283 return NULL;
284 }
285
286 if (!certfile[0])
287 {
288 error("EAP-TLS: Certificate missing");
289 return NULL;
290 }
291
292 if (!privkeyfile[0])
293 {
294 error("EAP-TLS: Private key missing");
295 return NULL;
296 }
297 }
298
299 tls_init();
300
301 #ifndef OPENSSL_NO_ENGINE
302 /* load the openssl config file only once and load it before triggering
303 the loading of a global openssl config file via SSL_CTX_new()
304 */
305 if (!ssl_config)
306 ssl_config = eaptls_ssl_load_config();
307 #endif
308
309 ctx = SSL_CTX_new(tls_method());
310 if (!ctx) {
311 error("EAP-TLS: Cannot initialize SSL CTX context");
312 goto fail;
313 }
314
315 #ifndef OPENSSL_NO_ENGINE
316 /* if the certificate filename is of the form engine:id. e.g.
317 pkcs11:12345
318 then we try to load and use this engine.
319 If the certificate filename starts with a / or . then we
320 ALWAYS assume it is a file and not an engine/pkcs11 identifier
321 */
322 if ( (idx = index( certfile, ':' )) != NULL )
323 {
324 cert_engine_name = strdup( certfile );
325 cert_engine_name[idx - certfile] = 0;
326
327 dbglog( "Using engine '%s' for certificate, URI: '%s'",
328 cert_engine_name, certfile );
329 }
330
331 /* if the privatekey filename is of the form engine:id. e.g.
332 pkcs11:12345
333 then we try to load and use this engine.
334 If the privatekey filename starts with a / or . then we
335 ALWAYS assume it is a file and not an engine/pkcs11 identifier
336 */
337 if ( (idx = index( privkeyfile, ':' )) != NULL )
338 {
339 pkey_engine_name = strdup( privkeyfile );
340 pkey_engine_name[idx - privkeyfile] = 0;
341
342 dbglog( "Using engine '%s' for private key, URI: '%s'",
343 pkey_engine_name, privkeyfile );
344 }
345
346 if (cert_engine_name && pkey_engine_name)
347 {
348 if (strlen( certfile ) - strlen( cert_engine_name ) == 1)
349 {
350 if (strlen( privkeyfile ) - strlen( pkey_engine_name ) == 1)
351 error( "EAP-TLS: both the certificate and privatekey identifiers are missing!" );
352 else
353 {
354 dbglog( "Substituting privatekey identifier for certificate identifier" );
355 certfile = privkeyfile;
356 }
357 }
358 else
359 {
360 if (strlen( privkeyfile ) - strlen( pkey_engine_name ) == 1)
361 {
362 dbglog( "Substituting certificate identifier for privatekey identifier" );
363 privkeyfile = certfile;
364 }
365 }
366 }
367
368 if (ssl_config && cert_engine_name)
369 cert_engine = eaptls_ssl_load_engine( cert_engine_name );
370
371 if (ssl_config && pkey_engine_name)
372 {
373 /* don't load the same engine twice */
374 if ( cert_engine && strcmp( cert_engine_name, pkey_engine_name) == 0 )
375 pkey_engine = cert_engine;
376 else
377 pkey_engine = eaptls_ssl_load_engine( pkey_engine_name );
378 }
379
380 if (cert_engine_name)
381 free(cert_engine_name);
382
383 if (pkey_engine_name)
384 free(pkey_engine_name);
385
386 #endif
387
388 SSL_CTX_set_default_passwd_cb (ctx, password_callback);
389
390 if (tls_set_ca(ctx, capath, cacertfile) != 0) {
391 goto fail;
392 }
393
394 if (init_server)
395 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(cacertfile));
396
397 #ifndef OPENSSL_NO_ENGINE
398 if (cert_engine)
399 {
400 struct
401 {
402 const char *s_slot_cert_id;
403 X509 *cert;
404 } cert_info;
405
406 cert_info.s_slot_cert_id = certfile;
407 cert_info.cert = NULL;
408
409 if (!ENGINE_ctrl_cmd( cert_engine, "LOAD_CERT_CTRL", 0, &cert_info, NULL, 0 ) )
410 {
411 error( "EAP-TLS: Error loading certificate with URI '%s' from engine", certfile );
412 goto fail;
413 }
414
415 if (cert_info.cert)
416 {
417 dbglog( "Got the certificate" );
418 dbglog( "subject = %s", X509_NAME_oneline( X509_get_subject_name( cert_info.cert ), NULL, 0 ) );
419 cert = cert_info.cert;
420 }
421 else
422 {
423 warn("EAP-TLS: Cannot load key with URI: '%s'", certfile );
424 tls_log_sslerr();
425 }
426 }
427 else
428 #endif
429 {
430 if (pkcs12[0])
431 {
432 input = BIO_new_file(pkcs12, "r");
433 if (input == NULL)
434 {
435 error("EAP-TLS: Cannot open `%s' PKCS12 for input", pkcs12);
436 goto fail;
437 }
438
439 p12 = d2i_PKCS12_bio(input, NULL);
440 BIO_free(input);
441 if (!p12)
442 {
443 error("EAP-TLS: Cannot load PKCS12 certificate");
444 goto fail;
445 }
446
447 if (PKCS12_parse(p12, passwd, &pkey, &cert, &chain) != 1)
448 {
449 error("EAP-TLS: Cannot parse PKCS12 certificate, invalid password");
450 PKCS12_free(p12);
451 goto fail;
452 }
453
454 PKCS12_free(p12);
455 }
456 else
457 {
458 if (!SSL_CTX_use_certificate_chain_file(ctx, certfile))
459 {
460 error( "EAP-TLS: Cannot load certificate %s", certfile );
461 goto fail;
462 }
463 }
464 }
465
466 if (cert)
467 {
468 if (!SSL_CTX_use_certificate(ctx, cert))
469 {
470 error("EAP-TLS: Cannot use load certificate");
471 goto fail;
472 }
473
474 if (chain)
475 {
476 int i;
477 for (i = 0; i < sk_X509_num(chain); i++)
478 {
479 if (!SSL_CTX_add_extra_chain_cert(ctx, sk_X509_value(chain, i)))
480 {
481 error("EAP-TLS: Cannot add extra chain certificate");
482 goto fail;
483 }
484 }
485 }
486 }
487
488 /*
489 * Check the Before and After dates of the certificate
490 */
491 ssl = SSL_new(ctx);
492 tmp = SSL_get_certificate(ssl);
493
494 ret = X509_cmp_time(X509_get_notBefore(tmp), NULL);
495 if (ret == 0)
496 {
497 warn( "EAP-TLS: Failed to read certificate notBefore field.");
498 }
499 if (ret > 0)
500 {
501 warn( "EAP-TLS: Your certificate is not yet valid!");
502 }
503
504 ret = X509_cmp_time(X509_get_notAfter(tmp), NULL);
505 if (ret == 0)
506 {
507 warn( "EAP-TLS: Failed to read certificate notAfter field.");
508 }
509 if (ret < 0)
510 {
511 warn( "EAP-TLS: Your certificate has expired!");
512 }
513 SSL_free(ssl);
514
515 #ifndef OPENSSL_NO_ENGINE
516 if (pkey_engine)
517 {
518 PW_CB_DATA cb_data;
519
520 cb_data.password = passwd;
521 cb_data.prompt_info = privkeyfile;
522
523 if (passwd[0] != 0)
524 {
525 UI_METHOD* transfer_pin = UI_create_method("transfer_pin");
526
527 UI_method_set_writer(transfer_pin, eaptls_UI_writer);
528 UI_method_set_opener(transfer_pin, eaptls_UI_stub);
529 UI_method_set_closer(transfer_pin, eaptls_UI_stub);
530 UI_method_set_flusher(transfer_pin, eaptls_UI_stub);
531 UI_method_set_reader(transfer_pin, eaptls_UI_reader);
532
533 dbglog( "Using our private key URI: '%s' in engine", privkeyfile );
534 pkey = ENGINE_load_private_key(pkey_engine, privkeyfile, transfer_pin, &cb_data);
535
536 if (transfer_pin) UI_destroy_method(transfer_pin);
537 }
538 else {
539 dbglog( "Loading private key URI: '%s' from engine", privkeyfile );
540 pkey = ENGINE_load_private_key(pkey_engine, privkeyfile, NULL, NULL);
541 }
542 }
543 else
544 #endif
545 {
546 if (!pkey)
547 {
548 input = BIO_new_file(privkeyfile, "r");
549 if (!input)
550 {
551 error("EAP-TLS: Could not open private key, %s", privkeyfile);
552 goto fail;
553 }
554
555 pkey = PEM_read_bio_PrivateKey(input, NULL, password_callback, NULL);
556 BIO_free(input);
557 if (!pkey)
558 {
559 error("EAP-TLS: Cannot load private key, %s", privkeyfile);
560 goto fail;
561 }
562 }
563 }
564
565 if (SSL_CTX_use_PrivateKey(ctx, pkey) != 1)
566 {
567 error("EAP-TLS: Cannot use private key");
568 goto fail;
569 }
570
571 if (SSL_CTX_check_private_key(ctx) != 1)
572 {
573 error("EAP-TLS: Private key fails security check");
574 goto fail;
575 }
576
577 /* Configure the default options */
578 tls_set_opts(ctx);
579
580 /* Set up a SSL Session cache with a callback. This is needed for TLSv1.3+.
581 * During the initial handshake the server signals to the client early on
582 * that the handshake is finished, even before the client has sent its
583 * credentials to the server. The actual connection (and moment that the
584 * client sends its credentials) only starts after the arrival of the first
585 * session ticket. The 'ssl_new_session_cb' catches this ticket.
586 */
587 SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL_STORE);
588 SSL_CTX_sess_set_new_cb(ctx, ssl_new_session_cb);
589
590 /* Configure the maximum SSL version */
591 tls_set_version(ctx, max_tls_version);
592
593 /* Configure the callback */
594 if (tls_set_verify(ctx, 5)) {
595 goto fail;
596 }
597
598 /* Configure CRL check (if any) */
599 if (tls_set_crl(ctx, crl_dir, crl_file)) {
600 goto fail;
601 }
602
603 return ctx;
604
605 fail:
606
607 if (cert)
608 X509_free(cert);
609
610 if (pkey)
611 EVP_PKEY_free(pkey);
612
613 if (chain)
614 sk_X509_pop_free(chain, X509_free);
615
616 tls_log_sslerr();
617 SSL_CTX_free(ctx);
618 return NULL;
619 }
620
621 /*
622 * Determine the maximum packet size by looking at the LCP handshake
623 */
624
eaptls_get_mtu(int unit)625 static int eaptls_get_mtu(int unit)
626 {
627 int mtu, mru;
628
629 lcp_options *wo = &lcp_wantoptions[unit];
630 lcp_options *go = &lcp_gotoptions[unit];
631 lcp_options *ho = &lcp_hisoptions[unit];
632 lcp_options *ao = &lcp_allowoptions[unit];
633
634 mtu = ho->neg_mru? ho->mru: PPP_MRU;
635 mru = go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU;
636 mtu = MIN(MIN(mtu, mru), ao->mru)- PPP_HDRLEN - 10;
637
638 dbglog("MTU = %d", mtu);
639 return mtu;
640 }
641
642
643 /*
644 * Init the ssl handshake (server mode)
645 */
eaptls_init_ssl_server(eap_state * esp)646 int eaptls_init_ssl_server(eap_state * esp)
647 {
648 struct eaptls_session *ets;
649 char servcertfile[MAXWORDLEN];
650 char clicertfile[MAXWORDLEN];
651 char cacertfile[MAXWORDLEN];
652 char capath[MAXWORDLEN];
653 char pkfile[MAXWORDLEN];
654 char pkcs12[MAXWORDLEN];
655
656 /*
657 * Allocate new eaptls session
658 */
659 esp->es_server.ea_session = malloc(sizeof(struct eaptls_session));
660 if (!esp->es_server.ea_session)
661 fatal("Allocation error");
662 ets = esp->es_server.ea_session;
663
664 if (!esp->es_server.ea_peer) {
665 error("EAP-TLS: Error: client name not set (BUG)");
666 return 0;
667 }
668
669 dbglog( "getting eaptls secret" );
670 if (!get_eaptls_secret(esp->es_unit, esp->es_server.ea_peer,
671 esp->es_server.ea_name, clicertfile,
672 servcertfile, cacertfile, capath, pkfile, pkcs12, 1)) {
673 error( "EAP-TLS: Cannot get secret/password for client \"%s\", server \"%s\"",
674 esp->es_server.ea_peer, esp->es_server.ea_name );
675 return 0;
676 }
677
678 ets->mtu = eaptls_get_mtu(esp->es_unit);
679
680 ets->ctx = eaptls_init_ssl(1, cacertfile, capath, servcertfile, pkfile, pkcs12);
681 if (!ets->ctx)
682 goto fail;
683
684 if (!(ets->ssl = SSL_new(ets->ctx)))
685 goto fail;
686
687 if (tls_set_verify_info(ets->ssl, esp->es_server.ea_peer,
688 clicertfile, 0, &ets->info))
689 goto fail;
690
691 /*
692 * Set auto-retry to avoid timeouts on BIO_read
693 */
694 SSL_set_mode(ets->ssl, SSL_MODE_AUTO_RETRY);
695
696 /*
697 * Initialize the BIOs we use to read/write to ssl engine
698 */
699 ets->into_ssl = BIO_new(BIO_s_mem());
700 ets->from_ssl = BIO_new(BIO_s_mem());
701 SSL_set_bio(ets->ssl, ets->into_ssl, ets->from_ssl);
702
703 SSL_set_msg_callback(ets->ssl, ssl_msg_callback);
704 SSL_set_msg_callback_arg(ets->ssl, ets);
705
706 SSL_set_accept_state(ets->ssl);
707
708 ets->tls_v13 = 0;
709
710 ets->data = NULL;
711 ets->datalen = 0;
712 ets->alert_sent = 0;
713 ets->alert_recv = 0;
714 return 1;
715
716 fail:
717 SSL_CTX_free(ets->ctx);
718 return 0;
719 }
720
721 /*
722 * Init the ssl handshake (client mode)
723 */
eaptls_init_ssl_client(eap_state * esp)724 int eaptls_init_ssl_client(eap_state * esp)
725 {
726 struct eaptls_session *ets;
727 char servcertfile[MAXWORDLEN];
728 char clicertfile[MAXWORDLEN];
729 char cacertfile[MAXWORDLEN];
730 char capath[MAXWORDLEN];
731 char pkfile[MAXWORDLEN];
732 char pkcs12[MAXWORDLEN];
733
734 /*
735 * Allocate new eaptls session
736 */
737 esp->es_client.ea_session = malloc(sizeof(struct eaptls_session));
738 if (!esp->es_client.ea_session)
739 fatal("Allocation error");
740 ets = esp->es_client.ea_session;
741 ets->mtu = eaptls_get_mtu(esp->es_unit);
742
743 dbglog( "calling get_eaptls_secret" );
744 if (!get_eaptls_secret(esp->es_unit, esp->es_client.ea_name,
745 esp->es_client.ea_peer, clicertfile,
746 servcertfile, cacertfile, capath, pkfile, pkcs12, 0)) {
747 error( "EAP-TLS: Cannot get secret/password for client \"%s\", server \"%s\"",
748 esp->es_client.ea_name, esp->es_client.ea_peer);
749 return 0;
750 }
751
752 dbglog( "calling eaptls_init_ssl" );
753 ets->ctx = eaptls_init_ssl(0, cacertfile, capath, clicertfile, pkfile, pkcs12);
754 if (!ets->ctx)
755 goto fail;
756
757 ets->ssl = SSL_new(ets->ctx);
758 if (!ets->ssl)
759 goto fail;
760
761 if (tls_set_verify_info(ets->ssl, esp->es_client.ea_peer,
762 servcertfile, 0, &ets->info))
763 goto fail;
764
765 /*
766 * Initialize the BIOs we use to read/write to ssl engine
767 */
768 dbglog( "Initializing SSL BIOs" );
769 ets->into_ssl = BIO_new(BIO_s_mem());
770 ets->from_ssl = BIO_new(BIO_s_mem());
771 SSL_set_bio(ets->ssl, ets->into_ssl, ets->from_ssl);
772
773 SSL_set_msg_callback(ets->ssl, ssl_msg_callback);
774 SSL_set_msg_callback_arg(ets->ssl, ets);
775 SSL_set_connect_state(ets->ssl);
776
777 ets->tls_v13 = 0;
778
779 ets->data = NULL;
780 ets->datalen = 0;
781 ets->alert_sent = 0;
782 ets->alert_recv = 0;
783 return 1;
784
785 fail:
786 dbglog( "eaptls_init_ssl_client: fail" );
787 SSL_CTX_free(ets->ctx);
788 return 0;
789
790 }
791
eaptls_free_session(struct eaptls_session * ets)792 void eaptls_free_session(struct eaptls_session *ets)
793 {
794 if (ets->ssl)
795 SSL_free(ets->ssl);
796
797 if (ets->ctx)
798 SSL_CTX_free(ets->ctx);
799
800 if (ets->info)
801 tls_free_verify_info(&ets->info);
802
803 free(ets);
804 }
805
806
eaptls_is_init_finished(struct eaptls_session * ets)807 int eaptls_is_init_finished(struct eaptls_session *ets)
808 {
809 if (ets->ssl && SSL_is_init_finished(ets->ssl))
810 {
811 if (ets->tls_v13)
812 return have_session_ticket;
813 else
814 return 1;
815 }
816
817 return 0;
818 }
819
820 /*
821 * Handle a received packet, reassembling fragmented messages and
822 * passing them to the ssl engine
823 */
eaptls_receive(struct eaptls_session * ets,u_char * inp,int len)824 int eaptls_receive(struct eaptls_session *ets, u_char * inp, int len)
825 {
826 u_char flags;
827 u_int tlslen = 0;
828 u_char dummy[65536];
829
830 if (len < 1) {
831 warn("EAP-TLS: received no or invalid data");
832 return 1;
833 }
834
835 GETCHAR(flags, inp);
836 len--;
837
838 if (flags & EAP_TLS_FLAGS_LI && len > 4) {
839 /*
840 * LenghtIncluded flag set -> this is the first packet of a message
841 */
842
843 /*
844 * the first 4 octets are the length of the EAP-TLS message
845 */
846 GETLONG(tlslen, inp);
847 len -= 4;
848
849 if (!ets->data) {
850
851 if (tlslen > EAP_TLS_MAX_LEN) {
852 error("EAP-TLS: TLS message length > %d, truncated", EAP_TLS_MAX_LEN);
853 tlslen = EAP_TLS_MAX_LEN;
854 }
855
856 /*
857 * Allocate memory for the whole message
858 */
859 ets->data = malloc(tlslen);
860 if (!ets->data)
861 fatal("EAP-TLS: allocation error\n");
862
863 ets->datalen = 0;
864 ets->tlslen = tlslen;
865 }
866 else
867 warn("EAP-TLS: non-first LI packet? that's odd...");
868 }
869 else if (!ets->data) {
870 /*
871 * A non fragmented message without LI flag
872 */
873
874 ets->data = malloc(len);
875 if (!ets->data)
876 fatal("EAP-TLS: memory allocation error in eaptls_receive\n");
877
878 ets->datalen = 0;
879 ets->tlslen = len;
880 }
881
882 if (flags & EAP_TLS_FLAGS_MF)
883 ets->frag = 1;
884 else
885 ets->frag = 0;
886
887 if (len < 0) {
888 warn("EAP-TLS: received malformed data");
889 return 1;
890 }
891
892 if (len + ets->datalen > ets->tlslen) {
893 warn("EAP-TLS: received data > TLS message length");
894 return 1;
895 }
896
897 BCOPY(inp, ets->data + ets->datalen, len);
898 ets->datalen += len;
899
900 if (!ets->frag) {
901
902 /*
903 * If we have the whole message, pass it to ssl
904 */
905
906 if (ets->datalen != ets->tlslen) {
907 warn("EAP-TLS: received data != TLS message length");
908 return 1;
909 }
910
911 if (BIO_write(ets->into_ssl, ets->data, ets->datalen) == -1)
912 tls_log_sslerr();
913
914 SSL_read(ets->ssl, dummy, 65536);
915
916 free(ets->data);
917 ets->data = NULL;
918 ets->datalen = 0;
919 }
920
921 return 0;
922 }
923
924 /*
925 * Return an eap-tls packet in outp.
926 * A TLS message read from the ssl engine is buffered in ets->data.
927 * At each call we control if there is buffered data and send a
928 * packet of mtu bytes.
929 */
eaptls_send(struct eaptls_session * ets,u_char ** outp)930 int eaptls_send(struct eaptls_session *ets, u_char ** outp)
931 {
932 bool first = 0;
933 int size;
934 u_char fromtls[65536];
935 int res;
936 u_char *start;
937
938 start = *outp;
939
940 if (!ets->data)
941 {
942 if(!ets->alert_sent)
943 {
944 res = SSL_read(ets->ssl, fromtls, 65536);
945 }
946
947 /*
948 * Read from ssl
949 */
950 if ((res = BIO_read(ets->from_ssl, fromtls, 65536)) == -1)
951 {
952 warn("EAP-TLS send: No data from BIO_read");
953 return 1;
954 }
955
956 ets->datalen = res;
957
958 ets->data = malloc(ets->datalen);
959 if (!ets->data)
960 fatal("EAP-TLS: memory allocation error in eaptls_send\n");
961
962 BCOPY(fromtls, ets->data, ets->datalen);
963
964 ets->offset = 0;
965 first = 1;
966 }
967
968 size = ets->datalen - ets->offset;
969
970 if (size > ets->mtu) {
971 size = ets->mtu;
972 ets->frag = 1;
973 } else
974 ets->frag = 0;
975
976 PUTCHAR(EAPT_TLS, *outp);
977
978 /*
979 * Set right flags and length if necessary
980 */
981 if (ets->frag && first) {
982 PUTCHAR(EAP_TLS_FLAGS_LI | EAP_TLS_FLAGS_MF, *outp);
983 PUTLONG(ets->datalen, *outp);
984 } else if (ets->frag) {
985 PUTCHAR(EAP_TLS_FLAGS_MF, *outp);
986 } else
987 PUTCHAR(0, *outp);
988
989 /*
990 * Copy the data in outp
991 */
992 BCOPY(ets->data + ets->offset, *outp, size);
993 INCPTR(size, *outp);
994
995 /*
996 * Copy the packet in retransmission buffer
997 */
998 BCOPY(start, &ets->rtx[0], *outp - start);
999 ets->rtx_len = *outp - start;
1000
1001 ets->offset += size;
1002
1003 if (ets->offset >= ets->datalen) {
1004
1005 /*
1006 * The whole message has been sent
1007 */
1008
1009 free(ets->data);
1010 ets->data = NULL;
1011 ets->datalen = 0;
1012 ets->offset = 0;
1013 }
1014
1015 return 0;
1016 }
1017
1018 /*
1019 * Get the sent packet from the retransmission buffer
1020 */
eaptls_retransmit(struct eaptls_session * ets,u_char ** outp)1021 void eaptls_retransmit(struct eaptls_session *ets, u_char ** outp)
1022 {
1023 BCOPY(ets->rtx, *outp, ets->rtx_len);
1024 INCPTR(ets->rtx_len, *outp);
1025 }
1026
1027 /*
1028 * Every sent & received message this callback function is invoked,
1029 * so we know when alert messages have arrived or are sent and
1030 * we can print debug information about TLS handshake.
1031 */
1032 void
ssl_msg_callback(int write_p,int version,int content_type,const void * buf,size_t len,SSL * ssl,void * arg)1033 ssl_msg_callback(int write_p, int version, int content_type,
1034 const void *buf, size_t len, SSL * ssl, void *arg)
1035 {
1036 char string[256];
1037 struct eaptls_session *ets = (struct eaptls_session *)arg;
1038 unsigned char code;
1039 const unsigned char*msg = buf;
1040 int hvers = msg[1] << 8 | msg[2];
1041
1042 if(write_p)
1043 strcpy(string, " -> ");
1044 else
1045 strcpy(string, " <- ");
1046
1047 switch(content_type) {
1048
1049 case SSL3_RT_HEADER:
1050 strcat(string, "SSL/TLS Header: ");
1051 switch(hvers) {
1052 case SSL3_VERSION:
1053 strcat(string, "SSL 3.0");
1054 break;
1055 case TLS1_VERSION:
1056 strcat(string, "TLS 1.0");
1057 break;
1058 case TLS1_1_VERSION:
1059 strcat(string, "TLS 1.1");
1060 break;
1061 case TLS1_2_VERSION:
1062 strcat(string, "TLS 1.2");
1063 break;
1064 default:
1065 sprintf(string, "SSL/TLS Header: Unknown version (%d)", hvers);
1066 }
1067 break;
1068
1069 case SSL3_RT_ALERT:
1070 strcat(string, "Alert: ");
1071 code = msg[1];
1072
1073 if (write_p) {
1074 ets->alert_sent = 1;
1075 ets->alert_sent_desc = code;
1076 } else {
1077 ets->alert_recv = 1;
1078 ets->alert_recv_desc = code;
1079 }
1080
1081 strcat(string, SSL_alert_desc_string_long(code));
1082 break;
1083
1084 case SSL3_RT_CHANGE_CIPHER_SPEC:
1085 strcat(string, "ChangeCipherSpec");
1086 break;
1087
1088 #ifdef SSL3_RT_INNER_CONTENT_TYPE
1089 case SSL3_RT_INNER_CONTENT_TYPE:
1090 strcat(string, "InnerContentType (TLS1.3)");
1091 break;
1092 #endif
1093
1094 case SSL3_RT_HANDSHAKE:
1095
1096 strcat(string, "Handshake: ");
1097 code = msg[0];
1098
1099 switch(code) {
1100 case SSL3_MT_HELLO_REQUEST:
1101 strcat(string,"Hello Request");
1102 break;
1103 case SSL3_MT_CLIENT_HELLO:
1104 strcat(string,"Client Hello");
1105 break;
1106 case SSL3_MT_SERVER_HELLO:
1107 strcat(string,"Server Hello");
1108 break;
1109 #ifdef SSL3_MT_NEWSESSION_TICKET
1110 case SSL3_MT_NEWSESSION_TICKET:
1111 strcat(string,"New Session Ticket");
1112 break;
1113 #endif
1114 #ifdef SSL3_MT_END_OF_EARLY_DATA
1115 case SSL3_MT_END_OF_EARLY_DATA:
1116 strcat(string,"End of Early Data");
1117 break;
1118 #endif
1119 #ifdef SSL3_MT_ENCRYPTED_EXTENSIONS
1120 case SSL3_MT_ENCRYPTED_EXTENSIONS:
1121 strcat(string,"Encryped Extensions");
1122 break;
1123 #endif
1124 case SSL3_MT_CERTIFICATE:
1125 strcat(string,"Certificate");
1126 break;
1127 case SSL3_MT_SERVER_KEY_EXCHANGE:
1128 strcat(string,"Server Key Exchange");
1129 break;
1130 case SSL3_MT_CERTIFICATE_REQUEST:
1131 strcat(string,"Certificate Request");
1132 break;
1133 case SSL3_MT_SERVER_DONE:
1134 strcat(string,"Server Hello Done");
1135 break;
1136 case SSL3_MT_CERTIFICATE_VERIFY:
1137 strcat(string,"Certificate Verify");
1138 break;
1139 case SSL3_MT_CLIENT_KEY_EXCHANGE:
1140 strcat(string,"Client Key Exchange");
1141 break;
1142 case SSL3_MT_FINISHED:
1143 strcat(string,"Finished: ");
1144 hvers = SSL_version(ssl);
1145 switch(hvers){
1146 case SSL3_VERSION:
1147 strcat(string, "SSL 3.0");
1148 break;
1149 case TLS1_VERSION:
1150 strcat(string, "TLS 1.0");
1151 break;
1152 case TLS1_1_VERSION:
1153 strcat(string, "TLS 1.1");
1154 break;
1155 case TLS1_2_VERSION:
1156 strcat(string, "TLS 1.2");
1157 break;
1158 #ifdef TLS1_3_VERSION
1159 case TLS1_3_VERSION:
1160 strcat(string, "TLS 1.3 (experimental)");
1161 ets->tls_v13 = 1;
1162 break;
1163 #endif
1164 default:
1165 strcat(string, "Unknown version");
1166 }
1167 break;
1168 default:
1169 sprintf( string, "Handshake: Unknown SSL3 code received: %d", code );
1170 }
1171 break;
1172
1173 default:
1174 sprintf( string, "SSL message contains unknown content type: %d", content_type );
1175 }
1176
1177 /* Alert messages must always be displayed */
1178 if(content_type == SSL3_RT_ALERT)
1179 error("%s", string);
1180 else
1181 dbglog("%s", string);
1182 }
1183
1184 int
ssl_new_session_cb(SSL * s,SSL_SESSION * sess)1185 ssl_new_session_cb(SSL *s, SSL_SESSION *sess)
1186 {
1187 dbglog("EAP-TLS: Post-Handshake New Session Ticket arrived:");
1188 have_session_ticket = 1;
1189
1190 /* always return success */
1191 return 1;
1192 }
1193
1194