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.
39 #include <sys/types.h>
43 #include <openssl/conf.h>
44 #ifndef OPENSSL_NO_ENGINE
45 #include <openssl/engine.h>
47 #include <openssl/hmac.h>
48 #include <openssl/err.h>
49 #include <openssl/ui.h>
50 #include <openssl/x509v3.h>
51 #include <openssl/pkcs12.h>
60 #include "pathnames.h"
62 typedef struct pw_cb_data
65 const char *prompt_info;
68 #ifndef OPENSSL_NO_ENGINE
69 /* The openssl configuration file and engines can be loaded only once */
70 static CONF *ssl_config = NULL;
71 static ENGINE *cert_engine = NULL;
72 static ENGINE *pkey_engine = NULL;
75 /* TLSv1.3 do we have a session ticket ? */
76 static int have_session_ticket = 0;
78 int ssl_verify_callback(int, X509_STORE_CTX *);
79 void ssl_msg_callback(int write_p, int version, int ct, const void *buf,
80 size_t len, SSL * ssl, void *arg);
81 int ssl_new_session_cb(SSL *s, SSL_SESSION *sess);
83 X509 *get_X509_from_file(char *filename);
84 int ssl_cmp_certs(char *filename, X509 * a);
87 * OpenSSL 1.1+ introduced a generic TLS_method()
88 * For older releases we substitute the appropriate method
91 #if OPENSSL_VERSION_NUMBER < 0x10100000L
93 #define TLS_method SSLv23_method
95 #define SSL3_RT_HEADER 0x100
97 #ifndef SSL_CTX_set_max_proto_version
98 /** Mimics SSL_CTX_set_max_proto_version for OpenSSL < 1.1 */
99 static inline int SSL_CTX_set_max_proto_version(SSL_CTX *ctx, long tls_ver_max)
103 if (tls_ver_max < TLS1_VERSION)
105 sslopt |= SSL_OP_NO_TLSv1;
107 #ifdef SSL_OP_NO_TLSv1_1
108 if (tls_ver_max < TLS1_1_VERSION)
110 sslopt |= SSL_OP_NO_TLSv1_1;
113 #ifdef SSL_OP_NO_TLSv1_2
114 if (tls_ver_max < TLS1_2_VERSION)
116 sslopt |= SSL_OP_NO_TLSv1_2;
119 SSL_CTX_set_options(ctx, sslopt);
123 #endif /* SSL_CTX_set_max_proto_version */
125 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
128 #define EAPTLS_MPPE_KEY_LEN 32
131 * Generate keys according to RFC 2716 and add to reply
133 void eaptls_gen_mppe_keys(struct eaptls_session *ets, int client)
135 unsigned char out[4*EAPTLS_MPPE_KEY_LEN];
136 const char *prf_label;
138 unsigned char eap_tls13_context[] = { EAPT_TLS };
139 unsigned char *context = NULL;
140 size_t context_len = 0;
143 dbglog("EAP-TLS generating MPPE keys");
146 prf_label = "EXPORTER_EAP_TLS_Key_Material";
147 context = eap_tls13_context;
152 prf_label = "client EAP encryption";
155 dbglog("EAP-TLS PRF label = %s", prf_label);
156 prf_size = strlen(prf_label);
157 if (SSL_export_keying_material(ets->ssl, out, sizeof(out), prf_label, prf_size,
158 context, context_len, 0) != 1)
160 warn( "EAP-TLS: Failed generating keying material" );
165 * We now have the master send and receive keys.
166 * From these, generate the session send and receive keys.
167 * (see RFC3079 / draft-ietf-pppext-mppe-keys-03.txt for details)
171 mppe_set_keys(out, out + EAPTLS_MPPE_KEY_LEN, EAPTLS_MPPE_KEY_LEN);
175 mppe_set_keys(out + EAPTLS_MPPE_KEY_LEN, out, EAPTLS_MPPE_KEY_LEN);
182 void log_ssl_errors( void )
184 unsigned long ssl_err = ERR_get_error();
187 dbglog("EAP-TLS SSL error stack:");
188 while (ssl_err != 0) {
189 dbglog( ERR_error_string( ssl_err, NULL ) );
190 ssl_err = ERR_get_error();
195 int password_callback (char *buf, int size, int rwflag, void *u)
199 strlcpy (buf, passwd, size);
206 CONF *eaptls_ssl_load_config( void )
210 long error_line = 33;
212 config = NCONF_new( NULL );
213 dbglog( "Loading OpenSSL config file" );
214 ret_code = NCONF_load( config, _PATH_OPENSSLCONFFILE, &error_line );
217 warn( "EAP-TLS: Error in OpenSSL config file %s at line %d", _PATH_OPENSSLCONFFILE, error_line );
218 NCONF_free( config );
223 dbglog( "Loading OpenSSL built-ins" );
224 #ifndef OPENSSL_NO_ENGINE
225 ENGINE_load_builtin_engines();
227 OPENSSL_load_builtin_modules();
229 dbglog( "Loading OpenSSL configured modules" );
230 if (CONF_modules_load( config, NULL, 0 ) <= 0 )
232 warn( "EAP-TLS: Error loading OpenSSL modules" );
240 #ifndef OPENSSL_NO_ENGINE
241 ENGINE *eaptls_ssl_load_engine( char *engine_name )
245 dbglog( "Enabling OpenSSL auto engines" );
246 ENGINE_register_all_complete();
248 dbglog( "Loading OpenSSL '%s' engine support", engine_name );
249 e = ENGINE_by_id( engine_name );
252 dbglog( "EAP-TLS: Cannot load '%s' engine support, trying 'dynamic'", engine_name );
253 e = ENGINE_by_id( "dynamic" );
256 if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine_name, 0)
257 || !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0))
259 warn( "EAP-TLS: Error loading dynamic engine '%s'", engine_name );
267 warn( "EAP-TLS: Cannot load dynamic engine support" );
273 dbglog( "Initialising engine" );
274 if(!ENGINE_set_default(e, ENGINE_METHOD_ALL))
276 warn( "EAP-TLS: Cannot use that engine" );
288 #ifndef OPENSSL_NO_ENGINE
289 static int eaptls_UI_writer(UI *ui, UI_STRING *uis)
291 PW_CB_DATA* cb_data = (PW_CB_DATA*)UI_get0_user_data(ui);
292 UI_set_result(ui, uis, cb_data->password);
296 static int eaptls_UI_stub(UI* ui) {
300 static int eaptls_UI_reader(UI *ui, UI_STRING *uis) {
306 * Initialize the SSL stacks and tests if certificates, key and crl
307 * for client or server use can be loaded.
309 SSL_CTX *eaptls_init_ssl(int init_server, char *cacertfile, char *capath,
310 char *certfile, char *peer_certfile, char *privkeyfile, char *pkcs12)
312 #ifndef OPENSSL_NO_ENGINE
313 char *cert_engine_name = NULL;
314 char *pkey_engine_name = NULL;
319 X509_STORE *certstore;
324 EVP_PKEY *pkey = NULL;
325 STACK_OF(X509) *chain = NULL;
329 #if defined(TLS1_2_VERSION)
330 long tls_version = TLS1_2_VERSION;
331 #elif defined(TLS1_1_VERSION)
332 long tls_version = TLS1_1_VERSION;
334 long tls_version = TLS1_VERSION;
338 * Without these can't continue
342 if (!(cacertfile[0] || capath[0]))
344 error("EAP-TLS: CA certificate file or path missing");
350 error("EAP-TLS: Certificate missing");
356 error("EAP-TLS: Private key missing");
362 SSL_load_error_strings();
364 #ifndef OPENSSL_NO_ENGINE
365 /* load the openssl config file only once and load it before triggering
366 the loading of a global openssl config file via SSL_CTX_new()
369 ssl_config = eaptls_ssl_load_config();
372 ctx = SSL_CTX_new(TLS_method());
375 error("EAP-TLS: Cannot initialize SSL CTX context");
379 #ifndef OPENSSL_NO_ENGINE
380 /* if the certificate filename is of the form engine:id. e.g.
382 then we try to load and use this engine.
383 If the certificate filename starts with a / or . then we
384 ALWAYS assume it is a file and not an engine/pkcs11 identifier
386 if ( (idx = index( certfile, ':' )) != NULL )
388 cert_engine_name = strdup( certfile );
389 cert_engine_name[idx - certfile] = 0;
391 dbglog( "Using engine '%s' for certificate, URI: '%s'",
392 cert_engine_name, certfile );
395 /* if the privatekey filename is of the form engine:id. e.g.
397 then we try to load and use this engine.
398 If the privatekey filename starts with a / or . then we
399 ALWAYS assume it is a file and not an engine/pkcs11 identifier
401 if ( (idx = index( privkeyfile, ':' )) != NULL )
403 pkey_engine_name = strdup( privkeyfile );
404 pkey_engine_name[idx - privkeyfile] = 0;
406 dbglog( "Using engine '%s' for private key, URI: '%s'",
407 pkey_engine_name, privkeyfile );
410 if (cert_engine_name && pkey_engine_name)
412 if (strlen( certfile ) - strlen( cert_engine_name ) == 1)
414 if (strlen( privkeyfile ) - strlen( pkey_engine_name ) == 1)
415 error( "EAP-TLS: both the certificate and privatekey identifiers are missing!" );
418 dbglog( "Substituting privatekey identifier for certificate identifier" );
419 certfile = privkeyfile;
424 if (strlen( privkeyfile ) - strlen( pkey_engine_name ) == 1)
426 dbglog( "Substituting certificate identifier for privatekey identifier" );
427 privkeyfile = certfile;
432 if (ssl_config && cert_engine_name)
433 cert_engine = eaptls_ssl_load_engine( cert_engine_name );
435 if (ssl_config && pkey_engine_name)
437 /* don't load the same engine twice */
438 if ( cert_engine && strcmp( cert_engine_name, pkey_engine_name) == 0 )
439 pkey_engine = cert_engine;
441 pkey_engine = eaptls_ssl_load_engine( pkey_engine_name );
444 if (cert_engine_name)
445 free(cert_engine_name);
447 if (pkey_engine_name)
448 free(pkey_engine_name);
452 SSL_CTX_set_default_passwd_cb (ctx, password_callback);
454 if (strlen(cacertfile) == 0) cacertfile = NULL;
455 if (strlen(capath) == 0) capath = NULL;
457 if (!SSL_CTX_load_verify_locations(ctx, cacertfile, capath))
459 error("EAP-TLS: Cannot load verify locations");
460 if (cacertfile) dbglog("CA certificate file = [%s]", cacertfile);
461 if (capath) dbglog("CA certificate path = [%s]", capath);
466 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(cacertfile));
468 #ifndef OPENSSL_NO_ENGINE
473 const char *s_slot_cert_id;
477 cert_info.s_slot_cert_id = certfile;
478 cert_info.cert = NULL;
480 if (!ENGINE_ctrl_cmd( cert_engine, "LOAD_CERT_CTRL", 0, &cert_info, NULL, 0 ) )
482 error( "EAP-TLS: Error loading certificate with URI '%s' from engine", certfile );
488 dbglog( "Got the certificate" );
489 dbglog( "subject = %s", X509_NAME_oneline( X509_get_subject_name( cert_info.cert ), NULL, 0 ) );
490 cert = cert_info.cert;
494 warn("EAP-TLS: Cannot load key with URI: '%s'", certfile );
503 input = BIO_new_file(pkcs12, "r");
506 error("EAP-TLS: Cannot open `%s' PKCS12 for input", pkcs12);
510 p12 = d2i_PKCS12_bio(input, NULL);
514 error("EAP-TLS: Cannot load PKCS12 certificate");
518 if (PKCS12_parse(p12, passwd, &pkey, &cert, &chain) != 1)
520 error("EAP-TLS: Cannot parse PKCS12 certificate, invalid password");
529 if (!SSL_CTX_use_certificate_chain_file(ctx, certfile))
531 error( "EAP-TLS: Cannot load certificate %s", certfile );
539 if (!SSL_CTX_use_certificate(ctx, cert))
541 error("EAP-TLS: Cannot use load certificate");
548 for (i = 0; i < sk_X509_num(chain); i++)
550 if (!SSL_CTX_add_extra_chain_cert(ctx, sk_X509_value(chain, i)))
552 error("EAP-TLS: Cannot add extra chain certificate");
560 * Check the Before and After dates of the certificate
563 tmp = SSL_get_certificate(ssl);
565 ret = X509_cmp_time(X509_get_notBefore(tmp), NULL);
568 warn( "EAP-TLS: Failed to read certificate notBefore field.");
572 warn( "EAP-TLS: Your certificate is not yet valid!");
575 ret = X509_cmp_time(X509_get_notAfter(tmp), NULL);
578 warn( "EAP-TLS: Failed to read certificate notAfter field.");
582 warn( "EAP-TLS: Your certificate has expired!");
586 #ifndef OPENSSL_NO_ENGINE
591 cb_data.password = passwd;
592 cb_data.prompt_info = privkeyfile;
596 UI_METHOD* transfer_pin = UI_create_method("transfer_pin");
598 UI_method_set_writer(transfer_pin, eaptls_UI_writer);
599 UI_method_set_opener(transfer_pin, eaptls_UI_stub);
600 UI_method_set_closer(transfer_pin, eaptls_UI_stub);
601 UI_method_set_flusher(transfer_pin, eaptls_UI_stub);
602 UI_method_set_reader(transfer_pin, eaptls_UI_reader);
604 dbglog( "Using our private key URI: '%s' in engine", privkeyfile );
605 pkey = ENGINE_load_private_key(pkey_engine, privkeyfile, transfer_pin, &cb_data);
607 if (transfer_pin) UI_destroy_method(transfer_pin);
610 dbglog( "Loading private key URI: '%s' from engine", privkeyfile );
611 pkey = ENGINE_load_private_key(pkey_engine, privkeyfile, NULL, NULL);
619 input = BIO_new_file(privkeyfile, "r");
622 error("EAP-TLS: Could not open private key, %s", privkeyfile);
626 pkey = PEM_read_bio_PrivateKey(input, NULL, password_callback, NULL);
630 error("EAP-TLS: Cannot load private key, %s", privkeyfile);
636 if (SSL_CTX_use_PrivateKey(ctx, pkey) != 1)
638 error("EAP-TLS: Cannot use private key");
642 if (SSL_CTX_check_private_key(ctx) != 1)
644 error("EAP-TLS: Private key fails security check");
648 /* Explicitly set the NO_TICKETS flag to support Win7/Win8 clients */
649 SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3
650 #ifdef SSL_OP_NO_TICKET
655 /* OpenSSL 1.1.1+ does not include RC4 ciphers by default.
656 * This causes totally obsolete WinXP clients to fail. If you really
657 * need ppp+EAP-TLS+openssl 1.1.1+WinXP then enable RC4 cipers and
658 * make sure that you use an OpenSSL that supports them
660 SSL_CTX_set_cipher_list(ctx, "RC4");
664 /* Set up a SSL Session cache with a callback. This is needed for TLSv1.3+.
665 * During the initial handshake the server signals to the client early on
666 * that the handshake is finished, even before the client has sent its
667 * credentials to the server. The actual connection (and moment that the
668 * client sends its credentials) only starts after the arrival of the first
669 * session ticket. The 'ssl_new_session_cb' catches this ticket.
671 SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL_STORE);
672 SSL_CTX_sess_set_new_cb(ctx, ssl_new_session_cb);
674 /* As EAP-TLS+TLSv1.3 is highly experimental we offer the user a chance to override */
677 if (strncmp(max_tls_version, "1.0", 3) == 0)
678 tls_version = TLS1_VERSION;
679 else if (strncmp(max_tls_version, "1.1", 3) == 0)
680 tls_version = TLS1_1_VERSION;
681 else if (strncmp(max_tls_version, "1.2", 3) == 0)
682 #ifdef TLS1_2_VERSION
683 tls_version = TLS1_2_VERSION;
686 warn("TLSv1.2 not available. Defaulting to TLSv1.1");
687 tls_version = TLS_1_1_VERSION;
690 else if (strncmp(max_tls_version, "1.3", 3) == 0)
691 #ifdef TLS1_3_VERSION
692 tls_version = TLS1_3_VERSION;
694 warn("TLSv1.3 not available.");
698 dbglog("EAP-TLS: Setting max protocol version to 0x%X", tls_version);
699 SSL_CTX_set_max_proto_version(ctx, tls_version);
701 SSL_CTX_set_verify_depth(ctx, 5);
702 SSL_CTX_set_verify(ctx,
704 SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
705 &ssl_verify_callback);
708 if (!(certstore = SSL_CTX_get_cert_store(ctx))) {
709 error("EAP-TLS: Failed to get certificate store");
714 X509_STORE_add_lookup(certstore, X509_LOOKUP_hash_dir()))) {
715 error("EAP-TLS: Store lookup for CRL failed");
720 X509_LOOKUP_add_dir(lookup, crl_dir, X509_FILETYPE_PEM);
721 X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK);
726 X509_CRL *crl = NULL;
728 fp = fopen(crl_file, "r");
730 error("EAP-TLS: Cannot open CRL file '%s'", crl_file);
734 crl = PEM_read_X509_CRL(fp, NULL, NULL, NULL);
736 error("EAP-TLS: Cannot read CRL file '%s'", crl_file);
740 if (!(certstore = SSL_CTX_get_cert_store(ctx))) {
741 error("EAP-TLS: Failed to get certificate store");
744 if (!X509_STORE_add_crl(certstore, crl)) {
745 error("EAP-TLS: Cannot add CRL to certificate store");
748 X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK);
753 * If a peer certificate file was specified, it must be valid, else fail
755 if (peer_certfile[0]) {
756 if (!(tmp = get_X509_from_file(peer_certfile))) {
757 error("EAP-TLS: Error loading client certificate from file %s",
775 sk_X509_pop_free(chain, X509_free);
783 * Determine the maximum packet size by looking at the LCP handshake
786 int eaptls_get_mtu(int unit)
790 lcp_options *wo = &lcp_wantoptions[unit];
791 lcp_options *go = &lcp_gotoptions[unit];
792 lcp_options *ho = &lcp_hisoptions[unit];
793 lcp_options *ao = &lcp_allowoptions[unit];
795 mtu = ho->neg_mru? ho->mru: PPP_MRU;
796 mru = go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU;
797 mtu = MIN(MIN(mtu, mru), ao->mru)- PPP_HDRLEN - 10;
799 dbglog("MTU = %d", mtu);
805 * Init the ssl handshake (server mode)
807 int eaptls_init_ssl_server(eap_state * esp)
809 struct eaptls_session *ets;
810 char servcertfile[MAXWORDLEN];
811 char clicertfile[MAXWORDLEN];
812 char cacertfile[MAXWORDLEN];
813 char capath[MAXWORDLEN];
814 char pkfile[MAXWORDLEN];
815 char pkcs12[MAXWORDLEN];
818 * Allocate new eaptls session
820 esp->es_server.ea_session = malloc(sizeof(struct eaptls_session));
821 if (!esp->es_server.ea_session)
822 fatal("Allocation error");
823 ets = esp->es_server.ea_session;
826 if (!esp->es_server.ea_peer) {
827 error("EAP-TLS: Error: client name not set (BUG)");
831 strlcpy(ets->peer, esp->es_server.ea_peer, MAXWORDLEN-1);
833 dbglog( "getting eaptls secret" );
834 if (!get_eaptls_secret(esp->es_unit, esp->es_server.ea_peer,
835 esp->es_server.ea_name, clicertfile,
836 servcertfile, cacertfile, capath, pkfile, pkcs12, 1)) {
837 error( "EAP-TLS: Cannot get secret/password for client \"%s\", server \"%s\"",
838 esp->es_server.ea_peer, esp->es_server.ea_name );
842 ets->mtu = eaptls_get_mtu(esp->es_unit);
844 ets->ctx = eaptls_init_ssl(1, cacertfile, capath, servcertfile, clicertfile, pkfile, pkcs12);
848 if (!(ets->ssl = SSL_new(ets->ctx)))
852 * Set auto-retry to avoid timeouts on BIO_read
854 SSL_set_mode(ets->ssl, SSL_MODE_AUTO_RETRY);
857 * Initialize the BIOs we use to read/write to ssl engine
859 ets->into_ssl = BIO_new(BIO_s_mem());
860 ets->from_ssl = BIO_new(BIO_s_mem());
861 SSL_set_bio(ets->ssl, ets->into_ssl, ets->from_ssl);
863 SSL_set_msg_callback(ets->ssl, ssl_msg_callback);
864 SSL_set_msg_callback_arg(ets->ssl, ets);
867 * Attach the session struct to the connection, so we can later
868 * retrieve it when doing certificate verification
870 SSL_set_ex_data(ets->ssl, 0, ets);
872 SSL_set_accept_state(ets->ssl);
882 * If we specified the client certificate file, store it in ets->peercertfile,
883 * so we can check it later in ssl_verify_callback()
886 strlcpy(&ets->peercertfile[0], clicertfile, MAXWORDLEN);
888 ets->peercertfile[0] = 0;
893 SSL_CTX_free(ets->ctx);
898 * Init the ssl handshake (client mode)
900 int eaptls_init_ssl_client(eap_state * esp)
902 struct eaptls_session *ets;
903 char servcertfile[MAXWORDLEN];
904 char clicertfile[MAXWORDLEN];
905 char cacertfile[MAXWORDLEN];
906 char capath[MAXWORDLEN];
907 char pkfile[MAXWORDLEN];
908 char pkcs12[MAXWORDLEN];
911 * Allocate new eaptls session
913 esp->es_client.ea_session = malloc(sizeof(struct eaptls_session));
914 if (!esp->es_client.ea_session)
915 fatal("Allocation error");
916 ets = esp->es_client.ea_session;
920 * If available, copy server name in ets; it will be used in cert
923 if (esp->es_client.ea_peer)
924 strlcpy(ets->peer, esp->es_client.ea_peer, MAXWORDLEN-1);
928 ets->mtu = eaptls_get_mtu(esp->es_unit);
930 dbglog( "calling get_eaptls_secret" );
931 if (!get_eaptls_secret(esp->es_unit, esp->es_client.ea_name,
932 ets->peer, clicertfile,
933 servcertfile, cacertfile, capath, pkfile, pkcs12, 0)) {
934 error( "EAP-TLS: Cannot get secret/password for client \"%s\", server \"%s\"",
935 esp->es_client.ea_name, ets->peer );
939 dbglog( "calling eaptls_init_ssl" );
940 ets->ctx = eaptls_init_ssl(0, cacertfile, capath, clicertfile, servcertfile, pkfile, pkcs12);
944 ets->ssl = SSL_new(ets->ctx);
950 * Initialize the BIOs we use to read/write to ssl engine
952 dbglog( "Initializing SSL BIOs" );
953 ets->into_ssl = BIO_new(BIO_s_mem());
954 ets->from_ssl = BIO_new(BIO_s_mem());
955 SSL_set_bio(ets->ssl, ets->into_ssl, ets->from_ssl);
957 SSL_set_msg_callback(ets->ssl, ssl_msg_callback);
958 SSL_set_msg_callback_arg(ets->ssl, ets);
961 * Attach the session struct to the connection, so we can later
962 * retrieve it when doing certificate verification
964 SSL_set_ex_data(ets->ssl, 0, ets);
966 SSL_set_connect_state(ets->ssl);
976 * If we specified the server certificate file, store it in
977 * ets->peercertfile, so we can check it later in
978 * ssl_verify_callback()
981 strlcpy(ets->peercertfile, servcertfile, MAXWORDLEN);
983 ets->peercertfile[0] = 0;
988 dbglog( "eaptls_init_ssl_client: fail" );
989 SSL_CTX_free(ets->ctx);
994 void eaptls_free_session(struct eaptls_session *ets)
1000 SSL_CTX_free(ets->ctx);
1006 int eaptls_is_init_finished(struct eaptls_session *ets)
1008 if (ets->ssl && SSL_is_init_finished(ets->ssl))
1011 return have_session_ticket;
1020 * Handle a received packet, reassembling fragmented messages and
1021 * passing them to the ssl engine
1023 int eaptls_receive(struct eaptls_session *ets, u_char * inp, int len)
1027 u_char dummy[65536];
1030 warn("EAP-TLS: received no or invalid data");
1034 GETCHAR(flags, inp);
1037 if (flags & EAP_TLS_FLAGS_LI && len > 4) {
1039 * LenghtIncluded flag set -> this is the first packet of a message
1043 * the first 4 octets are the length of the EAP-TLS message
1045 GETLONG(tlslen, inp);
1050 if (tlslen > EAP_TLS_MAX_LEN) {
1051 error("EAP-TLS: TLS message length > %d, truncated", EAP_TLS_MAX_LEN);
1052 tlslen = EAP_TLS_MAX_LEN;
1056 * Allocate memory for the whole message
1058 ets->data = malloc(tlslen);
1060 fatal("EAP-TLS: allocation error\n");
1063 ets->tlslen = tlslen;
1066 warn("EAP-TLS: non-first LI packet? that's odd...");
1068 else if (!ets->data) {
1070 * A non fragmented message without LI flag
1073 ets->data = malloc(len);
1075 fatal("EAP-TLS: memory allocation error in eaptls_receive\n");
1081 if (flags & EAP_TLS_FLAGS_MF)
1087 warn("EAP-TLS: received malformed data");
1091 if (len + ets->datalen > ets->tlslen) {
1092 warn("EAP-TLS: received data > TLS message length");
1096 BCOPY(inp, ets->data + ets->datalen, len);
1097 ets->datalen += len;
1102 * If we have the whole message, pass it to ssl
1105 if (ets->datalen != ets->tlslen) {
1106 warn("EAP-TLS: received data != TLS message length");
1110 if (BIO_write(ets->into_ssl, ets->data, ets->datalen) == -1)
1113 SSL_read(ets->ssl, dummy, 65536);
1124 * Return an eap-tls packet in outp.
1125 * A TLS message read from the ssl engine is buffered in ets->data.
1126 * At each call we control if there is buffered data and send a
1127 * packet of mtu bytes.
1129 int eaptls_send(struct eaptls_session *ets, u_char ** outp)
1133 u_char fromtls[65536];
1141 if(!ets->alert_sent)
1143 res = SSL_read(ets->ssl, fromtls, 65536);
1149 if ((res = BIO_read(ets->from_ssl, fromtls, 65536)) == -1)
1151 warn("EAP-TLS send: No data from BIO_read");
1157 ets->data = malloc(ets->datalen);
1159 fatal("EAP-TLS: memory allocation error in eaptls_send\n");
1161 BCOPY(fromtls, ets->data, ets->datalen);
1167 size = ets->datalen - ets->offset;
1169 if (size > ets->mtu) {
1175 PUTCHAR(EAPT_TLS, *outp);
1178 * Set right flags and length if necessary
1180 if (ets->frag && first) {
1181 PUTCHAR(EAP_TLS_FLAGS_LI | EAP_TLS_FLAGS_MF, *outp);
1182 PUTLONG(ets->datalen, *outp);
1183 } else if (ets->frag) {
1184 PUTCHAR(EAP_TLS_FLAGS_MF, *outp);
1189 * Copy the data in outp
1191 BCOPY(ets->data + ets->offset, *outp, size);
1192 INCPTR(size, *outp);
1195 * Copy the packet in retransmission buffer
1197 BCOPY(start, &ets->rtx[0], *outp - start);
1198 ets->rtx_len = *outp - start;
1200 ets->offset += size;
1202 if (ets->offset >= ets->datalen) {
1205 * The whole message has been sent
1218 * Get the sent packet from the retransmission buffer
1220 void eaptls_retransmit(struct eaptls_session *ets, u_char ** outp)
1222 BCOPY(ets->rtx, *outp, ets->rtx_len);
1223 INCPTR(ets->rtx_len, *outp);
1227 * Verify a certificate.
1228 * Most of the work (signatures and issuer attributes checking)
1229 * is done by ssl; we check the CN in the peer certificate
1230 * against the peer name.
1232 int ssl_verify_callback(int ok, X509_STORE_CTX * ctx)
1239 struct eaptls_session *ets;
1240 char *ptr1 = NULL, *ptr2 = NULL;
1242 peer_cert = X509_STORE_CTX_get_current_cert(ctx);
1243 err = X509_STORE_CTX_get_error(ctx);
1244 depth = X509_STORE_CTX_get_error_depth(ctx);
1246 dbglog("certificate verify depth: %d", depth);
1248 if (auth_required && !ok) {
1249 X509_NAME_oneline(X509_get_subject_name(peer_cert),
1252 X509_NAME_get_text_by_NID(X509_get_subject_name(peer_cert),
1253 NID_commonName, cn_str, 256);
1255 dbglog("Certificate verification error:\n depth: %d CN: %s"
1256 "\n err: %d (%s)\n", depth, cn_str, err,
1257 X509_verify_cert_error_string(err));
1262 ssl = X509_STORE_CTX_get_ex_data(ctx,
1263 SSL_get_ex_data_X509_STORE_CTX_idx());
1265 ets = (struct eaptls_session *)SSL_get_ex_data(ssl, 0);
1268 error("Error: SSL_get_ex_data returned NULL");
1276 /* Verify certificate based on certificate type and extended key usage */
1277 if (tls_verify_key_usage) {
1278 int purpose = ets->client ? X509_PURPOSE_SSL_SERVER : X509_PURPOSE_SSL_CLIENT ;
1279 if (X509_check_purpose(peer_cert, purpose, 0) == 0) {
1280 error("Certificate verification error: nsCertType mismatch");
1284 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
1285 int flags = ets->client ? XKU_SSL_SERVER : XKU_SSL_CLIENT;
1286 if (!(X509_get_extended_key_usage(peer_cert) & flags)) {
1287 error("Certificate verification error: invalid extended key usage");
1291 info("Certificate key usage: OK");
1295 * If acting as client and the name of the server wasn't specified
1296 * explicitely, we can't verify the server authenticity
1298 if (!tls_verify_method)
1299 tls_verify_method = TLS_VERIFY_NONE;
1301 if (!ets->peer[0] || !strcmp(TLS_VERIFY_NONE, tls_verify_method)) {
1302 warn("Certificate verication disabled or no peer name was specified");
1306 /* This is the peer certificate */
1307 X509_NAME_oneline(X509_get_subject_name(peer_cert),
1310 X509_NAME_get_text_by_NID(X509_get_subject_name(peer_cert),
1311 NID_commonName, cn_str, 256);
1313 /* Verify based on subject name */
1315 if (!strcmp(TLS_VERIFY_SUBJECT, tls_verify_method)) {
1319 /* Verify based on common name (default) */
1320 if (strlen(tls_verify_method) == 0 ||
1321 !strcmp(TLS_VERIFY_NAME, tls_verify_method)) {
1325 /* Match the suffix of common name */
1326 if (!strcmp(TLS_VERIFY_SUFFIX, tls_verify_method)) {
1327 int len = strlen(ptr1);
1328 int off = strlen(cn_str) - len;
1331 ptr2 = cn_str + off;
1335 if (strcmp(ptr1, ptr2)) {
1336 error("Certificate verification error: CN (%s) != %s", ptr1, ptr2);
1340 info("Certificate CN: %s, peer name %s", cn_str, ets->peer);
1343 * If a peer certificate file was specified, here we check it
1345 if (ets->peercertfile[0]) {
1346 if (ssl_cmp_certs(&ets->peercertfile[0], peer_cert)
1349 ("Peer certificate doesn't match stored certificate");
1359 * Compare a certificate with the one stored in a file
1361 int ssl_cmp_certs(char *filename, X509 * a)
1366 if (!(b = get_X509_from_file(filename)))
1369 ret = X509_cmp(a, b);
1376 X509 *get_X509_from_file(char *filename)
1381 if (!(fp = fopen(filename, "r")))
1384 ret = PEM_read_X509(fp, NULL, NULL, NULL);
1392 * Every sent & received message this callback function is invoked,
1393 * so we know when alert messages have arrived or are sent and
1394 * we can print debug information about TLS handshake.
1397 ssl_msg_callback(int write_p, int version, int content_type,
1398 const void *buf, size_t len, SSL * ssl, void *arg)
1401 struct eaptls_session *ets = (struct eaptls_session *)arg;
1403 const unsigned char*msg = buf;
1404 int hvers = msg[1] << 8 | msg[2];
1407 strcpy(string, " -> ");
1409 strcpy(string, " <- ");
1411 switch(content_type) {
1413 case SSL3_RT_HEADER:
1414 strcat(string, "SSL/TLS Header: ");
1417 strcat(string, "SSL 3.0");
1420 strcat(string, "TLS 1.0");
1422 case TLS1_1_VERSION:
1423 strcat(string, "TLS 1.1");
1425 case TLS1_2_VERSION:
1426 strcat(string, "TLS 1.2");
1429 sprintf(string, "SSL/TLS Header: Unknown version (%d)", hvers);
1434 strcat(string, "Alert: ");
1438 ets->alert_sent = 1;
1439 ets->alert_sent_desc = code;
1441 ets->alert_recv = 1;
1442 ets->alert_recv_desc = code;
1445 strcat(string, SSL_alert_desc_string_long(code));
1448 case SSL3_RT_CHANGE_CIPHER_SPEC:
1449 strcat(string, "ChangeCipherSpec");
1452 #ifdef SSL3_RT_INNER_CONTENT_TYPE
1453 case SSL3_RT_INNER_CONTENT_TYPE:
1454 strcat(string, "InnerContentType (TLS1.3)");
1458 case SSL3_RT_HANDSHAKE:
1460 strcat(string, "Handshake: ");
1464 case SSL3_MT_HELLO_REQUEST:
1465 strcat(string,"Hello Request");
1467 case SSL3_MT_CLIENT_HELLO:
1468 strcat(string,"Client Hello");
1470 case SSL3_MT_SERVER_HELLO:
1471 strcat(string,"Server Hello");
1473 #ifdef SSL3_MT_NEWSESSION_TICKET
1474 case SSL3_MT_NEWSESSION_TICKET:
1475 strcat(string,"New Session Ticket");
1478 #ifdef SSL3_MT_END_OF_EARLY_DATA
1479 case SSL3_MT_END_OF_EARLY_DATA:
1480 strcat(string,"End of Early Data");
1483 #ifdef SSL3_MT_ENCRYPTED_EXTENSIONS
1484 case SSL3_MT_ENCRYPTED_EXTENSIONS:
1485 strcat(string,"Encryped Extensions");
1488 case SSL3_MT_CERTIFICATE:
1489 strcat(string,"Certificate");
1491 case SSL3_MT_SERVER_KEY_EXCHANGE:
1492 strcat(string,"Server Key Exchange");
1494 case SSL3_MT_CERTIFICATE_REQUEST:
1495 strcat(string,"Certificate Request");
1497 case SSL3_MT_SERVER_DONE:
1498 strcat(string,"Server Hello Done");
1500 case SSL3_MT_CERTIFICATE_VERIFY:
1501 strcat(string,"Certificate Verify");
1503 case SSL3_MT_CLIENT_KEY_EXCHANGE:
1504 strcat(string,"Client Key Exchange");
1506 case SSL3_MT_FINISHED:
1507 strcat(string,"Finished: ");
1508 hvers = SSL_version(ssl);
1511 strcat(string, "SSL 3.0");
1514 strcat(string, "TLS 1.0");
1516 case TLS1_1_VERSION:
1517 strcat(string, "TLS 1.1");
1519 case TLS1_2_VERSION:
1520 strcat(string, "TLS 1.2");
1522 #ifdef TLS1_3_VERSION
1523 case TLS1_3_VERSION:
1524 strcat(string, "TLS 1.3 (experimental)");
1529 strcat(string, "Unknown version");
1533 sprintf( string, "Handshake: Unknown SSL3 code received: %d", code );
1538 sprintf( string, "SSL message contains unknown content type: %d", content_type );
1541 /* Alert messages must always be displayed */
1542 if(content_type == SSL3_RT_ALERT)
1543 error("%s", string);
1545 dbglog("%s", string);
1549 ssl_new_session_cb(SSL *s, SSL_SESSION *sess)
1551 dbglog("EAP-TLS: Post-Handshake New Session Ticket arrived:");
1552 have_session_ticket = 1;
1554 /* always return success */