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

📄 ikev2.c

📁 IEEE802.11 a/b/g 客户端应用程序源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	hdr->next_payload = next_payload;	hdr->version = IKEV2_VERSION;	hdr->exchange_type = exchange_type;	hdr->flags = IKEV2_HDR_RESPONSE;	WPA_PUT_BE32(hdr->message_id, message_id);}static int ikev2_build_sar1(struct ikev2_responder_data *data,			    struct wpabuf *msg, u8 next_payload){	struct ikev2_payload_hdr *phdr;	size_t plen;	struct ikev2_proposal *p;	struct ikev2_transform *t;	wpa_printf(MSG_DEBUG, "IKEV2: Adding SAr1 payload");	/* SAr1 - RFC 4306, Sect. 2.7 and 3.3 */	phdr = wpabuf_put(msg, sizeof(*phdr));	phdr->next_payload = next_payload;	phdr->flags = 0;	p = wpabuf_put(msg, sizeof(*p));#ifdef CCNS_PL	/* Seems to require that the Proposal # is 1 even though RFC 4306	 * Sect 3.3.1 has following requirement "When a proposal is accepted,	 * all of the proposal numbers in the SA payload MUST be the same and	 * MUST match the number on the proposal sent that was accepted.".	 */	p->proposal_num = 1;#else /* CCNS_PL */	p->proposal_num = data->proposal.proposal_num;#endif /* CCNS_PL */	p->protocol_id = IKEV2_PROTOCOL_IKE;	p->num_transforms = 4;	t = wpabuf_put(msg, sizeof(*t));	t->type = 3;	t->transform_type = IKEV2_TRANSFORM_ENCR;	WPA_PUT_BE16(t->transform_id, data->proposal.encr);	if (data->proposal.encr == ENCR_AES_CBC) {		/* Transform Attribute: Key Len = 128 bits */#ifdef CCNS_PL		wpabuf_put_be16(msg, 0x001d); /* ?? */#else /* CCNS_PL */		wpabuf_put_be16(msg, 0x800e); /* AF=1, AttrType=14 */#endif /* CCNS_PL */		wpabuf_put_be16(msg, 128); /* 128-bit key */	}	plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) t;	WPA_PUT_BE16(t->transform_length, plen);	t = wpabuf_put(msg, sizeof(*t));	t->type = 3;	WPA_PUT_BE16(t->transform_length, sizeof(*t));	t->transform_type = IKEV2_TRANSFORM_PRF;	WPA_PUT_BE16(t->transform_id, data->proposal.prf);	t = wpabuf_put(msg, sizeof(*t));	t->type = 3;	WPA_PUT_BE16(t->transform_length, sizeof(*t));	t->transform_type = IKEV2_TRANSFORM_INTEG;	WPA_PUT_BE16(t->transform_id, data->proposal.integ);	t = wpabuf_put(msg, sizeof(*t));	WPA_PUT_BE16(t->transform_length, sizeof(*t));	t->transform_type = IKEV2_TRANSFORM_DH;	WPA_PUT_BE16(t->transform_id, data->proposal.dh);	plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) p;	WPA_PUT_BE16(p->proposal_length, plen);	plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;	WPA_PUT_BE16(phdr->payload_length, plen);	return 0;}static int ikev2_build_ker(struct ikev2_responder_data *data,			   struct wpabuf *msg, u8 next_payload){	struct ikev2_payload_hdr *phdr;	size_t plen;	struct wpabuf *pv;	wpa_printf(MSG_DEBUG, "IKEV2: Adding KEr payload");	pv = dh_init(data->dh, &data->r_dh_private);	if (pv == NULL) {		wpa_printf(MSG_DEBUG, "IKEV2: Failed to initialize DH");		return -1;	}	/* KEr - RFC 4306, Sect. 3.4 */	phdr = wpabuf_put(msg, sizeof(*phdr));	phdr->next_payload = next_payload;	phdr->flags = 0;	wpabuf_put_be16(msg, data->proposal.dh); /* DH Group # */	wpabuf_put(msg, 2); /* RESERVED */	/*	 * RFC 4306, Sect. 3.4: possible zero padding for public value to	 * match the length of the prime.	 */	wpabuf_put(msg, data->dh->prime_len - wpabuf_len(pv));	wpabuf_put_buf(msg, pv);	wpabuf_free(pv);	plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;	WPA_PUT_BE16(phdr->payload_length, plen);	return 0;}static int ikev2_build_nr(struct ikev2_responder_data *data,			  struct wpabuf *msg, u8 next_payload){	struct ikev2_payload_hdr *phdr;	size_t plen;	wpa_printf(MSG_DEBUG, "IKEV2: Adding Nr payload");	/* Nr - RFC 4306, Sect. 3.9 */	phdr = wpabuf_put(msg, sizeof(*phdr));	phdr->next_payload = next_payload;	phdr->flags = 0;	wpabuf_put_data(msg, data->r_nonce, data->r_nonce_len);	plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;	WPA_PUT_BE16(phdr->payload_length, plen);	return 0;}static int ikev2_build_idr(struct ikev2_responder_data *data,			   struct wpabuf *msg, u8 next_payload){	struct ikev2_payload_hdr *phdr;	size_t plen;	wpa_printf(MSG_DEBUG, "IKEV2: Adding IDr payload");	if (data->IDr == NULL) {		wpa_printf(MSG_INFO, "IKEV2: No IDr available");		return -1;	}	/* IDr - RFC 4306, Sect. 3.5 */	phdr = wpabuf_put(msg, sizeof(*phdr));	phdr->next_payload = next_payload;	phdr->flags = 0;	wpabuf_put_u8(msg, ID_KEY_ID);	wpabuf_put(msg, 3); /* RESERVED */	wpabuf_put_data(msg, data->IDr, data->IDr_len);	plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;	WPA_PUT_BE16(phdr->payload_length, plen);	return 0;}static int ikev2_build_auth(struct ikev2_responder_data *data,			    struct wpabuf *msg, u8 next_payload){	struct ikev2_payload_hdr *phdr;	size_t plen;	const struct ikev2_prf_alg *prf;	wpa_printf(MSG_DEBUG, "IKEV2: Adding AUTH payload");	prf = ikev2_get_prf(data->proposal.prf);	if (prf == NULL)		return -1;	/* Authentication - RFC 4306, Sect. 3.8 */	phdr = wpabuf_put(msg, sizeof(*phdr));	phdr->next_payload = next_payload;	phdr->flags = 0;	wpabuf_put_u8(msg, AUTH_SHARED_KEY_MIC);	wpabuf_put(msg, 3); /* RESERVED */	/* msg | Ni | prf(SK_pr,IDr') */	if (ikev2_derive_auth_data(data->proposal.prf, data->r_sign_msg,				   data->IDr, data->IDr_len, ID_KEY_ID,				   &data->keys, 0, data->shared_secret,				   data->shared_secret_len,				   data->i_nonce, data->i_nonce_len,				   data->key_pad, data->key_pad_len,				   wpabuf_put(msg, prf->hash_len)) < 0) {		wpa_printf(MSG_INFO, "IKEV2: Could not derive AUTH data");		return -1;	}	wpabuf_free(data->r_sign_msg);	data->r_sign_msg = NULL;	plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;	WPA_PUT_BE16(phdr->payload_length, plen);	return 0;}static int ikev2_build_notification(struct ikev2_responder_data *data,				    struct wpabuf *msg, u8 next_payload){	struct ikev2_payload_hdr *phdr;	size_t plen;	wpa_printf(MSG_DEBUG, "IKEV2: Adding Notification payload");	if (data->error_type == 0) {		wpa_printf(MSG_INFO, "IKEV2: No Notify Message Type "			   "available");		return -1;	}	/* Notify - RFC 4306, Sect. 3.10 */	phdr = wpabuf_put(msg, sizeof(*phdr));	phdr->next_payload = next_payload;	phdr->flags = 0;#ifdef CCNS_PL	wpabuf_put_u8(msg, 1); /* Protocol ID: IKE_SA notification */#else /* CCNS_PL */	wpabuf_put_u8(msg, 0); /* Protocol ID: no existing SA */#endif /* CCNS_PL */	wpabuf_put_u8(msg, 0); /* SPI Size */	wpabuf_put_be16(msg, data->error_type);	switch (data->error_type) {	case INVALID_KE_PAYLOAD:		if (data->proposal.dh == -1) {			wpa_printf(MSG_INFO, "IKEV2: No DH Group selected for "				   "INVALID_KE_PAYLOAD notifications");			return -1;		}		wpabuf_put_be16(msg, data->proposal.dh);		wpa_printf(MSG_DEBUG, "IKEV2: INVALID_KE_PAYLOAD - request "			   "DH Group #%d", data->proposal.dh);		break;	case AUTHENTICATION_FAILED:		/* no associated data */		break;	default:		wpa_printf(MSG_INFO, "IKEV2: Unsupported Notify Message Type "			   "%d", data->error_type);		return -1;	}	plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;	WPA_PUT_BE16(phdr->payload_length, plen);	return 0;}static struct wpabuf * ikev2_build_sa_init(struct ikev2_responder_data *data){	struct wpabuf *msg;	/* build IKE_SA_INIT: HDR, SAr1, KEr, Nr, [CERTREQ], [SK{IDr}] */	if (os_get_random(data->r_spi, IKEV2_SPI_LEN))		return NULL;	wpa_hexdump(MSG_DEBUG, "IKEV2: IKE_SA Responder's SPI",		    data->r_spi, IKEV2_SPI_LEN);	data->r_nonce_len = IKEV2_NONCE_MIN_LEN;	if (os_get_random(data->r_nonce, data->r_nonce_len))		return NULL;#ifdef CCNS_PL	/* Zeros are removed incorrectly from the beginning of the nonces in	 * key derivation; as a workaround, make sure Nr does not start with	 * zero.. */	if (data->r_nonce[0] == 0)		data->r_nonce[0] = 1;#endif /* CCNS_PL */	wpa_hexdump(MSG_DEBUG, "IKEV2: Nr", data->r_nonce, data->r_nonce_len);	msg = wpabuf_alloc(sizeof(struct ikev2_hdr) + data->IDr_len + 1500);	if (msg == NULL)		return NULL;	ikev2_build_hdr(data, msg, IKE_SA_INIT, IKEV2_PAYLOAD_SA, 0);	if (ikev2_build_sar1(data, msg, IKEV2_PAYLOAD_KEY_EXCHANGE) ||	    ikev2_build_ker(data, msg, IKEV2_PAYLOAD_NONCE) ||	    ikev2_build_nr(data, msg, data->peer_auth == PEER_AUTH_SECRET ?			   IKEV2_PAYLOAD_ENCRYPTED :			   IKEV2_PAYLOAD_NO_NEXT_PAYLOAD)) {		wpabuf_free(msg);		return NULL;	}	if (ikev2_derive_keys(data)) {		wpabuf_free(msg);		return NULL;	}	if (data->peer_auth == PEER_AUTH_CERT) {		/* TODO: CERTREQ with SHA-1 hashes of Subject Public Key Info		 * for trust agents */	}	if (data->peer_auth == PEER_AUTH_SECRET) {		struct wpabuf *plain = wpabuf_alloc(data->IDr_len + 1000);		if (plain == NULL) {			wpabuf_free(msg);			return NULL;		}		if (ikev2_build_idr(data, plain,				    IKEV2_PAYLOAD_NO_NEXT_PAYLOAD) ||		    ikev2_build_encrypted(data->proposal.encr,					  data->proposal.integ,					  &data->keys, 0, msg, plain,					  IKEV2_PAYLOAD_IDr)) {			wpabuf_free(plain);			wpabuf_free(msg);			return NULL;		}		wpabuf_free(plain);	}	ikev2_update_hdr(msg);	wpa_hexdump_buf(MSG_MSGDUMP, "IKEV2: Sending message (SA_INIT)", msg);	data->state = SA_AUTH;	wpabuf_free(data->r_sign_msg);	data->r_sign_msg = wpabuf_dup(msg);	return msg;}static struct wpabuf * ikev2_build_sa_auth(struct ikev2_responder_data *data){	struct wpabuf *msg, *plain;	/* build IKE_SA_AUTH: HDR, SK {IDr, [CERT,] AUTH} */	msg = wpabuf_alloc(sizeof(struct ikev2_hdr) + data->IDr_len + 1000);	if (msg == NULL)		return NULL;	ikev2_build_hdr(data, msg, IKE_SA_AUTH, IKEV2_PAYLOAD_ENCRYPTED, 1);	plain = wpabuf_alloc(data->IDr_len + 1000);	if (plain == NULL) {		wpabuf_free(msg);		return NULL;	}	if (ikev2_build_idr(data, plain, IKEV2_PAYLOAD_AUTHENTICATION) ||	    ikev2_build_auth(data, plain, IKEV2_PAYLOAD_NO_NEXT_PAYLOAD) ||	    ikev2_build_encrypted(data->proposal.encr, data->proposal.integ,				  &data->keys, 0, msg, plain,				  IKEV2_PAYLOAD_IDr)) {		wpabuf_free(plain);		wpabuf_free(msg);		return NULL;	}	wpabuf_free(plain);	wpa_hexdump_buf(MSG_MSGDUMP, "IKEV2: Sending message (SA_AUTH)", msg);	data->state = IKEV2_DONE;	return msg;}static struct wpabuf * ikev2_build_notify(struct ikev2_responder_data *data){	struct wpabuf *msg;	msg = wpabuf_alloc(sizeof(struct ikev2_hdr) + 1000);	if (msg == NULL)		return NULL;	if (data->last_msg == LAST_MSG_SA_AUTH) {		/* HDR, SK{N} */		struct wpabuf *plain = wpabuf_alloc(100);		if (plain == NULL) {			wpabuf_free(msg);			return NULL;		}		ikev2_build_hdr(data, msg, IKE_SA_AUTH,				IKEV2_PAYLOAD_ENCRYPTED, 1);		if (ikev2_build_notification(data, plain,					     IKEV2_PAYLOAD_NO_NEXT_PAYLOAD) ||		    ikev2_build_encrypted(data->proposal.encr,					  data->proposal.integ,					  &data->keys, 0, msg, plain,					  IKEV2_PAYLOAD_NOTIFICATION)) {			wpabuf_free(plain);			wpabuf_free(msg);			return NULL;		}		data->state = IKEV2_FAILED;	} else {		/* HDR, N */		ikev2_build_hdr(data, msg, IKE_SA_INIT,				IKEV2_PAYLOAD_NOTIFICATION, 0);		if (ikev2_build_notification(data, msg,					     IKEV2_PAYLOAD_NO_NEXT_PAYLOAD)) {			wpabuf_free(msg);			return NULL;		}		data->state = SA_INIT;	}	ikev2_update_hdr(msg);	wpa_hexdump_buf(MSG_MSGDUMP, "IKEV2: Sending message (Notification)",			msg);	return msg;}struct wpabuf * ikev2_responder_build(struct ikev2_responder_data *data){	switch (data->state) {	case SA_INIT:		return ikev2_build_sa_init(data);	case SA_AUTH:		return ikev2_build_sa_auth(data);	case CHILD_SA:		return NULL;	case NOTIFY:		return ikev2_build_notify(data);	case IKEV2_DONE:	case IKEV2_FAILED:		return NULL;	}	return NULL;}

⌨️ 快捷键说明

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