diff options
author | Andreas Steffen <andreas.steffen@strongswan.org> | 2013-08-16 14:13:35 +0200 |
---|---|---|
committer | Andreas Steffen <andreas.steffen@strongswan.org> | 2013-08-16 14:13:35 +0200 |
commit | 4d2bac37c48358544b2862120b91e11c547d1db6 (patch) | |
tree | 82745a14963d3e0563598f832577207e7a4d744a /src | |
parent | f405c15a597502d39318af8516b7316834dfff56 (diff) | |
download | strongswan-4d2bac37c48358544b2862120b91e11c547d1db6.tar.bz2 strongswan-4d2bac37c48358544b2862120b91e11c547d1db6.tar.xz |
Implemented SWID Tag Inventory attribute
Diffstat (limited to 'src')
-rw-r--r-- | src/libpts/Makefile.am | 4 | ||||
-rw-r--r-- | src/libpts/plugins/imc_swid/imc_swid.c | 59 | ||||
-rw-r--r-- | src/libpts/plugins/imv_swid/imv_swid_agent.c | 101 | ||||
-rw-r--r-- | src/libpts/swid/swid_tag.c | 86 | ||||
-rw-r--r-- | src/libpts/swid/swid_tag.h | 63 | ||||
-rw-r--r-- | src/libpts/tcg/swid/tcg_swid_attr_req.c | 2 | ||||
-rw-r--r-- | src/libpts/tcg/swid/tcg_swid_attr_tag_inv.c | 321 | ||||
-rw-r--r-- | src/libpts/tcg/swid/tcg_swid_attr_tag_inv.h | 92 | ||||
-rw-r--r-- | src/libpts/tcg/tcg_attr.c | 6 |
9 files changed, 692 insertions, 42 deletions
diff --git a/src/libpts/Makefile.am b/src/libpts/Makefile.am index 06246f392..e545e01bf 100644 --- a/src/libpts/Makefile.am +++ b/src/libpts/Makefile.am @@ -35,6 +35,7 @@ libpts_la_SOURCES = \ pts/components/ita/ita_comp_tboot.h pts/components/ita/ita_comp_tboot.c \ pts/components/ita/ita_comp_tgrub.h pts/components/ita/ita_comp_tgrub.c \ pts/components/tcg/tcg_comp_func_name.h pts/components/tcg/tcg_comp_func_name.c \ + swid/swid_tag.h swid/swid_tag.c \ swid/swid_tag_id.h swid/swid_tag_id.c \ tcg/tcg_attr.h tcg/tcg_attr.c \ tcg/pts/tcg_pts_attr_proto_caps.h tcg/pts/tcg_pts_attr_proto_caps.c \ @@ -55,7 +56,8 @@ libpts_la_SOURCES = \ tcg/pts/tcg_pts_attr_req_file_meta.h tcg/pts/tcg_pts_attr_req_file_meta.c \ tcg/pts/tcg_pts_attr_unix_file_meta.h tcg/pts/tcg_pts_attr_unix_file_meta.c \ tcg/swid/tcg_swid_attr_req.h tcg/swid/tcg_swid_attr_req.c \ - tcg/swid/tcg_swid_attr_tag_id_inv.h tcg/swid/tcg_swid_attr_tag_id_inv.c + tcg/swid/tcg_swid_attr_tag_id_inv.h tcg/swid/tcg_swid_attr_tag_id_inv.c \ + tcg/swid/tcg_swid_attr_tag_inv.h tcg/swid/tcg_swid_attr_tag_inv.c SUBDIRS = . diff --git a/src/libpts/plugins/imc_swid/imc_swid.c b/src/libpts/plugins/imc_swid/imc_swid.c index f83ced16c..aa0f69eff 100644 --- a/src/libpts/plugins/imc_swid/imc_swid.c +++ b/src/libpts/plugins/imc_swid/imc_swid.c @@ -16,8 +16,10 @@ #include "imc_swid_state.h" #include "libpts.h" +#include "swid/swid_tag.h" #include "swid/swid_tag_id.h" #include "tcg/swid/tcg_swid_attr_req.h" +#include "tcg/swid/tcg_swid_attr_tag_inv.h" #include "tcg/swid/tcg_swid_attr_tag_id_inv.h" #include <imc/imc_agent.h> @@ -28,6 +30,39 @@ #include <pen/pen.h> #include <utils/debug.h> +static char strongswan_tag[] = + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + "<software_identification_tag " + "xmlns=\"http://standards.iso.org/iso/19770/-2/2009/schema.xsd\">\n" + "<entitlement_required_indicator>true</entitlement_required_indicator>\n" + "<product_title>strongSwan</product_title>\n" + "<product_version>\n" + " <name>5.1.1dr1</name>\n" + " <numeric>\n" + " <major>5</major>\n" + " <minor>1</minor>\n" + " <build>0</build>\n" + " <review></review>\n" + " </numeric>\n" + "</product_version>\n" + "<software_creator>\n" + " <name>strongSwan Project</name>\n" + " <regid>regid.2004-03.org.strongswan</regid>\n" + "</software_creator>\n" + "<software_licensor>\n" + " <name>strongSwan Project</name>\n" + " <regid>regid.2004-03.org.strongswan</regid>\n" + "</software_licensor>\n" + "<software_id>\n" + " <unique_id>strongSwan-5-1-0</unique_id>\n" + " <tag_creator_regid>regid.2004-03.org.strongswan</tag_creator_regid>\n" + "</software_id>\n" + "<tag_creator>\n" + " <name>strongSwan</name>\n" + " <regid>regid.2004-03.org.strongswan</regid>\n" + "</tag_creator>\n" + "</software_identification_tag>\n"; + /* IMC definitions */ static const char imc_name[] = "SWID"; @@ -149,8 +184,6 @@ static TNC_Result receive_message(imc_state_t *state, imc_msg_t *in_msg) while (enumerator->enumerate(enumerator, &attr)) { tcg_swid_attr_req_t *attr_req; - tcg_swid_attr_tag_id_inv_t *attr_tag_id_inv; - swid_tag_id_t *tag_id; u_int8_t flags; u_int32_t request_id, eid_epoch; @@ -164,18 +197,32 @@ static TNC_Result receive_message(imc_state_t *state, imc_msg_t *in_msg) attr_req = (tcg_swid_attr_req_t*)attr; flags = attr_req->get_flags(attr_req); request_id = attr_req->get_request_id(attr_req); + eid_epoch = swid_state->get_eid_epoch(swid_state); + if (flags & TCG_SWID_ATTR_REQ_FLAG_R) { - eid_epoch = swid_state->get_eid_epoch(swid_state); + swid_tag_id_t *tag_id; + tcg_swid_attr_tag_id_inv_t *attr_cast; + attr = tcg_swid_attr_tag_id_inv_create(request_id, eid_epoch, 1); - attr_tag_id_inv = (tcg_swid_attr_tag_id_inv_t*)attr; + attr_cast = (tcg_swid_attr_tag_id_inv_t*)attr; tag_id = swid_tag_id_create( chunk_from_str("regid.2004-03.org.strongswan"), chunk_from_str("strongSwan-5-1-0"), chunk_empty); - attr_tag_id_inv->add_tag_id(attr_tag_id_inv, tag_id); - out_msg->add_attribute(out_msg, attr); + attr_cast->add_tag_id(attr_cast, tag_id); + } + else + { + swid_tag_t *tag; + tcg_swid_attr_tag_inv_t *attr_cast; + + attr = tcg_swid_attr_tag_inv_create(request_id, eid_epoch, 1); + attr_cast = (tcg_swid_attr_tag_inv_t*)attr; + tag = swid_tag_create(chunk_from_str(strongswan_tag), chunk_empty); + attr_cast->add_tag(attr_cast, tag); } + out_msg->add_attribute(out_msg, attr); } enumerator->destroy(enumerator); diff --git a/src/libpts/plugins/imv_swid/imv_swid_agent.c b/src/libpts/plugins/imv_swid/imv_swid_agent.c index eb477a907..3050b0069 100644 --- a/src/libpts/plugins/imv_swid/imv_swid_agent.c +++ b/src/libpts/plugins/imv_swid/imv_swid_agent.c @@ -18,6 +18,7 @@ #include "libpts.h" #include "tcg/swid/tcg_swid_attr_req.h" +#include "tcg/swid/tcg_swid_attr_tag_inv.h" #include "tcg/swid/tcg_swid_attr_tag_id_inv.h" #include <imcv.h> @@ -86,14 +87,10 @@ static TNC_Result receive_msg(private_imv_swid_agent_t *this, { imv_msg_t *out_msg; imv_session_t *session; - imv_workitem_t *workitem, *found = NULL; enumerator_t *enumerator; pa_tnc_attr_t *attr; pen_type_t type; - TNC_IMV_Evaluation_Result eval; - TNC_IMV_Action_Recommendation rec; TNC_Result result; - char *result_str; bool fatal_error = FALSE; /* parse received PA-TNC message and handle local and remote errors */ @@ -109,6 +106,14 @@ static TNC_Result receive_msg(private_imv_swid_agent_t *this, enumerator = in_msg->create_attribute_enumerator(in_msg); while (enumerator->enumerate(enumerator, &attr)) { + TNC_IMV_Evaluation_Result eval; + TNC_IMV_Action_Recommendation rec; + u_int32_t request_id, last_eid, eid_epoch; + int tag_count = 0; + char result_str[BUF_LEN], *tag_item; + imv_workitem_t *workitem, *found = NULL; + enumerator_t *et, *ew; + type = attr->get_type(attr); if (type.vendor_id != PEN_TCG) @@ -120,19 +125,21 @@ static TNC_Result receive_msg(private_imv_swid_agent_t *this, case TCG_SWID_TAG_ID_INVENTORY: { tcg_swid_attr_tag_id_inv_t *attr_cast; - u_int32_t request_id; swid_tag_id_t *tag_id; chunk_t tag_creator, unique_sw_id; - enumerator_t *et, *ew; attr_cast = (tcg_swid_attr_tag_id_inv_t*)attr; request_id = attr_cast->get_request_id(attr_cast); + last_eid = attr_cast->get_last_eid(attr_cast, &eid_epoch); + tag_item = "tag ID"; + DBG2(DBG_IMV, "received SWID %s inventory for request %d " + "at eid %d of epoch 0x%08x", tag_item, + request_id, last_eid, eid_epoch); - DBG2(DBG_IMV, "received SWID tag ID inventory for request %d", - request_id); et = attr_cast->create_tag_id_enumerator(attr_cast); while (et->enumerate(et, &tag_id)) { + tag_count++; tag_creator = tag_id->get_tag_creator(tag_id); unique_sw_id = tag_id->get_unique_sw_id(tag_id, NULL); DBG3(DBG_IMV, " %.*s_%.*s.swidtag", @@ -146,40 +153,68 @@ static TNC_Result receive_msg(private_imv_swid_agent_t *this, /* TODO handle subscribed messages */ break; } + break; + } + case TCG_SWID_TAG_INVENTORY: + { + tcg_swid_attr_tag_inv_t *attr_cast; + swid_tag_t *tag; + chunk_t tag_encoding; - ew = session->create_workitem_enumerator(session); - while (ew->enumerate(ew, &workitem)) + attr_cast = (tcg_swid_attr_tag_inv_t*)attr; + request_id = attr_cast->get_request_id(attr_cast); + last_eid = attr_cast->get_last_eid(attr_cast, &eid_epoch); + tag_item = "tag"; + DBG2(DBG_IMV, "received SWID %s inventory for request %d " + "at eid %d of epoch 0x%08x", tag_item, + request_id, last_eid, eid_epoch); + + et = attr_cast->create_tag_enumerator(attr_cast); + while (et->enumerate(et, &tag)) { - if (workitem->get_id(workitem) == request_id) - { - found = workitem; - break; - } + tag_count++; + tag_encoding = tag->get_encoding(tag); + DBG3(DBG_IMV, "%.*s", tag_encoding.len, tag_encoding.ptr); } + et->destroy(et); - if (!found) + if (request_id == 0) { - DBG1(DBG_IMV, "no workitem found for SWID tag ID inventory " - "with request ID %d", request_id); - ew->destroy(ew); + /* TODO handle subscribed messages */ break; } - - eval = TNC_IMV_EVALUATION_RESULT_COMPLIANT; - result_str = "received SWID tag ID inventory"; - session->remove_workitem(session, ew); - ew->destroy(ew); - rec = found->set_result(found, result_str, eval); - state->update_recommendation(state, rec, eval); - imcv_db->finalize_workitem(imcv_db, found); - found->destroy(found); break; } - case TCG_SWID_TAG_INVENTORY: - break; default: + continue; + } + + ew = session->create_workitem_enumerator(session); + while (ew->enumerate(ew, &workitem)) + { + if (workitem->get_id(workitem) == request_id) + { + found = workitem; break; - } + } + } + if (!found) + { + DBG1(DBG_IMV, "no workitem found for SWID %s inventory " + "with request ID %d", tag_item, request_id); + ew->destroy(ew); + continue; + } + + eval = TNC_IMV_EVALUATION_RESULT_COMPLIANT; + snprintf(result_str, BUF_LEN, "received inventory of %d SWID %s%s", + tag_count, tag_item, (tag_count == 1) ? "" : "s"); + session->remove_workitem(session, ew); + ew->destroy(ew); + rec = found->set_result(found, result_str, eval); + state->update_recommendation(state, rec, eval); + imcv_db->finalize_workitem(imcv_db, found); + found->destroy(found); } enumerator->destroy(enumerator); @@ -322,12 +357,12 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result, } request_id = workitem->get_id(workitem); - DBG2(DBG_IMV, "IMV %d issues SWID tag request %d", - imv_id, request_id); attr = tcg_swid_attr_req_create(flags, request_id, 0); out_msg->add_attribute(out_msg, attr); workitem->set_imv_id(workitem, imv_id); no_workitems = FALSE; + DBG2(DBG_IMV, "IMV %d issues SWID request %d", + imv_id, request_id); } enumerator->destroy(enumerator); diff --git a/src/libpts/swid/swid_tag.c b/src/libpts/swid/swid_tag.c new file mode 100644 index 000000000..0b6519693 --- /dev/null +++ b/src/libpts/swid/swid_tag.c @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2013 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 "swid_tag.h" + +typedef struct private_swid_tag_t private_swid_tag_t; + +/** + * Private data of a swid_tag_t object. + * + */ +struct private_swid_tag_t { + + /** + * Public swid_tag_t interface. + */ + swid_tag_t public; + + /** + * UTF-8 XML encoding of SWID tag + */ + chunk_t encoding; + + /** + * Optional Unique Sequence ID + */ + chunk_t unique_seq_id; + +}; + +METHOD(swid_tag_t, get_encoding, chunk_t, + private_swid_tag_t *this) +{ + return this->encoding; +} + +METHOD(swid_tag_t, get_unique_seq_id, chunk_t, + private_swid_tag_t *this) +{ + return this->unique_seq_id; +} + +METHOD(swid_tag_t, destroy, void, + private_swid_tag_t *this) +{ + free(this->encoding.ptr); + free(this->unique_seq_id.ptr); + free(this); +} + +/** + * See header + */ +swid_tag_t *swid_tag_create(chunk_t encoding, chunk_t unique_seq_id) +{ + private_swid_tag_t *this; + + INIT(this, + .public = { + .get_encoding = _get_encoding, + .get_unique_seq_id = _get_unique_seq_id, + .destroy = _destroy, + }, + .encoding = chunk_clone(encoding), + ); + + if (unique_seq_id.len > 0) + { + this->unique_seq_id = chunk_clone(unique_seq_id); + } + + return &this->public; +} + diff --git a/src/libpts/swid/swid_tag.h b/src/libpts/swid/swid_tag.h new file mode 100644 index 000000000..9d3f86333 --- /dev/null +++ b/src/libpts/swid/swid_tag.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2013 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. + */ + +/** + * @defgroup swid_tag swid_tag + * @{ @ingroup swid + */ + +#ifndef SWID_TAG_H_ +#define SWID_TAG_H_ + +#include <library.h> + +typedef struct swid_tag_t swid_tag_t; + + +/** + * Class storing a SWID Tag + */ +struct swid_tag_t { + + /** + * Get UTF-8 XML encoding of SWID tag + * + * @return XML encoding of SWID tag + */ + chunk_t (*get_encoding)(swid_tag_t *this); + + /** + * Get th Optional Unique Sequence ID + * + * @return Optional Unique Sequence ID + */ + chunk_t (*get_unique_seq_id)(swid_tag_t *this); + + /** + * Destroys a swid_tag_t object. + */ + void (*destroy)(swid_tag_t *this); + +}; + +/** + * Creates a swid_tag_t object + * + * @param encoding XML encoding of SWID tag + * @param unique_seq_id Unique Sequence ID or empty chunk + */ +swid_tag_t* swid_tag_create(chunk_t encoding, chunk_t unique_seq_id); + +#endif /** SWID_TAG_H_ @}*/ diff --git a/src/libpts/tcg/swid/tcg_swid_attr_req.c b/src/libpts/tcg/swid/tcg_swid_attr_req.c index 48f1d1040..67772c20b 100644 --- a/src/libpts/tcg/swid/tcg_swid_attr_req.c +++ b/src/libpts/tcg/swid/tcg_swid_attr_req.c @@ -29,7 +29,7 @@ typedef struct private_tcg_swid_attr_req_t private_tcg_swid_attr_req_t; * SWID Request * see section 4.7 of TCG TNC SWID Message and Attributes for IF-M * - * 1 2 3 + * 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |Reserved |C|S|R| Tag ID Count | diff --git a/src/libpts/tcg/swid/tcg_swid_attr_tag_inv.c b/src/libpts/tcg/swid/tcg_swid_attr_tag_inv.c new file mode 100644 index 000000000..129d062fc --- /dev/null +++ b/src/libpts/tcg/swid/tcg_swid_attr_tag_inv.c @@ -0,0 +1,321 @@ +/* + * Copyright (C) 2013 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 "tcg_swid_attr_tag_inv.h" + +#include <pa_tnc/pa_tnc_msg.h> +#include <bio/bio_writer.h> +#include <bio/bio_reader.h> +#include <utils/debug.h> + + +typedef struct private_tcg_swid_attr_tag_inv_t private_tcg_swid_attr_tag_inv_t; + +/** + * SWID Tag Inventory + * see section 4.10 of TCG TNC SWID Message and Attributes for IF-M + * + * 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Reserved | Tag ID Count | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Request ID Copy | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | EID Epoch | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Last EID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Unique Sequence ID Length |Unique Sequence ID (var length)| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Tag Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Tag (Variable) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +#define SWID_TAG_INV_SIZE 16 +#define SWID_TAG_INV_RESERVED 0x00 + +/** + * Private data of an tcg_swid_attr_tag_inv_t object. + */ +struct private_tcg_swid_attr_tag_inv_t { + + /** + * Public members of tcg_swid_attr_tag_inv_t + */ + tcg_swid_attr_tag_inv_t public; + + /** + * Vendor-specific attribute type + */ + pen_type_t type; + + /** + * Attribute value + */ + chunk_t value; + + /** + * Noskip flag + */ + bool noskip_flag; + + /** + * Request ID + */ + u_int32_t request_id; + + /** + * Event ID Epoch + */ + u_int32_t eid_epoch; + + /** + * Last Event ID + */ + u_int32_t last_eid; + + /** + * List of SWID Tags + */ + linked_list_t *tag_list; + + /** + * Reference count + */ + refcount_t ref; +}; + +METHOD(pa_tnc_attr_t, get_type, pen_type_t, + private_tcg_swid_attr_tag_inv_t *this) +{ + return this->type; +} + +METHOD(pa_tnc_attr_t, get_value, chunk_t, + private_tcg_swid_attr_tag_inv_t *this) +{ + return this->value; +} + +METHOD(pa_tnc_attr_t, get_noskip_flag, bool, + private_tcg_swid_attr_tag_inv_t *this) +{ + return this->noskip_flag; +} + +METHOD(pa_tnc_attr_t, set_noskip_flag,void, + private_tcg_swid_attr_tag_inv_t *this, bool noskip) +{ + this->noskip_flag = noskip; +} + +METHOD(pa_tnc_attr_t, build, void, + private_tcg_swid_attr_tag_inv_t *this) +{ + bio_writer_t *writer; + swid_tag_t *tag; + enumerator_t *enumerator; + + if (this->value.ptr) + { + return; + } + + writer = bio_writer_create(SWID_TAG_INV_SIZE); + writer->write_uint8 (writer, SWID_TAG_INV_RESERVED); + writer->write_uint24(writer, this->tag_list->get_count(this->tag_list)); + writer->write_uint32(writer, this->request_id); + writer->write_uint32(writer, this->eid_epoch); + writer->write_uint32(writer, this->last_eid); + + enumerator = this->tag_list->create_enumerator(this->tag_list); + while (enumerator->enumerate(enumerator, &tag)) + { + writer->write_data16(writer, tag->get_unique_seq_id(tag)); + writer->write_data32(writer, tag->get_encoding(tag)); + } + enumerator->destroy(enumerator); + + this->value = writer->extract_buf(writer); + writer->destroy(writer); +} + +METHOD(pa_tnc_attr_t, process, status_t, + private_tcg_swid_attr_tag_inv_t *this, u_int32_t *offset) +{ + bio_reader_t *reader; + u_int32_t tag_count; + u_int8_t reserved; + chunk_t tag_encoding, unique_seq_id; + swid_tag_t *tag; + + if (this->value.len < SWID_TAG_INV_SIZE) + { + DBG1(DBG_TNC, "insufficient data for SWID Tag Inventory"); + *offset = 0; + return FAILED; + } + + reader = bio_reader_create(this->value); + reader->read_uint8 (reader, &reserved); + reader->read_uint24(reader, &tag_count); + reader->read_uint32(reader, &this->request_id); + reader->read_uint32(reader, &this->eid_epoch); + reader->read_uint32(reader, &this->last_eid); + *offset = SWID_TAG_INV_SIZE; + + while (tag_count--) + { + if (!reader->read_data16(reader, &unique_seq_id)) + { + DBG1(DBG_TNC, "insufficient data for Unique Sequence ID"); + return FAILED; + } + *offset += 2 + unique_seq_id.len; + + if (!reader->read_data32(reader, &tag_encoding)) + { + DBG1(DBG_TNC, "insufficient data for Tag"); + return FAILED; + } + *offset += 4 + tag_encoding.len; + + tag = swid_tag_create(tag_encoding, unique_seq_id); + this->tag_list->insert_last(this->tag_list, tag); + } + reader->destroy(reader); + + return SUCCESS; +} + +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_tcg_swid_attr_tag_inv_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + +METHOD(pa_tnc_attr_t, destroy, void, + private_tcg_swid_attr_tag_inv_t *this) +{ + if (ref_put(&this->ref)) + { + this->tag_list->destroy_offset(this->tag_list, + offsetof(swid_tag_t, destroy)); + free(this->value.ptr); + free(this); + } +} + +METHOD(tcg_swid_attr_tag_inv_t, get_request_id, u_int32_t, + private_tcg_swid_attr_tag_inv_t *this) +{ + return this->request_id; +} + +METHOD(tcg_swid_attr_tag_inv_t, get_last_eid, u_int32_t, + private_tcg_swid_attr_tag_inv_t *this, u_int32_t *eid_epoch) +{ + if (eid_epoch) + { + *eid_epoch = this->eid_epoch; + } + return this->last_eid; +} + +METHOD(tcg_swid_attr_tag_inv_t, add_tag, void, + private_tcg_swid_attr_tag_inv_t *this, swid_tag_t *tag) +{ + this->tag_list->insert_last(this->tag_list, tag); +} + +METHOD(tcg_swid_attr_tag_inv_t, create_tag_enumerator, enumerator_t*, + private_tcg_swid_attr_tag_inv_t *this) +{ + return this->tag_list->create_enumerator(this->tag_list); +} + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_swid_attr_tag_inv_create(u_int32_t request_id, + u_int32_t eid_epoch, u_int32_t eid) +{ + private_tcg_swid_attr_tag_inv_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_request_id = _get_request_id, + .get_last_eid = _get_last_eid, + .add_tag = _add_tag, + .create_tag_enumerator = _create_tag_enumerator, + }, + .type = { PEN_TCG, TCG_SWID_TAG_INVENTORY }, + .request_id = request_id, + .eid_epoch = eid_epoch, + .last_eid = eid, + .tag_list = linked_list_create(), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + + +/** + * Described in header. + */ +pa_tnc_attr_t *tcg_swid_attr_tag_inv_create_from_data(chunk_t data) +{ + private_tcg_swid_attr_tag_inv_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_request_id = _get_request_id, + .get_last_eid = _get_last_eid, + .add_tag = _add_tag, + .create_tag_enumerator = _create_tag_enumerator, + }, + .type = { PEN_TCG, TCG_SWID_TAG_INVENTORY }, + .value = chunk_clone(data), + .tag_list = linked_list_create(), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} diff --git a/src/libpts/tcg/swid/tcg_swid_attr_tag_inv.h b/src/libpts/tcg/swid/tcg_swid_attr_tag_inv.h new file mode 100644 index 000000000..f116090b1 --- /dev/null +++ b/src/libpts/tcg/swid/tcg_swid_attr_tag_inv.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2013 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. + */ + +/** + * @defgroup tcg_swid_attr_tag_inv tcg_swid_attr_tag_inv + * @{ @ingroup tcg_attr + */ + +#ifndef TCG_SWID_ATTR_TAG_INV_H_ +#define TCG_SWID_ATTR_TAG_INV_H_ + +typedef struct tcg_swid_attr_tag_inv_t tcg_swid_attr_tag_inv_t; + +#include "tcg/tcg_attr.h" +#include "swid/swid_tag.h" + +#include <pa_tnc/pa_tnc_attr.h> + +/** + * Class implementing the TCG SWID Tag Inventory attribute + * + */ +struct tcg_swid_attr_tag_inv_t { + + /** + * Public PA-TNC attribute interface + */ + pa_tnc_attr_t pa_tnc_attribute; + + /** + * Get Request ID + * + * @return Request ID + */ + u_int32_t (*get_request_id)(tcg_swid_attr_tag_inv_t *this); + + /** + * Get Last Event ID + * + * @param eid_epoch Event ID Epoch + * @return Last Event ID + */ + u_int32_t (*get_last_eid)(tcg_swid_attr_tag_inv_t *this, + u_int32_t *eid_epoch); + + /** + * Add SWID Tag + * + * @param tag SWID Tag (is not cloned by constructor!) + */ + void (*add_tag)(tcg_swid_attr_tag_inv_t *this, swid_tag_t *tag); + + /** + * Create SWID Tag enumerator + * + * @return SWID Tag enumerator + */ + enumerator_t* (*create_tag_enumerator)(tcg_swid_attr_tag_inv_t *this); + +}; + +/** + * Creates an tcg_swid_attr_tag_inv_t object + * + * @param request_id Copy of the Request ID + * @param eid_epoch Event ID Epoch + * @param eid Last Event ID + */ +pa_tnc_attr_t* tcg_swid_attr_tag_inv_create(u_int32_t request_id, + u_int32_t eid_epoch, + u_int32_t eid); + +/** + * Creates an tcg_swid_attr_tag_inv_t object from received data + * + * @param value unparsed attribute value + */ +pa_tnc_attr_t* tcg_swid_attr_tag_inv_create_from_data(chunk_t value); + +#endif /** TCG_SWID_ATTR_TAG_INV_H_ @}*/ diff --git a/src/libpts/tcg/tcg_attr.c b/src/libpts/tcg/tcg_attr.c index d55ce9367..f9c6c46cf 100644 --- a/src/libpts/tcg/tcg_attr.c +++ b/src/libpts/tcg/tcg_attr.c @@ -32,6 +32,7 @@ #include "tcg/pts/tcg_pts_attr_unix_file_meta.h" #include "tcg/swid/tcg_swid_attr_req.h" #include "tcg/swid/tcg_swid_attr_tag_id_inv.h" +#include "tcg/swid/tcg_swid_attr_tag_inv.h" ENUM_BEGIN(tcg_attr_names, TCG_SCAP_REFERENCES, TCG_SCAP_SUMMARY_RESULTS, @@ -178,6 +179,8 @@ pa_tnc_attr_t* tcg_attr_create_from_data(u_int32_t type, chunk_t value) return tcg_swid_attr_req_create_from_data(value); case TCG_SWID_TAG_ID_INVENTORY: return tcg_swid_attr_tag_id_inv_create_from_data(value); + case TCG_SWID_TAG_INVENTORY: + return tcg_swid_attr_tag_inv_create_from_data(value); case TCG_PTS_REQ_PROTO_CAPS: return tcg_pts_attr_proto_caps_create_from_data(value, TRUE); case TCG_PTS_PROTO_CAPS: @@ -216,9 +219,10 @@ pa_tnc_attr_t* tcg_attr_create_from_data(u_int32_t type, chunk_t value) return tcg_pts_attr_req_file_meta_create_from_data(value); case TCG_PTS_UNIX_FILE_META: return tcg_pts_attr_unix_file_meta_create_from_data(value); + /* unsupported TCG/SWID attributes */ case TCG_SWID_TAG_ID_EVENTS: - case TCG_SWID_TAG_INVENTORY: case TCG_SWID_TAG_EVENTS: + /* unsupported TCG/PTS attributes */ case TCG_PTS_REQ_TEMPL_REF_MANI_SET_META: case TCG_PTS_TEMPL_REF_MANI_SET_META: case TCG_PTS_UPDATE_TEMPL_REF_MANI: |