Exemplo n.º 1
0
int
ikev2_pld_attr(struct iked *env, struct ikev2_transform *xfrm,
    struct iked_message *msg, size_t offset, size_t total)
{
	struct ikev2_attribute		 attr;
	u_int				 type;
	u_int8_t			*msgbuf = ibuf_data(msg->msg_data);
	int				 ret = 0;
	size_t				 attr_length;

	if (ikev2_validate_attr(msg, offset, total, &attr))
		return (-1);

	type = betoh16(attr.attr_type) & ~IKEV2_ATTRAF_TV;

	log_debug("%s: attribute type %s length %d total %zu",
	    __func__, print_map(type, ikev2_attrtype_map),
	    betoh16(attr.attr_length), total);

	if (betoh16(attr.attr_type) & IKEV2_ATTRAF_TV) {
		/* Type-Value attribute */
		offset += sizeof(attr);
		total -= sizeof(attr);

		if (type == IKEV2_ATTRTYPE_KEY_LENGTH)
			msg->msg_attrlength = betoh16(attr.attr_length);
	} else {
		/* Type-Length-Value attribute */
		attr_length = betoh16(attr.attr_length);
		if (total < attr_length) {
			log_debug("%s: payload malformed: attribute larger "
			    "than actual payload (%zu < %zu)", __func__,
			    total, attr_length);
			return (-1);
		}
		print_hex(msgbuf, offset + sizeof(attr),
		    attr_length - sizeof(attr));
		offset += attr_length;
		total -= attr_length;
	}

	if (total > 0) {
		/* Next attribute */
		ret = ikev2_pld_attr(env, xfrm, msg, offset, total);
	}

	return (ret);
}
Exemplo n.º 2
0
int
ikev2_pld_attr(struct iked *env, struct ikev2_transform *xfrm,
    struct iked_message *msg, off_t offset, int total)
{
	struct ikev2_attribute		 attr;
	u_int				 type;
	u_int8_t			*msgbuf = ibuf_data(msg->msg_data);

	memcpy(&attr, msgbuf + offset, sizeof(attr));

	type = betoh16(attr.attr_type) & ~IKEV2_ATTRAF_TV;

	log_debug("%s: attribute type %s length %d total %d",
	    __func__, print_map(type, ikev2_attrtype_map),
	    betoh16(attr.attr_length), total);

	if (betoh16(attr.attr_type) & IKEV2_ATTRAF_TV) {
		/* Type-Value attribute */
		offset += sizeof(attr);
		total -= sizeof(attr);

		if (type == IKEV2_ATTRTYPE_KEY_LENGTH)
			msg->msg_attrlength = betoh16(attr.attr_length);
	} else {
		/* Type-Length-Value attribute */
		print_hex(msgbuf, offset + sizeof(attr),
		    betoh16(attr.attr_length) - sizeof(attr));
		offset += betoh16(attr.attr_length);
		total -= betoh16(attr.attr_length);
	}

	if (total > 0) {
		/* Next attribute */
		ikev2_pld_attr(env, xfrm, msg, offset, total);
	}

	return (0);
}
Exemplo n.º 3
0
int
ikev2_pld_xform(struct iked *env, struct ikev2_sa_proposal *sap,
    struct iked_message *msg, off_t offset)
{
	struct ikev2_transform		 xfrm;
	char				 id[BUFSIZ];
	u_int8_t			*msgbuf = ibuf_data(msg->msg_data);

	memcpy(&xfrm, msgbuf + offset, sizeof(xfrm));

	switch (xfrm.xfrm_type) {
	case IKEV2_XFORMTYPE_ENCR:
		strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
		    ikev2_xformencr_map), sizeof(id));
		break;
	case IKEV2_XFORMTYPE_PRF:
		strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
		    ikev2_xformprf_map), sizeof(id));
		break;
	case IKEV2_XFORMTYPE_INTEGR:
		strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
		    ikev2_xformauth_map), sizeof(id));
		break;
	case IKEV2_XFORMTYPE_DH:
		strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
		    ikev2_xformdh_map), sizeof(id));
		break;
	case IKEV2_XFORMTYPE_ESN:
		strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
		    ikev2_xformesn_map), sizeof(id));
		break;
	default:
		snprintf(id, sizeof(id), "<%d>", betoh16(xfrm.xfrm_id));
		break;
	}

	log_debug("%s: more %d reserved %d length %d"
	    " type %s id %s",
	    __func__, xfrm.xfrm_more, xfrm.xfrm_reserved,
	    betoh16(xfrm.xfrm_length),
	    print_map(xfrm.xfrm_type, ikev2_xformtype_map), id);

	/*
	 * Parse transform attributes, if available
	 */
	msg->msg_attrlength = 0;
	if ((u_int)betoh16(xfrm.xfrm_length) > sizeof(xfrm))
		ikev2_pld_attr(env, &xfrm, msg, offset + sizeof(xfrm),
		    betoh16(xfrm.xfrm_length) - sizeof(xfrm));

	if (ikev2_msg_frompeer(msg)) {
		if (config_add_transform(msg->msg_parent->msg_prop,
		    xfrm.xfrm_type, betoh16(xfrm.xfrm_id),
		    msg->msg_attrlength, msg->msg_attrlength) == NULL) {
			log_debug("%s: failed to add transform", __func__);
			return (-1);
		}
	}

	/* Next transform */
	offset += betoh16(xfrm.xfrm_length);
	if (xfrm.xfrm_more == IKEV2_XFORM_MORE)
		ikev2_pld_xform(env, sap, msg, offset);

	return (0);
}
Exemplo n.º 4
0
int
ikev2_pld_xform(struct iked *env, struct ikev2_sa_proposal *sap,
    struct iked_message *msg, size_t offset, size_t total)
{
	struct ikev2_transform		 xfrm;
	char				 id[BUFSIZ];
	int				 ret = 0;
	size_t				 xfrm_length;

	if (ikev2_validate_xform(msg, offset, total, &xfrm))
		return (-1);

	xfrm_length = betoh16(xfrm.xfrm_length);

	switch (xfrm.xfrm_type) {
	case IKEV2_XFORMTYPE_ENCR:
		strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
		    ikev2_xformencr_map), sizeof(id));
		break;
	case IKEV2_XFORMTYPE_PRF:
		strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
		    ikev2_xformprf_map), sizeof(id));
		break;
	case IKEV2_XFORMTYPE_INTEGR:
		strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
		    ikev2_xformauth_map), sizeof(id));
		break;
	case IKEV2_XFORMTYPE_DH:
		strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
		    ikev2_xformdh_map), sizeof(id));
		break;
	case IKEV2_XFORMTYPE_ESN:
		strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
		    ikev2_xformesn_map), sizeof(id));
		break;
	default:
		snprintf(id, sizeof(id), "<%d>", betoh16(xfrm.xfrm_id));
		break;
	}

	log_debug("%s: more %d reserved %d length %zu"
	    " type %s id %s",
	    __func__, xfrm.xfrm_more, xfrm.xfrm_reserved, xfrm_length,
	    print_map(xfrm.xfrm_type, ikev2_xformtype_map), id);

	/*
	 * Parse transform attributes, if available
	 */
	msg->msg_attrlength = 0;
	if (xfrm_length > sizeof(xfrm)) {
		if (ikev2_pld_attr(env, &xfrm, msg, offset + sizeof(xfrm),
		    xfrm_length - sizeof(xfrm)) != 0) {
			return (-1);
		}
	}

	if (ikev2_msg_frompeer(msg)) {
		if (config_add_transform(msg->msg_parent->msg_prop,
		    xfrm.xfrm_type, betoh16(xfrm.xfrm_id),
		    msg->msg_attrlength, msg->msg_attrlength) == NULL) {
			log_debug("%s: failed to add transform", __func__);
			return (-1);
		}
	}

	/* Next transform */
	offset += xfrm_length;
	total -= xfrm_length;
	if (xfrm.xfrm_more == IKEV2_XFORM_MORE)
		ret = ikev2_pld_xform(env, sap, msg, offset, total);
	else if (total != 0) {
		/* No more transforms but still some data left. */
		log_debug("%s: less data than specified, %zu bytes left",
		    __func__, total);
		ret = -1;
	}

	return (ret);
}