Home | History | Annotate | Line # | Download | only in pppd
      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  */
     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 
    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 
    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
    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
    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 
    244 static int eaptls_UI_stub(UI* ui) {
    245     return 1;
    246 }
    247 
    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  */
    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 
    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  */
    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  */
    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 
    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 
    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  */
    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  */
    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  */
   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
   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
   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