📄 eapcrypt.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. *//******************************************************************* * EAP Crypto Function Implementations * * File: eapcrypt.c * * Authors: bdpayne@cs.umd.edu, npetroni@cs.umd.edu * * $Id: eapcrypt.c,v 1.21 2003/03/13 21:43:11 chessing Exp $ * $Date: 2003/03/13 21:43:11 $ * $Log: eapcrypt.c,v $ * Revision 1.21 2003/03/13 21:43:11 chessing * Fix for wired/wireless problem that only shows up on MacOS-X (for now). Additional documentation in the 1x.conf file. * * Revision 1.20 2003/03/12 02:12:01 npetroni * made change to hopefully succeed key signature on re-auth * * Revision 1.19 2003/03/11 19:30:55 chessing * Various code cleanups * * Revision 1.18 2003/03/10 23:35:44 chessing * Patches to try to get TLS working with RADIUS servers other than FreeRADIUS. * * Revision 1.17 2003/03/10 04:49:41 npetroni * modified ssl code to read PEM or ASN1 (DER) formats for user certs and user keys * * Revision 1.16 2003/03/05 21:18:45 npetroni * migration to libdnet. Please notify developers of build problems AFTER doing a cvs update. * * Revision 1.15 2003/03/03 23:29:02 npetroni * more fixing/testing/cleaning up key stuff * * Revision 1.14 2003/03/03 03:30:44 npetroni * rekeying works. Added a lot of stuff back to eapcrypt that had been removed * fixed process_keys * * Revision 1.13 2003/03/02 21:02:49 npetroni * fixed return values for ssl functions. This could NOT have been working before! * * Revision 1.12 2003/03/02 20:13:09 npetroni * increased error checking for a number of function calls * fixed tls to set ctx = NULL after freeing it (redundant free's segfault) * * Revision 1.11 2003/02/27 22:38:48 chessing * More error checking. TLS failures are reported better now. * * Revision 1.10 2003/02/27 04:05:57 chessing * Added more error checking, fixed a few omissions that have not yet caused bugs. ;) * * Revision 1.9 2003/01/24 20:48:22 chessing * Cleaned up framing code, TLS no longer sends a malformed frame. * * Revision 1.8 2003/01/23 23:06:09 chessing * Fixed a small bug in the buffering code. * * Revision 1.7 2003/01/15 21:34:26 galimorerpg * Linux OpenSSL/TLS bug fixes. * * Revision 1.6 2003/01/14 23:52:07 chessing * More work on the TLS code. It should be mostly stable now. There is a problem if get_pass("") in eaptls_auth_challenge is called twice. * * Revision 1.5 2003/01/14 19:12:40 chessing * TLS code now uses OpenSSL! Cleaned out some of the no longer needed stuff from the TLS code. Still needs more work on error checking. * * Revision 1.4 2003/01/09 21:49:53 galimorerpg * Logging Updates. * * Revision 1.3 2003/01/09 21:36:54 galimorerpg * Logging Updates. * * Revision 1.2 2003/01/09 20:17:28 galimorerpg * Logging Updates * * Revision 1.1 2003/01/02 19:35:47 chessing * Add some files that were missed in the last import.. * * * Revision 1.2 2002/08/30 13:56:32 bdpayne * removed cvs logging information from old server (i.e., before * the transition to sourceforge.net) * * Revision 1.1.1.1 2002/08/30 13:44:50 bdpayne * initial import of xsupplicant code tree * *******************************************************************/#include <stdio.h>#include <inttypes.h>#include <string.h>#include <stdlib.h>#include <unistd.h>#include <openssl/ssl.h>#include <openssl/rand.h>#include <openssl/md5.h>#include <openssl/rc4.h>#include <openssl/hmac.h>#include <openssl/err.h>#include "eapcrypt.h"#include "eaptls.h"#include "logging.h"#include "userconf.h"SSL_CTX *ctx;SSL *ssl;BIO *ssl_in, *ssl_out;struct packet_data pkt_out;#ifndef EAPCRYPT_DEBUG#define EAPCRYPT_DEBUG 0#endif#ifndef TLS_DEBUG#define TLS_DEBUG 0#endifu_char *eapcrypt_session_keyblock = NULL;#if EAPCRYPT_DEBUGvoid eapcrypt_debug(char *fun, u_char *buf, int size, char *comment){ int i; xlogf(DEBUG_EVERYTHING, "%%%% %s %%%%: %s", fun, comment); if (buf != NULL) { xlogf(DEBUG_EVERYTHING, "\n\tPacket size is %d decimal %x hex", size, size); for (i = 0; i < size; i++) { if (i % 16 == 0) xlogf(DEBUG_EVERYTHING, "\n\t"); xlogf(DEBUG_EVERYTHING, "%.2x ", *(buf+i)); } } xlogf(DEBUG_EVERYTHING, "\n");}#endif/** * Setup all necessary variables and routines before using eapcrypt * * return -1 on fail 0 on success */int eapcrypt_init(){ static u_char eapcrypt_is_init = 0; if (eapcrypt_is_init == 1) { return 0; } eapcrypt_is_init = 1; return 0;}/* TLS PRF from rfc2246 pages 11-12 */inteapcrypt_PRF(u_char *secret, int secret_len, u_char *label, int label_len, u_char *seed, int seed_len, u_char *output, int outlen){ int retVal = 0; int L_S1, L_S2; u_char *S1, *S2; u_char *P_MD5_buf, *P_SHA1_buf; u_char *P_seed; int P_seed_len; u_char A_MD5[MD5_DIGEST_LENGTH]; u_char A_SHA1[SHA_DIGEST_LENGTH]; int MD5_iterations, SHA1_iterations; int i, hashed_len; EVP_MD *hash; HMAC_CTX ctx; /* determine the length of "half" the secret */ if (secret_len % 2 == 0) { L_S1 = secret_len / 2; } else { L_S1 = secret_len / 2 + 1; } L_S2 = L_S1; S1 = secret; /* first L_S1 bytes of secret */ S2 = secret + secret_len - L_S2; /* last L_S2 bytes of secret */ MD5_iterations = outlen / MD5_DIGEST_LENGTH; /* if there is anything left over, iterate 1 more time */ MD5_iterations = outlen % MD5_DIGEST_LENGTH == 0 ? MD5_iterations : MD5_iterations + 1; SHA1_iterations = outlen / SHA_DIGEST_LENGTH; SHA1_iterations = outlen % SHA_DIGEST_LENGTH == 0 ? SHA1_iterations : SHA1_iterations + 1; P_seed_len = label_len + seed_len; P_seed = (u_char *)malloc(sizeof(u_char) * P_seed_len); memcpy(P_seed, label, label_len); memcpy(P_seed+label_len, seed, seed_len); P_MD5_buf = (u_char *)malloc(sizeof(u_char) * MD5_iterations * MD5_DIGEST_LENGTH); P_SHA1_buf = (u_char *)malloc(sizeof(u_char) * SHA1_iterations * SHA_DIGEST_LENGTH); /* P_MD5 */ hash = EVP_md5(); /* Initialize A_MD5 */ HMAC(hash, S1, L_S1, P_seed, P_seed_len, A_MD5, &hashed_len); for (i = 0; i < MD5_iterations; i++) { HMAC_Init(&ctx, S1, L_S1, hash); HMAC_Update(&ctx, A_MD5, MD5_DIGEST_LENGTH); HMAC_Update(&ctx, P_seed, P_seed_len); HMAC_Final(&ctx, P_MD5_buf + i*(MD5_DIGEST_LENGTH), &hashed_len); HMAC_cleanup(&ctx); HMAC(hash, S1, L_S1, A_MD5, MD5_DIGEST_LENGTH, A_MD5, &hashed_len); } /* do P_SHA1 */ hash = EVP_sha1(); /* Initialize A_SHA1 */ HMAC(hash, S2, L_S2, P_seed, P_seed_len, A_SHA1, &hashed_len); for (i = 0; i < SHA1_iterations; i++) { HMAC_Init(&ctx, S2, L_S2, hash); HMAC_Update(&ctx, A_SHA1, SHA_DIGEST_LENGTH); HMAC_Update(&ctx, P_seed, P_seed_len); HMAC_Final(&ctx, P_SHA1_buf + i*(SHA_DIGEST_LENGTH), &hashed_len); HMAC_cleanup(&ctx); HMAC(hash, S2, L_S2, A_SHA1, SHA_DIGEST_LENGTH, A_SHA1, &hashed_len); } /* XOR Them for the answer */ for (i = 0; i < outlen; i++) { *(output + i) = P_MD5_buf[i] ^ P_SHA1_buf[i]; } if (P_seed) free(P_seed); if (P_MD5_buf) free(P_MD5_buf); if (P_SHA1_buf) free(P_SHA1_buf); return retVal;}int eapcrypt_build_session_keyblock(void){ u_char seed[SSL3_RANDOM_SIZE*2]; u_char *p = seed; if (!ssl) {printf("NO SSL!!\n"); return -1;} if (eapcrypt_session_keyblock != NULL) { free(eapcrypt_session_keyblock); } eapcrypt_session_keyblock = (u_char *)malloc(sizeof(u_char)* EAPCRYPT_SESSION_KEY_SIZE); if (!eapcrypt_session_keyblock) { printf("Failure to allocate for eapcrypt_session_keyblock\n"); return -1; } memcpy(p, ssl->s3->client_random, SSL3_RANDOM_SIZE); p+= SSL3_RANDOM_SIZE; memcpy(p, ssl->s3->server_random, SSL3_RANDOM_SIZE); eapcrypt_PRF(ssl->session->master_key, ssl->session->master_key_length, EAPCRYPT_SESSION_KEY_CONST, EAPCRYPT_SESSION_KEY_CONST_SIZE, seed, SSL3_RANDOM_SIZE * 2, eapcrypt_session_keyblock, EAPCRYPT_SESSION_KEY_SIZE); return 0;}int eapcrypt_key_hmac(u_char *inbuf, int len, u_char *outbuf){ int outlen;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -