summaryrefslogtreecommitdiff
path: root/sbin/iked/ikev2_pld.c
diff options
context:
space:
mode:
authorTobias Heider <tobhe@cvs.openbsd.org>2024-03-02 16:16:08 +0000
committerTobias Heider <tobhe@cvs.openbsd.org>2024-03-02 16:16:08 +0000
commit5d25cd599e7dba10080f358c9d2101e6fa79eb4a (patch)
tree392bbe1b8e1a80184428c4c3352dc7d4dde29a64 /sbin/iked/ikev2_pld.c
parent903fc5927a38d6f0d7fd4d5684b66ce3dd3efeac (diff)
Trigger retransmission only for fragment 1/x, otherwise each received
fragment can trigger retransmission of the full fragment queue. From RFC7383, 2.6.1: "[...] that even MUST only trigger a retransmission of the response message (fragmented or no) if the Fragment Number field in the received fragments is set to 1; otherwise, it MUST be ignored." from markus
Diffstat (limited to 'sbin/iked/ikev2_pld.c')
-rw-r--r--sbin/iked/ikev2_pld.c78
1 files changed, 77 insertions, 1 deletions
diff --git a/sbin/iked/ikev2_pld.c b/sbin/iked/ikev2_pld.c
index f207fbfc348..1fb5f305499 100644
--- a/sbin/iked/ikev2_pld.c
+++ b/sbin/iked/ikev2_pld.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ikev2_pld.c,v 1.133 2023/09/02 18:36:30 tobhe Exp $ */
+/* $OpenBSD: ikev2_pld.c,v 1.134 2024/03/02 16:16:07 tobhe Exp $ */
/*
* Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
@@ -2103,3 +2103,79 @@ ikev2_pld_eap(struct iked *env, struct ikev2_payload *pld,
return (0);
}
+
+/* parser for the initial IKE_AUTH payload, does not require msg_sa */
+int
+ikev2_pld_parse_quick(struct iked *env, struct ike_header *hdr,
+ struct iked_message *msg, size_t offset)
+{
+ struct ikev2_payload pld;
+ struct ikev2_frag_payload frag;
+ uint8_t *msgbuf = ibuf_data(msg->msg_data);
+ uint8_t *buf;
+ size_t len, total, left;
+ size_t length;
+ unsigned int payload;
+
+ log_debug("%s: header ispi %s rspi %s"
+ " nextpayload %s version 0x%02x exchange %s flags 0x%02x"
+ " msgid %d length %u response %d", __func__,
+ print_spi(betoh64(hdr->ike_ispi), 8),
+ print_spi(betoh64(hdr->ike_rspi), 8),
+ print_map(hdr->ike_nextpayload, ikev2_payload_map),
+ hdr->ike_version,
+ print_map(hdr->ike_exchange, ikev2_exchange_map),
+ hdr->ike_flags,
+ betoh32(hdr->ike_msgid),
+ betoh32(hdr->ike_length),
+ msg->msg_response);
+
+ length = betoh32(hdr->ike_length);
+
+ if (ibuf_size(msg->msg_data) < length) {
+ log_debug("%s: short message", __func__);
+ return (-1);
+ }
+
+ offset += sizeof(*hdr);
+
+ /* Bytes left in datagram. */
+ total = length - offset;
+
+ payload = hdr->ike_nextpayload;
+
+ while (payload != 0 && offset < length) {
+ if (ikev2_validate_pld(msg, offset, total, &pld))
+ return (-1);
+
+ log_debug("%s: %spayload %s"
+ " nextpayload %s critical 0x%02x length %d",
+ __func__, msg->msg_e ? "decrypted " : "",
+ print_map(payload, ikev2_payload_map),
+ print_map(pld.pld_nextpayload, ikev2_payload_map),
+ pld.pld_reserved & IKEV2_CRITICAL_PAYLOAD,
+ betoh16(pld.pld_length));
+
+ /* Skip over generic payload header. */
+ offset += sizeof(pld);
+ total -= sizeof(pld);
+ left = betoh16(pld.pld_length) - sizeof(pld);
+
+ switch (payload) {
+ case IKEV2_PAYLOAD_SKF:
+ len = left;
+ buf = msgbuf + offset;
+ if (len < sizeof(frag))
+ return (-1);
+ memcpy(&frag, buf, sizeof(frag));
+ msg->msg_frag_num = betoh16(frag.frag_num);
+ break;
+ }
+
+ payload = pld.pld_nextpayload;
+ offset += left;
+ total -= left;
+ }
+
+ return (0);
+}