-/* $OpenBSD: ikev2.c,v 1.160 2017/12/01 19:49:31 patrick Exp $ */
+/* $OpenBSD: ikev2.c,v 1.161 2017/12/03 21:02:06 patrick Exp $ */
/*
* Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
struct iked_transform *tpeer, *tlocal;
unsigned int i, j, type, score, requiredh = 0;
uint8_t protoid = peer->prop_protoid;
+ uint8_t peerxfs[IKEV2_XFORMTYPE_MAX];
+
+ bzero(peerxfs, sizeof(peerxfs));
for (i = 0; i < peer->prop_nxforms; i++) {
tpeer = peer->prop_xforms + i;
+ if (tpeer->xform_type > IKEV2_XFORMTYPE_MAX)
+ continue;
+
+ /*
+ * Record all transform types from the peer's proposal,
+ * because if we want this proposal we have to select
+ * a transform for each proposed transform type.
+ */
+ peerxfs[tpeer->xform_type] = 1;
+
for (j = 0; j < local->prop_nxforms; j++) {
tlocal = local->prop_xforms + j;
tpeer->xform_id != tlocal->xform_id ||
tpeer->xform_length != tlocal->xform_length)
continue;
- if (tpeer->xform_type > IKEV2_XFORMTYPE_MAX)
- continue;
type = tpeer->xform_type;
if (xforms[type] == NULL || tlocal->xform_score <
(requiredh && i == IKEV2_XFORMTYPE_DH))) {
score = 0;
break;
+ } else if (peerxfs[i] && xforms[i] == NULL) {
+ score = 0;
+ break;
} else if (xforms[i] == NULL)
continue;