1 /* * eap-tls.c - EAP-TLS implementation for PPP
3 * Copyright (c) Beniamino Galvani 2005 All rights reserved.
4 * Jan Just Keijser 2006-2019 All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
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
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.
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.
35 #include <sys/types.h>
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>
51 #include "pathnames.h"
53 typedef struct pw_cb_data
56 const char *prompt_info;
59 /* The openssl configuration file and engines can be loaded only once */
60 static CONF *ssl_config = NULL;
61 static ENGINE *cert_engine = NULL;
62 static ENGINE *pkey_engine = NULL;
64 /* TLSv1.3 do we have a session ticket ? */
65 static int have_session_ticket = 0;
67 int ssl_verify_callback(int, X509_STORE_CTX *);
68 void ssl_msg_callback(int write_p, int version, int ct, const void *buf,
69 size_t len, SSL * ssl, void *arg);
70 int ssl_new_session_cb(SSL *s, SSL_SESSION *sess);
72 X509 *get_X509_from_file(char *filename);
73 int ssl_cmp_certs(char *filename, X509 * a);
77 #define EAPTLS_MPPE_KEY_LEN 32
80 * OpenSSL 1.1+ introduced a generic TLS_method()
81 * For older releases we substitute the appropriate method
84 #if OPENSSL_VERSION_NUMBER < 0x10100000L
86 #define TLS_method SSLv23_method
88 #define SSL3_RT_HEADER 0x100
90 #ifndef SSL_CTX_set_max_proto_version
91 /** Mimics SSL_CTX_set_max_proto_version for OpenSSL < 1.1 */
92 static inline int SSL_CTX_set_max_proto_version(SSL_CTX *ctx, long tls_ver_max)
96 if (tls_ver_max < TLS1_VERSION)
98 sslopt |= SSL_OP_NO_TLSv1;
100 #ifdef SSL_OP_NO_TLSv1_1
101 if (tls_ver_max < TLS1_1_VERSION)
103 sslopt |= SSL_OP_NO_TLSv1_1;
106 #ifdef SSL_OP_NO_TLSv1_2
107 if (tls_ver_max < TLS1_2_VERSION)
109 sslopt |= SSL_OP_NO_TLSv1_2;
112 SSL_CTX_set_options(ctx, sslopt);
116 #endif /* SSL_CTX_set_max_proto_version */
118 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
122 * Generate keys according to RFC 2716 and add to reply
124 void eaptls_gen_mppe_keys(struct eaptls_session *ets, int client)
126 unsigned char out[4*EAPTLS_MPPE_KEY_LEN];
127 const char *prf_label;
129 unsigned char eap_tls13_context[] = { EAPT_TLS };
130 unsigned char *context = NULL;
131 size_t context_len = 0;
134 dbglog("EAP-TLS generating MPPE keys");
137 prf_label = "EXPORTER_EAP_TLS_Key_Material";
138 context = eap_tls13_context;
143 prf_label = "client EAP encryption";
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)
151 warn( "EAP-TLS: Failed generating keying material" );
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)
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) );
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) );
180 void log_ssl_errors( void )
182 unsigned long ssl_err = ERR_get_error();
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();
193 int password_callback (char *buf, int size, int rwflag, void *u)
197 strlcpy (buf, passwd, size);
204 CONF *eaptls_ssl_load_config( void )
208 long error_line = 33;
210 config = NCONF_new( NULL );
211 dbglog( "Loading OpenSSL config file" );
212 ret_code = NCONF_load( config, _PATH_OPENSSLCONFFILE, &error_line );
215 warn( "EAP-TLS: Error in OpenSSL config file %s at line %d", _PATH_OPENSSLCONFFILE, error_line );
216 NCONF_free( config );
221 dbglog( "Loading OpenSSL built-ins" );
222 ENGINE_load_builtin_engines();
223 OPENSSL_load_builtin_modules();
225 dbglog( "Loading OpenSSL configured modules" );
226 if (CONF_modules_load( config, NULL, 0 ) <= 0 )
228 warn( "EAP-TLS: Error loading OpenSSL modules" );
236 ENGINE *eaptls_ssl_load_engine( char *engine_name )
240 dbglog( "Enabling OpenSSL auto engines" );
241 ENGINE_register_all_complete();
243 dbglog( "Loading OpenSSL '%s' engine support", engine_name );
244 e = ENGINE_by_id( engine_name );
247 dbglog( "EAP-TLS: Cannot load '%s' engine support, trying 'dynamic'", engine_name );
248 e = ENGINE_by_id( "dynamic" );
251 if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine_name, 0)
252 || !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0))
254 warn( "EAP-TLS: Error loading dynamic engine '%s'", engine_name );
262 warn( "EAP-TLS: Cannot load dynamic engine support" );
268 dbglog( "Initialising engine" );
269 if(!ENGINE_set_default(e, ENGINE_METHOD_ALL))
271 warn( "EAP-TLS: Cannot use that engine" );
284 * Initialize the SSL stacks and tests if certificates, key and crl
285 * for client or server use can be loaded.
287 SSL_CTX *eaptls_init_ssl(int init_server, char *cacertfile, char *capath,
288 char *certfile, char *peer_certfile, char *privkeyfile)
290 char *cert_engine_name = NULL;
291 char *cert_identifier = NULL;
292 char *pkey_engine_name = NULL;
293 char *pkey_identifier = NULL;
296 X509_STORE *certstore;
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;
305 long tls_version = TLS1_VERSION;
309 * Without these can't continue
311 if (!(cacertfile[0] || capath[0]))
313 error("EAP-TLS: CA certificate file or path missing");
319 error("EAP-TLS: Certificate missing");
325 error("EAP-TLS: Private key missing");
330 SSL_load_error_strings();
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()
336 ssl_config = eaptls_ssl_load_config();
338 ctx = SSL_CTX_new(TLS_method());
341 error("EAP-TLS: Cannot initialize SSL CTX context");
345 /* if the certificate filename is of the form engine:id. e.g.
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
351 if ( index( certfile, '/' ) == NULL && index( certfile, '.') == NULL )
353 cert_identifier = index( certfile, ':' );
357 cert_engine_name = certfile;
358 *cert_identifier = '\0';
361 dbglog( "Found certificate engine '%s'", cert_engine_name );
362 dbglog( "Found certificate identifier '%s'", cert_identifier );
366 /* if the privatekey filename is of the form engine:id. e.g.
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
372 if ( index( privkeyfile, '/' ) == NULL && index( privkeyfile, '.') == NULL )
374 pkey_identifier = index( privkeyfile, ':' );
378 pkey_engine_name = privkeyfile;
379 *pkey_identifier = '\0';
382 dbglog( "Found privatekey engine '%s'", pkey_engine_name );
383 dbglog( "Found privatekey identifier '%s'", pkey_identifier );
387 if (cert_identifier && pkey_identifier)
389 if (strlen( cert_identifier ) == 0)
391 if (strlen( pkey_identifier ) == 0)
392 error( "EAP-TLS: both the certificate and privatekey identifiers are missing!" );
395 dbglog( "Substituting privatekey identifier for certificate identifier" );
396 cert_identifier = pkey_identifier;
401 if (strlen( pkey_identifier ) == 0)
403 dbglog( "Substituting certificate identifier for privatekey identifier" );
404 pkey_identifier = cert_identifier;
409 if (ssl_config && cert_engine_name)
410 cert_engine = eaptls_ssl_load_engine( cert_engine_name );
412 if (ssl_config && pkey_engine_name)
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;
418 pkey_engine = eaptls_ssl_load_engine( pkey_engine_name );
421 SSL_CTX_set_default_passwd_cb (ctx, password_callback);
423 if (strlen(cacertfile) == 0) cacertfile = NULL;
424 if (strlen(capath) == 0) capath = NULL;
426 if (!SSL_CTX_load_verify_locations(ctx, cacertfile, capath))
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);
435 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(cacertfile));
441 const char *s_slot_cert_id;
445 cert_info.s_slot_cert_id = cert_identifier;
446 cert_info.cert = NULL;
448 if (!ENGINE_ctrl_cmd( cert_engine, "LOAD_CERT_CTRL", 0, &cert_info, NULL, 0 ) )
450 error( "EAP-TLS: Error loading certificate with id '%s' from engine", cert_identifier );
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)
460 error("EAP-TLS: Cannot use PKCS11 certificate %s", cert_identifier);
466 warn("EAP-TLS: Cannot load PKCS11 key %s", cert_identifier);
472 if (!SSL_CTX_use_certificate_chain_file(ctx, certfile))
474 error( "EAP-TLS: Cannot use public certificate %s", certfile );
481 * Check the Before and After dates of the certificate
484 tmp = SSL_get_certificate(ssl);
486 ret = X509_cmp_time(X509_get_notBefore(tmp), NULL);
489 warn( "EAP-TLS: Failed to read certificate notBefore field.");
493 warn( "EAP-TLS: Your certificate is not yet valid!");
496 ret = X509_cmp_time(X509_get_notAfter(tmp), NULL);
499 warn( "EAP-TLS: Failed to read certificate notAfter field.");
503 warn( "EAP-TLS: Your certificate has expired!");
509 EVP_PKEY *pkey = NULL;
512 cb_data.password = passwd;
513 cb_data.prompt_info = pkey_identifier;
517 UI_METHOD* transfer_pin = UI_create_method("transfer_pin");
519 int writer (UI *ui, UI_STRING *uis)
521 PW_CB_DATA* cb_data = (PW_CB_DATA*)UI_get0_user_data(ui);
522 UI_set_result(ui, uis, cb_data->password);
525 int stub (UI* ui) {return 1;};
526 int stub_reader (UI *ui, UI_STRING *uis) {return 1;};
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);
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);
537 if (transfer_pin) UI_destroy_method(transfer_pin);
540 dbglog( "Loading private key '%s' from engine", pkey_identifier );
541 pkey = ENGINE_load_private_key(pkey_engine, pkey_identifier, NULL, NULL);
545 dbglog( "Got the private key, adding it to SSL context" );
546 if (SSL_CTX_use_PrivateKey(ctx, pkey) <= 0)
548 error("EAP-TLS: Cannot use PKCS11 key %s", pkey_identifier);
554 warn("EAP-TLS: Cannot load PKCS11 key %s", pkey_identifier);
560 if (!SSL_CTX_use_PrivateKey_file(ctx, privkeyfile, SSL_FILETYPE_PEM))
562 error("EAP-TLS: Cannot use private key %s", privkeyfile);
567 if (SSL_CTX_check_private_key(ctx) != 1) {
568 error("EAP-TLS: Private key %s fails security check", privkeyfile);
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
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
584 SSL_CTX_set_cipher_list(ctx, "RC4");
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.
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);
598 /* As EAP-TLS+TLSv1.3 is highly experimental we offer the user a chance to override */
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;
610 warn("TLSv1.2 not available. Defaulting to TLSv1.1");
611 tls_version = TLS_1_1_VERSION;
614 else if (strncmp(max_tls_version, "1.3", 3) == 0)
615 #ifdef TLS1_3_VERSION
616 tls_version = TLS1_3_VERSION;
618 warn("TLSv1.3 not available.");
622 dbglog("EAP-TLS: Setting max protocol version to 0x%X", tls_version);
623 SSL_CTX_set_max_proto_version(ctx, tls_version);
625 SSL_CTX_set_verify_depth(ctx, 5);
626 SSL_CTX_set_verify(ctx,
628 SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
629 &ssl_verify_callback);
632 if (!(certstore = SSL_CTX_get_cert_store(ctx))) {
633 error("EAP-TLS: Failed to get certificate store");
638 X509_STORE_add_lookup(certstore, X509_LOOKUP_hash_dir()))) {
639 error("EAP-TLS: Store lookup for CRL failed");
644 X509_LOOKUP_add_dir(lookup, crl_dir, X509_FILETYPE_PEM);
645 X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK);
650 X509_CRL *crl = NULL;
652 fp = fopen(crl_file, "r");
654 error("EAP-TLS: Cannot open CRL file '%s'", crl_file);
658 crl = PEM_read_X509_CRL(fp, NULL, NULL, NULL);
660 error("EAP-TLS: Cannot read CRL file '%s'", crl_file);
664 if (!(certstore = SSL_CTX_get_cert_store(ctx))) {
665 error("EAP-TLS: Failed to get certificate store");
668 if (!X509_STORE_add_crl(certstore, crl)) {
669 error("EAP-TLS: Cannot add CRL to certificate store");
672 X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK);
677 * If a peer certificate file was specified, it must be valid, else fail
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",
697 * Determine the maximum packet size by looking at the LCP handshake
700 int eaptls_get_mtu(int unit)
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];
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;
713 dbglog("MTU = %d", mtu);
719 * Init the ssl handshake (server mode)
721 int eaptls_init_ssl_server(eap_state * esp)
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];
730 * Allocate new eaptls session
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;
737 if (!esp->es_server.ea_peer) {
738 error("EAP-TLS: Error: client name not set (BUG)");
742 strlcpy(ets->peer, esp->es_server.ea_peer, MAXWORDLEN-1);
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 );
753 ets->mtu = eaptls_get_mtu(esp->es_unit);
755 ets->ctx = eaptls_init_ssl(1, cacertfile, capath, servcertfile, clicertfile, pkfile);
759 if (!(ets->ssl = SSL_new(ets->ctx)))
763 * Set auto-retry to avoid timeouts on BIO_read
765 SSL_set_mode(ets->ssl, SSL_MODE_AUTO_RETRY);
768 * Initialize the BIOs we use to read/write to ssl engine
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);
774 SSL_set_msg_callback(ets->ssl, ssl_msg_callback);
775 SSL_set_msg_callback_arg(ets->ssl, ets);
778 * Attach the session struct to the connection, so we can later
779 * retrieve it when doing certificate verification
781 SSL_set_ex_data(ets->ssl, 0, ets);
783 SSL_set_accept_state(ets->ssl);
793 * If we specified the client certificate file, store it in ets->peercertfile,
794 * so we can check it later in ssl_verify_callback()
797 strlcpy(&ets->peercertfile[0], clicertfile, MAXWORDLEN);
799 ets->peercertfile[0] = 0;
804 SSL_CTX_free(ets->ctx);
809 * Init the ssl handshake (client mode)
811 int eaptls_init_ssl_client(eap_state * esp)
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];
821 * Allocate new eaptls session
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;
829 * If available, copy server name in ets; it will be used in cert
832 if (esp->es_client.ea_peer)
833 strlcpy(ets->peer, esp->es_client.ea_peer, MAXWORDLEN-1);
837 ets->mtu = eaptls_get_mtu(esp->es_unit);
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 );
848 dbglog( "calling eaptls_init_ssl" );
849 ets->ctx = eaptls_init_ssl(0, cacertfile, capath, clicertfile, servcertfile, pkfile);
853 ets->ssl = SSL_new(ets->ctx);
859 * Initialize the BIOs we use to read/write to ssl engine
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);
866 SSL_set_msg_callback(ets->ssl, ssl_msg_callback);
867 SSL_set_msg_callback_arg(ets->ssl, ets);
870 * Attach the session struct to the connection, so we can later
871 * retrieve it when doing certificate verification
873 SSL_set_ex_data(ets->ssl, 0, ets);
875 SSL_set_connect_state(ets->ssl);
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()
890 strlcpy(ets->peercertfile, servcertfile, MAXWORDLEN);
892 ets->peercertfile[0] = 0;
897 dbglog( "eaptls_init_ssl_client: fail" );
898 SSL_CTX_free(ets->ctx);
903 void eaptls_free_session(struct eaptls_session *ets)
909 SSL_CTX_free(ets->ctx);
915 int eaptls_is_init_finished(struct eaptls_session *ets)
917 if (ets->ssl && SSL_is_init_finished(ets->ssl))
920 return have_session_ticket;
929 * Handle a received packet, reassembling fragmented messages and
930 * passing them to the ssl engine
932 int eaptls_receive(struct eaptls_session *ets, u_char * inp, int len)
939 warn("EAP-TLS: received no or invalid data");
946 if (flags & EAP_TLS_FLAGS_LI && len > 4) {
948 * LenghtIncluded flag set -> this is the first packet of a message
952 * the first 4 octets are the length of the EAP-TLS message
954 GETLONG(tlslen, inp);
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;
965 * Allocate memory for the whole message
967 ets->data = malloc(tlslen);
969 fatal("EAP-TLS: allocation error\n");
972 ets->tlslen = tlslen;
975 warn("EAP-TLS: non-first LI packet? that's odd...");
977 else if (!ets->data) {
979 * A non fragmented message without LI flag
982 ets->data = malloc(len);
984 fatal("EAP-TLS: memory allocation error in eaptls_receive\n");
990 if (flags & EAP_TLS_FLAGS_MF)
996 warn("EAP-TLS: received malformed data");
1000 if (len + ets->datalen > ets->tlslen) {
1001 warn("EAP-TLS: received data > TLS message length");
1005 BCOPY(inp, ets->data + ets->datalen, len);
1006 ets->datalen += len;
1011 * If we have the whole message, pass it to ssl
1014 if (ets->datalen != ets->tlslen) {
1015 warn("EAP-TLS: received data != TLS message length");
1019 if (BIO_write(ets->into_ssl, ets->data, ets->datalen) == -1)
1022 SSL_read(ets->ssl, dummy, 65536);
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.
1038 int eaptls_send(struct eaptls_session *ets, u_char ** outp)
1042 u_char fromtls[65536];
1050 if(!ets->alert_sent)
1052 res = SSL_read(ets->ssl, fromtls, 65536);
1058 if ((res = BIO_read(ets->from_ssl, fromtls, 65536)) == -1)
1060 warn("EAP-TLS send: No data from BIO_read");
1066 ets->data = malloc(ets->datalen);
1068 fatal("EAP-TLS: memory allocation error in eaptls_send\n");
1070 BCOPY(fromtls, ets->data, ets->datalen);
1076 size = ets->datalen - ets->offset;
1078 if (size > ets->mtu) {
1084 PUTCHAR(EAPT_TLS, *outp);
1087 * Set right flags and length if necessary
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);
1098 * Copy the data in outp
1100 BCOPY(ets->data + ets->offset, *outp, size);
1101 INCPTR(size, *outp);
1104 * Copy the packet in retransmission buffer
1106 BCOPY(start, &ets->rtx[0], *outp - start);
1107 ets->rtx_len = *outp - start;
1109 ets->offset += size;
1111 if (ets->offset >= ets->datalen) {
1114 * The whole message has been sent
1127 * Get the sent packet from the retransmission buffer
1129 void eaptls_retransmit(struct eaptls_session *ets, u_char ** outp)
1131 BCOPY(ets->rtx, *outp, ets->rtx_len);
1132 INCPTR(ets->rtx_len, *outp);
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.
1141 int ssl_verify_callback(int ok, X509_STORE_CTX * ctx)
1148 struct eaptls_session *ets;
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);
1154 dbglog("certificate verify depth: %d", depth);
1156 if (auth_required && !ok) {
1157 X509_NAME_oneline(X509_get_subject_name(peer_cert),
1160 X509_NAME_get_text_by_NID(X509_get_subject_name(peer_cert),
1161 NID_commonName, cn_str, 256);
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));
1170 ssl = X509_STORE_CTX_get_ex_data(ctx,
1171 SSL_get_ex_data_X509_STORE_CTX_idx());
1173 ets = (struct eaptls_session *)SSL_get_ex_data(ssl, 0);
1176 error("Error: SSL_get_ex_data returned NULL");
1184 /* This is the peer certificate */
1186 X509_NAME_oneline(X509_get_subject_name(peer_cert),
1189 X509_NAME_get_text_by_NID(X509_get_subject_name(peer_cert),
1190 NID_commonName, cn_str, 256);
1193 * If acting as client and the name of the server wasn't specified
1194 * explicitely, we can't verify the server authenticity
1196 if (!ets->peer[0]) {
1197 warn("Peer name not specified: no check");
1204 if (strcmp(cn_str, ets->peer)) {
1206 ("Certificate verification error: CN (%s) != peer_name (%s)",
1211 warn("Certificate CN: %s , peer name %s", cn_str, ets->peer);
1214 * If a peer certificate file was specified, here we check it
1216 if (ets->peercertfile[0]) {
1217 if (ssl_cmp_certs(&ets->peercertfile[0], peer_cert)
1220 ("Peer certificate doesn't match stored certificate");
1230 * Compare a certificate with the one stored in a file
1232 int ssl_cmp_certs(char *filename, X509 * a)
1237 if (!(b = get_X509_from_file(filename)))
1240 ret = X509_cmp(a, b);
1247 X509 *get_X509_from_file(char *filename)
1252 if (!(fp = fopen(filename, "r")))
1255 ret = PEM_read_X509(fp, NULL, NULL, NULL);
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.
1268 ssl_msg_callback(int write_p, int version, int content_type,
1269 const void *buf, size_t len, SSL * ssl, void *arg)
1272 struct eaptls_session *ets = (struct eaptls_session *)arg;
1274 const unsigned char*msg = buf;
1275 int hvers = msg[1] << 8 | msg[2];
1278 strcpy(string, " -> ");
1280 strcpy(string, " <- ");
1282 switch(content_type) {
1284 case SSL3_RT_HEADER:
1285 strcat(string, "SSL/TLS Header: ");
1288 strcat(string, "SSL 3.0");
1291 strcat(string, "TLS 1.0");
1293 case TLS1_1_VERSION:
1294 strcat(string, "TLS 1.1");
1296 case TLS1_2_VERSION:
1297 strcat(string, "TLS 1.2");
1300 sprintf(string, "SSL/TLS Header: Unknown version (%d)", hvers);
1305 strcat(string, "Alert: ");
1309 ets->alert_sent = 1;
1310 ets->alert_sent_desc = code;
1312 ets->alert_recv = 1;
1313 ets->alert_recv_desc = code;
1316 strcat(string, SSL_alert_desc_string_long(code));
1319 case SSL3_RT_CHANGE_CIPHER_SPEC:
1320 strcat(string, "ChangeCipherSpec");
1323 #ifdef SSL3_RT_INNER_CONTENT_TYPE
1324 case SSL3_RT_INNER_CONTENT_TYPE:
1325 strcat(string, "InnerContentType (TLS1.3)");
1329 case SSL3_RT_HANDSHAKE:
1331 strcat(string, "Handshake: ");
1335 case SSL3_MT_HELLO_REQUEST:
1336 strcat(string,"Hello Request");
1338 case SSL3_MT_CLIENT_HELLO:
1339 strcat(string,"Client Hello");
1341 case SSL3_MT_SERVER_HELLO:
1342 strcat(string,"Server Hello");
1344 #ifdef SSL3_MT_NEWSESSION_TICKET
1345 case SSL3_MT_NEWSESSION_TICKET:
1346 strcat(string,"New Session Ticket");
1349 #ifdef SSL3_MT_END_OF_EARLY_DATA
1350 case SSL3_MT_END_OF_EARLY_DATA:
1351 strcat(string,"End of Early Data");
1354 #ifdef SSL3_MT_ENCRYPTED_EXTENSIONS
1355 case SSL3_MT_ENCRYPTED_EXTENSIONS:
1356 strcat(string,"Encryped Extensions");
1359 case SSL3_MT_CERTIFICATE:
1360 strcat(string,"Certificate");
1362 case SSL3_MT_SERVER_KEY_EXCHANGE:
1363 strcat(string,"Server Key Exchange");
1365 case SSL3_MT_CERTIFICATE_REQUEST:
1366 strcat(string,"Certificate Request");
1368 case SSL3_MT_SERVER_DONE:
1369 strcat(string,"Server Hello Done");
1371 case SSL3_MT_CERTIFICATE_VERIFY:
1372 strcat(string,"Certificate Verify");
1374 case SSL3_MT_CLIENT_KEY_EXCHANGE:
1375 strcat(string,"Client Key Exchange");
1377 case SSL3_MT_FINISHED:
1378 strcat(string,"Finished: ");
1379 hvers = SSL_version(ssl);
1382 strcat(string, "SSL 3.0");
1385 strcat(string, "TLS 1.0");
1387 case TLS1_1_VERSION:
1388 strcat(string, "TLS 1.1");
1390 case TLS1_2_VERSION:
1391 strcat(string, "TLS 1.2");
1393 #ifdef TLS1_3_VERSION
1394 case TLS1_3_VERSION:
1395 strcat(string, "TLS 1.3 (experimental)");
1400 strcat(string, "Unknown version");
1404 sprintf( string, "Handshake: Unknown SSL3 code received: %d", code );
1409 sprintf( string, "SSL message contains unknown content type: %d", content_type );
1412 /* Alert messages must always be displayed */
1413 if(content_type == SSL3_RT_ALERT)
1414 error("%s", string);
1416 dbglog("%s", string);
1420 ssl_new_session_cb(SSL *s, SSL_SESSION *sess)
1422 dbglog("EAP-TLS: Post-Handshake New Session Ticket arrived:");
1423 have_session_ticket = 1;
1425 /* always return success */