summaryrefslogtreecommitdiff
path: root/src/libimcv/suites/test_imcv_swima.c
diff options
context:
space:
mode:
authorYves-Alexis Perez <corsac@corsac.net>2017-09-01 17:21:25 +0200
committerYves-Alexis Perez <corsac@corsac.net>2017-09-01 17:21:25 +0200
commit11d6b62db969bdd808d0f56706cb18f113927a31 (patch)
tree8aa7d8fb611c3da6a3523cb78a082f62ffd0dac8 /src/libimcv/suites/test_imcv_swima.c
parentbba25e2ff6c4a193acb54560ea4417537bd2954e (diff)
downloadvyos-strongswan-11d6b62db969bdd808d0f56706cb18f113927a31.tar.gz
vyos-strongswan-11d6b62db969bdd808d0f56706cb18f113927a31.zip
New upstream version 5.6.0
Diffstat (limited to 'src/libimcv/suites/test_imcv_swima.c')
-rw-r--r--src/libimcv/suites/test_imcv_swima.c1117
1 files changed, 1117 insertions, 0 deletions
diff --git a/src/libimcv/suites/test_imcv_swima.c b/src/libimcv/suites/test_imcv_swima.c
new file mode 100644
index 000000000..c54669d1d
--- /dev/null
+++ b/src/libimcv/suites/test_imcv_swima.c
@@ -0,0 +1,1117 @@
+/*
+ * Copyright (C) 2017 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "test_suite.h"
+
+#include "swima/swima_record.h"
+#include "swima/swima_data_model.h"
+#include "swima/swima_inventory.h"
+#include "swima/swima_event.h"
+#include "swima/swima_events.h"
+#include "swima/swima_collector.h"
+#include "ietf/swima/ietf_swima_attr_req.h"
+#include "ietf/swima/ietf_swima_attr_sw_inv.h"
+#include "ietf/swima/ietf_swima_attr_sw_ev.h"
+
+static pen_type_t ita_data_model = { PEN_ITA, 0x19 };
+
+static char* sw_id_str[] = {
+ "strongswan.org_strongSwan_5.3.3",
+ "strongswan.org_62251aa6-1a01-479b-aea6-f3dcf0ab1f1a"
+};
+static char sw_locator_str[] = "/usr/share/strongswan";
+
+static char* sw_record_str[] = {
+ "<SoftwareIdentity tagId=\"abc\"></SoftwareIdentity>",
+ "<SoftwareIdentity tagId=\"def\"></SoftwareIdentity>"
+};
+
+START_TEST(test_imcv_swima_record)
+{
+ chunk_t sw_id, sw_locator, locator;
+ swima_record_t *sw_record, *sw_record_cp;
+ uint32_t record_id = 1;
+ uint8_t source_id = 2;
+ chunk_t record = chunk_from_str(sw_record_str[0]);
+
+ sw_id = chunk_from_str(sw_id_str[0]);
+ sw_locator = chunk_from_str(sw_locator_str);
+
+ /* Software Identity with Software Locator */
+ sw_record = swima_record_create(record_id, sw_id, sw_locator),
+ ck_assert(sw_record);
+ sw_record_cp = sw_record->get_ref(sw_record);
+
+ ck_assert(record_id == sw_record->get_record_id(sw_record));
+ ck_assert_chunk_eq(sw_id, sw_record->get_sw_id(sw_record, NULL));
+ ck_assert_chunk_eq(sw_id, sw_record->get_sw_id(sw_record, &locator));
+ ck_assert_chunk_eq(locator, sw_locator);
+
+ sw_record->set_data_model(sw_record, ita_data_model);
+ ck_assert(pen_type_equals(sw_record->get_data_model(sw_record),
+ ita_data_model));
+
+ sw_record->set_source_id(sw_record, source_id);
+ ck_assert(source_id == sw_record->get_source_id(sw_record));
+
+ sw_record->set_record(sw_record, record);
+ ck_assert_chunk_eq(record, sw_record->get_record(sw_record));
+
+ sw_record->destroy(sw_record);
+ sw_record_cp->destroy(sw_record);
+
+ /* Software Identity without Software Locator */
+ sw_record = swima_record_create(record_id, sw_id, chunk_empty),
+ ck_assert(sw_record);
+ ck_assert_chunk_eq(sw_id, sw_record->get_sw_id(sw_record, &locator));
+ ck_assert(locator.ptr == NULL && locator.len == 0);
+
+ ck_assert(pen_type_equals(swima_data_model_iso_2015_swid_xml,
+ sw_record->get_data_model(sw_record)));
+
+ sw_record->destroy(sw_record);
+}
+END_TEST
+
+typedef struct req_data_t req_data_t;
+
+struct req_data_t {
+ uint8_t flags;
+ uint32_t request_id;
+ uint32_t earliest_eid;
+ uint32_t sw_id_count;
+ chunk_t value;
+};
+
+static req_data_t req_data[] = {
+ { IETF_SWIMA_ATTR_REQ_FLAG_NONE, 1, 0, 0, chunk_from_chars(
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x00)
+ },
+ { IETF_SWIMA_ATTR_REQ_FLAG_R, 2, 15, 1, chunk_from_chars(
+ 0x20, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
+ 0x00, 0x0F, 0x00, 0x1f, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67,
+ 0x73, 0x77, 0x61, 0x6e, 0x2e, 0x6f, 0x72, 0x67, 0x5f, 0x73,
+ 0x74, 0x72, 0x6f, 0x6e, 0x67, 0x53, 0x77, 0x61, 0x6e, 0x5f,
+ 0x35, 0x2e, 0x33, 0x2e, 0x33)
+ },
+ { IETF_SWIMA_ATTR_REQ_FLAG_S, 3, 256, 2, chunk_from_chars(
+ 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x1f, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67,
+ 0x73, 0x77, 0x61, 0x6e, 0x2e, 0x6f, 0x72, 0x67, 0x5f, 0x73,
+ 0x74, 0x72, 0x6f, 0x6e, 0x67, 0x53, 0x77, 0x61, 0x6e, 0x5f,
+ 0x35, 0x2e, 0x33, 0x2e, 0x33, 0x00, 0x33, 0x73, 0x74, 0x72,
+ 0x6f, 0x6e, 0x67, 0x73, 0x77, 0x61, 0x6e, 0x2e, 0x6f, 0x72,
+ 0x67, 0x5f, 0x36, 0x32, 0x32, 0x35, 0x31, 0x61, 0x61, 0x36,
+ 0x2d, 0x31, 0x61, 0x30, 0x31, 0x2d, 0x34, 0x37, 0x39, 0x62,
+ 0x2d, 0x61, 0x65, 0x61, 0x36, 0x2d, 0x66, 0x33, 0x64, 0x63,
+ 0x66, 0x30, 0x61, 0x62, 0x31, 0x66, 0x31, 0x61)
+ },
+};
+
+START_TEST(test_imcv_swima_sw_req)
+{
+ pen_type_t type;
+ pen_type_t pen_type = { PEN_IETF, IETF_ATTR_SW_REQUEST };
+ pa_tnc_attr_t *attr, *attr1, *attr2;
+ ietf_swima_attr_req_t *c_attr;
+ swima_record_t *target;
+ swima_inventory_t *targets;
+ chunk_t sw_id, value;
+ enumerator_t *enumerator;
+ uint32_t offset;
+ int n;
+
+ attr = ietf_swima_attr_req_create(req_data[_i].flags,
+ req_data[_i].request_id);
+ ck_assert(attr);
+
+ type = attr->get_type(attr);
+ ck_assert(pen_type_equals(type, pen_type));
+
+ ck_assert(attr->get_noskip_flag(attr) == FALSE);
+ attr->set_noskip_flag(attr, TRUE);
+ ck_assert(attr->get_noskip_flag(attr) == TRUE);
+
+ targets = swima_inventory_create();
+ targets->set_eid(targets, req_data[_i].earliest_eid, 0);
+
+ for (n = 0; n < req_data[_i].sw_id_count; n++)
+ {
+ sw_id = chunk_from_str(sw_id_str[n]);
+ target = swima_record_create(0, sw_id, chunk_empty);
+ targets->add(targets, target);
+ }
+ c_attr = (ietf_swima_attr_req_t*)attr;
+ c_attr->set_targets(c_attr, targets);
+ c_attr->set_targets(c_attr, targets);
+ targets->destroy(targets);
+
+ attr->build(attr);
+ attr->build(attr);
+ value = attr->get_value(attr);
+ ck_assert_chunk_eq(value, req_data[_i].value);
+
+ attr1 = attr->get_ref(attr);
+ attr->destroy(attr);
+
+ attr2 = ietf_swima_attr_req_create_from_data(value.len, value);
+ ck_assert(attr2);
+
+ attr1->destroy(attr1);
+ ck_assert(attr2->process(attr2, &offset) == SUCCESS);
+
+ type = attr2->get_type(attr2);
+ ck_assert(pen_type_equals(type, pen_type));
+
+ c_attr = (ietf_swima_attr_req_t*)attr2;
+ ck_assert(c_attr->get_flags(c_attr) == req_data[_i].flags);
+ ck_assert(c_attr->get_request_id(c_attr) == req_data[_i].request_id);
+
+ targets = c_attr->get_targets(c_attr);
+ ck_assert(targets->get_eid(targets, NULL) == req_data[_i].earliest_eid);
+
+ enumerator = targets->create_enumerator(targets);
+ ck_assert(enumerator);
+ n = 0;
+ while (enumerator->enumerate(enumerator, &target))
+ {
+ sw_id = target->get_sw_id(target, NULL);
+ ck_assert(chunk_equals(sw_id, chunk_from_str(sw_id_str[n++])));
+ }
+ enumerator->destroy(enumerator);
+
+ attr2->destroy(attr2);
+}
+END_TEST
+
+START_TEST(test_imcv_swima_sw_req_trunc)
+{
+ pa_tnc_attr_t *attr;
+ chunk_t data;
+ uint32_t offset = 100;
+
+ /* Data smaller than minimum size */
+ attr = ietf_swima_attr_req_create_from_data(0, chunk_empty);
+ ck_assert(attr);
+ ck_assert(attr->process(attr, &offset) == FAILED && offset == 0);
+ attr->destroy(attr);
+
+ /* Truncate first SW ID */
+ data = req_data[2].value;
+ data.len = 14;
+ attr = ietf_swima_attr_req_create_from_data(data.len, data);
+ ck_assert(attr);
+ ck_assert(attr->process(attr, &offset) == FAILED && offset == 12);
+ attr->destroy(attr);
+
+ /* Truncate second SW ID */
+ data = req_data[2].value;
+ data.len = 47;
+ attr = ietf_swima_attr_req_create_from_data(data.len, data);
+ ck_assert(attr);
+ ck_assert(attr->process(attr, &offset) == FAILED && offset == 45);
+ attr->destroy(attr);
+
+ /* Segmentation */
+ data = req_data[2].value;
+ data.len = 50;
+ attr = ietf_swima_attr_req_create_from_data(req_data[2].value.len, data);
+ ck_assert(attr);
+ ck_assert(attr->process(attr, &offset) == NEED_MORE);
+ data = chunk_skip(req_data[2].value, 50);
+ attr->add_segment(attr, data);
+ ck_assert(attr->process(attr, &offset) == SUCCESS);
+ attr->destroy(attr);
+}
+END_TEST
+
+static pen_type_t sw_inv_types[] = {
+ { PEN_IETF, IETF_ATTR_SW_INVENTORY },
+ { PEN_IETF, IETF_ATTR_SW_ID_INVENTORY }
+};
+
+typedef struct sw_inv_data_t sw_inv_data_t;
+
+struct sw_inv_data_t {
+ uint8_t flags;
+ uint32_t request_id;
+ uint32_t eid_epoch;
+ uint32_t last_eid;
+ chunk_t value;
+};
+
+static sw_inv_data_t sw_inv_data[] = {
+ { IETF_SWIMA_ATTR_SW_INV_FLAG_NONE, 0xaabbccd0, 0x87654321, 0x00000007,
+ chunk_from_chars(
+ 0x00, 0x00, 0x00, 0x00, 0xAA, 0xBB, 0xCC, 0xD0, 0x87, 0x65,
+ 0x43, 0x21, 0x00, 0x00, 0x00, 0x07)
+ },
+ { IETF_SWIMA_ATTR_SW_INV_FLAG_NONE, 0xaabbccd1, 0x87654321, 0x00000007,
+ chunk_from_chars(
+ 0x00, 0x00, 0x00, 0x00, 0xAA, 0xBB, 0xCC, 0xD1, 0x87, 0x65,
+ 0x43, 0x21, 0x00, 0x00, 0x00, 0x07)
+ },
+ { IETF_SWIMA_ATTR_SW_INV_FLAG_NONE, 0xaabbccd2, 0x12345678, 0x00000030,
+ chunk_from_chars(
+ 0x00, 0x00, 0x00, 0x01, 0xAA, 0xBB, 0xCC, 0xD2, 0x12, 0x34,
+ 0x56, 0x78, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1F, 0x73, 0x74, 0x72,
+ 0x6F, 0x6E, 0x67, 0x73, 0x77, 0x61, 0x6E, 0x2E, 0x6F, 0x72,
+ 0x67, 0x5F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x53, 0x77,
+ 0x61, 0x6E, 0x5F, 0x35, 0x2E, 0x33, 0x2E, 0x33, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x31, 0x3C, 0x53, 0x6F, 0x66, 0x74, 0x77,
+ 0x61, 0x72, 0x65, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x74,
+ 0x79, 0x20, 0x74, 0x61, 0x67, 0x49, 0x64, 0x3D, 0x22, 0x61,
+ 0x62, 0x63, 0x22, 0x3E, 0x3C, 0x2F, 0x53, 0x6F, 0x66, 0x74,
+ 0x77, 0x61, 0x72, 0x65, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69,
+ 0x74, 0x79, 0x3E)
+ },
+ { IETF_SWIMA_ATTR_SW_INV_FLAG_NONE, 0xaabbccd3, 0x12345678, 0x00000030,
+ chunk_from_chars(
+ 0x00, 0x00, 0x00, 0x01, 0xAA, 0xBB, 0xCC, 0xD3, 0x12, 0x34,
+ 0x56, 0x78, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1F, 0x73, 0x74, 0x72,
+ 0x6F, 0x6E, 0x67, 0x73, 0x77, 0x61, 0x6E, 0x2E, 0x6F, 0x72,
+ 0x67, 0x5F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x53, 0x77,
+ 0x61, 0x6E, 0x5F, 0x35, 0x2E, 0x33, 0x2E, 0x33, 0x00, 0x00)
+ },
+ { IETF_SWIMA_ATTR_SW_INV_FLAG_S_F, 0xaabbccd4, 0x12345678, 0x00000034,
+ chunk_from_chars(
+ 0x80, 0x00, 0x00, 0x02, 0xAA, 0xBB, 0xCC, 0xD4, 0x12, 0x34,
+ 0x56, 0x78, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1F, 0x73, 0x74, 0x72,
+ 0x6F, 0x6E, 0x67, 0x73, 0x77, 0x61, 0x6E, 0x2E, 0x6F, 0x72,
+ 0x67, 0x5F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x53, 0x77,
+ 0x61, 0x6E, 0x5F, 0x35, 0x2E, 0x33, 0x2E, 0x33, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x31, 0x3C, 0x53, 0x6F, 0x66, 0x74, 0x77,
+ 0x61, 0x72, 0x65, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x74,
+ 0x79, 0x20, 0x74, 0x61, 0x67, 0x49, 0x64, 0x3D, 0x22, 0x61,
+ 0x62, 0x63, 0x22, 0x3E, 0x3C, 0x2F, 0x53, 0x6F, 0x66, 0x74,
+ 0x77, 0x61, 0x72, 0x65, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69,
+ 0x74, 0x79, 0x3E, 0x00, 0x00, 0x00, 0x01, 0x00, 0x90, 0x2A,
+ 0x19, 0x11, 0x00, 0x33, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67,
+ 0x73, 0x77, 0x61, 0x6E, 0x2E, 0x6F, 0x72, 0x67, 0x5F, 0x36,
+ 0x32, 0x32, 0x35, 0x31, 0x61, 0x61, 0x36, 0x2D, 0x31, 0x61,
+ 0x30, 0x31, 0x2D, 0x34, 0x37, 0x39, 0x62, 0x2D, 0x61, 0x65,
+ 0x61, 0x36, 0x2D, 0x66, 0x33, 0x64, 0x63, 0x66, 0x30, 0x61,
+ 0x62, 0x31, 0x66, 0x31, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x31, 0x3C, 0x53, 0x6F, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
+ 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x74, 0x79, 0x20, 0x74,
+ 0x61, 0x67, 0x49, 0x64, 0x3D, 0x22, 0x64, 0x65, 0x66, 0x22,
+ 0x3E, 0x3C, 0x2F, 0x53, 0x6F, 0x66, 0x74, 0x77, 0x61, 0x72,
+ 0x65, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x74, 0x79, 0x3E)
+ },
+ { IETF_SWIMA_ATTR_SW_INV_FLAG_S_F, 0xaabbccd5, 0x12345678, 0x00000034,
+ chunk_from_chars(
+ 0x80, 0x00, 0x00, 0x02, 0xAA, 0xBB, 0xCC, 0xD5, 0x12, 0x34,
+ 0x56, 0x78, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1F, 0x73, 0x74, 0x72,
+ 0x6F, 0x6E, 0x67, 0x73, 0x77, 0x61, 0x6E, 0x2E, 0x6F, 0x72,
+ 0x67, 0x5F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x53, 0x77,
+ 0x61, 0x6E, 0x5F, 0x35, 0x2E, 0x33, 0x2E, 0x33, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x90, 0x2A, 0x19, 0x11, 0x00,
+ 0x33, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x73, 0x77, 0x61,
+ 0x6E, 0x2E, 0x6F, 0x72, 0x67, 0x5F, 0x36, 0x32, 0x32, 0x35,
+ 0x31, 0x61, 0x61, 0x36, 0x2D, 0x31, 0x61, 0x30, 0x31, 0x2D,
+ 0x34, 0x37, 0x39, 0x62, 0x2D, 0x61, 0x65, 0x61, 0x36, 0x2D,
+ 0x66, 0x33, 0x64, 0x63, 0x66, 0x30, 0x61, 0x62, 0x31, 0x66,
+ 0x31, 0x61, 0x00, 0x00)
+ }
+};
+
+START_TEST(test_imcv_swima_inv)
+{
+ pen_type_t type, data_model;
+ chunk_t sw_id, record, value;
+ ietf_swima_attr_sw_inv_t *c_attr;
+ pa_tnc_attr_t *attr, *attr1, *attr2;
+ swima_record_t *sw_record;
+ swima_inventory_t *sw_inv;
+ enumerator_t *enumerator;
+ uint32_t offset, epoch;
+ uint8_t source_id;
+ bool sw_id_only = _i % 2;
+ int n;
+
+ attr = ietf_swima_attr_sw_inv_create(sw_inv_data[_i].flags,
+ sw_inv_data[_i].request_id,
+ sw_id_only);
+
+ sw_inv = swima_inventory_create();
+ sw_inv->set_eid(sw_inv, sw_inv_data[_i].last_eid, sw_inv_data[_i].eid_epoch);
+ for (n = 0; n < _i/2; n++)
+ {
+ sw_id = chunk_from_str(sw_id_str[n]);
+ sw_record = swima_record_create(n, sw_id, chunk_empty);
+
+ if (n == 1)
+ {
+ sw_record->set_data_model(sw_record, ita_data_model);
+ sw_record->set_source_id(sw_record, 0x11);
+ }
+ if (!sw_id_only)
+ {
+ record = chunk_from_str(sw_record_str[n]);
+ sw_record->set_record(sw_record, record);
+ }
+ sw_inv->add(sw_inv, sw_record);
+ }
+ c_attr = (ietf_swima_attr_sw_inv_t*)attr;
+ c_attr->set_inventory(c_attr, sw_inv);
+ c_attr->set_inventory(c_attr, sw_inv);
+
+ attr->build(attr);
+ attr->build(attr);
+ sw_inv->destroy(sw_inv);
+
+ type = attr->get_type(attr);
+ ck_assert(pen_type_equals(type, sw_inv_types[sw_id_only]));
+
+ ck_assert(attr->get_noskip_flag(attr) == FALSE);
+ attr->set_noskip_flag(attr, TRUE);
+ ck_assert(attr->get_noskip_flag(attr) == TRUE);
+
+ value = attr->get_value(attr);
+ ck_assert_chunk_eq(value, sw_inv_data[_i].value);
+
+ attr1 = attr->get_ref(attr);
+ attr->destroy(attr);
+
+ attr2 = ietf_swima_attr_sw_inv_create_from_data(value.len, value,
+ sw_id_only);
+ ck_assert(attr2);
+ attr1->destroy(attr1);
+ ck_assert(attr2->process(attr2, &offset) == SUCCESS);
+
+ type = attr2->get_type(attr2);
+ ck_assert(pen_type_equals(type, sw_inv_types[sw_id_only]));
+
+ c_attr = (ietf_swima_attr_sw_inv_t*)attr2;
+ ck_assert(c_attr->get_flags(c_attr) == sw_inv_data[_i].flags);
+ ck_assert(c_attr->get_record_count(c_attr) == 0);
+ ck_assert(c_attr->get_request_id(c_attr) == sw_inv_data[_i].request_id);
+
+ sw_inv = c_attr->get_inventory(c_attr);
+ ck_assert(sw_inv->get_eid(sw_inv, NULL) == sw_inv_data[_i].last_eid);
+ ck_assert(sw_inv->get_eid(sw_inv, &epoch) == sw_inv_data[_i].last_eid);
+ ck_assert(epoch == sw_inv_data[_i].eid_epoch);
+ ck_assert(sw_inv);
+ ck_assert(sw_inv->get_count(sw_inv) == _i/2);
+
+ enumerator = sw_inv->create_enumerator(sw_inv);
+ ck_assert(enumerator);
+
+ n = 0;
+ while (enumerator->enumerate(enumerator, &sw_record))
+ {
+ ck_assert(sw_record->get_record_id(sw_record) == n);
+ data_model = sw_record->get_data_model(sw_record);
+ ck_assert(pen_type_equals(data_model, (n == 1) ? ita_data_model :
+ swima_data_model_iso_2015_swid_xml));
+ source_id = sw_record->get_source_id(sw_record);
+ ck_assert(source_id == (n == 1 ? 0x11 : 0x00));
+ n++;
+ }
+ enumerator->destroy(enumerator);
+ ck_assert(n == _i/2);
+
+ attr2->destroy(attr2);
+}
+END_TEST
+
+/**
+ * Offsets in sw_inv_data[4].value
+ *
+ * 0 constant header
+ * 12 segment 1 - 12 octets
+ * 16 record_id
+ * 18 segment 2 - 6 octets
+ * 20 data_model_pen
+ * 22 segment 3 - 4 octets
+ * 23 segment 4 - 1 octet
+ * 23 data_model_type
+ * 24 segment 5 - 1 octet
+ * 24 source_id
+ * 25 sw_id
+ * 26 segment 6 - 2 octets
+ * 58 sw_locator
+ * 59 segment 7 - 33 octets
+ * 60 record
+ * 62 segment 8 - 3 octets
+ * 113 sw record 2
+ * 114 segment 9 - 52 octets
+ * 230 segment 10 - 116 octets
+ */
+
+START_TEST(test_imcv_swima_sw_inv_trunc)
+{
+ pa_tnc_attr_t *attr;
+ ietf_swima_attr_sw_inv_t *c_attr;
+ chunk_t data;
+ swima_inventory_t *sw_inv;
+ size_t len = sw_inv_data[4].value.len;
+ uint32_t offset = 100;
+
+ /* Data smaller than minimum size */
+ attr = ietf_swima_attr_sw_inv_create_from_data(0, chunk_empty, FALSE);
+ ck_assert(attr);
+ ck_assert(attr->process(attr, &offset) == FAILED && offset == 0);
+ attr->destroy(attr);
+
+ /* Length larger than data */
+ data = sw_inv_data[4].value;
+ attr = ietf_swima_attr_sw_inv_create_from_data(len + 2, data, FALSE);
+ ck_assert(attr);
+ ck_assert(attr->process(attr, &offset) == FAILED && offset == len);
+ attr->destroy(attr);
+
+ /* Segment 1 truncates minimum size */
+ data = sw_inv_data[4].value;
+ data.len = 12;
+ attr = ietf_swima_attr_sw_inv_create_from_data(len, data, FALSE);
+ ck_assert(attr);
+ ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+ /* Segment 2 truncates record_id */
+ data = chunk_skip(sw_inv_data[4].value, 12);
+ data.len = 6;
+ attr->add_segment(attr, data);
+ ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+ /* Segment 3 truncates data_model_pen */
+ data = chunk_skip(sw_inv_data[4].value, 18);
+ data.len = 4;
+ attr->add_segment(attr, data);
+ ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+ /* Segment 4 truncates data_model_type */
+ data = chunk_skip(sw_inv_data[4].value, 22);
+ data.len = 1;
+ attr->add_segment(attr, data);
+ ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+ /* Segment 5 truncates source_id */
+ data = chunk_skip(sw_inv_data[4].value, 23);
+ data.len = 1;
+ attr->add_segment(attr, data);
+ ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+ /* Segment 6 truncates sw_id */
+ data = chunk_skip(sw_inv_data[4].value, 24);
+ data.len = 2;
+ attr->add_segment(attr, data);
+ ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+ /* Segment 7 truncates sw_locator */
+ data = chunk_skip(sw_inv_data[4].value, 26);
+ data.len = 33;
+ attr->add_segment(attr, data);
+ ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+ /* Segment 8 truncates record */
+ data = chunk_skip(sw_inv_data[4].value, 59);
+ data.len = 3;
+ attr->add_segment(attr, data);
+ ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+ /* Segment 9 truncates second sw_record */
+ data = chunk_skip(sw_inv_data[4].value, 62);
+ data.len = 52;
+ attr->add_segment(attr, data);
+ ck_assert(attr->process(attr, &offset) == SUCCESS);
+
+ /* Process first inventory entry */
+ c_attr = (ietf_swima_attr_sw_inv_t*)attr;
+ sw_inv = c_attr->get_inventory(c_attr);
+ ck_assert(sw_inv->get_count(sw_inv) == 1);
+ c_attr->clear_inventory(c_attr);
+
+ /* Segment 10 truncates second sw_record */
+ data = chunk_skip(sw_inv_data[4].value, 114);
+ data.len = 116;
+ attr->add_segment(attr, data);
+ ck_assert(attr->process(attr, &offset) == SUCCESS);
+
+ /* Process second inventory entry */
+ sw_inv = c_attr->get_inventory(c_attr);
+ ck_assert(sw_inv->get_count(sw_inv) == 1);
+ c_attr->clear_inventory(c_attr);
+
+ attr->destroy(attr);
+}
+END_TEST
+
+static char* sw_ev_timestamp_str[] = {
+ "2017-05-30T18:09:25Z",
+ "2017-06-14T15:38:00Z"
+};
+
+START_TEST(test_imcv_swima_event)
+{
+ chunk_t sw_id, sw_timestamp, timestamp;
+ swima_event_t *sw_event, *sw_event_cp;
+ swima_record_t *sw_record;
+ uint32_t record_id = 1, eid = 7;
+ uint8_t action = SWIMA_EVENT_ACTION_CREATION;
+
+ sw_id = chunk_from_str(sw_id_str[0]);
+ sw_timestamp = chunk_from_str(sw_ev_timestamp_str[0]);
+
+ /* Software Identity without Software Locator */
+ sw_record = swima_record_create(record_id, sw_id, chunk_empty),
+ ck_assert(sw_record);
+
+ sw_event = swima_event_create(eid, sw_timestamp, action, sw_record);
+ ck_assert(sw_event);
+ sw_event_cp = sw_event->get_ref(sw_event);
+
+ ck_assert(sw_event->get_eid(sw_event, NULL) == eid);
+ ck_assert(sw_event->get_eid(sw_event, &timestamp) == eid);
+ ck_assert_chunk_eq(sw_timestamp, timestamp);
+ ck_assert(sw_event->get_action(sw_event) == action);
+ sw_event->destroy(sw_event);
+
+ sw_record = sw_event_cp->get_sw_record(sw_event_cp);
+ ck_assert(sw_record);
+ ck_assert(sw_record->get_record_id(sw_record) == record_id);
+ ck_assert_chunk_eq(sw_record->get_sw_id(sw_record, NULL), sw_id);
+ sw_event_cp->destroy(sw_event_cp);
+}
+END_TEST
+
+static pen_type_t sw_ev_types[] = {
+ { PEN_IETF, IETF_ATTR_SW_EVENTS },
+ { PEN_IETF, IETF_ATTR_SW_ID_EVENTS }
+};
+
+typedef struct sw_ev_data_t sw_ev_data_t;
+
+struct sw_ev_data_t {
+ uint8_t flags;
+ uint32_t request_id;
+ uint32_t eid_epoch;
+ uint32_t last_eid;
+ uint32_t last_consulted_eid;
+ chunk_t value;
+};
+
+static sw_ev_data_t sw_ev_data[] = {
+ { IETF_SWIMA_ATTR_SW_EV_FLAG_NONE, 0xaabbccd0, 0x87654321, 0x00000007,
+ 0x00000007, chunk_from_chars(
+ 0x00, 0x00, 0x00, 0x00, 0xAA, 0xBB, 0xCC, 0xD0, 0x87, 0x65,
+ 0x43, 0x21, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07)
+ },
+ { IETF_SWIMA_ATTR_SW_EV_FLAG_NONE, 0xaabbccd1, 0x87654321, 0x00000007,
+ 0x00000007, chunk_from_chars(
+ 0x00, 0x00, 0x00, 0x00, 0xAA, 0xBB, 0xCC, 0xD1, 0x87, 0x65,
+ 0x43, 0x21, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07)
+ },
+ { IETF_SWIMA_ATTR_SW_EV_FLAG_NONE, 0xaabbccd2, 0x12345678, 0x00000030,
+ 0x00000030, chunk_from_chars(
+ 0x00, 0x00, 0x00, 0x01, 0xAA, 0xBB, 0xCC, 0xD2, 0x12, 0x34,
+ 0x56, 0x78, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30,
+ 0x00, 0x00, 0x00, 0x30, '2', '0', '1', '7', '-', '0',
+ '5', '-', '3', '0', 'T', '1', '8', ':', '0', '9',
+ ':', '2', '5', 'Z', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x01, 0x00, 0x1F, 0x73, 0x74, 0x72, 0x6F,
+ 0x6E, 0x67, 0x73, 0x77, 0x61, 0x6E, 0x2E, 0x6F, 0x72, 0x67,
+ 0x5F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x53, 0x77, 0x61,
+ 0x6E, 0x5F, 0x35, 0x2E, 0x33, 0x2E, 0x33, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x31, 0x3C, 0x53, 0x6F, 0x66, 0x74, 0x77, 0x61,
+ 0x72, 0x65, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x74, 0x79,
+ 0x20, 0x74, 0x61, 0x67, 0x49, 0x64, 0x3D, 0x22, 0x61, 0x62,
+ 0x63, 0x22, 0x3E, 0x3C, 0x2F, 0x53, 0x6F, 0x66, 0x74, 0x77,
+ 0x61, 0x72, 0x65, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x74,
+ 0x79, 0x3E)
+ },
+ { IETF_SWIMA_ATTR_SW_EV_FLAG_NONE, 0xaabbccd3, 0x12345678, 0x00000030,
+ 0x00000030, chunk_from_chars(
+ 0x00, 0x00, 0x00, 0x01, 0xAA, 0xBB, 0xCC, 0xD3, 0x12, 0x34,
+ 0x56, 0x78, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30,
+ 0x00, 0x00, 0x00, 0x30, '2', '0', '1', '7', '-', '0',
+ '5', '-', '3', '0', 'T', '1', '8', ':', '0', '9',
+ ':', '2', '5', 'Z', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x01, 0x00, 0x1F, 0x73, 0x74, 0x72, 0x6F,
+ 0x6E, 0x67, 0x73, 0x77, 0x61, 0x6E, 0x2E, 0x6F, 0x72, 0x67,
+ 0x5F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x53, 0x77, 0x61,
+ 0x6E, 0x5F, 0x35, 0x2E, 0x33, 0x2E, 0x33, 0x00, 0x00)
+ },
+ { IETF_SWIMA_ATTR_SW_EV_FLAG_S_F, 0xaabbccd4, 0x12345678, 0x00000050,
+ 0x00000034, chunk_from_chars(
+ 0x80, 0x00, 0x00, 0x02, 0xAA, 0xBB, 0xCC, 0xD4, 0x12, 0x34,
+ 0x56, 0x78, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x34,
+ 0x00, 0x00, 0x00, 0x30, '2', '0', '1', '7', '-', '0',
+ '5', '-', '3', '0', 'T', '1', '8', ':', '0', '9',
+ ':', '2', '5', 'Z', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x01, 0x00, 0x1F, 0x73, 0x74, 0x72, 0x6F,
+ 0x6E, 0x67, 0x73, 0x77, 0x61, 0x6E, 0x2E, 0x6F, 0x72, 0x67,
+ 0x5F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x53, 0x77, 0x61,
+ 0x6E, 0x5F, 0x35, 0x2E, 0x33, 0x2E, 0x33, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x31, 0x3C, 0x53, 0x6F, 0x66, 0x74, 0x77, 0x61,
+ 0x72, 0x65, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x74, 0x79,
+ 0x20, 0x74, 0x61, 0x67, 0x49, 0x64, 0x3D, 0x22, 0x61, 0x62,
+ 0x63, 0x22, 0x3E, 0x3C, 0x2F, 0x53, 0x6F, 0x66, 0x74, 0x77,
+ 0x61, 0x72, 0x65, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x74,
+ 0x79, 0x3E, 0x00, 0x00, 0x00, 0x34, '2', '0', '1', '7',
+ '-', '0', '6', '-', '1', '4', 'T', '1', '5', ':',
+ '3', '8', ':', '0', '0', 'Z', 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x90, 0x2A, 0x19, 0x11, 0x02, 0x00, 0x33, 0x73, 0x74,
+ 0x72, 0x6F, 0x6E, 0x67, 0x73, 0x77, 0x61, 0x6E, 0x2E, 0x6F,
+ 0x72, 0x67, 0x5F, 0x36, 0x32, 0x32, 0x35, 0x31, 0x61, 0x61,
+ 0x36, 0x2D, 0x31, 0x61, 0x30, 0x31, 0x2D, 0x34, 0x37, 0x39,
+ 0x62, 0x2D, 0x61, 0x65, 0x61, 0x36, 0x2D, 0x66, 0x33, 0x64,
+ 0x63, 0x66, 0x30, 0x61, 0x62, 0x31, 0x66, 0x31, 0x61, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x31, 0x3C, 0x53, 0x6F, 0x66, 0x74,
+ 0x77, 0x61, 0x72, 0x65, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69,
+ 0x74, 0x79, 0x20, 0x74, 0x61, 0x67, 0x49, 0x64, 0x3D, 0x22,
+ 0x64, 0x65, 0x66, 0x22, 0x3E, 0x3C, 0x2F, 0x53, 0x6F, 0x66,
+ 0x74, 0x77, 0x61, 0x72, 0x65, 0x49, 0x64, 0x65, 0x6E, 0x74,
+ 0x69, 0x74, 0x79, 0x3E)
+ },
+ { IETF_SWIMA_ATTR_SW_EV_FLAG_S_F, 0xaabbccd5, 0x12345678, 0x00000050,
+ 0x00000034, chunk_from_chars(
+ 0x80, 0x00, 0x00, 0x02, 0xAA, 0xBB, 0xCC, 0xD5, 0x12, 0x34,
+ 0x56, 0x78, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x34,
+ 0x00, 0x00, 0x00, 0x30, '2', '0', '1', '7', '-', '0',
+ '5', '-', '3', '0', 'T', '1', '8', ':', '0', '9',
+ ':', '2', '5', 'Z', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x01, 0x00, 0x1F, 0x73, 0x74, 0x72, 0x6F,
+ 0x6E, 0x67, 0x73, 0x77, 0x61, 0x6E, 0x2E, 0x6F, 0x72, 0x67,
+ 0x5F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x53, 0x77, 0x61,
+ 0x6E, 0x5F, 0x35, 0x2E, 0x33, 0x2E, 0x33, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x34, '2', '0', '1', '7', '-', '0', '6',
+ '-', '1', '4', 'T', '1', '5', ':', '3', '8', ':',
+ '0', '0', 'Z', 0x00, 0x00, 0x00, 0x01, 0x00, 0x90, 0x2A,
+ 0x19, 0x11, 0x02, 0x00, 0x33, 0x73, 0x74, 0x72, 0x6F, 0x6E,
+ 0x67, 0x73, 0x77, 0x61, 0x6E, 0x2E, 0x6F, 0x72, 0x67, 0x5F,
+ 0x36, 0x32, 0x32, 0x35, 0x31, 0x61, 0x61, 0x36, 0x2D, 0x31,
+ 0x61, 0x30, 0x31, 0x2D, 0x34, 0x37, 0x39, 0x62, 0x2D, 0x61,
+ 0x65, 0x61, 0x36, 0x2D, 0x66, 0x33, 0x64, 0x63, 0x66, 0x30,
+ 0x61, 0x62, 0x31, 0x66, 0x31, 0x61, 0x00, 0x00)
+ }
+};
+
+START_TEST(test_imcv_swima_ev)
+{
+ pen_type_t type, data_model;
+ chunk_t sw_id, record, timestamp, value;
+ ietf_swima_attr_sw_ev_t *c_attr;
+ pa_tnc_attr_t *attr, *attr1, *attr2;
+ swima_record_t *sw_record;
+ swima_event_t *sw_event;
+ swima_events_t *sw_ev;
+ enumerator_t *enumerator;
+ uint32_t offset, epoch, eid, last_eid;
+ uint8_t source_id, action;
+ bool sw_id_only = _i % 2;
+ int n;
+
+ attr = ietf_swima_attr_sw_ev_create(sw_ev_data[_i].flags,
+ sw_ev_data[_i].request_id,
+ sw_id_only);
+ sw_ev = swima_events_create();
+ sw_ev->set_eid(sw_ev, sw_ev_data[_i].last_consulted_eid,
+ sw_ev_data[_i].eid_epoch);
+ if (sw_ev_data[_i].last_consulted_eid < sw_ev_data[_i].last_eid)
+ {
+ sw_ev->set_last_eid(sw_ev, sw_ev_data[_i].last_eid);
+ }
+
+ for (n = 0; n < _i/2; n++)
+ {
+ sw_id = chunk_from_str(sw_id_str[n]);
+ sw_record = swima_record_create(n, sw_id, chunk_empty);
+
+ if (n == 1)
+ {
+ sw_record->set_data_model(sw_record, ita_data_model);
+ sw_record->set_source_id(sw_record, 0x11);
+ }
+ if (!sw_id_only)
+ {
+ record = chunk_from_str(sw_record_str[n]);
+ sw_record->set_record(sw_record, record);
+ }
+ eid = 0x30 + 4 * n;
+ timestamp = chunk_from_str(sw_ev_timestamp_str[n]);
+ action = n + 1;
+ sw_event = swima_event_create(eid, timestamp, action, sw_record);
+ sw_ev->add(sw_ev, sw_event);
+ }
+ c_attr = (ietf_swima_attr_sw_ev_t*)attr;
+ c_attr->set_events(c_attr, sw_ev);
+ c_attr->set_events(c_attr, sw_ev);
+
+ attr->build(attr);
+ attr->build(attr);
+ sw_ev->destroy(sw_ev);
+
+ type = attr->get_type(attr);
+ ck_assert(pen_type_equals(type, sw_ev_types[sw_id_only]));
+
+ ck_assert(attr->get_noskip_flag(attr) == FALSE);
+ attr->set_noskip_flag(attr, TRUE);
+ ck_assert(attr->get_noskip_flag(attr) == TRUE);
+
+ value = attr->get_value(attr);
+ ck_assert_chunk_eq(value, sw_ev_data[_i].value);
+
+ attr1 = attr->get_ref(attr);
+ attr->destroy(attr);
+
+ attr2 = ietf_swima_attr_sw_ev_create_from_data(value.len, value,
+ sw_id_only);
+ ck_assert(attr2);
+ attr1->destroy(attr1);
+ ck_assert(attr2->process(attr2, &offset) == SUCCESS);
+
+ type = attr2->get_type(attr2);
+ ck_assert(pen_type_equals(type, sw_ev_types[sw_id_only]));
+
+ c_attr = (ietf_swima_attr_sw_ev_t*)attr2;
+ ck_assert(c_attr->get_flags(c_attr) == sw_ev_data[_i].flags);
+ ck_assert(c_attr->get_event_count(c_attr) == 0);
+ ck_assert(c_attr->get_request_id(c_attr) == sw_ev_data[_i].request_id);
+
+ sw_ev = c_attr->get_events(c_attr);
+ ck_assert(sw_ev);
+ eid = sw_ev->get_eid(sw_ev, NULL, NULL);
+ ck_assert(eid == sw_ev_data[_i].last_consulted_eid);
+ eid = sw_ev->get_eid(sw_ev, &epoch, &last_eid);
+ ck_assert(eid == sw_ev_data[_i].last_consulted_eid);
+ ck_assert(epoch == sw_ev_data[_i].eid_epoch);
+ ck_assert(last_eid == sw_ev_data[_i].last_eid);
+ ck_assert(sw_ev->get_count(sw_ev) == _i/2);
+
+ enumerator = sw_ev->create_enumerator(sw_ev);
+ ck_assert(enumerator);
+
+ n = 0;
+ while (enumerator->enumerate(enumerator, &sw_event))
+ {
+ ck_assert(sw_event->get_eid(sw_event, &timestamp) == 0x30 + 4 * n);
+ ck_assert_chunk_eq(timestamp, chunk_from_str(sw_ev_timestamp_str[n]));
+ sw_record = sw_event->get_sw_record(sw_event);
+ ck_assert(sw_record);
+ ck_assert(sw_record->get_record_id(sw_record) == n);
+ data_model = sw_record->get_data_model(sw_record);
+ ck_assert(pen_type_equals(data_model, (n == 1) ? ita_data_model :
+ swima_data_model_iso_2015_swid_xml));
+ source_id = sw_record->get_source_id(sw_record);
+ ck_assert(source_id == (n == 1 ? 0x11 : 0x00));
+ n++;
+ }
+ enumerator->destroy(enumerator);
+ ck_assert(n == _i/2);
+
+ attr2->destroy(attr2);
+}
+END_TEST
+
+
+/**
+ * Offsets in sw_ev_data[4].value
+ *
+ * 0 constant header
+ * 16 segment 1 - 16 octets
+ * 20 eid
+ * 22 segment 2 - 6 octets
+ * 24 timestamp
+ * 26 segment 3 - 4 octets
+ * 44 record_id
+ * 46 segment 4 - 20 octets
+ * 48 data_model_pen
+ * 50 segment 5 - 4 octets
+ * 51 segment 6 - 1 octet
+ * 51 data_model_type
+ * 52 segment 7 - 1 octet
+ * 52 source_id
+ * 53 segment 8 - 1 octet
+ * 53 action
+ * 54 sw_id
+ * 55 segment 9 - 2 octets
+ * 87 sw_locator
+ * 88 segment 10 - 33 octets
+ * 89 record
+ * 91 segment 11 - 3 octets
+ * 142 sw record 2
+ * 143 segment 12 - 52 octets
+ * 284 segment 13 - 141 octets
+ */
+
+START_TEST(test_imcv_swima_sw_ev_trunc)
+{
+ pa_tnc_attr_t *attr;
+ ietf_swima_attr_sw_ev_t *c_attr;
+ chunk_t data;
+ swima_events_t *sw_ev;
+ size_t len = sw_ev_data[4].value.len;
+ uint32_t offset = 100;
+
+ /* Data smaller than minimum size */
+ attr = ietf_swima_attr_sw_ev_create_from_data(0, chunk_empty, FALSE);
+ ck_assert(attr);
+ ck_assert(attr->process(attr, &offset) == FAILED && offset == 0);
+ attr->destroy(attr);
+
+ /* Length larger than data */
+ data = sw_ev_data[4].value;
+ attr = ietf_swima_attr_sw_ev_create_from_data(len + 2, data, FALSE);
+ ck_assert(attr);
+ ck_assert(attr->process(attr, &offset) == FAILED && offset == len);
+ attr->destroy(attr);
+
+ /* Segment 1 truncates minimum size */
+ data = sw_ev_data[4].value;
+ data.len = 16;
+ attr = ietf_swima_attr_sw_ev_create_from_data(len, data, FALSE);
+ ck_assert(attr);
+ ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+ /* Segment 2 truncates eid */
+ data = chunk_skip(sw_ev_data[4].value, 16);
+ data.len = 6;
+ attr->add_segment(attr, data);
+ ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+ /* Segment 3 truncates timestamp */
+ data = chunk_skip(sw_ev_data[4].value, 22);
+ data.len = 4;
+ attr->add_segment(attr, data);
+ ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+ /* Segment 4 truncates record_id */
+ data = chunk_skip(sw_ev_data[4].value, 26);
+ data.len = 20;
+ attr->add_segment(attr, data);
+ ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+ /* Segment 5 truncates data_model_pen */
+ data = chunk_skip(sw_ev_data[4].value, 46);
+ data.len = 4;
+ attr->add_segment(attr, data);
+ ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+ /* Segment 6 truncates data_model_type */
+ data = chunk_skip(sw_ev_data[4].value, 50);
+ data.len = 1;
+ attr->add_segment(attr, data);
+ ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+ /* Segment 7 truncates source_id */
+ data = chunk_skip(sw_ev_data[4].value, 51);
+ data.len = 1;
+ attr->add_segment(attr, data);
+ ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+ /* Segment 8 truncates action */
+ data = chunk_skip(sw_ev_data[4].value, 52);
+ data.len = 1;
+ attr->add_segment(attr, data);
+ ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+ /* Segment 9 truncates sw_id */
+ data = chunk_skip(sw_ev_data[4].value, 53);
+ data.len = 2;
+ attr->add_segment(attr, data);
+ ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+ /* Segment 10 truncates sw_locator */
+ data = chunk_skip(sw_ev_data[4].value, 55);
+ data.len = 33;
+ attr->add_segment(attr, data);
+ ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+ /* Segment 11 truncates record */
+ data = chunk_skip(sw_ev_data[4].value, 88);
+ data.len = 3;
+ attr->add_segment(attr, data);
+ ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+ /* Segment 12 truncates second sw_entry */
+ data = chunk_skip(sw_ev_data[4].value, 91);
+ data.len = 52;
+ attr->add_segment(attr, data);
+ ck_assert(attr->process(attr, &offset) == SUCCESS);
+
+ /* Process first event entry */
+ c_attr = (ietf_swima_attr_sw_ev_t*)attr;
+ sw_ev = c_attr->get_events(c_attr);
+ ck_assert(sw_ev->get_count(sw_ev) == 1);
+ c_attr->clear_events(c_attr);
+
+ /* Segment 13 truncates second sw_record */
+ data = chunk_skip(sw_ev_data[4].value, 143);
+ data.len = 141;
+ attr->add_segment(attr, data);
+ ck_assert(attr->process(attr, &offset) == SUCCESS);
+
+ /* Process second event entry */
+ sw_ev = c_attr->get_events(c_attr);
+ ck_assert(sw_ev->get_count(sw_ev) == 1);
+ c_attr->clear_events(c_attr);
+ attr->destroy(attr);
+
+ /* Invalid Action values */
+ data = chunk_clone(sw_ev_data[2].value);
+ data.ptr[53] = 0;
+ attr = ietf_swima_attr_sw_ev_create_from_data(data.len, data, FALSE);
+ ck_assert(attr);
+ ck_assert(attr->process(attr, &offset) == FAILED);
+ attr->destroy(attr);
+
+ data.ptr[53] = SWIMA_EVENT_ACTION_LAST + 1;
+ attr = ietf_swima_attr_sw_ev_create_from_data(data.len, data, FALSE);
+ ck_assert(attr);
+ ck_assert(attr->process(attr, &offset) == FAILED && offset == 20);
+ attr->destroy(attr);
+ chunk_free(&data);
+}
+END_TEST
+
+START_TEST(test_imcv_swima_sw_collector)
+{
+ swima_collector_t *collector;
+ swima_inventory_t *targets, *inventory;
+ swima_events_t *events;
+ swima_record_t *sw_record;
+ swima_event_t *sw_event;
+ chunk_t sw_id, sw_locator, swid_tag;
+ enumerator_t *enumerator;
+ uint8_t source_id;
+ int item = 0, items;
+
+ targets = swima_inventory_create();
+ collector = swima_collector_create();
+
+ /* software identifier events only */
+ events = collector->collect_events(collector, TRUE, targets);
+ if (events)
+ {
+ items = events->get_count(events);
+ DBG1(DBG_IMC, "%d software identifiers collected", items);
+
+ enumerator = events->create_enumerator(events);
+ while (enumerator->enumerate(enumerator, &sw_event))
+ {
+ item++;
+ if ( item == 1 || item == items)
+ {
+ sw_record = sw_event->get_sw_record(sw_event);
+ sw_id = sw_record->get_sw_id(sw_record, NULL);
+ source_id =sw_record->get_source_id(sw_record);
+ DBG1(DBG_IMC, "source %u: %.*s", source_id, sw_id.len, sw_id.ptr);
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+
+ /* software identifier inventory only */
+ inventory = collector->collect_inventory(collector, TRUE, targets);
+ if (inventory)
+ {
+ items = inventory->get_count(inventory);
+ DBG1(DBG_IMC, "%d software identifiers collected", items);
+
+ enumerator = inventory->create_enumerator(inventory);
+ while (enumerator->enumerate(enumerator, &sw_record))
+ {
+ item++;
+ if ( item == 1 || item == items)
+ {
+ sw_id = sw_record->get_sw_id(sw_record, &sw_locator);
+ source_id =sw_record->get_source_id(sw_record);
+ DBG1(DBG_IMC, "source %u: %.*s", source_id, sw_id.len, sw_id.ptr);
+ if (sw_locator.len > 0)
+ {
+ DBG1(DBG_IMC, " locator: %.*s",
+ sw_locator.len, sw_locator.ptr);
+ }
+ targets->add(targets, sw_record->get_ref(sw_record));
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+
+ /* targeted software inventory */
+ inventory = collector->collect_inventory(collector, FALSE, targets);
+ if (inventory)
+ {
+ items = inventory->get_count(inventory);
+ DBG1(DBG_IMC, "%d SWID tags collected", items);
+
+ enumerator = inventory->create_enumerator(inventory);
+ while (enumerator->enumerate(enumerator, &sw_record))
+ {
+ sw_id = sw_record->get_sw_id(sw_record, NULL);
+ source_id =sw_record->get_source_id(sw_record);
+ swid_tag = sw_record->get_record(sw_record);
+ DBG1(DBG_IMC, "source %u: %.*s", source_id, sw_id.len, sw_id.ptr);
+ DBG2(DBG_IMC, "%B", &swid_tag);
+ }
+ enumerator->destroy(enumerator);
+ }
+
+ collector->destroy(collector);
+ targets->destroy(targets);
+}
+END_TEST
+
+Suite *imcv_swima_suite_create()
+{
+ Suite *s;
+ TCase *tc;
+
+ s = suite_create("imcv_swima");
+
+ tc = tcase_create("sw_record");
+ tcase_add_test(tc, test_imcv_swima_record);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("sw_req");
+ tcase_add_loop_test(tc, test_imcv_swima_sw_req, 0, countof(req_data));
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("sw_req_trunc");
+ tcase_add_test(tc, test_imcv_swima_sw_req_trunc);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("sw_inv");
+ tcase_add_loop_test(tc, test_imcv_swima_inv, 0, 6);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("sw_inv_trunc");
+ tcase_add_test(tc, test_imcv_swima_sw_inv_trunc);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("sw_event");
+ tcase_add_test(tc, test_imcv_swima_event);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("sw_ev");
+ tcase_add_loop_test(tc, test_imcv_swima_ev, 0, 6);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("sw_ev_trunc");
+ tcase_add_test(tc, test_imcv_swima_sw_ev_trunc);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("sw_collector");
+ tcase_add_test(tc, test_imcv_swima_sw_collector);
+ suite_add_tcase(s, tc);
+
+ return s;
+}