Version bump to 5.9.5rc1
[strongswan.git] / src / libimcv / suites / test_imcv_seg.c
1 /*
2 * Copyright (C) 2014 Andreas Steffen
3 * HSR Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "test_suite.h"
17
18 #include <imcv.h>
19 #include <pa_tnc/pa_tnc_attr.h>
20 #include <seg/seg_env.h>
21 #include <seg/seg_contract.h>
22 #include <seg/seg_contract_manager.h>
23 #include <ietf/ietf_attr_pa_tnc_error.h>
24 #include <ita/ita_attr.h>
25 #include <ita/ita_attr_command.h>
26 #include <ita/ita_attr_dummy.h>
27 #include <tcg/seg/tcg_seg_attr_seg_env.h>
28
29 #include <tncif_pa_subtypes.h>
30
31 static struct {
32 uint32_t max_seg_size, next_segs, last_seg_size;
33 } seg_env_tests[] = {
34 { 0, 0, 0 },
35 { 11, 0, 0 },
36 { 12, 3, 12 },
37 { 13, 3, 9 },
38 { 15, 3, 3 },
39 { 16, 2, 16 },
40 { 17, 2, 14 },
41 { 23, 2, 2 },
42 { 24, 1, 24 },
43 { 25, 1, 23 },
44 { 47, 1, 1 },
45 { 48, 0, 0 },
46 };
47
48 static char command[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
49 static uint32_t id = 0x123456;
50
51 START_TEST(test_imcv_seg_env)
52 {
53 pa_tnc_attr_t *attr, *attr1, *base_attr, *base_attr1, *error;
54 tcg_seg_attr_seg_env_t *seg_env_attr;
55 ita_attr_command_t *ita_attr;
56 seg_env_t *seg_env, *seg_env1 = NULL;
57 pen_type_t type;
58 uint32_t base_attr_id, max_seg_size, last_seg_size, seg_size, offset;
59 uint8_t flags;
60 bool last, last_seg;
61 chunk_t value, segment, seg;
62 int n;
63
64 libimcv_init(FALSE);
65 max_seg_size = seg_env_tests[_i].max_seg_size;
66 last_seg_size = seg_env_tests[_i].last_seg_size;
67
68 base_attr = ita_attr_command_create(command);
69 base_attr->build(base_attr);
70 seg_env = seg_env_create(id, base_attr, max_seg_size);
71
72 if (seg_env_tests[_i].next_segs == 0)
73 {
74 ck_assert(seg_env == NULL);
75 }
76 else
77 {
78 ck_assert(seg_env->get_base_attr_id(seg_env) == id);
79 base_attr1 = seg_env->get_base_attr(seg_env);
80 ck_assert(base_attr == base_attr1);
81 base_attr1->destroy(base_attr1);
82
83 for (n = 0; n <= seg_env_tests[_i].next_segs; n++)
84 {
85 last_seg = (n == seg_env_tests[_i].next_segs);
86 seg_size = (last_seg) ? last_seg_size : max_seg_size;
87 if (n == 0)
88 {
89 /* create first segment */
90 attr = seg_env->first_segment(seg_env, 0);
91
92 seg_env_attr = (tcg_seg_attr_seg_env_t*)attr;
93 segment = seg_env_attr->get_segment(seg_env_attr, &flags);
94 if (max_seg_size > 12)
95 {
96 seg = chunk_create(command, seg_size - 12);
97 ck_assert(chunk_equals(seg, chunk_skip(segment, 12)));
98 }
99 ck_assert(flags == (SEG_ENV_FLAG_MORE | SEG_ENV_FLAG_START));
100 }
101 else
102 {
103 /* create next segments */
104 attr = seg_env->next_segment(seg_env, &last);
105 ck_assert(last == last_seg);
106
107 seg_env_attr = (tcg_seg_attr_seg_env_t*)attr;
108 segment = seg_env_attr->get_segment(seg_env_attr, &flags);
109 seg = chunk_create(command + n * max_seg_size - 12, seg_size);
110 ck_assert(chunk_equals(seg, segment));
111 ck_assert(flags == (last_seg ? SEG_ENV_FLAG_NONE :
112 SEG_ENV_FLAG_MORE));
113 }
114
115 /* check built segment envelope attribute */
116 value = attr->get_value(attr);
117 ck_assert(value.len == 4 + seg_size);
118 ck_assert(segment.len == seg_size);
119 ck_assert(seg_env_attr->get_base_attr_id(seg_env_attr) == id);
120
121 /* create parse segment envelope attribute from data */
122 attr1 = tcg_seg_attr_seg_env_create_from_data(value.len, value);
123 ck_assert(attr1->process(attr1, &offset) == SUCCESS);
124 attr->destroy(attr);
125
126 seg_env_attr = (tcg_seg_attr_seg_env_t*)attr1;
127 segment = seg_env_attr->get_segment(seg_env_attr, &flags);
128 base_attr_id = seg_env_attr->get_base_attr_id(seg_env_attr);
129 ck_assert(base_attr_id == id);
130
131 /* create and update seg_env object on the receiving side */
132 if (n == 0)
133 {
134 ck_assert(flags == (SEG_ENV_FLAG_MORE | SEG_ENV_FLAG_START));
135 seg_env1 = seg_env_create_from_data(base_attr_id, segment,
136 max_seg_size, &error);
137 }
138 else
139 {
140 ck_assert(flags == (last_seg ? SEG_ENV_FLAG_NONE :
141 SEG_ENV_FLAG_MORE));
142 seg_env1->add_segment(seg_env1, segment, &error);
143 }
144 attr1->destroy(attr1);
145 }
146
147 /* check reconstructed base attribute */
148 ck_assert(seg_env1);
149 base_attr1 = seg_env1->get_base_attr(seg_env1);
150 ck_assert(base_attr1);
151 type = base_attr1->get_type(base_attr1);
152 ck_assert(type.vendor_id == PEN_ITA);
153 ck_assert(type.type == ITA_ATTR_COMMAND);
154 ita_attr = (ita_attr_command_t*)base_attr1;
155 ck_assert(streq(ita_attr->get_command(ita_attr), command));
156
157 seg_env->destroy(seg_env);
158 seg_env1->destroy(seg_env1);
159 base_attr1->destroy(base_attr1);
160 }
161 libimcv_deinit();
162 }
163 END_TEST
164
165 START_TEST(test_imcv_seg_env_special)
166 {
167 pa_tnc_attr_t *attr, *attr1, *base_attr;
168 tcg_seg_attr_seg_env_t *seg_env_attr;
169 pen_type_t type;
170 seg_env_t *seg_env;
171 chunk_t segment, value;
172 uint32_t max_attr_len = 60;
173 uint32_t max_seg_size = 47;
174 uint32_t last_seg_size = 4;
175 uint32_t offset = 12;
176
177 base_attr = ita_attr_command_create(command);
178 base_attr->build(base_attr);
179
180 /* set noskip flag in base attribute */
181 base_attr->set_noskip_flag(base_attr, TRUE);
182
183 seg_env = seg_env_create(id, base_attr, max_seg_size);
184 attr = seg_env->first_segment(seg_env, max_attr_len);
185 attr->destroy(attr);
186
187 /* don't return last segment indicator */
188 attr = seg_env->next_segment(seg_env, NULL);
189
190 /* build attribute */
191 attr->build(attr);
192
193 /* don't return flags */
194 seg_env_attr = (tcg_seg_attr_seg_env_t*)attr;
195 segment = seg_env_attr->get_segment(seg_env_attr, NULL);
196 ck_assert(segment.len == last_seg_size);
197
198 /* get segment envelope attribute reference and destroy it */
199 attr1 = attr->get_ref(attr);
200 attr1->destroy(attr1);
201
202 /* check some standard methods */
203 type = attr->get_type(attr);
204 ck_assert(type.vendor_id == PEN_TCG);
205 ck_assert(type.type == TCG_SEG_ATTR_SEG_ENV);
206 ck_assert(attr->get_noskip_flag(attr) == FALSE);
207 attr->set_noskip_flag(attr, TRUE);
208 ck_assert(attr->get_noskip_flag(attr) == TRUE);
209
210 /* request next segment which does not exist */
211 ck_assert(seg_env->next_segment(seg_env, NULL) == NULL);
212
213 /* create and parse a too short segment envelope attribute */
214 attr1 = tcg_seg_attr_seg_env_create_from_data(0, chunk_empty);
215 ck_assert(attr1->process(attr1, &offset) == FAILED);
216 ck_assert(offset == 0);
217 attr1->destroy(attr1);
218
219 /* create and parse correct segment envelope attribute */
220 value = attr->get_value(attr);
221 attr1 = tcg_seg_attr_seg_env_create_from_data(value.len, value);
222 ck_assert(attr1->process(attr1, &offset) == SUCCESS);
223 type = attr1->get_type(attr1);
224 ck_assert(type.vendor_id == PEN_TCG);
225 ck_assert(type.type == TCG_SEG_ATTR_SEG_ENV);
226 attr1->destroy(attr1);
227
228 /* cleanup */
229 attr->destroy(attr);
230 seg_env->destroy(seg_env);
231 }
232 END_TEST
233
234 static struct {
235 pa_tnc_error_code_t error_code;
236 chunk_t segment;
237 } env_invalid_tests[] = {
238 { PA_ERROR_INVALID_PARAMETER, { NULL, 0 } },
239 { PA_ERROR_INVALID_PARAMETER, chunk_from_chars(
240 0x00, 0xff, 0xff, 0xf0, 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x0a)
241 },
242 { PA_ERROR_INVALID_PARAMETER, chunk_from_chars(
243 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c)
244 },
245 { PA_ERROR_INVALID_PARAMETER, chunk_from_chars(
246 0x00, 0x00, 0x90, 0x2a, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x0c)
247 },
248 { PA_ERROR_ATTR_TYPE_NOT_SUPPORTED, chunk_from_chars(
249 0x80, 0x00, 0x90, 0x2a, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x0c)
250 },
251 { PA_ERROR_RESERVED, chunk_from_chars(
252 0x00, 0x00, 0x90, 0x2a, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x0c)
253 },
254 { PA_ERROR_RESERVED, chunk_from_chars(
255 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0c)
256 },
257 { PA_ERROR_INVALID_PARAMETER, chunk_from_chars(
258 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0c)
259 }
260 };
261
262 START_TEST(test_imcv_seg_env_invalid)
263 {
264 seg_env_t *seg_env;
265 pen_type_t error_code;
266 pa_tnc_attr_t*error;
267 ietf_attr_pa_tnc_error_t *error_attr;
268
269 libimcv_init(FALSE);
270 seg_env = seg_env_create_from_data(id, env_invalid_tests[_i].segment, 20,
271 &error);
272 ck_assert(seg_env == NULL);
273 if (env_invalid_tests[_i].error_code == PA_ERROR_RESERVED)
274 {
275 ck_assert(error == NULL);
276 }
277 else
278 {
279 ck_assert(error);
280 error->build(error);
281 error_attr = (ietf_attr_pa_tnc_error_t*)error;
282 error_code = error_attr->get_error_code(error_attr);
283 ck_assert(error_code.vendor_id == PEN_IETF);
284 ck_assert(error_code.type == env_invalid_tests[_i].error_code);
285 error->destroy(error);
286 }
287 libimcv_deinit();
288 }
289 END_TEST
290
291 START_TEST(test_imcv_seg_contract)
292 {
293 seg_contract_t *contract_i, *contract_r;
294 tcg_seg_attr_seg_env_t *seg_env_attr;
295 ita_attr_command_t *ita_attr;
296 pa_tnc_attr_t *attr, *base_attr_i, *base_attr_r, *error;
297 pen_type_t type, msg_type = { PEN_ITA, PA_SUBTYPE_ITA_TEST };
298 uint32_t max_seg_size, max_attr_size = 1000, issuer_id = 1;
299 uint32_t base_attr_id;
300 bool more;
301
302 libimcv_init(FALSE);
303 max_seg_size = seg_env_tests[_i].max_seg_size;
304 base_attr_r = ita_attr_command_create(command);
305 base_attr_r->build(base_attr_r);
306 contract_i = seg_contract_create(msg_type, max_attr_size, max_seg_size,
307 TRUE, issuer_id, FALSE);
308 contract_r = seg_contract_create(msg_type, max_attr_size, max_seg_size,
309 FALSE, issuer_id, TRUE);
310 attr = contract_r->first_segment(contract_r,
311 base_attr_r->get_ref(base_attr_r), 0);
312
313 if (seg_env_tests[_i].next_segs == 0)
314 {
315 ck_assert(attr == NULL);
316 }
317 else
318 {
319 ck_assert(attr);
320 seg_env_attr = (tcg_seg_attr_seg_env_t*)attr;
321 base_attr_id = seg_env_attr->get_base_attr_id(seg_env_attr);
322 ck_assert(base_attr_id == 1);
323 base_attr_i = contract_i->add_segment(contract_i, attr, &error, &more);
324 ck_assert(base_attr_i == NULL);
325 attr->destroy(attr);
326 ck_assert(more);
327 while (more)
328 {
329 attr = contract_r->next_segment(contract_r, base_attr_id);
330 ck_assert(attr);
331 seg_env_attr = (tcg_seg_attr_seg_env_t*)attr;
332 base_attr_id = seg_env_attr->get_base_attr_id(seg_env_attr);
333 ck_assert(base_attr_id == 1);
334 base_attr_i = contract_i->add_segment(contract_i, attr, &error,
335 &more);
336 attr->destroy(attr);
337 }
338 ck_assert(base_attr_i);
339 ck_assert(error == NULL);
340 type = base_attr_i->get_type(base_attr_i);
341 ck_assert(pen_type_equals(type, base_attr_r->get_type(base_attr_r)));
342 ita_attr = (ita_attr_command_t*)base_attr_i;
343 ck_assert(streq(ita_attr->get_command(ita_attr), command));
344 base_attr_i->destroy(base_attr_i);
345 }
346 contract_i->destroy(contract_i);
347 contract_r->destroy(contract_r);
348 base_attr_r->destroy(base_attr_r);
349 libimcv_deinit();
350 }
351 END_TEST
352
353 START_TEST(test_imcv_seg_contract_special)
354 {
355 seg_contract_t *contract_i, *contract_r;
356 tcg_seg_attr_seg_env_t *seg_env_attr1, *seg_env_attr2;
357 ita_attr_command_t *ita_attr;
358 pa_tnc_attr_t *base_attr1_i, *base_attr2_i, *base_attr1_r, *base_attr2_r;
359 pa_tnc_attr_t *attr1_f, *attr2_f, *attr1_n, *attr2_n, *attr3, *error;
360 pen_type_t type, msg_type = { PEN_ITA, PA_SUBTYPE_ITA_TEST };
361 uint32_t max_seg_size, max_attr_size, issuer_id = 1;
362 uint32_t base_attr1_id, base_attr2_id;
363 char info[512];
364 bool oversize, more;
365
366 libimcv_init(FALSE);
367
368 /* create two base attributes to be segmented */
369 base_attr1_r = ita_attr_command_create(command);
370 base_attr2_r = ita_attr_dummy_create(129);
371 base_attr1_r->build(base_attr1_r);
372 base_attr2_r->build(base_attr2_r);
373
374 /* create an issuer contract*/
375 contract_i = seg_contract_create(msg_type, 1000, 47,
376 TRUE, issuer_id, FALSE);
377 ck_assert(pen_type_equals(contract_i->get_msg_type(contract_i), msg_type));
378 ck_assert(contract_i->is_issuer(contract_i));
379 ck_assert(!contract_i->is_null(contract_i));
380
381 /* set null contract */
382 contract_i->set_max_size(contract_i, SEG_CONTRACT_MAX_SIZE_VALUE,
383 SEG_CONTRACT_MAX_SIZE_VALUE);
384 ck_assert(contract_i->is_null(contract_i));
385
386 /* set and get maximum attribute and segment sizes */
387 contract_i->set_max_size(contract_i, 1000, 47);
388 contract_i->get_max_size(contract_i, NULL, NULL);
389 contract_i->get_max_size(contract_i, &max_attr_size, &max_seg_size);
390 contract_i->get_info_string(contract_i, info, sizeof(info), TRUE);
391 ck_assert(max_attr_size == 1000 && max_seg_size == 47);
392 ck_assert(!contract_i->is_null(contract_i));
393
394 /* create a null responder contract*/
395 contract_r = seg_contract_create(msg_type, SEG_CONTRACT_MAX_SIZE_VALUE,
396 SEG_CONTRACT_MAX_SIZE_VALUE,
397 FALSE, issuer_id, TRUE);
398 ck_assert(!contract_r->is_issuer(contract_r));
399 ck_assert(!contract_r->check_size(contract_r, base_attr2_r, &oversize));
400 ck_assert(!oversize);
401
402 /* allow no fragmentation */
403 contract_r->set_max_size(contract_r, 1000, SEG_CONTRACT_MAX_SIZE_VALUE);
404 ck_assert(!contract_r->is_null(contract_r));
405 ck_assert(!contract_r->check_size(contract_r, base_attr2_r, &oversize));
406 ck_assert(!oversize);
407
408 /* no maximum size limit and no fragmentation needed */
409 contract_r->set_max_size(contract_r, SEG_CONTRACT_MAX_SIZE_VALUE, 141);
410 ck_assert(!contract_r->is_null(contract_r));
411 ck_assert(!contract_r->check_size(contract_r, base_attr2_r, &oversize));
412 ck_assert(!oversize);
413
414 /* oversize base attribute */
415 contract_r->set_max_size(contract_r, 140, 47);
416 ck_assert(!contract_r->is_null(contract_r));
417 ck_assert(!contract_r->check_size(contract_r, base_attr2_r, &oversize));
418 ck_assert(oversize);
419
420 /* set final maximum attribute and segment sizes */
421 contract_r->set_max_size(contract_r, 141, 47);
422 contract_r->get_info_string(contract_r, info, sizeof(info), TRUE);
423 ck_assert(contract_r->check_size(contract_r, base_attr2_r, &oversize));
424 ck_assert(!oversize);
425
426 /* get first segment of each base attribute */
427 attr1_f = contract_r->first_segment(contract_r, base_attr1_r->get_ref(base_attr1_r), 0);
428 attr2_f = contract_r->first_segment(contract_r, base_attr2_r->get_ref(base_attr2_r), 0);
429 ck_assert(attr1_f);
430 ck_assert(attr2_f);
431 seg_env_attr1 = (tcg_seg_attr_seg_env_t*)attr1_f;
432 seg_env_attr2 = (tcg_seg_attr_seg_env_t*)attr2_f;
433 base_attr1_id = seg_env_attr1->get_base_attr_id(seg_env_attr1);
434 base_attr2_id = seg_env_attr2->get_base_attr_id(seg_env_attr2);
435 ck_assert(base_attr1_id == 1);
436 ck_assert(base_attr2_id == 2);
437
438 /* get second segment of each base attribute */
439 attr1_n = contract_r->next_segment(contract_r, 1);
440 attr2_n = contract_r->next_segment(contract_r, 2);
441 ck_assert(attr1_n);
442 ck_assert(attr2_n);
443
444 /* process first segment of first base attribute */
445 base_attr1_i = contract_i->add_segment(contract_i, attr1_f, &error, &more);
446 ck_assert(base_attr1_i == NULL);
447 ck_assert(error == NULL);
448 ck_assert(more);
449
450 /* reapply first segment of first base attribute */
451 base_attr1_i = contract_i->add_segment(contract_i, attr1_f, &error, &more);
452 ck_assert(base_attr1_i == NULL);
453 ck_assert(error == NULL);
454 ck_assert(more);
455
456 /* process stray second segment of second attribute */
457 base_attr2_i = contract_i->add_segment(contract_i, attr2_n, &error, &more);
458 ck_assert(base_attr2_i == NULL);
459 ck_assert(error == NULL);
460 ck_assert(more);
461
462 /* process first segment of second base attribute */
463 base_attr2_i = contract_i->add_segment(contract_i, attr2_f, &error, &more);
464 ck_assert(base_attr2_i == NULL);
465 ck_assert(error == NULL);
466 ck_assert(more);
467
468 /* try to get a segment of a non-existing base-attribute */
469 attr3 = contract_r->next_segment(contract_r, 3);
470 ck_assert(attr3 == NULL);
471
472 /* process second segment of first base attribute */
473 base_attr1_i = contract_i->add_segment(contract_i, attr1_n, &error, &more);
474 ck_assert(base_attr1_i);
475 ck_assert(error == NULL);
476 ck_assert(!more);
477
478 /* process second segment of second base attribute */
479 base_attr2_i = contract_i->add_segment(contract_i, attr2_n, &error, &more);
480 ck_assert(base_attr2_i == NULL);
481 ck_assert(error == NULL);
482 ck_assert(more);
483
484 /* destroy first and second segments */
485 attr1_f->destroy(attr1_f);
486 attr2_f->destroy(attr2_f);
487 attr1_n->destroy(attr1_n);
488 attr2_n->destroy(attr2_n);
489
490 /* request surplus segment of first base attribute */
491 attr1_n = contract_r->next_segment(contract_r, 1);
492 ck_assert(attr1_n == NULL);
493
494 /* get last segment of second base attribute */
495 attr2_n = contract_r->next_segment(contract_r, 2);
496 ck_assert(attr2_n);
497
498 /* process last segment of second base attribute */
499 base_attr2_i = contract_i->add_segment(contract_i, attr2_n, &error, &more);
500 attr2_n->destroy(attr2_n);
501 ck_assert(base_attr2_i);
502 ck_assert(error == NULL);
503 ck_assert(!more);
504
505 /* request surplus segment of second base attribute */
506 attr2_n = contract_r->next_segment(contract_r, 2);
507 ck_assert(attr2_n == NULL);
508
509 /* compare original with reconstructed base attributes */
510 type = base_attr1_i->get_type(base_attr1_i);
511 ck_assert(pen_type_equals(type, base_attr1_r->get_type(base_attr1_r)));
512 ita_attr = (ita_attr_command_t*)base_attr1_i;
513 ck_assert(streq(ita_attr->get_command(ita_attr), command));
514
515 type = base_attr2_i->get_type(base_attr2_i);
516 ck_assert(pen_type_equals(type, base_attr2_r->get_type(base_attr2_r)));
517 ck_assert(chunk_equals(base_attr2_i->get_value(base_attr2_i),
518 base_attr2_r->get_value(base_attr2_r)));
519
520 /* cleanup */
521 base_attr1_r->destroy(base_attr1_r);
522 base_attr2_r->destroy(base_attr2_r);
523 base_attr1_i->destroy(base_attr1_i);
524 base_attr2_i->destroy(base_attr2_i);
525 contract_i->destroy(contract_i);
526 contract_r->destroy(contract_r);
527 libimcv_deinit();
528 }
529 END_TEST
530
531 static struct {
532 bool err_f;
533 chunk_t frag_f;
534 bool err_n;
535 bool base_attr;
536 chunk_t frag_n;
537 } contract_invalid_tests[] = {
538 { FALSE, chunk_from_chars(
539 0xc0, 0x00, 0x00, 0x01, 0x00, 0x00, 0x90, 0x2a, 0x00, 0x00, 0x00, 0x01,
540 0x00, 0x00, 0x00, 0x0d),
541 FALSE, TRUE, chunk_from_chars(
542 0x00, 0x00, 0x00, 0x01, 0x01 )
543 },
544 { FALSE, chunk_from_chars(
545 0xc0, 0x00, 0x00, 0x02, 0x00, 0x00, 0x90, 0x2a, 0x00, 0x00, 0x00, 0x01,
546 0x00, 0x00, 0x00, 0x0e),
547 TRUE, FALSE, chunk_from_chars(
548 0x00, 0x00, 0x00, 0x02, 0x01 )
549 },
550 { TRUE, chunk_from_chars(
551 0xc0, 0x00, 0x00, 0x03, 0x00, 0x00, 0x55, 0x97, 0x00, 0x00, 0x00, 0x23,
552 0x00, 0x00, 0x00, 0x0d),
553 FALSE, FALSE, chunk_from_chars(
554 0x00, 0x00, 0x00, 0x03, 0x01 )
555 },
556 { FALSE, chunk_from_chars(
557 0xc0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
558 0x00, 0x00, 0x00, 0x14),
559 FALSE, FALSE, chunk_from_chars(
560 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 )
561 },
562 { FALSE, chunk_from_chars(
563 0xc0, 0x00, 0x00, 0x05, 0x00, 0x00, 0x90, 0x2a, 0x00, 0x00, 0x00, 0x03,
564 0x00, 0x00, 0x00, 0x0f),
565 TRUE, FALSE, chunk_from_chars(
566 0x00, 0x00, 0x00, 0x05, 0x00, 0x02, 0x01 )
567 },
568 { FALSE, chunk_from_chars(
569 0xc0, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
570 0x00, 0x00, 0x00, 0x11),
571 TRUE, FALSE, chunk_from_chars(
572 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0xff )
573 }
574 };
575
576 START_TEST(test_imcv_seg_contract_invalid)
577 {
578 uint32_t max_seg_size = 12, max_attr_size = 100, issuer_id = 1;
579 pen_type_t msg_type = { PEN_ITA, PA_SUBTYPE_ITA_TEST };
580 pa_tnc_attr_t *attr_f, *attr_n, *base_attr, *error;
581 chunk_t value_f, value_n;
582 seg_contract_t *contract;
583 uint32_t offset;
584 bool more;
585
586 libimcv_init(FALSE);
587 value_f = contract_invalid_tests[_i].frag_f;
588 value_n = contract_invalid_tests[_i].frag_n;
589 attr_f = tcg_seg_attr_seg_env_create_from_data(value_f.len, value_f);
590 attr_n = tcg_seg_attr_seg_env_create_from_data(value_n.len, value_n);
591 ck_assert(attr_f->process(attr_f, &offset) == SUCCESS);
592 ck_assert(attr_n->process(attr_n, &offset) == SUCCESS);
593
594 contract = seg_contract_create(msg_type, max_attr_size, max_seg_size,
595 TRUE, issuer_id, FALSE);
596 base_attr = contract->add_segment(contract, attr_f, &error, &more);
597 ck_assert(base_attr == NULL);
598
599 if (contract_invalid_tests[_i].err_f)
600 {
601 ck_assert(error);
602 error->destroy(error);
603 }
604 else
605 {
606 ck_assert(error == NULL);
607 ck_assert(more);
608 base_attr = contract->add_segment(contract, attr_n, &error, &more);
609 if (contract_invalid_tests[_i].err_n)
610 {
611 ck_assert(error);
612 error->destroy(error);
613 }
614 else
615 {
616 ck_assert(error == NULL);
617 }
618 if (contract_invalid_tests[_i].base_attr)
619 {
620 ck_assert(base_attr);
621 base_attr->destroy(base_attr);
622 }
623 }
624
625 /* cleanup */
626 attr_f->destroy(attr_f);
627 attr_n->destroy(attr_n);
628 contract->destroy(contract);
629 libimcv_deinit();
630 }
631 END_TEST
632
633 START_TEST(test_imcv_seg_contract_mgr)
634 {
635 char buf[BUF_LEN];
636 uint32_t max_seg_size = 12, max_attr_size = 100;
637 pen_type_t msg_type1 = { PEN_ITA, PA_SUBTYPE_ITA_TEST };
638 pen_type_t msg_type2 = { PEN_IETF, PA_SUBTYPE_IETF_OPERATING_SYSTEM };
639 seg_contract_manager_t *contracts;
640 seg_contract_t *cx, *c1, *c2, *c3, *c4;
641
642 contracts = seg_contract_manager_create();
643
644 /* add contract template as issuer */
645 c1 = seg_contract_create(msg_type1, max_attr_size, max_seg_size,
646 TRUE, 1, FALSE);
647 c1->get_info_string(c1, buf, BUF_LEN, TRUE);
648
649 contracts->add_contract(contracts, c1);
650
651 /* received contract request for msg_type1 as responder */
652 cx = contracts->get_contract(contracts, msg_type1, FALSE, 2);
653 ck_assert(cx == NULL);
654
655 /* add directed contract as responder */
656 c2 = seg_contract_create(msg_type1, max_attr_size, max_seg_size,
657 FALSE, 2, FALSE);
658 c2->set_responder(c2, 1);
659 c2->get_info_string(c2, buf, BUF_LEN, TRUE);
660 contracts->add_contract(contracts, c2);
661
662 /* retrieve this contract */
663 cx = contracts->get_contract(contracts, msg_type1, FALSE, 2);
664 ck_assert(cx == c2);
665
666 /* received directed contract response as issuer */
667 cx = contracts->get_contract(contracts, msg_type1, TRUE, 3);
668 ck_assert(cx == NULL);
669
670 /* get contract template */
671 cx = contracts->get_contract(contracts, msg_type1, TRUE, TNC_IMCID_ANY);
672 ck_assert(cx == c1);
673
674 /* clone the contract template and as it as a directed contract */
675 c3 = cx->clone(cx);
676 c3->set_responder(c3, 3);
677 c3->get_info_string(c3, buf, BUF_LEN, FALSE);
678 contracts->add_contract(contracts, c3);
679
680 /* retrieve this contract */
681 cx = contracts->get_contract(contracts, msg_type1, TRUE, 3);
682 ck_assert(cx == c3);
683
684 /* received contract request for msg_type2 as responder */
685 cx = contracts->get_contract(contracts, msg_type2, FALSE, 2);
686 ck_assert(cx == NULL);
687
688 /* add directed contract as responder */
689 c4 = seg_contract_create(msg_type2, max_attr_size, max_seg_size,
690 FALSE, 2, FALSE);
691 c4->set_responder(c4, 1);
692 contracts->add_contract(contracts, c4);
693
694 /* retrieve this contract */
695 cx = contracts->get_contract(contracts, msg_type2, FALSE, 2);
696 ck_assert(cx == c4);
697
698 contracts->destroy(contracts);
699 }
700 END_TEST
701
702 Suite *imcv_seg_suite_create()
703 {
704 Suite *s;
705 TCase *tc;
706
707 s = suite_create("imcv_seg");
708
709 tc = tcase_create("env");
710 tcase_add_loop_test(tc, test_imcv_seg_env, 0, countof(seg_env_tests));
711 suite_add_tcase(s, tc);
712
713 tc = tcase_create("env_special");
714 tcase_add_test(tc, test_imcv_seg_env_special);
715 suite_add_tcase(s, tc);
716
717 tc = tcase_create("env_invalid");
718 tcase_add_loop_test(tc, test_imcv_seg_env_invalid, 0,
719 countof(env_invalid_tests));
720 suite_add_tcase(s, tc);
721
722 tc = tcase_create("contract");
723 tcase_add_loop_test(tc, test_imcv_seg_contract, 0, countof(seg_env_tests));
724 suite_add_tcase(s, tc);
725
726 tc = tcase_create("contract_special");
727 tcase_add_test(tc, test_imcv_seg_contract_special);
728 suite_add_tcase(s, tc);
729
730 tc = tcase_create("contract_invalid");
731 tcase_add_loop_test(tc, test_imcv_seg_contract_invalid, 0,
732 countof(contract_invalid_tests));
733 suite_add_tcase(s, tc);
734
735 tc = tcase_create("contract_mgr");
736 tcase_add_test(tc, test_imcv_seg_contract_mgr);
737 suite_add_tcase(s, tc);
738
739 return s;
740 }