-/* $OpenBSD: ikev2.c,v 1.159 2017/11/30 12:18:44 patrick Exp $ */
+/* $OpenBSD: ikev2.c,v 1.160 2017/12/01 19:49:31 patrick Exp $ */
/*
* Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
struct iked_transform **, struct iked_transform **, int *);
ssize_t ikev2_add_proposals(struct iked *, struct iked_sa *, struct ibuf *,
- struct iked_proposals *, uint8_t, int, int);
+ struct iked_proposals *, uint8_t, int, int, int);
ssize_t ikev2_add_cp(struct iked *, struct iked_sa *, struct ibuf *);
ssize_t ikev2_add_transform(struct ibuf *,
uint8_t, uint8_t, uint16_t, uint16_t);
if ((pld = ikev2_add_payload(buf)) == NULL)
goto done;
if ((len = ikev2_add_proposals(env, sa, buf, &pol->pol_proposals,
- IKEV2_SAPROTO_IKE, sa->sa_hdr.sh_initiator, 0)) == -1)
+ IKEV2_SAPROTO_IKE, sa->sa_hdr.sh_initiator, 0, 0)) == -1)
goto done;
if (ikev2_next_payload(pld, len, IKEV2_PAYLOAD_KE) == -1)
if ((pld = ikev2_add_payload(e)) == NULL)
goto done;
if ((len = ikev2_add_proposals(env, sa, e, &pol->pol_proposals, 0,
- sa->sa_hdr.sh_initiator, 0)) == -1)
+ sa->sa_hdr.sh_initiator, 0, 1)) == -1)
goto done;
if ((len = ikev2_add_ts(e, &pld, len, sa, 0)) == -1)
ssize_t
ikev2_add_proposals(struct iked *env, struct iked_sa *sa, struct ibuf *buf,
struct iked_proposals *proposals, uint8_t protoid, int initiator,
- int sendikespi)
+ int sendikespi, int skipdh)
{
struct ikev2_sa_proposal *sap;
struct iked_transform *xform;
ssize_t length = 0, saplength, xflen;
uint64_t spi64;
uint32_t spi32, spi;
- unsigned int i;
+ unsigned int i, xfi, nxforms;
TAILQ_FOREACH(prop, proposals, prop_entry) {
if ((protoid && prop->prop_protoid != protoid) ||
prop->prop_localspi.spi_protoid = IKEV2_SAPROTO_IKE;
}
+ /*
+ * RFC 7296: 1.2. The Initial Exchanges
+ * IKE_AUTH messages do not contain KE/N payloads, thus
+ * SA payloads cannot contain groups.
+ */
+ if (skipdh) {
+ nxforms = 0;
+ for (i = 0; i < prop->prop_nxforms; i++) {
+ xform = prop->prop_xforms + i;
+ if (xform->xform_type == IKEV2_XFORMTYPE_DH)
+ continue;
+ nxforms++;
+ }
+ } else
+ nxforms = prop->prop_nxforms;
+
sap->sap_proposalnr = prop->prop_id;
sap->sap_protoid = prop->prop_protoid;
sap->sap_spisize = prop->prop_localspi.spi_size;
- sap->sap_transforms = prop->prop_nxforms;
+ sap->sap_transforms = nxforms;
saplength = sizeof(*sap);
switch (prop->prop_localspi.spi_size) {
break;
}
- for (i = 0; i < prop->prop_nxforms; i++) {
+ for (i = 0, xfi = 0; i < prop->prop_nxforms; i++) {
xform = prop->prop_xforms + i;
+ if (skipdh && xform->xform_type == IKEV2_XFORMTYPE_DH)
+ continue;
+
if ((xflen = ikev2_add_transform(buf,
- i == prop->prop_nxforms - 1 ?
+ xfi == nxforms - 1 ?
IKEV2_XFORM_LAST : IKEV2_XFORM_MORE,
xform->xform_type, xform->xform_id,
xform->xform_length)) == -1)
return (-1);
+ xfi++;
saplength += xflen;
}
if ((pld = ikev2_add_payload(buf)) == NULL)
goto done;
if ((len = ikev2_add_proposals(env, sa, buf, &sa->sa_proposals,
- IKEV2_SAPROTO_IKE, sa->sa_hdr.sh_initiator, 0)) == -1)
+ IKEV2_SAPROTO_IKE, sa->sa_hdr.sh_initiator, 0, 0)) == -1)
goto done;
if (ikev2_next_payload(pld, len, IKEV2_PAYLOAD_KE) == -1)
if ((pld = ikev2_add_payload(e)) == NULL)
goto done;
if ((len = ikev2_add_proposals(env, sa, e, &sa->sa_proposals, 0,
- sa->sa_hdr.sh_initiator, 0)) == -1)
+ sa->sa_hdr.sh_initiator, 0, 1)) == -1)
goto done;
if ((len = ikev2_add_ts(e, &pld, len, sa, 0)) == -1)
}
if ((len = ikev2_add_proposals(env, sa, e, &sa->sa_proposals,
- protoid, 1, 0)) == -1)
+ protoid, 1, 0, 0)) == -1)
goto done;
if (ikev2_next_payload(pld, len, IKEV2_PAYLOAD_NONCE) == -1)
/* just reuse the old IKE SA proposals */
if ((len = ikev2_add_proposals(env, nsa, e, &sa->sa_proposals,
- IKEV2_SAPROTO_IKE, 1, 1)) == -1)
+ IKEV2_SAPROTO_IKE, 1, 1, 0)) == -1)
goto done;
if (ikev2_next_payload(pld, len, IKEV2_PAYLOAD_NONCE) == -1)
if ((len = ikev2_add_proposals(env, nsa ? nsa : sa, e,
nsa ? &nsa->sa_proposals : &proposals,
- protoid, 0, nsa ? 1 : 0)) == -1)
+ protoid, 0, nsa ? 1 : 0, 0)) == -1)
goto done;
if (ikev2_next_payload(pld, len, IKEV2_PAYLOAD_NONCE) == -1)