File 0129-Fix-vulnerabilities-in-GSS-message-token-handling.patch of Package krb5.34946
From 55db6d6c6fc1d8ee135ce47be0ee8e4babf52339 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Mon, 5 May 2014 00:05:54 -0400
Subject: [PATCH 1/5] Add k5-input.h
Add a header containing a declaration for struct k5input and static
inline functions to use it. A k5input structure can be used to safely
extract bytes and integers from a fixed-sized input buffer without
overrunning the buffer. It supports deferred error checking (similar
to k5buf) by returning dummy values and storing a status value in the
input structure.
(cherry picked from commit 1263ed281d1f50b97399137b90344a75e991129c)
---
src/include/k5-input.h | 143 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 143 insertions(+)
create mode 100644 src/include/k5-input.h
diff --git a/src/include/k5-input.h b/src/include/k5-input.h
new file mode 100644
index 0000000000..d42ebce8f2
--- /dev/null
+++ b/src/include/k5-input.h
@@ -0,0 +1,143 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* include/k5-input.h - k5input helper functions */
+/*
+ * Copyright (C) 2014 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef K5_INPUT_H
+#define K5_INPUT_H
+
+#include "k5-int.h"
+
+/*
+ * The k5input module defines helpers for safely consuming a fixed-sized block
+ * of memory. If an overrun or allocation failure occurs at any step,
+ * subsequent functions will return default values until the error is detected
+ * by looking at the status field.
+ */
+
+struct k5input {
+ const unsigned char *ptr;
+ size_t len;
+ krb5_error_code status;
+};
+
+static inline void
+k5_input_init(struct k5input *in, const void *ptr, size_t len)
+{
+ in->ptr = ptr;
+ in->len = len;
+ in->status = 0;
+}
+
+/* Only set the status value of in if it hasn't already been set, so status
+ * reflects the first thing to go wrong. */
+static inline void
+k5_input_set_status(struct k5input *in, krb5_error_code status)
+{
+ if (!in->status)
+ in->status = status;
+}
+
+static inline const unsigned char *
+k5_input_get_bytes(struct k5input *in, size_t len)
+{
+ if (in->len < len)
+ k5_input_set_status(in, EINVAL);
+ if (in->status)
+ return NULL;
+ in->len -= len;
+ in->ptr += len;
+ return in->ptr - len;
+}
+
+static inline unsigned char
+k5_input_get_byte(struct k5input *in)
+{
+ const unsigned char *ptr = k5_input_get_bytes(in, 1);
+ return (ptr == NULL) ? '\0' : *ptr;
+}
+
+static inline uint16_t
+k5_input_get_uint16_be(struct k5input *in)
+{
+ const unsigned char *ptr = k5_input_get_bytes(in, 2);
+ return (ptr == NULL) ? 0 : load_16_be(ptr);
+}
+
+static inline uint16_t
+k5_input_get_uint16_le(struct k5input *in)
+{
+ const unsigned char *ptr = k5_input_get_bytes(in, 2);
+ return (ptr == NULL) ? 0 : load_16_le(ptr);
+}
+
+static inline uint16_t
+k5_input_get_uint16_n(struct k5input *in)
+{
+ const unsigned char *ptr = k5_input_get_bytes(in, 2);
+ return (ptr == NULL) ? 0 : load_16_n(ptr);
+}
+
+static inline uint32_t
+k5_input_get_uint32_be(struct k5input *in)
+{
+ const unsigned char *ptr = k5_input_get_bytes(in, 4);
+ return (ptr == NULL) ? 0 : load_32_be(ptr);
+}
+
+static inline uint32_t
+k5_input_get_uint32_le(struct k5input *in)
+{
+ const unsigned char *ptr = k5_input_get_bytes(in, 4);
+ return (ptr == NULL) ? 0 : load_32_le(ptr);
+}
+
+static inline uint32_t
+k5_input_get_uint32_n(struct k5input *in)
+{
+ const unsigned char *ptr = k5_input_get_bytes(in, 4);
+ return (ptr == NULL) ? 0 : load_32_n(ptr);
+}
+
+static inline uint64_t
+k5_input_get_uint64_be(struct k5input *in)
+{
+ const unsigned char *ptr = k5_input_get_bytes(in, 8);
+ return (ptr == NULL) ? 0 : load_64_be(ptr);
+}
+
+static inline uint64_t
+k5_input_get_uint64_le(struct k5input *in)
+{
+ const unsigned char *ptr = k5_input_get_bytes(in, 8);
+ return (ptr == NULL) ? 0 : load_64_le(ptr);
+}
+
+#endif /* K5_BUF_H */
--
2.45.2
From d733ea4b387270a6e85744964fc4d972b32f1c1d Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Tue, 7 Mar 2023 00:19:33 -0500
Subject: [PATCH 2/5] Add a simple DER support header
(cherry picked from commit 548da160b52b25a106e9f6077d6a42c2c049586c)
---
src/include/k5-der.h | 149 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 149 insertions(+)
create mode 100644 src/include/k5-der.h
diff --git a/src/include/k5-der.h b/src/include/k5-der.h
new file mode 100644
index 0000000000..b8371d9b4d
--- /dev/null
+++ b/src/include/k5-der.h
@@ -0,0 +1,149 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* include/k5-der.h - Distinguished Encoding Rules (DER) declarations */
+/*
+ * Copyright (C) 2023 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Most ASN.1 encoding and decoding is done using the table-driven framework in
+ * libkrb5. When that is not an option, these helpers can be used to encode
+ * and decode simple types.
+ */
+
+#ifndef K5_DER_H
+#define K5_DER_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "k5-buf.h"
+#include "k5-input.h"
+
+/* Return the number of bytes needed to encode len as a DER encoding length. */
+static inline size_t
+k5_der_len_len(size_t len)
+{
+ size_t llen;
+
+ if (len < 128)
+ return 1;
+ llen = 1;
+ while (len > 0) {
+ len >>= 8;
+ llen++;
+ }
+ return llen;
+}
+
+/* Return the number of bytes needed to encode a DER value (with identifier
+ * byte and length) for a given contents length. */
+static inline size_t
+k5_der_value_len(size_t contents_len)
+{
+ return 1 + k5_der_len_len(contents_len) + contents_len;
+}
+
+/* Add a DER identifier byte (composed by the caller, including the ASN.1
+ * class, tag, and constructed bit) and length. */
+static inline void
+k5_der_add_taglen(struct k5buf *buf, uint8_t idbyte, size_t len)
+{
+ uint8_t *p;
+ size_t llen = k5_der_len_len(len);
+
+ p = k5_buf_get_space(buf, 1 + llen);
+ if (p == NULL)
+ return;
+ *p++ = idbyte;
+ if (len < 128) {
+ *p = len;
+ } else {
+ *p = 0x80 | (llen - 1);
+ /* Encode the length bytes backwards so the most significant byte is
+ * first. */
+ p += llen;
+ while (len > 0) {
+ *--p = len & 0xFF;
+ len >>= 8;
+ }
+ }
+}
+
+/* Add a DER value (identifier byte, length, and contents). */
+static inline void
+k5_der_add_value(struct k5buf *buf, uint8_t idbyte, const void *contents,
+ size_t len)
+{
+ k5_der_add_taglen(buf, idbyte, len);
+ k5_buf_add_len(buf, contents, len);
+}
+
+/*
+ * If the next byte in in matches idbyte and the subsequent DER length is
+ * valid, advance in past the value, set *contents_out to the value contents,
+ * and return true. Otherwise return false. Only set an error on in if the
+ * next bytes matches idbyte but the ensuing length is invalid. contents_out
+ * may be aliased to in; it will only be written to on successful decoding of a
+ * value.
+ */
+static inline bool
+k5_der_get_value(struct k5input *in, uint8_t idbyte,
+ struct k5input *contents_out)
+{
+ uint8_t lenbyte, i;
+ size_t len;
+ const void *bytes;
+
+ /* Do nothing if in is empty or the next byte doesn't match idbyte. */
+ if (in->status || in->len == 0 || *in->ptr != idbyte)
+ return false;
+
+ /* Advance past the identifier byte and decode the length. */
+ (void)k5_input_get_byte(in);
+ lenbyte = k5_input_get_byte(in);
+ if (lenbyte < 128) {
+ len = lenbyte;
+ } else {
+ len = 0;
+ for (i = 0; i < (lenbyte & 0x7F); i++) {
+ if (len > (SIZE_MAX >> 8)) {
+ k5_input_set_status(in, EOVERFLOW);
+ return false;
+ }
+ len = (len << 8) | k5_input_get_byte(in);
+ }
+ }
+
+ bytes = k5_input_get_bytes(in, len);
+ if (bytes == NULL)
+ return false;
+ k5_input_init(contents_out, bytes, len);
+ return true;
+}
+
+#endif /* K5_DER_H */
--
2.45.2
From 6c3322b313f887730b5871109d1b867fe34deb40 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Sun, 4 May 2014 15:43:35 -0400
Subject: [PATCH 3/5] Add k5_buf_get_space
Add a new k5_buf method to make room in the buffer for the caller to
fill in.
(cherry picked from commit ccd989bdc2656b153bc226462e0c13800810ae04)
---
src/include/k5-buf.h | 4 ++++
src/util/support/k5buf.c | 10 ++++++++++
src/util/support/libkrb5support-fixed.exports | 1 +
3 files changed, 15 insertions(+)
diff --git a/src/include/k5-buf.h b/src/include/k5-buf.h
index c5576a3e32..da10fd9f4d 100644
--- a/src/include/k5-buf.h
+++ b/src/include/k5-buf.h
@@ -91,6 +91,10 @@ void k5_buf_add_fmt(struct k5buf *buf, const char *fmt, ...)
#endif
;
+/* Extend the length of buf by len and return a pointer to the reserved space,
+ * to be filled in by the caller. Return NULL on error. */
+void *k5_buf_get_space(struct k5buf *buf, size_t len);
+
/* Truncate BUF. LEN must be between 0 and the existing buffer
* length, or an assertion failure will result. */
void k5_buf_truncate(struct k5buf *buf, size_t len);
diff --git a/src/util/support/k5buf.c b/src/util/support/k5buf.c
index 778e68b39b..c3c81b0b2c 100644
--- a/src/util/support/k5buf.c
+++ b/src/util/support/k5buf.c
@@ -191,6 +191,16 @@ k5_buf_add_fmt(struct k5buf *buf, const char *fmt, ...)
free(tmp);
}
+void *
+k5_buf_get_space(struct k5buf *buf, size_t len)
+{
+ if (!ensure_space(buf, len))
+ return NULL;
+ buf->len += len;
+ buf->data[buf->len] = '\0';
+ return &buf->data[buf->len - len];
+}
+
void
k5_buf_truncate(struct k5buf *buf, size_t len)
{
diff --git a/src/util/support/libkrb5support-fixed.exports b/src/util/support/libkrb5support-fixed.exports
index 2f38242d91..f5fbe9e0cb 100644
--- a/src/util/support/libkrb5support-fixed.exports
+++ b/src/util/support/libkrb5support-fixed.exports
@@ -6,6 +6,7 @@ k5_buf_init_dynamic
k5_buf_add
k5_buf_add_len
k5_buf_add_fmt
+k5_buf_get_space
k5_buf_truncate
k5_buf_data
k5_buf_len
--
2.45.2
From e152c50288378ac80f0180e3a6ca9c1521ff7b53 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Sat, 11 Nov 2017 13:42:28 -0500
Subject: [PATCH 4/5] Length check when parsing GSS token encapsulation
gssint_get_mech_type_oid() is used by gss_accept_sec_context() to
determine the mechanism of the token. Without length checking, it
might read a few bytes past the end of the input token buffer. Add
length checking as well as test cases for truncated encapsulations.
Reported by Bar Katz.
ticket: 8620 (new)
target_version: 1.16
target_version: 1.15-next
target_version: 1.14-next
tags: pullup
(cherry picked from commit f949e990f930f48df1f108fe311c58ae3da18b24)
---
src/lib/gssapi/mechglue/g_glue.c | 20 ++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/src/lib/gssapi/mechglue/g_glue.c b/src/lib/gssapi/mechglue/g_glue.c
index e438a032ca..bfddf64ba7 100644
--- a/src/lib/gssapi/mechglue/g_glue.c
+++ b/src/lib/gssapi/mechglue/g_glue.c
@@ -189,7 +189,7 @@ OM_uint32 gssint_get_mech_type_oid(OID, token)
gss_buffer_t token;
{
unsigned char * buffer_ptr;
- int length;
+ size_t buflen, lenbytes, length, oidlen;
/*
* This routine reads the prefix of "token" in order to determine
@@ -223,25 +223,33 @@ OM_uint32 gssint_get_mech_type_oid(OID, token)
/* Skip past the APP/Sequnce byte and the token length */
buffer_ptr = (unsigned char *) token->value;
+ buflen = token->length;
- if (*(buffer_ptr++) != 0x60)
+ if (buflen < 2 || *buffer_ptr++ != 0x60)
return (GSS_S_DEFECTIVE_TOKEN);
length = *buffer_ptr++;
+ buflen -= 2;
/* check if token length is null */
if (length == 0)
return (GSS_S_DEFECTIVE_TOKEN);
if (length & 0x80) {
- if ((length & 0x7f) > 4)
+ lenbytes = length & 0x7f;
+ if (lenbytes > 4 || lenbytes > buflen)
return (GSS_S_DEFECTIVE_TOKEN);
- buffer_ptr += length & 0x7f;
+ buffer_ptr += lenbytes;
+ buflen -= lenbytes;
}
- if (*(buffer_ptr++) != 0x06)
+ if (buflen < 2 || *buffer_ptr++ != 0x06)
+ return (GSS_S_DEFECTIVE_TOKEN);
+ oidlen = *buffer_ptr++;
+ buflen -= 2;
+ if (oidlen > 0x7f || oidlen > buflen)
return (GSS_S_DEFECTIVE_TOKEN);
- OID->length = (OM_uint32) *(buffer_ptr++);
+ OID->length = oidlen;
OID->elements = (void *) buffer_ptr;
return (GSS_S_COMPLETE);
}
--
2.45.2
From b22c0093eab772e92a1df4e0c0fecdb2cdea594f Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Fri, 14 Jun 2024 10:56:12 -0400
Subject: [PATCH 5/5] Fix vulnerabilities in GSS message token handling
In gss_krb5int_unseal_token_v3() and gss_krb5int_unseal_v3_iov(),
verify the Extra Count field of CFX wrap tokens against the encrypted
header. Reported by Jacob Champion.
In gss_krb5int_unseal_token_v3(), check for a decrypted plaintext
length too short to contain the encrypted header and extra count
bytes. Reported by Jacob Champion.
In kg_unseal_iov_token(), separately track the header IOV length and
complete token length when parsing the token's ASN.1 wrapper. This
fix contains modified versions of functions from k5-der.h and
util_token.c; this duplication will be cleaned up in a future commit.
CVE-2024-37370:
In MIT krb5 release 1.3 and later, an attacker can modify the
plaintext Extra Count field of a confidential GSS krb5 wrap token,
causing the unwrapped token to appear truncated to the application.
CVE-2024-37371:
In MIT krb5 release 1.3 and later, an attacker can cause invalid
memory reads by sending message tokens with invalid length fields.
(cherry picked from commit b0a2f8a5365f2eec3e27d78907de9f9d2c80505a)
ticket: 9128
version_fixed: 1.21.3
(cherry picked from commit 55fbf435edbe2e92dd8101669b1ce7144bc96fef)
---
src/lib/gssapi/krb5/k5sealv3.c | 5 ++
src/lib/gssapi/krb5/k5sealv3iov.c | 3 +-
src/lib/gssapi/krb5/k5unsealiov.c | 80 ++++++++++++++++++++++++++++---
3 files changed, 80 insertions(+), 8 deletions(-)
diff --git a/src/lib/gssapi/krb5/k5sealv3.c b/src/lib/gssapi/krb5/k5sealv3.c
index 7e4de86c8c..57c0476e22 100644
--- a/src/lib/gssapi/krb5/k5sealv3.c
+++ b/src/lib/gssapi/krb5/k5sealv3.c
@@ -409,10 +409,15 @@ gss_krb5int_unseal_token_v3(krb5_context *contextptr,
/* Don't use bodysize here! Use the fact that
cipher.ciphertext.length has been adjusted to the
correct length. */
+ if (plain.length < 16 + ec) {
+ free(plain.data);
+ goto defective;
+ }
althdr = (unsigned char *)plain.data + plain.length - 16;
if (load_16_be(althdr) != KG2_TOK_WRAP_MSG
|| althdr[2] != ptr[2]
|| althdr[3] != ptr[3]
+ || load_16_be(althdr+4) != ec
|| memcmp(althdr+8, ptr+8, 8)) {
free(plain.data);
goto defective;
diff --git a/src/lib/gssapi/krb5/k5sealv3iov.c b/src/lib/gssapi/krb5/k5sealv3iov.c
index 8f6c4d4413..8a3d140b3e 100644
--- a/src/lib/gssapi/krb5/k5sealv3iov.c
+++ b/src/lib/gssapi/krb5/k5sealv3iov.c
@@ -406,9 +406,10 @@ gss_krb5int_unseal_v3_iov(krb5_context context,
if (load_16_be(althdr) != KG2_TOK_WRAP_MSG
|| althdr[2] != ptr[2]
|| althdr[3] != ptr[3]
+ || load_16_be(althdr + 4) != ec
|| memcmp(althdr + 8, ptr + 8, 8) != 0) {
*minor_status = 0;
- return GSS_S_BAD_SIG;
+ return GSS_S_DEFECTIVE_TOKEN;
}
} else {
/* Verify checksum: note EC is checksum size here, not padding */
diff --git a/src/lib/gssapi/krb5/k5unsealiov.c b/src/lib/gssapi/krb5/k5unsealiov.c
index 191de2cff1..35e571b637 100644
--- a/src/lib/gssapi/krb5/k5unsealiov.c
+++ b/src/lib/gssapi/krb5/k5unsealiov.c
@@ -27,6 +27,7 @@
#include <assert.h>
#include "k5-platform.h" /* for 64-bit support */
#include "k5-int.h" /* for zap() */
+#include "k5-der.h"
#include "gssapiP_krb5.h"
#include <stdarg.h>
@@ -297,6 +298,73 @@ cleanup:
return retval;
}
+/* Similar to k5_der_get_value(), but output an unchecked content length
+ * instead of a k5input containing the contents. */
+static inline bool
+get_der_tag(struct k5input *in, uint8_t idbyte, size_t *len_out)
+{
+ uint8_t lenbyte, i;
+ size_t len;
+
+ /* Do nothing if in is empty or the next byte doesn't match idbyte. */
+ if (in->status || in->len == 0 || *in->ptr != idbyte)
+ return false;
+
+ /* Advance past the identifier byte and decode the length. */
+ (void)k5_input_get_byte(in);
+ lenbyte = k5_input_get_byte(in);
+ if (lenbyte < 128) {
+ len = lenbyte;
+ } else {
+ len = 0;
+ for (i = 0; i < (lenbyte & 0x7F); i++) {
+ if (len > (SIZE_MAX >> 8)) {
+ k5_input_set_status(in, EOVERFLOW);
+ return false;
+ }
+ len = (len << 8) | k5_input_get_byte(in);
+ }
+ }
+
+ if (in->status)
+ return false;
+
+ *len_out = len;
+ return true;
+}
+
+/*
+ * Similar to g_verify_token_header() without toktype or flags, but do not read
+ * more than *header_len bytes of ASN.1 wrapper, and on output set *header_len
+ * to the remaining number of header bytes. Verify the outer DER tag's length
+ * against token_len, which may be larger (but not smaller) than *header_len.
+ */
+static gss_int32
+verify_detached_wrapper(const gss_OID_desc *mech, size_t *header_len,
+ uint8_t **header_in, size_t token_len)
+{
+ struct k5input in, mech_der;
+ gss_OID_desc toid;
+ size_t len;
+
+ k5_input_init(&in, *header_in, *header_len);
+
+ if (get_der_tag(&in, 0x60, &len)) {
+ if (len != token_len - (in.ptr - *header_in))
+ return G_BAD_TOK_HEADER;
+ if (!k5_der_get_value(&in, 0x06, &mech_der))
+ return G_BAD_TOK_HEADER;
+ toid.elements = (uint8_t *)mech_der.ptr;
+ toid.length = mech_der.len;
+ if (!g_OID_equal(&toid, mech))
+ return G_WRONG_MECH;
+ }
+
+ *header_in = (uint8_t *)in.ptr;
+ *header_len = in.len;
+ return 0;
+}
+
/*
* Caller must provide TOKEN | DATA | PADDING | TRAILER, except
* for DCE in which case it can just provide TOKEN | DATA (must
@@ -317,8 +385,7 @@ kg_unseal_iov_token(OM_uint32 *minor_status,
gss_iov_buffer_t header;
gss_iov_buffer_t padding;
gss_iov_buffer_t trailer;
- size_t input_length;
- unsigned int bodysize;
+ size_t input_length, hlen;
int toktype2;
header = kg_locate_header_iov(iov, iov_count, toktype);
@@ -348,15 +415,14 @@ kg_unseal_iov_token(OM_uint32 *minor_status,
input_length += trailer->buffer.length;
}
- code = g_verify_token_header(ctx->mech_used,
- &bodysize, &ptr, -1,
- input_length, 0);
+ hlen = header->buffer.length;
+ code = verify_detached_wrapper(ctx->mech_used, &hlen, &ptr, input_length);
if (code != 0) {
*minor_status = code;
return GSS_S_DEFECTIVE_TOKEN;
}
- if (bodysize < 2) {
+ if (hlen < 2) {
*minor_status = (OM_uint32)G_BAD_TOK_HEADER;
return GSS_S_DEFECTIVE_TOKEN;
}
@@ -364,7 +430,7 @@ kg_unseal_iov_token(OM_uint32 *minor_status,
toktype2 = load_16_be(ptr);
ptr += 2;
- bodysize -= 2;
+ hlen -= 2;
switch (toktype2) {
case KG2_TOK_MIC_MSG:
--
2.45.2