Implemented IF-M segmentation
This commit is contained in:
@@ -56,8 +56,9 @@ libimcv_la_SOURCES = \
|
|||||||
pa_tnc/pa_tnc_attr.h \
|
pa_tnc/pa_tnc_attr.h \
|
||||||
pa_tnc/pa_tnc_msg.h pa_tnc/pa_tnc_msg.c \
|
pa_tnc/pa_tnc_msg.h pa_tnc/pa_tnc_msg.c \
|
||||||
pa_tnc/pa_tnc_attr_manager.h pa_tnc/pa_tnc_attr_manager.c \
|
pa_tnc/pa_tnc_attr_manager.h pa_tnc/pa_tnc_attr_manager.c \
|
||||||
seg_contract/seg_contract.h seg_contract/seg_contract.c \
|
seg/seg_contract.h seg/seg_contract.c \
|
||||||
seg_contract/seg_contract_manager.h seg_contract/seg_contract_manager.c
|
seg/seg_contract_manager.h seg/seg_contract_manager.c \
|
||||||
|
seg/seg_env.h seg/seg_env.c
|
||||||
|
|
||||||
ipsec_SCRIPTS = imv/_imv_policy
|
ipsec_SCRIPTS = imv/_imv_policy
|
||||||
EXTRA_DIST = imv/_imv_policy Android.mk
|
EXTRA_DIST = imv/_imv_policy Android.mk
|
||||||
|
|||||||
+158
-60
@@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include <tcg/seg/tcg_seg_attr_max_size.h>
|
#include <tcg/seg/tcg_seg_attr_max_size.h>
|
||||||
#include <tcg/seg/tcg_seg_attr_seg_env.h>
|
#include <tcg/seg/tcg_seg_attr_seg_env.h>
|
||||||
|
#include <tcg/seg/tcg_seg_attr_next_seg.h>
|
||||||
|
|
||||||
#include <pen/pen.h>
|
#include <pen/pen.h>
|
||||||
#include <collections/linked_list.h>
|
#include <collections/linked_list.h>
|
||||||
@@ -108,11 +109,17 @@ METHOD(imc_msg_t, send_, TNC_Result,
|
|||||||
pa_tnc_attr_t *attr;
|
pa_tnc_attr_t *attr;
|
||||||
TNC_UInt32 msg_flags;
|
TNC_UInt32 msg_flags;
|
||||||
TNC_MessageType msg_type;
|
TNC_MessageType msg_type;
|
||||||
bool attr_added;
|
bool attr_added, oversize;
|
||||||
chunk_t msg;
|
chunk_t msg;
|
||||||
|
seg_contract_t *contract;
|
||||||
|
seg_contract_manager_t *contracts;
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
TNC_Result result = TNC_RESULT_SUCCESS;
|
TNC_Result result = TNC_RESULT_SUCCESS;
|
||||||
|
|
||||||
|
/* Get IF-M segmentation contract for this subtype if any */
|
||||||
|
contracts = this->state->get_contracts(this->state);
|
||||||
|
contract = contracts->get_contract(contracts, this->msg_type, FALSE);
|
||||||
|
|
||||||
while (this->attr_list->get_count(this->attr_list))
|
while (this->attr_list->get_count(this->attr_list))
|
||||||
{
|
{
|
||||||
pa_tnc_msg = pa_tnc_msg_create(this->state->get_max_msg_len(this->state));
|
pa_tnc_msg = pa_tnc_msg_create(this->state->get_max_msg_len(this->state));
|
||||||
@@ -121,6 +128,17 @@ METHOD(imc_msg_t, send_, TNC_Result,
|
|||||||
enumerator = this->attr_list->create_enumerator(this->attr_list);
|
enumerator = this->attr_list->create_enumerator(this->attr_list);
|
||||||
while (enumerator->enumerate(enumerator, &attr))
|
while (enumerator->enumerate(enumerator, &attr))
|
||||||
{
|
{
|
||||||
|
if (contract && contract->check_size(contract, attr, &oversize))
|
||||||
|
{
|
||||||
|
if (oversize)
|
||||||
|
{
|
||||||
|
/* TODO generate SWID error msg */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
attr = contract->first_segment(contract, attr);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (pa_tnc_msg->add_attribute(pa_tnc_msg, attr))
|
if (pa_tnc_msg->add_attribute(pa_tnc_msg, attr))
|
||||||
{
|
{
|
||||||
attr_added = TRUE;
|
attr_added = TRUE;
|
||||||
@@ -274,7 +292,6 @@ METHOD(imc_msg_t, receive, TNC_Result,
|
|||||||
enumerator = this->pa_msg->create_attribute_enumerator(this->pa_msg);
|
enumerator = this->pa_msg->create_attribute_enumerator(this->pa_msg);
|
||||||
while (enumerator->enumerate(enumerator, &attr))
|
while (enumerator->enumerate(enumerator, &attr))
|
||||||
{
|
{
|
||||||
tcg_seg_attr_max_size_t *attr_cast;
|
|
||||||
uint32_t max_attr_size, max_seg_size, my_max_attr_size, my_max_seg_size;
|
uint32_t max_attr_size, max_seg_size, my_max_attr_size, my_max_seg_size;
|
||||||
seg_contract_t *contract;
|
seg_contract_t *contract;
|
||||||
seg_contract_manager_t *contracts;
|
seg_contract_manager_t *contracts;
|
||||||
@@ -283,79 +300,160 @@ METHOD(imc_msg_t, receive, TNC_Result,
|
|||||||
|
|
||||||
type = attr->get_type(attr);
|
type = attr->get_type(attr);
|
||||||
|
|
||||||
|
contracts = this->state->get_contracts(this->state);
|
||||||
|
|
||||||
if (type.vendor_id != PEN_TCG)
|
if (type.vendor_id != PEN_TCG)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type.type == TCG_SEG_MAX_ATTR_SIZE_REQ)
|
switch (type.type)
|
||||||
{
|
{
|
||||||
attr_cast = (tcg_seg_attr_max_size_t*)attr;
|
case TCG_SEG_MAX_ATTR_SIZE_REQ:
|
||||||
attr_cast->get_attr_size(attr_cast, &max_attr_size, &max_seg_size);
|
|
||||||
|
|
||||||
contracts = this->state->get_contracts(this->state);
|
|
||||||
contract = contracts->get_contract(contracts, this->msg_type, FALSE);
|
|
||||||
if (contract)
|
|
||||||
{
|
{
|
||||||
contract->set_max_size(contract, max_attr_size, max_seg_size);
|
tcg_seg_attr_max_size_t *attr_cast;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
contract = seg_contract_create(this->msg_type, max_attr_size,
|
|
||||||
max_seg_size, FALSE, this->src_id, TRUE);
|
|
||||||
contracts->add_contract(contracts, contract);
|
|
||||||
}
|
|
||||||
contract->get_info_string(contract, buf, BUF_LEN, TRUE);
|
|
||||||
DBG2(DBG_IMC, "%s", buf);
|
|
||||||
|
|
||||||
/* Determine maximum PA-TNC attribute segment size */
|
attr_cast = (tcg_seg_attr_max_size_t*)attr;
|
||||||
my_max_seg_size = this->state->get_max_msg_len(this->state)
|
attr_cast->get_attr_size(attr_cast, &max_attr_size,
|
||||||
- PA_TNC_HEADER_SIZE
|
&max_seg_size);
|
||||||
- PA_TNC_ATTR_HEADER_SIZE
|
contract = contracts->get_contract(contracts, this->msg_type,
|
||||||
- TCG_SEG_ATTR_SEG_ENV_HEADER
|
FALSE);
|
||||||
- PA_TNC_ATTR_HEADER_SIZE
|
if (contract)
|
||||||
- TCG_SEG_ATTR_MAX_SIZE_SIZE;
|
|
||||||
|
|
||||||
/* If segmentation is not prohibited select lower segment size */
|
|
||||||
if (max_seg_size != SEG_CONTRACT_NO_FRAGMENTATION &&
|
|
||||||
max_seg_size > my_max_seg_size)
|
|
||||||
{
|
|
||||||
max_seg_size = my_max_seg_size;
|
|
||||||
contract->set_max_size(contract, max_attr_size, max_seg_size);
|
|
||||||
DBG2(DBG_IMC, " lowered maximum segment size to %u bytes",
|
|
||||||
max_seg_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add Maximum Attribute Size Response attribute */
|
|
||||||
attr = tcg_seg_attr_max_size_create(max_attr_size,
|
|
||||||
max_seg_size, FALSE);
|
|
||||||
out_msg->add_attribute(out_msg, attr);
|
|
||||||
}
|
|
||||||
else if (type.type == TCG_SEG_MAX_ATTR_SIZE_RESP)
|
|
||||||
{
|
|
||||||
attr_cast = (tcg_seg_attr_max_size_t*)attr;
|
|
||||||
attr_cast->get_attr_size(attr_cast, &max_attr_size, &max_seg_size);
|
|
||||||
|
|
||||||
contracts = this->state->get_contracts(this->state);
|
|
||||||
contract = contracts->get_contract(contracts, this->msg_type, TRUE);
|
|
||||||
if (contract)
|
|
||||||
{
|
|
||||||
contract->get_max_size(contract, &my_max_attr_size,
|
|
||||||
&my_max_seg_size);
|
|
||||||
if (my_max_seg_size != SEG_CONTRACT_NO_FRAGMENTATION &&
|
|
||||||
my_max_seg_size > max_seg_size)
|
|
||||||
{
|
{
|
||||||
my_max_seg_size = max_seg_size;
|
contract->set_max_size(contract, max_attr_size,
|
||||||
contract->set_max_size(contract, my_max_attr_size,
|
max_seg_size);
|
||||||
my_max_seg_size);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
contract = seg_contract_create(this->msg_type, max_attr_size,
|
||||||
|
max_seg_size, FALSE, this->src_id, TRUE);
|
||||||
|
contracts->add_contract(contracts, contract);
|
||||||
|
}
|
||||||
|
contract->get_info_string(contract, buf, BUF_LEN, TRUE);
|
||||||
|
DBG2(DBG_IMC, "%s", buf);
|
||||||
|
|
||||||
|
/* Determine maximum PA-TNC attribute segment size */
|
||||||
|
my_max_seg_size = this->state->get_max_msg_len(this->state)
|
||||||
|
- PA_TNC_HEADER_SIZE
|
||||||
|
- PA_TNC_ATTR_HEADER_SIZE
|
||||||
|
- TCG_SEG_ATTR_SEG_ENV_HEADER
|
||||||
|
- PA_TNC_ATTR_HEADER_SIZE
|
||||||
|
- TCG_SEG_ATTR_MAX_SIZE_SIZE;
|
||||||
|
|
||||||
|
/* If segmentation is possible select lower segment size */
|
||||||
|
if (max_seg_size != SEG_CONTRACT_NO_FRAGMENTATION &&
|
||||||
|
max_seg_size > my_max_seg_size)
|
||||||
|
{
|
||||||
|
max_seg_size = my_max_seg_size;
|
||||||
|
contract->set_max_size(contract, max_attr_size,
|
||||||
|
max_seg_size);
|
||||||
|
DBG2(DBG_IMC, " lowered maximum segment size to %u bytes",
|
||||||
|
max_seg_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add Maximum Attribute Size Response attribute */
|
||||||
|
attr = tcg_seg_attr_max_size_create(max_attr_size,
|
||||||
|
max_seg_size, FALSE);
|
||||||
|
out_msg->add_attribute(out_msg, attr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TCG_SEG_MAX_ATTR_SIZE_RESP:
|
||||||
|
{
|
||||||
|
tcg_seg_attr_max_size_t *attr_cast;
|
||||||
|
|
||||||
|
attr_cast = (tcg_seg_attr_max_size_t*)attr;
|
||||||
|
attr_cast->get_attr_size(attr_cast, &max_attr_size,
|
||||||
|
&max_seg_size);
|
||||||
|
contract = contracts->get_contract(contracts, this->msg_type,
|
||||||
|
TRUE);
|
||||||
|
if (contract)
|
||||||
|
{
|
||||||
|
contract->get_max_size(contract, &my_max_attr_size,
|
||||||
|
&my_max_seg_size);
|
||||||
|
if (my_max_seg_size != SEG_CONTRACT_NO_FRAGMENTATION &&
|
||||||
|
my_max_seg_size > max_seg_size)
|
||||||
|
{
|
||||||
|
my_max_seg_size = max_seg_size;
|
||||||
|
contract->set_max_size(contract, my_max_attr_size,
|
||||||
|
my_max_seg_size);
|
||||||
|
}
|
||||||
contract->get_info_string(contract, buf, BUF_LEN, FALSE);
|
contract->get_info_string(contract, buf, BUF_LEN, FALSE);
|
||||||
DBG2(DBG_IMC, "%s", buf);
|
DBG2(DBG_IMC, "%s", buf);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* TODO no request pending */
|
||||||
|
DBG1(DBG_IMC, "no contract for this PA message type found");
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
case TCG_SEG_ATTR_SEG_ENV:
|
||||||
{
|
{
|
||||||
/* TODO no request pending */
|
tcg_seg_attr_seg_env_t *seg_env_attr;
|
||||||
|
pa_tnc_attr_t *error;
|
||||||
|
uint32_t base_attr_id;
|
||||||
|
bool more;
|
||||||
|
|
||||||
|
seg_env_attr = (tcg_seg_attr_seg_env_t*)attr;
|
||||||
|
base_attr_id = seg_env_attr->get_base_attr_id(seg_env_attr);
|
||||||
|
|
||||||
|
contract = contracts->get_contract(contracts, this->msg_type,
|
||||||
|
TRUE);
|
||||||
|
if (!contract)
|
||||||
|
{
|
||||||
|
DBG2(DBG_IMC, "no contract for received attribute segment "
|
||||||
|
"with base attribute ID %u", base_attr_id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
attr = contract->add_segment(contract, attr, &error, &more);
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
out_msg->add_attribute(out_msg, error);
|
||||||
|
}
|
||||||
|
if (attr)
|
||||||
|
{
|
||||||
|
this->pa_msg->add_attribute(this->pa_msg, attr);
|
||||||
|
}
|
||||||
|
if (more)
|
||||||
|
{
|
||||||
|
/* Send Next Segment Request */
|
||||||
|
attr = tcg_seg_attr_next_seg_create(base_attr_id, FALSE);
|
||||||
|
out_msg->add_attribute(out_msg, attr);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
case TCG_SEG_NEXT_SEG_REQ:
|
||||||
|
{
|
||||||
|
tcg_seg_attr_next_seg_t *attr_cast;
|
||||||
|
uint32_t base_attr_id;
|
||||||
|
|
||||||
|
attr_cast = (tcg_seg_attr_next_seg_t*)attr;
|
||||||
|
base_attr_id = attr_cast->get_base_attr_id(attr_cast);
|
||||||
|
|
||||||
|
contract = contracts->get_contract(contracts, this->msg_type,
|
||||||
|
FALSE);
|
||||||
|
if (!contract)
|
||||||
|
{
|
||||||
|
/* TODO no contract - generate error message */
|
||||||
|
DBG2(DBG_IMC, "no contract for received next segment "
|
||||||
|
"request with base attribute ID %u", base_attr_id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
attr = contract->next_segment(contract, base_attr_id);
|
||||||
|
if (attr)
|
||||||
|
{
|
||||||
|
out_msg->add_attribute(out_msg, attr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* TODO no more segments - generate error message */
|
||||||
|
DBG1(DBG_IMC, "no more segments found for "
|
||||||
|
"base attribute ID %u", base_attr_id);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
#ifndef IMC_STATE_H_
|
#ifndef IMC_STATE_H_
|
||||||
#define IMC_STATE_H_
|
#define IMC_STATE_H_
|
||||||
|
|
||||||
#include "seg_contract/seg_contract_manager.h"
|
#include "seg/seg_contract_manager.h"
|
||||||
|
|
||||||
#include <tncif.h>
|
#include <tncif.h>
|
||||||
#include <tncifimv.h>
|
#include <tncifimv.h>
|
||||||
|
|||||||
+168
-63
@@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include <tcg/seg/tcg_seg_attr_max_size.h>
|
#include <tcg/seg/tcg_seg_attr_max_size.h>
|
||||||
#include <tcg/seg/tcg_seg_attr_seg_env.h>
|
#include <tcg/seg/tcg_seg_attr_seg_env.h>
|
||||||
|
#include <tcg/seg/tcg_seg_attr_next_seg.h>
|
||||||
|
|
||||||
#include <pen/pen.h>
|
#include <pen/pen.h>
|
||||||
#include <collections/linked_list.h>
|
#include <collections/linked_list.h>
|
||||||
@@ -125,11 +126,17 @@ METHOD(imv_msg_t, send_, TNC_Result,
|
|||||||
pa_tnc_attr_t *attr;
|
pa_tnc_attr_t *attr;
|
||||||
TNC_UInt32 msg_flags;
|
TNC_UInt32 msg_flags;
|
||||||
TNC_MessageType msg_type;
|
TNC_MessageType msg_type;
|
||||||
bool attr_added;
|
bool attr_added, oversize;
|
||||||
chunk_t msg;
|
chunk_t msg;
|
||||||
|
seg_contract_t *contract;
|
||||||
|
seg_contract_manager_t *contracts;
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
TNC_Result result = TNC_RESULT_SUCCESS;
|
TNC_Result result = TNC_RESULT_SUCCESS;
|
||||||
|
|
||||||
|
/* Get IF-M segmentation contract for this subtype if any */
|
||||||
|
contracts = this->state->get_contracts(this->state);
|
||||||
|
contract = contracts->get_contract(contracts, this->msg_type, FALSE);
|
||||||
|
|
||||||
while (this->attr_list->get_count(this->attr_list))
|
while (this->attr_list->get_count(this->attr_list))
|
||||||
{
|
{
|
||||||
pa_tnc_msg = pa_tnc_msg_create(this->state->get_max_msg_len(this->state));
|
pa_tnc_msg = pa_tnc_msg_create(this->state->get_max_msg_len(this->state));
|
||||||
@@ -138,6 +145,17 @@ METHOD(imv_msg_t, send_, TNC_Result,
|
|||||||
enumerator = this->attr_list->create_enumerator(this->attr_list);
|
enumerator = this->attr_list->create_enumerator(this->attr_list);
|
||||||
while (enumerator->enumerate(enumerator, &attr))
|
while (enumerator->enumerate(enumerator, &attr))
|
||||||
{
|
{
|
||||||
|
if (contract && contract->check_size(contract, attr, &oversize))
|
||||||
|
{
|
||||||
|
if (oversize)
|
||||||
|
{
|
||||||
|
/* TODO generate SWID error msg */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
attr = contract->first_segment(contract, attr);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (pa_tnc_msg->add_attribute(pa_tnc_msg, attr))
|
if (pa_tnc_msg->add_attribute(pa_tnc_msg, attr))
|
||||||
{
|
{
|
||||||
attr_added = TRUE;
|
attr_added = TRUE;
|
||||||
@@ -317,15 +335,14 @@ METHOD(imv_msg_t, receive, TNC_Result,
|
|||||||
return TNC_RESULT_FATAL;
|
return TNC_RESULT_FATAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* process any IF-M segmentation contracts */
|
/* process IF-M segmentation attributes */
|
||||||
enumerator = this->pa_msg->create_attribute_enumerator(this->pa_msg);
|
enumerator = this->pa_msg->create_attribute_enumerator(this->pa_msg);
|
||||||
while (enumerator->enumerate(enumerator, &attr))
|
while (enumerator->enumerate(enumerator, &attr))
|
||||||
{
|
{
|
||||||
uint32_t max_attr_size, max_seg_size, my_max_attr_size, my_max_seg_size;
|
uint32_t max_attr_size, max_seg_size, my_max_attr_size, my_max_seg_size;
|
||||||
tcg_seg_attr_max_size_t *attr_cast;
|
|
||||||
imv_msg_t *out_msg;
|
imv_msg_t *out_msg;
|
||||||
seg_contract_t *contract;
|
|
||||||
seg_contract_manager_t *contracts;
|
seg_contract_manager_t *contracts;
|
||||||
|
seg_contract_t *contract;
|
||||||
char buf[BUF_LEN];
|
char buf[BUF_LEN];
|
||||||
pen_type_t type;
|
pen_type_t type;
|
||||||
|
|
||||||
@@ -336,81 +353,169 @@ METHOD(imv_msg_t, receive, TNC_Result,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type.type == TCG_SEG_MAX_ATTR_SIZE_REQ)
|
contracts = this->state->get_contracts(this->state);
|
||||||
|
|
||||||
|
switch (type.type)
|
||||||
{
|
{
|
||||||
attr_cast = (tcg_seg_attr_max_size_t*)attr;
|
case TCG_SEG_MAX_ATTR_SIZE_REQ:
|
||||||
attr_cast->get_attr_size(attr_cast, &max_attr_size, &max_seg_size);
|
{
|
||||||
|
tcg_seg_attr_max_size_t *attr_cast;
|
||||||
|
|
||||||
contracts = this->state->get_contracts(this->state);
|
attr_cast = (tcg_seg_attr_max_size_t*)attr;
|
||||||
contract = contracts->get_contract(contracts, this->msg_type, FALSE);
|
attr_cast->get_attr_size(attr_cast, &max_attr_size,
|
||||||
if (contract)
|
&max_seg_size);
|
||||||
{
|
contract = contracts->get_contract(contracts, this->msg_type,
|
||||||
contract->set_max_size(contract, max_attr_size, max_seg_size);
|
FALSE);
|
||||||
}
|
if (contract)
|
||||||
else
|
{
|
||||||
{
|
contract->set_max_size(contract, max_attr_size,
|
||||||
contract = seg_contract_create(this->msg_type, max_attr_size,
|
max_seg_size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
contract = seg_contract_create(this->msg_type, max_attr_size,
|
||||||
max_seg_size, FALSE, this->src_id, FALSE);
|
max_seg_size, FALSE, this->src_id, FALSE);
|
||||||
contracts->add_contract(contracts, contract);
|
contracts->add_contract(contracts, contract);
|
||||||
}
|
}
|
||||||
contract->get_info_string(contract, buf, BUF_LEN, TRUE);
|
contract->get_info_string(contract, buf, BUF_LEN, TRUE);
|
||||||
DBG2(DBG_IMV, "%s", buf);
|
DBG2(DBG_IMV, "%s", buf);
|
||||||
|
|
||||||
/* Determine maximum PA-TNC attribute segment size */
|
/* Determine maximum PA-TNC attribute segment size */
|
||||||
my_max_seg_size = this->state->get_max_msg_len(this->state)
|
my_max_seg_size = this->state->get_max_msg_len(this->state)
|
||||||
- PA_TNC_HEADER_SIZE
|
- PA_TNC_HEADER_SIZE
|
||||||
- PA_TNC_ATTR_HEADER_SIZE
|
- PA_TNC_ATTR_HEADER_SIZE
|
||||||
- TCG_SEG_ATTR_SEG_ENV_HEADER
|
- TCG_SEG_ATTR_SEG_ENV_HEADER
|
||||||
- PA_TNC_ATTR_HEADER_SIZE
|
- PA_TNC_ATTR_HEADER_SIZE
|
||||||
- TCG_SEG_ATTR_MAX_SIZE_SIZE;
|
- TCG_SEG_ATTR_MAX_SIZE_SIZE;
|
||||||
|
|
||||||
/* If segmentation is not prohibited select lower segment size */
|
/* If segmentation is possible select lower segment size */
|
||||||
if (max_seg_size != SEG_CONTRACT_NO_FRAGMENTATION &&
|
if (max_seg_size != SEG_CONTRACT_NO_FRAGMENTATION &&
|
||||||
max_seg_size > my_max_seg_size)
|
max_seg_size > my_max_seg_size)
|
||||||
{
|
{
|
||||||
max_seg_size = my_max_seg_size;
|
max_seg_size = my_max_seg_size;
|
||||||
contract->set_max_size(contract, max_attr_size, max_seg_size);
|
contract->set_max_size(contract, max_attr_size,
|
||||||
DBG2(DBG_IMV, " lowered maximum segment size to %u bytes",
|
max_seg_size);
|
||||||
max_seg_size);
|
DBG2(DBG_IMV, " lowered maximum segment size to %u bytes",
|
||||||
}
|
max_seg_size);
|
||||||
|
}
|
||||||
|
|
||||||
/* Send Maximum Attribute Size Response */
|
/* Send Maximum Attribute Size Response */
|
||||||
out_msg = imv_msg_create_as_reply(&this->public);
|
out_msg = imv_msg_create_as_reply(&this->public);
|
||||||
attr = tcg_seg_attr_max_size_create(max_attr_size,
|
attr = tcg_seg_attr_max_size_create(max_attr_size,
|
||||||
max_seg_size, FALSE);
|
max_seg_size, FALSE);
|
||||||
out_msg->add_attribute(out_msg, attr);
|
out_msg->add_attribute(out_msg, attr);
|
||||||
result = out_msg->send(out_msg, TRUE);
|
result = out_msg->send(out_msg, TRUE);
|
||||||
out_msg->destroy(out_msg);
|
out_msg->destroy(out_msg);
|
||||||
if (result != TNC_RESULT_SUCCESS)
|
if (result != TNC_RESULT_SUCCESS)
|
||||||
{
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
case TCG_SEG_MAX_ATTR_SIZE_RESP:
|
||||||
else if (type.type == TCG_SEG_MAX_ATTR_SIZE_RESP)
|
|
||||||
{
|
|
||||||
attr_cast = (tcg_seg_attr_max_size_t*)attr;
|
|
||||||
attr_cast->get_attr_size(attr_cast, &max_attr_size, &max_seg_size);
|
|
||||||
|
|
||||||
contracts = this->state->get_contracts(this->state);
|
|
||||||
contract = contracts->get_contract(contracts, this->msg_type, TRUE);
|
|
||||||
if (contract)
|
|
||||||
{
|
{
|
||||||
contract->get_max_size(contract, &my_max_attr_size,
|
tcg_seg_attr_max_size_t *attr_cast;
|
||||||
&my_max_seg_size);
|
|
||||||
if (my_max_seg_size != SEG_CONTRACT_NO_FRAGMENTATION &&
|
attr_cast = (tcg_seg_attr_max_size_t*)attr;
|
||||||
my_max_seg_size > max_seg_size)
|
attr_cast->get_attr_size(attr_cast, &max_attr_size,
|
||||||
|
&max_seg_size);
|
||||||
|
contract = contracts->get_contract(contracts, this->msg_type,
|
||||||
|
TRUE);
|
||||||
|
if (contract)
|
||||||
{
|
{
|
||||||
my_max_seg_size = max_seg_size;
|
contract->get_max_size(contract, &my_max_attr_size,
|
||||||
contract->set_max_size(contract, my_max_attr_size,
|
&my_max_seg_size);
|
||||||
my_max_seg_size);
|
if (my_max_seg_size != SEG_CONTRACT_NO_FRAGMENTATION &&
|
||||||
|
my_max_seg_size > max_seg_size)
|
||||||
|
{
|
||||||
|
my_max_seg_size = max_seg_size;
|
||||||
|
contract->set_max_size(contract, my_max_attr_size,
|
||||||
|
my_max_seg_size);
|
||||||
|
}
|
||||||
contract->get_info_string(contract, buf, BUF_LEN, FALSE);
|
contract->get_info_string(contract, buf, BUF_LEN, FALSE);
|
||||||
DBG2(DBG_IMV, "%s", buf);
|
DBG2(DBG_IMV, "%s", buf);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* TODO no request pending */
|
||||||
|
DBG1(DBG_IMV, "no contract for this PA message type found");
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
case TCG_SEG_ATTR_SEG_ENV:
|
||||||
{
|
{
|
||||||
/* TODO no request pending */
|
tcg_seg_attr_seg_env_t *seg_env_attr;
|
||||||
|
pa_tnc_attr_t *error;
|
||||||
|
uint32_t base_attr_id;
|
||||||
|
bool more;
|
||||||
|
|
||||||
|
seg_env_attr = (tcg_seg_attr_seg_env_t*)attr;
|
||||||
|
base_attr_id = seg_env_attr->get_base_attr_id(seg_env_attr);
|
||||||
|
|
||||||
|
contract = contracts->get_contract(contracts, this->msg_type,
|
||||||
|
TRUE);
|
||||||
|
if (!contract)
|
||||||
|
{
|
||||||
|
DBG2(DBG_IMV, "no contract for received attribute segment "
|
||||||
|
"with base attribute ID %u", base_attr_id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
attr = contract->add_segment(contract, attr, &error, &more);
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
out_msg = imv_msg_create_as_reply(&this->public);
|
||||||
|
out_msg->add_attribute(out_msg, error);
|
||||||
|
result = out_msg->send(out_msg, TRUE);
|
||||||
|
out_msg->destroy(out_msg);
|
||||||
|
}
|
||||||
|
if (attr)
|
||||||
|
{
|
||||||
|
this->pa_msg->add_attribute(this->pa_msg, attr);
|
||||||
|
}
|
||||||
|
if (more)
|
||||||
|
{
|
||||||
|
/* Send Next Segment Request */
|
||||||
|
out_msg = imv_msg_create_as_reply(&this->public);
|
||||||
|
attr = tcg_seg_attr_next_seg_create(base_attr_id, FALSE);
|
||||||
|
out_msg->add_attribute(out_msg, attr);
|
||||||
|
result = out_msg->send(out_msg, TRUE);
|
||||||
|
out_msg->destroy(out_msg);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
case TCG_SEG_NEXT_SEG_REQ:
|
||||||
|
{
|
||||||
|
tcg_seg_attr_next_seg_t *attr_cast;
|
||||||
|
uint32_t base_attr_id;
|
||||||
|
|
||||||
|
attr_cast = (tcg_seg_attr_next_seg_t*)attr;
|
||||||
|
base_attr_id = attr_cast->get_base_attr_id(attr_cast);
|
||||||
|
|
||||||
|
contract = contracts->get_contract(contracts, this->msg_type,
|
||||||
|
FALSE);
|
||||||
|
if (!contract)
|
||||||
|
{
|
||||||
|
/* TODO no contract - generate error message */
|
||||||
|
DBG2(DBG_IMV, "no contract for received next segment "
|
||||||
|
"request with base attribute ID %u", base_attr_id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
attr = contract->next_segment(contract, base_attr_id);
|
||||||
|
if (attr)
|
||||||
|
{
|
||||||
|
out_msg = imv_msg_create_as_reply(&this->public);
|
||||||
|
out_msg->add_attribute(out_msg, attr);
|
||||||
|
result = out_msg->send(out_msg, TRUE);
|
||||||
|
out_msg->destroy(out_msg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* TODO no more segments - generate error message */
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#define IMV_STATE_H_
|
#define IMV_STATE_H_
|
||||||
|
|
||||||
#include "imv_session.h"
|
#include "imv_session.h"
|
||||||
#include "seg_contract/seg_contract_manager.h"
|
#include "seg/seg_contract_manager.h"
|
||||||
|
|
||||||
#include <tncifimv.h>
|
#include <tncifimv.h>
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,9 @@ typedef struct pa_tnc_attr_t pa_tnc_attr_t;
|
|||||||
|
|
||||||
#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_NOSKIP (1<<7)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for an RFC 5792 PA-TNC Posture Attribute.
|
* Interface for an RFC 5792 PA-TNC Posture Attribute.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2011 Andreas Steffen
|
* Copyright (C) 2011-2014 Andreas Steffen
|
||||||
*
|
*
|
||||||
* HSR Hochschule fuer Technik Rapperswil
|
* HSR Hochschule fuer Technik Rapperswil
|
||||||
*
|
*
|
||||||
@@ -16,6 +16,10 @@
|
|||||||
|
|
||||||
#include "pa_tnc_attr_manager.h"
|
#include "pa_tnc_attr_manager.h"
|
||||||
|
|
||||||
|
#include "imcv.h"
|
||||||
|
#include "pa_tnc_attr.h"
|
||||||
|
#include "ietf/ietf_attr_pa_tnc_error.h"
|
||||||
|
|
||||||
#include <collections/linked_list.h>
|
#include <collections/linked_list.h>
|
||||||
#include <utils/debug.h>
|
#include <utils/debug.h>
|
||||||
|
|
||||||
@@ -100,14 +104,102 @@ METHOD(pa_tnc_attr_manager_t, get_names, enum_name_t*,
|
|||||||
return attr_names;
|
return attr_names;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PA-TNC attribute
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
* | Flags | PA-TNC Attribute Vendor ID |
|
||||||
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
* | PA-TNC Attribute Type |
|
||||||
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
* | PA-TNC Attribute Length |
|
||||||
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
* | Attribute Value (Variable Length) |
|
||||||
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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, pen_t vendor_id, u_int32_t type,
|
private_pa_tnc_attr_manager_t *this, bio_reader_t *reader, uint32_t *offset,
|
||||||
chunk_t value)
|
chunk_t msg_info, pa_tnc_attr_t **error)
|
||||||
{
|
{
|
||||||
|
uint8_t flags;
|
||||||
|
uint32_t type, length, attr_offset;
|
||||||
|
chunk_t value;
|
||||||
|
ietf_attr_pa_tnc_error_t *error_attr;
|
||||||
|
pen_t vendor_id;
|
||||||
|
pen_type_t unsupported_type;
|
||||||
|
pen_type_t error_code = { PEN_IETF, PA_ERROR_INVALID_PARAMETER };
|
||||||
|
enum_name_t *pa_attr_names;
|
||||||
|
pa_tnc_attr_t *attr = NULL;
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
entry_t *entry;
|
entry_t *entry;
|
||||||
pa_tnc_attr_t *attr = NULL;
|
|
||||||
|
|
||||||
|
/* properly initialize error return argument in case of no error */
|
||||||
|
*error = NULL;
|
||||||
|
|
||||||
|
if (reader->remaining(reader) < PA_TNC_ATTR_HEADER_SIZE)
|
||||||
|
{
|
||||||
|
DBG1(DBG_TNC, "insufficient bytes for PA-TNC attribute header");
|
||||||
|
*error = ietf_attr_pa_tnc_error_create_with_offset(error_code,
|
||||||
|
msg_info, *offset);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
reader->read_uint8 (reader, &flags);
|
||||||
|
reader->read_uint24(reader, &vendor_id);
|
||||||
|
reader->read_uint32(reader, &type);
|
||||||
|
reader->read_uint32(reader, &length);
|
||||||
|
|
||||||
|
pa_attr_names = imcv_pa_tnc_attributes->get_names(imcv_pa_tnc_attributes,
|
||||||
|
vendor_id);
|
||||||
|
if (pa_attr_names)
|
||||||
|
{
|
||||||
|
DBG2(DBG_TNC, "processing PA-TNC attribute type '%N/%N' "
|
||||||
|
"0x%06x/0x%08x", pen_names, vendor_id,
|
||||||
|
pa_attr_names, type, vendor_id, type);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBG2(DBG_TNC, "processing PA-TNC attribute type '%N' "
|
||||||
|
"0x%06x/0x%08x", pen_names, vendor_id,
|
||||||
|
vendor_id, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length < PA_TNC_ATTR_HEADER_SIZE)
|
||||||
|
{
|
||||||
|
DBG1(DBG_TNC, "%u bytes too small for PA-TNC attribute length",
|
||||||
|
length);
|
||||||
|
*error = ietf_attr_pa_tnc_error_create_with_offset(error_code,
|
||||||
|
msg_info, *offset + PA_TNC_ATTR_INFO_SIZE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!reader->read_data(reader, length - PA_TNC_ATTR_HEADER_SIZE, &value))
|
||||||
|
{
|
||||||
|
DBG1(DBG_TNC, "insufficient bytes for PA-TNC attribute value");
|
||||||
|
*error = ietf_attr_pa_tnc_error_create_with_offset(error_code,
|
||||||
|
msg_info, *offset + PA_TNC_ATTR_INFO_SIZE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
DBG3(DBG_TNC, "%B", &value);
|
||||||
|
|
||||||
|
if (vendor_id == PEN_RESERVED)
|
||||||
|
{
|
||||||
|
*error = ietf_attr_pa_tnc_error_create_with_offset(error_code,
|
||||||
|
msg_info, *offset + 1);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (type == IETF_ATTR_RESERVED)
|
||||||
|
{
|
||||||
|
*error = ietf_attr_pa_tnc_error_create_with_offset(error_code,
|
||||||
|
msg_info, *offset + 4);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check if the attribute type is registered */
|
||||||
enumerator = this->list->create_enumerator(this->list);
|
enumerator = this->list->create_enumerator(this->list);
|
||||||
while (enumerator->enumerate(enumerator, &entry))
|
while (enumerator->enumerate(enumerator, &entry))
|
||||||
{
|
{
|
||||||
@@ -122,6 +214,39 @@ METHOD(pa_tnc_attr_manager_t, create, pa_tnc_attr_t*,
|
|||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
|
|
||||||
|
if (!attr)
|
||||||
|
{
|
||||||
|
if (!(flags & PA_TNC_ATTR_FLAG_NOSKIP))
|
||||||
|
{
|
||||||
|
DBG1(DBG_TNC, "skipping unsupported PA-TNC attribute");
|
||||||
|
offset += length;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBG1(DBG_TNC, "unsupported PA-TNC attribute with NOSKIP flag");
|
||||||
|
unsupported_type = pen_type_create(vendor_id, type);
|
||||||
|
error_code = pen_type_create(PEN_IETF, PA_ERROR_ATTR_TYPE_NOT_SUPPORTED);
|
||||||
|
*error = ietf_attr_pa_tnc_error_create(error_code, msg_info);
|
||||||
|
error_attr = (ietf_attr_pa_tnc_error_t*)(*error);
|
||||||
|
error_attr->set_unsupported_attr(error_attr, flags, unsupported_type);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (attr->process(attr, &attr_offset) != SUCCESS)
|
||||||
|
{
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2011 Andreas Steffen
|
* Copyright (C) 2011-2014 Andreas Steffen
|
||||||
* HSR Hochschule fuer Technik Rapperswil
|
* HSR Hochschule fuer Technik Rapperswil
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
@@ -26,6 +26,7 @@ typedef struct pa_tnc_attr_manager_t pa_tnc_attr_manager_t;
|
|||||||
#include "pa_tnc_attr.h"
|
#include "pa_tnc_attr.h"
|
||||||
|
|
||||||
#include <library.h>
|
#include <library.h>
|
||||||
|
#include <bio/bio_reader.h>
|
||||||
|
|
||||||
typedef pa_tnc_attr_t* (*pa_tnc_attr_create_t)(u_int32_t type, chunk_t value);
|
typedef pa_tnc_attr_t* (*pa_tnc_attr_create_t)(u_int32_t type, chunk_t value);
|
||||||
|
|
||||||
@@ -61,15 +62,17 @@ struct pa_tnc_attr_manager_t {
|
|||||||
enum_name_t* (*get_names)(pa_tnc_attr_manager_t *this, pen_t vendor_id);
|
enum_name_t* (*get_names)(pa_tnc_attr_manager_t *this, pen_t vendor_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a PA-TNC attribute object from data for a given vendor ID and type
|
* Create and pre-parse a PA-TNC attribute object from data
|
||||||
*
|
*
|
||||||
* @param vendor_id Private Enterprise Number (PEN)
|
* @param reader PA-TNC attribute as encoded data
|
||||||
* @param type PA-TNC attribute type
|
* @param offset Offset in bytes where an error has been found
|
||||||
* @param value PA-TNC attribute value as encoded data
|
* @param msg_info Message info added to an error attribute
|
||||||
|
* @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, pen_t vendor_id,
|
pa_tnc_attr_t* (*create)(pa_tnc_attr_manager_t *this, bio_reader_t *reader,
|
||||||
u_int32_t type, chunk_t value);
|
uint32_t *offset, chunk_t msg_info,
|
||||||
|
pa_tnc_attr_t **error);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroys a pa_tnc_attr_manager_t object.
|
* Destroys a pa_tnc_attr_manager_t object.
|
||||||
|
|||||||
+26
-135
@@ -37,28 +37,6 @@ typedef struct private_pa_tnc_msg_t private_pa_tnc_msg_t;
|
|||||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define PA_TNC_RESERVED 0x000000
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PA-TNC attribute
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
||||||
* | Flags | PA-TNC Attribute Vendor ID |
|
|
||||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
||||||
* | PA-TNC Attribute Type |
|
|
||||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
||||||
* | PA-TNC Attribute Length |
|
|
||||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
||||||
* | Attribute Value (Variable Length) |
|
|
||||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define PA_TNC_ATTR_FLAG_NONE 0x00
|
|
||||||
#define PA_TNC_ATTR_FLAG_NOSKIP (1<<7)
|
|
||||||
#define PA_TNC_ATTR_INFO_SIZE 8
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private data of a pa_tnc_msg_t object.
|
* Private data of a pa_tnc_msg_t object.
|
||||||
*
|
*
|
||||||
@@ -95,6 +73,11 @@ struct private_pa_tnc_msg_t {
|
|||||||
*/
|
*/
|
||||||
size_t max_msg_len;
|
size_t max_msg_len;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TRUE if attribute was extracted from data
|
||||||
|
*/
|
||||||
|
bool from_data;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encoded message
|
* Encoded message
|
||||||
*/
|
*/
|
||||||
@@ -113,17 +96,19 @@ METHOD(pa_tnc_msg_t, add_attribute, bool,
|
|||||||
chunk_t attr_value;
|
chunk_t attr_value;
|
||||||
size_t attr_len;
|
size_t attr_len;
|
||||||
|
|
||||||
attr->build(attr);
|
if (!this->from_data)
|
||||||
attr_value = attr->get_value(attr);
|
|
||||||
attr_len = PA_TNC_ATTR_HEADER_SIZE + attr_value.len;
|
|
||||||
|
|
||||||
if (this->max_msg_len && this->msg_len + attr_len > this->max_msg_len)
|
|
||||||
{
|
{
|
||||||
/* attribute just does not fit into this message */
|
attr->build(attr);
|
||||||
return FALSE;
|
attr_value = attr->get_value(attr);
|
||||||
}
|
attr_len = PA_TNC_ATTR_HEADER_SIZE + attr_value.len;
|
||||||
this->msg_len += attr_len;
|
|
||||||
|
|
||||||
|
if (this->max_msg_len && this->msg_len + attr_len > this->max_msg_len)
|
||||||
|
{
|
||||||
|
/* attribute just does not fit into this message */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
this->msg_len += attr_len;
|
||||||
|
}
|
||||||
this->attributes->insert_last(this->attributes, attr);
|
this->attributes->insert_last(this->attributes, attr);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -201,9 +186,9 @@ METHOD(pa_tnc_msg_t, process, status_t,
|
|||||||
private_pa_tnc_msg_t *this)
|
private_pa_tnc_msg_t *this)
|
||||||
{
|
{
|
||||||
bio_reader_t *reader;
|
bio_reader_t *reader;
|
||||||
pa_tnc_attr_t *error;
|
pa_tnc_attr_t *attr, *error;
|
||||||
uint8_t version;
|
uint8_t version;
|
||||||
uint32_t reserved, offset, attr_offset;
|
uint32_t reserved, 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 */
|
||||||
@@ -231,116 +216,21 @@ METHOD(pa_tnc_msg_t, process, status_t,
|
|||||||
offset = PA_TNC_HEADER_SIZE;
|
offset = PA_TNC_HEADER_SIZE;
|
||||||
|
|
||||||
/* pre-process PA-TNC attributes */
|
/* pre-process PA-TNC attributes */
|
||||||
while (reader->remaining(reader) >= PA_TNC_ATTR_HEADER_SIZE)
|
while (reader->remaining(reader) > 0)
|
||||||
{
|
{
|
||||||
pen_t vendor_id;
|
|
||||||
uint8_t flags;
|
|
||||||
uint32_t type, length;
|
|
||||||
chunk_t value;
|
|
||||||
pa_tnc_attr_t *attr;
|
|
||||||
enum_name_t *pa_attr_names;
|
|
||||||
ietf_attr_pa_tnc_error_t *error_attr;
|
|
||||||
pen_type_t unsupported_type;
|
|
||||||
|
|
||||||
reader->read_uint8 (reader, &flags);
|
|
||||||
reader->read_uint24(reader, &vendor_id);
|
|
||||||
reader->read_uint32(reader, &type);
|
|
||||||
reader->read_uint32(reader, &length);
|
|
||||||
|
|
||||||
pa_attr_names = imcv_pa_tnc_attributes->get_names(imcv_pa_tnc_attributes,
|
|
||||||
vendor_id);
|
|
||||||
if (pa_attr_names)
|
|
||||||
{
|
|
||||||
DBG2(DBG_TNC, "processing PA-TNC attribute type '%N/%N' "
|
|
||||||
"0x%06x/0x%08x", pen_names, vendor_id,
|
|
||||||
pa_attr_names, type, vendor_id, type);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DBG2(DBG_TNC, "processing PA-TNC attribute type '%N' "
|
|
||||||
"0x%06x/0x%08x", pen_names, vendor_id,
|
|
||||||
vendor_id, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (length < PA_TNC_ATTR_HEADER_SIZE)
|
|
||||||
{
|
|
||||||
DBG1(DBG_TNC, "%u bytes too small for PA-TNC attribute length",
|
|
||||||
length);
|
|
||||||
error = ietf_attr_pa_tnc_error_create_with_offset(error_code,
|
|
||||||
this->encoding, offset + PA_TNC_ATTR_INFO_SIZE);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!reader->read_data(reader, length - PA_TNC_ATTR_HEADER_SIZE, &value))
|
|
||||||
{
|
|
||||||
DBG1(DBG_TNC, "insufficient bytes for PA-TNC attribute value");
|
|
||||||
error = ietf_attr_pa_tnc_error_create_with_offset(error_code,
|
|
||||||
this->encoding, offset + PA_TNC_ATTR_INFO_SIZE);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
DBG3(DBG_TNC, "%B", &value);
|
|
||||||
|
|
||||||
if (vendor_id == PEN_RESERVED)
|
|
||||||
{
|
|
||||||
error = ietf_attr_pa_tnc_error_create_with_offset(error_code,
|
|
||||||
this->encoding, offset + 1);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
if (type == IETF_ATTR_RESERVED)
|
|
||||||
{
|
|
||||||
error = ietf_attr_pa_tnc_error_create_with_offset(error_code,
|
|
||||||
this->encoding, offset + 4);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
attr = imcv_pa_tnc_attributes->create(imcv_pa_tnc_attributes,
|
attr = imcv_pa_tnc_attributes->create(imcv_pa_tnc_attributes,
|
||||||
vendor_id, type, value);
|
reader, &offset, this->encoding, &error);
|
||||||
if (!attr)
|
if (error)
|
||||||
{
|
{
|
||||||
if (!(flags & PA_TNC_ATTR_FLAG_NOSKIP))
|
|
||||||
{
|
|
||||||
DBG1(DBG_TNC, "skipping unsupported PA-TNC attribute");
|
|
||||||
offset += length;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG1(DBG_TNC, "unsupported PA-TNC attribute with NOSKIP flag");
|
|
||||||
unsupported_type = pen_type_create(vendor_id, type);
|
|
||||||
error_code = pen_type_create(PEN_IETF,
|
|
||||||
PA_ERROR_ATTR_TYPE_NOT_SUPPORTED);
|
|
||||||
error = ietf_attr_pa_tnc_error_create(error_code, this->encoding);
|
|
||||||
error_attr = (ietf_attr_pa_tnc_error_t*)error;
|
|
||||||
error_attr->set_unsupported_attr(error_attr, flags, unsupported_type);
|
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
if (attr)
|
||||||
if (attr->process(attr, &attr_offset) != SUCCESS)
|
|
||||||
{
|
{
|
||||||
attr->destroy(attr);
|
this->attributes->insert_last(this->attributes, attr);
|
||||||
if (vendor_id == PEN_IETF && type == IETF_ATTR_PA_TNC_ERROR)
|
|
||||||
{
|
|
||||||
/* error while processing a PA-TNC error attribute - abort */
|
|
||||||
reader->destroy(reader);
|
|
||||||
return FAILED;
|
|
||||||
}
|
|
||||||
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 + PA_TNC_ATTR_HEADER_SIZE + attr_offset);
|
|
||||||
goto err;
|
|
||||||
}
|
}
|
||||||
this->attributes->insert_last(this->attributes, attr);
|
|
||||||
offset += length;
|
|
||||||
}
|
}
|
||||||
|
reader->destroy(reader);
|
||||||
if (reader->remaining(reader) == 0)
|
return SUCCESS;
|
||||||
{
|
|
||||||
reader->destroy(reader);
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
DBG1(DBG_TNC, "insufficient bytes for PA-TNC attribute header");
|
|
||||||
error = ietf_attr_pa_tnc_error_create_with_offset(error_code,
|
|
||||||
this->encoding, offset);
|
|
||||||
|
|
||||||
err:
|
err:
|
||||||
reader->destroy(reader);
|
reader->destroy(reader);
|
||||||
@@ -509,6 +399,7 @@ pa_tnc_msg_t *pa_tnc_msg_create_from_data(chunk_t data)
|
|||||||
.encoding = chunk_clone(data),
|
.encoding = chunk_clone(data),
|
||||||
.attributes = linked_list_create(),
|
.attributes = linked_list_create(),
|
||||||
.errors = linked_list_create(),
|
.errors = linked_list_create(),
|
||||||
|
.from_data = TRUE,
|
||||||
);
|
);
|
||||||
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
|
|||||||
@@ -25,6 +25,9 @@ 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"
|
||||||
|
|
||||||
|
|||||||
@@ -14,16 +14,19 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "seg_contract.h"
|
#include "seg_contract.h"
|
||||||
|
#include "seg_env.h"
|
||||||
|
|
||||||
#include <utils/debug.h>
|
#include <utils/debug.h>
|
||||||
|
#include <bio/bio_writer.h>
|
||||||
|
|
||||||
#include <tncif_pa_subtypes.h>
|
#include <tncif_pa_subtypes.h>
|
||||||
|
|
||||||
|
#include <tcg/seg/tcg_seg_attr_seg_env.h>
|
||||||
|
|
||||||
typedef struct private_seg_contract_t private_seg_contract_t;
|
typedef struct private_seg_contract_t private_seg_contract_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private data of a seg_contract_t object.
|
* Private data of a seg_contract_t object.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
struct private_seg_contract_t {
|
struct private_seg_contract_t {
|
||||||
|
|
||||||
@@ -47,6 +50,17 @@ struct private_seg_contract_t {
|
|||||||
*/
|
*/
|
||||||
uint32_t max_seg_size;
|
uint32_t max_seg_size;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum PA-TNC attribute segment size
|
||||||
|
*/
|
||||||
|
uint32_t last_base_attr_id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of attribute segment envelopes
|
||||||
|
*/
|
||||||
|
|
||||||
|
linked_list_t *seg_envs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is this a null contract?
|
* Is this a null contract?
|
||||||
*/
|
*/
|
||||||
@@ -97,6 +111,154 @@ METHOD(seg_contract_t, get_max_size, void,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(seg_contract_t, check_size, bool,
|
||||||
|
private_seg_contract_t *this, pa_tnc_attr_t *attr, bool *oversize)
|
||||||
|
{
|
||||||
|
chunk_t attr_value;
|
||||||
|
size_t attr_len;
|
||||||
|
|
||||||
|
*oversize = FALSE;
|
||||||
|
|
||||||
|
if (this->is_null)
|
||||||
|
{
|
||||||
|
/* null segmentation contract */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
attr->build(attr);
|
||||||
|
attr_value = attr->get_value(attr);
|
||||||
|
attr_len = PA_TNC_ATTR_HEADER_SIZE + attr_value.len;
|
||||||
|
|
||||||
|
if (attr_len > this->max_attr_size)
|
||||||
|
{
|
||||||
|
/* oversize attribute */
|
||||||
|
*oversize = TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (this->max_seg_size == SEG_CONTRACT_NO_FRAGMENTATION)
|
||||||
|
{
|
||||||
|
/* no fragmentation wanted */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return attr_value.len > this->max_seg_size + TCG_SEG_ATTR_SEG_ENV_HEADER;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(seg_contract_t, first_segment, pa_tnc_attr_t*,
|
||||||
|
private_seg_contract_t *this, pa_tnc_attr_t *attr)
|
||||||
|
{
|
||||||
|
seg_env_t *seg_env;
|
||||||
|
|
||||||
|
seg_env = seg_env_create(++this->last_base_attr_id, attr,
|
||||||
|
this->max_seg_size);
|
||||||
|
if (!seg_env)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
this->seg_envs->insert_last(this->seg_envs, seg_env);
|
||||||
|
|
||||||
|
return seg_env->first_segment(seg_env);
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(seg_contract_t, next_segment, pa_tnc_attr_t*,
|
||||||
|
private_seg_contract_t *this, uint32_t base_attr_id)
|
||||||
|
{
|
||||||
|
pa_tnc_attr_t *seg_env_attr = NULL;
|
||||||
|
seg_env_t *seg_env;
|
||||||
|
bool last_segment = FALSE;
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
|
||||||
|
enumerator = this->seg_envs->create_enumerator(this->seg_envs);
|
||||||
|
while (enumerator->enumerate(enumerator, &seg_env))
|
||||||
|
{
|
||||||
|
if (seg_env->get_base_attr_id(seg_env) == base_attr_id)
|
||||||
|
{
|
||||||
|
seg_env_attr = seg_env->next_segment(seg_env, &last_segment);
|
||||||
|
if (!seg_env_attr)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (last_segment)
|
||||||
|
{
|
||||||
|
this->seg_envs->remove_at(this->seg_envs, enumerator);
|
||||||
|
seg_env->destroy(seg_env);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
|
||||||
|
return seg_env_attr;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(seg_contract_t, add_segment, pa_tnc_attr_t*,
|
||||||
|
private_seg_contract_t *this, pa_tnc_attr_t *attr, pa_tnc_attr_t **error,
|
||||||
|
bool *more)
|
||||||
|
{
|
||||||
|
tcg_seg_attr_seg_env_t *seg_env_attr;
|
||||||
|
seg_env_t *current, *seg_env = NULL;
|
||||||
|
pa_tnc_attr_t *base_attr;
|
||||||
|
uint32_t base_attr_id;
|
||||||
|
uint8_t flags;
|
||||||
|
chunk_t segment_data;
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
|
||||||
|
seg_env_attr = (tcg_seg_attr_seg_env_t*)attr;
|
||||||
|
base_attr_id = seg_env_attr->get_base_attr_id(seg_env_attr);
|
||||||
|
segment_data = seg_env_attr->get_segment(seg_env_attr, &flags);
|
||||||
|
*more = flags & SEG_ENV_FLAG_MORE;
|
||||||
|
*error = NULL;
|
||||||
|
|
||||||
|
enumerator = this->seg_envs->create_enumerator(this->seg_envs);
|
||||||
|
while (enumerator->enumerate(enumerator, ¤t))
|
||||||
|
{
|
||||||
|
if (current->get_base_attr_id(current) == base_attr_id)
|
||||||
|
{
|
||||||
|
seg_env = current;
|
||||||
|
if (!(*more))
|
||||||
|
{
|
||||||
|
this->seg_envs->remove_at(this->seg_envs, enumerator);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
|
||||||
|
if (flags & SEG_ENV_FLAG_START)
|
||||||
|
{
|
||||||
|
if (seg_env)
|
||||||
|
{
|
||||||
|
DBG1(DBG_TNC, "base attribute ID %d is already in use",
|
||||||
|
base_attr_id);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
DBG2(DBG_TNC, "received first segment for base attribute ID %d "
|
||||||
|
"(%d bytes)", base_attr_id, segment_data.len);
|
||||||
|
seg_env = seg_env_create_from_data(base_attr_id, segment_data,
|
||||||
|
this->max_seg_size);
|
||||||
|
this->seg_envs->insert_last(this->seg_envs, seg_env);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!seg_env)
|
||||||
|
{
|
||||||
|
DBG1(DBG_TNC, "base attribute ID %d not found", base_attr_id);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
DBG2(DBG_TNC, "received %s segment for base attribute ID %d "
|
||||||
|
"(%d bytes)", (*more) ? "next" : "last", base_attr_id,
|
||||||
|
segment_data.len);
|
||||||
|
seg_env->add_segment(seg_env, segment_data);
|
||||||
|
}
|
||||||
|
if (*more)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
base_attr = seg_env->get_base_attr(seg_env, error);
|
||||||
|
seg_env->destroy(seg_env);
|
||||||
|
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
@@ -206,6 +368,7 @@ METHOD(seg_contract_t, get_info_string, void,
|
|||||||
METHOD(seg_contract_t, destroy, void,
|
METHOD(seg_contract_t, destroy, void,
|
||||||
private_seg_contract_t *this)
|
private_seg_contract_t *this)
|
||||||
{
|
{
|
||||||
|
this->seg_envs->destroy_offset(this->seg_envs, offsetof(seg_env_t, destroy));
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,6 +388,10 @@ seg_contract_t *seg_contract_create(pen_type_t msg_type,
|
|||||||
.get_msg_type = _get_msg_type,
|
.get_msg_type = _get_msg_type,
|
||||||
.set_max_size = _set_max_size,
|
.set_max_size = _set_max_size,
|
||||||
.get_max_size = _get_max_size,
|
.get_max_size = _get_max_size,
|
||||||
|
.check_size = _check_size,
|
||||||
|
.first_segment = _first_segment,
|
||||||
|
.next_segment = _next_segment,
|
||||||
|
.add_segment = _add_segment,
|
||||||
.is_issuer = _is_issuer,
|
.is_issuer = _is_issuer,
|
||||||
.is_null = _is_null,
|
.is_null = _is_null,
|
||||||
.get_info_string = _get_info_string,
|
.get_info_string = _get_info_string,
|
||||||
@@ -233,6 +400,7 @@ seg_contract_t *seg_contract_create(pen_type_t msg_type,
|
|||||||
.msg_type = msg_type,
|
.msg_type = msg_type,
|
||||||
.max_attr_size = max_attr_size,
|
.max_attr_size = max_attr_size,
|
||||||
.max_seg_size = max_seg_size,
|
.max_seg_size = max_seg_size,
|
||||||
|
.seg_envs = linked_list_create(),
|
||||||
.is_issuer = is_issuer,
|
.is_issuer = is_issuer,
|
||||||
.issuer_id = issuer_id,
|
.issuer_id = issuer_id,
|
||||||
.is_imc = is_imc,
|
.is_imc = is_imc,
|
||||||
@@ -23,6 +23,8 @@
|
|||||||
|
|
||||||
typedef struct seg_contract_t seg_contract_t;
|
typedef struct seg_contract_t seg_contract_t;
|
||||||
|
|
||||||
|
#include "pa_tnc/pa_tnc_attr.h"
|
||||||
|
|
||||||
#include <library.h>
|
#include <library.h>
|
||||||
#include <pen/pen.h>
|
#include <pen/pen.h>
|
||||||
|
|
||||||
@@ -47,8 +49,8 @@ struct seg_contract_t {
|
|||||||
/**
|
/**
|
||||||
* Set maximum PA-TNC attribute and segment size in octets
|
* Set maximum PA-TNC attribute and segment size in octets
|
||||||
*
|
*
|
||||||
* @param max_attr_size Maximum PA-TNC attribute size in octets
|
* @param max_attr_size Maximum PA-TNC attribute size in octets
|
||||||
* @param max_seg_size Maximum PA-TNC attribute segment size in octets
|
* @param max_seg_size Maximum PA-TNC attribute segment size in octets
|
||||||
*/
|
*/
|
||||||
void (*set_max_size)(seg_contract_t *this, uint32_t max_attr_size,
|
void (*set_max_size)(seg_contract_t *this, uint32_t max_attr_size,
|
||||||
uint32_t max_seg_size);
|
uint32_t max_seg_size);
|
||||||
@@ -56,33 +58,71 @@ struct seg_contract_t {
|
|||||||
/**
|
/**
|
||||||
* Get maximum PA-TNC attribute and segment size in octets
|
* Get maximum PA-TNC attribute and segment size in octets
|
||||||
*
|
*
|
||||||
* @param max_attr_size Maximum PA-TNC attribute size in octets
|
* @param max_attr_size Maximum PA-TNC attribute size in octets
|
||||||
* @param max_seg_size Maximum PA-TNC attribute segment size in octets
|
* @param max_seg_size Maximum PA-TNC attribute segment size in octets
|
||||||
*/
|
*/
|
||||||
void (*get_max_size)(seg_contract_t *this, uint32_t *max_attr_size,
|
void (*get_max_size)(seg_contract_t *this, uint32_t *max_attr_size,
|
||||||
uint32_t *max_seg_size);
|
uint32_t *max_seg_size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a PA-TNC attribute must be segmented or is oversized
|
||||||
|
*
|
||||||
|
* @param attr PA-TNC attribute to be checked
|
||||||
|
* @param oversize PA-TNC attribute is larger than maximum size
|
||||||
|
* @return TRUE if PA-TNC attribute must be segmented
|
||||||
|
*/
|
||||||
|
bool (*check_size)(seg_contract_t *this, pa_tnc_attr_t *attr,
|
||||||
|
bool *oversize);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate first segment of a PA-TNC attribute according to the contract
|
||||||
|
*
|
||||||
|
* @param attr PA-TNC attribute to be segmented
|
||||||
|
* @return First segment envelope attribute
|
||||||
|
*/
|
||||||
|
pa_tnc_attr_t* (*first_segment)(seg_contract_t *this, pa_tnc_attr_t *attr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate next segment of a PA-TNC attribute according to the contract
|
||||||
|
*
|
||||||
|
* @param base_attr_id Base Attribute ID
|
||||||
|
* @return Next segment envelope attribute
|
||||||
|
*/
|
||||||
|
pa_tnc_attr_t* (*next_segment)(seg_contract_t *this, uint32_t base_attr_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an attribute segments until the PA-TNC attribute is reconstructed
|
||||||
|
*
|
||||||
|
* @param attr Segment envelope attribute
|
||||||
|
* @param error Error attribute if an error occurred or NULL
|
||||||
|
* @param more Need more segments
|
||||||
|
* @return Completed PA-TNC attribute or NULL
|
||||||
|
*/
|
||||||
|
pa_tnc_attr_t* (*add_segment)(seg_contract_t *this,
|
||||||
|
pa_tnc_attr_t *attr, pa_tnc_attr_t **error,
|
||||||
|
bool *more);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get contract role
|
* Get contract role
|
||||||
*
|
*
|
||||||
* @return TRUE: contracting party (issuer),
|
* @return TRUE: contracting party (issuer),
|
||||||
* FALSE: contracted party
|
* FALSE: contracted party
|
||||||
*/
|
*/
|
||||||
bool (*is_issuer)(seg_contract_t *this);
|
bool (*is_issuer)(seg_contract_t *this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is this a null contract ?
|
* Is this a null contract ?
|
||||||
*
|
*
|
||||||
* @return TRUE if null contract
|
* @return TRUE if null contract
|
||||||
*/
|
*/
|
||||||
bool (*is_null)(seg_contract_t *this);
|
bool (*is_null)(seg_contract_t *this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an info string about the contract
|
* Get an info string about the contract
|
||||||
*
|
*
|
||||||
* @param buf String buffer of at least size len
|
* @param buf String buffer of at least size len
|
||||||
* @param len Size of string buffer
|
* @param len Size of string buffer
|
||||||
* @param request TRUE if contract request, FALSE if response
|
* @param request TRUE if contract request, FALSE if response
|
||||||
*/
|
*/
|
||||||
void (*get_info_string)(seg_contract_t *this, char *buf, size_t len,
|
void (*get_info_string)(seg_contract_t *this, char *buf, size_t len,
|
||||||
bool request);
|
bool request);
|
||||||
@@ -96,7 +136,7 @@ struct seg_contract_t {
|
|||||||
/**
|
/**
|
||||||
* Create a PA-TNC attribute segmentation contract
|
* Create a PA-TNC attribute segmentation contract
|
||||||
*
|
*
|
||||||
* @param msg_type PA-TNC message type
|
* @param msg_type PA-TNC message type
|
||||||
* @param max_attr_size Maximum PA-TNC attribute size in octets
|
* @param max_attr_size Maximum PA-TNC attribute size in octets
|
||||||
* @param max_seg_size Maximum PA-TNC attribute segment size in octets
|
* @param max_seg_size Maximum PA-TNC attribute segment size in octets
|
||||||
* @param is_issuer TRUE if issuer of the contract
|
* @param is_issuer TRUE if issuer of the contract
|
||||||
@@ -0,0 +1,261 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 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 "seg_env.h"
|
||||||
|
|
||||||
|
#include "imcv.h"
|
||||||
|
#include "pa_tnc/pa_tnc_msg.h"
|
||||||
|
|
||||||
|
#include <utils/debug.h>
|
||||||
|
#include <bio/bio_reader.h>
|
||||||
|
#include <bio/bio_writer.h>
|
||||||
|
|
||||||
|
#include <tcg/seg/tcg_seg_attr_seg_env.h>
|
||||||
|
|
||||||
|
#define BASE_ATTR_ID_PREFIX 0xFF
|
||||||
|
|
||||||
|
typedef struct private_seg_env_t private_seg_env_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private data of a seg_env_t object.
|
||||||
|
*/
|
||||||
|
struct private_seg_env_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public seg_env_t interface.
|
||||||
|
*/
|
||||||
|
seg_env_t public;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base Attribute ID
|
||||||
|
*/
|
||||||
|
uint32_t base_attr_id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base Attribute
|
||||||
|
*/
|
||||||
|
pa_tnc_attr_t *base_attr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum PA-TNC attribute segment 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,
|
||||||
|
private_seg_env_t *this)
|
||||||
|
{
|
||||||
|
return this->base_attr_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(seg_env_t, get_base_attr, pa_tnc_attr_t*,
|
||||||
|
private_seg_env_t *this, pa_tnc_attr_t** error)
|
||||||
|
{
|
||||||
|
*error = NULL;
|
||||||
|
|
||||||
|
if (!this->base_attr)
|
||||||
|
{
|
||||||
|
bio_writer_t *writer;
|
||||||
|
bio_reader_t *reader;
|
||||||
|
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*,
|
||||||
|
private_seg_env_t *this)
|
||||||
|
{
|
||||||
|
pa_tnc_attr_t *seg_env_attr;
|
||||||
|
bio_writer_t *writer;
|
||||||
|
pen_type_t type;
|
||||||
|
chunk_t segment_data, value;
|
||||||
|
uint8_t flags, seg_env_flags;
|
||||||
|
|
||||||
|
/* get components of base attribute header and data */
|
||||||
|
flags = this->base_attr->get_noskip_flag(this->base_attr) ?
|
||||||
|
PA_TNC_ATTR_FLAG_NOSKIP : PA_TNC_ATTR_FLAG_NONE;
|
||||||
|
type = this->base_attr->get_type(this->base_attr);
|
||||||
|
|
||||||
|
/* attribute data going into the first segment */
|
||||||
|
segment_data = this->data;
|
||||||
|
segment_data.len = this->max_seg_size - PA_TNC_ATTR_HEADER_SIZE;
|
||||||
|
|
||||||
|
/* build encoding of the base attribute header and first segment data */
|
||||||
|
writer = bio_writer_create(this->max_seg_size);
|
||||||
|
writer->write_uint8 (writer, flags);
|
||||||
|
writer->write_uint24(writer, type.vendor_id);
|
||||||
|
writer->write_uint32(writer, type.type);
|
||||||
|
writer->write_uint32(writer, PA_TNC_ATTR_HEADER_SIZE + this->data.len);
|
||||||
|
writer->write_data (writer, segment_data);
|
||||||
|
value = writer->extract_buf(writer);
|
||||||
|
writer->destroy(writer);
|
||||||
|
this->data = chunk_skip(this->data, segment_data.len);
|
||||||
|
|
||||||
|
DBG2(DBG_TNC, "creating first segment for base attribute ID %d (%d bytes)",
|
||||||
|
this->base_attr_id, this->max_seg_size);
|
||||||
|
|
||||||
|
seg_env_flags = SEG_ENV_FLAG_START | SEG_ENV_FLAG_MORE;
|
||||||
|
seg_env_attr = tcg_seg_attr_seg_env_create(value, seg_env_flags,
|
||||||
|
this->base_attr_id);
|
||||||
|
chunk_free(&value);
|
||||||
|
|
||||||
|
return seg_env_attr;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(seg_env_t, next_segment, pa_tnc_attr_t*,
|
||||||
|
private_seg_env_t *this, bool *last)
|
||||||
|
{
|
||||||
|
pa_tnc_attr_t *seg_env_attr;
|
||||||
|
chunk_t segment_data;
|
||||||
|
uint8_t seg_env_flags;
|
||||||
|
bool is_last_segment;
|
||||||
|
|
||||||
|
if (this->data.len == 0)
|
||||||
|
{
|
||||||
|
/* no more attribute data to segment available */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* attribute data going into the next segment */
|
||||||
|
segment_data = this->data;
|
||||||
|
segment_data.len = min(this->max_seg_size, this->data.len);
|
||||||
|
this->data = chunk_skip(this->data, segment_data.len);
|
||||||
|
|
||||||
|
is_last_segment = (this->data.len == 0);
|
||||||
|
if (last)
|
||||||
|
{
|
||||||
|
*last = is_last_segment;
|
||||||
|
}
|
||||||
|
DBG2(DBG_TNC, "creating %s segment for base attribute ID %d (%d bytes)",
|
||||||
|
is_last_segment ? "last" : "next", this->base_attr_id,
|
||||||
|
segment_data.len);
|
||||||
|
|
||||||
|
seg_env_flags = is_last_segment ? SEG_ENV_FLAG_NONE : SEG_ENV_FLAG_MORE;
|
||||||
|
seg_env_attr = tcg_seg_attr_seg_env_create(segment_data, seg_env_flags,
|
||||||
|
this->base_attr_id);
|
||||||
|
|
||||||
|
return seg_env_attr;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(seg_env_t, add_segment, void,
|
||||||
|
private_seg_env_t *this, chunk_t segment_data)
|
||||||
|
{
|
||||||
|
this->data = chunk_cat("mc", this->data, segment_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(seg_env_t, destroy, void,
|
||||||
|
private_seg_env_t *this)
|
||||||
|
{
|
||||||
|
if (this->from_data)
|
||||||
|
{
|
||||||
|
chunk_free(&this->data);
|
||||||
|
}
|
||||||
|
DESTROY_IF(this->base_attr);
|
||||||
|
free(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See header
|
||||||
|
*/
|
||||||
|
seg_env_t *seg_env_create(uint32_t base_attr_id, pa_tnc_attr_t *base_attr,
|
||||||
|
uint32_t max_seg_size)
|
||||||
|
{
|
||||||
|
private_seg_env_t *this;
|
||||||
|
chunk_t value;
|
||||||
|
|
||||||
|
base_attr->build(base_attr);
|
||||||
|
value = base_attr->get_value(base_attr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The PA-TNC attribute header must not be segmented and
|
||||||
|
* there must be at least a first and one next segment
|
||||||
|
*/
|
||||||
|
if (max_seg_size < PA_TNC_ATTR_HEADER_SIZE ||
|
||||||
|
max_seg_size >= PA_TNC_ATTR_HEADER_SIZE + value.len)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
INIT(this,
|
||||||
|
.public = {
|
||||||
|
.get_base_attr_id = _get_base_attr_id,
|
||||||
|
.get_base_attr = _get_base_attr,
|
||||||
|
.first_segment = _first_segment,
|
||||||
|
.next_segment = _next_segment,
|
||||||
|
.add_segment = _add_segment,
|
||||||
|
.destroy = _destroy,
|
||||||
|
},
|
||||||
|
.base_attr_id = base_attr_id,
|
||||||
|
.base_attr = base_attr->get_ref(base_attr),
|
||||||
|
.max_seg_size = max_seg_size,
|
||||||
|
.data = base_attr->get_value(base_attr),
|
||||||
|
);
|
||||||
|
|
||||||
|
return &this->public;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See header
|
||||||
|
*/
|
||||||
|
seg_env_t *seg_env_create_from_data(uint32_t base_attr_id, chunk_t data,
|
||||||
|
uint32_t max_seg_size)
|
||||||
|
{
|
||||||
|
private_seg_env_t *this;
|
||||||
|
|
||||||
|
INIT(this,
|
||||||
|
.public = {
|
||||||
|
.get_base_attr_id = _get_base_attr_id,
|
||||||
|
.get_base_attr = _get_base_attr,
|
||||||
|
.first_segment = _first_segment,
|
||||||
|
.next_segment = _next_segment,
|
||||||
|
.add_segment = _add_segment,
|
||||||
|
.destroy = _destroy,
|
||||||
|
},
|
||||||
|
.base_attr_id = base_attr_id,
|
||||||
|
.max_seg_size = max_seg_size,
|
||||||
|
.data = chunk_clone(data),
|
||||||
|
.from_data = TRUE,
|
||||||
|
);
|
||||||
|
|
||||||
|
return &this->public;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 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 seg_env seg_env
|
||||||
|
* @{ @ingroup libimcv
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SEG_ENV_H_
|
||||||
|
#define SEG_ENV_H_
|
||||||
|
|
||||||
|
typedef struct seg_env_t seg_env_t;
|
||||||
|
typedef enum seg_env_flags_t seg_env_flags_t;
|
||||||
|
|
||||||
|
#include <library.h>
|
||||||
|
|
||||||
|
#include <pa_tnc/pa_tnc_attr.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Segment Envelope flags
|
||||||
|
*/
|
||||||
|
enum seg_env_flags_t {
|
||||||
|
SEG_ENV_FLAG_NONE = 0,
|
||||||
|
SEG_ENV_FLAG_MORE = (1<<7),
|
||||||
|
SEG_ENV_FLAG_START = (1<<6)
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for a PA-TNC attribute segment envelope object
|
||||||
|
*/
|
||||||
|
struct seg_env_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Base Attribute ID
|
||||||
|
*
|
||||||
|
* @return Base Attribute ID
|
||||||
|
*/
|
||||||
|
uint32_t (*get_base_attr_id)(seg_env_t *this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Base Attribute
|
||||||
|
*
|
||||||
|
* @param error Error attribute if an error occurred 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);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate the first segment envelope of the base attribute
|
||||||
|
*
|
||||||
|
* @return First attribute segment envelope
|
||||||
|
*/
|
||||||
|
pa_tnc_attr_t* (*first_segment)(seg_env_t *this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate the next segment envelope of the base attribute
|
||||||
|
*
|
||||||
|
* @param last TRUE if last segment
|
||||||
|
* @return Next attribute segment envelope
|
||||||
|
*/
|
||||||
|
pa_tnc_attr_t* (*next_segment)(seg_env_t *this, bool *last);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate the first segment envelope of the base attribute
|
||||||
|
*
|
||||||
|
* @param segment Attribute segment to be added
|
||||||
|
*/
|
||||||
|
void (*add_segment)(seg_env_t *this, chunk_t segment);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys a seg_env_t object.
|
||||||
|
*/
|
||||||
|
void (*destroy)(seg_env_t *this);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a PA-TNC attribute segment envelope object
|
||||||
|
*
|
||||||
|
* @param base_attr_id Base Attribute ID
|
||||||
|
* @param base_attr Base Attribute to be segmented
|
||||||
|
* @param max_seg_size Maximum segment size
|
||||||
|
*/
|
||||||
|
seg_env_t* seg_env_create(uint32_t base_attr_id, pa_tnc_attr_t *base_attr,
|
||||||
|
uint32_t max_seg_size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a PA-TNC attribute segment envelope object
|
||||||
|
*
|
||||||
|
* @param base_attr_id Base Attribute ID
|
||||||
|
* @param data First attribute segment
|
||||||
|
* @param max_seg_size Maximum segment size
|
||||||
|
*/
|
||||||
|
seg_env_t* seg_env_create_from_data(uint32_t base_attr_id, chunk_t data,
|
||||||
|
uint32_t max_seg_size);
|
||||||
|
|
||||||
|
#endif /** SEG_ENV_H_ @}*/
|
||||||
@@ -70,7 +70,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_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/pts/tcg_pts_attr_unix_file_meta.h tcg/pts/tcg_pts_attr_unix_file_meta.c \
|
||||||
tcg/seg/tcg_seg_attr_max_size.h tcg/seg/tcg_seg_attr_max_size.c \
|
tcg/seg/tcg_seg_attr_max_size.h tcg/seg/tcg_seg_attr_max_size.c \
|
||||||
tcg/seg/tcg_seg_attr_seg_env.h \
|
tcg/seg/tcg_seg_attr_seg_env.h tcg/seg/tcg_seg_attr_seg_env.c \
|
||||||
|
tcg/seg/tcg_seg_attr_next_seg.h tcg/seg/tcg_seg_attr_next_seg.c \
|
||||||
tcg/swid/tcg_swid_attr_req.h tcg/swid/tcg_swid_attr_req.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
|
tcg/swid/tcg_swid_attr_tag_inv.h tcg/swid/tcg_swid_attr_tag_inv.c
|
||||||
|
|||||||
@@ -241,43 +241,15 @@ static bool add_swid_inventory(imc_state_t *state, imc_msg_t *msg,
|
|||||||
{
|
{
|
||||||
tcg_swid_attr_tag_id_inv_t *swid_id_attr;
|
tcg_swid_attr_tag_id_inv_t *swid_id_attr;
|
||||||
swid_tag_id_t *tag_id;
|
swid_tag_id_t *tag_id;
|
||||||
chunk_t tag_creator, unique_sw_id, instance_id;
|
|
||||||
|
|
||||||
/* At least one TCG Tag ID Inventory attribute is sent */
|
/* Send a TCG Tag ID Inventory attribute */
|
||||||
attr_size = PA_TNC_ATTR_HEADER_SIZE + TCG_SWID_TAG_ID_INV_MIN_SIZE;
|
|
||||||
attr = tcg_swid_attr_tag_id_inv_create(request_id, eid_epoch, 1);
|
attr = tcg_swid_attr_tag_id_inv_create(request_id, eid_epoch, 1);
|
||||||
swid_id_attr = (tcg_swid_attr_tag_id_inv_t*)attr;
|
swid_id_attr = (tcg_swid_attr_tag_id_inv_t*)attr;
|
||||||
|
|
||||||
enumerator = swid_inventory->create_enumerator(swid_inventory);
|
enumerator = swid_inventory->create_enumerator(swid_inventory);
|
||||||
while (enumerator->enumerate(enumerator, &tag_id))
|
while (enumerator->enumerate(enumerator, &tag_id))
|
||||||
{
|
{
|
||||||
tag_creator = tag_id->get_tag_creator(tag_id);
|
|
||||||
unique_sw_id = tag_id->get_unique_sw_id(tag_id, &instance_id);
|
|
||||||
entry_size = 2 + tag_creator.len + 2 + unique_sw_id.len +
|
|
||||||
2 + instance_id.len;
|
|
||||||
|
|
||||||
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 ID 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 ID Inventory attribute */
|
|
||||||
attr_size = PA_TNC_ATTR_HEADER_SIZE +
|
|
||||||
TCG_SWID_TAG_ID_INV_MIN_SIZE;
|
|
||||||
attr = tcg_swid_attr_tag_id_inv_create(request_id, eid_epoch, 1);
|
|
||||||
}
|
|
||||||
swid_id_attr = (tcg_swid_attr_tag_id_inv_t*)attr;
|
|
||||||
swid_id_attr->add(swid_id_attr, tag_id->get_ref(tag_id));
|
swid_id_attr->add(swid_id_attr, tag_id->get_ref(tag_id));
|
||||||
attr_size += entry_size;
|
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
p="Ubuntu 14.04 x86_64"
|
p="Ubuntu 14.04 x86_64"
|
||||||
a="x86_64-linux-gnu"
|
a="x86_64-linux-gnu"
|
||||||
k="3.13.0-32-generic"
|
k="3.13.0-34-generic"
|
||||||
|
|
||||||
for hash in sha1 sha256
|
for hash in sha1 sha256
|
||||||
do
|
do
|
||||||
|
|||||||
@@ -0,0 +1,235 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 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_seg_attr_next_seg.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_seg_attr_next_seg_t private_tcg_seg_attr_next_seg_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
NEXT_SEG_FLAG_NONE = 0,
|
||||||
|
NEXT_SEG_FLAG_CANCEL = 1
|
||||||
|
} next_seg_flags_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Next Segment
|
||||||
|
* see TCG IF-M Segmentation Specification
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
* |C| Reserved | Base Attribute ID |
|
||||||
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private data of an tcg_seg_attr_next_seg_t object.
|
||||||
|
*/
|
||||||
|
struct private_tcg_seg_attr_next_seg_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public members of tcg_seg_attr_next_seg_t
|
||||||
|
*/
|
||||||
|
tcg_seg_attr_next_seg_t public;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vendor-specific attribute type
|
||||||
|
*/
|
||||||
|
pen_type_t type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute value
|
||||||
|
*/
|
||||||
|
chunk_t value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Noskip flag
|
||||||
|
*/
|
||||||
|
bool noskip_flag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancel flag
|
||||||
|
*/
|
||||||
|
bool cancel_flag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base Attribute ID
|
||||||
|
*/
|
||||||
|
uint32_t base_attr_id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reference count
|
||||||
|
*/
|
||||||
|
refcount_t ref;
|
||||||
|
};
|
||||||
|
|
||||||
|
METHOD(pa_tnc_attr_t, get_type, pen_type_t,
|
||||||
|
private_tcg_seg_attr_next_seg_t *this)
|
||||||
|
{
|
||||||
|
return this->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(pa_tnc_attr_t, get_value, chunk_t,
|
||||||
|
private_tcg_seg_attr_next_seg_t *this)
|
||||||
|
{
|
||||||
|
return this->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
|
||||||
|
private_tcg_seg_attr_next_seg_t *this)
|
||||||
|
{
|
||||||
|
return this->noskip_flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(pa_tnc_attr_t, set_noskip_flag,void,
|
||||||
|
private_tcg_seg_attr_next_seg_t *this, bool noskip)
|
||||||
|
{
|
||||||
|
this->noskip_flag = noskip;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(pa_tnc_attr_t, build, void,
|
||||||
|
private_tcg_seg_attr_next_seg_t *this)
|
||||||
|
{
|
||||||
|
bio_writer_t *writer;
|
||||||
|
|
||||||
|
if (this->value.ptr)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
writer = bio_writer_create(TCG_SEG_ATTR_NEXT_SEG_SIZE);
|
||||||
|
writer->write_uint8 (writer, this->cancel_flag ? NEXT_SEG_FLAG_CANCEL :
|
||||||
|
NEXT_SEG_FLAG_NONE);
|
||||||
|
writer->write_uint24(writer, this->base_attr_id);
|
||||||
|
|
||||||
|
this->value = writer->extract_buf(writer);
|
||||||
|
writer->destroy(writer);
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(pa_tnc_attr_t, process, status_t,
|
||||||
|
private_tcg_seg_attr_next_seg_t *this, u_int32_t *offset)
|
||||||
|
{
|
||||||
|
bio_reader_t *reader;
|
||||||
|
uint8_t flags;
|
||||||
|
|
||||||
|
if (this->value.len < TCG_SEG_ATTR_NEXT_SEG_SIZE)
|
||||||
|
{
|
||||||
|
DBG1(DBG_TNC, "insufficient data for %N", tcg_attr_names,
|
||||||
|
this->type.type);
|
||||||
|
*offset = 0;
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
reader = bio_reader_create(this->value);
|
||||||
|
reader->read_uint8 (reader, &flags);
|
||||||
|
reader->read_uint24(reader, &this->base_attr_id);
|
||||||
|
reader->destroy(reader);
|
||||||
|
|
||||||
|
this->cancel_flag = (flags & NEXT_SEG_FLAG_CANCEL);
|
||||||
|
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(pa_tnc_attr_t, destroy, void,
|
||||||
|
private_tcg_seg_attr_next_seg_t *this)
|
||||||
|
{
|
||||||
|
if (ref_put(&this->ref))
|
||||||
|
{
|
||||||
|
free(this->value.ptr);
|
||||||
|
free(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
|
||||||
|
private_tcg_seg_attr_next_seg_t *this)
|
||||||
|
{
|
||||||
|
ref_get(&this->ref);
|
||||||
|
return &this->public.pa_tnc_attribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(tcg_seg_attr_next_seg_t, get_base_attr_id, uint32_t,
|
||||||
|
private_tcg_seg_attr_next_seg_t *this)
|
||||||
|
{
|
||||||
|
return this->base_attr_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(tcg_seg_attr_next_seg_t, get_cancel_flag, bool,
|
||||||
|
private_tcg_seg_attr_next_seg_t *this)
|
||||||
|
{
|
||||||
|
return this->cancel_flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Described in header.
|
||||||
|
*/
|
||||||
|
pa_tnc_attr_t* tcg_seg_attr_next_seg_create(uint32_t base_attr_id, bool cancel)
|
||||||
|
{
|
||||||
|
private_tcg_seg_attr_next_seg_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_base_attr_id = _get_base_attr_id,
|
||||||
|
.get_cancel_flag = _get_cancel_flag,
|
||||||
|
},
|
||||||
|
.type = { PEN_TCG, TCG_SEG_NEXT_SEG_REQ },
|
||||||
|
.base_attr_id = base_attr_id,
|
||||||
|
.cancel_flag = cancel,
|
||||||
|
.ref = 1,
|
||||||
|
);
|
||||||
|
|
||||||
|
return &this->public.pa_tnc_attribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Described in header.
|
||||||
|
*/
|
||||||
|
pa_tnc_attr_t *tcg_seg_attr_next_seg_create_from_data(chunk_t data)
|
||||||
|
{
|
||||||
|
private_tcg_seg_attr_next_seg_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_base_attr_id = _get_base_attr_id,
|
||||||
|
.get_cancel_flag = _get_cancel_flag,
|
||||||
|
},
|
||||||
|
.type = { PEN_TCG, TCG_SEG_NEXT_SEG_REQ },
|
||||||
|
.value = chunk_clone(data),
|
||||||
|
.ref = 1,
|
||||||
|
);
|
||||||
|
|
||||||
|
return &this->public.pa_tnc_attribute;
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 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_seg_attr_next_seg tcg_seg_attr_next_seg
|
||||||
|
* @{ @ingroup tcg_attr
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TCG_SEG_ATTR_NEXT_SEG_H_
|
||||||
|
#define TCG_SEG_ATTR_NEXT_SEG_H_
|
||||||
|
|
||||||
|
typedef struct tcg_seg_attr_next_seg_t tcg_seg_attr_next_seg_t;
|
||||||
|
|
||||||
|
#include "tcg/tcg_attr.h"
|
||||||
|
|
||||||
|
#define TCG_SEG_ATTR_NEXT_SEG_SIZE 4
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class implementing the TCG Segmentation Next Segment Attribute
|
||||||
|
*/
|
||||||
|
struct tcg_seg_attr_next_seg_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public PA-TNC attribute interface
|
||||||
|
*/
|
||||||
|
pa_tnc_attr_t pa_tnc_attribute;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Base Attribute ID
|
||||||
|
*
|
||||||
|
* @return Base Attribute ID
|
||||||
|
*/
|
||||||
|
uint32_t (*get_base_attr_id)(tcg_seg_attr_next_seg_t *this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Cancel flag
|
||||||
|
*
|
||||||
|
* @return Cancel flag
|
||||||
|
*/
|
||||||
|
bool (*get_cancel_flag)(tcg_seg_attr_next_seg_t *this);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an tcg_seg_attr_next_seg_t object
|
||||||
|
*
|
||||||
|
* @param base_attr_id Base Attribute ID
|
||||||
|
* @param cancel If TRUE set Cancel flag
|
||||||
|
*/
|
||||||
|
pa_tnc_attr_t* tcg_seg_attr_next_seg_create(uint32_t base_attr_id, bool cancel);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an tcg_seg_attr_next_seg_t object from received data
|
||||||
|
*
|
||||||
|
* @param value unparsed attribute value
|
||||||
|
*/
|
||||||
|
pa_tnc_attr_t* tcg_seg_attr_next_seg_create_from_data(chunk_t value);
|
||||||
|
|
||||||
|
#endif /** TCG_SEG_ATTR_NEXT_SEG_H_ @}*/
|
||||||
@@ -0,0 +1,234 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 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_seg_attr_seg_env.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_seg_attr_seg_env_t private_tcg_seg_attr_seg_env_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute Segment Envelope
|
||||||
|
* see TCG IF-M Segmentation Specification
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
* |M|S| Reserved | Base Attribute ID |
|
||||||
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
* | Segment Value (Variable Length) |
|
||||||
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private data of an tcg_seg_attr_seg_env_t object.
|
||||||
|
*/
|
||||||
|
struct private_tcg_seg_attr_seg_env_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public members of tcg_seg_attr_seg_env_t
|
||||||
|
*/
|
||||||
|
tcg_seg_attr_seg_env_t public;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vendor-specific attribute type
|
||||||
|
*/
|
||||||
|
pen_type_t type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute value
|
||||||
|
*/
|
||||||
|
chunk_t value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Noskip flag
|
||||||
|
*/
|
||||||
|
bool noskip_flag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PA-TNC segmentation flags
|
||||||
|
*/
|
||||||
|
uint8_t flags;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base Attribute ID
|
||||||
|
*/
|
||||||
|
uint32_t base_attr_id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute value
|
||||||
|
*/
|
||||||
|
chunk_t segment;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reference count
|
||||||
|
*/
|
||||||
|
refcount_t ref;
|
||||||
|
};
|
||||||
|
|
||||||
|
METHOD(pa_tnc_attr_t, get_type, pen_type_t,
|
||||||
|
private_tcg_seg_attr_seg_env_t *this)
|
||||||
|
{
|
||||||
|
return this->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(pa_tnc_attr_t, get_value, chunk_t,
|
||||||
|
private_tcg_seg_attr_seg_env_t *this)
|
||||||
|
{
|
||||||
|
return this->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
|
||||||
|
private_tcg_seg_attr_seg_env_t *this)
|
||||||
|
{
|
||||||
|
return this->noskip_flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(pa_tnc_attr_t, set_noskip_flag,void,
|
||||||
|
private_tcg_seg_attr_seg_env_t *this, bool noskip)
|
||||||
|
{
|
||||||
|
this->noskip_flag = noskip;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(pa_tnc_attr_t, build, void,
|
||||||
|
private_tcg_seg_attr_seg_env_t *this)
|
||||||
|
{
|
||||||
|
/* constructor already allocated and built value */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(pa_tnc_attr_t, process, status_t,
|
||||||
|
private_tcg_seg_attr_seg_env_t *this, u_int32_t *offset)
|
||||||
|
{
|
||||||
|
bio_reader_t *reader;
|
||||||
|
|
||||||
|
if (this->value.len < TCG_SEG_ATTR_SEG_ENV_HEADER)
|
||||||
|
{
|
||||||
|
DBG1(DBG_TNC, "insufficient data for %N", tcg_attr_names,
|
||||||
|
this->type.type);
|
||||||
|
*offset = 0;
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
reader = bio_reader_create(this->value);
|
||||||
|
reader->read_uint8 (reader, &this->flags);
|
||||||
|
reader->read_uint24(reader, &this->base_attr_id);
|
||||||
|
reader->destroy(reader);
|
||||||
|
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(pa_tnc_attr_t, destroy, void,
|
||||||
|
private_tcg_seg_attr_seg_env_t *this)
|
||||||
|
{
|
||||||
|
if (ref_put(&this->ref))
|
||||||
|
{
|
||||||
|
free(this->value.ptr);
|
||||||
|
free(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
|
||||||
|
private_tcg_seg_attr_seg_env_t *this)
|
||||||
|
{
|
||||||
|
ref_get(&this->ref);
|
||||||
|
return &this->public.pa_tnc_attribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(tcg_seg_attr_seg_env_t, get_segment, chunk_t,
|
||||||
|
private_tcg_seg_attr_seg_env_t *this, uint8_t *flags)
|
||||||
|
{
|
||||||
|
if (flags)
|
||||||
|
{
|
||||||
|
*flags = this->flags;
|
||||||
|
}
|
||||||
|
return chunk_skip(this->value, TCG_SEG_ATTR_SEG_ENV_HEADER);
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(tcg_seg_attr_seg_env_t, get_base_attr_id, uint32_t,
|
||||||
|
private_tcg_seg_attr_seg_env_t *this)
|
||||||
|
{
|
||||||
|
return this->base_attr_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Described in header.
|
||||||
|
*/
|
||||||
|
pa_tnc_attr_t* tcg_seg_attr_seg_env_create(chunk_t segment, uint8_t flags,
|
||||||
|
uint32_t base_attr_id)
|
||||||
|
{
|
||||||
|
private_tcg_seg_attr_seg_env_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_base_attr_id = _get_base_attr_id,
|
||||||
|
.get_segment = _get_segment,
|
||||||
|
},
|
||||||
|
.type = { PEN_TCG, TCG_SEG_ATTR_SEG_ENV },
|
||||||
|
.flags = flags,
|
||||||
|
.base_attr_id = base_attr_id,
|
||||||
|
.value = chunk_alloc(TCG_SEG_ATTR_SEG_ENV_HEADER + segment.len),
|
||||||
|
.ref = 1,
|
||||||
|
);
|
||||||
|
|
||||||
|
htoun32(this->value.ptr, base_attr_id);
|
||||||
|
*this->value.ptr = flags;
|
||||||
|
memcpy(this->value.ptr + TCG_SEG_ATTR_SEG_ENV_HEADER,
|
||||||
|
segment.ptr, segment.len);
|
||||||
|
|
||||||
|
return &this->public.pa_tnc_attribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Described in header.
|
||||||
|
*/
|
||||||
|
pa_tnc_attr_t *tcg_seg_attr_seg_env_create_from_data(chunk_t data)
|
||||||
|
{
|
||||||
|
private_tcg_seg_attr_seg_env_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_base_attr_id = _get_base_attr_id,
|
||||||
|
.get_segment = _get_segment,
|
||||||
|
},
|
||||||
|
.type = { PEN_TCG, TCG_SEG_ATTR_SEG_ENV },
|
||||||
|
.value = chunk_clone(data),
|
||||||
|
.ref = 1,
|
||||||
|
);
|
||||||
|
|
||||||
|
return &this->public.pa_tnc_attribute;
|
||||||
|
}
|
||||||
@@ -37,22 +37,37 @@ struct tcg_seg_attr_seg_env_t {
|
|||||||
*/
|
*/
|
||||||
pa_tnc_attr_t pa_tnc_attribute;
|
pa_tnc_attr_t pa_tnc_attribute;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get enveloped attribute segment
|
||||||
|
*
|
||||||
|
* @param flags Segmentation flags
|
||||||
|
* @return Segment
|
||||||
|
*/
|
||||||
|
chunk_t (*get_segment)(tcg_seg_attr_seg_env_t *this, uint8_t *flags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Base Attribute ID
|
||||||
|
*
|
||||||
|
* @return Base Attribute ID
|
||||||
|
*/
|
||||||
|
uint32_t (*get_base_attr_id)(tcg_seg_attr_seg_env_t *this);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an tcg_seg_attr_seg_env_t object
|
* Creates an tcg_seg_attr_seg_env_t object
|
||||||
*
|
*
|
||||||
* @param max_attr_size Maximum IF-M attribute size in octets
|
* @param segment Attribute segment
|
||||||
* @param max_seg_size Maximum IF-M attribute segment size in octets
|
* @param flags Segmentation flags
|
||||||
* @param request TRUE for a request, FALSE for a response
|
* @param base_attr_id Base Attribute ID
|
||||||
*/
|
*/
|
||||||
pa_tnc_attr_t* tcg_seg_attr_seg_env_create(chunk_t segment, uint8_t flags);
|
pa_tnc_attr_t* tcg_seg_attr_seg_env_create(chunk_t segment, uint8_t flags,
|
||||||
|
uint32_t base_attr_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an tcg_seg_attr_seg_env_t object from received data
|
* Creates an tcg_seg_attr_seg_env_t object from received data
|
||||||
*
|
*
|
||||||
* @param value unparsed attribute value
|
* @param value unparsed attribute value
|
||||||
* @param request TRUE for a request, FALSE for a response
|
|
||||||
*/
|
*/
|
||||||
pa_tnc_attr_t* tcg_seg_attr_seg_env_create_from_data(chunk_t value);
|
pa_tnc_attr_t* tcg_seg_attr_seg_env_create_from_data(chunk_t value);
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,8 @@
|
|||||||
#include "tcg/swid/tcg_swid_attr_tag_id_inv.h"
|
#include "tcg/swid/tcg_swid_attr_tag_id_inv.h"
|
||||||
#include "tcg/swid/tcg_swid_attr_tag_inv.h"
|
#include "tcg/swid/tcg_swid_attr_tag_inv.h"
|
||||||
#include "tcg/seg/tcg_seg_attr_max_size.h"
|
#include "tcg/seg/tcg_seg_attr_max_size.h"
|
||||||
|
#include "tcg/seg/tcg_seg_attr_seg_env.h"
|
||||||
|
#include "tcg/seg/tcg_seg_attr_next_seg.h"
|
||||||
|
|
||||||
ENUM_BEGIN(tcg_attr_names, TCG_SCAP_REFERENCES,
|
ENUM_BEGIN(tcg_attr_names, TCG_SCAP_REFERENCES,
|
||||||
TCG_SCAP_SUMMARY_RESULTS,
|
TCG_SCAP_SUMMARY_RESULTS,
|
||||||
@@ -195,6 +197,10 @@ pa_tnc_attr_t* tcg_attr_create_from_data(u_int32_t type, chunk_t value)
|
|||||||
return tcg_seg_attr_max_size_create_from_data(value, TRUE);
|
return tcg_seg_attr_max_size_create_from_data(value, TRUE);
|
||||||
case TCG_SEG_MAX_ATTR_SIZE_RESP:
|
case TCG_SEG_MAX_ATTR_SIZE_RESP:
|
||||||
return tcg_seg_attr_max_size_create_from_data(value, FALSE);
|
return tcg_seg_attr_max_size_create_from_data(value, FALSE);
|
||||||
|
case TCG_SEG_ATTR_SEG_ENV:
|
||||||
|
return tcg_seg_attr_seg_env_create_from_data(value);
|
||||||
|
case TCG_SEG_NEXT_SEG_REQ:
|
||||||
|
return tcg_seg_attr_next_seg_create_from_data(value);
|
||||||
case TCG_PTS_REQ_PROTO_CAPS:
|
case TCG_PTS_REQ_PROTO_CAPS:
|
||||||
return tcg_pts_attr_proto_caps_create_from_data(value, TRUE);
|
return tcg_pts_attr_proto_caps_create_from_data(value, TRUE);
|
||||||
case TCG_PTS_PROTO_CAPS:
|
case TCG_PTS_PROTO_CAPS:
|
||||||
|
|||||||
Reference in New Issue
Block a user