diff options
Diffstat (limited to 'net/samba413/files/CVE-2022-3437-des3-overflow-v4a-4.12.patch')
-rw-r--r-- | net/samba413/files/CVE-2022-3437-des3-overflow-v4a-4.12.patch | 1897 |
1 files changed, 0 insertions, 1897 deletions
diff --git a/net/samba413/files/CVE-2022-3437-des3-overflow-v4a-4.12.patch b/net/samba413/files/CVE-2022-3437-des3-overflow-v4a-4.12.patch deleted file mode 100644 index 1d1a538a9cbd..000000000000 --- a/net/samba413/files/CVE-2022-3437-des3-overflow-v4a-4.12.patch +++ /dev/null @@ -1,1897 +0,0 @@ -From e63b31932441b6213ace55f4e627d098682965c3 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton <josephsutton@catalyst.net.nz> -Date: Wed, 12 Oct 2022 13:56:08 +1300 -Subject: [PATCH 01/11] CVE-2022-3437 source4/heimdal: Remove __func__ - compatibility workaround - -As described by the C standard, __func__ is a variable, not a macro. -Hence this #ifndef check does not work as intended, and only serves to -unconditionally disable __func__. A nonoperating __func__ prevents -cmocka operating correctly, so remove this definition. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15134 - -Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> -Reviewed-by: Andrew Bartlett <abartlet@samba.org> ---- - source4/heimdal/lib/krb5/krb5_locl.h | 4 ---- - 1 file changed, 4 deletions(-) - -diff --git a/source4/heimdal/lib/krb5/krb5_locl.h b/source4/heimdal/lib/krb5/krb5_locl.h -index 49c614d5efe..d3360c556ce 100644 ---- a/source4/heimdal/lib/krb5/krb5_locl.h -+++ b/source4/heimdal/lib/krb5/krb5_locl.h -@@ -188,10 +188,6 @@ struct _krb5_krb_auth_data; - #define ALLOC(X, N) (X) = calloc((N), sizeof(*(X))) - #define ALLOC_SEQ(X, N) do { (X)->len = (N); ALLOC((X)->val, (N)); } while(0) - --#ifndef __func__ --#define __func__ "unknown-function" --#endif -- - #define krb5_einval(context, argnum) _krb5_einval((context), __func__, (argnum)) - - #ifndef PATH_SEP --- -2.25.1 - - -From f11ebd82b4b6e04433907a8fe15d0a8df11fac8a Mon Sep 17 00:00:00 2001 -From: Joseph Sutton <josephsutton@catalyst.net.nz> -Date: Wed, 12 Oct 2022 13:55:51 +1300 -Subject: [PATCH 02/11] CVE-2022-3437 source4/heimdal_build: Add - gssapi-subsystem subsystem - -This allows us to access (and so test) functions internal to GSSAPI by -depending on this subsystem. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15134 - -Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> -Reviewed-by: Andrew Bartlett <abartlet@samba.org> - -[jsutton@samba.org Adapted to older wscript_build file] ---- - source4/heimdal_build/wscript_build | 14 ++++++++++---- - 1 file changed, 10 insertions(+), 4 deletions(-) - -diff --git a/source4/heimdal_build/wscript_build b/source4/heimdal_build/wscript_build -index f151788dcfd..396656e0727 100644 ---- a/source4/heimdal_build/wscript_build -+++ b/source4/heimdal_build/wscript_build -@@ -556,8 +556,8 @@ if not bld.CONFIG_SET("USING_SYSTEM_GSSAPI"): - HEIMDAL_AUTOPROTO_PRIVATE('lib/gssapi/krb5/gsskrb5-private.h', - HEIMDAL_GSSAPI_KRB5_SOURCE) - -- HEIMDAL_LIBRARY('gssapi', -- HEIMDAL_GSSAPI_SPNEGO_SOURCE + HEIMDAL_GSSAPI_KRB5_SOURCE + ''' -+ HEIMDAL_SUBSYSTEM('gssapi-subsystem', -+ HEIMDAL_GSSAPI_SPNEGO_SOURCE + HEIMDAL_GSSAPI_KRB5_SOURCE + ''' - lib/gssapi/mech/context.c lib/gssapi/mech/gss_krb5.c lib/gssapi/mech/gss_mech_switch.c - lib/gssapi/mech/gss_process_context_token.c lib/gssapi/mech/gss_buffer_set.c - lib/gssapi/mech/gss_aeap.c lib/gssapi/mech/gss_add_cred.c lib/gssapi/mech/gss_cred.c -@@ -582,10 +582,16 @@ if not bld.CONFIG_SET("USING_SYSTEM_GSSAPI"): - lib/gssapi/mech/gss_set_cred_option.c lib/gssapi/mech/gss_pseudo_random.c ../heimdal_build/gssapi-glue.c''', - includes='../heimdal/lib/gssapi ../heimdal/lib/gssapi/gssapi ../heimdal/lib/gssapi/spnego ../heimdal/lib/gssapi/krb5 ../heimdal/lib/gssapi/mech', - deps='hcrypto asn1 HEIMDAL_SPNEGO_ASN1 HEIMDAL_GSSAPI_ASN1 roken krb5 com_err wind', -- vnum='2.0.0', -- version_script='lib/gssapi/version-script.map', - ) - -+ HEIMDAL_LIBRARY('gssapi', -+ '', -+ includes='../heimdal/lib/gssapi ../heimdal/lib/gssapi/gssapi ../heimdal/lib/gssapi/spnego ../heimdal/lib/gssapi/krb5 ../heimdal/lib/gssapi/mech', -+ deps='gssapi-subsystem', -+ vnum='2.0.0', -+ version_script='lib/gssapi/version-script.map', -+ ) -+ - if not bld.CONFIG_SET("USING_SYSTEM_KRB5"): - # expand_path.c needs some of the install paths - HEIMDAL_SUBSYSTEM('HEIMDAL_CONFIG', --- -2.25.1 - - -From 04e71e8e5398f42c329db2a9a51c7f76a62a18b0 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton <josephsutton@catalyst.net.nz> -Date: Wed, 12 Oct 2022 13:55:39 +1300 -Subject: [PATCH 03/11] CVE-2022-3437 s4/auth/tests: Add unit tests for - unwrap_des3() - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15134 - -Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> -Reviewed-by: Andrew Bartlett <abartlet@samba.org> -[jsutton@samba.org Adapted to lack of 'samba.unittests.auth.sam' test, - renamed 'third_party' to 'source4' in paths, defined - HEIMDAL_NORETURN_ATTRIBUTE and HEIMDAL_PRINTF_ATTRIBUTE to fix compiler - error] -[abartlet@samba.org backported to 4.12 required fixing merge conflicts - in wscript_build subsystem conversion (different deps) and tests.py test addition - (unrelated changes in context)] ---- - selftest/knownfail.d/heimdal-des-overflow | 9 + - selftest/tests.py | 5 + - source4/auth/tests/heimdal_unwrap_des.c | 1247 +++++++++++++++++++++ - source4/auth/wscript_build | 21 + - 4 files changed, 1282 insertions(+) - create mode 100644 selftest/knownfail.d/heimdal-des-overflow - create mode 100644 source4/auth/tests/heimdal_unwrap_des.c - -diff --git a/selftest/knownfail.d/heimdal-des-overflow b/selftest/knownfail.d/heimdal-des-overflow -new file mode 100644 -index 00000000000..23acbb43d31 ---- /dev/null -+++ b/selftest/knownfail.d/heimdal-des-overflow -@@ -0,0 +1,9 @@ -+^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_dce_style_missing_payload.none -+^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_dce_style_with_seal_missing_payload.none -+^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_missing_8_bytes.none -+^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_missing_payload.none -+^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_truncated_header_0.none -+^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_truncated_header_1.none -+^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_with_padding_truncated_0.none -+^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_with_padding_truncated_1.none -+^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_with_seal_missing_payload.none -diff --git a/selftest/tests.py b/selftest/tests.py -index 10648b19155..721c36ae4c3 100644 ---- a/selftest/tests.py -+++ b/selftest/tests.py -@@ -46,6 +46,8 @@ have_man_pages_support = ("XSLTPROC_MANPAGES" in config_hash) - with_pam = ("WITH_PAM" in config_hash) - pam_wrapper_so_path = config_hash["LIBPAM_WRAPPER_SO_PATH"] - pam_set_items_so_path = config_hash["PAM_SET_ITEMS_SO_PATH"] -+have_heimdal_support = "SAMBA4_USES_HEIMDAL" in config_hash -+using_system_gssapi = "USING_SYSTEM_GSSAPI" in config_hash - - planpythontestsuite("none", "samba.tests.source") - if have_man_pages_support: -@@ -409,5 +411,8 @@ plantestsuite("samba.unittests.test_registry_regfio", "none", - [os.path.join(bindir(), "default/source3/test_registry_regfio")]) - plantestsuite("samba.unittests.test_oLschema2ldif", "none", - [os.path.join(bindir(), "default/source4/utils/oLschema2ldif/test_oLschema2ldif")]) -+if have_heimdal_support and not using_system_gssapi: -+ plantestsuite("samba.unittests.auth.heimdal_gensec_unwrap_des", "none", -+ [valgrindify(os.path.join(bindir(), "test_heimdal_gensec_unwrap_des"))]) - plantestsuite("samba.unittests.mdsparser_es", "none", - [os.path.join(bindir(), "default/source3/test_mdsparser_es")] + [configuration]) -diff --git a/source4/auth/tests/heimdal_unwrap_des.c b/source4/auth/tests/heimdal_unwrap_des.c -new file mode 100644 -index 00000000000..dc31e9d0ad1 ---- /dev/null -+++ b/source4/auth/tests/heimdal_unwrap_des.c -@@ -0,0 +1,1247 @@ -+/* -+ * Unit tests for source4/heimdal/lib/gssapi/krb5/unwrap.c -+ * -+ * Copyright (C) Catalyst.NET Ltd 2022 -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see <http://www.gnu.org/licenses/>. -+ * -+ */ -+ -+/* -+ * from cmocka.c: -+ * These headers or their equivalents should be included prior to -+ * including -+ * this header file. -+ * -+ * #include <stdarg.h> -+ * #include <stddef.h> -+ * #include <setjmp.h> -+ * -+ * This allows test applications to use custom definitions of C standard -+ * library functions and types. -+ * -+ */ -+ -+#include <stdarg.h> -+#include <stddef.h> -+#include <setjmp.h> -+ -+#include <cmocka.h> -+ -+#include "includes.h" -+#include "replace.h" -+ -+#define HEIMDAL_NORETURN_ATTRIBUTE _NORETURN_ -+#define HEIMDAL_PRINTF_ATTRIBUTE(x) FORMAT_ATTRIBUTE(x) -+ -+#include "../../../source4/heimdal/lib/gssapi/gssapi/gssapi.h" -+#include "gsskrb5_locl.h" -+ -+/****************************************************************************** -+ * Helper functions -+ ******************************************************************************/ -+ -+const uint8_t *valid_range_begin; -+const uint8_t *valid_range_end; -+const uint8_t *invalid_range_end; -+ -+/* -+ * 'array_len' is the size of the passed in array. 'buffer_len' is the size to -+ * report in the resulting buffer. -+ */ -+static const gss_buffer_desc get_input_buffer(TALLOC_CTX *mem_ctx, -+ const uint8_t array[], -+ const size_t array_len, -+ const size_t buffer_len) -+{ -+ gss_buffer_desc buf; -+ -+ /* Add some padding to catch invalid memory accesses. */ -+ const size_t padding = 0x100; -+ const size_t padded_len = array_len + padding; -+ -+ uint8_t *data = talloc_size(mem_ctx, padded_len); -+ assert_non_null(data); -+ -+ memcpy(data, array, array_len); -+ memset(data + array_len, 0, padding); -+ -+ assert_in_range(buffer_len, 0, array_len); -+ -+ buf.value = data; -+ buf.length = buffer_len; -+ -+ valid_range_begin = buf.value; -+ valid_range_end = valid_range_begin + buf.length; -+ invalid_range_end = valid_range_begin + padded_len; -+ -+ return buf; -+} -+ -+static void assert_mem_in_valid_range(const uint8_t *ptr, const size_t len) -+{ -+ /* Ensure we've set up the range pointers properly. */ -+ assert_non_null(valid_range_begin); -+ assert_non_null(valid_range_end); -+ assert_non_null(invalid_range_end); -+ -+ /* -+ * Ensure the length isn't excessively large (a symptom of integer -+ * underflow). -+ */ -+ assert_in_range(len, 0, 0x1000); -+ -+ /* Ensure the memory is in our valid range. */ -+ assert_in_range(ptr, valid_range_begin, valid_range_end); -+ assert_in_range(ptr + len, valid_range_begin, valid_range_end); -+} -+ -+/* -+ * This function takes a pointer to volatile to allow it to be called from the -+ * ct_memcmp() wrapper. -+ */ -+static void assert_mem_outside_invalid_range(const volatile uint8_t *ptr, -+ const size_t len) -+{ -+ const LargestIntegralType _valid_range_end -+ = cast_ptr_to_largest_integral_type(valid_range_end); -+ const LargestIntegralType _invalid_range_end -+ = cast_ptr_to_largest_integral_type(invalid_range_end); -+ const LargestIntegralType _ptr = cast_ptr_to_largest_integral_type(ptr); -+ const LargestIntegralType _len = cast_to_largest_integral_type(len); -+ -+ /* Ensure we've set up the range pointers properly. */ -+ assert_non_null(valid_range_begin); -+ assert_non_null(valid_range_end); -+ assert_non_null(invalid_range_end); -+ -+ /* -+ * Ensure the length isn't excessively large (a symptom of integer -+ * underflow). -+ */ -+ assert_in_range(len, 0, 0x1000); -+ -+ /* Ensure the memory is outside the invalid range. */ -+ if (_ptr < _invalid_range_end && _ptr + _len > _valid_range_end) { -+ fail(); -+ } -+} -+ -+/***************************************************************************** -+ * wrapped functions -+ *****************************************************************************/ -+ -+krb5_keyblock dummy_key; -+ -+krb5_error_code __wrap_krb5_auth_con_getlocalsubkey(krb5_context context, -+ krb5_auth_context auth_context, -+ krb5_keyblock **keyblock); -+krb5_error_code __wrap_krb5_auth_con_getlocalsubkey(krb5_context context, -+ krb5_auth_context auth_context, -+ krb5_keyblock **keyblock) -+{ -+ *keyblock = &dummy_key; -+ return 0; -+} -+ -+void __wrap_krb5_free_keyblock(krb5_context context, -+ krb5_keyblock *keyblock); -+void __wrap_krb5_free_keyblock(krb5_context context, -+ krb5_keyblock *keyblock) -+{ -+ assert_ptr_equal(&dummy_key, keyblock); -+} -+ -+struct krb5_crypto_data dummy_crypto; -+ -+krb5_error_code __wrap_krb5_crypto_init(krb5_context context, -+ const krb5_keyblock *key, -+ krb5_enctype etype, -+ krb5_crypto *crypto); -+krb5_error_code __wrap_krb5_crypto_init(krb5_context context, -+ const krb5_keyblock *key, -+ krb5_enctype etype, -+ krb5_crypto *crypto) -+{ -+ static const LargestIntegralType etypes[] = {ETYPE_DES3_CBC_NONE, 0}; -+ -+ assert_ptr_equal(&dummy_key, key); -+ assert_in_set(etype, etypes, ARRAY_SIZE(etypes)); -+ -+ *crypto = &dummy_crypto; -+ -+ return 0; -+} -+ -+krb5_error_code __wrap_krb5_decrypt(krb5_context context, -+ krb5_crypto crypto, -+ unsigned usage, -+ void *data, -+ size_t len, -+ krb5_data *result); -+krb5_error_code __wrap_krb5_decrypt(krb5_context context, -+ krb5_crypto crypto, -+ unsigned usage, -+ void *data, -+ size_t len, -+ krb5_data *result) -+{ -+ assert_ptr_equal(&dummy_crypto, crypto); -+ assert_int_equal(KRB5_KU_USAGE_SEAL, usage); -+ -+ assert_mem_in_valid_range(data, len); -+ -+ check_expected(len); -+ check_expected_ptr(data); -+ -+ result->data = malloc(len); -+ assert_non_null(result->data); -+ result->length = len; -+ -+ memcpy(result->data, data, len); -+ -+ return 0; -+} -+ -+krb5_error_code __wrap_krb5_decrypt_ivec(krb5_context context, -+ krb5_crypto crypto, -+ unsigned usage, -+ void *data, -+ size_t len, -+ krb5_data *result, -+ void *ivec); -+krb5_error_code __wrap_krb5_decrypt_ivec(krb5_context context, -+ krb5_crypto crypto, -+ unsigned usage, -+ void *data, -+ size_t len, -+ krb5_data *result, -+ void *ivec) -+{ -+ assert_ptr_equal(&dummy_crypto, crypto); -+ assert_int_equal(KRB5_KU_USAGE_SEQ, usage); -+ -+ assert_mem_in_valid_range(data, len); -+ -+ assert_int_equal(8, len); -+ check_expected_ptr(data); -+ check_expected_ptr(ivec); -+ -+ result->data = malloc(len); -+ assert_non_null(result->data); -+ result->length = len; -+ -+ memcpy(result->data, data, len); -+ -+ return 0; -+} -+ -+krb5_error_code __wrap_krb5_verify_checksum(krb5_context context, -+ krb5_crypto crypto, -+ krb5_key_usage usage, -+ void *data, -+ size_t len, -+ Checksum *cksum); -+krb5_error_code __wrap_krb5_verify_checksum(krb5_context context, -+ krb5_crypto crypto, -+ krb5_key_usage usage, -+ void *data, -+ size_t len, -+ Checksum *cksum) -+{ -+ assert_ptr_equal(&dummy_crypto, crypto); -+ assert_int_equal(KRB5_KU_USAGE_SIGN, usage); -+ -+ assert_mem_in_valid_range(data, len); -+ -+ check_expected(len); -+ check_expected_ptr(data); -+ -+ assert_non_null(cksum); -+ assert_int_equal(CKSUMTYPE_HMAC_SHA1_DES3, cksum->cksumtype); -+ assert_int_equal(20, cksum->checksum.length); -+ check_expected_ptr(cksum->checksum.data); -+ -+ return 0; -+} -+ -+krb5_error_code __wrap_krb5_crypto_destroy(krb5_context context, -+ krb5_crypto crypto); -+krb5_error_code __wrap_krb5_crypto_destroy(krb5_context context, -+ krb5_crypto crypto) -+{ -+ assert_ptr_equal(&dummy_crypto, crypto); -+ -+ return 0; -+} -+ -+ -+int __wrap_der_get_length(const unsigned char *p, -+ size_t len, -+ size_t *val, -+ size_t *size); -+int __real_der_get_length(const unsigned char *p, -+ size_t len, -+ size_t *val, -+ size_t *size); -+int __wrap_der_get_length(const unsigned char *p, -+ size_t len, -+ size_t *val, -+ size_t *size) -+{ -+ assert_mem_in_valid_range(p, len); -+ -+ return __real_der_get_length(p, len, val, size); -+} -+ -+int __wrap_ct_memcmp(const volatile void * volatile p1, -+ const volatile void * volatile p2, -+ size_t len); -+int __real_ct_memcmp(const volatile void * volatile p1, -+ const volatile void * volatile p2, -+ size_t len); -+int __wrap_ct_memcmp(const volatile void * volatile p1, -+ const volatile void * volatile p2, -+ size_t len) -+{ -+ assert_mem_outside_invalid_range(p1, len); -+ assert_mem_outside_invalid_range(p2, len); -+ -+ return __real_ct_memcmp(p1, p2, len); -+} -+ -+void *__wrap_malloc(size_t size); -+void *__real_malloc(size_t size); -+void *__wrap_malloc(size_t size) -+{ -+ /* -+ * Ensure the length isn't excessively large (a symptom of integer -+ * underflow). -+ */ -+ assert_in_range(size, 0, 0x10000); -+ -+ return __real_malloc(size); -+} -+ -+/***************************************************************************** -+ * Mock implementations -+ *****************************************************************************/ -+ -+/* -+ * Set the globals used by the mocked functions to a known and consistent state -+ * -+ */ -+static void init_mock_results(TALLOC_CTX *mem_ctx) -+{ -+ dummy_key.keytype = KRB5_ENCTYPE_DES3_CBC_MD5; -+ dummy_key.keyvalue.data = NULL; -+ dummy_key.keyvalue.length = 0; -+ -+ dummy_crypto = (struct krb5_crypto_data) {0}; -+ -+ valid_range_begin = NULL; -+ valid_range_end = NULL; -+ invalid_range_end = NULL; -+} -+ -+/***************************************************************************** -+ * Unit test set up and tear down -+ *****************************************************************************/ -+ -+struct context { -+ gss_ctx_id_t context_handle; -+}; -+ -+static int setup(void **state) { -+ struct context *ctx = NULL; -+ krb5_context context = NULL; -+ OM_uint32 major_status; -+ OM_uint32 minor_status; -+ krb5_error_code code; -+ -+ ctx = talloc_zero(NULL, struct context); -+ assert_non_null(ctx); -+ -+ init_mock_results(ctx); -+ -+ code = _gsskrb5_init(&context); -+ assert_int_equal(0, code); -+ -+ major_status = _gsskrb5_create_ctx(&minor_status, -+ &ctx->context_handle, -+ context, -+ GSS_C_NO_CHANNEL_BINDINGS, -+ ACCEPTOR_START); -+ assert_int_equal(GSS_S_COMPLETE, major_status); -+ -+ *state = ctx; -+ return 0; -+} -+ -+static int teardown(void **state) { -+ struct context *ctx = *state; -+ OM_uint32 major_status; -+ OM_uint32 minor_status; -+ -+ major_status = _gsskrb5_delete_sec_context(&minor_status, -+ &ctx->context_handle, -+ GSS_C_NO_BUFFER); -+ assert_int_equal(GSS_S_COMPLETE, major_status); -+ -+ TALLOC_FREE(ctx); -+ return 0; -+} -+ -+/***************************************************************************** -+ * _gsskrb5_unwrap unit tests -+ *****************************************************************************/ -+ -+static void test_unwrap_dce_style_missing_payload(void **state) { -+ struct context *ctx = *state; -+ OM_uint32 major_status; -+ OM_uint32 minor_status; -+ gsskrb5_ctx gss_ctx; -+ gss_buffer_desc input = {0}; -+ gss_buffer_desc output = {0}; -+ int conf_state; -+ gss_qop_t qop_state; -+ -+ /* See RFC 1964 for token format. */ -+ static const uint8_t data[] = { -+ 0x60, /* ASN.1 Application tag */ -+ 0x37, /* total length */ -+ 0x06, /* OBJECT IDENTIFIER */ -+ 0x09, /* mech length */ -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */ -+ 0x02, 0x01, /* TOK_ID */ -+ 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */ -+ 0xff, 0xff, /* SEAL_ALG (none) */ -+ 0xff, 0xff, /* Filler */ -+ 0xa0, 0xa1, 0xa2, 0xa3, /* encrypted sequence number */ -+ 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */ -+ /* checksum */ -+ 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, -+ 0xa9, 0xaa, 0xab, 0xac, 0xad, -+ 0xae, 0xaf, 0xb0, 0xb1, 0xb2, -+ 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, -+ }; -+ -+ input = get_input_buffer(ctx, data, sizeof(data), 22); -+ -+ gss_ctx = (gsskrb5_ctx) ctx->context_handle; -+ gss_ctx->flags |= GSS_C_DCE_STYLE; -+ -+ major_status = _gsskrb5_unwrap(&minor_status, -+ ctx->context_handle, -+ &input, -+ &output, -+ &conf_state, -+ &qop_state); -+ assert_int_equal(GSS_S_BAD_MECH, major_status); -+} -+ -+static void test_unwrap_dce_style_valid(void **state) { -+ struct context *ctx = *state; -+ OM_uint32 major_status; -+ OM_uint32 minor_status; -+ gsskrb5_ctx gss_ctx; -+ gss_buffer_desc input = {0}; -+ gss_buffer_desc output = {0}; -+ int conf_state; -+ gss_qop_t qop_state; -+ -+ /* See RFC 1964 for token format. */ -+ static const uint8_t data[] = { -+ 0x60, /* ASN.1 Application tag */ -+ 0x37, /* total length */ -+ 0x06, /* OBJECT IDENTIFIER */ -+ 0x09, /* mech length */ -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */ -+ 0x02, 0x01, /* TOK_ID */ -+ 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */ -+ 0xff, 0xff, /* SEAL_ALG (none) */ -+ 0xff, 0xff, /* Filler */ -+ 0xa0, 0xa1, 0xa2, 0xa3, /* encrypted sequence number */ -+ 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */ -+ /* checksum */ -+ 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, -+ 0xa9, 0xaa, 0xab, 0xac, 0xad, -+ 0xae, 0xaf, 0xb0, 0xb1, 0xb2, -+ 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, -+ /* unused */ -+ 0xb8, 0xb9, 0xba, 0xbb, -+ 0xbc, 0xbd, 0xbe, -+ 0x00, /* padding byte */ -+ }; -+ -+ input = get_input_buffer(ctx, data, sizeof(data), 57); -+ -+ gss_ctx = (gsskrb5_ctx) ctx->context_handle; -+ gss_ctx->flags |= GSS_C_DCE_STYLE; -+ -+ expect_value(__wrap_krb5_decrypt_ivec, data, (uint8_t *)input.value + 21); -+ expect_memory(__wrap_krb5_decrypt_ivec, ivec, -+ (uint8_t *)input.value + 29, DES_CBLOCK_LEN); -+ -+ expect_value(__wrap_krb5_verify_checksum, len, 16); -+ expect_value(__wrap_krb5_verify_checksum, data, (uint8_t *)input.value + 41); -+ expect_memory(__wrap_krb5_verify_checksum, cksum->checksum.data, -+ (uint8_t *)input.value + 29, 20); -+ -+ major_status = _gsskrb5_unwrap(&minor_status, -+ ctx->context_handle, -+ &input, -+ &output, -+ &conf_state, -+ &qop_state); -+ assert_int_equal(GSS_S_COMPLETE, major_status); -+ -+ assert_int_equal(0, conf_state); -+ assert_int_equal(GSS_C_QOP_DEFAULT, qop_state); -+ -+ assert_int_equal(output.length, 0); -+ -+ major_status = gss_release_buffer(&minor_status, &output); -+ assert_int_equal(GSS_S_COMPLETE, major_status); -+} -+ -+static void test_unwrap_dce_style_with_seal_missing_payload(void **state) { -+ struct context *ctx = *state; -+ OM_uint32 major_status; -+ OM_uint32 minor_status; -+ gsskrb5_ctx gss_ctx; -+ gss_buffer_desc input = {0}; -+ gss_buffer_desc output = {0}; -+ int conf_state; -+ gss_qop_t qop_state; -+ -+ /* See RFC 1964 for token format. */ -+ static const uint8_t data[] = { -+ 0x60, /* ASN.1 Application tag */ -+ 0x37, /* total length */ -+ 0x06, /* OBJECT IDENTIFIER */ -+ 0x09, /* mech length */ -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */ -+ 0x02, 0x01, /* TOK_ID */ -+ 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */ -+ 0x02, 0x00, /* SEAL_ALG (DES3-KD) */ -+ 0xff, 0xff, /* Filler */ -+ 0xa0, 0xa1, 0xa2, 0xa3, /* encrypted sequence number */ -+ 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */ -+ /* checksum */ -+ 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, -+ 0xa9, 0xaa, 0xab, 0xac, 0xad, -+ 0xae, 0xaf, 0xb0, 0xb1, 0xb2, -+ 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, -+ }; -+ -+ input = get_input_buffer(ctx, data, sizeof(data), 22); -+ -+ gss_ctx = (gsskrb5_ctx) ctx->context_handle; -+ gss_ctx->flags |= GSS_C_DCE_STYLE; -+ -+ major_status = _gsskrb5_unwrap(&minor_status, -+ ctx->context_handle, -+ &input, -+ &output, -+ &conf_state, -+ &qop_state); -+ assert_int_equal(GSS_S_BAD_MECH, major_status); -+} -+ -+static void test_unwrap_dce_style_with_seal_valid(void **state) { -+ struct context *ctx = *state; -+ OM_uint32 major_status; -+ OM_uint32 minor_status; -+ gsskrb5_ctx gss_ctx; -+ gss_buffer_desc input = {0}; -+ gss_buffer_desc output = {0}; -+ int conf_state; -+ gss_qop_t qop_state; -+ -+ /* See RFC 1964 for token format. */ -+ static const uint8_t data[] = { -+ 0x60, /* ASN.1 Application tag */ -+ 0x37, /* total length */ -+ 0x06, /* OBJECT IDENTIFIER */ -+ 0x09, /* mech length */ -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */ -+ 0x02, 0x01, /* TOK_ID */ -+ 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */ -+ 0x02, 0x00, /* SEAL_ALG (DES3-KD) */ -+ 0xff, 0xff, /* Filler */ -+ 0xa0, 0xa1, 0xa2, 0xa3, /* encrypted sequence number */ -+ 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */ -+ /* checksum */ -+ 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, -+ 0xa9, 0xaa, 0xab, 0xac, 0xad, -+ 0xae, 0xaf, 0xb0, 0xb1, 0xb2, -+ 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, -+ /* unused */ -+ 0xb8, 0xb9, 0xba, 0xbb, -+ 0xbc, 0xbd, 0xbe, -+ 0x00, /* padding byte */ -+ }; -+ -+ input = get_input_buffer(ctx, data, sizeof(data), 57); -+ -+ gss_ctx = (gsskrb5_ctx) ctx->context_handle; -+ gss_ctx->flags |= GSS_C_DCE_STYLE; -+ -+ expect_value(__wrap_krb5_decrypt, len, 8); -+ expect_value(__wrap_krb5_decrypt, data, (uint8_t *)input.value + 49); -+ -+ expect_value(__wrap_krb5_decrypt_ivec, data, (uint8_t *)input.value + 21); -+ expect_memory(__wrap_krb5_decrypt_ivec, ivec, -+ (uint8_t *)input.value + 29, DES_CBLOCK_LEN); -+ -+ expect_value(__wrap_krb5_verify_checksum, len, 16); -+ expect_value(__wrap_krb5_verify_checksum, data, (uint8_t *)input.value + 41); -+ expect_memory(__wrap_krb5_verify_checksum, cksum->checksum.data, -+ (uint8_t *)input.value + 29, 20); -+ -+ major_status = _gsskrb5_unwrap(&minor_status, -+ ctx->context_handle, -+ &input, -+ &output, -+ &conf_state, -+ &qop_state); -+ assert_int_equal(GSS_S_COMPLETE, major_status); -+ -+ assert_int_equal(1, conf_state); -+ assert_int_equal(GSS_C_QOP_DEFAULT, qop_state); -+ -+ assert_int_equal(output.length, 0); -+ -+ major_status = gss_release_buffer(&minor_status, &output); -+ assert_int_equal(GSS_S_COMPLETE, major_status); -+} -+ -+static void test_unwrap_missing_8_bytes(void **state) { -+ struct context *ctx = *state; -+ OM_uint32 major_status; -+ OM_uint32 minor_status; -+ gss_buffer_desc input = {0}; -+ gss_buffer_desc output = {0}; -+ int conf_state; -+ gss_qop_t qop_state; -+ -+ /* See RFC 1964 for token format. */ -+ static const uint8_t data[] = { -+ 0x60, /* ASN.1 Application tag */ -+ 0x2f, /* total length */ -+ 0x06, /* OBJECT IDENTIFIER */ -+ 0x09, /* mech length */ -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */ -+ 0x02, 0x01, /* TOK_ID */ -+ 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */ -+ 0xff, 0xff, /* SEAL_ALG (none) */ -+ 0xff, 0xff, /* Filler */ -+ 0xa0, 0xa1, 0xa2, 0xa3, /* encrypted sequence number */ -+ 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */ -+ /* checksum */ -+ 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, -+ 0xa9, 0xaa, 0xab, 0xac, 0xad, -+ 0xae, 0xaf, 0xb0, 0xb1, 0xb2, -+ 0xb3, 0xb4, 0xb5, 0xb6, 0x00, /* padding byte */ -+ }; -+ -+ input = get_input_buffer(ctx, data, sizeof(data), 49); -+ -+ /* -+ * A fixed unwrap_des3() should fail before these wrappers are called, -+ * but we want the wrappers to have access to any required values in the -+ * event that they are called. Specifying WILL_RETURN_ONCE avoids a test -+ * failure if these values remain unused. -+ */ -+ expect_value_count(__wrap_krb5_decrypt_ivec, data, -+ (uint8_t *)input.value + 21, -+ WILL_RETURN_ONCE); -+ expect_memory_count(__wrap_krb5_decrypt_ivec, ivec, -+ (uint8_t *)input.value + 29, DES_CBLOCK_LEN, -+ WILL_RETURN_ONCE); -+ -+ expect_value_count(__wrap_krb5_verify_checksum, len, 8, WILL_RETURN_ONCE); -+ expect_value_count(__wrap_krb5_verify_checksum, data, -+ (uint8_t *)input.value + 41, -+ WILL_RETURN_ONCE); -+ expect_memory_count(__wrap_krb5_verify_checksum, cksum->checksum.data, -+ (uint8_t *)input.value + 29, 20, -+ WILL_RETURN_ONCE); -+ -+ major_status = _gsskrb5_unwrap(&minor_status, -+ ctx->context_handle, -+ &input, -+ &output, -+ &conf_state, -+ &qop_state); -+ assert_int_equal(GSS_S_BAD_MECH, major_status); -+} -+ -+static void test_unwrap_missing_payload(void **state) { -+ struct context *ctx = *state; -+ OM_uint32 major_status; -+ OM_uint32 minor_status; -+ gss_buffer_desc input = {0}; -+ gss_buffer_desc output = {0}; -+ int conf_state; -+ gss_qop_t qop_state; -+ -+ /* See RFC 1964 for token format. */ -+ static const uint8_t data[] = { -+ 0x60, /* ASN.1 Application tag */ -+ 0x14, /* total length */ -+ 0x06, /* OBJECT IDENTIFIER */ -+ 0x09, /* mech length */ -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */ -+ 0x02, 0x01, /* TOK_ID */ -+ 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */ -+ 0xff, 0xff, /* SEAL_ALG (none) */ -+ 0xff, 0xff, /* Filler */ -+ 0x00, 0xa1, 0xa2, 0xa3, /* padding byte / encrypted sequence number */ -+ 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */ -+ /* checksum */ -+ 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, -+ 0xa9, 0xaa, 0xab, 0xac, 0xad, -+ 0xae, 0xaf, 0xb0, 0xb1, 0xb2, -+ 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, -+ }; -+ -+ input = get_input_buffer(ctx, data, sizeof(data), 22); -+ -+ major_status = _gsskrb5_unwrap(&minor_status, -+ ctx->context_handle, -+ &input, -+ &output, -+ &conf_state, -+ &qop_state); -+ assert_int_equal(GSS_S_BAD_MECH, major_status); -+} -+ -+static void test_unwrap_truncated_header_0(void **state) { -+ struct context *ctx = *state; -+ OM_uint32 major_status; -+ OM_uint32 minor_status; -+ gss_buffer_desc input = {0}; -+ gss_buffer_desc output = {0}; -+ int conf_state; -+ gss_qop_t qop_state; -+ -+ /* See RFC 1964 for token format. */ -+ static const uint8_t data[] = { -+ 0x60, /* ASN.1 Application tag */ -+ 0x00, /* total length */ -+ 0x06, /* OBJECT IDENTIFIER */ -+ }; -+ -+ input = get_input_buffer(ctx, data, sizeof(data), 2); -+ -+ major_status = _gsskrb5_unwrap(&minor_status, -+ ctx->context_handle, -+ &input, -+ &output, -+ &conf_state, -+ &qop_state); -+ assert_int_equal(GSS_S_DEFECTIVE_TOKEN, major_status); -+} -+ -+static void test_unwrap_truncated_header_1(void **state) { -+ struct context *ctx = *state; -+ OM_uint32 major_status; -+ OM_uint32 minor_status; -+ gss_buffer_desc input = {0}; -+ gss_buffer_desc output = {0}; -+ int conf_state; -+ gss_qop_t qop_state; -+ -+ /* See RFC 1964 for token format. */ -+ static const uint8_t data[] = { -+ 0x60, /* ASN.1 Application tag */ -+ 0x02, /* total length */ -+ 0x06, /* OBJECT IDENTIFIER */ -+ 0x09, /* mech length */ -+ 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, /* GSS KRB5 mech */ -+ }; -+ -+ input = get_input_buffer(ctx, data, sizeof(data), 4); -+ -+ major_status = _gsskrb5_unwrap(&minor_status, -+ ctx->context_handle, -+ &input, -+ &output, -+ &conf_state, -+ &qop_state); -+ assert_int_equal(GSS_S_BAD_MECH, major_status); -+} -+ -+static void test_unwrap_valid(void **state) { -+ struct context *ctx = *state; -+ OM_uint32 major_status; -+ OM_uint32 minor_status; -+ gss_buffer_desc input = {0}; -+ gss_buffer_desc output = {0}; -+ int conf_state; -+ gss_qop_t qop_state; -+ -+ /* See RFC 1964 for token format. */ -+ static const uint8_t data[] = { -+ 0x60, /* ASN.1 Application tag */ -+ 0x37, /* total length */ -+ 0x06, /* OBJECT IDENTIFIER */ -+ 0x09, /* mech length */ -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */ -+ 0x02, 0x01, /* TOK_ID */ -+ 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */ -+ 0xff, 0xff, /* SEAL_ALG (none) */ -+ 0xff, 0xff, /* Filler */ -+ 0xa0, 0xa1, 0xa2, 0xa3, /* encrypted sequence number */ -+ 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */ -+ /* checksum */ -+ 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, -+ 0xa9, 0xaa, 0xab, 0xac, 0xad, -+ 0xae, 0xaf, 0xb0, 0xb1, 0xb2, -+ 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, -+ /* unused */ -+ 0xb8, 0xb9, 0xba, 0xbb, -+ 0xbc, 0xbd, 0xbe, -+ 0x00, /* padding byte */ -+ }; -+ -+ input = get_input_buffer(ctx, data, sizeof(data), 57); -+ -+ expect_value(__wrap_krb5_decrypt_ivec, data, (uint8_t *)input.value + 21); -+ expect_memory(__wrap_krb5_decrypt_ivec, ivec, -+ (uint8_t *)input.value + 29, DES_CBLOCK_LEN); -+ -+ expect_value(__wrap_krb5_verify_checksum, len, 16); -+ expect_value(__wrap_krb5_verify_checksum, data, (uint8_t *)input.value + 41); -+ expect_memory(__wrap_krb5_verify_checksum, cksum->checksum.data, -+ (uint8_t *)input.value + 29, 20); -+ -+ major_status = _gsskrb5_unwrap(&minor_status, -+ ctx->context_handle, -+ &input, -+ &output, -+ &conf_state, -+ &qop_state); -+ assert_int_equal(GSS_S_COMPLETE, major_status); -+ -+ assert_int_equal(0, conf_state); -+ assert_int_equal(GSS_C_QOP_DEFAULT, qop_state); -+ -+ assert_int_equal(output.length, 0); -+ -+ major_status = gss_release_buffer(&minor_status, &output); -+ assert_int_equal(GSS_S_COMPLETE, major_status); -+} -+ -+static void test_unwrap_with_padding_truncated_0(void **state) { -+ struct context *ctx = *state; -+ OM_uint32 major_status; -+ OM_uint32 minor_status; -+ gss_buffer_desc input = {0}; -+ gss_buffer_desc output = {0}; -+ int conf_state; -+ gss_qop_t qop_state; -+ -+ /* See RFC 1964 for token format. */ -+ static const uint8_t data[] = { -+ 0x60, /* ASN.1 Application tag */ -+ 0x37, /* total length */ -+ 0x06, /* OBJECT IDENTIFIER */ -+ 0x09, /* mech length */ -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */ -+ 0x02, 0x01, /* TOK_ID */ -+ 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */ -+ 0xff, 0xff, /* SEAL_ALG (none) */ -+ 0xff, 0xff, /* Filler */ -+ 0xa0, 0xa1, 0xa2, 0xa3, /* encrypted sequence number */ -+ 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */ -+ /* checksum */ -+ 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, -+ 0xa9, 0xaa, 0xab, 0xac, 0xad, -+ 0xae, 0xaf, 0xb0, 0xb1, 0xb2, -+ 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, -+ /* unused */ -+ 0xb8, 0xb9, 0xba, 0xbb, -+ 0x04, 0x04, 0x04, 0x04, /* padding bytes */ -+ }; -+ -+ input = get_input_buffer(ctx, data, sizeof(data), 57); -+ -+ /* -+ * A fixed unwrap_des3() should fail before these wrappers are called, -+ * but we want the wrappers to have access to any required values in the -+ * event that they are called. Specifying WILL_RETURN_ONCE avoids a test -+ * failure if these values remain unused. -+ */ -+ expect_value_count(__wrap_krb5_decrypt_ivec, data, -+ (uint8_t *)input.value + 21, -+ WILL_RETURN_ONCE); -+ expect_memory_count(__wrap_krb5_decrypt_ivec, ivec, -+ (uint8_t *)input.value + 29, DES_CBLOCK_LEN, -+ WILL_RETURN_ONCE); -+ -+ expect_value_count(__wrap_krb5_verify_checksum, len, 16, WILL_RETURN_ONCE); -+ expect_value_count(__wrap_krb5_verify_checksum, data, -+ (uint8_t *)input.value + 41, -+ WILL_RETURN_ONCE); -+ expect_memory_count(__wrap_krb5_verify_checksum, cksum->checksum.data, -+ (uint8_t *)input.value + 29, 20, -+ WILL_RETURN_ONCE); -+ -+ major_status = _gsskrb5_unwrap(&minor_status, -+ ctx->context_handle, -+ &input, -+ &output, -+ &conf_state, -+ &qop_state); -+ assert_int_equal(GSS_S_BAD_MECH, major_status); -+} -+ -+static void test_unwrap_with_padding_truncated_1(void **state) { -+ struct context *ctx = *state; -+ OM_uint32 major_status; -+ OM_uint32 minor_status; -+ gss_buffer_desc input = {0}; -+ gss_buffer_desc output = {0}; -+ int conf_state; -+ gss_qop_t qop_state; -+ -+ /* See RFC 1964 for token format. */ -+ static const uint8_t data[] = { -+ 0x60, /* ASN.1 Application tag */ -+ 0x37, /* total length */ -+ 0x06, /* OBJECT IDENTIFIER */ -+ 0x09, /* mech length */ -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */ -+ 0x02, 0x01, /* TOK_ID */ -+ 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */ -+ 0xff, 0xff, /* SEAL_ALG (none) */ -+ 0xff, 0xff, /* Filler */ -+ 0x00, 0xa1, 0xa2, 0xa3, /* padding byte / encrypted sequence number */ -+ 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */ -+ /* checksum */ -+ 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, -+ 0xa9, 0xaa, 0xab, 0xac, 0xad, -+ 0xae, 0xaf, 0xb0, 0xb1, 0xb2, -+ 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, -+ /* padding bytes */ -+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, -+ }; -+ -+ input = get_input_buffer(ctx, data, sizeof(data), 57); -+ -+ /* -+ * A fixed unwrap_des3() should fail before these wrappers are called, -+ * but we want the wrappers to have access to any required values in the -+ * event that they are called. Specifying WILL_RETURN_ONCE avoids a test -+ * failure if these values remain unused. -+ */ -+ expect_value_count(__wrap_krb5_decrypt_ivec, data, -+ (uint8_t *)input.value + 21, -+ WILL_RETURN_ONCE); -+ expect_memory_count(__wrap_krb5_decrypt_ivec, ivec, -+ (uint8_t *)input.value + 29, DES_CBLOCK_LEN, -+ WILL_RETURN_ONCE); -+ -+ expect_value_count(__wrap_krb5_verify_checksum, len, 16, WILL_RETURN_ONCE); -+ expect_value_count(__wrap_krb5_verify_checksum, data, -+ (uint8_t *)input.value + 41, -+ WILL_RETURN_ONCE); -+ expect_memory_count(__wrap_krb5_verify_checksum, cksum->checksum.data, -+ (uint8_t *)input.value + 29, 20, -+ WILL_RETURN_ONCE); -+ -+ major_status = _gsskrb5_unwrap(&minor_status, -+ ctx->context_handle, -+ &input, -+ &output, -+ &conf_state, -+ &qop_state); -+ assert_int_equal(GSS_S_BAD_MECH, major_status); -+} -+ -+static void test_unwrap_with_padding_valid(void **state) { -+ struct context *ctx = *state; -+ OM_uint32 major_status; -+ OM_uint32 minor_status; -+ gss_buffer_desc input = {0}; -+ gss_buffer_desc output = {0}; -+ int conf_state; -+ gss_qop_t qop_state; -+ -+ /* See RFC 1964 for token format. */ -+ static const uint8_t data[] = { -+ 0x60, /* ASN.1 Application tag */ -+ 0x3f, /* total length */ -+ 0x06, /* OBJECT IDENTIFIER */ -+ 0x09, /* mech length */ -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */ -+ 0x02, 0x01, /* TOK_ID */ -+ 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */ -+ 0xff, 0xff, /* SEAL_ALG (none) */ -+ 0xff, 0xff, /* Filler */ -+ 0xa0, 0xa1, 0xa2, 0xa3, /* encrypted sequence number */ -+ 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */ -+ /* checksum */ -+ 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, -+ 0xa9, 0xaa, 0xab, 0xac, 0xad, -+ 0xae, 0xaf, 0xb0, 0xb1, 0xb2, -+ 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, -+ /* unused */ -+ 0xb8, 0xb9, 0xba, 0xbb, -+ 0xbc, 0xbd, 0xbe, 0xbf, -+ /* padding bytes */ -+ 0x08, 0x08, 0x08, 0x08, -+ 0x08, 0x08, 0x08, 0x08, -+ }; -+ -+ input = get_input_buffer(ctx, data, sizeof(data), 65); -+ -+ expect_value(__wrap_krb5_decrypt_ivec, data, (uint8_t *)input.value + 21); -+ expect_memory(__wrap_krb5_decrypt_ivec, ivec, -+ (uint8_t *)input.value + 29, DES_CBLOCK_LEN); -+ -+ expect_value(__wrap_krb5_verify_checksum, len, 24); -+ expect_value(__wrap_krb5_verify_checksum, data, (uint8_t *)input.value + 41); -+ expect_memory(__wrap_krb5_verify_checksum, cksum->checksum.data, -+ (uint8_t *)input.value + 29, 20); -+ -+ major_status = _gsskrb5_unwrap(&minor_status, -+ ctx->context_handle, -+ &input, -+ &output, -+ &conf_state, -+ &qop_state); -+ assert_int_equal(GSS_S_COMPLETE, major_status); -+ -+ assert_int_equal(0, conf_state); -+ assert_int_equal(GSS_C_QOP_DEFAULT, qop_state); -+ -+ assert_int_equal(output.length, 0); -+ -+ major_status = gss_release_buffer(&minor_status, &output); -+ assert_int_equal(GSS_S_COMPLETE, major_status); -+} -+ -+static void test_unwrap_with_seal_empty_token_valid(void **state) { -+ struct context *ctx = *state; -+ OM_uint32 major_status; -+ OM_uint32 minor_status; -+ gss_buffer_desc input = {0}; -+ gss_buffer_desc output = {0}; -+ int conf_state; -+ gss_qop_t qop_state; -+ -+ /* See RFC 1964 for token format. */ -+ static const uint8_t data[] = { -+ 0x60, /* ASN.1 Application tag */ -+ 0x37, /* total length */ -+ 0x06, /* OBJECT IDENTIFIER */ -+ 0x09, /* mech length */ -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */ -+ 0x02, 0x01, /* TOK_ID */ -+ 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */ -+ 0x02, 0x00, /* SEAL_ALG (DES3-KD) */ -+ 0xff, 0xff, /* Filler */ -+ 0xa0, 0xa1, 0xa2, 0xa3, /* encrypted sequence number */ -+ 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */ -+ /* checksum */ -+ 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, -+ 0xa9, 0xaa, 0xab, 0xac, 0xad, -+ 0xae, 0xaf, 0xb0, 0xb1, 0xb2, -+ 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, -+ /* unused */ -+ 0xb8, 0xb9, 0xba, 0xbb, -+ 0xbc, 0xbd, 0xbe, -+ 0x00, /* padding byte */ -+ }; -+ -+ input = get_input_buffer(ctx, data, sizeof(data), 57); -+ -+ expect_value(__wrap_krb5_decrypt, len, 8); -+ expect_value(__wrap_krb5_decrypt, data, (uint8_t *)input.value + 49); -+ -+ expect_value(__wrap_krb5_decrypt_ivec, data, (uint8_t *)input.value + 21); -+ expect_memory(__wrap_krb5_decrypt_ivec, ivec, -+ (uint8_t *)input.value + 29, DES_CBLOCK_LEN); -+ -+ expect_value(__wrap_krb5_verify_checksum, len, 16); -+ expect_value(__wrap_krb5_verify_checksum, data, (uint8_t *)input.value + 41); -+ expect_memory(__wrap_krb5_verify_checksum, cksum->checksum.data, -+ (uint8_t *)input.value + 29, 20); -+ -+ major_status = _gsskrb5_unwrap(&minor_status, -+ ctx->context_handle, -+ &input, -+ &output, -+ &conf_state, -+ &qop_state); -+ assert_int_equal(GSS_S_COMPLETE, major_status); -+ -+ assert_int_equal(1, conf_state); -+ assert_int_equal(GSS_C_QOP_DEFAULT, qop_state); -+ -+ assert_int_equal(output.length, 0); -+ -+ major_status = gss_release_buffer(&minor_status, &output); -+ assert_int_equal(GSS_S_COMPLETE, major_status); -+} -+ -+static void test_unwrap_with_seal_missing_payload(void **state) { -+ struct context *ctx = *state; -+ OM_uint32 major_status; -+ OM_uint32 minor_status; -+ gss_buffer_desc input = {0}; -+ gss_buffer_desc output = {0}; -+ int conf_state; -+ gss_qop_t qop_state; -+ -+ /* See RFC 1964 for token format. */ -+ static const uint8_t data[] = { -+ 0x60, /* ASN.1 Application tag */ -+ 0x14, /* total length */ -+ 0x06, /* OBJECT IDENTIFIER */ -+ 0x09, /* mech length */ -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */ -+ 0x02, 0x01, /* TOK_ID */ -+ 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */ -+ 0x02, 0x00, /* SEAL_ALG (DES3-KD) */ -+ 0xff, 0xff, /* Filler */ -+ 0xa0, 0xa1, 0xa2, 0xa3, /* encrypted sequence number */ -+ 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */ -+ /* checksum */ -+ 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, -+ 0xa9, 0xaa, 0xab, 0xac, 0xad, -+ 0xae, 0xaf, 0xb0, 0xb1, 0xb2, -+ 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, -+ }; -+ -+ input = get_input_buffer(ctx, data, sizeof(data), 22); -+ -+ major_status = _gsskrb5_unwrap(&minor_status, -+ ctx->context_handle, -+ &input, -+ &output, -+ &conf_state, -+ &qop_state); -+ assert_int_equal(GSS_S_BAD_MECH, major_status); -+} -+ -+static void test_unwrap_with_seal_valid(void **state) { -+ struct context *ctx = *state; -+ OM_uint32 major_status; -+ OM_uint32 minor_status; -+ gss_buffer_desc input = {0}; -+ gss_buffer_desc output = {0}; -+ int conf_state; -+ gss_qop_t qop_state; -+ -+ /* See RFC 1964 for token format. */ -+ static const uint8_t data[] = { -+ 0x60, /* ASN.1 Application tag */ -+ 0x3e, /* total length */ -+ 0x06, /* OBJECT IDENTIFIER */ -+ 0x09, /* mech length */ -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */ -+ 0x02, 0x01, /* TOK_ID */ -+ 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */ -+ 0x02, 0x00, /* SEAL_ALG (DES3-KD) */ -+ 0xff, 0xff, /* Filler */ -+ 0xa0, 0xa1, 0xa2, 0xa3, /* encrypted sequence number */ -+ 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */ -+ /* checksum */ -+ 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, -+ 0xa9, 0xaa, 0xab, 0xac, 0xad, -+ 0xae, 0xaf, 0xb0, 0xb1, 0xb2, -+ 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, -+ /* unused */ -+ 0xb8, 0xb9, 0xba, 0xbb, -+ 0xbc, 0xbd, 0xbe, 0xbf, -+ 0xc0, 0xc1, 0xc2, 0xc3, -+ 0xc4, 0xc5, -+ 0x00, /* padding byte */ -+ }; -+ -+ input = get_input_buffer(ctx, data, sizeof(data), 64); -+ -+ expect_value(__wrap_krb5_decrypt, len, 15); -+ expect_value(__wrap_krb5_decrypt, data, (uint8_t *)input.value + 49); -+ -+ expect_value(__wrap_krb5_decrypt_ivec, data, (uint8_t *)input.value + 21); -+ expect_memory(__wrap_krb5_decrypt_ivec, ivec, -+ (uint8_t *)input.value + 29, DES_CBLOCK_LEN); -+ -+ expect_value(__wrap_krb5_verify_checksum, len, 23); -+ expect_value(__wrap_krb5_verify_checksum, data, (uint8_t *)input.value + 41); -+ expect_memory(__wrap_krb5_verify_checksum, cksum->checksum.data, -+ (uint8_t *)input.value + 29, 20); -+ -+ major_status = _gsskrb5_unwrap(&minor_status, -+ ctx->context_handle, -+ &input, -+ &output, -+ &conf_state, -+ &qop_state); -+ assert_int_equal(GSS_S_COMPLETE, major_status); -+ -+ assert_int_equal(1, conf_state); -+ assert_int_equal(GSS_C_QOP_DEFAULT, qop_state); -+ -+ assert_int_equal(output.length, 7); -+ assert_memory_equal((uint8_t *)input.value + 57, output.value, output.length); -+ -+ major_status = gss_release_buffer(&minor_status, &output); -+ assert_int_equal(GSS_S_COMPLETE, major_status); -+} -+ -+int main(int argc, const char **argv) -+{ -+ static const struct CMUnitTest tests[] = { -+ cmocka_unit_test_setup_teardown( -+ test_unwrap_dce_style_missing_payload, setup, teardown), -+ cmocka_unit_test_setup_teardown( -+ test_unwrap_dce_style_valid, setup, teardown), -+ cmocka_unit_test_setup_teardown( -+ test_unwrap_dce_style_with_seal_missing_payload, setup, teardown), -+ cmocka_unit_test_setup_teardown( -+ test_unwrap_dce_style_with_seal_valid, setup, teardown), -+ cmocka_unit_test_setup_teardown( -+ test_unwrap_missing_8_bytes, setup, teardown), -+ cmocka_unit_test_setup_teardown( -+ test_unwrap_missing_payload, setup, teardown), -+ cmocka_unit_test_setup_teardown( -+ test_unwrap_truncated_header_0, setup, teardown), -+ cmocka_unit_test_setup_teardown( -+ test_unwrap_truncated_header_1, setup, teardown), -+ cmocka_unit_test_setup_teardown( -+ test_unwrap_valid, setup, teardown), -+ cmocka_unit_test_setup_teardown( -+ test_unwrap_with_padding_truncated_0, setup, teardown), -+ cmocka_unit_test_setup_teardown( -+ test_unwrap_with_padding_truncated_1, setup, teardown), -+ cmocka_unit_test_setup_teardown( -+ test_unwrap_with_padding_valid, setup, teardown), -+ cmocka_unit_test_setup_teardown( -+ test_unwrap_with_seal_empty_token_valid, setup, teardown), -+ cmocka_unit_test_setup_teardown( -+ test_unwrap_with_seal_missing_payload, setup, teardown), -+ cmocka_unit_test_setup_teardown( -+ test_unwrap_with_seal_valid, setup, teardown), -+ }; -+ -+ cmocka_set_message_output(CM_OUTPUT_SUBUNIT); -+ return cmocka_run_group_tests(tests, NULL, NULL); -+} -diff --git a/source4/auth/wscript_build b/source4/auth/wscript_build -index 381a7b19bf0..01b2f280609 100644 ---- a/source4/auth/wscript_build -+++ b/source4/auth/wscript_build -@@ -49,6 +49,27 @@ bld.SAMBA_BINARY('test_kerberos', - for_selftest=True - ) - -+bld.SAMBA_BINARY('test_heimdal_gensec_unwrap_des', -+ source='tests/heimdal_unwrap_des.c', -+ deps='cmocka talloc gssapi-subsystem', -+ local_include=False, -+ for_selftest=True, -+ enabled=(bld.CONFIG_SET('SAMBA4_USES_HEIMDAL') and -+ not bld.CONFIG_SET('USING_SYSTEM_GSSAPI')), -+ ldflags=''' -+ -Wl,--wrap,ct_memcmp -+ -Wl,--wrap,der_get_length -+ -Wl,--wrap,krb5_auth_con_getlocalsubkey -+ -Wl,--wrap,krb5_crypto_destroy -+ -Wl,--wrap,krb5_crypto_init -+ -Wl,--wrap,krb5_decrypt -+ -Wl,--wrap,krb5_decrypt_ivec -+ -Wl,--wrap,krb5_free_keyblock -+ -Wl,--wrap,krb5_verify_checksum -+ -Wl,--wrap,malloc -+ ''' -+) -+ - pytalloc_util = bld.pyembed_libname('pytalloc-util') - pyparam_util = bld.pyembed_libname('pyparam_util') - pyldb_util = bld.pyembed_libname('pyldb-util') --- -2.25.1 - - -From b4eefd391b2511d306637a050807c0d68aaaede1 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton <josephsutton@catalyst.net.nz> -Date: Wed, 12 Oct 2022 13:57:13 +1300 -Subject: [PATCH 04/11] CVE-2022-3437 source4/heimdal: Use constant-time - memcmp() for arcfour unwrap - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15134 - -Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> -Reviewed-by: Andrew Bartlett <abartlet@samba.org> - -[jsutton@samba.org Adapted to small differences in comparisons, and - removed erroneous duplicate code in conflicting region] ---- - source4/heimdal/lib/gssapi/krb5/arcfour.c | 24 +++++++---------------- - 1 file changed, 7 insertions(+), 17 deletions(-) - -diff --git a/source4/heimdal/lib/gssapi/krb5/arcfour.c b/source4/heimdal/lib/gssapi/krb5/arcfour.c -index a61f7686e95..c6b317ff683 100644 ---- a/source4/heimdal/lib/gssapi/krb5/arcfour.c -+++ b/source4/heimdal/lib/gssapi/krb5/arcfour.c -@@ -385,9 +385,9 @@ _gssapi_verify_mic_arcfour(OM_uint32 * minor_status, - _gsskrb5_decode_be_om_uint32(SND_SEQ, &seq_number); - - if (context_handle->more_flags & LOCAL) -- cmp = memcmp(&SND_SEQ[4], "\xff\xff\xff\xff", 4); -+ cmp = ct_memcmp(&SND_SEQ[4], "\xff\xff\xff\xff", 4); - else -- cmp = memcmp(&SND_SEQ[4], "\x00\x00\x00\x00", 4); -+ cmp = ct_memcmp(&SND_SEQ[4], "\x00\x00\x00\x00", 4); - - memset(SND_SEQ, 0, sizeof(SND_SEQ)); - if (cmp != 0) { -@@ -656,9 +656,9 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status, - _gsskrb5_decode_be_om_uint32(SND_SEQ, &seq_number); - - if (context_handle->more_flags & LOCAL) -- cmp = memcmp(&SND_SEQ[4], "\xff\xff\xff\xff", 4); -+ cmp = ct_memcmp(&SND_SEQ[4], "\xff\xff\xff\xff", 4); - else -- cmp = memcmp(&SND_SEQ[4], "\x00\x00\x00\x00", 4); -+ cmp = ct_memcmp(&SND_SEQ[4], "\x00\x00\x00\x00", 4); - - if (cmp != 0) { - *minor_status = 0; -@@ -1266,19 +1266,9 @@ _gssapi_unwrap_iov_arcfour(OM_uint32 *minor_status, - _gsskrb5_decode_be_om_uint32(snd_seq, &seq_number); - - if (ctx->more_flags & LOCAL) { -- cmp = memcmp(&snd_seq[4], "\xff\xff\xff\xff", 4); -+ cmp = ct_memcmp(&snd_seq[4], "\xff\xff\xff\xff", 4); - } else { -- cmp = memcmp(&snd_seq[4], "\x00\x00\x00\x00", 4); -- } -- if (cmp != 0) { -- *minor_status = 0; -- return GSS_S_BAD_MIC; -- } -- -- if (ctx->more_flags & LOCAL) { -- cmp = memcmp(&snd_seq[4], "\xff\xff\xff\xff", 4); -- } else { -- cmp = memcmp(&snd_seq[4], "\x00\x00\x00\x00", 4); -+ cmp = ct_memcmp(&snd_seq[4], "\x00\x00\x00\x00", 4); - } - if (cmp != 0) { - *minor_status = 0; -@@ -1353,7 +1343,7 @@ _gssapi_unwrap_iov_arcfour(OM_uint32 *minor_status, - return GSS_S_FAILURE; - } - -- cmp = memcmp(cksum_data, p0 + 16, 8); /* SGN_CKSUM */ -+ cmp = ct_memcmp(cksum_data, p0 + 16, 8); /* SGN_CKSUM */ - if (cmp != 0) { - *minor_status = 0; - return GSS_S_BAD_MIC; --- -2.25.1 - - -From 42b23fee3ad77aa29f6f7cbdcf8573756a68f95e Mon Sep 17 00:00:00 2001 -From: Joseph Sutton <josephsutton@catalyst.net.nz> -Date: Wed, 12 Oct 2022 13:57:55 +1300 -Subject: [PATCH 05/11] CVE-2022-3437 source4/heimdal: Use constant-time - memcmp() in unwrap_des3() - -The surrounding checks all use ct_memcmp(), so this one was presumably -meant to as well. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15134 - -Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> -Reviewed-by: Andrew Bartlett <abartlet@samba.org> ---- - source4/heimdal/lib/gssapi/krb5/unwrap.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/source4/heimdal/lib/gssapi/krb5/unwrap.c b/source4/heimdal/lib/gssapi/krb5/unwrap.c -index b3da35ee9e2..7111a7944fe 100644 ---- a/source4/heimdal/lib/gssapi/krb5/unwrap.c -+++ b/source4/heimdal/lib/gssapi/krb5/unwrap.c -@@ -227,7 +227,7 @@ unwrap_des3 - if (ret) - return ret; - -- if (memcmp (p, "\x04\x00", 2) != 0) /* HMAC SHA1 DES3_KD */ -+ if (ct_memcmp (p, "\x04\x00", 2) != 0) /* HMAC SHA1 DES3_KD */ - return GSS_S_BAD_SIG; - p += 2; - if (ct_memcmp (p, "\x02\x00", 2) == 0) { --- -2.25.1 - - -From 109a01fba88b641c988a04b14d911929ee82db92 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton <josephsutton@catalyst.net.nz> -Date: Wed, 12 Oct 2022 13:57:42 +1300 -Subject: [PATCH 06/11] CVE-2022-3437 source4/heimdal: Don't pass NULL pointers - to memcpy() in DES unwrap - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15134 - -Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> -Reviewed-by: Andrew Bartlett <abartlet@samba.org> ---- - source4/heimdal/lib/gssapi/krb5/unwrap.c | 14 ++++++++------ - 1 file changed, 8 insertions(+), 6 deletions(-) - -diff --git a/source4/heimdal/lib/gssapi/krb5/unwrap.c b/source4/heimdal/lib/gssapi/krb5/unwrap.c -index 7111a7944fe..9639091cb3a 100644 ---- a/source4/heimdal/lib/gssapi/krb5/unwrap.c -+++ b/source4/heimdal/lib/gssapi/krb5/unwrap.c -@@ -180,9 +180,10 @@ unwrap_des - output_message_buffer->value = malloc(output_message_buffer->length); - if(output_message_buffer->length != 0 && output_message_buffer->value == NULL) - return GSS_S_FAILURE; -- memcpy (output_message_buffer->value, -- p + 24, -- output_message_buffer->length); -+ if (output_message_buffer->value != NULL) -+ memcpy (output_message_buffer->value, -+ p + 24, -+ output_message_buffer->length); - return GSS_S_COMPLETE; - } - #endif -@@ -374,9 +375,10 @@ unwrap_des3 - output_message_buffer->value = malloc(output_message_buffer->length); - if(output_message_buffer->length != 0 && output_message_buffer->value == NULL) - return GSS_S_FAILURE; -- memcpy (output_message_buffer->value, -- p + 36, -- output_message_buffer->length); -+ if (output_message_buffer->value != NULL) -+ memcpy (output_message_buffer->value, -+ p + 36, -+ output_message_buffer->length); - return GSS_S_COMPLETE; - } - --- -2.25.1 - - -From d466a7c156b0797ae9d6eaf49b2f4fd5c9e3e7eb Mon Sep 17 00:00:00 2001 -From: Joseph Sutton <josephsutton@catalyst.net.nz> -Date: Mon, 15 Aug 2022 16:53:45 +1200 -Subject: [PATCH 07/11] CVE-2022-3437 source4/heimdal: Avoid undefined - behaviour in _gssapi_verify_pad() - -By decrementing 'pad' only when we know it's safe, we ensure we can't -stray backwards past the start of a buffer, which would be undefined -behaviour. - -In the previous version of the loop, 'i' is the number of bytes left to -check, and 'pad' is the current byte we're checking. 'pad' was -decremented at the end of each loop iteration. If 'i' was 1 (so we -checked the final byte), 'pad' could potentially be pointing to the -first byte of the input buffer, and the decrement would put it one -byte behind the buffer. - -That would be undefined behaviour. - -The patch changes it so that 'pad' is the byte we previously checked, -which allows us to ensure that we only decrement it when we know we -have a byte to check. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15134 - -Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> -Reviewed-by: Andrew Bartlett <abartlet@samba.org> ---- - source4/heimdal/lib/gssapi/krb5/decapsulate.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/source4/heimdal/lib/gssapi/krb5/decapsulate.c b/source4/heimdal/lib/gssapi/krb5/decapsulate.c -index 86085f56950..4e3fcd659e9 100644 ---- a/source4/heimdal/lib/gssapi/krb5/decapsulate.c -+++ b/source4/heimdal/lib/gssapi/krb5/decapsulate.c -@@ -193,13 +193,13 @@ _gssapi_verify_pad(gss_buffer_t wrapped_token, - if (wrapped_token->length < 1) - return GSS_S_BAD_MECH; - -- pad = (u_char *)wrapped_token->value + wrapped_token->length - 1; -- padlength = *pad; -+ pad = (u_char *)wrapped_token->value + wrapped_token->length; -+ padlength = pad[-1]; - - if (padlength > datalen) - return GSS_S_BAD_MECH; - -- for (i = padlength; i > 0 && *pad == padlength; i--, pad--) -+ for (i = padlength; i > 0 && *--pad == padlength; i--) - ; - if (i != 0) - return GSS_S_BAD_MIC; --- -2.25.1 - - -From 73e28ffbce8894c93374feb95c4ed1a87f2e6051 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton <josephsutton@catalyst.net.nz> -Date: Mon, 15 Aug 2022 16:53:55 +1200 -Subject: [PATCH 08/11] CVE-2022-3437 source4/heimdal: Check the result of - _gsskrb5_get_mech() - -We should make sure that the result of 'total_len - mech_len' won't -overflow, and that we don't memcmp() past the end of the buffer. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15134 - -Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> -Reviewed-by: Andrew Bartlett <abartlet@samba.org> ---- - selftest/knownfail.d/heimdal-des-overflow | 1 - - source4/heimdal/lib/gssapi/krb5/decapsulate.c | 4 ++++ - 2 files changed, 4 insertions(+), 1 deletion(-) - -diff --git a/selftest/knownfail.d/heimdal-des-overflow b/selftest/knownfail.d/heimdal-des-overflow -index 23acbb43d31..68b304530db 100644 ---- a/selftest/knownfail.d/heimdal-des-overflow -+++ b/selftest/knownfail.d/heimdal-des-overflow -@@ -3,7 +3,6 @@ - ^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_missing_8_bytes.none - ^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_missing_payload.none - ^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_truncated_header_0.none --^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_truncated_header_1.none - ^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_with_padding_truncated_0.none - ^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_with_padding_truncated_1.none - ^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_with_seal_missing_payload.none -diff --git a/source4/heimdal/lib/gssapi/krb5/decapsulate.c b/source4/heimdal/lib/gssapi/krb5/decapsulate.c -index 4e3fcd659e9..031a621eabc 100644 ---- a/source4/heimdal/lib/gssapi/krb5/decapsulate.c -+++ b/source4/heimdal/lib/gssapi/krb5/decapsulate.c -@@ -80,6 +80,10 @@ _gssapi_verify_mech_header(u_char **str, - - if (mech_len != mech->length) - return GSS_S_BAD_MECH; -+ if (mech_len > total_len) -+ return GSS_S_BAD_MECH; -+ if (p - *str > total_len - mech_len) -+ return GSS_S_BAD_MECH; - if (ct_memcmp(p, - mech->elements, - mech->length) != 0) --- -2.25.1 - - -From 3320c411c5cdf8bb9e4bc945e8bbe0947933d5e1 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton <josephsutton@catalyst.net.nz> -Date: Mon, 15 Aug 2022 16:54:23 +1200 -Subject: [PATCH 09/11] CVE-2022-3437 source4/heimdal: Check buffer length - against overflow for DES{,3} unwrap - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15134 - -Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> -Reviewed-by: Andrew Bartlett <abartlet@samba.org> ---- - selftest/knownfail.d/heimdal-des-overflow | 5 ----- - source4/heimdal/lib/gssapi/krb5/unwrap.c | 14 ++++++++++++++ - 2 files changed, 14 insertions(+), 5 deletions(-) - -diff --git a/selftest/knownfail.d/heimdal-des-overflow b/selftest/knownfail.d/heimdal-des-overflow -index 68b304530db..94a49bbee7f 100644 ---- a/selftest/knownfail.d/heimdal-des-overflow -+++ b/selftest/knownfail.d/heimdal-des-overflow -@@ -1,8 +1,3 @@ --^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_dce_style_missing_payload.none --^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_dce_style_with_seal_missing_payload.none --^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_missing_8_bytes.none --^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_missing_payload.none - ^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_truncated_header_0.none - ^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_with_padding_truncated_0.none - ^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_with_padding_truncated_1.none --^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_with_seal_missing_payload.none -diff --git a/source4/heimdal/lib/gssapi/krb5/unwrap.c b/source4/heimdal/lib/gssapi/krb5/unwrap.c -index 9639091cb3a..70d26a75ccf 100644 ---- a/source4/heimdal/lib/gssapi/krb5/unwrap.c -+++ b/source4/heimdal/lib/gssapi/krb5/unwrap.c -@@ -64,6 +64,8 @@ unwrap_des - - if (IS_DCE_STYLE(context_handle)) { - token_len = 22 + 8 + 15; /* 45 */ -+ if (input_message_buffer->length < token_len) -+ return GSS_S_BAD_MECH; - } else { - token_len = input_message_buffer->length; - } -@@ -76,6 +78,11 @@ unwrap_des - if (ret) - return ret; - -+ len = (p - (u_char *)input_message_buffer->value) -+ + 22 + 8; -+ if (input_message_buffer->length < len) -+ return GSS_S_BAD_MECH; -+ - if (memcmp (p, "\x00\x00", 2) != 0) - return GSS_S_BAD_SIG; - p += 2; -@@ -216,6 +223,8 @@ unwrap_des3 - - if (IS_DCE_STYLE(context_handle)) { - token_len = 34 + 8 + 15; /* 57 */ -+ if (input_message_buffer->length < token_len) -+ return GSS_S_BAD_MECH; - } else { - token_len = input_message_buffer->length; - } -@@ -228,6 +237,11 @@ unwrap_des3 - if (ret) - return ret; - -+ len = (p - (u_char *)input_message_buffer->value) -+ + 34 + 8; -+ if (input_message_buffer->length < len) -+ return GSS_S_BAD_MECH; -+ - if (ct_memcmp (p, "\x04\x00", 2) != 0) /* HMAC SHA1 DES3_KD */ - return GSS_S_BAD_SIG; - p += 2; --- -2.25.1 - - -From 9eb844370966625733f90d17a5d9ad611002567f Mon Sep 17 00:00:00 2001 -From: Joseph Sutton <josephsutton@catalyst.net.nz> -Date: Mon, 10 Oct 2022 20:33:09 +1300 -Subject: [PATCH 10/11] CVE-2022-3437 source4/heimdal: Check for overflow in - _gsskrb5_get_mech() - -If len_len is equal to total_len - 1 (i.e. the input consists only of a -0x60 byte and a length), the expression 'total_len - 1 - len_len - 1', -used as the 'len' parameter to der_get_length(), will overflow to -SIZE_MAX. Then der_get_length() will proceed to read, unconstrained, -whatever data follows in memory. Add a check to ensure that doesn't -happen. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15134 - -Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> -Reviewed-by: Andrew Bartlett <abartlet@samba.org> ---- - selftest/knownfail.d/heimdal-des-overflow | 1 - - source4/heimdal/lib/gssapi/krb5/decapsulate.c | 2 ++ - 2 files changed, 2 insertions(+), 1 deletion(-) - -diff --git a/selftest/knownfail.d/heimdal-des-overflow b/selftest/knownfail.d/heimdal-des-overflow -index 94a49bbee7f..a7416dc61d9 100644 ---- a/selftest/knownfail.d/heimdal-des-overflow -+++ b/selftest/knownfail.d/heimdal-des-overflow -@@ -1,3 +1,2 @@ --^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_truncated_header_0.none - ^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_with_padding_truncated_0.none - ^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_with_padding_truncated_1.none -diff --git a/source4/heimdal/lib/gssapi/krb5/decapsulate.c b/source4/heimdal/lib/gssapi/krb5/decapsulate.c -index 031a621eabc..d7b75a64222 100644 ---- a/source4/heimdal/lib/gssapi/krb5/decapsulate.c -+++ b/source4/heimdal/lib/gssapi/krb5/decapsulate.c -@@ -54,6 +54,8 @@ _gsskrb5_get_mech (const u_char *ptr, - e = der_get_length (p, total_len - 1, &len, &len_len); - if (e || 1 + len_len + len != total_len) - return -1; -+ if (total_len < 1 + len_len + 1) -+ return -1; - p += len_len; - if (*p++ != 0x06) - return -1; --- -2.25.1 - - -From 4c272bd20bbd512a63889e25f86506324957d232 Mon Sep 17 00:00:00 2001 -From: Joseph Sutton <josephsutton@catalyst.net.nz> -Date: Wed, 12 Oct 2022 13:57:33 +1300 -Subject: [PATCH 11/11] CVE-2022-3437 source4/heimdal: Pass correct length to - _gssapi_verify_pad() - -We later subtract 8 when calculating the length of the output message -buffer. If padlength is excessively high, this calculation can underflow -and result in a very large positive value. - -Now we properly constrain the value of padlength so underflow shouldn't -be possible. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15134 - -Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> -Reviewed-by: Andrew Bartlett <abartlet@samba.org> ---- - selftest/knownfail.d/heimdal-des-overflow | 2 -- - source4/heimdal/lib/gssapi/krb5/unwrap.c | 4 ++-- - 2 files changed, 2 insertions(+), 4 deletions(-) - delete mode 100644 selftest/knownfail.d/heimdal-des-overflow - -diff --git a/selftest/knownfail.d/heimdal-des-overflow b/selftest/knownfail.d/heimdal-des-overflow -deleted file mode 100644 -index a7416dc61d9..00000000000 ---- a/selftest/knownfail.d/heimdal-des-overflow -+++ /dev/null -@@ -1,2 +0,0 @@ --^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_with_padding_truncated_0.none --^samba.unittests.auth.heimdal_gensec_unwrap_des.test_unwrap_with_padding_truncated_1.none -diff --git a/source4/heimdal/lib/gssapi/krb5/unwrap.c b/source4/heimdal/lib/gssapi/krb5/unwrap.c -index 70d26a75ccf..ed8f7d78ffa 100644 ---- a/source4/heimdal/lib/gssapi/krb5/unwrap.c -+++ b/source4/heimdal/lib/gssapi/krb5/unwrap.c -@@ -124,7 +124,7 @@ unwrap_des - } else { - /* check pad */ - ret = _gssapi_verify_pad(input_message_buffer, -- input_message_buffer->length - len, -+ input_message_buffer->length - len - 8, - &padlength); - if (ret) - return ret; -@@ -289,7 +289,7 @@ unwrap_des3 - } else { - /* check pad */ - ret = _gssapi_verify_pad(input_message_buffer, -- input_message_buffer->length - len, -+ input_message_buffer->length - len - 8, - &padlength); - if (ret) - return ret; --- -2.25.1 - |