unit-tests: Base attributes get adopted by seg-env/seg-contract
[strongswan.git] / src / libimcv / suites / test_imcv_seg.c
index 546a8eb..8b51eda 100644 (file)
@@ -19,6 +19,7 @@
 #include <pa_tnc/pa_tnc_attr.h>
 #include <seg/seg_env.h>
 #include <seg/seg_contract.h>
+#include <seg/seg_contract_manager.h>
 #include <ietf/ietf_attr_pa_tnc_error.h>
 #include <ita/ita_attr.h>
 #include <ita/ita_attr_command.h>
@@ -63,10 +64,11 @@ START_TEST(test_imcv_seg_env)
        libimcv_init(FALSE);
        max_seg_size  = seg_env_tests[_i].max_seg_size;
        last_seg_size = seg_env_tests[_i].last_seg_size;
+
        base_attr = ita_attr_command_create(command);
        base_attr->build(base_attr);
-
        seg_env = seg_env_create(id, base_attr, max_seg_size);
+
        if (seg_env_tests[_i].next_segs == 0)
        {
                ck_assert(seg_env == NULL);
@@ -74,9 +76,8 @@ START_TEST(test_imcv_seg_env)
        else
        {
                ck_assert(seg_env->get_base_attr_id(seg_env) == id);
-               base_attr1 = seg_env->get_base_attr(seg_env, &error);
+               base_attr1 = seg_env->get_base_attr(seg_env);
                ck_assert(base_attr == base_attr1);
-               ck_assert(error == NULL);
                base_attr1->destroy(base_attr1);
 
                for (n = 0; n <= seg_env_tests[_i].next_segs; n++)
@@ -118,7 +119,7 @@ START_TEST(test_imcv_seg_env)
                        ck_assert(seg_env_attr->get_base_attr_id(seg_env_attr) == id);
 
                        /* create parse segment envelope attribute from data */
-                       attr1 = tcg_seg_attr_seg_env_create_from_data(value);
+                       attr1 = tcg_seg_attr_seg_env_create_from_data(value.len, value);
                        ck_assert(attr1->process(attr1, &offset) == SUCCESS);
                        attr->destroy(attr);
 
@@ -132,21 +133,20 @@ START_TEST(test_imcv_seg_env)
                        {
                                ck_assert(flags == (SEG_ENV_FLAG_MORE | SEG_ENV_FLAG_START));
                                seg_env1 = seg_env_create_from_data(base_attr_id, segment,
-                                                                                                       max_seg_size);
+                                                                                                       max_seg_size, &error);
                        }
                        else
                        {
                                ck_assert(flags == last_seg ? SEG_ENV_FLAG_NONE :
                                                                                          SEG_ENV_FLAG_MORE);
-                               seg_env1->add_segment(seg_env1, segment);
+                               seg_env1->add_segment(seg_env1, segment, &error);
                        }
                        attr1->destroy(attr1);
                }
 
                /* check reconstructed base attribute */
-               base_attr1 = seg_env1->get_base_attr(seg_env1, &error);
+               base_attr1 = seg_env1->get_base_attr(seg_env1);
                ck_assert(base_attr1);
-               ck_assert(error == NULL);
                type = base_attr1->get_type(base_attr1);
                ck_assert(type.vendor_id == PEN_ITA);
                ck_assert(type.type == ITA_ATTR_COMMAND);
@@ -157,7 +157,6 @@ START_TEST(test_imcv_seg_env)
                seg_env1->destroy(seg_env1);
                base_attr1->destroy(base_attr1);
        }
-       base_attr->destroy(base_attr);
        libimcv_deinit();
 }
 END_TEST
@@ -168,7 +167,7 @@ START_TEST(test_imcv_seg_env_special)
        tcg_seg_attr_seg_env_t *seg_env_attr;
        pen_type_t type;
        seg_env_t *seg_env;
-       chunk_t segment;
+       chunk_t segment, value;
        uint32_t max_seg_size = 47;
        uint32_t last_seg_size = 1;
        uint32_t offset = 12;
@@ -210,13 +209,14 @@ START_TEST(test_imcv_seg_env_special)
        ck_assert(seg_env->next_segment(seg_env, NULL) == NULL);
 
        /* create and parse a too short segment envelope attribute */
-       attr1 = tcg_seg_attr_seg_env_create_from_data(chunk_empty);
+       attr1 = tcg_seg_attr_seg_env_create_from_data(0, chunk_empty);
        ck_assert(attr1->process(attr1, &offset) == FAILED);
        ck_assert(offset == 0);
        attr1->destroy(attr1);
 
        /* create and parse correct segment envelope attribute */
-       attr1 = tcg_seg_attr_seg_env_create_from_data(attr->get_value(attr));
+       value = attr->get_value(attr);
+       attr1 = tcg_seg_attr_seg_env_create_from_data(value.len, value);
        ck_assert(attr1->process(attr1, &offset) == SUCCESS);
        type = attr1->get_type(attr1);
        ck_assert(type.vendor_id == PEN_TCG);
@@ -226,22 +226,18 @@ START_TEST(test_imcv_seg_env_special)
        /* cleanup */
        attr->destroy(attr);
        seg_env->destroy(seg_env);
-       base_attr->destroy(base_attr);
 }
 END_TEST
 
 static struct {
        pa_tnc_error_code_t error_code;
        chunk_t segment;
-} invalid_tests[] = {
+} env_invalid_tests[] = {
        { PA_ERROR_INVALID_PARAMETER, { NULL, 0 } },
        { PA_ERROR_INVALID_PARAMETER, chunk_from_chars(
                0x00, 0xff, 0xff, 0xf0, 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x0a)
        },
        { PA_ERROR_INVALID_PARAMETER, chunk_from_chars(
-               0x00, 0x00, 0x90, 0x2a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0d)
-       },
-       { PA_ERROR_INVALID_PARAMETER, chunk_from_chars(
                0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c)
        },
        { PA_ERROR_INVALID_PARAMETER, chunk_from_chars(
@@ -265,14 +261,14 @@ START_TEST(test_imcv_seg_env_invalid)
 {
        seg_env_t *seg_env;
        pen_type_t error_code;
-       pa_tnc_attr_t *base_attr, *error;
+       pa_tnc_attr_t*error;
        ietf_attr_pa_tnc_error_t *error_attr;
 
        libimcv_init(FALSE);
-       seg_env = seg_env_create_from_data(id, invalid_tests[_i].segment, 20);
-       base_attr = seg_env->get_base_attr(seg_env, &error);
-       ck_assert(base_attr == NULL);
-       if (invalid_tests[_i].error_code == PA_ERROR_RESERVED)
+       seg_env = seg_env_create_from_data(id, env_invalid_tests[_i].segment, 20,
+                                                                          &error);
+       ck_assert(seg_env == NULL);
+       if (env_invalid_tests[_i].error_code == PA_ERROR_RESERVED)
        {
                ck_assert(error == NULL);
        }
@@ -283,10 +279,9 @@ START_TEST(test_imcv_seg_env_invalid)
                error_attr = (ietf_attr_pa_tnc_error_t*)error;
                error_code = error_attr->get_error_code(error_attr);
                ck_assert(error_code.vendor_id == PEN_IETF);
-               ck_assert(error_code.type == invalid_tests[_i].error_code);
+               ck_assert(error_code.type == env_invalid_tests[_i].error_code);
                error->destroy(error);
        }
-       seg_env->destroy(seg_env);
        libimcv_deinit();
 }
 END_TEST
@@ -310,7 +305,8 @@ START_TEST(test_imcv_seg_contract)
                                                                         TRUE, issuer_id, FALSE);
        contract_r = seg_contract_create(msg_type, max_attr_size, max_seg_size,
                                                                         FALSE, issuer_id, TRUE);
-       attr = contract_r->first_segment(contract_r, base_attr_r);
+       attr = contract_r->first_segment(contract_r,
+                                                                        base_attr_r->get_ref(base_attr_r));
 
        if (seg_env_tests[_i].next_segs == 0)
        {
@@ -426,8 +422,8 @@ START_TEST(test_imcv_seg_contract_special)
        ck_assert(!oversize);
 
        /* get first segment of each base attribute */
-       attr1_f = contract_r->first_segment(contract_r, base_attr1_r);
-       attr2_f = contract_r->first_segment(contract_r, base_attr2_r);
+       attr1_f = contract_r->first_segment(contract_r, base_attr1_r->get_ref(base_attr1_r));
+       attr2_f = contract_r->first_segment(contract_r, base_attr2_r->get_ref(base_attr2_r));
        ck_assert(attr1_f);
        ck_assert(attr2_f);
        seg_env_attr1 = (tcg_seg_attr_seg_env_t*)attr1_f;
@@ -530,6 +526,177 @@ START_TEST(test_imcv_seg_contract_special)
 }
 END_TEST
 
+static struct {
+       bool err_f;
+       chunk_t frag_f;
+       bool err_n;
+       bool base_attr;
+       chunk_t frag_n;
+} contract_invalid_tests[] = {
+       { FALSE, chunk_from_chars(
+               0xc0, 0x00, 0x00, 0x01, 0x00, 0x00, 0x90, 0x2a, 0x00, 0x00, 0x00, 0x01,
+               0x00, 0x00, 0x00, 0x0d),
+         FALSE, TRUE, chunk_from_chars(
+               0x00, 0x00, 0x00, 0x01, 0x01 )
+       },
+       { FALSE, chunk_from_chars(
+               0xc0, 0x00, 0x00, 0x02, 0x00, 0x00, 0x90, 0x2a, 0x00, 0x00, 0x00, 0x01,
+               0x00, 0x00, 0x00, 0x0e),
+         TRUE, FALSE, chunk_from_chars(
+               0x00, 0x00, 0x00, 0x02, 0x01 )
+       },
+       { TRUE, chunk_from_chars(
+               0xc0, 0x00, 0x00, 0x03, 0x00, 0x00, 0x55, 0x97, 0x00, 0x00, 0x00, 0x23,
+               0x00, 0x00, 0x00, 0x0d),
+         FALSE, FALSE, chunk_from_chars(
+               0x00, 0x00, 0x00, 0x03, 0x01 )
+       },
+       { FALSE, chunk_from_chars(
+               0xc0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+               0x00, 0x00, 0x00, 0x14),
+         FALSE, FALSE, chunk_from_chars(
+               0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 )
+       },
+       { FALSE, chunk_from_chars(
+               0xc0, 0x00, 0x00, 0x05, 0x00, 0x00, 0x90, 0x2a, 0x00, 0x00, 0x00, 0x03,
+               0x00, 0x00, 0x00, 0x0f),
+         TRUE, FALSE, chunk_from_chars(
+               0x00, 0x00, 0x00, 0x05, 0x00, 0x02, 0x01 )
+       },
+       { FALSE, chunk_from_chars(
+               0xc0, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+               0x00, 0x00, 0x00, 0x11),
+         TRUE, FALSE, chunk_from_chars(
+               0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0xff )
+       }
+};
+
+START_TEST(test_imcv_seg_contract_invalid)
+{
+       uint32_t max_seg_size = 12, max_attr_size = 100, issuer_id = 1;
+       pen_type_t msg_type = { PEN_ITA, PA_SUBTYPE_ITA_TEST };
+       pa_tnc_attr_t *attr_f, *attr_n, *base_attr, *error;
+       chunk_t value_f, value_n;
+       seg_contract_t *contract;
+       uint32_t offset;
+       bool more;
+
+       libimcv_init(FALSE);
+       value_f = contract_invalid_tests[_i].frag_f;
+       value_n = contract_invalid_tests[_i].frag_n;
+       attr_f = tcg_seg_attr_seg_env_create_from_data(value_f.len, value_f);
+       attr_n = tcg_seg_attr_seg_env_create_from_data(value_n.len, value_n);
+       ck_assert(attr_f->process(attr_f, &offset) == SUCCESS);
+       ck_assert(attr_n->process(attr_n, &offset) == SUCCESS);
+
+       contract = seg_contract_create(msg_type, max_attr_size, max_seg_size,
+                                                                        TRUE, issuer_id, FALSE);
+       base_attr = contract->add_segment(contract, attr_f, &error, &more);
+       ck_assert(base_attr == NULL);
+       
+       if (contract_invalid_tests[_i].err_f)
+       {
+               ck_assert(error);
+               error->destroy(error);
+       }
+       else
+       {
+               ck_assert(error == NULL);
+               ck_assert(more);
+               base_attr = contract->add_segment(contract, attr_n, &error, &more);
+               if (contract_invalid_tests[_i].err_n)
+               {
+                       ck_assert(error);
+                       error->destroy(error);
+               }
+               else
+               {
+                       ck_assert(error == NULL);
+               }
+               if (contract_invalid_tests[_i].base_attr)
+               {
+                       ck_assert(base_attr);
+                       base_attr->destroy(base_attr);
+               }
+       }
+
+       /* cleanup */
+       attr_f->destroy(attr_f);
+       attr_n->destroy(attr_n);
+       contract->destroy(contract);
+       libimcv_deinit();
+}
+END_TEST
+
+START_TEST(test_imcv_seg_contract_mgr)
+{
+       char buf[BUF_LEN];
+       uint32_t max_seg_size = 12, max_attr_size = 100;
+       pen_type_t msg_type1 = { PEN_ITA, PA_SUBTYPE_ITA_TEST };
+       pen_type_t msg_type2 = { PEN_IETF, PA_SUBTYPE_IETF_OPERATING_SYSTEM };
+       seg_contract_manager_t *contracts;
+       seg_contract_t *cx, *c1, *c2, *c3, *c4;
+
+       contracts = seg_contract_manager_create();
+
+       /* add contract template as issuer */
+       c1 = seg_contract_create(msg_type1, max_attr_size, max_seg_size, 
+                                                        TRUE, 1, FALSE);
+       c1->get_info_string(c1, buf, BUF_LEN, TRUE);
+
+       contracts->add_contract(contracts, c1);
+               
+       /* received contract request for msg_type1 as responder */
+       cx = contracts->get_contract(contracts, msg_type1, FALSE, 2);
+       ck_assert(cx == NULL);
+
+       /* add directed contract as responder */
+       c2 = seg_contract_create(msg_type1, max_attr_size, max_seg_size, 
+                                                        FALSE, 2, FALSE);
+       c2->set_responder(c2, 1);
+       c2->get_info_string(c2, buf, BUF_LEN, TRUE);
+       contracts->add_contract(contracts, c2);
+
+       /* retrieve this contract */
+       cx = contracts->get_contract(contracts, msg_type1, FALSE, 2);
+       ck_assert(cx == c2);
+
+       /* received directed contract response as issuer */
+       cx = contracts->get_contract(contracts, msg_type1, TRUE, 3);
+       ck_assert(cx == NULL);
+
+       /* get contract template */
+       cx = contracts->get_contract(contracts, msg_type1, TRUE, TNC_IMCID_ANY);
+       ck_assert(cx == c1);
+
+       /* clone the contract template and as it as a directed contract */
+       c3 = cx->clone(cx);
+       c3->set_responder(c3, 3);
+       c3->get_info_string(c3, buf, BUF_LEN, FALSE);
+       contracts->add_contract(contracts, c3);
+
+       /* retrieve this contract */
+       cx = contracts->get_contract(contracts, msg_type1, TRUE, 3);
+       ck_assert(cx == c3);
+
+       /* received contract request for msg_type2 as responder */
+       cx = contracts->get_contract(contracts, msg_type2, FALSE, 2);
+       ck_assert(cx == NULL);
+
+       /* add directed contract as responder */
+       c4 = seg_contract_create(msg_type2, max_attr_size, max_seg_size, 
+                                                        FALSE, 2, FALSE);
+       c4->set_responder(c4, 1);
+       contracts->add_contract(contracts, c4);
+
+       /* retrieve this contract */
+       cx = contracts->get_contract(contracts, msg_type2, FALSE, 2);
+       ck_assert(cx == c4);
+
+       contracts->destroy(contracts);
+}
+END_TEST
+
 Suite *imcv_seg_suite_create()
 {
        Suite *s;
@@ -546,7 +713,8 @@ Suite *imcv_seg_suite_create()
        suite_add_tcase(s, tc);
 
        tc = tcase_create("env_invalid");
-       tcase_add_loop_test(tc, test_imcv_seg_env_invalid, 0, countof(invalid_tests));
+       tcase_add_loop_test(tc, test_imcv_seg_env_invalid, 0,
+                                               countof(env_invalid_tests));
        suite_add_tcase(s, tc);
 
        tc = tcase_create("contract");
@@ -557,5 +725,14 @@ Suite *imcv_seg_suite_create()
        tcase_add_test(tc, test_imcv_seg_contract_special);
        suite_add_tcase(s, tc);
 
+       tc = tcase_create("contract_invalid");
+       tcase_add_loop_test(tc, test_imcv_seg_contract_invalid, 0,
+                                               countof(contract_invalid_tests));
+       suite_add_tcase(s, tc);
+
+       tc = tcase_create("contract_mgr");
+       tcase_add_test(tc, test_imcv_seg_contract_mgr);
+       suite_add_tcase(s, tc);
+
        return s;
 }