Implemented add_segment method for PA-TNC attributes

This commit is contained in:
Andreas Steffen 2014-10-01 23:11:30 +02:00
parent e77df5a1f6
commit eba0cbcee3
11 changed files with 213 additions and 95 deletions

View File

@ -26,6 +26,7 @@ typedef struct pa_tnc_attr_t pa_tnc_attr_t;
#include <library.h> #include <library.h>
#include <pen/pen.h> #include <pen/pen.h>
#define PA_TNC_ATTR_INFO_SIZE 8
#define PA_TNC_ATTR_HEADER_SIZE 12 #define PA_TNC_ATTR_HEADER_SIZE 12
#define PA_TNC_ATTR_FLAG_NONE 0x00 #define PA_TNC_ATTR_FLAG_NONE 0x00
@ -73,11 +74,18 @@ struct pa_tnc_attr_t {
/** /**
* Process the value of an PA-TNC attribute to extract its parameters * Process the value of an PA-TNC attribute to extract its parameters
* *
* @param relative error offset within attribute body * @param offset relative error offset within attribute body
* @return result status * @return result status
*/ */
status_t (*process)(pa_tnc_attr_t *this, uint32_t *offset); status_t (*process)(pa_tnc_attr_t *this, uint32_t *offset);
/**
* Add a data segment to an attribute allowing incremental processing
*
* @param segment data segment to be appended
*/
void (*add_segment)(pa_tnc_attr_t *this, chunk_t segment);
/** /**
* Get a new reference to the PA-TNC attribute * Get a new reference to the PA-TNC attribute
* *

View File

@ -120,14 +120,12 @@ METHOD(pa_tnc_attr_manager_t, get_names, enum_name_t*,
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/ */
#define PA_TNC_ATTR_INFO_SIZE 8
METHOD(pa_tnc_attr_manager_t, create, pa_tnc_attr_t*, METHOD(pa_tnc_attr_manager_t, create, pa_tnc_attr_t*,
private_pa_tnc_attr_manager_t *this, bio_reader_t *reader, uint32_t *offset, private_pa_tnc_attr_manager_t *this, bio_reader_t *reader, bool segmented,
chunk_t msg_info, pa_tnc_attr_t **error) uint32_t *offset, chunk_t msg_info, pa_tnc_attr_t **error)
{ {
uint8_t flags; uint8_t flags;
uint32_t type, length, attr_offset; uint32_t type, length, value_len;
chunk_t value; chunk_t value;
ietf_attr_pa_tnc_error_t *error_attr; ietf_attr_pa_tnc_error_t *error_attr;
pen_t vendor_id; pen_t vendor_id;
@ -177,8 +175,9 @@ METHOD(pa_tnc_attr_manager_t, create, pa_tnc_attr_t*,
return NULL; return NULL;
} }
length -= PA_TNC_ATTR_HEADER_SIZE; length -= PA_TNC_ATTR_HEADER_SIZE;
value_len = segmented ? reader->remaining(reader) : length;
if (!reader->read_data(reader, length, &value)) if (!reader->read_data(reader, value_len, &value))
{ {
DBG1(DBG_TNC, "insufficient bytes for PA-TNC attribute value"); DBG1(DBG_TNC, "insufficient bytes for PA-TNC attribute value");
*error = ietf_attr_pa_tnc_error_create_with_offset(error_code, *error = ietf_attr_pa_tnc_error_create_with_offset(error_code,
@ -220,7 +219,7 @@ METHOD(pa_tnc_attr_manager_t, create, pa_tnc_attr_t*,
if (!(flags & PA_TNC_ATTR_FLAG_NOSKIP)) if (!(flags & PA_TNC_ATTR_FLAG_NOSKIP))
{ {
DBG1(DBG_TNC, "skipping unsupported PA-TNC attribute"); DBG1(DBG_TNC, "skipping unsupported PA-TNC attribute");
offset += length; (*offset) += PA_TNC_ATTR_HEADER_SIZE + length;
return NULL; return NULL;
} }
@ -232,21 +231,7 @@ METHOD(pa_tnc_attr_manager_t, create, pa_tnc_attr_t*,
error_attr->set_unsupported_attr(error_attr, flags, unsupported_type); error_attr->set_unsupported_attr(error_attr, flags, unsupported_type);
return NULL; return NULL;
} }
if (attr->process(attr, &attr_offset) != SUCCESS) (*offset) += PA_TNC_ATTR_HEADER_SIZE;
{
attr->destroy(attr);
attr = NULL;
if (vendor_id == PEN_IETF && type == IETF_ATTR_PA_TNC_ERROR)
{
/* error while processing a PA-TNC error attribute - abort */
return NULL;
}
error_code = pen_type_create(PEN_IETF, PA_ERROR_INVALID_PARAMETER);
*error = ietf_attr_pa_tnc_error_create_with_offset(error_code,
msg_info, *offset + PA_TNC_ATTR_HEADER_SIZE + attr_offset);
return NULL;
}
(*offset) += length;
return attr; return attr;
} }

View File

@ -66,13 +66,14 @@ struct pa_tnc_attr_manager_t {
* Create and pre-parse a PA-TNC attribute object from data * Create and pre-parse a PA-TNC attribute object from data
* *
* @param reader PA-TNC attribute as encoded data * @param reader PA-TNC attribute as encoded data
* @param segmented TRUE if attribute is segmented
* @param offset Offset in bytes where an error has been found * @param offset Offset in bytes where an error has been found
* @param msg_info Message info added to an error attribute * @param msg_info Message info added to an error attribute
* @param error Error attribute if an error occurred * @param error Error attribute if an error occurred
* @return PA-TNC attribute object if supported, NULL else * @return PA-TNC attribute object if supported, NULL else
*/ */
pa_tnc_attr_t* (*create)(pa_tnc_attr_manager_t *this, bio_reader_t *reader, pa_tnc_attr_t* (*create)(pa_tnc_attr_manager_t *this, bio_reader_t *reader,
uint32_t *offset, chunk_t msg_info, bool segmented, uint32_t *offset, chunk_t msg_info,
pa_tnc_attr_t **error); pa_tnc_attr_t **error);
/** /**

View File

@ -37,6 +37,8 @@ typedef struct private_pa_tnc_msg_t private_pa_tnc_msg_t;
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/ */
#define PA_TNC_RESERVED 0x000000
/** /**
* Private data of a pa_tnc_msg_t object. * Private data of a pa_tnc_msg_t object.
* *
@ -187,8 +189,10 @@ METHOD(pa_tnc_msg_t, process, status_t,
{ {
bio_reader_t *reader; bio_reader_t *reader;
pa_tnc_attr_t *attr, *error; pa_tnc_attr_t *attr, *error;
pen_type_t attr_type;
chunk_t attr_value;
uint8_t version; uint8_t version;
uint32_t reserved, offset; uint32_t reserved, offset, attr_offset;
pen_type_t error_code = { PEN_IETF, PA_ERROR_INVALID_PARAMETER }; pen_type_t error_code = { PEN_IETF, PA_ERROR_INVALID_PARAMETER };
/* process message header */ /* process message header */
@ -219,15 +223,32 @@ METHOD(pa_tnc_msg_t, process, status_t,
while (reader->remaining(reader) > 0) while (reader->remaining(reader) > 0)
{ {
attr = imcv_pa_tnc_attributes->create(imcv_pa_tnc_attributes, attr = imcv_pa_tnc_attributes->create(imcv_pa_tnc_attributes,
reader, &offset, this->encoding, &error); reader, FALSE, &offset, this->encoding, &error);
if (error) if (!attr)
{ {
goto err; goto err;
} }
if (attr) attr_value = attr->get_value(attr);
attr_type = attr->get_type(attr);
if (attr->process(attr, &attr_offset) != SUCCESS)
{ {
this->attributes->insert_last(this->attributes, attr); attr->destroy(attr);
if (attr_type.vendor_id == PEN_IETF &&
attr_type.type == IETF_ATTR_PA_TNC_ERROR)
{
/* suppress error while processing a PA-TNC error attribute */
offset += attr_value.len;
continue;
}
error_code = pen_type_create(PEN_IETF, PA_ERROR_INVALID_PARAMETER);
error = ietf_attr_pa_tnc_error_create_with_offset(error_code,
this->encoding, offset + attr_offset);
goto err;
} }
offset += attr_value.len;
this->attributes->insert_last(this->attributes, attr);
} }
reader->destroy(reader); reader->destroy(reader);
return SUCCESS; return SUCCESS;

View File

@ -25,9 +25,6 @@ typedef struct pa_tnc_msg_t pa_tnc_msg_t;
#define PA_TNC_VERSION 0x01 #define PA_TNC_VERSION 0x01
#define PA_TNC_HEADER_SIZE 8 #define PA_TNC_HEADER_SIZE 8
#define PA_TNC_RESERVED 0x000000
#include "pa_tnc_attr.h" #include "pa_tnc_attr.h"

View File

@ -15,6 +15,7 @@
#include "seg_contract.h" #include "seg_contract.h"
#include "seg_env.h" #include "seg_env.h"
#include "ietf/ietf_attr_pa_tnc_error.h"
#include "tcg/seg/tcg_seg_attr_seg_env.h" #include "tcg/seg/tcg_seg_attr_seg_env.h"
#include <utils/debug.h> #include <utils/debug.h>
@ -195,9 +196,10 @@ METHOD(seg_contract_t, add_segment, pa_tnc_attr_t*,
tcg_seg_attr_seg_env_t *seg_env_attr; tcg_seg_attr_seg_env_t *seg_env_attr;
seg_env_t *current, *seg_env = NULL; seg_env_t *current, *seg_env = NULL;
pa_tnc_attr_t *base_attr; pa_tnc_attr_t *base_attr;
pen_type_t error_code;
uint32_t base_attr_id; uint32_t base_attr_id;
uint8_t flags; uint8_t flags;
chunk_t segment_data; chunk_t segment_data, msg_info;
enumerator_t *enumerator; enumerator_t *enumerator;
seg_env_attr = (tcg_seg_attr_seg_env_t*)attr; seg_env_attr = (tcg_seg_attr_seg_env_t*)attr;
@ -212,10 +214,7 @@ METHOD(seg_contract_t, add_segment, pa_tnc_attr_t*,
if (current->get_base_attr_id(current) == base_attr_id) if (current->get_base_attr_id(current) == base_attr_id)
{ {
seg_env = current; seg_env = current;
if (!(*more)) this->seg_envs->remove_at(this->seg_envs, enumerator);
{
this->seg_envs->remove_at(this->seg_envs, enumerator);
}
break; break;
} }
} }
@ -227,13 +226,17 @@ METHOD(seg_contract_t, add_segment, pa_tnc_attr_t*,
{ {
DBG1(DBG_TNC, "base attribute ID %d is already in use", DBG1(DBG_TNC, "base attribute ID %d is already in use",
base_attr_id); base_attr_id);
this->seg_envs->insert_last(this->seg_envs, seg_env);
return NULL; return NULL;
} }
DBG2(DBG_TNC, "received first segment for base attribute ID %d " DBG2(DBG_TNC, "received first segment for base attribute ID %d "
"(%d bytes)", base_attr_id, segment_data.len); "(%d bytes)", base_attr_id, segment_data.len);
seg_env = seg_env_create_from_data(base_attr_id, segment_data, seg_env = seg_env_create_from_data(base_attr_id, segment_data,
this->max_seg_size); this->max_seg_size, error);
this->seg_envs->insert_last(this->seg_envs, seg_env); if (!seg_env)
{
return NULL;
}
} }
else else
{ {
@ -245,19 +248,36 @@ METHOD(seg_contract_t, add_segment, pa_tnc_attr_t*,
DBG2(DBG_TNC, "received %s segment for base attribute ID %d " DBG2(DBG_TNC, "received %s segment for base attribute ID %d "
"(%d bytes)", (*more) ? "next" : "last", base_attr_id, "(%d bytes)", (*more) ? "next" : "last", base_attr_id,
segment_data.len); segment_data.len);
seg_env->add_segment(seg_env, segment_data); if (!seg_env->add_segment(seg_env, segment_data, error))
{
seg_env->destroy(seg_env);
return NULL;
}
} }
base_attr = seg_env->get_base_attr(seg_env);
if (*more) if (*more)
{ {
return NULL; /* reinsert into list since more segments are to come */
this->seg_envs->insert_last(this->seg_envs, seg_env);
}
else
{
/* added the last segment */
if (!base_attr)
{
/* base attribute waits for more data */
DBG1(DBG_TNC, "insufficient bytes for PA-TNC attribute value");
msg_info = seg_env->get_base_attr_info(seg_env);
error_code = pen_type_create(PEN_IETF, PA_ERROR_INVALID_PARAMETER);
*error = ietf_attr_pa_tnc_error_create_with_offset(error_code,
msg_info, PA_TNC_ATTR_INFO_SIZE);
}
seg_env->destroy(seg_env);
} }
base_attr = seg_env->get_base_attr(seg_env, error);
seg_env->destroy(seg_env);
return base_attr; return base_attr;
} }
METHOD(seg_contract_t, is_issuer, bool, METHOD(seg_contract_t, is_issuer, bool,
private_seg_contract_t *this) private_seg_contract_t *this)
{ {

View File

@ -17,6 +17,7 @@
#include "imcv.h" #include "imcv.h"
#include "pa_tnc/pa_tnc_msg.h" #include "pa_tnc/pa_tnc_msg.h"
#include "ietf/ietf_attr_pa_tnc_error.h"
#include "tcg/seg/tcg_seg_attr_seg_env.h" #include "tcg/seg/tcg_seg_attr_seg_env.h"
#include <utils/debug.h> #include <utils/debug.h>
@ -47,21 +48,26 @@ struct private_seg_env_t {
*/ */
pa_tnc_attr_t *base_attr; pa_tnc_attr_t *base_attr;
/**
* Base Attribute Info to be used for PA-TNC error messages
*/
u_char base_attr_info[8];
/**
* Base Attribute needs more segment data
*/
bool need_more;
/**
* Pointer to remaining attribute data to be sent
*/
chunk_t data;
/** /**
* Maximum PA-TNC attribute segment size * Maximum PA-TNC attribute segment size
*/ */
uint32_t max_seg_size; uint32_t max_seg_size;
/**
* TRUE if attribute is assembled from data
*/
bool from_data;
/**
* Remaining attribute data to be sent or received data being accumulated
*/
chunk_t data;
}; };
METHOD(seg_env_t, get_base_attr_id, uint32_t, METHOD(seg_env_t, get_base_attr_id, uint32_t,
@ -71,33 +77,15 @@ METHOD(seg_env_t, get_base_attr_id, uint32_t,
} }
METHOD(seg_env_t, get_base_attr, pa_tnc_attr_t*, METHOD(seg_env_t, get_base_attr, pa_tnc_attr_t*,
private_seg_env_t *this, pa_tnc_attr_t** error) private_seg_env_t *this)
{ {
*error = NULL; return this->need_more ? NULL : this->base_attr->get_ref(this->base_attr);
}
if (!this->base_attr) METHOD(seg_env_t, get_base_attr_info, chunk_t,
{ private_seg_env_t *this)
bio_writer_t *writer; {
bio_reader_t *reader; return chunk_create(this->base_attr_info, 8);
chunk_t msg_info;
uint32_t offset = 0;
writer = bio_writer_create(8);
writer->write_uint8 (writer, PA_TNC_VERSION);
writer->write_uint24(writer, PA_TNC_RESERVED);
writer->write_uint8 (writer, BASE_ATTR_ID_PREFIX);
writer->write_uint24(writer, this->base_attr_id);
msg_info = writer->extract_buf(writer);
writer->destroy(writer);
reader = bio_reader_create(this->data);
this->base_attr = imcv_pa_tnc_attributes->create(imcv_pa_tnc_attributes,
reader, &offset, msg_info, error);
chunk_free(&msg_info);
reader->destroy(reader);
}
return this->base_attr ? this->base_attr->get_ref(this->base_attr) : NULL;
} }
METHOD(seg_env_t, first_segment, pa_tnc_attr_t*, METHOD(seg_env_t, first_segment, pa_tnc_attr_t*,
@ -175,19 +163,44 @@ METHOD(seg_env_t, next_segment, pa_tnc_attr_t*,
return seg_env_attr; return seg_env_attr;
} }
METHOD(seg_env_t, add_segment, void, METHOD(seg_env_t, add_segment, bool,
private_seg_env_t *this, chunk_t segment_data) private_seg_env_t *this, chunk_t segment, pa_tnc_attr_t **error)
{ {
this->data = chunk_cat("mc", this->data, segment_data); pen_type_t type, error_code;
uint32_t attr_offset;
chunk_t msg_info;
status_t status;
/* not all attributes might have implemented the add_segment method */
if (!this->base_attr->add_segment)
{
return FALSE;
}
this->base_attr->add_segment(this->base_attr, segment);
status = this->base_attr->process(this->base_attr, &attr_offset);
if (status != SUCCESS && status != NEED_MORE)
{
type = this->base_attr->get_type(this->base_attr);
if (type.vendor_id == PEN_IETF && type.type == IETF_ATTR_PA_TNC_ERROR)
{
/* error while processing a PA-TNC error attribute - abort */
return FALSE;
}
error_code = pen_type_create(PEN_IETF, PA_ERROR_INVALID_PARAMETER);
msg_info = get_base_attr_info(this);
*error = ietf_attr_pa_tnc_error_create_with_offset(error_code,
msg_info, PA_TNC_ATTR_HEADER_SIZE + attr_offset);
return FALSE;
}
this->need_more = (status == NEED_MORE);
return TRUE;
} }
METHOD(seg_env_t, destroy, void, METHOD(seg_env_t, destroy, void,
private_seg_env_t *this) private_seg_env_t *this)
{ {
if (this->from_data)
{
chunk_free(&this->data);
}
DESTROY_IF(this->base_attr); DESTROY_IF(this->base_attr);
free(this); free(this);
} }
@ -218,6 +231,7 @@ seg_env_t *seg_env_create(uint32_t base_attr_id, pa_tnc_attr_t *base_attr,
.public = { .public = {
.get_base_attr_id = _get_base_attr_id, .get_base_attr_id = _get_base_attr_id,
.get_base_attr = _get_base_attr, .get_base_attr = _get_base_attr,
.get_base_attr_info = _get_base_attr_info,
.first_segment = _first_segment, .first_segment = _first_segment,
.next_segment = _next_segment, .next_segment = _next_segment,
.add_segment = _add_segment, .add_segment = _add_segment,
@ -236,14 +250,20 @@ seg_env_t *seg_env_create(uint32_t base_attr_id, pa_tnc_attr_t *base_attr,
* See header * See header
*/ */
seg_env_t *seg_env_create_from_data(uint32_t base_attr_id, chunk_t data, seg_env_t *seg_env_create_from_data(uint32_t base_attr_id, chunk_t data,
uint32_t max_seg_size) uint32_t max_seg_size, pa_tnc_attr_t** error)
{ {
private_seg_env_t *this; private_seg_env_t *this;
pen_type_t type, error_code;
bio_reader_t *reader;
chunk_t msg_info;
uint32_t offset = 0, attr_offset;
status_t status;
INIT(this, INIT(this,
.public = { .public = {
.get_base_attr_id = _get_base_attr_id, .get_base_attr_id = _get_base_attr_id,
.get_base_attr = _get_base_attr, .get_base_attr = _get_base_attr,
.get_base_attr_info = _get_base_attr_info,
.first_segment = _first_segment, .first_segment = _first_segment,
.next_segment = _next_segment, .next_segment = _next_segment,
.add_segment = _add_segment, .add_segment = _add_segment,
@ -251,10 +271,41 @@ seg_env_t *seg_env_create_from_data(uint32_t base_attr_id, chunk_t data,
}, },
.base_attr_id = base_attr_id, .base_attr_id = base_attr_id,
.max_seg_size = max_seg_size, .max_seg_size = max_seg_size,
.data = chunk_clone(data),
.from_data = TRUE,
); );
/* create info field to be used by PA-TNC error messages */
memset(this->base_attr_info, 0xff, 4);
htoun32(this->base_attr_info + 4, base_attr_id);
msg_info = get_base_attr_info(this);
/* extract from base attribute segment from data */
reader = bio_reader_create(data);
this->base_attr = imcv_pa_tnc_attributes->create(imcv_pa_tnc_attributes,
reader, TRUE, &offset, msg_info, error);
reader->destroy(reader);
if (!this->base_attr)
{
destroy(this);
return NULL;
}
status = this->base_attr->process(this->base_attr, &attr_offset);
if (status != SUCCESS && status != NEED_MORE)
{
type = this->base_attr->get_type(this->base_attr);
if (!(type.vendor_id == PEN_IETF &&
type.type == IETF_ATTR_PA_TNC_ERROR))
{
error_code = pen_type_create(PEN_IETF, PA_ERROR_INVALID_PARAMETER);
*error = ietf_attr_pa_tnc_error_create_with_offset(error_code,
msg_info, PA_TNC_ATTR_HEADER_SIZE + attr_offset);
}
destroy(this);
return NULL;
}
this->need_more = (status == NEED_MORE);
return &this->public; return &this->public;
} }

View File

@ -50,12 +50,18 @@ struct seg_env_t {
uint32_t (*get_base_attr_id)(seg_env_t *this); uint32_t (*get_base_attr_id)(seg_env_t *this);
/** /**
* Get Base Attribute * Get Base Attribute if it contains processed [incremental] data
* *
* @param error Error attribute if an error occurred or NULL
* @return Base Attribute (must be destroyed) or NULL * @return Base Attribute (must be destroyed) or NULL
*/ */
pa_tnc_attr_t* (*get_base_attr)(seg_env_t *this, pa_tnc_attr_t **error); pa_tnc_attr_t* (*get_base_attr)(seg_env_t *this);
/**
* Base Attribute Info to be used by PA-TNC error messages
*
* @return Message info string
*/
chunk_t (*get_base_attr_info)(seg_env_t *this);
/** /**
* Generate the first segment envelope of the base attribute * Generate the first segment envelope of the base attribute
@ -76,8 +82,11 @@ struct seg_env_t {
* Generate the first segment envelope of the base attribute * Generate the first segment envelope of the base attribute
* *
* @param segment Attribute segment to be added * @param segment Attribute segment to be added
* @param error Error attribute if a parsing error occurred
* return TRUE if segment was successfully added
*/ */
void (*add_segment)(seg_env_t *this, chunk_t segment); bool (*add_segment)(seg_env_t *this, chunk_t segment,
pa_tnc_attr_t** error);
/** /**
* Destroys a seg_env_t object. * Destroys a seg_env_t object.
@ -101,8 +110,10 @@ seg_env_t* seg_env_create(uint32_t base_attr_id, pa_tnc_attr_t *base_attr,
* @param base_attr_id Base Attribute ID * @param base_attr_id Base Attribute ID
* @param data First attribute segment * @param data First attribute segment
* @param max_seg_size Maximum segment size * @param max_seg_size Maximum segment size
* @param error Error attribute if a parsing error occurred
*/ */
seg_env_t* seg_env_create_from_data(uint32_t base_attr_id, chunk_t data, seg_env_t* seg_env_create_from_data(uint32_t base_attr_id, chunk_t data,
uint32_t max_seg_size); uint32_t max_seg_size,
pa_tnc_attr_t** error);
#endif /** SEG_ENV_H_ @}*/ #endif /** SEG_ENV_H_ @}*/

View File

@ -220,6 +220,12 @@ METHOD(pa_tnc_attr_t, process, status_t,
return SUCCESS; return SUCCESS;
} }
METHOD(pa_tnc_attr_t, add_segment, void,
private_tcg_swid_attr_req_t *this, chunk_t segment)
{
this->value = chunk_cat("mc", this->value, segment);
}
METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
private_tcg_swid_attr_req_t *this) private_tcg_swid_attr_req_t *this)
{ {
@ -285,6 +291,7 @@ pa_tnc_attr_t *tcg_swid_attr_req_create(u_int8_t flags, u_int32_t request_id,
.set_noskip_flag = _set_noskip_flag, .set_noskip_flag = _set_noskip_flag,
.build = _build, .build = _build,
.process = _process, .process = _process,
.add_segment = _add_segment,
.get_ref = _get_ref, .get_ref = _get_ref,
.destroy = _destroy, .destroy = _destroy,
}, },
@ -321,6 +328,7 @@ pa_tnc_attr_t *tcg_swid_attr_req_create_from_data(size_t length, chunk_t data)
.set_noskip_flag = _set_noskip_flag, .set_noskip_flag = _set_noskip_flag,
.build = _build, .build = _build,
.process = _process, .process = _process,
.add_segment = _add_segment,
.get_ref = _get_ref, .get_ref = _get_ref,
.destroy = _destroy, .destroy = _destroy,
}, },

View File

@ -224,6 +224,12 @@ METHOD(pa_tnc_attr_t, process, status_t,
return SUCCESS; return SUCCESS;
} }
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);
}
METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
private_tcg_swid_attr_tag_id_inv_t *this) private_tcg_swid_attr_tag_id_inv_t *this)
{ {
@ -288,6 +294,7 @@ pa_tnc_attr_t *tcg_swid_attr_tag_id_inv_create(uint32_t request_id,
.set_noskip_flag = _set_noskip_flag, .set_noskip_flag = _set_noskip_flag,
.build = _build, .build = _build,
.process = _process, .process = _process,
.add_segment = _add_segment,
.get_ref = _get_ref, .get_ref = _get_ref,
.destroy = _destroy, .destroy = _destroy,
}, },
@ -325,6 +332,7 @@ pa_tnc_attr_t *tcg_swid_attr_tag_id_inv_create_from_data(size_t length,
.set_noskip_flag = _set_noskip_flag, .set_noskip_flag = _set_noskip_flag,
.build = _build, .build = _build,
.process = _process, .process = _process,
.add_segment = _add_segment,
.get_ref = _get_ref, .get_ref = _get_ref,
.destroy = _destroy, .destroy = _destroy,
}, },

View File

@ -213,6 +213,12 @@ METHOD(pa_tnc_attr_t, process, status_t,
return SUCCESS; return SUCCESS;
} }
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);
}
METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
private_tcg_swid_attr_tag_inv_t *this) private_tcg_swid_attr_tag_inv_t *this)
{ {
@ -276,6 +282,7 @@ pa_tnc_attr_t *tcg_swid_attr_tag_inv_create(uint32_t request_id,
.set_noskip_flag = _set_noskip_flag, .set_noskip_flag = _set_noskip_flag,
.build = _build, .build = _build,
.process = _process, .process = _process,
.add_segment = _add_segment,
.get_ref = _get_ref, .get_ref = _get_ref,
.destroy = _destroy, .destroy = _destroy,
}, },
@ -312,6 +319,7 @@ pa_tnc_attr_t *tcg_swid_attr_tag_inv_create_from_data(size_t length,
.set_noskip_flag = _set_noskip_flag, .set_noskip_flag = _set_noskip_flag,
.build = _build, .build = _build,
.process = _process, .process = _process,
.add_segment = _add_segment,
.get_ref = _get_ref, .get_ref = _get_ref,
.destroy = _destroy, .destroy = _destroy,
}, },