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

📄 tlsv1_client_write.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * TLSv1 client - write 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 size_t tls_client_cert_chain_der_len(struct tlsv1_client *conn){	size_t len = 0;	struct x509_certificate *cert;	if (conn->cred == NULL)		return 0;	cert = conn->cred->cert;	while (cert) {		len += 3 + cert->cert_len;		if (x509_certificate_self_signed(cert))			break;		cert = x509_certificate_get_subject(conn->cred->trusted_certs,						    &cert->issuer);	}	return len;}u8 * tls_send_client_hello(struct tlsv1_client *conn, size_t *out_len){	u8 *hello, *end, *pos, *hs_length, *hs_start, *rhdr;	struct os_time now;	size_t len, i;	wpa_printf(MSG_DEBUG, "TLSv1: Send ClientHello");	*out_len = 0;	os_get_time(&now);	WPA_PUT_BE32(conn->client_random, now.sec);	if (os_get_random(conn->client_random + 4, TLS_RANDOM_LEN - 4)) {		wpa_printf(MSG_ERROR, "TLSv1: Could not generate "			   "client_random");		return NULL;	}	wpa_hexdump(MSG_MSGDUMP, "TLSv1: client_random",		    conn->client_random, TLS_RANDOM_LEN);	len = 100 + conn->num_cipher_suites * 2 + conn->client_hello_ext_len;	hello = os_malloc(len);	if (hello == NULL)		return NULL;	end = hello + len;	rhdr = hello;	pos = rhdr + TLS_RECORD_HEADER_LEN;	/* opaque fragment[TLSPlaintext.length] */	/* Handshake */	hs_start = pos;	/* HandshakeType msg_type */	*pos++ = TLS_HANDSHAKE_TYPE_CLIENT_HELLO;	/* uint24 length (to be filled) */	hs_length = pos;	pos += 3;	/* body - ClientHello */	/* ProtocolVersion client_version */	WPA_PUT_BE16(pos, TLS_VERSION);	pos += 2;	/* Random random: uint32 gmt_unix_time, opaque random_bytes */	os_memcpy(pos, conn->client_random, TLS_RANDOM_LEN);	pos += TLS_RANDOM_LEN;	/* SessionID session_id */	*pos++ = conn->session_id_len;	os_memcpy(pos, conn->session_id, conn->session_id_len);	pos += conn->session_id_len;	/* CipherSuite cipher_suites<2..2^16-1> */	WPA_PUT_BE16(pos, 2 * conn->num_cipher_suites);	pos += 2;	for (i = 0; i < conn->num_cipher_suites; i++) {		WPA_PUT_BE16(pos, conn->cipher_suites[i]);		pos += 2;	}	/* CompressionMethod compression_methods<1..2^8-1> */	*pos++ = 1;	*pos++ = TLS_COMPRESSION_NULL;	if (conn->client_hello_ext) {		os_memcpy(pos, conn->client_hello_ext,			  conn->client_hello_ext_len);		pos += conn->client_hello_ext_len;	}	WPA_PUT_BE24(hs_length, pos - hs_length - 3);	tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start);	if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,			      rhdr, end - rhdr, pos - hs_start, out_len) < 0) {		wpa_printf(MSG_DEBUG, "TLSv1: Failed to create TLS record");		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,			  TLS_ALERT_INTERNAL_ERROR);		os_free(hello);		return NULL;	}	conn->state = SERVER_HELLO;	return hello;}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->cred ? conn->cred->cert : NULL;	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->cred->trusted_certs,						    &cert->issuer);	}	if (conn->cred == NULL || cert == conn->cred->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->verify, 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;	}	if (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)) {		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,			  TLS_ALERT_INTERNAL_ERROR);		os_free(csecret);		os_free(dh_yc);		return -1;	}	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 */	if (crypto_mod_exp(conn->dh_ys, conn->dh_ys_len,			   csecret_start, csecret_len,			   conn->dh_p, conn->dh_p_len,			   shared, &shared_len)) {		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,			  TLS_ALERT_INTERNAL_ERROR);		os_free(csecret);		os_free(shared);		return -1;	}	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;

⌨️ 快捷键说明

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