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 : }
|