eap-tls.c revision 1.1.1.1
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#include <string.h>
33#include <strings.h>
34#include <unistd.h>
35#include <sys/types.h>
36#include <sys/stat.h>
37#include <fcntl.h>
38
39#include <openssl/conf.h>
40#include <openssl/engine.h>
41#include <openssl/hmac.h>
42#include <openssl/err.h>
43#include <openssl/ui.h>
44#include <openssl/x509v3.h>
45
46#include "pppd.h"
47#include "eap.h"
48#include "eap-tls.h"
49#include "fsm.h"
50#include "lcp.h"
51#include "pathnames.h"
52
53typedef struct pw_cb_data
54{
55    const void *password;
56    const char *prompt_info;
57} PW_CB_DATA;
58
59/* The openssl configuration file and engines can be loaded only once */
60static CONF   *ssl_config  = NULL;
61static ENGINE *cert_engine = NULL;
62static ENGINE *pkey_engine = NULL;
63
64/* TLSv1.3 do we have a session ticket ? */
65static int have_session_ticket = 0;
66
67int ssl_verify_callback(int, X509_STORE_CTX *);
68void ssl_msg_callback(int write_p, int version, int ct, const void *buf,
69              size_t len, SSL * ssl, void *arg);
70int ssl_new_session_cb(SSL *s, SSL_SESSION *sess);
71
72X509 *get_X509_from_file(char *filename);
73int ssl_cmp_certs(char *filename, X509 * a);
74
75#ifdef MPPE
76
77#define EAPTLS_MPPE_KEY_LEN     32
78
79/*
80 *  OpenSSL 1.1+ introduced a generic TLS_method()
81 *  For older releases we substitute the appropriate method
82 */
83
84#if OPENSSL_VERSION_NUMBER < 0x10100000L
85
86#define TLS_method SSLv23_method
87
88#define SSL3_RT_HEADER  0x100
89
90#ifndef SSL_CTX_set_max_proto_version
91/** Mimics SSL_CTX_set_max_proto_version for OpenSSL < 1.1 */
92static inline int SSL_CTX_set_max_proto_version(SSL_CTX *ctx, long tls_ver_max)
93{
94    long sslopt = 0;
95
96    if (tls_ver_max < TLS1_VERSION)
97    {
98        sslopt |= SSL_OP_NO_TLSv1;
99    }
100#ifdef SSL_OP_NO_TLSv1_1
101    if (tls_ver_max < TLS1_1_VERSION)
102    {
103        sslopt |= SSL_OP_NO_TLSv1_1;
104    }
105#endif
106#ifdef SSL_OP_NO_TLSv1_2
107    if (tls_ver_max < TLS1_2_VERSION)
108    {
109        sslopt |= SSL_OP_NO_TLSv1_2;
110    }
111#endif
112    SSL_CTX_set_options(ctx, sslopt);
113
114    return 1;
115}
116#endif /* SSL_CTX_set_max_proto_version */
117
118#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
119
120
121/*
122 *  Generate keys according to RFC 2716 and add to reply
123 */
124void eaptls_gen_mppe_keys(struct eaptls_session *ets, int client)
125{
126    unsigned char  out[4*EAPTLS_MPPE_KEY_LEN];
127    const char    *prf_label;
128    size_t         prf_size;
129    unsigned char  eap_tls13_context[] = { EAPT_TLS };
130    unsigned char *context = NULL;
131    size_t         context_len = 0;
132    unsigned char *p;
133
134    dbglog("EAP-TLS generating MPPE keys");
135    if (ets->tls_v13)
136    {
137        prf_label = "EXPORTER_EAP_TLS_Key_Material";
138        context   = eap_tls13_context;
139        context_len = 1;
140    }
141    else
142    {
143        prf_label = "client EAP encryption";
144    }
145
146    dbglog("EAP-TLS PRF label = %s", prf_label);
147    prf_size = strlen(prf_label);
148    if (SSL_export_keying_material(ets->ssl, out, sizeof(out), prf_label, prf_size,
149                                   context, context_len, 0) != 1)
150    {
151        warn( "EAP-TLS: Failed generating keying material" );
152        return;
153    }
154
155    /*
156     * We now have the master send and receive keys.
157     * From these, generate the session send and receive keys.
158     * (see RFC3079 / draft-ietf-pppext-mppe-keys-03.txt for details)
159     */
160    if (client)
161    {
162        p = out;
163        BCOPY( p, mppe_send_key, sizeof(mppe_send_key) );
164        p += EAPTLS_MPPE_KEY_LEN;
165        BCOPY( p, mppe_recv_key, sizeof(mppe_recv_key) );
166    }
167    else
168    {
169        p = out;
170        BCOPY( p, mppe_recv_key, sizeof(mppe_recv_key) );
171        p += EAPTLS_MPPE_KEY_LEN;
172        BCOPY( p, mppe_send_key, sizeof(mppe_send_key) );
173    }
174
175    mppe_keys_set = 1;
176}
177
178#endif /* MPPE */
179
180void log_ssl_errors( void )
181{
182    unsigned long ssl_err = ERR_get_error();
183
184    if (ssl_err != 0)
185        dbglog("EAP-TLS SSL error stack:");
186    while (ssl_err != 0) {
187        dbglog( ERR_error_string( ssl_err, NULL ) );
188        ssl_err = ERR_get_error();
189    }
190}
191
192
193int password_callback (char *buf, int size, int rwflag, void *u)
194{
195    if (buf)
196    {
197        strlcpy (buf, passwd, size);
198        return strlen (buf);
199    }
200    return 0;
201}
202
203
204CONF *eaptls_ssl_load_config( void )
205{
206    CONF        *config;
207    int          ret_code;
208    long         error_line = 33;
209
210    config = NCONF_new( NULL );
211    dbglog( "Loading OpenSSL config file" );
212    ret_code = NCONF_load( config, _PATH_OPENSSLCONFFILE, &error_line );
213    if (ret_code == 0)
214    {
215        warn( "EAP-TLS: Error in OpenSSL config file %s at line %d", _PATH_OPENSSLCONFFILE, error_line );
216        NCONF_free( config );
217        config = NULL;
218        ERR_clear_error();
219    }
220
221    dbglog( "Loading OpenSSL built-ins" );
222    ENGINE_load_builtin_engines();
223    OPENSSL_load_builtin_modules();
224
225    dbglog( "Loading OpenSSL configured modules" );
226    if (CONF_modules_load( config, NULL, 0 ) <= 0 )
227    {
228        warn( "EAP-TLS: Error loading OpenSSL modules" );
229        log_ssl_errors();
230        config = NULL;
231    }
232
233    return config;
234}
235
236ENGINE *eaptls_ssl_load_engine( char *engine_name )
237{
238    ENGINE      *e = NULL;
239
240    dbglog( "Enabling OpenSSL auto engines" );
241    ENGINE_register_all_complete();
242
243    dbglog( "Loading OpenSSL '%s' engine support", engine_name );
244    e = ENGINE_by_id( engine_name );
245    if (!e)
246    {
247        dbglog( "EAP-TLS: Cannot load '%s' engine support, trying 'dynamic'", engine_name );
248        e = ENGINE_by_id( "dynamic" );
249        if (e)
250        {
251            if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine_name, 0)
252             || !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0))
253            {
254                warn( "EAP-TLS: Error loading dynamic engine '%s'", engine_name );
255                log_ssl_errors();
256                ENGINE_free(e);
257                e = NULL;
258            }
259        }
260        else
261        {
262            warn( "EAP-TLS: Cannot load dynamic engine support" );
263        }
264    }
265
266    if (e)
267    {
268        dbglog( "Initialising engine" );
269        if(!ENGINE_set_default(e, ENGINE_METHOD_ALL))
270        {
271            warn( "EAP-TLS: Cannot use that engine" );
272            log_ssl_errors();
273            ENGINE_free(e);
274            e = NULL;
275        }
276    }
277
278    return e;
279}
280
281
282
283/*
284 * Initialize the SSL stacks and tests if certificates, key and crl
285 * for client or server use can be loaded.
286 */
287SSL_CTX *eaptls_init_ssl(int init_server, char *cacertfile, char *capath,
288            char *certfile, char *peer_certfile, char *privkeyfile)
289{
290    char        *cert_engine_name = NULL;
291    char        *cert_identifier = NULL;
292    char        *pkey_engine_name = NULL;
293    char        *pkey_identifier = NULL;
294    SSL_CTX     *ctx;
295    SSL         *ssl;
296    X509_STORE  *certstore;
297    X509_LOOKUP *lookup;
298    X509        *tmp;
299    int          ret;
300#if defined(TLS1_2_VERSION)
301    long         tls_version = TLS1_2_VERSION;
302#elif defined(TLS1_1_VERSION)
303    long         tls_version = TLS1_1_VERSION;
304#else
305    long         tls_version = TLS1_VERSION;
306#endif
307
308    /*
309     * Without these can't continue
310     */
311    if (!(cacertfile[0] || capath[0]))
312    {
313        error("EAP-TLS: CA certificate file or path missing");
314        return NULL;
315    }
316
317    if (!certfile[0])
318    {
319        error("EAP-TLS: Certificate missing");
320        return NULL;
321    }
322
323    if (!privkeyfile[0])
324    {
325        error("EAP-TLS: Private key missing");
326        return NULL;
327    }
328
329    SSL_library_init();
330    SSL_load_error_strings();
331
332    /* load the openssl config file only once and load it before triggering
333       the loading of a global openssl config file via SSL_CTX_new()
334     */
335    if (!ssl_config)
336        ssl_config = eaptls_ssl_load_config();
337
338    ctx = SSL_CTX_new(TLS_method());
339
340    if (!ctx) {
341        error("EAP-TLS: Cannot initialize SSL CTX context");
342        goto fail;
343    }
344
345    /* if the certificate filename is of the form engine:id. e.g.
346        pkcs11:12345
347       then we try to load and use this engine.
348       If the certificate filename starts with a / or . then we
349       ALWAYS assume it is a file and not an engine/pkcs11 identifier
350     */
351    if ( index( certfile, '/' ) == NULL && index( certfile, '.') == NULL )
352    {
353        cert_identifier = index( certfile, ':' );
354
355        if (cert_identifier)
356        {
357            cert_engine_name = certfile;
358            *cert_identifier = '\0';
359            cert_identifier++;
360
361            dbglog( "Found certificate engine '%s'", cert_engine_name );
362            dbglog( "Found certificate identifier '%s'", cert_identifier );
363        }
364    }
365
366    /* if the privatekey filename is of the form engine:id. e.g.
367        pkcs11:12345
368       then we try to load and use this engine.
369       If the privatekey filename starts with a / or . then we
370       ALWAYS assume it is a file and not an engine/pkcs11 identifier
371     */
372    if ( index( privkeyfile, '/' ) == NULL && index( privkeyfile, '.') == NULL )
373    {
374        pkey_identifier = index( privkeyfile, ':' );
375
376        if (pkey_identifier)
377        {
378            pkey_engine_name = privkeyfile;
379            *pkey_identifier = '\0';
380            pkey_identifier++;
381
382            dbglog( "Found privatekey engine '%s'", pkey_engine_name );
383            dbglog( "Found privatekey identifier '%s'", pkey_identifier );
384        }
385    }
386
387    if (cert_identifier && pkey_identifier)
388    {
389        if (strlen( cert_identifier ) == 0)
390        {
391            if (strlen( pkey_identifier ) == 0)
392                error( "EAP-TLS: both the certificate and privatekey identifiers are missing!" );
393            else
394            {
395                dbglog( "Substituting privatekey identifier for certificate identifier" );
396                cert_identifier = pkey_identifier;
397            }
398        }
399        else
400        {
401            if (strlen( pkey_identifier ) == 0)
402            {
403                dbglog( "Substituting certificate identifier for privatekey identifier" );
404                pkey_identifier = cert_identifier;
405            }
406        }
407    }
408
409    if (ssl_config && cert_engine_name)
410        cert_engine = eaptls_ssl_load_engine( cert_engine_name );
411
412    if (ssl_config && pkey_engine_name)
413    {
414        /* don't load the same engine twice */
415        if ( cert_engine && strcmp( cert_engine_name, pkey_engine_name) == 0 )
416            pkey_engine = cert_engine;
417        else
418            pkey_engine = eaptls_ssl_load_engine( pkey_engine_name );
419    }
420
421    SSL_CTX_set_default_passwd_cb (ctx, password_callback);
422
423    if (strlen(cacertfile) == 0) cacertfile = NULL;
424    if (strlen(capath) == 0)     capath = NULL;
425
426    if (!SSL_CTX_load_verify_locations(ctx, cacertfile, capath))
427    {
428        error("EAP-TLS: Cannot load verify locations");
429        if (cacertfile) dbglog("CA certificate file = [%s]", cacertfile);
430        if (capath) dbglog("CA certificate path = [%s]", capath);
431        goto fail;
432    }
433
434    if (init_server)
435        SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(cacertfile));
436
437    if (cert_engine)
438    {
439        struct
440        {
441            const char *s_slot_cert_id;
442            X509 *cert;
443        } cert_info;
444
445        cert_info.s_slot_cert_id = cert_identifier;
446        cert_info.cert = NULL;
447
448        if (!ENGINE_ctrl_cmd( cert_engine, "LOAD_CERT_CTRL", 0, &cert_info, NULL, 0 ) )
449        {
450            error( "EAP-TLS: Error loading certificate with id '%s' from engine", cert_identifier );
451            goto fail;
452        }
453
454        if (cert_info.cert)
455        {
456            dbglog( "Got the certificate, adding it to SSL context" );
457            dbglog( "subject = %s", X509_NAME_oneline( X509_get_subject_name( cert_info.cert ), NULL, 0 ) );
458            if (SSL_CTX_use_certificate(ctx, cert_info.cert) <= 0)
459            {
460                error("EAP-TLS: Cannot use PKCS11 certificate %s", cert_identifier);
461                goto fail;
462            }
463        }
464        else
465        {
466            warn("EAP-TLS: Cannot load PKCS11 key %s", cert_identifier);
467            log_ssl_errors();
468        }
469    }
470    else
471    {
472        if (!SSL_CTX_use_certificate_chain_file(ctx, certfile))
473        {
474            error( "EAP-TLS: Cannot use public certificate %s", certfile );
475            goto fail;
476        }
477    }
478
479
480    /*
481     *  Check the Before and After dates of the certificate
482     */
483    ssl = SSL_new(ctx);
484    tmp = SSL_get_certificate(ssl);
485
486    ret = X509_cmp_time(X509_get_notBefore(tmp), NULL);
487    if (ret == 0)
488    {
489        warn( "EAP-TLS: Failed to read certificate notBefore field.");
490    }
491    if (ret > 0)
492    {
493        warn( "EAP-TLS: Your certificate is not yet valid!");
494    }
495
496    ret = X509_cmp_time(X509_get_notAfter(tmp), NULL);
497    if (ret == 0)
498    {
499        warn( "EAP-TLS: Failed to read certificate notAfter field.");
500    }
501    if (ret < 0)
502    {
503        warn( "EAP-TLS: Your certificate has expired!");
504    }
505    SSL_free(ssl);
506
507    if (pkey_engine)
508    {
509        EVP_PKEY   *pkey = NULL;
510        PW_CB_DATA  cb_data;
511
512        cb_data.password = passwd;
513        cb_data.prompt_info = pkey_identifier;
514
515        if (passwd[0] != 0)
516        {
517            UI_METHOD* transfer_pin = UI_create_method("transfer_pin");
518
519            int writer (UI *ui, UI_STRING *uis)
520            {
521                PW_CB_DATA* cb_data = (PW_CB_DATA*)UI_get0_user_data(ui);
522                UI_set_result(ui, uis, cb_data->password);
523                return 1;
524            };
525            int stub (UI* ui) {return 1;};
526            int stub_reader (UI *ui, UI_STRING *uis) {return 1;};
527
528            UI_method_set_writer(transfer_pin,  writer);
529            UI_method_set_opener(transfer_pin,  stub);
530            UI_method_set_closer(transfer_pin,  stub);
531            UI_method_set_flusher(transfer_pin, stub);
532            UI_method_set_reader(transfer_pin,  stub_reader);
533
534            dbglog( "Using our private key '%s' in engine", pkey_identifier );
535            pkey = ENGINE_load_private_key(pkey_engine, pkey_identifier, transfer_pin, &cb_data);
536
537            if (transfer_pin) UI_destroy_method(transfer_pin);
538        }
539        else {
540            dbglog( "Loading private key '%s' from engine", pkey_identifier );
541            pkey = ENGINE_load_private_key(pkey_engine, pkey_identifier, NULL, NULL);
542        }
543        if (pkey)
544        {
545            dbglog( "Got the private key, adding it to SSL context" );
546            if (SSL_CTX_use_PrivateKey(ctx, pkey) <= 0)
547            {
548                error("EAP-TLS: Cannot use PKCS11 key %s", pkey_identifier);
549                goto fail;
550            }
551        }
552        else
553        {
554            warn("EAP-TLS: Cannot load PKCS11 key %s", pkey_identifier);
555            log_ssl_errors();
556        }
557    }
558    else
559    {
560        if (!SSL_CTX_use_PrivateKey_file(ctx, privkeyfile, SSL_FILETYPE_PEM))
561        {
562            error("EAP-TLS: Cannot use private key %s", privkeyfile);
563            goto fail;
564        }
565    }
566
567    if (SSL_CTX_check_private_key(ctx) != 1) {
568        error("EAP-TLS: Private key %s fails security check", privkeyfile);
569        goto fail;
570    }
571
572    /* Explicitly set the NO_TICKETS flag to support Win7/Win8 clients */
573    SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3
574#ifdef SSL_OP_NO_TICKET
575    | SSL_OP_NO_TICKET
576#endif
577    );
578
579    /* OpenSSL 1.1.1+ does not include RC4 ciphers by default.
580     * This causes totally obsolete WinXP clients to fail. If you really
581     * need ppp+EAP-TLS+openssl 1.1.1+WinXP then enable RC4 cipers and
582     * make sure that you use an OpenSSL that supports them
583
584    SSL_CTX_set_cipher_list(ctx, "RC4");
585     */
586
587
588    /* Set up a SSL Session cache with a callback. This is needed for TLSv1.3+.
589     * During the initial handshake the server signals to the client early on
590     * that the handshake is finished, even before the client has sent its
591     * credentials to the server. The actual connection (and moment that the
592     * client sends its credentials) only starts after the arrival of the first
593     * session ticket. The 'ssl_new_session_cb' catches this ticket.
594     */
595    SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL_STORE);
596    SSL_CTX_sess_set_new_cb(ctx, ssl_new_session_cb);
597
598    /* As EAP-TLS+TLSv1.3 is highly experimental we offer the user a chance to override */
599    if (max_tls_version)
600    {
601        if (strncmp(max_tls_version, "1.0", 3) == 0)
602            tls_version = TLS1_VERSION;
603        else if (strncmp(max_tls_version, "1.1", 3) == 0)
604            tls_version = TLS1_1_VERSION;
605        else if (strncmp(max_tls_version, "1.2", 3) == 0)
606#ifdef TLS1_2_VERSION
607            tls_version = TLS1_2_VERSION;
608#else
609        {
610            warn("TLSv1.2 not available. Defaulting to TLSv1.1");
611            tls_version = TLS_1_1_VERSION;
612        }
613#endif
614        else if (strncmp(max_tls_version, "1.3", 3) == 0)
615#ifdef TLS1_3_VERSION
616            tls_version = TLS1_3_VERSION;
617#else
618            warn("TLSv1.3 not available.");
619#endif
620    }
621
622    dbglog("EAP-TLS: Setting max protocol version to 0x%X", tls_version);
623    SSL_CTX_set_max_proto_version(ctx, tls_version);
624
625    SSL_CTX_set_verify_depth(ctx, 5);
626    SSL_CTX_set_verify(ctx,
627               SSL_VERIFY_PEER |
628               SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
629               &ssl_verify_callback);
630
631    if (crl_dir) {
632        if (!(certstore = SSL_CTX_get_cert_store(ctx))) {
633            error("EAP-TLS: Failed to get certificate store");
634            goto fail;
635        }
636
637        if (!(lookup =
638             X509_STORE_add_lookup(certstore, X509_LOOKUP_hash_dir()))) {
639            error("EAP-TLS: Store lookup for CRL failed");
640
641            goto fail;
642        }
643
644        X509_LOOKUP_add_dir(lookup, crl_dir, X509_FILETYPE_PEM);
645        X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK);
646    }
647
648    if (crl_file) {
649        FILE     *fp  = NULL;
650        X509_CRL *crl = NULL;
651
652        fp = fopen(crl_file, "r");
653        if (!fp) {
654            error("EAP-TLS: Cannot open CRL file '%s'", crl_file);
655            goto fail;
656        }
657
658        crl = PEM_read_X509_CRL(fp, NULL, NULL, NULL);
659        if (!crl) {
660            error("EAP-TLS: Cannot read CRL file '%s'", crl_file);
661            goto fail;
662        }
663
664        if (!(certstore = SSL_CTX_get_cert_store(ctx))) {
665            error("EAP-TLS: Failed to get certificate store");
666            goto fail;
667        }
668        if (!X509_STORE_add_crl(certstore, crl)) {
669            error("EAP-TLS: Cannot add CRL to certificate store");
670            goto fail;
671        }
672        X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK);
673
674    }
675
676    /*
677     * If a peer certificate file was specified, it must be valid, else fail
678     */
679    if (peer_certfile[0]) {
680        if (!(tmp = get_X509_from_file(peer_certfile))) {
681            error("EAP-TLS: Error loading client certificate from file %s",
682                 peer_certfile);
683            goto fail;
684        }
685        X509_free(tmp);
686    }
687
688    return ctx;
689
690fail:
691    log_ssl_errors();
692    SSL_CTX_free(ctx);
693    return NULL;
694}
695
696/*
697 * Determine the maximum packet size by looking at the LCP handshake
698 */
699
700int eaptls_get_mtu(int unit)
701{
702    int mtu, mru;
703
704    lcp_options *wo = &lcp_wantoptions[unit];
705    lcp_options *go = &lcp_gotoptions[unit];
706    lcp_options *ho = &lcp_hisoptions[unit];
707    lcp_options *ao = &lcp_allowoptions[unit];
708
709    mtu = ho->neg_mru? ho->mru: PPP_MRU;
710    mru = go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU;
711    mtu = MIN(MIN(mtu, mru), ao->mru)- PPP_HDRLEN - 10;
712
713    dbglog("MTU = %d", mtu);
714    return mtu;
715}
716
717
718/*
719 * Init the ssl handshake (server mode)
720 */
721int eaptls_init_ssl_server(eap_state * esp)
722{
723    struct eaptls_session *ets;
724    char servcertfile[MAXWORDLEN];
725    char clicertfile[MAXWORDLEN];
726    char cacertfile[MAXWORDLEN];
727    char capath[MAXWORDLEN];
728    char pkfile[MAXWORDLEN];
729    /*
730     * Allocate new eaptls session
731     */
732    esp->es_server.ea_session = malloc(sizeof(struct eaptls_session));
733    if (!esp->es_server.ea_session)
734        fatal("Allocation error");
735    ets = esp->es_server.ea_session;
736
737    if (!esp->es_server.ea_peer) {
738        error("EAP-TLS: Error: client name not set (BUG)");
739        return 0;
740    }
741
742    strlcpy(ets->peer, esp->es_server.ea_peer, MAXWORDLEN-1);
743
744    dbglog( "getting eaptls secret" );
745    if (!get_eaptls_secret(esp->es_unit, esp->es_server.ea_peer,
746                   esp->es_server.ea_name, clicertfile,
747                   servcertfile, cacertfile, capath, pkfile, 1)) {
748        error( "EAP-TLS: Cannot get secret/password for client \"%s\", server \"%s\"",
749                esp->es_server.ea_peer, esp->es_server.ea_name );
750        return 0;
751    }
752
753    ets->mtu = eaptls_get_mtu(esp->es_unit);
754
755    ets->ctx = eaptls_init_ssl(1, cacertfile, capath, servcertfile, clicertfile, pkfile);
756    if (!ets->ctx)
757        goto fail;
758
759    if (!(ets->ssl = SSL_new(ets->ctx)))
760        goto fail;
761
762    /*
763     * Set auto-retry to avoid timeouts on BIO_read
764     */
765    SSL_set_mode(ets->ssl, SSL_MODE_AUTO_RETRY);
766
767    /*
768     * Initialize the BIOs we use to read/write to ssl engine
769     */
770    ets->into_ssl = BIO_new(BIO_s_mem());
771    ets->from_ssl = BIO_new(BIO_s_mem());
772    SSL_set_bio(ets->ssl, ets->into_ssl, ets->from_ssl);
773
774    SSL_set_msg_callback(ets->ssl, ssl_msg_callback);
775    SSL_set_msg_callback_arg(ets->ssl, ets);
776
777    /*
778     * Attach the session struct to the connection, so we can later
779     * retrieve it when doing certificate verification
780     */
781    SSL_set_ex_data(ets->ssl, 0, ets);
782
783    SSL_set_accept_state(ets->ssl);
784
785    ets->tls_v13 = 0;
786
787    ets->data = NULL;
788    ets->datalen = 0;
789    ets->alert_sent = 0;
790    ets->alert_recv = 0;
791
792    /*
793     * If we specified the client certificate file, store it in ets->peercertfile,
794     * so we can check it later in ssl_verify_callback()
795     */
796    if (clicertfile[0])
797        strlcpy(&ets->peercertfile[0], clicertfile, MAXWORDLEN);
798    else
799        ets->peercertfile[0] = 0;
800
801    return 1;
802
803fail:
804    SSL_CTX_free(ets->ctx);
805    return 0;
806}
807
808/*
809 * Init the ssl handshake (client mode)
810 */
811int eaptls_init_ssl_client(eap_state * esp)
812{
813    struct eaptls_session *ets;
814    char servcertfile[MAXWORDLEN];
815    char clicertfile[MAXWORDLEN];
816    char cacertfile[MAXWORDLEN];
817    char capath[MAXWORDLEN];
818    char pkfile[MAXWORDLEN];
819
820    /*
821     * Allocate new eaptls session
822     */
823    esp->es_client.ea_session = malloc(sizeof(struct eaptls_session));
824    if (!esp->es_client.ea_session)
825        fatal("Allocation error");
826    ets = esp->es_client.ea_session;
827
828    /*
829     * If available, copy server name in ets; it will be used in cert
830     * verify
831     */
832    if (esp->es_client.ea_peer)
833        strlcpy(ets->peer, esp->es_client.ea_peer, MAXWORDLEN-1);
834    else
835        ets->peer[0] = 0;
836
837    ets->mtu = eaptls_get_mtu(esp->es_unit);
838
839    dbglog( "calling get_eaptls_secret" );
840    if (!get_eaptls_secret(esp->es_unit, esp->es_client.ea_name,
841                   ets->peer, clicertfile,
842                   servcertfile, cacertfile, capath, pkfile, 0)) {
843        error( "EAP-TLS: Cannot get secret/password for client \"%s\", server \"%s\"",
844                esp->es_client.ea_name, ets->peer );
845        return 0;
846    }
847
848    dbglog( "calling eaptls_init_ssl" );
849    ets->ctx = eaptls_init_ssl(0, cacertfile, capath, clicertfile, servcertfile, pkfile);
850    if (!ets->ctx)
851        goto fail;
852
853    ets->ssl = SSL_new(ets->ctx);
854
855    if (!ets->ssl)
856        goto fail;
857
858    /*
859     * Initialize the BIOs we use to read/write to ssl engine
860     */
861    dbglog( "Initializing SSL BIOs" );
862    ets->into_ssl = BIO_new(BIO_s_mem());
863    ets->from_ssl = BIO_new(BIO_s_mem());
864    SSL_set_bio(ets->ssl, ets->into_ssl, ets->from_ssl);
865
866    SSL_set_msg_callback(ets->ssl, ssl_msg_callback);
867    SSL_set_msg_callback_arg(ets->ssl, ets);
868
869    /*
870     * Attach the session struct to the connection, so we can later
871     * retrieve it when doing certificate verification
872     */
873    SSL_set_ex_data(ets->ssl, 0, ets);
874
875    SSL_set_connect_state(ets->ssl);
876
877    ets->tls_v13 = 0;
878
879    ets->data = NULL;
880    ets->datalen = 0;
881    ets->alert_sent = 0;
882    ets->alert_recv = 0;
883
884    /*
885     * If we specified the server certificate file, store it in
886     * ets->peercertfile, so we can check it later in
887     * ssl_verify_callback()
888     */
889    if (servcertfile[0])
890        strlcpy(ets->peercertfile, servcertfile, MAXWORDLEN);
891    else
892        ets->peercertfile[0] = 0;
893
894    return 1;
895
896fail:
897    dbglog( "eaptls_init_ssl_client: fail" );
898    SSL_CTX_free(ets->ctx);
899    return 0;
900
901}
902
903void eaptls_free_session(struct eaptls_session *ets)
904{
905    if (ets->ssl)
906        SSL_free(ets->ssl);
907
908    if (ets->ctx)
909        SSL_CTX_free(ets->ctx);
910
911    free(ets);
912}
913
914
915int eaptls_is_init_finished(struct eaptls_session *ets)
916{
917    if (ets->ssl && SSL_is_init_finished(ets->ssl))
918    {
919        if (ets->tls_v13)
920            return have_session_ticket;
921        else
922            return 1;
923    }
924
925    return 0;
926}
927
928/*
929 * Handle a received packet, reassembling fragmented messages and
930 * passing them to the ssl engine
931 */
932int eaptls_receive(struct eaptls_session *ets, u_char * inp, int len)
933{
934    u_char flags;
935    u_int tlslen = 0;
936    u_char dummy[65536];
937
938    if (len < 1) {
939        warn("EAP-TLS: received no or invalid data");
940        return 1;
941    }
942
943    GETCHAR(flags, inp);
944    len--;
945
946    if (flags & EAP_TLS_FLAGS_LI && len > 4) {
947        /*
948         * LenghtIncluded flag set -> this is the first packet of a message
949        */
950
951        /*
952         * the first 4 octets are the length of the EAP-TLS message
953         */
954        GETLONG(tlslen, inp);
955        len -= 4;
956
957        if (!ets->data) {
958
959            if (tlslen > EAP_TLS_MAX_LEN) {
960                error("EAP-TLS: TLS message length > %d, truncated", EAP_TLS_MAX_LEN);
961                tlslen = EAP_TLS_MAX_LEN;
962            }
963
964            /*
965             * Allocate memory for the whole message
966            */
967            ets->data = malloc(tlslen);
968            if (!ets->data)
969                fatal("EAP-TLS: allocation error\n");
970
971            ets->datalen = 0;
972            ets->tlslen = tlslen;
973        }
974        else
975            warn("EAP-TLS: non-first LI packet? that's odd...");
976    }
977    else if (!ets->data) {
978        /*
979         * A non fragmented message without LI flag
980        */
981
982        ets->data = malloc(len);
983        if (!ets->data)
984            fatal("EAP-TLS: memory allocation error in eaptls_receive\n");
985
986        ets->datalen = 0;
987        ets->tlslen = len;
988    }
989
990    if (flags & EAP_TLS_FLAGS_MF)
991        ets->frag = 1;
992    else
993        ets->frag = 0;
994
995    if (len < 0) {
996        warn("EAP-TLS: received malformed data");
997        return 1;
998    }
999
1000    if (len + ets->datalen > ets->tlslen) {
1001        warn("EAP-TLS: received data > TLS message length");
1002        return 1;
1003    }
1004
1005    BCOPY(inp, ets->data + ets->datalen, len);
1006    ets->datalen += len;
1007
1008    if (!ets->frag) {
1009
1010        /*
1011         * If we have the whole message, pass it to ssl
1012         */
1013
1014        if (ets->datalen != ets->tlslen) {
1015            warn("EAP-TLS: received data != TLS message length");
1016            return 1;
1017        }
1018
1019        if (BIO_write(ets->into_ssl, ets->data, ets->datalen) == -1)
1020            log_ssl_errors();
1021
1022        SSL_read(ets->ssl, dummy, 65536);
1023
1024        free(ets->data);
1025        ets->data = NULL;
1026        ets->datalen = 0;
1027    }
1028
1029    return 0;
1030}
1031
1032/*
1033 * Return an eap-tls packet in outp.
1034 * A TLS message read from the ssl engine is buffered in ets->data.
1035 * At each call we control if there is buffered data and send a
1036 * packet of mtu bytes.
1037 */
1038int eaptls_send(struct eaptls_session *ets, u_char ** outp)
1039{
1040    bool first = 0;
1041    int size;
1042    u_char fromtls[65536];
1043    int res;
1044    u_char *start;
1045
1046    start = *outp;
1047
1048    if (!ets->data)
1049    {
1050        if(!ets->alert_sent)
1051        {
1052            res = SSL_read(ets->ssl, fromtls, 65536);
1053        }
1054
1055        /*
1056         * Read from ssl
1057         */
1058        if ((res = BIO_read(ets->from_ssl, fromtls, 65536)) == -1)
1059        {
1060            warn("EAP-TLS send: No data from BIO_read");
1061            return 1;
1062        }
1063
1064        ets->datalen = res;
1065
1066        ets->data = malloc(ets->datalen);
1067        if (!ets->data)
1068            fatal("EAP-TLS: memory allocation error in eaptls_send\n");
1069
1070        BCOPY(fromtls, ets->data, ets->datalen);
1071
1072        ets->offset = 0;
1073        first = 1;
1074    }
1075
1076    size = ets->datalen - ets->offset;
1077
1078    if (size > ets->mtu) {
1079        size = ets->mtu;
1080        ets->frag = 1;
1081    } else
1082        ets->frag = 0;
1083
1084    PUTCHAR(EAPT_TLS, *outp);
1085
1086    /*
1087     * Set right flags and length if necessary
1088     */
1089    if (ets->frag && first) {
1090        PUTCHAR(EAP_TLS_FLAGS_LI | EAP_TLS_FLAGS_MF, *outp);
1091        PUTLONG(ets->datalen, *outp);
1092    } else if (ets->frag) {
1093        PUTCHAR(EAP_TLS_FLAGS_MF, *outp);
1094    } else
1095        PUTCHAR(0, *outp);
1096
1097    /*
1098     * Copy the data in outp
1099     */
1100    BCOPY(ets->data + ets->offset, *outp, size);
1101    INCPTR(size, *outp);
1102
1103    /*
1104     * Copy the packet in retransmission buffer
1105     */
1106    BCOPY(start, &ets->rtx[0], *outp - start);
1107    ets->rtx_len = *outp - start;
1108
1109    ets->offset += size;
1110
1111    if (ets->offset >= ets->datalen) {
1112
1113        /*
1114         * The whole message has been sent
1115         */
1116
1117        free(ets->data);
1118        ets->data = NULL;
1119        ets->datalen = 0;
1120        ets->offset = 0;
1121    }
1122
1123    return 0;
1124}
1125
1126/*
1127 * Get the sent packet from the retransmission buffer
1128 */
1129void eaptls_retransmit(struct eaptls_session *ets, u_char ** outp)
1130{
1131    BCOPY(ets->rtx, *outp, ets->rtx_len);
1132    INCPTR(ets->rtx_len, *outp);
1133}
1134
1135/*
1136 * Verify a certificate.
1137 * Most of the work (signatures and issuer attributes checking)
1138 * is done by ssl; we check the CN in the peer certificate
1139 * against the peer name.
1140 */
1141int ssl_verify_callback(int ok, X509_STORE_CTX * ctx)
1142{
1143    char subject[256];
1144    char cn_str[256];
1145    X509 *peer_cert;
1146    int err, depth;
1147    SSL *ssl;
1148    struct eaptls_session *ets;
1149
1150    peer_cert = X509_STORE_CTX_get_current_cert(ctx);
1151    err = X509_STORE_CTX_get_error(ctx);
1152    depth = X509_STORE_CTX_get_error_depth(ctx);
1153
1154    dbglog("certificate verify depth: %d", depth);
1155
1156    if (auth_required && !ok) {
1157        X509_NAME_oneline(X509_get_subject_name(peer_cert),
1158                  subject, 256);
1159
1160        X509_NAME_get_text_by_NID(X509_get_subject_name(peer_cert),
1161                      NID_commonName, cn_str, 256);
1162
1163        dbglog("Certificate verification error:\n depth: %d CN: %s"
1164               "\n err: %d (%s)\n", depth, cn_str, err,
1165               X509_verify_cert_error_string(err));
1166
1167        return 0;
1168    }
1169
1170    ssl = X509_STORE_CTX_get_ex_data(ctx,
1171                       SSL_get_ex_data_X509_STORE_CTX_idx());
1172
1173    ets = (struct eaptls_session *)SSL_get_ex_data(ssl, 0);
1174
1175    if (ets == NULL) {
1176        error("Error: SSL_get_ex_data returned NULL");
1177        return 0;
1178    }
1179
1180    log_ssl_errors();
1181
1182    if (!depth)
1183    {
1184        /* This is the peer certificate */
1185
1186        X509_NAME_oneline(X509_get_subject_name(peer_cert),
1187                  subject, 256);
1188
1189        X509_NAME_get_text_by_NID(X509_get_subject_name(peer_cert),
1190                      NID_commonName, cn_str, 256);
1191
1192        /*
1193         * If acting as client and the name of the server wasn't specified
1194         * explicitely, we can't verify the server authenticity
1195         */
1196        if (!ets->peer[0]) {
1197            warn("Peer name not specified: no check");
1198            return ok;
1199        }
1200
1201        /*
1202         * Check the CN
1203         */
1204        if (strcmp(cn_str, ets->peer)) {
1205            error
1206                ("Certificate verification error: CN (%s) != peer_name (%s)",
1207                 cn_str, ets->peer);
1208            return 0;
1209        }
1210
1211        warn("Certificate CN: %s , peer name %s", cn_str, ets->peer);
1212
1213        /*
1214         * If a peer certificate file was specified, here we check it
1215         */
1216        if (ets->peercertfile[0]) {
1217            if (ssl_cmp_certs(&ets->peercertfile[0], peer_cert)
1218                != 0) {
1219                error
1220                    ("Peer certificate doesn't match stored certificate");
1221                return 0;
1222            }
1223        }
1224    }
1225
1226    return ok;
1227}
1228
1229/*
1230 * Compare a certificate with the one stored in a file
1231 */
1232int ssl_cmp_certs(char *filename, X509 * a)
1233{
1234    X509 *b;
1235    int ret;
1236
1237    if (!(b = get_X509_from_file(filename)))
1238        return 1;
1239
1240    ret = X509_cmp(a, b);
1241    X509_free(b);
1242
1243    return ret;
1244
1245}
1246
1247X509 *get_X509_from_file(char *filename)
1248{
1249    FILE *fp;
1250    X509 *ret;
1251
1252    if (!(fp = fopen(filename, "r")))
1253        return NULL;
1254
1255    ret = PEM_read_X509(fp, NULL, NULL, NULL);
1256
1257    fclose(fp);
1258
1259    return ret;
1260}
1261
1262/*
1263 * Every sent & received message this callback function is invoked,
1264 * so we know when alert messages have arrived or are sent and
1265 * we can print debug information about TLS handshake.
1266 */
1267void
1268ssl_msg_callback(int write_p, int version, int content_type,
1269         const void *buf, size_t len, SSL * ssl, void *arg)
1270{
1271    char string[256];
1272    struct eaptls_session *ets = (struct eaptls_session *)arg;
1273    unsigned char code;
1274    const unsigned char*msg = buf;
1275    int hvers = msg[1] << 8 | msg[2];
1276
1277    if(write_p)
1278        strcpy(string, " -> ");
1279    else
1280        strcpy(string, " <- ");
1281
1282    switch(content_type) {
1283
1284    case SSL3_RT_HEADER:
1285        strcat(string, "SSL/TLS Header: ");
1286        switch(hvers) {
1287        case SSL3_VERSION:
1288                strcat(string, "SSL 3.0");
1289                break;
1290        case TLS1_VERSION:
1291                strcat(string, "TLS 1.0");
1292                break;
1293        case TLS1_1_VERSION:
1294                strcat(string, "TLS 1.1");
1295                break;
1296        case TLS1_2_VERSION:
1297                strcat(string, "TLS 1.2");
1298                break;
1299        default:
1300            sprintf(string, "SSL/TLS Header: Unknown version (%d)", hvers);
1301        }
1302        break;
1303
1304    case SSL3_RT_ALERT:
1305        strcat(string, "Alert: ");
1306        code = msg[1];
1307
1308        if (write_p) {
1309            ets->alert_sent = 1;
1310            ets->alert_sent_desc = code;
1311        } else {
1312            ets->alert_recv = 1;
1313            ets->alert_recv_desc = code;
1314        }
1315
1316        strcat(string, SSL_alert_desc_string_long(code));
1317        break;
1318
1319    case SSL3_RT_CHANGE_CIPHER_SPEC:
1320        strcat(string, "ChangeCipherSpec");
1321        break;
1322
1323#ifdef SSL3_RT_INNER_CONTENT_TYPE
1324    case SSL3_RT_INNER_CONTENT_TYPE:
1325        strcat(string, "InnerContentType (TLS1.3)");
1326        break;
1327#endif
1328
1329    case SSL3_RT_HANDSHAKE:
1330
1331        strcat(string, "Handshake: ");
1332        code = msg[0];
1333
1334        switch(code) {
1335            case SSL3_MT_HELLO_REQUEST:
1336                strcat(string,"Hello Request");
1337                break;
1338            case SSL3_MT_CLIENT_HELLO:
1339                strcat(string,"Client Hello");
1340                break;
1341            case SSL3_MT_SERVER_HELLO:
1342                strcat(string,"Server Hello");
1343                break;
1344#ifdef SSL3_MT_NEWSESSION_TICKET
1345            case SSL3_MT_NEWSESSION_TICKET:
1346                strcat(string,"New Session Ticket");
1347                break;
1348#endif
1349#ifdef SSL3_MT_END_OF_EARLY_DATA
1350            case SSL3_MT_END_OF_EARLY_DATA:
1351                strcat(string,"End of Early Data");
1352                break;
1353#endif
1354#ifdef SSL3_MT_ENCRYPTED_EXTENSIONS
1355            case SSL3_MT_ENCRYPTED_EXTENSIONS:
1356                strcat(string,"Encryped Extensions");
1357                break;
1358#endif
1359            case SSL3_MT_CERTIFICATE:
1360                strcat(string,"Certificate");
1361                break;
1362            case SSL3_MT_SERVER_KEY_EXCHANGE:
1363                strcat(string,"Server Key Exchange");
1364                break;
1365            case SSL3_MT_CERTIFICATE_REQUEST:
1366                strcat(string,"Certificate Request");
1367                break;
1368            case SSL3_MT_SERVER_DONE:
1369                strcat(string,"Server Hello Done");
1370                break;
1371            case SSL3_MT_CERTIFICATE_VERIFY:
1372                strcat(string,"Certificate Verify");
1373                break;
1374            case SSL3_MT_CLIENT_KEY_EXCHANGE:
1375                strcat(string,"Client Key Exchange");
1376                break;
1377            case SSL3_MT_FINISHED:
1378                strcat(string,"Finished: ");
1379                hvers = SSL_version(ssl);
1380                switch(hvers){
1381                    case SSL3_VERSION:
1382                        strcat(string, "SSL 3.0");
1383                        break;
1384                    case TLS1_VERSION:
1385                        strcat(string, "TLS 1.0");
1386                        break;
1387                    case TLS1_1_VERSION:
1388                        strcat(string, "TLS 1.1");
1389                        break;
1390                    case TLS1_2_VERSION:
1391                        strcat(string, "TLS 1.2");
1392                        break;
1393#ifdef TLS1_3_VERSION
1394                    case TLS1_3_VERSION:
1395                        strcat(string, "TLS 1.3 (experimental)");
1396                        ets->tls_v13 = 1;
1397                        break;
1398#endif
1399                    default:
1400                        strcat(string, "Unknown version");
1401                }
1402                break;
1403            default:
1404                sprintf( string, "Handshake: Unknown SSL3 code received: %d", code );
1405        }
1406        break;
1407
1408    default:
1409        sprintf( string, "SSL message contains unknown content type: %d", content_type );
1410    }
1411
1412    /* Alert messages must always be displayed */
1413    if(content_type == SSL3_RT_ALERT)
1414        error("%s", string);
1415    else
1416        dbglog("%s", string);
1417}
1418
1419int
1420ssl_new_session_cb(SSL *s, SSL_SESSION *sess)
1421{
1422    dbglog("EAP-TLS: Post-Handshake New Session Ticket arrived:");
1423    have_session_ticket = 1;
1424
1425    /* always return success */
1426    return 1;
1427}
1428
1429