Do TPM measurements only if there is a TPMRA workitem

This commit is contained in:
Andreas Steffen
2014-01-13 12:06:18 +01:00
parent 81d49c5cfd
commit fbddf52c80
7 changed files with 139 additions and 126 deletions
@@ -33,8 +33,11 @@
#include <pts/pts.h>
#include <pts/pts_database.h>
#include <pts/pts_creds.h>
#include <pts/components/ita/ita_comp_func_name.h>
#include <tcg/tcg_attr.h>
#include <tcg/pts/tcg_pts_attr_meas_algo.h>
#include <tcg/pts/tcg_pts_attr_proto_caps.h>
#include <tcg/pts/tcg_pts_attr_req_file_meas.h>
#include <tcg/pts/tcg_pts_attr_req_file_meta.h>
@@ -289,6 +292,7 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
imv_state_t *state;
imv_session_t *session;
imv_attestation_state_t *attestation_state;
imv_attestation_handshake_state_t handshake_state;
TNC_IMVID imv_id;
TNC_Result result = TNC_RESULT_SUCCESS;
pts_t *pts;
@@ -300,6 +304,7 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
}
attestation_state = (imv_attestation_state_t*)state;
pts = attestation_state->get_pts(attestation_state);
handshake_state = attestation_state->get_handshake_state(attestation_state);
platform_info = pts->get_platform_info(pts);
session = state->get_session(state);
imv_id = this->agent->get_id(this->agent);
@@ -340,6 +345,26 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
out_msg = imv_msg_create(this->agent, state, id, imv_id, TNC_IMCID_ANY,
msg_types[0]);
if (handshake_state == IMV_ATTESTATION_STATE_INIT)
{
pa_tnc_attr_t *attr;
pts_proto_caps_flag_t flags;
/* Send Request Protocol Capabilities attribute */
flags = pts->get_proto_caps(pts);
attr = tcg_pts_attr_proto_caps_create(flags, TRUE);
attr->set_noskip_flag(attr, TRUE);
out_msg->add_attribute(out_msg, attr);
/* Send Measurement Algorithms attribute */
attr = tcg_pts_attr_meas_algo_create(this->supported_algorithms, FALSE);
attr->set_noskip_flag(attr, TRUE);
out_msg->add_attribute(out_msg, attr);
attestation_state->set_handshake_state(attestation_state,
IMV_ATTESTATION_STATE_DISCOVERY);
}
if (platform_info && session &&
(state->get_action_flags(state) & IMV_ATTESTATION_FLAG_ALGO) &&
!(state->get_action_flags(state) & IMV_ATTESTATION_FLAG_FILE_MEAS))
@@ -352,6 +377,9 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
char *pathname;
enumerator_t *enumerator;
attestation_state->set_handshake_state(attestation_state,
IMV_ATTESTATION_STATE_END);
enumerator = session->create_workitem_enumerator(session);
if (enumerator)
{
@@ -376,6 +404,8 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
break;
case IMV_WORKITEM_TPM_ATTEST:
{
pts_component_t *comp;
pts_comp_func_name_t *comp_name;
TNC_IMV_Action_Recommendation rec;
TNC_IMV_Evaluation_Result eval;
bool no_d_flag, no_t_flag;
@@ -397,7 +427,45 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
state->update_recommendation(state, rec, eval);
imcv_db->finalize_workitem(imcv_db, workitem);
workitem->destroy(workitem);
continue;
}
/* do TPM BIOS measurements */
if (strchr(workitem->get_arg_str(workitem), 'B'))
{
comp_name = pts_comp_func_name_create(PEN_ITA,
PTS_ITA_COMP_FUNC_NAME_IMA,
PTS_ITA_QUALIFIER_FLAG_KERNEL |
PTS_ITA_QUALIFIER_TYPE_TRUSTED);
comp = attestation_state->create_component(
attestation_state, comp_name,
0, this->pts_db);
if (!comp)
{
comp_name->log(comp_name, "unregistered ");
comp_name->destroy(comp_name);
}
}
/* do TPM IMA measurements */
if (strchr(workitem->get_arg_str(workitem), 'I'))
{
comp_name = pts_comp_func_name_create(PEN_ITA,
PTS_ITA_COMP_FUNC_NAME_IMA,
PTS_ITA_QUALIFIER_FLAG_KERNEL |
PTS_ITA_QUALIFIER_TYPE_OS);
comp = attestation_state->create_component(
attestation_state, comp_name,
0, this->pts_db);
if (!comp)
{
comp_name->log(comp_name, "unregistered ");
comp_name->destroy(comp_name);
}
}
attestation_state->set_handshake_state(attestation_state,
IMV_ATTESTATION_STATE_NONCE_REQ);
continue;
}
default:
@@ -467,8 +535,8 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
}
/* check the IMV state for the next PA-TNC attributes to send */
if (!imv_attestation_build(out_msg, state, this->supported_algorithms,
this->supported_dh_groups, this->pts_db))
if (!imv_attestation_build(out_msg, state, this->supported_dh_groups,
this->pts_db))
{
state->set_recommendation(state,
TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION,
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
* Copyright (C) 2011-2012 Sansar Choinyambuu
* Copyright (C) 2011-2014 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -16,8 +17,6 @@
#include "imv_attestation_build.h"
#include "imv_attestation_state.h"
#include <tcg/pts/tcg_pts_attr_proto_caps.h>
#include <tcg/pts/tcg_pts_attr_meas_algo.h>
#include <tcg/pts/tcg_pts_attr_dh_nonce_params_req.h>
#include <tcg/pts/tcg_pts_attr_dh_nonce_finish.h>
#include <tcg/pts/tcg_pts_attr_get_tpm_version_info.h>
@@ -27,9 +26,7 @@
#include <utils/debug.h>
bool imv_attestation_build(imv_msg_t *out_msg,
imv_state_t *state,
pts_meas_algorithms_t supported_algorithms,
bool imv_attestation_build(imv_msg_t *out_msg, imv_state_t *state,
pts_dh_group_t supported_dh_groups,
pts_database_t *pts_db)
{
@@ -42,60 +39,8 @@ bool imv_attestation_build(imv_msg_t *out_msg,
handshake_state = attestation_state->get_handshake_state(attestation_state);
pts = attestation_state->get_pts(attestation_state);
/**
* Received a response form the Attestation IMC so we can proceeed
*/
if (handshake_state == IMV_ATTESTATION_STATE_DISCOVERY &&
(state->get_action_flags(state) & IMV_ATTESTATION_FLAG_ALGO))
{
handshake_state = IMV_ATTESTATION_STATE_NONCE_REQ;
}
/**
* Skip DH Nonce Parameters Request attribute when
* DH Nonce Exchange is not selected by PTS-IMC side
*/
if (handshake_state == IMV_ATTESTATION_STATE_NONCE_REQ &&
!(pts->get_proto_caps(pts) & PTS_PROTO_CAPS_D))
{
DBG2(DBG_IMV, "PTS-IMC does not support DH Nonce negotiation");
handshake_state = IMV_ATTESTATION_STATE_TPM_INIT;
}
/**
* Skip TPM Version Info and AIK attributes when
* no TPM is available on the PTS-IMC side
*/
if (handshake_state == IMV_ATTESTATION_STATE_TPM_INIT &&
!(pts->get_proto_caps(pts) & PTS_PROTO_CAPS_T))
{
DBG2(DBG_IMV, "PTS-IMC made no TPM available");
handshake_state = IMV_ATTESTATION_STATE_END;
}
switch (handshake_state)
{
case IMV_ATTESTATION_STATE_INIT:
{
pts_proto_caps_flag_t flags;
/* Send Request Protocol Capabilities attribute */
flags = pts->get_proto_caps(pts);
attr = tcg_pts_attr_proto_caps_create(flags, TRUE);
attr->set_noskip_flag(attr, TRUE);
out_msg->add_attribute(out_msg, attr);
/* Send Measurement Algorithms attribute */
attr = tcg_pts_attr_meas_algo_create(supported_algorithms, FALSE);
attr->set_noskip_flag(attr, TRUE);
out_msg->add_attribute(out_msg, attr);
attestation_state->set_handshake_state(attestation_state,
IMV_ATTESTATION_STATE_DISCOVERY);
break;
}
case IMV_ATTESTATION_STATE_DISCOVERY:
break;
case IMV_ATTESTATION_STATE_NONCE_REQ:
{
int min_nonce_len;
@@ -117,16 +62,13 @@ bool imv_attestation_build(imv_msg_t *out_msg,
pts_meas_algorithms_t selected_algorithm;
chunk_t initiator_value, initiator_nonce;
if ((pts->get_proto_caps(pts) & PTS_PROTO_CAPS_D))
{
/* Send DH nonce finish attribute */
selected_algorithm = pts->get_meas_algorithm(pts);
pts->get_my_public_value(pts, &initiator_value, &initiator_nonce);
attr = tcg_pts_attr_dh_nonce_finish_create(selected_algorithm,
/* Send DH nonce finish attribute */
selected_algorithm = pts->get_meas_algorithm(pts);
pts->get_my_public_value(pts, &initiator_value, &initiator_nonce);
attr = tcg_pts_attr_dh_nonce_finish_create(selected_algorithm,
initiator_value, initiator_nonce);
attr->set_noskip_flag(attr, TRUE);
out_msg->add_attribute(out_msg, attr);
}
attr->set_noskip_flag(attr, TRUE);
out_msg->add_attribute(out_msg, attr);
/* Send Get TPM Version attribute */
attr = tcg_pts_attr_get_tpm_version_info_create();
@@ -146,24 +88,16 @@ bool imv_attestation_build(imv_msg_t *out_msg,
{
tcg_pts_attr_req_func_comp_evid_t *attr_cast;
enumerator_t *enumerator;
pts_component_t *comp;
pts_comp_func_name_t *comp_name;
pts_comp_func_name_t *name;
chunk_t keyid;
int kid, vid, name, qualifier;
int kid;
u_int8_t flags;
u_int32_t depth;
bool first = TRUE, first_component = TRUE;
bool first_component = TRUE;
attestation_state->set_handshake_state(attestation_state,
IMV_ATTESTATION_STATE_END);
if (!(pts->get_proto_caps(pts) & PTS_PROTO_CAPS_T) ||
!(pts->get_proto_caps(pts) & PTS_PROTO_CAPS_D))
{
DBG2(DBG_IMV, "PTS-IMC made no TPM available - "
"skipping Component Measurements");
break;
}
if (!pts->get_aik_keyid(pts, &keyid))
{
DBG1(DBG_IMV, "retrieval of AIK keyid failed");
@@ -178,41 +112,22 @@ bool imv_attestation_build(imv_msg_t *out_msg,
{
return FALSE;
}
enumerator = pts_db->create_comp_evid_enumerator(pts_db, kid);
if (!enumerator)
enumerator = attestation_state->create_component_enumerator(
attestation_state);
while (enumerator->enumerate(enumerator, &flags, &depth, &name))
{
break;
}
while (enumerator->enumerate(enumerator, &vid, &name,
&qualifier, &depth))
{
if (first)
{
DBG2(DBG_IMV, "evidence request by");
first = FALSE;
}
comp_name = pts_comp_func_name_create(vid, name, qualifier);
comp_name->log(comp_name, " ");
comp = attestation_state->create_component(attestation_state,
comp_name, depth, pts_db);
if (!comp)
{
DBG2(DBG_IMV, " not registered or duplicate"
" - removed from request");
comp_name->destroy(comp_name);
continue;
}
if (first_component)
{
attr = tcg_pts_attr_req_func_comp_evid_create();
attr->set_noskip_flag(attr, TRUE);
first_component = FALSE;
DBG2(DBG_IMV, "evidence request by");
}
flags = comp->get_evidence_flags(comp);
name->log(name, " ");
/* TODO check flags against negotiated_caps */
attr_cast = (tcg_pts_attr_req_func_comp_evid_t *)attr;
attr_cast->add_component(attr_cast, flags, depth, comp_name);
attr_cast->add_component(attr_cast, flags, depth, name);
}
enumerator->destroy(enumerator);
@@ -238,9 +153,7 @@ bool imv_attestation_build(imv_msg_t *out_msg,
IMV_ATTESTATION_STATE_END);
}
break;
case IMV_ATTESTATION_STATE_END:
attestation_state->set_handshake_state(attestation_state,
IMV_ATTESTATION_STATE_END);
default:
break;
}
return TRUE;
@@ -35,14 +35,11 @@
*
* @param out_msg outbound PA-TNC message to be built
* @param state state of a given connection
* @param supported_algorithms supported PTS measurement algorithms
* @param supported_dh_groups supported DH groups
* @param pts_db PTS configuration database
* @return TRUE if successful
*/
bool imv_attestation_build(imv_msg_t *out_msg,
imv_state_t *state,
pts_meas_algorithms_t supported_algorithms,
bool imv_attestation_build(imv_msg_t *out_msg, imv_state_t *state,
pts_dh_group_t supported_dh_groups,
pts_database_t *pts_db);
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2011-2013 Sansar Choinyambuu, Andreas Steffen
* Copyright (C) 2011-2012 Sansar Choinyambuu
* Copyright (C) 2011-2014 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -381,9 +382,6 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg,
status = comp->verify(comp, name->get_qualifier(name), pts, evidence);
if (status == VERIFY_ERROR || status == FAILED)
{
state->update_recommendation(state,
TNC_IMV_ACTION_RECOMMENDATION_ISOLATE,
TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR);
attestation_state->set_measurement_error(attestation_state,
IMV_ATTESTATION_ERROR_COMP_EVID_FAIL);
name->log(name, " measurement mismatch for ");
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2011-2012 Sansar Choinyambuu
* Copyright (C) 2011-2013 Andreas Steffen
* Copyright (C) 2011-2014 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -127,7 +127,7 @@ struct private_imv_attestation_state_t {
*/
struct func_comp_t {
pts_component_t *comp;
u_int8_t qualifier;
pts_comp_func_name_t* name;
};
/**
@@ -136,6 +136,7 @@ struct func_comp_t {
static void free_func_comp(func_comp_t *this)
{
this->comp->destroy(this->comp);
this->name->destroy(this->name);
free(this);
}
@@ -396,13 +397,13 @@ METHOD(imv_attestation_state_t, create_component, pts_component_t*,
if (found)
{
if (name->get_qualifier(name) == entry->qualifier)
if (name->equals(name, entry->name))
{
/* duplicate entry */
return NULL;
}
new_entry = malloc_thing(func_comp_t);
new_entry->qualifier = name->get_qualifier(name);
new_entry->name = name->clone(name);
new_entry->comp = entry->comp->get_ref(entry->comp);
this->components->insert_last(this->components, new_entry);
return entry->comp;
@@ -416,13 +417,41 @@ METHOD(imv_attestation_state_t, create_component, pts_component_t*,
return NULL;
}
new_entry = malloc_thing(func_comp_t);
new_entry->qualifier = name->get_qualifier(name);
new_entry->name = name->clone(name);
new_entry->comp = component;
this->components->insert_last(this->components, new_entry);
return component;
}
}
/**
* Enumerate file measurement entries
*/
static bool entry_filter(void *null, func_comp_t **entry, u_int8_t *flags,
void *i2, u_int32_t *depth,
void *i3, pts_comp_func_name_t **comp_name)
{
pts_component_t *comp;
pts_comp_func_name_t *name;
comp = (*entry)->comp;
name = (*entry)->name;
*flags = comp->get_evidence_flags(comp);
*depth = comp->get_depth(comp);
*comp_name = name;
return TRUE;
}
METHOD(imv_attestation_state_t, create_component_enumerator, enumerator_t*,
private_imv_attestation_state_t *this)
{
return enumerator_create_filter(
this->components->create_enumerator(this->components),
(void*)entry_filter, NULL, NULL);
}
METHOD(imv_attestation_state_t, get_component, pts_component_t*,
private_imv_attestation_state_t *this, pts_comp_func_name_t *name)
{
@@ -433,8 +462,7 @@ METHOD(imv_attestation_state_t, get_component, pts_component_t*,
enumerator = this->components->create_enumerator(this->components);
while (enumerator->enumerate(enumerator, &entry))
{
if (name->equals(name, entry->comp->get_comp_func_name(entry->comp)) &&
name->get_qualifier(name) == entry->qualifier)
if (name->equals(name, entry->name))
{
found = entry->comp;
break;
@@ -464,7 +492,8 @@ METHOD(imv_attestation_state_t, finalize_components, void,
while (this->components->remove_last(this->components,
(void**)&entry) == SUCCESS)
{
if (!entry->comp->finalize(entry->comp, entry->qualifier))
if (!entry->comp->finalize(entry->comp,
entry->name->get_qualifier(entry->name)))
{
set_measurement_error(this, IMV_ATTESTATION_ERROR_COMP_EVID_PEND);
}
@@ -512,6 +541,7 @@ imv_state_t *imv_attestation_state_create(TNC_ConnectionID connection_id)
.set_handshake_state = _set_handshake_state,
.get_pts = _get_pts,
.create_component = _create_component,
.create_component_enumerator = _create_component_enumerator,
.get_component = _get_component,
.finalize_components = _finalize_components,
.components_finalized = _components_finalized,
@@ -116,6 +116,13 @@ struct imv_attestation_state_t {
u_int32_t depth,
pts_database_t *pts_db);
/**
* Enumerate over all Functional Components
*
* @return Functional Component enumerator
*/
enumerator_t* (*create_component_enumerator)(imv_attestation_state_t *this);
/**
* Get a Functional Component with a given name
*
@@ -286,7 +286,7 @@ METHOD(tcg_pts_attr_req_func_comp_evid_t, add_component, void,
entry = malloc_thing(entry_t);
entry->flags = flags;
entry->depth = depth;
entry->name = name;
entry->name = name->clone(name);
this->list->insert_last(this->list, entry);
}