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

📄 tlsv1_client_read.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * TLSv1 client - 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_client.h"#include "tlsv1_client_i.h"static int tls_process_server_key_exchange(struct tlsv1_client *conn, u8 ct,					   const u8 *in_data, size_t *in_len);static int tls_process_certificate_request(struct tlsv1_client *conn, u8 ct,					   const u8 *in_data, size_t *in_len);static int tls_process_server_hello_done(struct tlsv1_client *conn, u8 ct,					 const u8 *in_data, size_t *in_len);static int tls_process_server_hello(struct tlsv1_client *conn, u8 ct,				    const u8 *in_data, size_t *in_len){	const u8 *pos, *end;	size_t left, len, i;	u16 cipher_suite;	if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {		wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "			   "received content type 0x%x", ct);		tls_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_SERVER_HELLO) {		wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "			   "message %d (expected ServerHello)", *pos);		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,			  TLS_ALERT_UNEXPECTED_MESSAGE);		return -1;	}	wpa_printf(MSG_DEBUG, "TLSv1: Received ServerHello");	pos++;	/* uint24 length */	len = WPA_GET_BE24(pos);	pos += 3;	left -= 4;	if (len > left)		goto decode_error;	/* body - ServerHello */	wpa_hexdump(MSG_MSGDUMP, "TLSv1: ServerHello", pos, len);	end = pos + len;	/* ProtocolVersion server_version */	if (end - pos < 2)		goto decode_error;	if (WPA_GET_BE16(pos) != TLS_VERSION) {		wpa_printf(MSG_DEBUG, "TLSv1: Unexpected protocol version in "			   "ServerHello");		tls_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->server_random, pos, TLS_RANDOM_LEN);	pos += TLS_RANDOM_LEN;	wpa_hexdump(MSG_MSGDUMP, "TLSv1: server_random",		    conn->server_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;	if (conn->session_id_len && conn->session_id_len == *pos &&	    os_memcmp(conn->session_id, pos + 1, conn->session_id_len) == 0) {		pos += 1 + conn->session_id_len;		wpa_printf(MSG_DEBUG, "TLSv1: Resuming old session");		conn->session_resumed = 1;	} else {		conn->session_id_len = *pos;		pos++;		os_memcpy(conn->session_id, pos, conn->session_id_len);		pos += conn->session_id_len;	}	wpa_hexdump(MSG_MSGDUMP, "TLSv1: session_id",		    conn->session_id, conn->session_id_len);	/* CipherSuite cipher_suite */	if (end - pos < 2)		goto decode_error;	cipher_suite = WPA_GET_BE16(pos);	pos += 2;	for (i = 0; i < conn->num_cipher_suites; i++) {		if (cipher_suite == conn->cipher_suites[i])			break;	}	if (i == conn->num_cipher_suites) {		wpa_printf(MSG_INFO, "TLSv1: Server selected unexpected "			   "cipher suite 0x%04x", cipher_suite);		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,			  TLS_ALERT_ILLEGAL_PARAMETER);		return -1;	}	if (conn->session_resumed && cipher_suite != conn->prev_cipher_suite) {		wpa_printf(MSG_DEBUG, "TLSv1: Server selected a different "			   "cipher suite for a resumed connection (0x%04x != "			   "0x%04x)", cipher_suite, conn->prev_cipher_suite);		tls_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");		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,			  TLS_ALERT_INTERNAL_ERROR);		return -1;	}	conn->prev_cipher_suite = cipher_suite;	/* CompressionMethod compression_method */	if (end - pos < 1)		goto decode_error;	if (*pos != TLS_COMPRESSION_NULL) {		wpa_printf(MSG_INFO, "TLSv1: Server selected unexpected "			   "compression 0x%02x", *pos);		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,			  TLS_ALERT_ILLEGAL_PARAMETER);		return -1;	}	pos++;	if (end != pos) {		/* TODO: ServerHello extensions */		wpa_hexdump(MSG_DEBUG, "TLSv1: Unexpected extra data in the "			    "end of ServerHello", pos, end - pos);		goto decode_error;	}	if (conn->session_ticket_included && conn->session_ticket_cb) {		/* TODO: include SessionTicket extension if one was included in		 * ServerHello */		int res = conn->session_ticket_cb(			conn->session_ticket_cb_ctx, NULL, 0,			conn->client_random, conn->server_random,			conn->master_secret);		if (res < 0) {			wpa_printf(MSG_DEBUG, "TLSv1: SessionTicket callback "				   "indicated failure");			tls_alert(conn, TLS_ALERT_LEVEL_FATAL,				  TLS_ALERT_HANDSHAKE_FAILURE);			return -1;		}		conn->use_session_ticket = !!res;	}	if ((conn->session_resumed || conn->use_session_ticket) &&	    tls_derive_keys(conn, NULL, 0)) {		wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive keys");		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,			  TLS_ALERT_INTERNAL_ERROR);		return -1;	}	*in_len = end - in_data;	conn->state = (conn->session_resumed || conn->use_session_ticket) ?		SERVER_CHANGE_CIPHER_SPEC : SERVER_CERTIFICATE;	return 0;decode_error:	wpa_printf(MSG_DEBUG, "TLSv1: Failed to decode ServerHello");	tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);	return -1;}static int tls_process_certificate(struct tlsv1_client *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);		tls_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);		tls_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);		tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);		return -1;	}	if (type == TLS_HANDSHAKE_TYPE_SERVER_KEY_EXCHANGE)		return tls_process_server_key_exchange(conn, ct, in_data,						       in_len);	if (type == TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST)		return tls_process_certificate_request(conn, ct, in_data,						       in_len);	if (type == TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE)		return tls_process_server_hello_done(conn, ct, in_data,						     in_len);	if (type != TLS_HANDSHAKE_TYPE_CERTIFICATE) {		wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "			   "message %d (expected Certificate/"			   "ServerKeyExchange/CertificateRequest/"			   "ServerHelloDone)", type);		tls_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);		tls_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));		tls_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");			tls_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));			tls_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->server_rsa_key);			if (tls_parse_cert(pos, cert_len,					   &conn->server_rsa_key)) {				wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse "					   "the certificate");				tls_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");			tls_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 (conn->cred &&	    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;		}		tls_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 = SERVER_KEY_EXCHANGE;	return 0;}static int tlsv1_process_diffie_hellman(struct tlsv1_client *conn,					const u8 *buf, size_t len){	const u8 *pos, *end;	tlsv1_client_free_dh(conn);	pos = buf;	end = buf + len;	if (end - pos < 3)		goto fail;	conn->dh_p_len = WPA_GET_BE16(pos);	pos += 2;	if (conn->dh_p_len == 0 || end - pos < (int) conn->dh_p_len) {		wpa_printf(MSG_DEBUG, "TLSv1: Invalid dh_p length %lu",			   (unsigned long) conn->dh_p_len);		goto fail;	}	conn->dh_p = os_malloc(conn->dh_p_len);	if (conn->dh_p == NULL)		goto fail;	os_memcpy(conn->dh_p, pos, conn->dh_p_len);	pos += conn->dh_p_len;	wpa_hexdump(MSG_DEBUG, "TLSv1: DH p (prime)",		    conn->dh_p, conn->dh_p_len);	if (end - pos < 3)		goto fail;	conn->dh_g_len = WPA_GET_BE16(pos);	pos += 2;	if (conn->dh_g_len == 0 || end - pos < (int) conn->dh_g_len)		goto fail;	conn->dh_g = os_malloc(conn->dh_g_len);	if (conn->dh_g == NULL)		goto fail;	os_memcpy(conn->dh_g, pos, conn->dh_g_len);	pos += conn->dh_g_len;	wpa_hexdump(MSG_DEBUG, "TLSv1: DH g (generator)",		    conn->dh_g, conn->dh_g_len);	if (conn->dh_g_len == 1 && conn->dh_g[0] < 2)		goto fail;	if (end - pos < 3)		goto fail;	conn->dh_ys_len = WPA_GET_BE16(pos);	pos += 2;	if (conn->dh_ys_len == 0 || end - pos < (int) conn->dh_ys_len)		goto fail;	conn->dh_ys = os_malloc(conn->dh_ys_len);	if (conn->dh_ys == NULL)		goto fail;	os_memcpy(conn->dh_ys, pos, conn->dh_ys_len);	pos += conn->dh_ys_len;	wpa_hexdump(MSG_DEBUG, "TLSv1: DH Ys (server's public value)",		    conn->dh_ys, conn->dh_ys_len);	return 0;fail:	wpa_printf(MSG_DEBUG, "TLSv1: Processing DH params failed");	tlsv1_client_free_dh(conn);	return -1;}static int tls_process_server_key_exchange(struct tlsv1_client *conn, u8 ct,					   const u8 *in_data, size_t *in_len){	const u8 *pos, *end;	size_t left, len;	u8 type;	const struct tls_cipher_suite *suite;	if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {		wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "			   "received content type 0x%x", ct);		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,			  TLS_ALERT_UNEXPECTED_MESSAGE);		return -1;

⌨️ 快捷键说明

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