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

📄 tlsv1_server_read.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
{#ifdef EAP_FAST	const u8 *dh_yc;	u16 dh_yc_len;	u8 *shared;	size_t shared_len;	int res;	/*	 * struct {	 *   select (PublicValueEncoding) {	 *     case implicit: struct { };	 *     case explicit: opaque dh_Yc<1..2^16-1>;	 *   } dh_public;	 * } ClientDiffieHellmanPublic;	 */	wpa_hexdump(MSG_MSGDUMP, "TLSv1: ClientDiffieHellmanPublic",		    pos, end - pos);	if (end == pos) {		wpa_printf(MSG_DEBUG, "TLSv1: Implicit public value encoding "			   "not supported");		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_INTERNAL_ERROR);		return -1;	}	if (end - pos < 3) {		wpa_printf(MSG_DEBUG, "TLSv1: Invalid client public value "			   "length");		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_DECODE_ERROR);		return -1;	}	dh_yc_len = WPA_GET_BE16(pos);	dh_yc = pos + 2;	if (dh_yc + dh_yc_len > end) {		wpa_printf(MSG_DEBUG, "TLSv1: Client public value overflow "			   "(length %d)", dh_yc_len);		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_DECODE_ERROR);		return -1;	}	wpa_hexdump(MSG_DEBUG, "TLSv1: DH Yc (client's public value)",		    dh_yc, dh_yc_len);	if (conn->cred == NULL || conn->cred->dh_p == NULL ||	    conn->dh_secret == NULL) {		wpa_printf(MSG_DEBUG, "TLSv1: No DH parameters available");		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_INTERNAL_ERROR);		return -1;	}	shared_len = conn->cred->dh_p_len;	shared = os_malloc(shared_len);	if (shared == NULL) {		wpa_printf(MSG_DEBUG, "TLSv1: Could not allocate memory for "			   "DH");		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_INTERNAL_ERROR);		return -1;	}	/* shared = Yc^secret mod p */	if (crypto_mod_exp(dh_yc, dh_yc_len, conn->dh_secret,			   conn->dh_secret_len,			   conn->cred->dh_p, conn->cred->dh_p_len,			   shared, &shared_len)) {		os_free(shared);		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_INTERNAL_ERROR);		return -1;	}	wpa_hexdump_key(MSG_DEBUG, "TLSv1: Shared secret from DH key exchange",			shared, shared_len);	os_memset(conn->dh_secret, 0, conn->dh_secret_len);	os_free(conn->dh_secret);	conn->dh_secret = NULL;	res = tlsv1_server_derive_keys(conn, shared, shared_len);	/* Clear the pre-master secret since it is not needed anymore */	os_memset(shared, 0, shared_len);	os_free(shared);	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;#else /* EAP_FAST */	return -1;#endif /* EAP_FAST */}static int tls_process_client_key_exchange(struct tlsv1_server *conn, u8 ct,					   const u8 *in_data, size_t *in_len){	const u8 *pos, *end;	size_t left, len;	u8 type;	tls_key_exchange keyx;	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);		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 ClientKeyExchange "			   "(Left=%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: Mismatch in ClientKeyExchange "			   "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;	}	end = pos + len;	if (type != TLS_HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE) {		wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "			   "message %d (expected ClientKeyExchange)", type);		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_UNEXPECTED_MESSAGE);		return -1;	}	wpa_printf(MSG_DEBUG, "TLSv1: Received ClientKeyExchange");	wpa_hexdump(MSG_DEBUG, "TLSv1: ClientKeyExchange", pos, len);	suite = tls_get_cipher_suite(conn->rl.cipher_suite);	if (suite == NULL)		keyx = TLS_KEY_X_NULL;	else		keyx = suite->key_exchange;	if (keyx == TLS_KEY_X_DH_anon &&	    tls_process_client_key_exchange_dh_anon(conn, pos, end) < 0)		return -1;	if (keyx != TLS_KEY_X_DH_anon &&	    tls_process_client_key_exchange_rsa(conn, pos, end) < 0)		return -1;	*in_len = end - in_data;	conn->state = CERTIFICATE_VERIFY;	return 0;}static int tls_process_certificate_verify(struct tlsv1_server *conn, u8 ct,					  const u8 *in_data, size_t *in_len){	const u8 *pos, *end;	size_t left, len;	u8 type;	size_t hlen, buflen;	u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN], *hpos, *buf;	enum { SIGN_ALG_RSA, SIGN_ALG_DSA } alg = SIGN_ALG_RSA;	u16 slen;	if (ct == TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC) {		if (conn->verify_peer) {			wpa_printf(MSG_DEBUG, "TLSv1: Client did not include "				   "CertificateVerify");			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,					   TLS_ALERT_UNEXPECTED_MESSAGE);			return -1;		}		return tls_process_change_cipher_spec(conn, ct, in_data,						      in_len);	}	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 CertificateVerify "			   "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 CertificateVerify "			   "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;	}	end = pos + len;	if (type != TLS_HANDSHAKE_TYPE_CERTIFICATE_VERIFY) {		wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "			   "message %d (expected CertificateVerify)", type);		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_UNEXPECTED_MESSAGE);		return -1;	}	wpa_printf(MSG_DEBUG, "TLSv1: Received CertificateVerify");	/*	 * struct {	 *   Signature signature;	 * } CertificateVerify;	 */	hpos = hash;	if (alg == SIGN_ALG_RSA) {		hlen = MD5_MAC_LEN;		if (conn->verify.md5_cert == NULL ||		    crypto_hash_finish(conn->verify.md5_cert, hpos, &hlen) < 0)		{			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,					   TLS_ALERT_INTERNAL_ERROR);			conn->verify.md5_cert = NULL;			crypto_hash_finish(conn->verify.sha1_cert, NULL, NULL);			conn->verify.sha1_cert = NULL;			return -1;		}		hpos += MD5_MAC_LEN;	} else		crypto_hash_finish(conn->verify.md5_cert, NULL, NULL);	conn->verify.md5_cert = NULL;	hlen = SHA1_MAC_LEN;	if (conn->verify.sha1_cert == NULL ||	    crypto_hash_finish(conn->verify.sha1_cert, hpos, &hlen) < 0) {		conn->verify.sha1_cert = NULL;		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_INTERNAL_ERROR);		return -1;	}	conn->verify.sha1_cert = NULL;	if (alg == SIGN_ALG_RSA)		hlen += MD5_MAC_LEN;	wpa_hexdump(MSG_MSGDUMP, "TLSv1: CertificateVerify hash", hash, hlen);	if (end - pos < 2) {		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_DECODE_ERROR);		return -1;	}	slen = WPA_GET_BE16(pos);	pos += 2;	if (end - pos < slen) {		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_DECODE_ERROR);		return -1;	}	wpa_hexdump(MSG_MSGDUMP, "TLSv1: Signature", pos, end - pos);	if (conn->client_rsa_key == NULL) {		wpa_printf(MSG_DEBUG, "TLSv1: No client public key to verify "			   "signature");		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_INTERNAL_ERROR);		return -1;	}	buflen = end - pos;	buf = os_malloc(end - pos);	if (crypto_public_key_decrypt_pkcs1(conn->client_rsa_key,					    pos, end - pos, buf, &buflen) < 0)	{		wpa_printf(MSG_DEBUG, "TLSv1: Failed to decrypt signature");		os_free(buf);		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_DECRYPT_ERROR);		return -1;	}	wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: Decrypted Signature",			buf, buflen);	if (buflen != hlen || os_memcmp(buf, hash, buflen) != 0) {		wpa_printf(MSG_DEBUG, "TLSv1: Invalid Signature in "			   "CertificateVerify - did not match with calculated "			   "hash");		os_free(buf);		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_DECRYPT_ERROR);		return -1;	}	os_free(buf);	*in_len = end - in_data;	conn->state = CHANGE_CIPHER_SPEC;	return 0;}static int tls_process_change_cipher_spec(struct tlsv1_server *conn,					  u8 ct, const u8 *in_data,					  size_t *in_len){	const u8 *pos;	size_t left;	if (ct != TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC) {		wpa_printf(MSG_DEBUG, "TLSv1: Expected ChangeCipherSpec; "			   "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 < 1) {		wpa_printf(MSG_DEBUG, "TLSv1: Too short ChangeCipherSpec");		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_DECODE_ERROR);		return -1;	}	if (*pos != TLS_CHANGE_CIPHER_SPEC) {		wpa_printf(MSG_DEBUG, "TLSv1: Expected ChangeCipherSpec; "			   "received data 0x%x", *pos);		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_UNEXPECTED_MESSAGE);		return -1;	}	wpa_printf(MSG_DEBUG, "TLSv1: Received ChangeCipherSpec");	if (tlsv1_record_change_read_cipher(&conn->rl) < 0) {		wpa_printf(MSG_DEBUG, "TLSv1: Failed to change read cipher "			   "for record layer");		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_INTERNAL_ERROR);		return -1;	}	*in_len = pos + 1 - in_data;	conn->state = CLIENT_FINISHED;	return 0;}static int tls_process_client_finished(struct tlsv1_server *conn, u8 ct,				       const u8 *in_data, size_t *in_len){	const u8 *pos, *end;	size_t left, len, hlen;	u8 verify_data[TLS_VERIFY_DATA_LEN];	u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN];	if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {		wpa_printf(MSG_DEBUG, "TLSv1: Expected Finished; "			   "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 record (left=%lu) for "			   "Finished",			   (unsigned long) left);		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_DECODE_ERROR);		return -1;	}	if (pos[0] != TLS_HANDSHAKE_TYPE_FINISHED) {		wpa_printf(MSG_DEBUG, "TLSv1: Expected Finished; received "			   "type 0x%x", pos[0]);		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_UNEXPECTED_MESSAGE);		return -1;	}	len = WPA_GET_BE24(pos + 1);	pos += 4;	left -= 4;	if (len > left) {		wpa_printf(MSG_DEBUG, "TLSv1: Too short buffer for Finished "			   "(len=%lu > left=%lu)",			   (unsigned long) len, (unsigned long) left);		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_DECODE_ERROR);		return -1;	}	end = pos + len;	if (len != TLS_VERIFY_DATA_LEN) {		wpa_printf(MSG_DEBUG, "TLSv1: Unexpected verify_data length "			   "in Finished: %lu (expected %d)",			   (unsigned long) len, TLS_VERIFY_DATA_LEN);		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_DECODE_ERROR);		return -1;	}	wpa_hexdump(MSG_MSGDUMP, "TLSv1: verify_data in Finished",		    pos, TLS_VERIFY_DATA_LEN);	hlen = MD5_MAC_LEN;	if (conn->verify.md5_client == NULL ||	    crypto_hash_finish(conn->verify.md5_client, hash, &hlen) < 0) {		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_INTERNAL_ERROR);		conn->verify.md5_client = NULL;		crypto_hash_finish(conn->verify.sha1_client, NULL, NULL);		conn->verify.sha1_client = NULL;		return -1;	}	conn->verify.md5_client = NULL;	hlen = SHA1_MAC_LEN;	if (conn->verify.sha1_client == NULL ||	    crypto_hash_finish(conn->verify.sha1_client, hash + MD5_MAC_LEN,			       &hlen) < 0) {		conn->verify.sha1_client = NULL;		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_INTERNAL_ERROR);		return -1;	}	conn->verify.sha1_client = NULL;	if (tls_prf(conn->master_secret, TLS_MASTER_SECRET_LEN,		    "client finished", hash, MD5_MAC_LEN + SHA1_MAC_LEN,		    verify_data, TLS_VERIFY_DATA_LEN)) {		wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive verify_data");		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,				   TLS_ALERT_DECRYPT_ERROR);		return -1;	}	wpa_hexdump_key(MSG_DEBUG, "TLSv1: verify_data (client)",			verify_data, TLS_VERIFY_DATA_LEN);	if (os_memcmp(pos, verify_data, TLS_VERIFY_DATA_LEN) != 0) {		wpa_printf(MSG_INFO, "TLSv1: Mismatch in verify_data");		return -1;	}	wpa_printf(MSG_DEBUG, "TLSv1: Received Finished");	*in_len = end - in_data;	if (conn->use_session_ticket) {		/* Abbreviated handshake using session ticket; RFC 4507 */		wpa_printf(MSG_DEBUG, "TLSv1: Abbreviated handshake completed "			   "successfully");		conn->state = ESTABLISHED;	} else {		/* Full handshake */		conn->state = SERVER_CHANGE_CIPHER_SPEC;	}	return 0;}int tlsv1_server_process_handshake(struct tlsv1_server *conn, u8 ct,				   const u8 *buf, size_t *len){	if (ct == TLS_CONTENT_TYPE_ALERT) {		if (*len < 2) {			wpa_printf(MSG_DEBUG, "TLSv1: Alert underflow");			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,					   TLS_ALERT_DECODE_ERROR);			return -1;		}		wpa_printf(MSG_DEBUG, "TLSv1: Received alert %d:%d",			   buf[0], buf[1]);		*len = 2;		conn->state = FAILED;		return -1;	}	switch (conn->state) {	case CLIENT_HELLO:		if (tls_process_client_hello(conn, ct, buf, len))			return -1;		break;	case CLIENT_CERTIFICATE:		if (tls_process_certificate(conn, ct, buf, len))			return -1;		break;	case CLIENT_KEY_EXCHANGE:		if (tls_process_client_key_exchange(conn, ct, buf, len))			return -1;		break;	case CERTIFICATE_VERIFY:		if (tls_process_certificate_verify(conn, ct, buf, len))			return -1;		break;	case CHANGE_CIPHER_SPEC:		if (tls_process_change_cipher_spec(conn, ct, buf, len))			return -1;		break;	case CLIENT_FINISHED:		if (tls_process_client_finished(conn, ct, buf, len))			return -1;		break;	default:		wpa_printf(MSG_DEBUG, "TLSv1: Unexpected state %d "			   "while processing received message",			   conn->state);		return -1;	}	if (ct == TLS_CONTENT_TYPE_HANDSHAKE)		tls_verify_hash_add(&conn->verify, buf, *len);	return 0;}

⌨️ 快捷键说明

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