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

📄 tlsv1_client_write.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
	/* 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->verify, 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;		tls_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);	/*	 * RFC 2246, 4.7:	 * In digital signing, one-way hash functions are used as input for a	 * signing algorithm. A digitally-signed element is encoded as an	 * opaque vector <0..2^16-1>, where the length is specified by the	 * signing algorithm and key.	 *	 * In RSA signing, a 36-byte structure of two hashes (one SHA and one	 * MD5) is signed (encrypted with the private key). It is encoded with	 * PKCS #1 block type 0 or type 1 as described in [PKCS1].	 */	signed_start = pos; /* length to be filled */	pos += 2;	clen = end - pos;	if (conn->cred == NULL ||	    crypto_private_key_sign_pkcs1(conn->cred->key, hash, hlen,					  pos, &clen) < 0) {		wpa_printf(MSG_DEBUG, "TLSv1: Failed to sign hash (PKCS #1)");		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,			  TLS_ALERT_INTERNAL_ERROR);		return -1;	}	WPA_PUT_BE16(signed_start, clen);	pos += clen;	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 tls_write_client_change_cipher_spec(struct tlsv1_client *conn,					       u8 **msgpos, u8 *end){	u8 *pos, *rhdr;	size_t rlen;	pos = *msgpos;	wpa_printf(MSG_DEBUG, "TLSv1: Send ChangeCipherSpec");	rhdr = pos;	pos += TLS_RECORD_HEADER_LEN;	*pos = TLS_CHANGE_CIPHER_SPEC;	if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC,			      rhdr, end - rhdr, 1, &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;	}	if (tlsv1_record_change_write_cipher(&conn->rl) < 0) {		wpa_printf(MSG_DEBUG, "TLSv1: Failed to set write cipher for "			   "record layer");		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,			  TLS_ALERT_INTERNAL_ERROR);		return -1;	}	*msgpos = rhdr + rlen;	return 0;}static int tls_write_client_finished(struct tlsv1_client *conn,				     u8 **msgpos, u8 *end){	u8 *pos, *rhdr, *hs_start, *hs_length;	size_t rlen, hlen;	u8 verify_data[TLS_VERIFY_DATA_LEN];	u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN];	pos = *msgpos;	wpa_printf(MSG_DEBUG, "TLSv1: Send Finished");	/* Encrypted Handshake Message: Finished */	hlen = MD5_MAC_LEN;	if (conn->verify.md5_client == NULL ||	    crypto_hash_finish(conn->verify.md5_client, hash, &hlen) < 0) {		tls_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;		tls_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 generate verify_data");		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,			  TLS_ALERT_INTERNAL_ERROR);		return -1;	}	wpa_hexdump_key(MSG_DEBUG, "TLSv1: verify_data (client)",			verify_data, TLS_VERIFY_DATA_LEN);	rhdr = pos;	pos += TLS_RECORD_HEADER_LEN;	/* Handshake */	hs_start = pos;	/* HandshakeType msg_type */	*pos++ = TLS_HANDSHAKE_TYPE_FINISHED;	/* uint24 length (to be filled) */	hs_length = pos;	pos += 3;	os_memcpy(pos, verify_data, TLS_VERIFY_DATA_LEN);	pos += TLS_VERIFY_DATA_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, &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;	*msgpos = pos;	return 0;}static u8 * tls_send_client_key_exchange(struct tlsv1_client *conn,					 size_t *out_len){	u8 *msg, *end, *pos;	size_t msglen;	*out_len = 0;	msglen = 1000;	if (conn->certificate_requested)		msglen += tls_client_cert_chain_der_len(conn);	msg = os_malloc(msglen);	if (msg == NULL)		return NULL;	pos = msg;	end = msg + msglen;	if (conn->certificate_requested) {		if (tls_write_client_certificate(conn, &pos, end) < 0) {			os_free(msg);			return NULL;		}	}	if (tls_write_client_key_exchange(conn, &pos, end) < 0 ||	    (conn->certificate_requested && conn->cred && conn->cred->key &&	     tls_write_client_certificate_verify(conn, &pos, end) < 0) ||	    tls_write_client_change_cipher_spec(conn, &pos, end) < 0 ||	    tls_write_client_finished(conn, &pos, end) < 0) {		os_free(msg);		return NULL;	}	*out_len = pos - msg;	conn->state = SERVER_CHANGE_CIPHER_SPEC;	return msg;}static u8 * tls_send_change_cipher_spec(struct tlsv1_client *conn,					size_t *out_len){	u8 *msg, *end, *pos;	*out_len = 0;	msg = os_malloc(1000);	if (msg == NULL)		return NULL;	pos = msg;	end = msg + 1000;	if (tls_write_client_change_cipher_spec(conn, &pos, end) < 0 ||	    tls_write_client_finished(conn, &pos, end) < 0) {		os_free(msg);		return NULL;	}	*out_len = pos - msg;	wpa_printf(MSG_DEBUG, "TLSv1: Session resumption completed "		   "successfully");	conn->state = ESTABLISHED;	return msg;}u8 * tlsv1_client_handshake_write(struct tlsv1_client *conn, size_t *out_len,				  int no_appl_data){	switch (conn->state) {	case CLIENT_KEY_EXCHANGE:		return tls_send_client_key_exchange(conn, out_len);	case CHANGE_CIPHER_SPEC:		return tls_send_change_cipher_spec(conn, out_len);	case ACK_FINISHED:		wpa_printf(MSG_DEBUG, "TLSv1: Handshake completed "			   "successfully");		conn->state = ESTABLISHED;		*out_len = 0;		if (no_appl_data) {			/* Need to return something to get final TLS ACK. */			return os_malloc(1);		}		return NULL;	default:		wpa_printf(MSG_DEBUG, "TLSv1: Unexpected state %d while "			   "generating reply", conn->state);		return NULL;	}}u8 * tlsv1_client_send_alert(struct tlsv1_client *conn, u8 level,			     u8 description, size_t *out_len){	u8 *alert, *pos, *length;	wpa_printf(MSG_DEBUG, "TLSv1: Send Alert(%d:%d)", level, description);	*out_len = 0;	alert = os_malloc(10);	if (alert == NULL)		return NULL;	pos = alert;	/* TLSPlaintext */	/* ContentType type */	*pos++ = TLS_CONTENT_TYPE_ALERT;	/* ProtocolVersion version */	WPA_PUT_BE16(pos, TLS_VERSION);	pos += 2;	/* uint16 length (to be filled) */	length = pos;	pos += 2;	/* opaque fragment[TLSPlaintext.length] */	/* Alert */	/* AlertLevel level */	*pos++ = level;	/* AlertDescription description */	*pos++ = description;	WPA_PUT_BE16(length, pos - length - 2);	*out_len = pos - alert;	return alert;}

⌨️ 快捷键说明

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