summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpatrick <patrick@openbsd.org>2017-12-03 21:02:06 +0000
committerpatrick <patrick@openbsd.org>2017-12-03 21:02:06 +0000
commit4cbd1be50ad1430fe18019adbbf7c36e9fda02ea (patch)
treef6ab0f0eb8ed080fabfac48ec7f282098cfdf038
parentMove timer fields 'expiry" and "rebind" out of struct client_lease (diff)
downloadwireguard-openbsd-4cbd1be50ad1430fe18019adbbf7c36e9fda02ea.tar.xz
wireguard-openbsd-4cbd1be50ad1430fe18019adbbf7c36e9fda02ea.zip
The RFC specifies that to accept a proposal, we must select a transform
for each transform type. We do some sanity checks, for instance we do require an encryption transform for ESP, but that's not enough. We need to check that for every proposed transform type we have found a matching transform in our own proposal. ok sthen@
-rw-r--r--sbin/iked/ikev2.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/sbin/iked/ikev2.c b/sbin/iked/ikev2.c
index fbc487695a9..0b88d13ab87 100644
--- a/sbin/iked/ikev2.c
+++ b/sbin/iked/ikev2.c
@@ -1,4 +1,4 @@
-/* $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>
@@ -4079,9 +4079,22 @@ ikev2_match_proposals(struct iked_proposal *local, struct iked_proposal *peer,
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;
@@ -4099,8 +4112,6 @@ ikev2_match_proposals(struct iked_proposal *local, struct iked_proposal *peer,
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 <
@@ -4136,6 +4147,9 @@ ikev2_match_proposals(struct iked_proposal *local, struct iked_proposal *peer,
(requiredh && i == IKEV2_XFORMTYPE_DH))) {
score = 0;
break;
+ } else if (peerxfs[i] && xforms[i] == NULL) {
+ score = 0;
+ break;
} else if (xforms[i] == NULL)
continue;