#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>
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;
}
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);
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))
char *pathname;
enumerator_t *enumerator;
+ attestation_state->set_handshake_state(attestation_state,
+ IMV_ATTESTATION_STATE_END);
+
enumerator = session->create_workitem_enumerator(session);
if (enumerator)
{
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;
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:
}
/* 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,
/*
- * 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
#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>
#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)
{
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;
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();
{
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");
{
return FALSE;
}
- enumerator = pts_db->create_comp_evid_enumerator(pts_db, kid);
- if (!enumerator)
- {
- break;
- }
- while (enumerator->enumerate(enumerator, &vid, &name,
- &qualifier, &depth))
+ enumerator = attestation_state->create_component_enumerator(
+ attestation_state);
+ while (enumerator->enumerate(enumerator, &flags, &depth, &name))
{
- 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);
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;
*
* @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);
/*
- * 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
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 ");
/*
* 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
*/
struct func_comp_t {
pts_component_t *comp;
- u_int8_t qualifier;
+ pts_comp_func_name_t* name;
};
/**
static void free_func_comp(func_comp_t *this)
{
this->comp->destroy(this->comp);
+ this->name->destroy(this->name);
free(this);
}
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;
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)
{
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;
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);
}
.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,
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
*
* @param name Name of the requested Functional Component
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);
}