Beispiel #1
0
int
ikev2_pld_sa(struct iked *env, struct ikev2_payload *pld,
    struct iked_message *msg, off_t offset)
{
	struct ikev2_sa_proposal	 sap;
	struct iked_proposal		*prop = NULL;
	u_int32_t			 spi32;
	u_int64_t			 spi = 0, spi64;
	u_int8_t			*msgbuf = ibuf_data(msg->msg_data);
	struct iked_proposals		*props;

	props = &msg->msg_parent->msg_proposals;

	memcpy(&sap, msgbuf + offset, sizeof(sap));
	offset += sizeof(sap);

	if (sap.sap_spisize) {
		switch (sap.sap_spisize) {
		case 4:
			memcpy(&spi32, msgbuf + offset, 4);
			spi = betoh32(spi32);
			break;
		case 8:
			memcpy(&spi64, msgbuf + offset, 8);
			spi = betoh64(spi64);
			break;
		default:
			log_debug("%s: unsupported SPI size %d",
			    __func__, sap.sap_spisize);
			return (-1);
		}

		offset += sap.sap_spisize;
	}

	log_debug("%s: more %d reserved %d length %d"
	    " proposal #%d protoid %s spisize %d xforms %d spi %s",
	    __func__, sap.sap_more, sap.sap_reserved,
	    betoh16(sap.sap_length), sap.sap_proposalnr,
	    print_map(sap.sap_protoid, ikev2_saproto_map), sap.sap_spisize,
	    sap.sap_transforms, print_spi(spi, sap.sap_spisize));

	if (ikev2_msg_frompeer(msg)) {
		if ((msg->msg_parent->msg_prop = config_add_proposal(props,
		    sap.sap_proposalnr, sap.sap_protoid)) == NULL) {
			log_debug("%s: invalid proposal", __func__);
			return (-1);
		}
		prop = msg->msg_parent->msg_prop;
		prop->prop_peerspi.spi = spi;
		prop->prop_peerspi.spi_protoid = sap.sap_protoid;
		prop->prop_peerspi.spi_size = sap.sap_spisize;

		prop->prop_localspi.spi_protoid = sap.sap_protoid;
		prop->prop_localspi.spi_size = sap.sap_spisize;
	}

	/*
	 * Parse the attached transforms
	 */
	if (sap.sap_transforms &&
	    ikev2_pld_xform(env, &sap, msg, offset) != 0) {
		log_debug("%s: invalid proposal transforms", __func__);
		return (-1);
	}

	return (0);
}
/*
 * NB: This function parses both the SA header and the first proposal.
 * Additional proposals are ignored.
 */
int
ikev2_pld_sa(struct iked *env, struct ikev2_payload *pld,
    struct iked_message *msg, size_t offset, size_t left)
{
	struct ikev2_sa_proposal	 sap;
	struct iked_proposal		*prop = NULL;
	u_int32_t			 spi32;
	u_int64_t			 spi = 0, spi64;
	u_int8_t			*msgbuf = ibuf_data(msg->msg_data);
	struct iked_proposals		*props;
	size_t				 total;

	if (ikev2_validate_sa(msg, offset, left, pld, &sap))
		return (-1);

	if (sap.sap_more)
		log_debug("%s: more than one proposal specified", __func__);

	/* Assumed size of the first proposals, including SPI if present. */
	total = (betoh16(sap.sap_length) - sizeof(sap));

	props = &msg->msg_parent->msg_proposals;

	offset += sizeof(sap);
	left -= sizeof(sap);

	if (sap.sap_spisize) {
		if (left < sap.sap_spisize) {
			log_debug("%s: malformed payload: SPI larger than "
			    "actual payload (%zu < %d)", __func__, left,
			    sap.sap_spisize);
			return (-1);
		}
		if (total < sap.sap_spisize) {
			log_debug("%s: malformed payload: SPI larger than "
			    "proposal (%zu < %d)", __func__, total,
			    sap.sap_spisize);
			return (-1);
		}
		if (total < sap.sap_spisize) {
			log_debug("%s: malformed payload: SPI too large "
			    "(%zu < %d)", __func__, total, sap.sap_spisize);
			return (-1);
		}
		switch (sap.sap_spisize) {
		case 4:
			memcpy(&spi32, msgbuf + offset, 4);
			spi = betoh32(spi32);
			break;
		case 8:
			memcpy(&spi64, msgbuf + offset, 8);
			spi = betoh64(spi64);
			break;
		default:
			log_debug("%s: unsupported SPI size %d",
			    __func__, sap.sap_spisize);
			return (-1);
		}

		offset += sap.sap_spisize;
		left -= sap.sap_spisize;

		/* Assumed size of the proposal, now without SPI. */
		total -= sap.sap_spisize;
	}

	/*
	 * As we verified sanity of packet headers, this check will
	 * be always false, but just to be sure we keep it.
	 */
	if (left < total) {
		log_debug("%s: payload malformed: too long for payload "
		    "(%zu < %zu)", __func__, left, total);
		return (-1);
	}

	log_debug("%s: more %d reserved %d length %d"
	    " proposal #%d protoid %s spisize %d xforms %d spi %s",
	    __func__, sap.sap_more, sap.sap_reserved,
	    betoh16(sap.sap_length), sap.sap_proposalnr,
	    print_map(sap.sap_protoid, ikev2_saproto_map), sap.sap_spisize,
	    sap.sap_transforms, print_spi(spi, sap.sap_spisize));

	if (ikev2_msg_frompeer(msg)) {
		if ((msg->msg_parent->msg_prop = config_add_proposal(props,
		    sap.sap_proposalnr, sap.sap_protoid)) == NULL) {
			log_debug("%s: invalid proposal", __func__);
			return (-1);
		}
		prop = msg->msg_parent->msg_prop;
		prop->prop_peerspi.spi = spi;
		prop->prop_peerspi.spi_protoid = sap.sap_protoid;
		prop->prop_peerspi.spi_size = sap.sap_spisize;

		prop->prop_localspi.spi_protoid = sap.sap_protoid;
		prop->prop_localspi.spi_size = sap.sap_spisize;
	}

	/*
	 * Parse the attached transforms
	 */
	if (sap.sap_transforms &&
	    ikev2_pld_xform(env, &sap, msg, offset, total) != 0) {
		log_debug("%s: invalid proposal transforms", __func__);
		return (-1);
	}

	return (0);
}