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

📄 tlsv1_client.c

📁 WLAN无线网络管理的最新程序
💻 C
📖 第 1 页 / 共 5 页
字号:
			   (unsigned long) len, (unsigned long) left);		tls_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);		tls_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_server == NULL ||	    crypto_hash_finish(conn->verify_md5_server, hash, &hlen) < 0) {		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,			  TLS_ALERT_INTERNAL_ERROR);		conn->verify_md5_server = NULL;		crypto_hash_finish(conn->verify_sha1_server, NULL, NULL);		conn->verify_sha1_server = NULL;		return -1;	}	conn->verify_md5_server = NULL;	hlen = SHA1_MAC_LEN;	if (conn->verify_sha1_server == NULL ||	    crypto_hash_finish(conn->verify_sha1_server, hash + MD5_MAC_LEN,			       &hlen) < 0) {		conn->verify_sha1_server = NULL;		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,			  TLS_ALERT_INTERNAL_ERROR);		return -1;	}	conn->verify_sha1_server = NULL;	if (tls_prf(conn->master_secret, TLS_MASTER_SECRET_LEN,		    "server finished", hash, MD5_MAC_LEN + SHA1_MAC_LEN,		    verify_data, TLS_VERIFY_DATA_LEN)) {		wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive verify_data");		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,			  TLS_ALERT_DECRYPT_ERROR);		return -1;	}	wpa_hexdump_key(MSG_DEBUG, "TLSv1: verify_data (server)",			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;	conn->state = (conn->session_resumed || conn->ticket) ?		CHANGE_CIPHER_SPEC : ACK_FINISHED;	return 0;}static int tls_derive_pre_master_secret(u8 *pre_master_secret){	WPA_PUT_BE16(pre_master_secret, TLS_VERSION);	if (os_get_random(pre_master_secret + 2,			  TLS_PRE_MASTER_SECRET_LEN - 2))		return -1;	return 0;}static int tls_derive_keys(struct tlsv1_client *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.write_mac_secret, pos, conn->rl.hash_size);	pos += conn->rl.hash_size;	/* server_write_MAC_secret */	os_memcpy(conn->rl.read_mac_secret, pos, conn->rl.hash_size);	pos += conn->rl.hash_size;	/* client_write_key */	os_memcpy(conn->rl.write_key, pos, conn->rl.key_material_len);	pos += conn->rl.key_material_len;	/* server_write_key */	os_memcpy(conn->rl.read_key, pos, conn->rl.key_material_len);	pos += conn->rl.key_material_len;	/* client_write_IV */	os_memcpy(conn->rl.write_iv, pos, conn->rl.iv_size);	pos += conn->rl.iv_size;	/* server_write_IV */	os_memcpy(conn->rl.read_iv, pos, conn->rl.iv_size);	pos += conn->rl.iv_size;	return 0;}static int tls_write_client_certificate(struct tlsv1_client *conn,					u8 **msgpos, u8 *end){	u8 *pos, *rhdr, *hs_start, *hs_length, *cert_start;	size_t rlen;	struct x509_certificate *cert;	pos = *msgpos;	wpa_printf(MSG_DEBUG, "TLSv1: Send Certificate");	rhdr = pos;	pos += TLS_RECORD_HEADER_LEN;	/* opaque fragment[TLSPlaintext.length] */	/* Handshake */	hs_start = pos;	/* HandshakeType msg_type */	*pos++ = TLS_HANDSHAKE_TYPE_CERTIFICATE;	/* uint24 length (to be filled) */	hs_length = pos;	pos += 3;	/* body - Certificate */	/* uint24 length (to be filled) */	cert_start = pos;	pos += 3;	cert = conn->client_cert;	while (cert) {		if (pos + 3 + cert->cert_len > end) {			wpa_printf(MSG_DEBUG, "TLSv1: Not enough buffer space "				   "for Certificate (cert_len=%lu left=%lu)",				   (unsigned long) cert->cert_len,				   (unsigned long) (end - pos));			tls_alert(conn, TLS_ALERT_LEVEL_FATAL,				  TLS_ALERT_INTERNAL_ERROR);			return -1;		}		WPA_PUT_BE24(pos, cert->cert_len);		pos += 3;		os_memcpy(pos, cert->cert_start, cert->cert_len);		pos += cert->cert_len;		if (x509_certificate_self_signed(cert))			break;		cert = x509_certificate_get_subject(conn->trusted_certs,						    &cert->issuer);	}	if (cert == conn->client_cert || cert == NULL) {		/*		 * Client was not configured with all the needed certificates		 * to form a full certificate chain. The server may fail to		 * validate the chain unless it is configured with all the		 * missing CA certificates.		 */		wpa_printf(MSG_DEBUG, "TLSv1: Full client certificate chain "			   "not configured - validation may fail");	}	WPA_PUT_BE24(cert_start, pos - cert_start - 3);	WPA_PUT_BE24(hs_length, pos - hs_length - 3);	if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,			      rhdr, end - rhdr, pos - hs_start, &rlen) < 0) {		wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record");		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,			  TLS_ALERT_INTERNAL_ERROR);		return -1;	}	pos = rhdr + rlen;	tls_verify_hash_add(conn, hs_start, pos - hs_start);	*msgpos = pos;	return 0;}static int tlsv1_key_x_anon_dh(struct tlsv1_client *conn, u8 **pos, u8 *end){#ifdef EAP_FAST	/* ClientDiffieHellmanPublic */	u8 *csecret, *csecret_start, *dh_yc, *shared;	size_t csecret_len, dh_yc_len, shared_len;	csecret_len = conn->dh_p_len;	csecret = os_malloc(csecret_len);	if (csecret == NULL) {		wpa_printf(MSG_DEBUG, "TLSv1: Failed to allocate "			   "memory for Yc (Diffie-Hellman)");		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,			  TLS_ALERT_INTERNAL_ERROR);		return -1;	}	if (os_get_random(csecret, csecret_len)) {		wpa_printf(MSG_DEBUG, "TLSv1: Failed to get random "			   "data for Diffie-Hellman");		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,			  TLS_ALERT_INTERNAL_ERROR);		os_free(csecret);		return -1;	}	if (os_memcmp(csecret, conn->dh_p, csecret_len) > 0)		csecret[0] = 0; /* make sure Yc < p */	csecret_start = csecret;	while (csecret_len > 1 && *csecret_start == 0) {		csecret_start++;		csecret_len--;	}	wpa_hexdump_key(MSG_DEBUG, "TLSv1: DH client's secret value",			csecret_start, csecret_len);	/* Yc = g^csecret mod p */	dh_yc_len = conn->dh_p_len;	dh_yc = os_malloc(dh_yc_len);	if (dh_yc == NULL) {		wpa_printf(MSG_DEBUG, "TLSv1: Failed to allocate "			   "memory for Diffie-Hellman");		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,			  TLS_ALERT_INTERNAL_ERROR);		os_free(csecret);		return -1;	}	crypto_mod_exp(conn->dh_g, conn->dh_g_len,		       csecret_start, csecret_len,		       conn->dh_p, conn->dh_p_len,		       dh_yc, &dh_yc_len);	wpa_hexdump(MSG_DEBUG, "TLSv1: DH Yc (client's public value)",		    dh_yc, dh_yc_len);	WPA_PUT_BE16(*pos, dh_yc_len);	*pos += 2;	if (*pos + dh_yc_len > end) {		wpa_printf(MSG_DEBUG, "TLSv1: Not enough room in the "			   "message buffer for Yc");		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,			  TLS_ALERT_INTERNAL_ERROR);		os_free(csecret);		os_free(dh_yc);		return -1;	}	os_memcpy(*pos, dh_yc, dh_yc_len);	*pos += dh_yc_len;	os_free(dh_yc);	shared_len = conn->dh_p_len;	shared = os_malloc(shared_len);	if (shared == NULL) {		wpa_printf(MSG_DEBUG, "TLSv1: Could not allocate memory for "			   "DH");		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,			  TLS_ALERT_INTERNAL_ERROR);		os_free(csecret);		return -1;	}	/* shared = Ys^csecret mod p */	crypto_mod_exp(conn->dh_ys, conn->dh_ys_len,		       csecret_start, csecret_len,		       conn->dh_p, conn->dh_p_len,		       shared, &shared_len);	wpa_hexdump_key(MSG_DEBUG, "TLSv1: Shared secret from DH key exchange",			shared, shared_len);	os_memset(csecret_start, 0, csecret_len);	os_free(csecret);	if (tls_derive_keys(conn, shared, shared_len)) {		wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive keys");		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,			  TLS_ALERT_INTERNAL_ERROR);		os_free(shared);		return -1;	}	os_memset(shared, 0, shared_len);	os_free(shared);	tlsv1_client_free_dh(conn);	return 0;#else /* EAP_FAST */	tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_INTERNAL_ERROR);	return -1;#endif /* EAP_FAST */}static int tlsv1_key_x_rsa(struct tlsv1_client *conn, u8 **pos, u8 *end){	u8 pre_master_secret[TLS_PRE_MASTER_SECRET_LEN];	size_t clen;	int res;	if (tls_derive_pre_master_secret(pre_master_secret) < 0 ||	    tls_derive_keys(conn, pre_master_secret,			    TLS_PRE_MASTER_SECRET_LEN)) {		wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive keys");		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,			  TLS_ALERT_INTERNAL_ERROR);		return -1;	}	/* EncryptedPreMasterSecret */	if (conn->server_rsa_key == NULL) {		wpa_printf(MSG_DEBUG, "TLSv1: No server RSA key to "			   "use for encrypting pre-master secret");		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,			  TLS_ALERT_INTERNAL_ERROR);		return -1;	}	/* RSA encrypted value is encoded with PKCS #1 v1.5 block type 2. */	*pos += 2;	clen = end - *pos;	res = crypto_public_key_encrypt_pkcs1_v15(		conn->server_rsa_key,		pre_master_secret, TLS_PRE_MASTER_SECRET_LEN,		*pos, &clen);	os_memset(pre_master_secret, 0, TLS_PRE_MASTER_SECRET_LEN);	if (res < 0) {		wpa_printf(MSG_DEBUG, "TLSv1: RSA encryption failed");		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,			  TLS_ALERT_INTERNAL_ERROR);		return -1;	}	WPA_PUT_BE16(*pos - 2, clen);	wpa_hexdump(MSG_MSGDUMP, "TLSv1: Encrypted pre_master_secret",		    *pos, clen);	*pos += clen;	return 0;}static int tls_write_client_key_exchange(struct tlsv1_client *conn,					 u8 **msgpos, u8 *end){	u8 *pos, *rhdr, *hs_start, *hs_length;	size_t rlen;	tls_key_exchange keyx;	const struct tls_cipher_suite *suite;	suite = tls_get_cipher_suite(conn->rl.cipher_suite);	if (suite == NULL)		keyx = TLS_KEY_X_NULL;	else		keyx = suite->key_exchange;	pos = *msgpos;	wpa_printf(MSG_DEBUG, "TLSv1: Send ClientKeyExchange");	rhdr = pos;	pos += TLS_RECORD_HEADER_LEN;	/* opaque fragment[TLSPlaintext.length] */	/* Handshake */	hs_start = pos;	/* HandshakeType msg_type */	*pos++ = TLS_HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE;	/* uint24 length (to be filled) */	hs_length = pos;	pos += 3;	/* body - ClientKeyExchange */	if (keyx == TLS_KEY_X_DH_anon) {		if (tlsv1_key_x_anon_dh(conn, &pos, end) < 0)			return -1;	} else {		if (tlsv1_key_x_rsa(conn, &pos, end) < 0)			return -1;	}	WPA_PUT_BE24(hs_length, pos - hs_length - 3);	if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,			      rhdr, end - rhdr, pos - hs_start, &rlen) < 0) {		wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,			  TLS_ALERT_INTERNAL_ERROR);		return -1;	}	pos = rhdr + rlen;	tls_verify_hash_add(conn, hs_start, pos - hs_start);	*msgpos = pos;	return 0;}static int tls_write_client_certificate_verify(struct tlsv1_client *conn,					       u8 **msgpos, u8 *end){	u8 *pos, *rhdr, *hs_start, *hs_length, *signed_start;	size_t rlen, hlen, clen;	u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN], *hpos;	enum { SIGN_ALG_RSA, SIGN_ALG_DSA } alg = SIGN_ALG_RSA;	pos = *msgpos;	wpa_printf(MSG_DEBUG, "TLSv1: Send CertificateVerify");	rhdr = pos;	pos += TLS_RECORD_HEADER_LEN;	/* Handshake */	hs_start = pos;	/* HandshakeType msg_type */	*pos++ = TLS_HANDSHAKE_TYPE_CERTIFICATE_VERIFY;	/* uint24 length (to be filled) */	hs_length = pos;	pos += 3;	/*	 * RFC 2246: 7.4.3 and 7.4.8:	 * Signature signature	 *	 * RSA:	 * digitally-signed struct {	 *     opaque md5_hash[16];	 *     opaque sha_hash[20];	 * };	 *	 * DSA:	 * digitally-signed struct {	 *     opaque sha_hash[20];	 * };	 *	 * The hash values are calculated over all handshake messages sent or	 * received starting at ClientHello up to, but not including, this	 * CertificateVerify message, including the type and length fields of	 * the handshake messages.	 */	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)		{			tls_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;

⌨️ 快捷键说明

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