diff options
author | Andreas Steffen <andreas.steffen@strongswan.org> | 2014-10-02 21:32:36 +0200 |
---|---|---|
committer | Andreas Steffen <andreas.steffen@strongswan.org> | 2014-10-05 18:43:54 +0200 |
commit | 903a427008d8f05cf90a81818b4772969970450e (patch) | |
tree | 776718a49b65b621e68564f751153de058e6586c | |
parent | eba0cbcee3b96f77fc51f460c25e3bc06eee9934 (diff) | |
download | strongswan-903a427008d8f05cf90a81818b4772969970450e.tar.bz2 strongswan-903a427008d8f05cf90a81818b4772969970450e.tar.xz |
Implemented incremental processing of SWID tag [ID] inventory attribute
-rw-r--r-- | src/libimcv/plugins/imc_swid/imc_swid.c | 68 | ||||
-rw-r--r-- | src/libimcv/plugins/imv_swid/imv_swid_agent.c | 43 | ||||
-rw-r--r-- | src/libimcv/plugins/imv_swid/imv_swid_state.c | 38 | ||||
-rw-r--r-- | src/libimcv/plugins/imv_swid/imv_swid_state.h | 29 | ||||
-rw-r--r-- | src/libimcv/tcg/swid/tcg_swid_attr_tag_id_inv.c | 128 | ||||
-rw-r--r-- | src/libimcv/tcg/swid/tcg_swid_attr_tag_id_inv.h | 12 | ||||
-rw-r--r-- | src/libimcv/tcg/swid/tcg_swid_attr_tag_inv.c | 122 | ||||
-rw-r--r-- | src/libimcv/tcg/swid/tcg_swid_attr_tag_inv.h | 12 |
8 files changed, 253 insertions, 199 deletions
diff --git a/src/libimcv/plugins/imc_swid/imc_swid.c b/src/libimcv/plugins/imc_swid/imc_swid.c index 86e2693d5..f4cca6a71 100644 --- a/src/libimcv/plugins/imc_swid/imc_swid.c +++ b/src/libimcv/plugins/imc_swid/imc_swid.c @@ -17,8 +17,6 @@ #include <imc/imc_agent.h> #include <imc/imc_msg.h> -#include <ita/ita_attr.h> -#include <ita/ita_attr_angel.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" @@ -133,13 +131,12 @@ static bool add_swid_inventory(imc_state_t *state, imc_msg_t *msg, uint32_t request_id, bool full_tags, swid_inventory_t *targets) { - pa_tnc_attr_t *attr, *attr_angel, *attr_error; + pa_tnc_attr_t *attr, *attr_error; imc_swid_state_t *swid_state; swid_inventory_t *swid_inventory; char *swid_directory, *swid_generator; uint32_t eid_epoch; - size_t max_attr_size, attr_size, entry_size; - bool first = TRUE, swid_pretty, swid_full; + bool swid_pretty, swid_full; enumerator_t *enumerator; swid_directory = lib->settings->get_str(lib->settings, @@ -172,63 +169,19 @@ static bool add_swid_inventory(imc_state_t *state, imc_msg_t *msg, swid_state = (imc_swid_state_t*)state; eid_epoch = swid_state->get_eid_epoch(swid_state); - /** - * Compute the maximum TCG SWID Tag [ID] Inventory attribute size - * leaving space for an additional ITA Angel attribute - */ - max_attr_size = state->get_max_msg_len(state) - - PA_TNC_HEADER_SIZE - PA_TNC_ATTR_HEADER_SIZE; - if (full_tags) { tcg_swid_attr_tag_inv_t *swid_attr; swid_tag_t *tag; - chunk_t encoding, instance_id; - /* At least one TCG Tag Inventory attribute is sent */ - attr_size = PA_TNC_ATTR_HEADER_SIZE + TCG_SWID_TAG_INV_MIN_SIZE; + /* Send a TCG SWID Tag Inventory attribute */ attr = tcg_swid_attr_tag_inv_create(request_id, eid_epoch, 1); + swid_attr = (tcg_swid_attr_tag_inv_t*)attr; enumerator = swid_inventory->create_enumerator(swid_inventory); while (enumerator->enumerate(enumerator, &tag)) { - instance_id = tag->get_instance_id(tag); - encoding = tag->get_encoding(tag); - entry_size = 2 + instance_id.len + 4 + encoding.len; - - /* Check for oversize tags that cannot be transported */ - if (PA_TNC_ATTR_HEADER_SIZE + TCG_SWID_TAG_INV_MIN_SIZE + - entry_size > max_attr_size) - { - attr_error = swid_error_create(TCG_SWID_RESPONSE_TOO_LARGE, - request_id, max_attr_size, - "oversize SWID tag omitted"); - msg->add_attribute(msg, attr_error); - continue; - } - - if (attr_size + entry_size > max_attr_size) - { - if (first) - { - /** - * Send an ITA Start Angel attribute to the IMV signalling - * that multiple TGC SWID Tag Inventory attributes follow - */ - attr_angel = ita_attr_angel_create(TRUE); - msg->add_attribute(msg, attr_angel); - first = FALSE; - } - msg->add_attribute(msg, attr); - - /* create the next TCG SWID Tag Inventory attribute */ - attr_size = PA_TNC_ATTR_HEADER_SIZE + - TCG_SWID_TAG_INV_MIN_SIZE; - attr = tcg_swid_attr_tag_inv_create(request_id, eid_epoch, 1); - } - swid_attr = (tcg_swid_attr_tag_inv_t*)attr; swid_attr->add(swid_attr, tag->get_ref(tag)); - attr_size += entry_size; } enumerator->destroy(enumerator); } @@ -237,7 +190,7 @@ static bool add_swid_inventory(imc_state_t *state, imc_msg_t *msg, tcg_swid_attr_tag_id_inv_t *swid_id_attr; swid_tag_id_t *tag_id; - /* Send a TCG Tag ID Inventory attribute */ + /* Send a TCG SWID Tag ID Inventory attribute */ attr = tcg_swid_attr_tag_id_inv_create(request_id, eid_epoch, 1); swid_id_attr = (tcg_swid_attr_tag_id_inv_t*)attr; @@ -248,19 +201,10 @@ static bool add_swid_inventory(imc_state_t *state, imc_msg_t *msg, } enumerator->destroy(enumerator); } + msg->add_attribute(msg, attr); swid_inventory->destroy(swid_inventory); - if (!first) - { - /** - * If we sent an ITA Start Angel attribute in the first place, - * terminate by appending a matching ITA Stop Angel attribute. - */ - attr_angel = ita_attr_angel_create(FALSE); - msg->add_attribute(msg, attr_angel); - } - return TRUE; } diff --git a/src/libimcv/plugins/imv_swid/imv_swid_agent.c b/src/libimcv/plugins/imv_swid/imv_swid_agent.c index 724611de8..c2da76ee0 100644 --- a/src/libimcv/plugins/imv_swid/imv_swid_agent.c +++ b/src/libimcv/plugins/imv_swid/imv_swid_agent.c @@ -24,8 +24,6 @@ #include <imv/imv_agent.h> #include <imv/imv_msg.h> #include <ietf/ietf_attr_pa_tnc_error.h> -#include <ita/ita_attr.h> -#include <ita/ita_attr_angel.h> #include "tcg/seg/tcg_seg_attr_max_size.h" #include "tcg/seg/tcg_seg_attr_seg_env.h" #include "tcg/swid/tcg_swid_attr_req.h" @@ -185,20 +183,6 @@ static TNC_Result receive_msg(private_imv_swid_agent_t *this, reader->destroy(reader); } } - else if (type.vendor_id == PEN_ITA) - { - switch (type.type) - { - case ITA_ATTR_START_ANGEL: - swid_state->set_angel_count(swid_state, TRUE); - continue; - case ITA_ATTR_STOP_ANGEL: - swid_state->set_angel_count(swid_state, FALSE); - continue; - default: - continue; - } - } else if (type.vendor_id != PEN_TCG) { continue; @@ -209,6 +193,7 @@ 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; + uint32_t missing; int tag_id_count; state->set_action_flags(state, IMV_SWID_ATTR_TAG_ID_INV); @@ -218,11 +203,14 @@ static TNC_Result receive_msg(private_imv_swid_agent_t *this, last_eid = attr_cast->get_last_eid(attr_cast, &eid_epoch); inventory = attr_cast->get_inventory(attr_cast); tag_id_count = inventory->get_count(inventory); + missing = attr_cast->get_tag_id_count(attr_cast); + swid_state->set_missing(swid_state, missing); DBG2(DBG_IMV, "received SWID tag ID inventory with %d item%s " - "for request %d at eid %d of epoch 0x%08x", - tag_id_count, (tag_id_count == 1) ? "" : "s", - request_id, last_eid, eid_epoch); + "for request %d at eid %d of epoch 0x%08x, %d item%s to " + "follow", tag_id_count, (tag_id_count == 1) ? "" : "s", + request_id, last_eid, eid_epoch, missing, + (missing == 1) ? "" : "s"); if (request_id == swid_state->get_request_id(swid_state)) { @@ -234,6 +222,7 @@ static TNC_Result receive_msg(private_imv_swid_agent_t *this, DBG1(DBG_IMV, "no workitem found for SWID tag ID inventory " "with request ID %d", request_id); } + attr_cast->clear_inventory(attr_cast); break; } case TCG_SWID_TAG_INVENTORY: @@ -243,6 +232,7 @@ static TNC_Result receive_msg(private_imv_swid_agent_t *this, chunk_t tag_encoding; json_object *jobj, *jarray, *jstring; char *tag_str; + uint32_t missing; int tag_count; enumerator_t *e; @@ -253,12 +243,13 @@ static TNC_Result receive_msg(private_imv_swid_agent_t *this, last_eid = attr_cast->get_last_eid(attr_cast, &eid_epoch); inventory = attr_cast->get_inventory(attr_cast); tag_count = inventory->get_count(inventory); + missing = attr_cast->get_tag_count(attr_cast); + swid_state->set_missing(swid_state, missing); DBG2(DBG_IMV, "received SWID tag inventory with %d item%s for " - "request %d at eid %d of epoch 0x%08x", - tag_count, (tag_count == 1) ? "" : "s", - request_id, last_eid, eid_epoch); - + "request %d at eid %d of epoch 0x%08x, %d item%s to follow", + tag_count, (tag_count == 1) ? "" : "s", request_id, + last_eid, eid_epoch, missing, (missing == 1) ? "" : "s"); if (request_id == swid_state->get_request_id(swid_state)) { @@ -295,9 +286,11 @@ static TNC_Result receive_msg(private_imv_swid_agent_t *this, DBG1(DBG_IMV, "no workitem found for SWID tag inventory " "with request ID %d", request_id); } + attr_cast->clear_inventory(attr_cast); + break; } default: - continue; + break; } } enumerator->destroy(enumerator); @@ -498,7 +491,7 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result, if (handshake_state == IMV_SWID_STATE_WORKITEMS && (received & (IMV_SWID_ATTR_TAG_INV|IMV_SWID_ATTR_TAG_ID_INV)) && - swid_state->get_angel_count(swid_state) <= 0) + swid_state->get_missing(swid_state) == 0) { TNC_IMV_Evaluation_Result eval; TNC_IMV_Action_Recommendation rec; diff --git a/src/libimcv/plugins/imv_swid/imv_swid_state.c b/src/libimcv/plugins/imv_swid/imv_swid_state.c index 885de62ce..04364b030 100644 --- a/src/libimcv/plugins/imv_swid/imv_swid_state.c +++ b/src/libimcv/plugins/imv_swid/imv_swid_state.c @@ -118,6 +118,11 @@ struct private_imv_swid_state_t { int tag_count; /** + * Number of missing SWID Tags or Tag IDs + */ + uint32_t missing; + + /** * Top level JSON object */ json_object *jobj; @@ -127,11 +132,6 @@ struct private_imv_swid_state_t { */ json_object *jarray; - /** - * Angel count - */ - int angel_count; - }; METHOD(imv_state_t, get_connection_id, TNC_ConnectionID, @@ -313,6 +313,18 @@ METHOD(imv_swid_state_t, get_swid_inventory, json_object*, return this->jobj; } +METHOD(imv_swid_state_t, set_missing, void, + private_imv_swid_state_t *this, uint32_t count) +{ + this->missing = count; +} + +METHOD(imv_swid_state_t, get_missing, uint32_t, + private_imv_swid_state_t *this) +{ + return this->missing; +} + METHOD(imv_swid_state_t, set_count, void, private_imv_swid_state_t *this, int tag_id_count, int tag_count) { @@ -333,18 +345,6 @@ METHOD(imv_swid_state_t, get_count, void, } } -METHOD(imv_swid_state_t, set_angel_count, void, - private_imv_swid_state_t *this, bool start) -{ - this->angel_count += start ? 1 : -1; -} - -METHOD(imv_swid_state_t, get_angel_count, int, - private_imv_swid_state_t *this) -{ - return this->angel_count; -} - /** * Described in header. */ @@ -380,10 +380,10 @@ imv_state_t *imv_swid_state_create(TNC_ConnectionID connection_id) .get_request_id = _get_request_id, .set_swid_inventory = _set_swid_inventory, .get_swid_inventory = _get_swid_inventory, + .set_missing = _set_missing, + .get_missing = _get_missing, .set_count = _set_count, .get_count = _get_count, - .set_angel_count = _set_angel_count, - .get_angel_count = _get_angel_count, }, .state = TNC_CONNECTION_STATE_CREATE, .rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION, diff --git a/src/libimcv/plugins/imv_swid/imv_swid_state.h b/src/libimcv/plugins/imv_swid/imv_swid_state.h index a6a8d0332..af5d95c9d 100644 --- a/src/libimcv/plugins/imv_swid/imv_swid_state.h +++ b/src/libimcv/plugins/imv_swid/imv_swid_state.h @@ -96,35 +96,34 @@ struct imv_swid_state_t { json_object* (*get_swid_inventory)(imv_swid_state_t *this); /** - * Set [or with multiple attributes increment] SWID Tag [ID] counters + * Set the number of still missing SWID Tags or Tag IDs * - * @param tag_id_count Number of received SWID Tag IDs - * @param tag_count Number of received SWID Tags + * @param count Number of missing SWID Tags or Tag IDs */ - void (*set_count)(imv_swid_state_t *this, int tag_id_count, int tag_count); + void (*set_missing)(imv_swid_state_t *this, uint32_t count); /** - * Set [or with multiple attributes increment] SWID Tag [ID] counters + * Get the number of still missing SWID Tags or Tag IDs * - * @param tag_id_count Number of received SWID Tag IDs - * @param tag_count Number of received SWID Tags + * @result Number of missing SWID Tags or Tag IDs */ - void (*get_count)(imv_swid_state_t *this, int *tag_id_count, int *tag_count); + uint32_t (*get_missing)(imv_swid_state_t *this); /** - * Increase/Decrease the ITA Angel count + * Set [or with multiple attributes increment] SWID Tag [ID] counters * - * @param start TRUE increases and FALSE decreases count by one + * @param tag_id_count Number of received SWID Tag IDs + * @param tag_count Number of received SWID Tags */ - void (*set_angel_count)(imv_swid_state_t *this, bool start); + void (*set_count)(imv_swid_state_t *this, int tag_id_count, int tag_count); /** - * Get the ITA Angel count + * Set [or with multiple attributes increment] SWID Tag [ID] counters * - * @return ITA Angel count + * @param tag_id_count Number of received SWID Tag IDs + * @param tag_count Number of received SWID Tags */ - int (*get_angel_count)(imv_swid_state_t *this); - + void (*get_count)(imv_swid_state_t *this, int *tag_id_count, int *tag_count); }; /** diff --git a/src/libimcv/tcg/swid/tcg_swid_attr_tag_id_inv.c b/src/libimcv/tcg/swid/tcg_swid_attr_tag_id_inv.c index 4d1316cc7..560d5878f 100644 --- a/src/libimcv/tcg/swid/tcg_swid_attr_tag_id_inv.c +++ b/src/libimcv/tcg/swid/tcg_swid_attr_tag_id_inv.c @@ -69,11 +69,21 @@ struct private_tcg_swid_attr_tag_id_inv_t { size_t length; /** - * Attribute value or segment + * Offset up to which attribute value has been processed + */ + size_t offset; + + /** + * Current position of attribute value pointer */ chunk_t value; /** + * Contains complete attribute or current segment + */ + chunk_t segment; + + /** * Noskip flag */ bool noskip_flag; @@ -94,6 +104,11 @@ struct private_tcg_swid_attr_tag_id_inv_t { uint32_t last_eid; /** + * Number of SWID Tag IDs in attribute + */ + uint32_t tag_id_count; + + /** * SWID Tag ID Inventory */ swid_inventory_t *inventory; @@ -160,6 +175,7 @@ METHOD(pa_tnc_attr_t, build, void, enumerator->destroy(enumerator); this->value = writer->extract_buf(writer); + this->segment = this->value; this->length = this->value.len; writer->destroy(writer); } @@ -168,66 +184,74 @@ METHOD(pa_tnc_attr_t, process, status_t, private_tcg_swid_attr_tag_id_inv_t *this, uint32_t *offset) { bio_reader_t *reader; - uint32_t tag_id_count; uint8_t reserved; chunk_t tag_creator, unique_sw_id, instance_id; swid_tag_id_t *tag_id; + status_t status = NEED_MORE; - *offset = 0; - - if (this->value.len < this->length) - { - return NEED_MORE; - } - if (this->value.len < TCG_SWID_TAG_ID_INV_MIN_SIZE) - { - DBG1(DBG_TNC, "insufficient data for SWID Tag Identifier Inventory"); - return FAILED; - } - - reader = bio_reader_create(this->value); - reader->read_uint8 (reader, &reserved); - reader->read_uint24(reader, &tag_id_count); - reader->read_uint32(reader, &this->request_id); - reader->read_uint32(reader, &this->eid_epoch); - reader->read_uint32(reader, &this->last_eid); - *offset = TCG_SWID_TAG_ID_INV_MIN_SIZE; - - while (tag_id_count--) + if (this->offset == 0) { - if (!reader->read_data16(reader, &tag_creator)) + if (this->length < TCG_SWID_TAG_ID_INV_MIN_SIZE) { - DBG1(DBG_TNC, "insufficient data for Tag Creator field"); + DBG1(DBG_TNC, "insufficient data for %N/%N", pen_names, PEN_TCG, + tcg_attr_names, this->type.type); + *offset = this->offset; return FAILED; } - *offset += 2 + tag_creator.len; - - if (!reader->read_data16(reader, &unique_sw_id)) + if (this->value.len < TCG_SWID_TAG_ID_INV_MIN_SIZE) { - DBG1(DBG_TNC, "insufficient data for Unique Software ID"); - return FAILED; + return NEED_MORE; } - *offset += 2 + unique_sw_id.len; - - if (!reader->read_data16(reader, &instance_id)) + reader = bio_reader_create(this->value); + reader->read_uint8 (reader, &reserved); + reader->read_uint24(reader, &this->tag_id_count); + reader->read_uint32(reader, &this->request_id); + reader->read_uint32(reader, &this->eid_epoch); + reader->read_uint32(reader, &this->last_eid); + this->offset = TCG_SWID_TAG_ID_INV_MIN_SIZE; + this->value = reader->peek(reader); + reader->destroy(reader); + } + + reader = bio_reader_create(this->value); + + while (this->tag_id_count) + { + if (!reader->read_data16(reader, &tag_creator) || + !reader->read_data16(reader, &unique_sw_id) || + !reader->read_data16(reader, &instance_id)) { - DBG1(DBG_TNC, "insufficient data for Instance ID"); - return FAILED; + goto end; } - *offset += 2 + instance_id.len; - tag_id = swid_tag_id_create(tag_creator, unique_sw_id, instance_id); this->inventory->add(this->inventory, tag_id); + this->offset += this->value.len - reader->remaining(reader); + this->value = reader->peek(reader); + + /* at least one tag ID was processed */ + status = SUCCESS; + this->tag_id_count--; + } + + if (this->length != this->offset) + { + DBG1(DBG_TNC, "inconsistent length for %N/%N", pen_names, PEN_TCG, + tcg_attr_names, this->type.type); + *offset = this->offset; + status = FAILED; } - reader->destroy(reader); - return SUCCESS; +end: + reader->destroy(reader); + return status; } METHOD(pa_tnc_attr_t, add_segment, void, private_tcg_swid_attr_tag_id_inv_t *this, chunk_t segment) { - this->value = chunk_cat("mc", this->value, segment); + this->value = chunk_cat("cc", this->value, segment); + chunk_free(&this->segment); + this->segment = this->value; } METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, @@ -243,7 +267,7 @@ METHOD(pa_tnc_attr_t, destroy, void, if (ref_put(&this->ref)) { this->inventory->destroy(this->inventory); - free(this->value.ptr); + free(this->segment.ptr); free(this); } } @@ -270,12 +294,25 @@ METHOD(tcg_swid_attr_tag_id_inv_t, get_last_eid, uint32_t, return this->last_eid; } +METHOD(tcg_swid_attr_tag_id_inv_t, get_tag_id_count, uint32_t, + private_tcg_swid_attr_tag_id_inv_t *this) +{ + return this->tag_id_count; +} + METHOD(tcg_swid_attr_tag_id_inv_t, get_inventory, swid_inventory_t*, private_tcg_swid_attr_tag_id_inv_t *this) { return this->inventory; } +METHOD(tcg_swid_attr_tag_id_inv_t, clear_inventory, void, + private_tcg_swid_attr_tag_id_inv_t *this) +{ + this->inventory->destroy(this->inventory); + this->inventory = swid_inventory_create(FALSE); +} + /** * Described in header. */ @@ -301,7 +338,9 @@ pa_tnc_attr_t *tcg_swid_attr_tag_id_inv_create(uint32_t request_id, .add = _add, .get_request_id = _get_request_id, .get_last_eid = _get_last_eid, + .get_tag_id_count = _get_tag_id_count, .get_inventory = _get_inventory, + .clear_inventory = _clear_inventory, }, .type = { PEN_TCG, TCG_SWID_TAG_ID_INVENTORY }, .request_id = request_id, @@ -339,14 +378,19 @@ pa_tnc_attr_t *tcg_swid_attr_tag_id_inv_create_from_data(size_t length, .add = _add, .get_request_id = _get_request_id, .get_last_eid = _get_last_eid, + .get_tag_id_count = _get_tag_id_count, .get_inventory = _get_inventory, + .clear_inventory = _clear_inventory, }, .type = { PEN_TCG, TCG_SWID_TAG_ID_INVENTORY }, .length = length, - .value = chunk_clone(data), + .segment = chunk_clone(data), .inventory = swid_inventory_create(FALSE), .ref = 1, ); + /* received either complete attribute value or first segment */ + this->value = this->segment; + return &this->public.pa_tnc_attribute; } diff --git a/src/libimcv/tcg/swid/tcg_swid_attr_tag_id_inv.h b/src/libimcv/tcg/swid/tcg_swid_attr_tag_id_inv.h index 897fd49e1..e9db9b3c6 100644 --- a/src/libimcv/tcg/swid/tcg_swid_attr_tag_id_inv.h +++ b/src/libimcv/tcg/swid/tcg_swid_attr_tag_id_inv.h @@ -66,12 +66,24 @@ struct tcg_swid_attr_tag_id_inv_t { uint32_t *eid_epoch); /** + * Get count of remaining SWID tag IDs + * + * @return SWID Tag ID count + */ + uint32_t (*get_tag_id_count)(tcg_swid_attr_tag_id_inv_t *this); + + /** * Get Inventory of SWID tag IDs * * @result SWID Tag ID Inventory */ swid_inventory_t* (*get_inventory)(tcg_swid_attr_tag_id_inv_t *this); + /** + * Remove all SWID Tag IDs from the Inventory + */ + void (*clear_inventory)(tcg_swid_attr_tag_id_inv_t *this); + }; /** diff --git a/src/libimcv/tcg/swid/tcg_swid_attr_tag_inv.c b/src/libimcv/tcg/swid/tcg_swid_attr_tag_inv.c index f61696788..ade0ca8a0 100644 --- a/src/libimcv/tcg/swid/tcg_swid_attr_tag_inv.c +++ b/src/libimcv/tcg/swid/tcg_swid_attr_tag_inv.c @@ -69,11 +69,21 @@ struct private_tcg_swid_attr_tag_inv_t { size_t length; /** - * Attribute value or segment + * Offset up to which attribute value has been processed + */ + size_t offset; + + /** + * Current position of attribute value pointer */ chunk_t value; /** + * Contains complete attribute or current segment + */ + chunk_t segment; + + /** * Noskip flag */ bool noskip_flag; @@ -94,6 +104,11 @@ struct private_tcg_swid_attr_tag_inv_t { uint32_t last_eid; /** + * Number of SWID Tags in attribute + */ + uint32_t tag_count; + + /** * SWID Tag Inventory */ swid_inventory_t *inventory; @@ -156,6 +171,7 @@ METHOD(pa_tnc_attr_t, build, void, enumerator->destroy(enumerator); this->value = writer->extract_buf(writer); + this->segment = this->value; this->length = this->value.len; writer->destroy(writer); } @@ -164,59 +180,73 @@ METHOD(pa_tnc_attr_t, process, status_t, private_tcg_swid_attr_tag_inv_t *this, uint32_t *offset) { bio_reader_t *reader; - uint32_t tag_count; uint8_t reserved; chunk_t tag_encoding, instance_id; swid_tag_t *tag; + status_t status = NEED_MORE; - *offset = 0; - - if (this->value.len < this->length) - { - return NEED_MORE; - } - if (this->value.len < TCG_SWID_TAG_INV_MIN_SIZE) - { - DBG1(DBG_TNC, "insufficient data for SWID Tag Inventory"); - 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 = TCG_SWID_TAG_INV_MIN_SIZE; - - while (tag_count--) + if (this->offset == 0) { - if (!reader->read_data16(reader, &instance_id)) + if (this->length < TCG_SWID_TAG_INV_MIN_SIZE) { - DBG1(DBG_TNC, "insufficient data for Instance ID"); + DBG1(DBG_TNC, "insufficient data for %N", tcg_attr_names, + this->type.type); + *offset = this->offset; return FAILED; } - *offset += 2 + instance_id.len; - - if (!reader->read_data32(reader, &tag_encoding)) + if (this->value.len < TCG_SWID_TAG_INV_MIN_SIZE) { - DBG1(DBG_TNC, "insufficient data for Tag"); - return FAILED; + return NEED_MORE; } - *offset += 4 + tag_encoding.len; + reader = bio_reader_create(this->value); + reader->read_uint8 (reader, &reserved); + reader->read_uint24(reader, &this->tag_count); + reader->read_uint32(reader, &this->request_id); + reader->read_uint32(reader, &this->eid_epoch); + reader->read_uint32(reader, &this->last_eid); + this->offset = TCG_SWID_TAG_INV_MIN_SIZE; + this->value = reader->peek(reader); + reader->destroy(reader); + } + reader = bio_reader_create(this->value); + + while (this->tag_count) + { + if (!reader->read_data16(reader, &instance_id) || + !reader->read_data32(reader, &tag_encoding)) + { + goto end; + } tag = swid_tag_create(tag_encoding, instance_id); this->inventory->add(this->inventory, tag); + this->offset += this->value.len - reader->remaining(reader); + this->value = reader->peek(reader); + + /* at least one tag was processed */ + status = SUCCESS; + this->tag_count--; + } + + if (this->length != this->offset) + { + DBG1(DBG_TNC, "inconsistent length for %N", tcg_attr_names, + this->type.type); + *offset = this->offset; + status = FAILED; } - reader->destroy(reader); - return SUCCESS; +end: + reader->destroy(reader); + return status; } METHOD(pa_tnc_attr_t, add_segment, void, private_tcg_swid_attr_tag_inv_t *this, chunk_t segment) { - this->value = chunk_cat("mc", this->value, segment); + this->value = chunk_cat("cc", this->value, segment); + chunk_free(&this->segment); + this->segment = this->value; } METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, @@ -232,7 +262,7 @@ METHOD(pa_tnc_attr_t, destroy, void, if (ref_put(&this->ref)) { this->inventory->destroy(this->inventory); - free(this->value.ptr); + free(this->segment.ptr); free(this); } } @@ -259,12 +289,25 @@ METHOD(tcg_swid_attr_tag_inv_t, get_last_eid, uint32_t, return this->last_eid; } +METHOD(tcg_swid_attr_tag_inv_t, get_tag_count, uint32_t, + private_tcg_swid_attr_tag_inv_t *this) +{ + return this->tag_count; +} + METHOD(tcg_swid_attr_tag_inv_t, get_inventory, swid_inventory_t*, private_tcg_swid_attr_tag_inv_t *this) { return this->inventory; } +METHOD(tcg_swid_attr_tag_inv_t, clear_inventory, void, + private_tcg_swid_attr_tag_inv_t *this) +{ + this->inventory->destroy(this->inventory); + this->inventory = swid_inventory_create(TRUE); +} + /** * Described in header. */ @@ -289,7 +332,9 @@ pa_tnc_attr_t *tcg_swid_attr_tag_inv_create(uint32_t request_id, .add = _add, .get_request_id = _get_request_id, .get_last_eid = _get_last_eid, + .get_tag_count = _get_tag_count, .get_inventory = _get_inventory, + .clear_inventory = _clear_inventory, }, .type = { PEN_TCG, TCG_SWID_TAG_INVENTORY }, .request_id = request_id, @@ -326,14 +371,19 @@ pa_tnc_attr_t *tcg_swid_attr_tag_inv_create_from_data(size_t length, .add = _add, .get_request_id = _get_request_id, .get_last_eid = _get_last_eid, + .get_tag_count = _get_tag_count, .get_inventory = _get_inventory, + .clear_inventory = _clear_inventory, }, .type = { PEN_TCG, TCG_SWID_TAG_INVENTORY }, .length = length, - .value = chunk_clone(data), + .segment = chunk_clone(data), .inventory = swid_inventory_create(TRUE), .ref = 1, ); + /* received either complete attribute value or first segment */ + this->value = this->segment; + return &this->public.pa_tnc_attribute; } diff --git a/src/libimcv/tcg/swid/tcg_swid_attr_tag_inv.h b/src/libimcv/tcg/swid/tcg_swid_attr_tag_inv.h index 4795fd001..43ebd9e2a 100644 --- a/src/libimcv/tcg/swid/tcg_swid_attr_tag_inv.h +++ b/src/libimcv/tcg/swid/tcg_swid_attr_tag_inv.h @@ -65,12 +65,24 @@ struct tcg_swid_attr_tag_inv_t { uint32_t *eid_epoch); /** + * Get count of remaining SWID tags + * + * @return SWID Tag count + */ + uint32_t (*get_tag_count)(tcg_swid_attr_tag_inv_t *this); + + /** * Get Inventory of SWID tags * * @result SWID Tag Inventory */ swid_inventory_t* (*get_inventory)(tcg_swid_attr_tag_inv_t *this); + /** + * Remove all SWID Tags from the Inventory + */ + void (*clear_inventory)(tcg_swid_attr_tag_inv_t *this); + }; /** |