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

📄 tlsv1_server.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * TLSv1 server (RFC 2246) * Copyright (c) 2006-2007, 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 "sha1.h"#include "tls.h"#include "tlsv1_common.h"#include "tlsv1_record.h"#include "tlsv1_server.h"#include "tlsv1_server_i.h"/* TODO: * Support for a message fragmented across several records (RFC 2246, 6.2.1) */void tlsv1_server_alert(struct tlsv1_server *conn, u8 level, u8 description){	conn->alert_level = level;	conn->alert_description = description;}int tlsv1_server_derive_keys(struct tlsv1_server *conn,			     const u8 *pre_master_secret,			     size_t pre_master_secret_len){	u8 seed[2 * TLS_RANDOM_LEN];	u8 key_block[TLS_MAX_KEY_BLOCK_LEN];	u8 *pos;	size_t key_block_len;	if (pre_master_secret) {		wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: pre_master_secret",				pre_master_secret, pre_master_secret_len);		os_memcpy(seed, conn->client_random, TLS_RANDOM_LEN);		os_memcpy(seed + TLS_RANDOM_LEN, conn->server_random,			  TLS_RANDOM_LEN);		if (tls_prf(pre_master_secret, pre_master_secret_len,			    "master secret", seed, 2 * TLS_RANDOM_LEN,			    conn->master_secret, TLS_MASTER_SECRET_LEN)) {			wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive "				   "master_secret");			return -1;		}		wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: master_secret",				conn->master_secret, TLS_MASTER_SECRET_LEN);	}	os_memcpy(seed, conn->server_random, TLS_RANDOM_LEN);	os_memcpy(seed + TLS_RANDOM_LEN, conn->client_random, TLS_RANDOM_LEN);	key_block_len = 2 * (conn->rl.hash_size + conn->rl.key_material_len +			     conn->rl.iv_size);	if (tls_prf(conn->master_secret, TLS_MASTER_SECRET_LEN,		    "key expansion", seed, 2 * TLS_RANDOM_LEN,		    key_block, key_block_len)) {		wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive key_block");		return -1;	}	wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: key_block",			key_block, key_block_len);	pos = key_block;	/* client_write_MAC_secret */	os_memcpy(conn->rl.read_mac_secret, pos, conn->rl.hash_size);	pos += conn->rl.hash_size;	/* server_write_MAC_secret */	os_memcpy(conn->rl.write_mac_secret, pos, conn->rl.hash_size);	pos += conn->rl.hash_size;	/* client_write_key */	os_memcpy(conn->rl.read_key, pos, conn->rl.key_material_len);	pos += conn->rl.key_material_len;	/* server_write_key */	os_memcpy(conn->rl.write_key, pos, conn->rl.key_material_len);	pos += conn->rl.key_material_len;	/* client_write_IV */	os_memcpy(conn->rl.read_iv, pos, conn->rl.iv_size);	pos += conn->rl.iv_size;	/* server_write_IV */	os_memcpy(conn->rl.write_iv, pos, conn->rl.iv_size);	pos += conn->rl.iv_size;	return 0;}/** * tlsv1_server_handshake - Process TLS handshake * @conn: TLSv1 server connection data from tlsv1_server_init() * @in_data: Input data from TLS peer * @in_len: Input data length * @out_len: Length of the output buffer. * Returns: Pointer to output data, %NULL on failure */u8 * tlsv1_server_handshake(struct tlsv1_server *conn,			    const u8 *in_data, size_t in_len,			    size_t *out_len){	const u8 *pos, *end;	u8 *msg = NULL, *in_msg, *in_pos, *in_end, alert, ct;	size_t in_msg_len;	if (in_data == NULL || in_len == 0) {		wpa_printf(MSG_DEBUG, "TLSv1: No input data to server");		return NULL;	}	pos = in_data;	end = in_data + in_len;	in_msg = os_malloc(in_len);	if (in_msg == NULL)		return NULL;	/* Each received packet may include multiple records */	while (pos < end) {		in_msg_len = in_len;		if (tlsv1_record_receive(&conn->rl, pos, end - pos,					 in_msg, &in_msg_len, &alert)) {			wpa_printf(MSG_DEBUG, "TLSv1: Processing received "				   "record failed");			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, alert);			goto failed;		}		ct = pos[0];		in_pos = in_msg;		in_end = in_msg + in_msg_len;		/* Each received record may include multiple messages of the		 * same ContentType. */		while (in_pos < in_end) {			in_msg_len = in_end - in_pos;			if (tlsv1_server_process_handshake(conn, ct, in_pos,							   &in_msg_len) < 0)				goto failed;			in_pos += in_msg_len;		}		pos += TLS_RECORD_HEADER_LEN + WPA_GET_BE16(pos + 3);	}	os_free(in_msg);	in_msg = NULL;	msg = tlsv1_server_handshake_write(conn, out_len);failed:	os_free(in_msg);	if (conn->alert_level) {		if (conn->state == FAILED) {			/* Avoid alert loops */			wpa_printf(MSG_DEBUG, "TLSv1: Drop alert loop");			os_free(msg);			return NULL;		}		conn->state = FAILED;		os_free(msg);		msg = tlsv1_server_send_alert(conn, conn->alert_level,					      conn->alert_description,					      out_len);	}	return msg;}/** * tlsv1_server_encrypt - Encrypt data into TLS tunnel * @conn: TLSv1 server connection data from tlsv1_server_init() * @in_data: Pointer to plaintext data to be encrypted * @in_len: Input buffer length * @out_data: Pointer to output buffer (encrypted TLS data) * @out_len: Maximum out_data length  * Returns: Number of bytes written to out_data, -1 on failure * * This function is used after TLS handshake has been completed successfully to * send data in the encrypted tunnel. */int tlsv1_server_encrypt(struct tlsv1_server *conn,			 const u8 *in_data, size_t in_len,			 u8 *out_data, size_t out_len){	size_t rlen;	wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: Plaintext AppData",			in_data, in_len);	os_memcpy(out_data + TLS_RECORD_HEADER_LEN, in_data, in_len);	if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_APPLICATION_DATA,			      out_data, out_len, in_len, &rlen) < 0) {		wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_INTERNAL_ERROR);		return -1;	}	return rlen;}/** * tlsv1_server_decrypt - Decrypt data from TLS tunnel * @conn: TLSv1 server connection data from tlsv1_server_init() * @in_data: Pointer to input buffer (encrypted TLS data) * @in_len: Input buffer length * @out_data: Pointer to output buffer (decrypted data from TLS tunnel) * @out_len: Maximum out_data length * Returns: Number of bytes written to out_data, -1 on failure * * This function is used after TLS handshake has been completed successfully to * receive data from the encrypted tunnel. */int tlsv1_server_decrypt(struct tlsv1_server *conn,			 const u8 *in_data, size_t in_len,			 u8 *out_data, size_t out_len){	const u8 *in_end, *pos;	int res;	u8 alert, *out_end, *out_pos;	size_t olen;	pos = in_data;	in_end = in_data + in_len;	out_pos = out_data;	out_end = out_data + out_len;	while (pos < in_end) {		if (pos[0] != TLS_CONTENT_TYPE_APPLICATION_DATA) {			wpa_printf(MSG_DEBUG, "TLSv1: Unexpected content type "				   "0x%x", pos[0]);			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,					   TLS_ALERT_UNEXPECTED_MESSAGE);			return -1;		}		olen = out_end - out_pos;		res = tlsv1_record_receive(&conn->rl, pos, in_end - pos,					   out_pos, &olen, &alert);		if (res < 0) {			wpa_printf(MSG_DEBUG, "TLSv1: Record layer processing "				   "failed");			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, alert);			return -1;		}		out_pos += olen;		if (out_pos > out_end) {			wpa_printf(MSG_DEBUG, "TLSv1: Buffer not large enough "				   "for processing the received record");			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,					   TLS_ALERT_INTERNAL_ERROR);			return -1;		}		pos += TLS_RECORD_HEADER_LEN + WPA_GET_BE16(pos + 3);	}	return out_pos - out_data;}/** * tlsv1_server_global_init - Initialize TLSv1 server * Returns: 0 on success, -1 on failure * * This function must be called before using any other TLSv1 server functions. */int tlsv1_server_global_init(void){	return crypto_global_init();}/** * tlsv1_server_global_deinit - Deinitialize TLSv1 server * * This function can be used to deinitialize the TLSv1 server that was * initialized by calling tlsv1_server_global_init(). No TLSv1 server functions * can be called after this before calling tlsv1_server_global_init() again. */void tlsv1_server_global_deinit(void){	crypto_global_deinit();

⌨️ 快捷键说明

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