📄 tls_funcs.c
字号:
/** * A client-side 802.1x implementation supporting EAP/TLS * * This code is released under both the GPL version 2 and BSD licenses. * Either license may be used. The respective licenses are found below. * * Copyright (C) 2002 Bryan D. Payne & Nick L. Petroni Jr. * All Rights Reserved * * --- GPL Version 2 License --- * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * --- BSD License --- * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * Maryland at College Park and its contributors. * - Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *//******************************************************************* * EAPTLS (RFC 2716) Function implementations * * File: eaptls.c * * Authors: Chris.Hessing@utah.edu * * $Id: tls_funcs.c,v 1.30 2004/07/15 04:15:37 chessing Exp $ * $Date: 2004/07/15 04:15:37 $ * $Log: tls_funcs.c,v $ * Revision 1.30 2004/07/15 04:15:37 chessing * * True/false int values are now bit flags in a byte. PEAP now calls back in to functions from eap.c for phase 2 methods. This allows for any phase 1 EAP type to work. This resulted in some major changes the functions in eap.c, and in peap_phase2.c. PEAP has been tested using both MS-CHAPv2, and EAP-MD5 as inner types. More types need to be tested, and enabled. * * Revision 1.29 2004/06/17 22:56:59 chessing * * Fixed the problem where an attempt to execute an invalid program would result in a second instance of XSupplicant running. (Which would then cause all kinds of interesting problems. ;) Also added a bunch of additional debugging to the TLS code to try to resolve the strange stalls that sometimes happen in authentications that use TLS for phase 1. * * Revision 1.28 2004/06/15 03:22:32 chessing * * XSupplicant Release 1.0 * * *******************************************************************/#include <openssl/ssl.h>#include <openssl/err.h>#include <openssl/rand.h>#include <openssl/hmac.h>#include <netinet/in.h>#include <string.h>#include <inttypes.h>#include <unistd.h>#include "config.h"#include "profile.h"#include "eap.h"#include "tls_funcs.h"#include "tls_crypt.h"#include "xsup_debug.h"#include "xsup_err.h"char *get_cert_common_name(SSL *ssl_ctx){ char *commonName = NULL; X509 *server_cert; if (!ssl_ctx) { debug_printf(DEBUG_NORMAL, "Invalid SSL context in get_cert_common_name()!\n"); return NULL; } // Get our certificate. server_cert = SSL_get_peer_certificate(ssl_ctx); if (!server_cert) return NULL; commonName = (char *)malloc(512); if (commonName == NULL) { debug_printf(DEBUG_NORMAL, "Couldn't allocate memory to hold the common name!\n"); return NULL; } if (X509_NAME_get_text_by_NID(X509_get_subject_name(server_cert), NID_commonName, commonName, 512) < 0) { debug_printf(DEBUG_NORMAL, "Couldn't extract common name from server certificate!\n"); return NULL; } debug_printf(DEBUG_AUTHTYPES, "Extracted common name of %s\n",commonName); return commonName;}void tls_funcs_process_error(){ unsigned long err; err = ERR_get_error(); if (err != 0) { debug_printf(DEBUG_NORMAL, "OpenSSL Error -- %s\n", ERR_error_string(err, NULL)); }}static int ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx){ char buf[256]; X509 *err_cert; int err, depth; if (!ctx) { debug_printf(DEBUG_NORMAL, "Invalid context in ssl_verify_callback()!\n"); return XEMALLOC; } err_cert = X509_STORE_CTX_get_current_cert(ctx); err = X509_STORE_CTX_get_error(ctx); depth = X509_STORE_CTX_get_error_depth(ctx); X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256); debug_printf(DEBUG_AUTHTYPES, " --- SSL_verify : depth %d\n", depth); if (!preverify_ok) { debug_printf(DEBUG_AUTHTYPES, " --- SSL_verify error : num=%d:%s:depth=%d:%s\n", err, X509_verify_cert_error_string(err), depth, buf); if (err == 26) preverify_ok = 1; } return preverify_ok;}int tls_funcs_init(struct generic_eap_data *thisint){ struct tls_vars *mytls_vars; if (thisint == NULL) return XETLSINIT; if (thisint->eap_data == NULL) return XETLSINIT; mytls_vars = (struct tls_vars *)thisint->eap_data; SSL_library_init(); SSL_load_error_strings(); mytls_vars->ctx = SSL_CTX_new(TLSv1_method()); if (mytls_vars->ctx == NULL) { debug_printf(DEBUG_NORMAL, "Couldn't initialize OpenSSL TLS library!\n"); tls_funcs_process_error(); return XETLSINIT; } return XENONE;}int tls_funcs_start(struct tls_vars *mytls_vars){ SSL_SESSION *sess = NULL; unsigned long err; int counter; if (mytls_vars == NULL) { debug_printf(DEBUG_NORMAL, "In tls_funcs_start(), mytls_vars is not valid!\n"); return XETLSSTARTFAIL; } mytls_vars->resuming = 0; if (!mytls_vars->ssl) { mytls_vars->ssl = SSL_new(mytls_vars->ctx); if (!mytls_vars->ssl) { debug_printf(DEBUG_NORMAL, "Couldn't create SSL object!\n"); tls_funcs_process_error(); return XETLSSTARTFAIL; } } else { // We already established a connection, so we probably we need to // resume the session. if (mytls_vars->resume == RES_YES) { sess = SSL_get_session(mytls_vars->ssl); if (!sess) { debug_printf(DEBUG_AUTHTYPES, "Couldn't get session information! We won't try to resume this session!\n"); mytls_vars->resuming = 0; } else { debug_printf(DEBUG_AUTHTYPES, "Got session information, trying to resume session!\n"); mytls_vars->resuming = 1; } } // We don't want to send an alert to the other end.. So do a quiet // shutdown. This violates the TLS standard, but it needed to avoid // confusing the other end of the connection when we want to do a // reconnect! SSL_set_quiet_shutdown(mytls_vars->ssl, 1); // Now, close off our old session. err = 0; counter = 0; while ((err == 0) && (counter < 60)) { err = SSL_shutdown(mytls_vars->ssl); if (err == 0) { sleep(1); counter++; } } if (err < 0) { debug_printf(DEBUG_NORMAL, "Error trying to shut down SSL context data.\n"); tls_funcs_process_error(); } } mytls_vars->ssl_in = BIO_new(BIO_s_mem()); if (!mytls_vars->ssl_in) { debug_printf(DEBUG_NORMAL, "Couldn't create ssl_in!\n"); tls_funcs_process_error(); return XETLSSTARTFAIL; } mytls_vars->ssl_out = BIO_new(BIO_s_mem()); if (!mytls_vars->ssl_out) { debug_printf(DEBUG_NORMAL, "Couldn't create ssl_out!\n"); tls_funcs_process_error(); return XETLSSTARTFAIL; } SSL_set_bio(mytls_vars->ssl, mytls_vars->ssl_in, mytls_vars->ssl_out); if (sess != NULL) { // If we have session information, we need to use it to resume the // session. debug_printf(DEBUG_AUTHTYPES, "Attempting to resume session...\n"); if (SSL_set_session(mytls_vars->ssl, sess) <= 0) { debug_printf(DEBUG_NORMAL, "There was an error attempting to resume the session!\n"); tls_funcs_process_error(); } } // Set this to SSL_VERIFY_NONE if we don't want to do anything with a failed // verification. SSL_set_verify(mytls_vars->ssl, mytls_vars->verify_mode, ssl_verify_callback); return XENONE;}int tls_funcs_parse(struct generic_eap_data *thisint, u_char *indata, int insize, char *outdata, int *outsize, int chunksize){ int rc; BUF_MEM *retData; struct tls_vars *mytls_vars; char *retVal; uint64_t length; if (!thisint) { debug_printf(DEBUG_NORMAL, "Invalid interface struct passed to tls_funcs_parse()!\n"); return XEMALLOC; } if ((!outdata) || (!outsize)) { debug_printf(DEBUG_NORMAL, "Invalid return buffer in tls_funcs_parse()!\n"); return XEMALLOC; } if (insize > 1520) { debug_printf(DEBUG_NORMAL, "Packet passed in to tls_funcs_parse() is too big! Ignoring!\n"); return XEBADPACKETSIZE; } if ((chunksize == 0) || (chunksize > 1398)) { chunksize = 1398; } if (thisint->eap_data == NULL) { debug_printf(DEBUG_NORMAL, "(TLS) eap_data has been destroyed, or not allocated!\n"); return XEMALLOC; } mytls_vars = (struct tls_vars *)thisint->eap_data; if (mytls_vars->tlsoutsize==0) { if (indata != NULL) { if (BIO_reset(mytls_vars->ssl_in) < 1) { tls_funcs_process_error(); } BIO_write(mytls_vars->ssl_in, indata, insize); } if (BIO_reset(mytls_vars->ssl_out) < 0) { tls_funcs_process_error(); } if (mytls_vars->ssl == NULL) { debug_printf(DEBUG_NORMAL, "SSL context is NULL!!!!\n"); return XETLSNOCTX; } rc = SSL_connect(mytls_vars->ssl); if (rc < 0) { tls_funcs_process_error(); } BIO_get_mem_ptr(mytls_vars->ssl_out, &retData);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -