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

📄 tlsv1_server_read.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * TLSv1 server - read handshake message * 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 "md5.h"#include "sha1.h"#include "x509v3.h"#include "tls.h"#include "tlsv1_common.h"#include "tlsv1_record.h"#include "tlsv1_server.h"#include "tlsv1_server_i.h"static int tls_process_client_key_exchange(struct tlsv1_server *conn, u8 ct,					   const u8 *in_data, size_t *in_len);static int tls_process_change_cipher_spec(struct tlsv1_server *conn,					  u8 ct, const u8 *in_data,					  size_t *in_len);static int tls_process_client_hello(struct tlsv1_server *conn, u8 ct,				    const u8 *in_data, size_t *in_len){	const u8 *pos, *end, *c;	size_t left, len, i, j;	u16 cipher_suite;	u16 num_suites;	int compr_null_found;	if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {		wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "			   "received content type 0x%x", ct);		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_UNEXPECTED_MESSAGE);		return -1;	}	pos = in_data;	left = *in_len;	if (left < 4)		goto decode_error;	/* HandshakeType msg_type */	if (*pos != TLS_HANDSHAKE_TYPE_CLIENT_HELLO) {		wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "			   "message %d (expected ClientHello)", *pos);		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_UNEXPECTED_MESSAGE);		return -1;	}	wpa_printf(MSG_DEBUG, "TLSv1: Received ClientHello");	pos++;	/* uint24 length */	len = WPA_GET_BE24(pos);	pos += 3;	left -= 4;	if (len > left)		goto decode_error;	/* body - ClientHello */	wpa_hexdump(MSG_MSGDUMP, "TLSv1: ClientHello", pos, len);	end = pos + len;	/* ProtocolVersion client_version */	if (end - pos < 2)		goto decode_error;	conn->client_version = WPA_GET_BE16(pos);	wpa_printf(MSG_DEBUG, "TLSv1: Client version %d.%d",		   conn->client_version >> 8, conn->client_version & 0xff);	if (conn->client_version < TLS_VERSION) {		wpa_printf(MSG_DEBUG, "TLSv1: Unexpected protocol version in "			   "ClientHello");		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_PROTOCOL_VERSION);		return -1;	}	pos += 2;	/* Random random */	if (end - pos < TLS_RANDOM_LEN)		goto decode_error;	os_memcpy(conn->client_random, pos, TLS_RANDOM_LEN);	pos += TLS_RANDOM_LEN;	wpa_hexdump(MSG_MSGDUMP, "TLSv1: client_random",		    conn->client_random, TLS_RANDOM_LEN);	/* SessionID session_id */	if (end - pos < 1)		goto decode_error;	if (end - pos < 1 + *pos || *pos > TLS_SESSION_ID_MAX_LEN)		goto decode_error;	wpa_hexdump(MSG_MSGDUMP, "TLSv1: client session_id", pos + 1, *pos);	pos += 1 + *pos;	/* TODO: add support for session resumption */	/* CipherSuite cipher_suites<2..2^16-1> */	if (end - pos < 2)		goto decode_error;	num_suites = WPA_GET_BE16(pos);	pos += 2;	if (end - pos < num_suites)		goto decode_error;	wpa_hexdump(MSG_MSGDUMP, "TLSv1: client cipher suites",		    pos, num_suites);	if (num_suites & 1)		goto decode_error;	num_suites /= 2;	cipher_suite = 0;	for (i = 0; !cipher_suite && i < conn->num_cipher_suites; i++) {		c = pos;		for (j = 0; j < num_suites; j++) {			u16 tmp = WPA_GET_BE16(c);			c += 2;			if (!cipher_suite && tmp == conn->cipher_suites[i]) {				cipher_suite = tmp;				break;			}		}	}	pos += num_suites * 2;	if (!cipher_suite) {		wpa_printf(MSG_INFO, "TLSv1: No supported cipher suite "			   "available");		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_ILLEGAL_PARAMETER);		return -1;	}	if (tlsv1_record_set_cipher_suite(&conn->rl, cipher_suite) < 0) {		wpa_printf(MSG_DEBUG, "TLSv1: Failed to set CipherSuite for "			   "record layer");		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_INTERNAL_ERROR);		return -1;	}	conn->cipher_suite = cipher_suite;	/* CompressionMethod compression_methods<1..2^8-1> */	if (end - pos < 1)		goto decode_error;	num_suites = *pos++;	if (end - pos < num_suites)		goto decode_error;	wpa_hexdump(MSG_MSGDUMP, "TLSv1: client compression_methods",		    pos, num_suites);	compr_null_found = 0;	for (i = 0; i < num_suites; i++) {		if (*pos++ == TLS_COMPRESSION_NULL)			compr_null_found = 1;	}	if (!compr_null_found) {		wpa_printf(MSG_INFO, "TLSv1: Client does not accept NULL "			   "compression");		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_ILLEGAL_PARAMETER);		return -1;	}	if (end - pos == 1) {		wpa_printf(MSG_DEBUG, "TLSv1: Unexpected extra octet in the "			    "end of ClientHello: 0x%02x", *pos);		goto decode_error;	}	if (end - pos >= 2) {		u16 ext_len;		/* Extension client_hello_extension_list<0..2^16-1> */		ext_len = WPA_GET_BE16(pos);		pos += 2;		wpa_printf(MSG_DEBUG, "TLSv1: %u bytes of ClientHello "			   "extensions", ext_len);		if (end - pos != ext_len) {			wpa_printf(MSG_DEBUG, "TLSv1: Invalid ClientHello "				   "extension list length %u (expected %u)",				   ext_len, end - pos);			goto decode_error;		}		/*		 * struct {		 *   ExtensionType extension_type (0..65535)		 *   opaque extension_data<0..2^16-1>		 * } Extension;		 */		while (pos < end) {			u16 ext_type, ext_len;			if (end - pos < 2) {				wpa_printf(MSG_DEBUG, "TLSv1: Invalid "					   "extension_type field");				goto decode_error;			}			ext_type = WPA_GET_BE16(pos);			pos += 2;			if (end - pos < 2) {				wpa_printf(MSG_DEBUG, "TLSv1: Invalid "					   "extension_data length field");				goto decode_error;			}			ext_len = WPA_GET_BE16(pos);			pos += 2;			if (end - pos < ext_len) {				wpa_printf(MSG_DEBUG, "TLSv1: Invalid "					   "extension_data field");				goto decode_error;			}			wpa_printf(MSG_DEBUG, "TLSv1: ClientHello Extension "				   "type %u", ext_type);			wpa_hexdump(MSG_MSGDUMP, "TLSv1: ClientHello "				    "Extension data", pos, ext_len);			if (ext_type == TLS_EXT_SESSION_TICKET) {				os_free(conn->session_ticket);				conn->session_ticket = os_malloc(ext_len);				if (conn->session_ticket) {					os_memcpy(conn->session_ticket, pos,						  ext_len);					conn->session_ticket_len = ext_len;				}			}			pos += ext_len;		}	}	*in_len = end - in_data;	wpa_printf(MSG_DEBUG, "TLSv1: ClientHello OK - proceed to "		   "ServerHello");	conn->state = SERVER_HELLO;	return 0;decode_error:	wpa_printf(MSG_DEBUG, "TLSv1: Failed to decode ClientHello");	tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,			   TLS_ALERT_DECODE_ERROR);	return -1;}static int tls_process_certificate(struct tlsv1_server *conn, u8 ct,				   const u8 *in_data, size_t *in_len){	const u8 *pos, *end;	size_t left, len, list_len, cert_len, idx;	u8 type;	struct x509_certificate *chain = NULL, *last = NULL, *cert;	int reason;	if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {		wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "			   "received content type 0x%x", ct);		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_UNEXPECTED_MESSAGE);		return -1;	}	pos = in_data;	left = *in_len;	if (left < 4) {		wpa_printf(MSG_DEBUG, "TLSv1: Too short Certificate message "			   "(len=%lu)", (unsigned long) left);		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_DECODE_ERROR);		return -1;	}	type = *pos++;	len = WPA_GET_BE24(pos);	pos += 3;	left -= 4;	if (len > left) {		wpa_printf(MSG_DEBUG, "TLSv1: Unexpected Certificate message "			   "length (len=%lu != left=%lu)",			   (unsigned long) len, (unsigned long) left);		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_DECODE_ERROR);		return -1;	}	if (type == TLS_HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE) {		if (conn->verify_peer) {			wpa_printf(MSG_DEBUG, "TLSv1: Client did not include "				   "Certificate");			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,					   TLS_ALERT_UNEXPECTED_MESSAGE);			return -1;		}		return tls_process_client_key_exchange(conn, ct, in_data,						       in_len);	}	if (type != TLS_HANDSHAKE_TYPE_CERTIFICATE) {		wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "			   "message %d (expected Certificate/"			   "ClientKeyExchange)", type);		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_UNEXPECTED_MESSAGE);		return -1;	}	wpa_printf(MSG_DEBUG,		   "TLSv1: Received Certificate (certificate_list len %lu)",		   (unsigned long) len);	/*	 * opaque ASN.1Cert<2^24-1>;	 *	 * struct {	 *     ASN.1Cert certificate_list<1..2^24-1>;	 * } Certificate;	 */	end = pos + len;	if (end - pos < 3) {		wpa_printf(MSG_DEBUG, "TLSv1: Too short Certificate "			   "(left=%lu)", (unsigned long) left);		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_DECODE_ERROR);		return -1;	}	list_len = WPA_GET_BE24(pos);	pos += 3;	if ((size_t) (end - pos) != list_len) {		wpa_printf(MSG_DEBUG, "TLSv1: Unexpected certificate_list "			   "length (len=%lu left=%lu)",			   (unsigned long) list_len,			   (unsigned long) (end - pos));		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_DECODE_ERROR);		return -1;	}	idx = 0;	while (pos < end) {		if (end - pos < 3) {			wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse "				   "certificate_list");			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,					   TLS_ALERT_DECODE_ERROR);			x509_certificate_chain_free(chain);			return -1;		}		cert_len = WPA_GET_BE24(pos);		pos += 3;		if ((size_t) (end - pos) < cert_len) {			wpa_printf(MSG_DEBUG, "TLSv1: Unexpected certificate "				   "length (len=%lu left=%lu)",				   (unsigned long) cert_len,				   (unsigned long) (end - pos));			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,					   TLS_ALERT_DECODE_ERROR);			x509_certificate_chain_free(chain);			return -1;		}		wpa_printf(MSG_DEBUG, "TLSv1: Certificate %lu (len %lu)",			   (unsigned long) idx, (unsigned long) cert_len);		if (idx == 0) {			crypto_public_key_free(conn->client_rsa_key);			if (tls_parse_cert(pos, cert_len,					   &conn->client_rsa_key)) {				wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse "					   "the certificate");				tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,						   TLS_ALERT_BAD_CERTIFICATE);				x509_certificate_chain_free(chain);				return -1;			}		}		cert = x509_certificate_parse(pos, cert_len);		if (cert == NULL) {			wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse "				   "the certificate");			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,					   TLS_ALERT_BAD_CERTIFICATE);			x509_certificate_chain_free(chain);			return -1;		}		if (last == NULL)			chain = cert;		else			last->next = cert;		last = cert;		idx++;		pos += cert_len;	}	if (x509_certificate_chain_validate(conn->cred->trusted_certs, chain,					    &reason) < 0) {		int tls_reason;		wpa_printf(MSG_DEBUG, "TLSv1: Server certificate chain "			   "validation failed (reason=%d)", reason);		switch (reason) {		case X509_VALIDATE_BAD_CERTIFICATE:			tls_reason = TLS_ALERT_BAD_CERTIFICATE;			break;		case X509_VALIDATE_UNSUPPORTED_CERTIFICATE:			tls_reason = TLS_ALERT_UNSUPPORTED_CERTIFICATE;			break;		case X509_VALIDATE_CERTIFICATE_REVOKED:			tls_reason = TLS_ALERT_CERTIFICATE_REVOKED;			break;		case X509_VALIDATE_CERTIFICATE_EXPIRED:			tls_reason = TLS_ALERT_CERTIFICATE_EXPIRED;			break;		case X509_VALIDATE_CERTIFICATE_UNKNOWN:			tls_reason = TLS_ALERT_CERTIFICATE_UNKNOWN;			break;		case X509_VALIDATE_UNKNOWN_CA:			tls_reason = TLS_ALERT_UNKNOWN_CA;			break;		default:			tls_reason = TLS_ALERT_BAD_CERTIFICATE;			break;		}		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, tls_reason);		x509_certificate_chain_free(chain);		return -1;	}	x509_certificate_chain_free(chain);	*in_len = end - in_data;	conn->state = CLIENT_KEY_EXCHANGE;	return 0;}static int tls_process_client_key_exchange_rsa(	struct tlsv1_server *conn, const u8 *pos, const u8 *end){	u8 *out;	size_t outlen, outbuflen;	u16 encr_len;	int res;	int use_random = 0;	if (end - pos < 2) {		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_DECODE_ERROR);		return -1;	}	encr_len = WPA_GET_BE16(pos);	pos += 2;	outbuflen = outlen = end - pos;	out = os_malloc(outlen >= TLS_PRE_MASTER_SECRET_LEN ?			outlen : TLS_PRE_MASTER_SECRET_LEN);	if (out == NULL) {		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_INTERNAL_ERROR);		return -1;	}	/*	 * struct {	 *   ProtocolVersion client_version;	 *   opaque random[46];	 * } PreMasterSecret;	 *	 * struct {	 *   public-key-encrypted PreMasterSecret pre_master_secret;	 * } EncryptedPreMasterSecret;	 */	/*	 * Note: To avoid Bleichenbacher attack, we do not report decryption or	 * parsing errors from EncryptedPreMasterSecret processing to the	 * client. Instead, a random pre-master secret is used to force the	 * handshake to fail.	 */	if (crypto_private_key_decrypt_pkcs1_v15(conn->cred->key,						 pos, end - pos,						 out, &outlen) < 0) {		wpa_printf(MSG_DEBUG, "TLSv1: Failed to decrypt "			   "PreMasterSecret (encr_len=%d outlen=%lu)",			   end - pos, (unsigned long) outlen);		use_random = 1;	}	if (outlen != TLS_PRE_MASTER_SECRET_LEN) {		wpa_printf(MSG_DEBUG, "TLSv1: Unexpected PreMasterSecret "			   "length %lu", (unsigned long) outlen);		use_random = 1;	}	if (WPA_GET_BE16(out) != conn->client_version) {		wpa_printf(MSG_DEBUG, "TLSv1: Client version in "			   "ClientKeyExchange does not match with version in "			   "ClientHello");		use_random = 1;	}	if (use_random) {		wpa_printf(MSG_DEBUG, "TLSv1: Using random premaster secret "			   "to avoid revealing information about private key");		outlen = TLS_PRE_MASTER_SECRET_LEN;		if (os_get_random(out, outlen)) {			wpa_printf(MSG_DEBUG, "TLSv1: Failed to get random "				   "data");			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,					   TLS_ALERT_INTERNAL_ERROR);			os_free(out);			return -1;		}	}	res = tlsv1_server_derive_keys(conn, out, outlen);	/* Clear the pre-master secret since it is not needed anymore */	os_memset(out, 0, outbuflen);	os_free(out);	if (res) {		wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive keys");		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_INTERNAL_ERROR);		return -1;	}	return 0;}static int tls_process_client_key_exchange_dh_anon(	struct tlsv1_server *conn, const u8 *pos, const u8 *end)

⌨️ 快捷键说明

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