📄 eapcrypt.cpp
字号:
/**************************************************************************/
/* WIRE1x Version 1.0: A client-side 802.1x implementation */
/* based on xsupplicant of Open1x for Windows XP, 2000, 98, and Me */
/* */
/* 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) 2004, WIRE Lab, National Tsing Hua Univ., Hsinchu, Taiwan*/
/* All Rights Reserved */
/**************************************************************************/
/** * 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. */#define OPENSSL_NO_KRB5#include <stdafx.h>#include <stdio.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 <winsock.h>
#include "eapcrypt.h"#include "userconf.h"#include "eaptls.h"#include "auth_tools.h"
//for EVP_md5()
#include <openssl/evp.h>
struct packet_data pkt_out;u_char *eapcrypt_session_keyblock = NULL;//----------------------------------------
extern int length;
extern u_char *pb;
extern int pk;
extern unsigned long kb;
extern long length_key;
extern X509 *x;
extern int ret1;
//----------------------------------------
void eapcrypt_debug(char *fun, u_char *buf, int size, char *comment){ int i; if (buf != NULL) { printf("\n\tPacket size is %d decimal %x hex", size, size); for (i = 0; i < size; i++) { if (i % 16 == 0) printf("\n\t"); printf("%.2x ", *(buf+i)); } } printf("\n");}int eapcrypt_state(){ int i=-1; if (ssl) i=SSL_get_state(ssl); return i;}/** * 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;
unsigned int hashed_len; const 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); if (P_seed == NULL) { printf("Error with malloc of P_seed in eapcrypt_PRF().\n"); return -1; } 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); if (P_MD5_buf == NULL) { printf("Error with malloc of P_MD5_buf in eapcrypt_PRF().\n"); return -1; } P_SHA1_buf = (u_char *)malloc(sizeof(u_char) * SHA1_iterations * SHA_DIGEST_LENGTH); if (P_SHA1_buf == NULL) { printf("Error with malloc of P_SHA1_buf in eapcrypt_PRF().\n"); return -1; } /* 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); P_seed = NULL;} if (P_MD5_buf) {free(P_MD5_buf); P_MD5_buf = NULL;} if (P_SHA1_buf) {free(P_SHA1_buf); P_SHA1_buf = NULL;} return retVal;}int eapcrypt_set_keyblock(u_char *keyblock, int blocksize){ if (eapcrypt_session_keyblock != NULL) { free(eapcrypt_session_keyblock); eapcrypt_session_keyblock = NULL; } eapcrypt_session_keyblock = (u_char *)malloc(blocksize); if (eapcrypt_session_keyblock == NULL) { printf("Error with malloc of eapcrypt_session_keyblock in eapcrypt_set_keyblock().\n"); return -1; } memcpy(eapcrypt_session_keyblock, keyblock, blocksize); return 0;}u_char *eapcrypt_gen_keyblock(u_char *inkey, uint32_t insize){ u_char seed[SSL3_RANDOM_SIZE*2]; u_char *p = seed; u_char *keyblock;
// SSL *ssl = NULL; if (!ssl) { printf("NO SSL!\n"); return NULL; } keyblock = (u_char *)malloc(EAPCRYPT_SESSION_KEY_SIZE); if (!keyblock) return NULL; 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, inkey, insize, seed, SSL3_RANDOM_SIZE * 2, keyblock, EAPCRYPT_SESSION_KEY_SIZE); return keyblock;}int eapcrypt_key_hmac(u_char *inbuf, int len, u_char *outbuf){ unsigned int outlen;
//int outlen; HMAC(EVP_md5(), eapcrypt_session_keyblock +32, 32 , inbuf, len, outbuf, & outlen); return 0;}/* This function graciously corrected by Denis Belanger <denis.belanger@colubris.com> along with the necessary set_key operations in eapol-wirelessext.c */int eapcrypt_decrypt_key(u_char *enckey, u_char *deckey, int keylen, u_char *iv, int ivlen){ u_char *wholekey; RC4_KEY key; wholekey = (u_char *)malloc(sizeof(u_char) * (ivlen + 32)); if (wholekey == NULL) { printf("Error with malloc of wholekey in eapcrypt_decrypt_key().\n"); return -1; } memcpy(wholekey, iv, ivlen); memcpy(wholekey + ivlen, eapcrypt_session_keyblock, 32); RC4_set_key(&key, ivlen + 32, wholekey); RC4(&key, keylen, enckey, deckey); if (wholekey) { free(wholekey); wholekey = NULL; } return 0; }int eapcrypt_get_peer_key(u_char *enckey, int len){ memcpy(enckey, eapcrypt_session_keyblock, len); return 0;}int eapcrypt_tls_init(){ SSL_library_init(); SSL_load_error_strings(); ctx = SSL_CTX_new(TLSv1_method()); if (ctx == NULL) { printf("(TLS) Couldn't initalize OpenSSL TLS library!\n"); return -1; } printf("(TLS) Initalized TLS Successfully!\n"); return 0;}int eapcrypt_tls_shutdown(){ printf("(TLS) Cleaning up.\n");
if (ctx) { SSL_CTX_free(ctx); // Will free ssl automatically ctx = NULL; } else if (ssl) { SSL_free(ssl);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -