LCOV - code coverage report
Current view: top level - source4/auth/tests - heimdal_unwrap_des.c (source / functions) Hit Total Coverage
Test: coverage report for master 98b443d9 Lines: 432 433 99.8 %
Date: 2024-05-31 13:13:24 Functions: 31 31 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Unit tests for third_party/heimdal/lib/gssapi/krb5/unwrap.c
       3             :  *
       4             :  * Copyright (C) Catalyst.NET Ltd 2022
       5             :  *
       6             :  * This program is free software; you can redistribute it and/or modify
       7             :  * it under the terms of the GNU General Public License as published by
       8             :  * the Free Software Foundation; either version 3 of the License, or
       9             :  * (at your option) any later version.
      10             :  *
      11             :  * This program is distributed in the hope that it will be useful,
      12             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :  * GNU General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU General Public License
      17             :  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
      18             :  *
      19             :  */
      20             : 
      21             : /*
      22             :  * from cmocka.c:
      23             :  * These headers or their equivalents should be included prior to
      24             :  * including
      25             :  * this header file.
      26             :  *
      27             :  * #include <stdarg.h>
      28             :  * #include <stddef.h>
      29             :  * #include <setjmp.h>
      30             :  *
      31             :  * This allows test applications to use custom definitions of C standard
      32             :  * library functions and types.
      33             :  *
      34             :  */
      35             : 
      36             : #include <stdarg.h>
      37             : #include <stddef.h>
      38             : #include <setjmp.h>
      39             : 
      40             : #include <cmocka.h>
      41             : 
      42             : #include "includes.h"
      43             : #include "replace.h"
      44             : 
      45             : #include "../../../third_party/heimdal/lib/gssapi/gssapi/gssapi.h"
      46             : #include "gsskrb5_locl.h"
      47             : 
      48             : /******************************************************************************
      49             :  * Helper functions
      50             :  ******************************************************************************/
      51             : 
      52             : const uint8_t *valid_range_begin;
      53             : const uint8_t *valid_range_end;
      54             : const uint8_t *invalid_range_end;
      55             : 
      56             : /*
      57             :  * 'array_len' is the size of the passed in array. 'buffer_len' is the size to
      58             :  * report in the resulting buffer.
      59             :  */
      60          15 : static const gss_buffer_desc get_input_buffer(TALLOC_CTX *mem_ctx,
      61             :                                               const uint8_t array[],
      62             :                                               const size_t array_len,
      63             :                                               const size_t buffer_len)
      64             : {
      65          15 :         gss_buffer_desc buf;
      66             : 
      67             :         /* Add some padding to catch invalid memory accesses. */
      68          15 :         const size_t padding = 0x100;
      69          15 :         const size_t padded_len = array_len + padding;
      70             : 
      71          15 :         uint8_t *data = talloc_size(mem_ctx, padded_len);
      72          15 :         assert_non_null(data);
      73             : 
      74          15 :         memcpy(data, array, array_len);
      75          15 :         memset(data + array_len, 0, padding);
      76             : 
      77          15 :         assert_in_range(buffer_len, 0, array_len);
      78             : 
      79          15 :         buf.value = data;
      80          15 :         buf.length = buffer_len;
      81             : 
      82          15 :         valid_range_begin = buf.value;
      83          15 :         valid_range_end = valid_range_begin + buf.length;
      84          15 :         invalid_range_end = valid_range_begin + padded_len;
      85             : 
      86          15 :         return buf;
      87             : }
      88             : 
      89          40 : static void assert_mem_in_valid_range(const uint8_t *ptr, const size_t len)
      90             : {
      91             :         /* Ensure we've set up the range pointers properly. */
      92          40 :         assert_non_null(valid_range_begin);
      93          40 :         assert_non_null(valid_range_end);
      94          40 :         assert_non_null(invalid_range_end);
      95             : 
      96             :         /*
      97             :          * Ensure the length isn't excessively large (a symptom of integer
      98             :          * underflow).
      99             :          */
     100          40 :         assert_in_range(len, 0, 0x1000);
     101             : 
     102             :         /* Ensure the memory is in our valid range. */
     103          40 :         assert_in_range(ptr, valid_range_begin, valid_range_end);
     104          40 :         assert_in_range(ptr + len, valid_range_begin, valid_range_end);
     105          40 : }
     106             : 
     107             : /*
     108             :  * This function takes a pointer to volatile to allow it to be called from the
     109             :  * ct_memcmp() wrapper.
     110             :  */
     111         114 : static void assert_mem_outside_invalid_range(const volatile uint8_t *ptr,
     112             :                                              const size_t len)
     113             : {
     114         114 :         const LargestIntegralType _valid_range_end
     115         114 :                 = cast_ptr_to_largest_integral_type(valid_range_end);
     116         114 :         const LargestIntegralType _invalid_range_end
     117         114 :                 = cast_ptr_to_largest_integral_type(invalid_range_end);
     118         114 :         const LargestIntegralType _ptr = cast_ptr_to_largest_integral_type(ptr);
     119         114 :         const LargestIntegralType _len = cast_to_largest_integral_type(len);
     120             : 
     121             :         /* Ensure we've set up the range pointers properly. */
     122         114 :         assert_non_null(valid_range_begin);
     123         114 :         assert_non_null(valid_range_end);
     124         114 :         assert_non_null(invalid_range_end);
     125             : 
     126             :         /*
     127             :          * Ensure the length isn't excessively large (a symptom of integer
     128             :          * underflow).
     129             :          */
     130         114 :         assert_in_range(len, 0, 0x1000);
     131             : 
     132             :         /* Ensure the memory is outside the invalid range. */
     133         114 :         if (_ptr < _invalid_range_end && _ptr + _len > _valid_range_end) {
     134           0 :                 fail();
     135             :         }
     136         114 : }
     137             : 
     138             : /*****************************************************************************
     139             :  * wrapped functions
     140             :  *****************************************************************************/
     141             : 
     142             : krb5_keyblock dummy_key;
     143             : 
     144             : krb5_error_code __wrap_krb5_auth_con_getlocalsubkey(krb5_context context,
     145             :                                                     krb5_auth_context auth_context,
     146             :                                                     krb5_keyblock **keyblock);
     147          15 : krb5_error_code __wrap_krb5_auth_con_getlocalsubkey(krb5_context context,
     148             :                                                     krb5_auth_context auth_context,
     149             :                                                     krb5_keyblock **keyblock)
     150             : {
     151          15 :         *keyblock = &dummy_key;
     152          15 :         return 0;
     153             : }
     154             : 
     155             : void __wrap_krb5_free_keyblock(krb5_context context,
     156             :                         krb5_keyblock *keyblock);
     157          15 : void __wrap_krb5_free_keyblock(krb5_context context,
     158             :                         krb5_keyblock *keyblock)
     159             : {
     160          15 :         assert_ptr_equal(&dummy_key, keyblock);
     161          15 : }
     162             : 
     163             : struct krb5_crypto_data dummy_crypto;
     164             : 
     165             : krb5_error_code __wrap_krb5_crypto_init(krb5_context context,
     166             :                                         const krb5_keyblock *key,
     167             :                                         krb5_enctype etype,
     168             :                                         krb5_crypto *crypto);
     169          15 : krb5_error_code __wrap_krb5_crypto_init(krb5_context context,
     170             :                                         const krb5_keyblock *key,
     171             :                                         krb5_enctype etype,
     172             :                                         krb5_crypto *crypto)
     173             : {
     174          15 :         static const LargestIntegralType etypes[] = {ETYPE_DES3_CBC_NONE, 0};
     175             : 
     176          15 :         assert_ptr_equal(&dummy_key, key);
     177          15 :         assert_in_set(etype, etypes, ARRAY_SIZE(etypes));
     178             : 
     179          15 :         *crypto = &dummy_crypto;
     180             : 
     181          15 :         return 0;
     182             : }
     183             : 
     184             : krb5_error_code __wrap_krb5_decrypt(krb5_context context,
     185             :                                     krb5_crypto crypto,
     186             :                                     unsigned usage,
     187             :                                     void *data,
     188             :                                     size_t len,
     189             :                                     krb5_data *result);
     190           3 : krb5_error_code __wrap_krb5_decrypt(krb5_context context,
     191             :                                     krb5_crypto crypto,
     192             :                                     unsigned usage,
     193             :                                     void *data,
     194             :                                     size_t len,
     195             :                                     krb5_data *result)
     196             : {
     197           3 :         assert_ptr_equal(&dummy_crypto, crypto);
     198           3 :         assert_int_equal(KRB5_KU_USAGE_SEAL, usage);
     199             : 
     200           3 :         assert_mem_in_valid_range(data, len);
     201             : 
     202           3 :         check_expected(len);
     203           3 :         check_expected_ptr(data);
     204             : 
     205           3 :         result->data = malloc(len);
     206           3 :         assert_non_null(result->data);
     207           3 :         result->length = len;
     208             : 
     209           3 :         memcpy(result->data, data, len);
     210             : 
     211           3 :         return 0;
     212             : }
     213             : 
     214             : krb5_error_code __wrap_krb5_decrypt_ivec(krb5_context context,
     215             :                                          krb5_crypto crypto,
     216             :                                          unsigned usage,
     217             :                                          void *data,
     218             :                                          size_t len,
     219             :                                          krb5_data *result,
     220             :                                          void *ivec);
     221           6 : krb5_error_code __wrap_krb5_decrypt_ivec(krb5_context context,
     222             :                                          krb5_crypto crypto,
     223             :                                          unsigned usage,
     224             :                                          void *data,
     225             :                                          size_t len,
     226             :                                          krb5_data *result,
     227             :                                          void *ivec)
     228             : {
     229           6 :         assert_ptr_equal(&dummy_crypto, crypto);
     230           6 :         assert_int_equal(KRB5_KU_USAGE_SEQ, usage);
     231             : 
     232           6 :         assert_mem_in_valid_range(data, len);
     233             : 
     234           6 :         assert_int_equal(8, len);
     235           6 :         check_expected_ptr(data);
     236           6 :         check_expected_ptr(ivec);
     237             : 
     238           6 :         result->data = malloc(len);
     239           6 :         assert_non_null(result->data);
     240           6 :         result->length = len;
     241             : 
     242           6 :         memcpy(result->data, data, len);
     243             : 
     244           6 :         return 0;
     245             : }
     246             : 
     247             : krb5_error_code __wrap_krb5_verify_checksum(krb5_context context,
     248             :                                             krb5_crypto crypto,
     249             :                                             krb5_key_usage usage,
     250             :                                             void *data,
     251             :                                             size_t len,
     252             :                                             Checksum *cksum);
     253           6 : krb5_error_code __wrap_krb5_verify_checksum(krb5_context context,
     254             :                                             krb5_crypto crypto,
     255             :                                             krb5_key_usage usage,
     256             :                                             void *data,
     257             :                                             size_t len,
     258             :                                             Checksum *cksum)
     259             : {
     260           6 :         assert_ptr_equal(&dummy_crypto, crypto);
     261           6 :         assert_int_equal(KRB5_KU_USAGE_SIGN, usage);
     262             : 
     263           6 :         assert_mem_in_valid_range(data, len);
     264             : 
     265           6 :         check_expected(len);
     266           6 :         check_expected_ptr(data);
     267             : 
     268           6 :         assert_non_null(cksum);
     269           6 :         assert_int_equal(CKSUMTYPE_HMAC_SHA1_DES3, cksum->cksumtype);
     270           6 :         assert_int_equal(20, cksum->checksum.length);
     271           6 :         check_expected_ptr(cksum->checksum.data);
     272             : 
     273           6 :         return 0;
     274             : }
     275             : 
     276             : krb5_error_code __wrap_krb5_crypto_destroy(krb5_context context,
     277             :                                            krb5_crypto crypto);
     278          15 : krb5_error_code __wrap_krb5_crypto_destroy(krb5_context context,
     279             :                                            krb5_crypto crypto)
     280             : {
     281          15 :         assert_ptr_equal(&dummy_crypto, crypto);
     282             : 
     283          15 :         return 0;
     284             : }
     285             : 
     286             : 
     287             : int __wrap_der_get_length(const unsigned char *p,
     288             :                           size_t len,
     289             :                           size_t *val,
     290             :                           size_t *size);
     291             : int __real_der_get_length(const unsigned char *p,
     292             :                           size_t len,
     293             :                           size_t *val,
     294             :                           size_t *size);
     295          25 : int __wrap_der_get_length(const unsigned char *p,
     296             :                           size_t len,
     297             :                           size_t *val,
     298             :                           size_t *size)
     299             : {
     300          25 :         assert_mem_in_valid_range(p, len);
     301             : 
     302          25 :         return __real_der_get_length(p, len, val, size);
     303             : }
     304             : 
     305             : int __wrap_ct_memcmp(const volatile void * volatile p1,
     306             :                      const volatile void * volatile p2,
     307             :                      size_t len);
     308             : int __real_ct_memcmp(const volatile void * volatile p1,
     309             :                      const volatile void * volatile p2,
     310             :                      size_t len);
     311          57 : int __wrap_ct_memcmp(const volatile void * volatile p1,
     312             :                      const volatile void * volatile p2,
     313             :                      size_t len)
     314             : {
     315          57 :         assert_mem_outside_invalid_range(p1, len);
     316          57 :         assert_mem_outside_invalid_range(p2, len);
     317             : 
     318          57 :         return __real_ct_memcmp(p1, p2, len);
     319             : }
     320             : 
     321             : void *__wrap_malloc(size_t size);
     322             : void *__real_malloc(size_t size);
     323          32 : void *__wrap_malloc(size_t size)
     324             : {
     325             :         /*
     326             :          * Ensure the length isn't excessively large (a symptom of integer
     327             :          * underflow).
     328             :          */
     329          32 :         assert_in_range(size, 0, 0x10000);
     330             : 
     331          32 :         return __real_malloc(size);
     332             : }
     333             : 
     334             : /*****************************************************************************
     335             :  * Mock implementations
     336             :  *****************************************************************************/
     337             : 
     338             : /*
     339             :  * Set the globals used by the mocked functions to a known and consistent state
     340             :  *
     341             :  */
     342          15 : static void init_mock_results(TALLOC_CTX *mem_ctx)
     343             : {
     344          15 :         dummy_key.keytype = KRB5_ENCTYPE_DES3_CBC_MD5;
     345          15 :         dummy_key.keyvalue.data = NULL;
     346          15 :         dummy_key.keyvalue.length = 0;
     347             : 
     348          15 :         dummy_crypto = (struct krb5_crypto_data) {0};
     349             : 
     350          15 :         valid_range_begin = NULL;
     351          15 :         valid_range_end = NULL;
     352          15 :         invalid_range_end = NULL;
     353             : }
     354             : 
     355             : /*****************************************************************************
     356             :  * Unit test set up and tear down
     357             :  *****************************************************************************/
     358             : 
     359             : struct context {
     360             :         gss_ctx_id_t context_handle;
     361             : };
     362             : 
     363          15 : static int setup(void **state) {
     364          15 :         struct context *ctx = NULL;
     365          15 :         krb5_context context = NULL;
     366          15 :         OM_uint32 major_status;
     367          15 :         OM_uint32 minor_status;
     368          15 :         krb5_error_code code;
     369             : 
     370          15 :         ctx = talloc_zero(NULL, struct context);
     371          15 :         assert_non_null(ctx);
     372             : 
     373          15 :         init_mock_results(ctx);
     374             : 
     375          15 :         code = _gsskrb5_init(&context);
     376          15 :         assert_int_equal(0, code);
     377             : 
     378          15 :         major_status = _gsskrb5_create_ctx(&minor_status,
     379             :                                            &ctx->context_handle,
     380             :                                            context,
     381             :                                            GSS_C_NO_CHANNEL_BINDINGS,
     382             :                                            ACCEPTOR_START);
     383          15 :         assert_int_equal(GSS_S_COMPLETE, major_status);
     384             : 
     385          15 :         *state = ctx;
     386          15 :         return 0;
     387             : }
     388             : 
     389          15 : static int teardown(void **state) {
     390          15 :         struct context *ctx = *state;
     391          15 :         OM_uint32 major_status;
     392          15 :         OM_uint32 minor_status;
     393             : 
     394          15 :         major_status = _gsskrb5_delete_sec_context(&minor_status,
     395             :                                                    &ctx->context_handle,
     396             :                                                    GSS_C_NO_BUFFER);
     397          15 :         assert_int_equal(GSS_S_COMPLETE, major_status);
     398             : 
     399          15 :         TALLOC_FREE(ctx);
     400          15 :         return 0;
     401             : }
     402             : 
     403             : /*****************************************************************************
     404             :  * _gsskrb5_unwrap unit tests
     405             :  *****************************************************************************/
     406             : 
     407           1 : static void test_unwrap_dce_style_missing_payload(void **state) {
     408           1 :         struct context *ctx = *state;
     409           1 :         OM_uint32 major_status;
     410           1 :         OM_uint32 minor_status;
     411           1 :         gsskrb5_ctx gss_ctx;
     412           1 :         gss_buffer_desc input = {0};
     413           1 :         gss_buffer_desc output = {0};
     414           1 :         int conf_state;
     415           1 :         gss_qop_t qop_state;
     416             : 
     417             :         /* See RFC 1964 for token format. */
     418           1 :         static const uint8_t data[] = {
     419             :                 0x60, /* ASN.1 Application tag */
     420             :                 0x37, /* total length */
     421             :                 0x06, /* OBJECT IDENTIFIER */
     422             :                 0x09, /* mech length */
     423             :                 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */
     424             :                 0x02, 0x01, /* TOK_ID */
     425             :                 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */
     426             :                 0xff, 0xff, /* SEAL_ALG (none) */
     427             :                 0xff, 0xff, /* Filler */
     428             :                 0xa0, 0xa1, 0xa2, 0xa3, /* encrypted sequence number */
     429             :                 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */
     430             :                 /* checksum */
     431             :                 0xa4, 0xa5, 0xa6, 0xa7, 0xa8,
     432             :                 0xa9, 0xaa, 0xab, 0xac, 0xad,
     433             :                 0xae, 0xaf, 0xb0, 0xb1, 0xb2,
     434             :                 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
     435             :         };
     436             : 
     437           1 :         input = get_input_buffer(ctx, data, sizeof(data), 22);
     438             : 
     439           1 :         gss_ctx = (gsskrb5_ctx) ctx->context_handle;
     440           1 :         gss_ctx->flags |= GSS_C_DCE_STYLE;
     441             : 
     442           1 :         major_status = _gsskrb5_unwrap(&minor_status,
     443             :                                        ctx->context_handle,
     444             :                                        &input,
     445             :                                        &output,
     446             :                                        &conf_state,
     447             :                                        &qop_state);
     448           1 :         assert_int_equal(GSS_S_BAD_MECH, major_status);
     449           1 : }
     450             : 
     451           1 : static void test_unwrap_dce_style_valid(void **state) {
     452           1 :         struct context *ctx = *state;
     453           1 :         OM_uint32 major_status;
     454           1 :         OM_uint32 minor_status;
     455           1 :         gsskrb5_ctx gss_ctx;
     456           1 :         gss_buffer_desc input = {0};
     457           1 :         gss_buffer_desc output = {0};
     458           1 :         int conf_state;
     459           1 :         gss_qop_t qop_state;
     460             : 
     461             :         /* See RFC 1964 for token format. */
     462           1 :         static const uint8_t data[] = {
     463             :                 0x60, /* ASN.1 Application tag */
     464             :                 0x37, /* total length */
     465             :                 0x06, /* OBJECT IDENTIFIER */
     466             :                 0x09, /* mech length */
     467             :                 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */
     468             :                 0x02, 0x01, /* TOK_ID */
     469             :                 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */
     470             :                 0xff, 0xff, /* SEAL_ALG (none) */
     471             :                 0xff, 0xff, /* Filler */
     472             :                 0xa0, 0xa1, 0xa2, 0xa3, /* encrypted sequence number */
     473             :                 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */
     474             :                 /* checksum */
     475             :                 0xa4, 0xa5, 0xa6, 0xa7, 0xa8,
     476             :                 0xa9, 0xaa, 0xab, 0xac, 0xad,
     477             :                 0xae, 0xaf, 0xb0, 0xb1, 0xb2,
     478             :                 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
     479             :                 /* unused */
     480             :                 0xb8, 0xb9, 0xba, 0xbb,
     481             :                 0xbc, 0xbd, 0xbe,
     482             :                 0x00, /* padding byte */
     483             :         };
     484             : 
     485           1 :         input = get_input_buffer(ctx, data, sizeof(data), 57);
     486             : 
     487           1 :         gss_ctx = (gsskrb5_ctx) ctx->context_handle;
     488           1 :         gss_ctx->flags |= GSS_C_DCE_STYLE;
     489             : 
     490           1 :         expect_value(__wrap_krb5_decrypt_ivec, data, (uint8_t *)input.value + 21);
     491           1 :         expect_memory(__wrap_krb5_decrypt_ivec, ivec,
     492             :                       (uint8_t *)input.value + 29, DES_CBLOCK_LEN);
     493             : 
     494           1 :         expect_value(__wrap_krb5_verify_checksum, len, 16);
     495           1 :         expect_value(__wrap_krb5_verify_checksum, data, (uint8_t *)input.value + 41);
     496           1 :         expect_memory(__wrap_krb5_verify_checksum, cksum->checksum.data,
     497             :                       (uint8_t *)input.value + 29, 20);
     498             : 
     499           2 :         major_status = _gsskrb5_unwrap(&minor_status,
     500           1 :                                        ctx->context_handle,
     501             :                                        &input,
     502             :                                        &output,
     503             :                                        &conf_state,
     504             :                                        &qop_state);
     505           1 :         assert_int_equal(GSS_S_COMPLETE, major_status);
     506             : 
     507           1 :         assert_int_equal(0, conf_state);
     508           1 :         assert_int_equal(GSS_C_QOP_DEFAULT, qop_state);
     509             : 
     510           1 :         assert_int_equal(output.length, 0);
     511             : 
     512           1 :         major_status = gss_release_buffer(&minor_status, &output);
     513           1 :         assert_int_equal(GSS_S_COMPLETE, major_status);
     514           1 : }
     515             : 
     516           1 : static void test_unwrap_dce_style_with_seal_missing_payload(void **state) {
     517           1 :         struct context *ctx = *state;
     518           1 :         OM_uint32 major_status;
     519           1 :         OM_uint32 minor_status;
     520           1 :         gsskrb5_ctx gss_ctx;
     521           1 :         gss_buffer_desc input = {0};
     522           1 :         gss_buffer_desc output = {0};
     523           1 :         int conf_state;
     524           1 :         gss_qop_t qop_state;
     525             : 
     526             :         /* See RFC 1964 for token format. */
     527           1 :         static const uint8_t data[] = {
     528             :                 0x60, /* ASN.1 Application tag */
     529             :                 0x37, /* total length */
     530             :                 0x06, /* OBJECT IDENTIFIER */
     531             :                 0x09, /* mech length */
     532             :                 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */
     533             :                 0x02, 0x01, /* TOK_ID */
     534             :                 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */
     535             :                 0x02, 0x00, /* SEAL_ALG (DES3-KD) */
     536             :                 0xff, 0xff, /* Filler */
     537             :                 0xa0, 0xa1, 0xa2, 0xa3, /* encrypted sequence number */
     538             :                 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */
     539             :                 /* checksum */
     540             :                 0xa4, 0xa5, 0xa6, 0xa7, 0xa8,
     541             :                 0xa9, 0xaa, 0xab, 0xac, 0xad,
     542             :                 0xae, 0xaf, 0xb0, 0xb1, 0xb2,
     543             :                 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
     544             :         };
     545             : 
     546           1 :         input = get_input_buffer(ctx, data, sizeof(data), 22);
     547             : 
     548           1 :         gss_ctx = (gsskrb5_ctx) ctx->context_handle;
     549           1 :         gss_ctx->flags |= GSS_C_DCE_STYLE;
     550             : 
     551           1 :         major_status = _gsskrb5_unwrap(&minor_status,
     552             :                                        ctx->context_handle,
     553             :                                        &input,
     554             :                                        &output,
     555             :                                        &conf_state,
     556             :                                        &qop_state);
     557           1 :         assert_int_equal(GSS_S_BAD_MECH, major_status);
     558           1 : }
     559             : 
     560           1 : static void test_unwrap_dce_style_with_seal_valid(void **state) {
     561           1 :         struct context *ctx = *state;
     562           1 :         OM_uint32 major_status;
     563           1 :         OM_uint32 minor_status;
     564           1 :         gsskrb5_ctx gss_ctx;
     565           1 :         gss_buffer_desc input = {0};
     566           1 :         gss_buffer_desc output = {0};
     567           1 :         int conf_state;
     568           1 :         gss_qop_t qop_state;
     569             : 
     570             :         /* See RFC 1964 for token format. */
     571           1 :         static const uint8_t data[] = {
     572             :                 0x60, /* ASN.1 Application tag */
     573             :                 0x37, /* total length */
     574             :                 0x06, /* OBJECT IDENTIFIER */
     575             :                 0x09, /* mech length */
     576             :                 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */
     577             :                 0x02, 0x01, /* TOK_ID */
     578             :                 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */
     579             :                 0x02, 0x00, /* SEAL_ALG (DES3-KD) */
     580             :                 0xff, 0xff, /* Filler */
     581             :                 0xa0, 0xa1, 0xa2, 0xa3, /* encrypted sequence number */
     582             :                 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */
     583             :                 /* checksum */
     584             :                 0xa4, 0xa5, 0xa6, 0xa7, 0xa8,
     585             :                 0xa9, 0xaa, 0xab, 0xac, 0xad,
     586             :                 0xae, 0xaf, 0xb0, 0xb1, 0xb2,
     587             :                 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
     588             :                 /* unused */
     589             :                 0xb8, 0xb9, 0xba, 0xbb,
     590             :                 0xbc, 0xbd, 0xbe,
     591             :                 0x00, /* padding byte */
     592             :         };
     593             : 
     594           1 :         input = get_input_buffer(ctx, data, sizeof(data), 57);
     595             : 
     596           1 :         gss_ctx = (gsskrb5_ctx) ctx->context_handle;
     597           1 :         gss_ctx->flags |= GSS_C_DCE_STYLE;
     598             : 
     599           1 :         expect_value(__wrap_krb5_decrypt, len, 8);
     600           1 :         expect_value(__wrap_krb5_decrypt, data, (uint8_t *)input.value + 49);
     601             : 
     602           1 :         expect_value(__wrap_krb5_decrypt_ivec, data, (uint8_t *)input.value + 21);
     603           1 :         expect_memory(__wrap_krb5_decrypt_ivec, ivec,
     604             :                       (uint8_t *)input.value + 29, DES_CBLOCK_LEN);
     605             : 
     606           1 :         expect_value(__wrap_krb5_verify_checksum, len, 16);
     607           1 :         expect_value(__wrap_krb5_verify_checksum, data, (uint8_t *)input.value + 41);
     608           1 :         expect_memory(__wrap_krb5_verify_checksum, cksum->checksum.data,
     609             :                       (uint8_t *)input.value + 29, 20);
     610             : 
     611           2 :         major_status = _gsskrb5_unwrap(&minor_status,
     612           1 :                                        ctx->context_handle,
     613             :                                        &input,
     614             :                                        &output,
     615             :                                        &conf_state,
     616             :                                        &qop_state);
     617           1 :         assert_int_equal(GSS_S_COMPLETE, major_status);
     618             : 
     619           1 :         assert_int_equal(1, conf_state);
     620           1 :         assert_int_equal(GSS_C_QOP_DEFAULT, qop_state);
     621             : 
     622           1 :         assert_int_equal(output.length, 0);
     623             : 
     624           1 :         major_status = gss_release_buffer(&minor_status, &output);
     625           1 :         assert_int_equal(GSS_S_COMPLETE, major_status);
     626           1 : }
     627             : 
     628           1 : static void test_unwrap_missing_8_bytes(void **state) {
     629           1 :         struct context *ctx = *state;
     630           1 :         OM_uint32 major_status;
     631           1 :         OM_uint32 minor_status;
     632           1 :         gss_buffer_desc input = {0};
     633           1 :         gss_buffer_desc output = {0};
     634           1 :         int conf_state;
     635           1 :         gss_qop_t qop_state;
     636             : 
     637             :         /* See RFC 1964 for token format. */
     638           1 :         static const uint8_t data[] = {
     639             :                 0x60, /* ASN.1 Application tag */
     640             :                 0x2f, /* total length */
     641             :                 0x06, /* OBJECT IDENTIFIER */
     642             :                 0x09, /* mech length */
     643             :                 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */
     644             :                 0x02, 0x01, /* TOK_ID */
     645             :                 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */
     646             :                 0xff, 0xff, /* SEAL_ALG (none) */
     647             :                 0xff, 0xff, /* Filler */
     648             :                 0xa0, 0xa1, 0xa2, 0xa3, /* encrypted sequence number */
     649             :                 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */
     650             :                 /* checksum */
     651             :                 0xa4, 0xa5, 0xa6, 0xa7, 0xa8,
     652             :                 0xa9, 0xaa, 0xab, 0xac, 0xad,
     653             :                 0xae, 0xaf, 0xb0, 0xb1, 0xb2,
     654             :                 0xb3, 0xb4, 0xb5, 0xb6, 0x00, /* padding byte */
     655             :         };
     656             : 
     657           1 :         input = get_input_buffer(ctx, data, sizeof(data), 49);
     658             : 
     659             :         /*
     660             :          * A fixed unwrap_des3() should fail before these wrappers are called,
     661             :          * but we want the wrappers to have access to any required values in the
     662             :          * event that they are called. Specifying WILL_RETURN_ONCE avoids a test
     663             :          * failure if these values remain unused.
     664             :          */
     665           1 :         expect_value_count(__wrap_krb5_decrypt_ivec, data,
     666             :                            (uint8_t *)input.value + 21,
     667             :                            WILL_RETURN_ONCE);
     668           1 :         expect_memory_count(__wrap_krb5_decrypt_ivec, ivec,
     669             :                             (uint8_t *)input.value + 29, DES_CBLOCK_LEN,
     670             :                             WILL_RETURN_ONCE);
     671             : 
     672           1 :         expect_value_count(__wrap_krb5_verify_checksum, len, 8, WILL_RETURN_ONCE);
     673           1 :         expect_value_count(__wrap_krb5_verify_checksum, data,
     674             :                            (uint8_t *)input.value + 41,
     675             :                            WILL_RETURN_ONCE);
     676           1 :         expect_memory_count(__wrap_krb5_verify_checksum, cksum->checksum.data,
     677             :                             (uint8_t *)input.value + 29, 20,
     678             :                             WILL_RETURN_ONCE);
     679             : 
     680           2 :         major_status = _gsskrb5_unwrap(&minor_status,
     681           1 :                                        ctx->context_handle,
     682             :                                        &input,
     683             :                                        &output,
     684             :                                        &conf_state,
     685             :                                        &qop_state);
     686           1 :         assert_int_equal(GSS_S_BAD_MECH, major_status);
     687           1 : }
     688             : 
     689           1 : static void test_unwrap_missing_payload(void **state) {
     690           1 :         struct context *ctx = *state;
     691           1 :         OM_uint32 major_status;
     692           1 :         OM_uint32 minor_status;
     693           1 :         gss_buffer_desc input = {0};
     694           1 :         gss_buffer_desc output = {0};
     695           1 :         int conf_state;
     696           1 :         gss_qop_t qop_state;
     697             : 
     698             :         /* See RFC 1964 for token format. */
     699           1 :         static const uint8_t data[] = {
     700             :                 0x60, /* ASN.1 Application tag */
     701             :                 0x14, /* total length */
     702             :                 0x06, /* OBJECT IDENTIFIER */
     703             :                 0x09, /* mech length */
     704             :                 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */
     705             :                 0x02, 0x01, /* TOK_ID */
     706             :                 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */
     707             :                 0xff, 0xff, /* SEAL_ALG (none) */
     708             :                 0xff, 0xff, /* Filler */
     709             :                 0x00, 0xa1, 0xa2, 0xa3, /* padding byte / encrypted sequence number */
     710             :                 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */
     711             :                 /* checksum */
     712             :                 0xa4, 0xa5, 0xa6, 0xa7, 0xa8,
     713             :                 0xa9, 0xaa, 0xab, 0xac, 0xad,
     714             :                 0xae, 0xaf, 0xb0, 0xb1, 0xb2,
     715             :                 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
     716             :         };
     717             : 
     718           1 :         input = get_input_buffer(ctx, data, sizeof(data), 22);
     719             : 
     720           2 :         major_status = _gsskrb5_unwrap(&minor_status,
     721           1 :                                        ctx->context_handle,
     722             :                                        &input,
     723             :                                        &output,
     724             :                                        &conf_state,
     725             :                                        &qop_state);
     726           1 :         assert_int_equal(GSS_S_BAD_MECH, major_status);
     727           1 : }
     728             : 
     729           1 : static void test_unwrap_truncated_header_0(void **state) {
     730           1 :         struct context *ctx = *state;
     731           1 :         OM_uint32 major_status;
     732           1 :         OM_uint32 minor_status;
     733           1 :         gss_buffer_desc input = {0};
     734           1 :         gss_buffer_desc output = {0};
     735           1 :         int conf_state;
     736           1 :         gss_qop_t qop_state;
     737             : 
     738             :         /* See RFC 1964 for token format. */
     739           1 :         static const uint8_t data[] = {
     740             :                 0x60, /* ASN.1 Application tag */
     741             :                 0x00, /* total length */
     742             :                 0x06, /* OBJECT IDENTIFIER */
     743             :         };
     744             : 
     745           1 :         input = get_input_buffer(ctx, data, sizeof(data), 2);
     746             : 
     747           2 :         major_status = _gsskrb5_unwrap(&minor_status,
     748           1 :                                        ctx->context_handle,
     749             :                                        &input,
     750             :                                        &output,
     751             :                                        &conf_state,
     752             :                                        &qop_state);
     753           1 :         assert_int_equal(GSS_S_DEFECTIVE_TOKEN, major_status);
     754           1 : }
     755             : 
     756           1 : static void test_unwrap_truncated_header_1(void **state) {
     757           1 :         struct context *ctx = *state;
     758           1 :         OM_uint32 major_status;
     759           1 :         OM_uint32 minor_status;
     760           1 :         gss_buffer_desc input = {0};
     761           1 :         gss_buffer_desc output = {0};
     762           1 :         int conf_state;
     763           1 :         gss_qop_t qop_state;
     764             : 
     765             :         /* See RFC 1964 for token format. */
     766           1 :         static const uint8_t data[] = {
     767             :                 0x60, /* ASN.1 Application tag */
     768             :                 0x02, /* total length */
     769             :                 0x06, /* OBJECT IDENTIFIER */
     770             :                 0x09, /* mech length */
     771             :                 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, /* GSS KRB5 mech */
     772             :         };
     773             : 
     774           1 :         input = get_input_buffer(ctx, data, sizeof(data), 4);
     775             : 
     776           2 :         major_status = _gsskrb5_unwrap(&minor_status,
     777           1 :                                        ctx->context_handle,
     778             :                                        &input,
     779             :                                        &output,
     780             :                                        &conf_state,
     781             :                                        &qop_state);
     782           1 :         assert_int_equal(GSS_S_BAD_MECH, major_status);
     783           1 : }
     784             : 
     785           1 : static void test_unwrap_valid(void **state) {
     786           1 :         struct context *ctx = *state;
     787           1 :         OM_uint32 major_status;
     788           1 :         OM_uint32 minor_status;
     789           1 :         gss_buffer_desc input = {0};
     790           1 :         gss_buffer_desc output = {0};
     791           1 :         int conf_state;
     792           1 :         gss_qop_t qop_state;
     793             : 
     794             :         /* See RFC 1964 for token format. */
     795           1 :         static const uint8_t data[] = {
     796             :                 0x60, /* ASN.1 Application tag */
     797             :                 0x37, /* total length */
     798             :                 0x06, /* OBJECT IDENTIFIER */
     799             :                 0x09, /* mech length */
     800             :                 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */
     801             :                 0x02, 0x01, /* TOK_ID */
     802             :                 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */
     803             :                 0xff, 0xff, /* SEAL_ALG (none) */
     804             :                 0xff, 0xff, /* Filler */
     805             :                 0xa0, 0xa1, 0xa2, 0xa3, /* encrypted sequence number */
     806             :                 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */
     807             :                 /* checksum */
     808             :                 0xa4, 0xa5, 0xa6, 0xa7, 0xa8,
     809             :                 0xa9, 0xaa, 0xab, 0xac, 0xad,
     810             :                 0xae, 0xaf, 0xb0, 0xb1, 0xb2,
     811             :                 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
     812             :                 /* unused */
     813             :                 0xb8, 0xb9, 0xba, 0xbb,
     814             :                 0xbc, 0xbd, 0xbe,
     815             :                 0x00, /* padding byte */
     816             :         };
     817             : 
     818           1 :         input = get_input_buffer(ctx, data, sizeof(data), 57);
     819             : 
     820           1 :         expect_value(__wrap_krb5_decrypt_ivec, data, (uint8_t *)input.value + 21);
     821           1 :         expect_memory(__wrap_krb5_decrypt_ivec, ivec,
     822             :                       (uint8_t *)input.value + 29, DES_CBLOCK_LEN);
     823             : 
     824           1 :         expect_value(__wrap_krb5_verify_checksum, len, 16);
     825           1 :         expect_value(__wrap_krb5_verify_checksum, data, (uint8_t *)input.value + 41);
     826           1 :         expect_memory(__wrap_krb5_verify_checksum, cksum->checksum.data,
     827             :                       (uint8_t *)input.value + 29, 20);
     828             : 
     829           2 :         major_status = _gsskrb5_unwrap(&minor_status,
     830           1 :                                        ctx->context_handle,
     831             :                                        &input,
     832             :                                        &output,
     833             :                                        &conf_state,
     834             :                                        &qop_state);
     835           1 :         assert_int_equal(GSS_S_COMPLETE, major_status);
     836             : 
     837           1 :         assert_int_equal(0, conf_state);
     838           1 :         assert_int_equal(GSS_C_QOP_DEFAULT, qop_state);
     839             : 
     840           1 :         assert_int_equal(output.length, 0);
     841             : 
     842           1 :         major_status = gss_release_buffer(&minor_status, &output);
     843           1 :         assert_int_equal(GSS_S_COMPLETE, major_status);
     844           1 : }
     845             : 
     846           1 : static void test_unwrap_with_padding_truncated_0(void **state) {
     847           1 :         struct context *ctx = *state;
     848           1 :         OM_uint32 major_status;
     849           1 :         OM_uint32 minor_status;
     850           1 :         gss_buffer_desc input = {0};
     851           1 :         gss_buffer_desc output = {0};
     852           1 :         int conf_state;
     853           1 :         gss_qop_t qop_state;
     854             : 
     855             :         /* See RFC 1964 for token format. */
     856           1 :         static const uint8_t data[] = {
     857             :                 0x60, /* ASN.1 Application tag */
     858             :                 0x37, /* total length */
     859             :                 0x06, /* OBJECT IDENTIFIER */
     860             :                 0x09, /* mech length */
     861             :                 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */
     862             :                 0x02, 0x01, /* TOK_ID */
     863             :                 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */
     864             :                 0xff, 0xff, /* SEAL_ALG (none) */
     865             :                 0xff, 0xff, /* Filler */
     866             :                 0xa0, 0xa1, 0xa2, 0xa3, /* encrypted sequence number */
     867             :                 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */
     868             :                 /* checksum */
     869             :                 0xa4, 0xa5, 0xa6, 0xa7, 0xa8,
     870             :                 0xa9, 0xaa, 0xab, 0xac, 0xad,
     871             :                 0xae, 0xaf, 0xb0, 0xb1, 0xb2,
     872             :                 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
     873             :                 /* unused */
     874             :                 0xb8, 0xb9, 0xba, 0xbb,
     875             :                 0x04, 0x04, 0x04, 0x04, /* padding bytes */
     876             :         };
     877             : 
     878           1 :         input = get_input_buffer(ctx, data, sizeof(data), 57);
     879             : 
     880             :         /*
     881             :          * A fixed unwrap_des3() should fail before these wrappers are called,
     882             :          * but we want the wrappers to have access to any required values in the
     883             :          * event that they are called. Specifying WILL_RETURN_ONCE avoids a test
     884             :          * failure if these values remain unused.
     885             :          */
     886           1 :         expect_value_count(__wrap_krb5_decrypt_ivec, data,
     887             :                            (uint8_t *)input.value + 21,
     888             :                            WILL_RETURN_ONCE);
     889           1 :         expect_memory_count(__wrap_krb5_decrypt_ivec, ivec,
     890             :                             (uint8_t *)input.value + 29, DES_CBLOCK_LEN,
     891             :                             WILL_RETURN_ONCE);
     892             : 
     893           1 :         expect_value_count(__wrap_krb5_verify_checksum, len, 16, WILL_RETURN_ONCE);
     894           1 :         expect_value_count(__wrap_krb5_verify_checksum, data,
     895             :                            (uint8_t *)input.value + 41,
     896             :                            WILL_RETURN_ONCE);
     897           1 :         expect_memory_count(__wrap_krb5_verify_checksum, cksum->checksum.data,
     898             :                             (uint8_t *)input.value + 29, 20,
     899             :                             WILL_RETURN_ONCE);
     900             : 
     901           2 :         major_status = _gsskrb5_unwrap(&minor_status,
     902           1 :                                        ctx->context_handle,
     903             :                                        &input,
     904             :                                        &output,
     905             :                                        &conf_state,
     906             :                                        &qop_state);
     907           1 :         assert_int_equal(GSS_S_BAD_MECH, major_status);
     908           1 : }
     909             : 
     910           1 : static void test_unwrap_with_padding_truncated_1(void **state) {
     911           1 :         struct context *ctx = *state;
     912           1 :         OM_uint32 major_status;
     913           1 :         OM_uint32 minor_status;
     914           1 :         gss_buffer_desc input = {0};
     915           1 :         gss_buffer_desc output = {0};
     916           1 :         int conf_state;
     917           1 :         gss_qop_t qop_state;
     918             : 
     919             :         /* See RFC 1964 for token format. */
     920           1 :         static const uint8_t data[] = {
     921             :                 0x60, /* ASN.1 Application tag */
     922             :                 0x37, /* total length */
     923             :                 0x06, /* OBJECT IDENTIFIER */
     924             :                 0x09, /* mech length */
     925             :                 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */
     926             :                 0x02, 0x01, /* TOK_ID */
     927             :                 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */
     928             :                 0xff, 0xff, /* SEAL_ALG (none) */
     929             :                 0xff, 0xff, /* Filler */
     930             :                 0x00, 0xa1, 0xa2, 0xa3, /* padding byte / encrypted sequence number */
     931             :                 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */
     932             :                 /* checksum */
     933             :                 0xa4, 0xa5, 0xa6, 0xa7, 0xa8,
     934             :                 0xa9, 0xaa, 0xab, 0xac, 0xad,
     935             :                 0xae, 0xaf, 0xb0, 0xb1, 0xb2,
     936             :                 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
     937             :                 /* padding bytes */
     938             :                 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
     939             :         };
     940             : 
     941           1 :         input = get_input_buffer(ctx, data, sizeof(data), 57);
     942             : 
     943             :         /*
     944             :          * A fixed unwrap_des3() should fail before these wrappers are called,
     945             :          * but we want the wrappers to have access to any required values in the
     946             :          * event that they are called. Specifying WILL_RETURN_ONCE avoids a test
     947             :          * failure if these values remain unused.
     948             :          */
     949           1 :         expect_value_count(__wrap_krb5_decrypt_ivec, data,
     950             :                            (uint8_t *)input.value + 21,
     951             :                            WILL_RETURN_ONCE);
     952           1 :         expect_memory_count(__wrap_krb5_decrypt_ivec, ivec,
     953             :                             (uint8_t *)input.value + 29, DES_CBLOCK_LEN,
     954             :                             WILL_RETURN_ONCE);
     955             : 
     956           1 :         expect_value_count(__wrap_krb5_verify_checksum, len, 16, WILL_RETURN_ONCE);
     957           1 :         expect_value_count(__wrap_krb5_verify_checksum, data,
     958             :                            (uint8_t *)input.value + 41,
     959             :                            WILL_RETURN_ONCE);
     960           1 :         expect_memory_count(__wrap_krb5_verify_checksum, cksum->checksum.data,
     961             :                             (uint8_t *)input.value + 29, 20,
     962             :                             WILL_RETURN_ONCE);
     963             : 
     964           2 :         major_status = _gsskrb5_unwrap(&minor_status,
     965           1 :                                        ctx->context_handle,
     966             :                                        &input,
     967             :                                        &output,
     968             :                                        &conf_state,
     969             :                                        &qop_state);
     970           1 :         assert_int_equal(GSS_S_BAD_MECH, major_status);
     971           1 : }
     972             : 
     973           1 : static void test_unwrap_with_padding_valid(void **state) {
     974           1 :         struct context *ctx = *state;
     975           1 :         OM_uint32 major_status;
     976           1 :         OM_uint32 minor_status;
     977           1 :         gss_buffer_desc input = {0};
     978           1 :         gss_buffer_desc output = {0};
     979           1 :         int conf_state;
     980           1 :         gss_qop_t qop_state;
     981             : 
     982             :         /* See RFC 1964 for token format. */
     983           1 :         static const uint8_t data[] = {
     984             :                 0x60, /* ASN.1 Application tag */
     985             :                 0x3f, /* total length */
     986             :                 0x06, /* OBJECT IDENTIFIER */
     987             :                 0x09, /* mech length */
     988             :                 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */
     989             :                 0x02, 0x01, /* TOK_ID */
     990             :                 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */
     991             :                 0xff, 0xff, /* SEAL_ALG (none) */
     992             :                 0xff, 0xff, /* Filler */
     993             :                 0xa0, 0xa1, 0xa2, 0xa3, /* encrypted sequence number */
     994             :                 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */
     995             :                 /* checksum */
     996             :                 0xa4, 0xa5, 0xa6, 0xa7, 0xa8,
     997             :                 0xa9, 0xaa, 0xab, 0xac, 0xad,
     998             :                 0xae, 0xaf, 0xb0, 0xb1, 0xb2,
     999             :                 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
    1000             :                 /* unused */
    1001             :                 0xb8, 0xb9, 0xba, 0xbb,
    1002             :                 0xbc, 0xbd, 0xbe, 0xbf,
    1003             :                 /* padding bytes */
    1004             :                 0x08, 0x08, 0x08, 0x08,
    1005             :                 0x08, 0x08, 0x08, 0x08,
    1006             :         };
    1007             : 
    1008           1 :         input = get_input_buffer(ctx, data, sizeof(data), 65);
    1009             : 
    1010           1 :         expect_value(__wrap_krb5_decrypt_ivec, data, (uint8_t *)input.value + 21);
    1011           1 :         expect_memory(__wrap_krb5_decrypt_ivec, ivec,
    1012             :                       (uint8_t *)input.value + 29, DES_CBLOCK_LEN);
    1013             : 
    1014           1 :         expect_value(__wrap_krb5_verify_checksum, len, 24);
    1015           1 :         expect_value(__wrap_krb5_verify_checksum, data, (uint8_t *)input.value + 41);
    1016           1 :         expect_memory(__wrap_krb5_verify_checksum, cksum->checksum.data,
    1017             :                       (uint8_t *)input.value + 29, 20);
    1018             : 
    1019           2 :         major_status = _gsskrb5_unwrap(&minor_status,
    1020           1 :                                        ctx->context_handle,
    1021             :                                        &input,
    1022             :                                        &output,
    1023             :                                        &conf_state,
    1024             :                                        &qop_state);
    1025           1 :         assert_int_equal(GSS_S_COMPLETE, major_status);
    1026             : 
    1027           1 :         assert_int_equal(0, conf_state);
    1028           1 :         assert_int_equal(GSS_C_QOP_DEFAULT, qop_state);
    1029             : 
    1030           1 :         assert_int_equal(output.length, 0);
    1031             : 
    1032           1 :         major_status = gss_release_buffer(&minor_status, &output);
    1033           1 :         assert_int_equal(GSS_S_COMPLETE, major_status);
    1034           1 : }
    1035             : 
    1036           1 : static void test_unwrap_with_seal_empty_token_valid(void **state) {
    1037           1 :         struct context *ctx = *state;
    1038           1 :         OM_uint32 major_status;
    1039           1 :         OM_uint32 minor_status;
    1040           1 :         gss_buffer_desc input = {0};
    1041           1 :         gss_buffer_desc output = {0};
    1042           1 :         int conf_state;
    1043           1 :         gss_qop_t qop_state;
    1044             : 
    1045             :         /* See RFC 1964 for token format. */
    1046           1 :         static const uint8_t data[] = {
    1047             :                 0x60, /* ASN.1 Application tag */
    1048             :                 0x37, /* total length */
    1049             :                 0x06, /* OBJECT IDENTIFIER */
    1050             :                 0x09, /* mech length */
    1051             :                 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */
    1052             :                 0x02, 0x01, /* TOK_ID */
    1053             :                 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */
    1054             :                 0x02, 0x00, /* SEAL_ALG (DES3-KD) */
    1055             :                 0xff, 0xff, /* Filler */
    1056             :                 0xa0, 0xa1, 0xa2, 0xa3, /* encrypted sequence number */
    1057             :                 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */
    1058             :                 /* checksum */
    1059             :                 0xa4, 0xa5, 0xa6, 0xa7, 0xa8,
    1060             :                 0xa9, 0xaa, 0xab, 0xac, 0xad,
    1061             :                 0xae, 0xaf, 0xb0, 0xb1, 0xb2,
    1062             :                 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
    1063             :                 /* unused */
    1064             :                 0xb8, 0xb9, 0xba, 0xbb,
    1065             :                 0xbc, 0xbd, 0xbe,
    1066             :                 0x00, /* padding byte */
    1067             :         };
    1068             : 
    1069           1 :         input = get_input_buffer(ctx, data, sizeof(data), 57);
    1070             : 
    1071           1 :         expect_value(__wrap_krb5_decrypt, len, 8);
    1072           1 :         expect_value(__wrap_krb5_decrypt, data, (uint8_t *)input.value + 49);
    1073             : 
    1074           1 :         expect_value(__wrap_krb5_decrypt_ivec, data, (uint8_t *)input.value + 21);
    1075           1 :         expect_memory(__wrap_krb5_decrypt_ivec, ivec,
    1076             :                       (uint8_t *)input.value + 29, DES_CBLOCK_LEN);
    1077             : 
    1078           1 :         expect_value(__wrap_krb5_verify_checksum, len, 16);
    1079           1 :         expect_value(__wrap_krb5_verify_checksum, data, (uint8_t *)input.value + 41);
    1080           1 :         expect_memory(__wrap_krb5_verify_checksum, cksum->checksum.data,
    1081             :                       (uint8_t *)input.value + 29, 20);
    1082             : 
    1083           2 :         major_status = _gsskrb5_unwrap(&minor_status,
    1084           1 :                                        ctx->context_handle,
    1085             :                                        &input,
    1086             :                                        &output,
    1087             :                                        &conf_state,
    1088             :                                        &qop_state);
    1089           1 :         assert_int_equal(GSS_S_COMPLETE, major_status);
    1090             : 
    1091           1 :         assert_int_equal(1, conf_state);
    1092           1 :         assert_int_equal(GSS_C_QOP_DEFAULT, qop_state);
    1093             : 
    1094           1 :         assert_int_equal(output.length, 0);
    1095             : 
    1096           1 :         major_status = gss_release_buffer(&minor_status, &output);
    1097           1 :         assert_int_equal(GSS_S_COMPLETE, major_status);
    1098           1 : }
    1099             : 
    1100           1 : static void test_unwrap_with_seal_missing_payload(void **state) {
    1101           1 :         struct context *ctx = *state;
    1102           1 :         OM_uint32 major_status;
    1103           1 :         OM_uint32 minor_status;
    1104           1 :         gss_buffer_desc input = {0};
    1105           1 :         gss_buffer_desc output = {0};
    1106           1 :         int conf_state;
    1107           1 :         gss_qop_t qop_state;
    1108             : 
    1109             :         /* See RFC 1964 for token format. */
    1110           1 :         static const uint8_t data[] = {
    1111             :                 0x60, /* ASN.1 Application tag */
    1112             :                 0x14, /* total length */
    1113             :                 0x06, /* OBJECT IDENTIFIER */
    1114             :                 0x09, /* mech length */
    1115             :                 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */
    1116             :                 0x02, 0x01, /* TOK_ID */
    1117             :                 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */
    1118             :                 0x02, 0x00, /* SEAL_ALG (DES3-KD) */
    1119             :                 0xff, 0xff, /* Filler */
    1120             :                 0xa0, 0xa1, 0xa2, 0xa3, /* encrypted sequence number */
    1121             :                 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */
    1122             :                 /* checksum */
    1123             :                 0xa4, 0xa5, 0xa6, 0xa7, 0xa8,
    1124             :                 0xa9, 0xaa, 0xab, 0xac, 0xad,
    1125             :                 0xae, 0xaf, 0xb0, 0xb1, 0xb2,
    1126             :                 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
    1127             :         };
    1128             : 
    1129           1 :         input = get_input_buffer(ctx, data, sizeof(data), 22);
    1130             : 
    1131           2 :         major_status = _gsskrb5_unwrap(&minor_status,
    1132           1 :                                        ctx->context_handle,
    1133             :                                        &input,
    1134             :                                        &output,
    1135             :                                        &conf_state,
    1136             :                                        &qop_state);
    1137           1 :         assert_int_equal(GSS_S_BAD_MECH, major_status);
    1138           1 : }
    1139             : 
    1140           1 : static void test_unwrap_with_seal_valid(void **state) {
    1141           1 :         struct context *ctx = *state;
    1142           1 :         OM_uint32 major_status;
    1143           1 :         OM_uint32 minor_status;
    1144           1 :         gss_buffer_desc input = {0};
    1145           1 :         gss_buffer_desc output = {0};
    1146           1 :         int conf_state;
    1147           1 :         gss_qop_t qop_state;
    1148             : 
    1149             :         /* See RFC 1964 for token format. */
    1150           1 :         static const uint8_t data[] = {
    1151             :                 0x60, /* ASN.1 Application tag */
    1152             :                 0x3e, /* total length */
    1153             :                 0x06, /* OBJECT IDENTIFIER */
    1154             :                 0x09, /* mech length */
    1155             :                 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02, /* GSS KRB5 mech */
    1156             :                 0x02, 0x01, /* TOK_ID */
    1157             :                 0x04, 0x00, /* SGN_ALG (HMAC SHA1 DES3-KD) */
    1158             :                 0x02, 0x00, /* SEAL_ALG (DES3-KD) */
    1159             :                 0xff, 0xff, /* Filler */
    1160             :                 0xa0, 0xa1, 0xa2, 0xa3, /* encrypted sequence number */
    1161             :                 0x00, 0x00, 0x00, 0x00, /* sequence number direction (remote) */
    1162             :                 /* checksum */
    1163             :                 0xa4, 0xa5, 0xa6, 0xa7, 0xa8,
    1164             :                 0xa9, 0xaa, 0xab, 0xac, 0xad,
    1165             :                 0xae, 0xaf, 0xb0, 0xb1, 0xb2,
    1166             :                 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
    1167             :                 /* unused */
    1168             :                 0xb8, 0xb9, 0xba, 0xbb,
    1169             :                 0xbc, 0xbd, 0xbe, 0xbf,
    1170             :                 0xc0, 0xc1, 0xc2, 0xc3,
    1171             :                 0xc4, 0xc5,
    1172             :                 0x00, /* padding byte */
    1173             :         };
    1174             : 
    1175           1 :         input = get_input_buffer(ctx, data, sizeof(data), 64);
    1176             : 
    1177           1 :         expect_value(__wrap_krb5_decrypt, len, 15);
    1178           1 :         expect_value(__wrap_krb5_decrypt, data, (uint8_t *)input.value + 49);
    1179             : 
    1180           1 :         expect_value(__wrap_krb5_decrypt_ivec, data, (uint8_t *)input.value + 21);
    1181           1 :         expect_memory(__wrap_krb5_decrypt_ivec, ivec,
    1182             :                       (uint8_t *)input.value + 29, DES_CBLOCK_LEN);
    1183             : 
    1184           1 :         expect_value(__wrap_krb5_verify_checksum, len, 23);
    1185           1 :         expect_value(__wrap_krb5_verify_checksum, data, (uint8_t *)input.value + 41);
    1186           1 :         expect_memory(__wrap_krb5_verify_checksum, cksum->checksum.data,
    1187             :                       (uint8_t *)input.value + 29, 20);
    1188             : 
    1189           2 :         major_status = _gsskrb5_unwrap(&minor_status,
    1190           1 :                                        ctx->context_handle,
    1191             :                                        &input,
    1192             :                                        &output,
    1193             :                                        &conf_state,
    1194             :                                        &qop_state);
    1195           1 :         assert_int_equal(GSS_S_COMPLETE, major_status);
    1196             : 
    1197           1 :         assert_int_equal(1, conf_state);
    1198           1 :         assert_int_equal(GSS_C_QOP_DEFAULT, qop_state);
    1199             : 
    1200           1 :         assert_int_equal(output.length, 7);
    1201           1 :         assert_memory_equal((uint8_t *)input.value + 57, output.value, output.length);
    1202             : 
    1203           1 :         major_status = gss_release_buffer(&minor_status, &output);
    1204           1 :         assert_int_equal(GSS_S_COMPLETE, major_status);
    1205           1 : }
    1206             : 
    1207           1 : int main(int argc, const char **argv)
    1208             : {
    1209           1 :         static const struct CMUnitTest tests[] = {
    1210             :                 cmocka_unit_test_setup_teardown(
    1211             :                         test_unwrap_dce_style_missing_payload, setup, teardown),
    1212             :                 cmocka_unit_test_setup_teardown(
    1213             :                         test_unwrap_dce_style_valid, setup, teardown),
    1214             :                 cmocka_unit_test_setup_teardown(
    1215             :                         test_unwrap_dce_style_with_seal_missing_payload, setup, teardown),
    1216             :                 cmocka_unit_test_setup_teardown(
    1217             :                         test_unwrap_dce_style_with_seal_valid, setup, teardown),
    1218             :                 cmocka_unit_test_setup_teardown(
    1219             :                         test_unwrap_missing_8_bytes, setup, teardown),
    1220             :                 cmocka_unit_test_setup_teardown(
    1221             :                         test_unwrap_missing_payload, setup, teardown),
    1222             :                 cmocka_unit_test_setup_teardown(
    1223             :                         test_unwrap_truncated_header_0, setup, teardown),
    1224             :                 cmocka_unit_test_setup_teardown(
    1225             :                         test_unwrap_truncated_header_1, setup, teardown),
    1226             :                 cmocka_unit_test_setup_teardown(
    1227             :                         test_unwrap_valid, setup, teardown),
    1228             :                 cmocka_unit_test_setup_teardown(
    1229             :                         test_unwrap_with_padding_truncated_0, setup, teardown),
    1230             :                 cmocka_unit_test_setup_teardown(
    1231             :                         test_unwrap_with_padding_truncated_1, setup, teardown),
    1232             :                 cmocka_unit_test_setup_teardown(
    1233             :                         test_unwrap_with_padding_valid, setup, teardown),
    1234             :                 cmocka_unit_test_setup_teardown(
    1235             :                         test_unwrap_with_seal_empty_token_valid, setup, teardown),
    1236             :                 cmocka_unit_test_setup_teardown(
    1237             :                         test_unwrap_with_seal_missing_payload, setup, teardown),
    1238             :                 cmocka_unit_test_setup_teardown(
    1239             :                         test_unwrap_with_seal_valid, setup, teardown),
    1240             :         };
    1241             : 
    1242           1 :         cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
    1243           1 :         return cmocka_run_group_tests(tests, NULL, NULL);
    1244             : }

Generated by: LCOV version 1.14