⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eap_tls_common.c

📁 WLAN无线网络管理的最新程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * EAP peer: EAP-TLS/PEAP/TTLS/FAST common functions * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Alternatively, this software may be distributed under the terms of BSD * license. * * See README and COPYING for more details. */#include "includes.h"#include "common.h"#include "eap_i.h"#include "eap_tls_common.h"#include "config_ssid.h"#include "md5.h"#include "sha1.h"#include "tls.h"#include "config.h"static int eap_tls_check_blob(struct eap_sm *sm, const char **name,			      const u8 **data, size_t *data_len){	const struct wpa_config_blob *blob;	if (*name == NULL || os_strncmp(*name, "blob://", 7) != 0)		return 0;	blob = eap_get_config_blob(sm, *name + 7);	if (blob == NULL) {		wpa_printf(MSG_ERROR, "%s: Named configuration blob '%s' not "			   "found", __func__, *name + 7);		return -1;	}	*name = NULL;	*data = blob->data;	*data_len = blob->len;	return 0;}static void eap_tls_params_from_conf1(struct tls_connection_params *params,				      struct wpa_ssid *config){	params->ca_cert = (char *) config->ca_cert;	params->ca_path = (char *) config->ca_path;	params->client_cert = (char *) config->client_cert;	params->private_key = (char *) config->private_key;	params->private_key_passwd = (char *) config->private_key_passwd;	params->dh_file = (char *) config->dh_file;	params->subject_match = (char *) config->subject_match;	params->altsubject_match = (char *) config->altsubject_match;	params->engine_id = config->engine_id;	params->pin = config->pin;	params->key_id = config->key_id;}static void eap_tls_params_from_conf2(struct tls_connection_params *params,				      struct wpa_ssid *config){	params->ca_cert = (char *) config->ca_cert2;	params->ca_path = (char *) config->ca_path2;	params->client_cert = (char *) config->client_cert2;	params->private_key = (char *) config->private_key2;	params->private_key_passwd = (char *) config->private_key2_passwd;	params->dh_file = (char *) config->dh_file2;	params->subject_match = (char *) config->subject_match2;	params->altsubject_match = (char *) config->altsubject_match2;}static int eap_tls_params_from_conf(struct eap_sm *sm,				    struct eap_ssl_data *data,				    struct tls_connection_params *params,				    struct wpa_ssid *config, int phase2){	os_memset(params, 0, sizeof(*params));	params->engine = config->engine;	if (phase2)		eap_tls_params_from_conf2(params, config);	else		eap_tls_params_from_conf1(params, config);	params->tls_ia = data->tls_ia;	if (eap_tls_check_blob(sm, &params->ca_cert, &params->ca_cert_blob,			       &params->ca_cert_blob_len) ||	    eap_tls_check_blob(sm, &params->client_cert,			       &params->client_cert_blob,			       &params->client_cert_blob_len) ||	    eap_tls_check_blob(sm, &params->private_key,			       &params->private_key_blob,			       &params->private_key_blob_len) ||	    eap_tls_check_blob(sm, &params->dh_file, &params->dh_blob,			       &params->dh_blob_len)) {		wpa_printf(MSG_INFO, "SSL: Failed to get configuration blobs");		return -1;	}	return 0;}static int eap_tls_init_connection(struct eap_sm *sm,				   struct eap_ssl_data *data,				   struct wpa_ssid *config,				   struct tls_connection_params *params){	int res;	data->conn = tls_connection_init(sm->ssl_ctx);	if (data->conn == NULL) {		wpa_printf(MSG_INFO, "SSL: Failed to initialize new TLS "			   "connection");		return -1;	}	res = tls_connection_set_params(sm->ssl_ctx, data->conn, params);	if (res == TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED) {		/* At this point with the pkcs11 engine the PIN might be wrong.		 * We reset the PIN in the configuration to be sure to not use		 * it again and the calling function must request a new one */		os_free(config->pin);		config->pin = NULL;	} else if (res == TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED) {		wpa_printf(MSG_INFO, "TLS: Failed to load private key");		/* We don't know exactly but maybe the PIN was wrong,		 * so ask for a new one. */		os_free(config->pin);		config->pin = NULL;		eap_sm_request_pin(sm);		sm->ignore = TRUE;		return -1;	} else if (res) {		wpa_printf(MSG_INFO, "TLS: Failed to set TLS connection "			   "parameters");		return -1;	}	return 0;}/** * eap_tls_ssl_init - Initialize shared TLS functionality * @sm: Pointer to EAP state machine allocated with eap_sm_init() * @data: Data for TLS processing * @config: Pointer to the network configuration * Returns: 0 on success, -1 on failure * * This function is used to initialize shared TLS functionality for EAP-TLS, * EAP-PEAP, EAP-TTLS, and EAP-FAST. */int eap_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data,		     struct wpa_ssid *config){	int ret = -1;	struct tls_connection_params params;	if (config == NULL)		return -1;	data->eap = sm;	data->phase2 = sm->init_phase2;	if (eap_tls_params_from_conf(sm, data, &params, config, data->phase2) <	    0)		goto done;	if (eap_tls_init_connection(sm, data, config, &params) < 0)		goto done;	data->tls_out_limit = config->fragment_size;	if (data->phase2) {		/* Limit the fragment size in the inner TLS authentication		 * since the outer authentication with EAP-PEAP does not yet		 * support fragmentation */		if (data->tls_out_limit > 100)			data->tls_out_limit -= 100;	}	if (config->phase1 &&	    os_strstr(config->phase1, "include_tls_length=1")) {		wpa_printf(MSG_DEBUG, "TLS: Include TLS Message Length in "			   "unfragmented packets");		data->include_tls_length = 1;	}	ret = 0;done:	return ret;}/** * eap_tls_ssl_deinit - Deinitialize shared TLS functionality * @sm: Pointer to EAP state machine allocated with eap_sm_init() * @data: Data for TLS processing * * This function deinitializes shared TLS functionality that was initialized * with eap_tls_ssl_init(). */void eap_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data){	tls_connection_deinit(sm->ssl_ctx, data->conn);	os_free(data->tls_in);	os_free(data->tls_out);}/** * eap_tls_derive_key - Derive a key based on TLS session data * @sm: Pointer to EAP state machine allocated with eap_sm_init() * @data: Data for TLS processing * @label: Label string for deriving the keys, e.g., "client EAP encryption" * @len: Length of the key material to generate (usually 64 for MSK) * Returns: Pointer to allocated key on success or %NULL on failure * * This function uses TLS-PRF to generate pseudo-random data based on the TLS * session data (client/server random and master key). Each key type may use a * different label to bind the key usage into the generated material. * * The caller is responsible for freeing the returned buffer. */u8 * eap_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data,			const char *label, size_t len){	struct tls_keys keys;	u8 *rnd = NULL, *out;	out = os_malloc(len);	if (out == NULL)		return NULL;	/* First, try to use TLS library function for PRF, if available. */	if (tls_connection_prf(sm->ssl_ctx, data->conn, label, 0, out, len) ==	    0)		return out;	/*	 * TLS library did not support key generation, so get the needed TLS	 * session parameters and use an internal implementation of TLS PRF to	 * derive the key.	 */	if (tls_connection_get_keys(sm->ssl_ctx, data->conn, &keys))		goto fail;	if (keys.client_random == NULL || keys.server_random == NULL ||	    keys.master_key == NULL)		goto fail;	rnd = os_malloc(keys.client_random_len + keys.server_random_len);	if (rnd == NULL)		goto fail;	os_memcpy(rnd, keys.client_random, keys.client_random_len);	os_memcpy(rnd + keys.client_random_len, keys.server_random,		  keys.server_random_len);	if (tls_prf(keys.master_key, keys.master_key_len,		    label, rnd, keys.client_random_len +		    keys.server_random_len, out, len))		goto fail;	os_free(rnd);	return out;fail:	os_free(out);	os_free(rnd);	return NULL;}/** * eap_tls_data_reassemble - Reassemble TLS data * @sm: Pointer to EAP state machine allocated with eap_sm_init() * @data: Data for TLS processing * @in_data: Next incoming TLS segment * @in_len: Length of in_data * @out_len: Variable for returning output data length * @need_more_input: Variable for returning whether more input data is needed * to reassemble this TLS packet * Returns: Pointer to output data, %NULL on error or when more data is needed * for the full message (in which case, *need_more_input is also set to 1). * * This function reassembles TLS fragments. Caller must not free the returned * data buffer since an internal pointer to it is maintained. */const u8 * eap_tls_data_reassemble(	struct eap_sm *sm, struct eap_ssl_data *data, const u8 *in_data,	size_t in_len, size_t *out_len, int *need_more_input){	u8 *buf;	*need_more_input = 0;	if (data->tls_in_left > in_len || data->tls_in) {		if (data->tls_in_len + in_len == 0) {			os_free(data->tls_in);			data->tls_in = NULL;			data->tls_in_len = 0;			wpa_printf(MSG_WARNING, "SSL: Invalid reassembly "				   "state: tls_in_left=%lu tls_in_len=%lu "				   "in_len=%lu",				   (unsigned long) data->tls_in_left,				   (unsigned long) data->tls_in_len,				   (unsigned long) in_len);			return NULL;		}		if (data->tls_in_len + in_len > 65536) {			/* Limit length to avoid rogue servers from causing			 * large memory allocations. */			os_free(data->tls_in);			data->tls_in = NULL;			data->tls_in_len = 0;			wpa_printf(MSG_INFO, "SSL: Too long TLS fragment (size"				   " over 64 kB)");			return NULL;		}		buf = os_realloc(data->tls_in, data->tls_in_len + in_len);		if (buf == NULL) {			os_free(data->tls_in);			data->tls_in = NULL;			data->tls_in_len = 0;			wpa_printf(MSG_INFO, "SSL: Could not allocate memory "				   "for TLS data");			return NULL;		}		os_memcpy(buf + data->tls_in_len, in_data, in_len);		data->tls_in = buf;		data->tls_in_len += in_len;		if (in_len > data->tls_in_left) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -