summaryrefslogtreecommitdiff
path: root/src/libpts/plugins/imv_attestation
diff options
context:
space:
mode:
Diffstat (limited to 'src/libpts/plugins/imv_attestation')
-rw-r--r--src/libpts/plugins/imv_attestation/Makefile.in12
-rw-r--r--src/libpts/plugins/imv_attestation/attest.c13
-rw-r--r--src/libpts/plugins/imv_attestation/attest_db.c4
-rw-r--r--src/libpts/plugins/imv_attestation/attest_usage.c7
-rw-r--r--src/libpts/plugins/imv_attestation/imv_attestation_agent.c186
-rw-r--r--src/libpts/plugins/imv_attestation/imv_attestation_build.c153
-rw-r--r--src/libpts/plugins/imv_attestation/imv_attestation_build.h5
-rw-r--r--src/libpts/plugins/imv_attestation/imv_attestation_process.c83
-rw-r--r--src/libpts/plugins/imv_attestation/imv_attestation_state.c114
-rw-r--r--src/libpts/plugins/imv_attestation/imv_attestation_state.h35
10 files changed, 379 insertions, 233 deletions
diff --git a/src/libpts/plugins/imv_attestation/Makefile.in b/src/libpts/plugins/imv_attestation/Makefile.in
index 032d07a38..c1c14d476 100644
--- a/src/libpts/plugins/imv_attestation/Makefile.in
+++ b/src/libpts/plugins/imv_attestation/Makefile.in
@@ -227,8 +227,6 @@ BTLIB = @BTLIB@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
-CHECK_CFLAGS = @CHECK_CFLAGS@
-CHECK_LIBS = @CHECK_LIBS@
COVERAGE_CFLAGS = @COVERAGE_CFLAGS@
COVERAGE_LDFLAGS = @COVERAGE_LDFLAGS@
CPP = @CPP@
@@ -296,6 +294,11 @@ PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
+PYTHON = @PYTHON@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
RUBY = @RUBY@
@@ -384,12 +387,16 @@ pcsclite_CFLAGS = @pcsclite_CFLAGS@
pcsclite_LIBS = @pcsclite_LIBS@
pdfdir = @pdfdir@
piddir = @piddir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
pki_plugins = @pki_plugins@
plugindir = @plugindir@
pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
@@ -404,6 +411,7 @@ soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
+strongswan_options = @strongswan_options@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
t_plugins = @t_plugins@
diff --git a/src/libpts/plugins/imv_attestation/attest.c b/src/libpts/plugins/imv_attestation/attest.c
index 4d25df3f4..b8a6854cb 100644
--- a/src/libpts/plugins/imv_attestation/attest.c
+++ b/src/libpts/plugins/imv_attestation/attest.c
@@ -266,19 +266,20 @@ static void do_args(int argc, char *argv[])
continue;
case 'F':
{
- char *path = strdup(optarg);
- char *dir = dirname(path);
- char *file = basename(optarg);
+ char *dir = path_dirname(optarg);
+ char *file = path_basename(optarg);
if (*dir != '.')
{
if (!attest->set_directory(attest, dir, op == OP_ADD))
{
- free(path);
+ free(file);
+ free(dir);
exit(EXIT_FAILURE);
}
}
- free(path);
+ free(file);
+ free(dir);
if (!attest->set_file(attest, file, op == OP_ADD))
{
exit(EXIT_FAILURE);
@@ -439,7 +440,7 @@ int main(int argc, char *argv[])
atexit(library_deinit);
/* initialize library */
- if (!library_init(NULL))
+ if (!library_init(NULL, "attest"))
{
exit(SS_RC_LIBSTRONGSWAN_INTEGRITY);
}
diff --git a/src/libpts/plugins/imv_attestation/attest_db.c b/src/libpts/plugins/imv_attestation/attest_db.c
index d7654ab43..7a8a1135a 100644
--- a/src/libpts/plugins/imv_attestation/attest_db.c
+++ b/src/libpts/plugins/imv_attestation/attest_db.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011-2012 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
@@ -1555,7 +1555,7 @@ METHOD(attest_db_t, list_sessions, void,
device_len = min(strlen(device), DEVICE_MAX_LEN);
identity = identity.len ? identity : chunk_from_str("-");
printf("%4d: %T %2d %-20s %.*s%*s%.*s - %N\n", session_id, &created,
- FALSE, conn_id, product, device_len, device,
+ this->utc, conn_id, product, device_len, device,
DEVICE_MAX_LEN - device_len + 1, " ", (int)identity.len,
identity.ptr, TNC_IMV_Action_Recommendation_names, rec);
}
diff --git a/src/libpts/plugins/imv_attestation/attest_usage.c b/src/libpts/plugins/imv_attestation/attest_usage.c
index 324fcafc3..8f4afdbad 100644
--- a/src/libpts/plugins/imv_attestation/attest_usage.c
+++ b/src/libpts/plugins/imv_attestation/attest_usage.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 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
@@ -24,7 +24,7 @@ void usage(void)
{
printf("\
Usage:\n\
- ipsec attest --components|--devices|--files|--hashes|--keys [options]\n\
+ ipsec attest --components|--devices|--sessions|--files|--hashes|--keys [options]\n\
\n\
ipsec attest --measurements|--packages|--products|--add|--del [options]\n\
\n\
@@ -35,6 +35,9 @@ Usage:\n\
ipsec attest --devices [--utc]\n\
Show a list of registered devices and associated collected information\n\
\n\
+ ipsec attest --sessions [--utc]\n\
+ Show a chronologically sorted list of all TNC sessions\n\
+ \n\
ipsec attest --files [--product <name>|--pid <id>]\n\
Show a list of files with a software product name or\n\
its primary key as an optional selector.\n\
diff --git a/src/libpts/plugins/imv_attestation/imv_attestation_agent.c b/src/libpts/plugins/imv_attestation/imv_attestation_agent.c
index 978c74001..e8c3c5e40 100644
--- a/src/libpts/plugins/imv_attestation/imv_attestation_agent.c
+++ b/src/libpts/plugins/imv_attestation/imv_attestation_agent.c
@@ -14,6 +14,9 @@
* for more details.
*/
+#define _GNU_SOURCE /* for stdndup() */
+#include <string.h>
+
#include "imv_attestation_agent.h"
#include "imv_attestation_state.h"
#include "imv_attestation_process.h"
@@ -33,8 +36,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,10 +295,15 @@ 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;
+ imv_workitem_t *workitem;
+ TNC_IMV_Action_Recommendation rec;
+ TNC_IMV_Evaluation_Result eval;
TNC_IMVID imv_id;
TNC_Result result = TNC_RESULT_SUCCESS;
pts_t *pts;
char *platform_info;
+ enumerator_t *enumerator;
if (!this->agent->get_state(this->agent, id, &state))
{
@@ -300,6 +311,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);
@@ -336,21 +348,57 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
state->set_action_flags(state, IMV_ATTESTATION_FLAG_ATTR_REQ);
}
+ if (handshake_state == IMV_ATTESTATION_STATE_INIT)
+ {
+ pa_tnc_attr_t *attr;
+ pts_proto_caps_flag_t flags;
+
+ out_msg = imv_msg_create(this->agent, state, id, imv_id, TNC_IMCID_ANY,
+ msg_types[0]);
+
+ /* 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);
+
+ /* send these initial PTS attributes and exit */
+ result = out_msg->send(out_msg, FALSE);
+ out_msg->destroy(out_msg);
+
+ return result;
+ }
+
+ /* exit if we are not ready yet for PTS measurements */
+ if (!platform_info || !session ||
+ !(state->get_action_flags(state) & IMV_ATTESTATION_FLAG_ALGO))
+ {
+ return TNC_RESULT_SUCCESS;
+ }
+
/* create an empty out message - we might need it */
out_msg = imv_msg_create(this->agent, state, id, imv_id, TNC_IMCID_ANY,
msg_types[0]);
- if (platform_info && session &&
- (state->get_action_flags(state) & IMV_ATTESTATION_FLAG_ALGO) &&
- !(state->get_action_flags(state) & IMV_ATTESTATION_FLAG_FILE_MEAS))
+ /* establish the PTS measurements to be taken */
+ if (!(state->get_action_flags(state) & IMV_ATTESTATION_FLAG_FILE_MEAS))
{
- imv_workitem_t *workitem;
bool is_dir, no_workitems = TRUE;
u_int32_t delimiter = SOLIDUS_UTF;
u_int16_t request_id;
pa_tnc_attr_t *attr;
char *pathname;
- enumerator_t *enumerator;
+
+ attestation_state->set_handshake_state(attestation_state,
+ IMV_ATTESTATION_STATE_END);
enumerator = session->create_workitem_enumerator(session);
if (enumerator)
@@ -374,10 +422,75 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
case IMV_WORKITEM_DIR_META:
is_dir = TRUE;
break;
+ case IMV_WORKITEM_TPM_ATTEST:
+ {
+ pts_component_t *comp;
+ pts_comp_func_name_t *comp_name;
+ bool no_d_flag, no_t_flag;
+ char result_str[BUF_LEN];
+
+ workitem->set_imv_id(workitem, imv_id);
+ no_workitems = FALSE;
+ no_d_flag = !(pts->get_proto_caps(pts) & PTS_PROTO_CAPS_D);
+ no_t_flag = !(pts->get_proto_caps(pts) & PTS_PROTO_CAPS_T);
+ if (no_d_flag || no_t_flag)
+ {
+ snprintf(result_str, BUF_LEN, "%s%s%s",
+ (no_t_flag) ? "no TPM available" : "",
+ (no_t_flag && no_d_flag) ? ", " : "",
+ (no_d_flag) ? "no DH nonce negotiation" : "");
+ eval = TNC_IMV_EVALUATION_RESULT_ERROR;
+ session->remove_workitem(session, enumerator);
+ rec = workitem->set_result(workitem, result_str, eval);
+ 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:
continue;
}
+ /* initiate file and directory measurements */
pathname = this->pts_db->get_pathname(this->pts_db, is_dir,
workitem->get_arg_int(workitem));
if (!pathname)
@@ -440,22 +553,35 @@ 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))
+ enumerator = session->create_workitem_enumerator(session);
+ while (enumerator->enumerate(enumerator, &workitem))
{
- state->set_recommendation(state,
- TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION,
- TNC_IMV_EVALUATION_RESULT_ERROR);
- result = out_msg->send_assessment(out_msg);
- out_msg->destroy(out_msg);
- state->set_action_flags(state, IMV_ATTESTATION_FLAG_REC);
-
- if (result != TNC_RESULT_SUCCESS)
+ if (workitem->get_type(workitem) == IMV_WORKITEM_TPM_ATTEST)
{
- return result;
+ if (!imv_attestation_build(out_msg, state,
+ this->supported_dh_groups, this->pts_db))
+ {
+ imv_reason_string_t *reason_string;
+ chunk_t result;
+ char *result_str;
+
+ reason_string = imv_reason_string_create("en", ", ");
+ attestation_state->add_comp_evid_reasons(attestation_state,
+ reason_string);
+ result = reason_string->get_encoding(reason_string);
+ result_str = strndup(result.ptr, result.len);
+ reason_string->destroy(reason_string);
+
+ eval = TNC_IMV_EVALUATION_RESULT_ERROR;
+ session->remove_workitem(session, enumerator);
+ rec = workitem->set_result(workitem, result_str, eval);
+ state->update_recommendation(state, rec, eval);
+ imcv_db->finalize_workitem(imcv_db, workitem);
+ }
+ break;
}
- return this->agent->provide_recommendation(this->agent, state);
}
+ enumerator->destroy(enumerator);
/* finalized all workitems? */
if (session && session->get_policy_started(session) &&
@@ -524,18 +650,22 @@ METHOD(imv_agent_if_t, solicit_recommendation, TNC_Result,
case IMV_WORKITEM_FILE_MEAS:
case IMV_WORKITEM_DIR_REF_MEAS:
case IMV_WORKITEM_DIR_MEAS:
- session->remove_workitem(session, enumerator);
- result_str = "pending file measurements";
- eval = TNC_IMV_EVALUATION_RESULT_ERROR;
- rec = workitem->set_result(workitem, result_str, eval);
- state->update_recommendation(state, rec, eval);
- imcv_db->finalize_workitem(imcv_db, workitem);
- workitem->destroy(workitem);
+ result_str = "Pending file measurements";
pending_file_meas++;
break;
- default:
+ case IMV_WORKITEM_TPM_ATTEST:
+ attestation_state->finalize_components(attestation_state);
+ result_str = "Pending component evidence";
break;
+ default:
+ continue;
}
+ session->remove_workitem(session, enumerator);
+ eval = TNC_IMV_EVALUATION_RESULT_ERROR;
+ rec = workitem->set_result(workitem, result_str, eval);
+ state->update_recommendation(state, rec, eval);
+ imcv_db->finalize_workitem(imcv_db, workitem);
+ workitem->destroy(workitem);
}
enumerator->destroy(enumerator);
@@ -585,11 +715,11 @@ imv_agent_if_t *imv_attestation_agent_create(const char *name, TNC_IMVID id,
}
hash_alg = lib->settings->get_str(lib->settings,
- "libimcv.plugins.imv-attestation.hash_algorithm", "sha256");
+ "%s.plugins.imv-attestation.hash_algorithm", "sha256", lib->ns);
dh_group = lib->settings->get_str(lib->settings,
- "libimcv.plugins.imv-attestation.dh_group", "ecp256");
+ "%s.plugins.imv-attestation.dh_group", "ecp256", lib->ns);
cadir = lib->settings->get_str(lib->settings,
- "libimcv.plugins.imv-attestation.cadir", NULL);
+ "%s.plugins.imv-attestation.cadir", NULL, lib->ns);
INIT(this,
.public = {
diff --git a/src/libpts/plugins/imv_attestation/imv_attestation_build.c b/src/libpts/plugins/imv_attestation/imv_attestation_build.c
index 1fbde2c6d..84023c6c6 100644
--- a/src/libpts/plugins/imv_attestation/imv_attestation_build.c
+++ b/src/libpts/plugins/imv_attestation/imv_attestation_build.c
@@ -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,67 +39,15 @@ 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;
/* Send DH nonce parameters request attribute */
min_nonce_len = lib->settings->get_int(lib->settings,
- "libimcv.plugins.imv-attestation.min_nonce_len", 0);
+ "%s.plugins.imv-attestation.min_nonce_len", 0, lib->ns);
attr = tcg_pts_attr_dh_nonce_params_req_create(min_nonce_len,
supported_dh_groups);
attr->set_noskip_flag(attr, TRUE);
@@ -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,73 +88,40 @@ 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");
- return FALSE;
- }
- if (!pts_db)
- {
- DBG1(DBG_IMV, "pts database not available");
- break;
- }
- if (pts_db->check_aik_keyid(pts_db, keyid, &kid) != SUCCESS)
+ if (!pts->get_aik_keyid(pts, &keyid) ||
+ pts_db->check_aik_keyid(pts_db, keyid, &kid) != SUCCESS)
{
+ attestation_state->set_measurement_error(attestation_state,
+ IMV_ATTESTATION_ERROR_NO_TRUSTED_AIK);
return FALSE;
}
- enumerator = pts_db->create_comp_evid_enumerator(pts_db, kid);
- if (!enumerator)
- {
- 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;
- }
+ enumerator = attestation_state->create_component_enumerator(
+ attestation_state);
+ while (enumerator->enumerate(enumerator, &flags, &depth, &name))
+ {
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);
@@ -231,17 +140,9 @@ bool imv_attestation_build(imv_msg_t *out_msg,
}
break;
}
- case IMV_ATTESTATION_STATE_EVID_FINAL:
- if (attestation_state->components_finalized(attestation_state))
- {
- attestation_state->set_handshake_state(attestation_state,
- 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;
}
diff --git a/src/libpts/plugins/imv_attestation/imv_attestation_build.h b/src/libpts/plugins/imv_attestation/imv_attestation_build.h
index 0cee49b34..88538b198 100644
--- a/src/libpts/plugins/imv_attestation/imv_attestation_build.h
+++ b/src/libpts/plugins/imv_attestation/imv_attestation_build.h
@@ -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);
diff --git a/src/libpts/plugins/imv_attestation/imv_attestation_process.c b/src/libpts/plugins/imv_attestation/imv_attestation_process.c
index 5137d64fe..e40c92a24 100644
--- a/src/libpts/plugins/imv_attestation/imv_attestation_process.c
+++ b/src/libpts/plugins/imv_attestation/imv_attestation_process.c
@@ -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
@@ -13,6 +14,9 @@
* for more details.
*/
+#define _GNU_SOURCE /* for stdndup() */
+#include <string.h>
+
#include "imv_attestation_process.h"
#include <imcv.h>
@@ -92,7 +96,7 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg,
/* check compliance of responder nonce length */
min_nonce_len = lib->settings->get_int(lib->settings,
- "libimcv.plugins.imv-attestation.min_nonce_len", 0);
+ "%s.plugins.imv-attestation.min_nonce_len", 0, lib->ns);
nonce_len = responder_nonce.len;
if (nonce_len < PTS_MIN_NONCE_LEN ||
(min_nonce_len > 0 && nonce_len < min_nonce_len))
@@ -162,7 +166,9 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg,
if (!aik)
{
DBG1(DBG_IMV, "AIK unavailable");
- return FALSE;
+ attestation_state->set_measurement_error(attestation_state,
+ IMV_ATTESTATION_ERROR_NO_TRUSTED_AIK);
+ break;
}
if (aik->get_type(aik) == CERT_X509)
{
@@ -186,7 +192,9 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg,
trusted ? "" : "not ");
if (!trusted)
{
- return FALSE;
+ attestation_state->set_measurement_error(attestation_state,
+ IMV_ATTESTATION_ERROR_NO_TRUSTED_AIK);
+ break;
}
}
pts->set_aik(pts, aik);
@@ -242,7 +250,7 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg,
}
type = found->get_type(found);
arg_int = found->get_arg_int(found);
-
+
switch (type)
{
default:
@@ -295,7 +303,7 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg,
e = measurements->create_enumerator(measurements);
while (e->enumerate(e, &filename, &measurement))
{
- if (pts_db->add_file_measurement(pts_db,
+ if (pts_db->add_file_measurement(pts_db,
platform_info, algo, measurement, filename,
is_dir, arg_int) != SUCCESS)
{
@@ -366,6 +374,7 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg,
pts_comp_evidence_t *evidence;
pts_component_t *comp;
u_int32_t depth;
+ status_t status;
attr_cast = (tcg_pts_attr_simple_comp_evid_t*)attr;
evidence = attr_cast->get_comp_evidence(attr_cast);
@@ -377,12 +386,9 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg,
DBG1(DBG_IMV, " no entry found for component evidence request");
break;
}
- if (comp->verify(comp, name->get_qualifier(name), pts,
- evidence) != SUCCESS)
+ 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 ");
@@ -396,6 +402,9 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg,
pts_meas_algorithms_t comp_hash_algorithm;
chunk_t pcr_comp, tpm_quote_sig, evid_sig;
chunk_t pcr_composite, quote_info;
+ imv_session_t *session;
+ imv_workitem_t *workitem;
+ enumerator_t *enumerator;
bool use_quote2, use_ver_info;
attr_cast = (tcg_pts_attr_simple_evid_final_t*)attr;
@@ -420,9 +429,6 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg,
{
DBG1(DBG_IMV, "received PCR Composite does not match "
"constructed one");
- 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_TPM_QUOTE_FAIL);
goto quote_error;
@@ -431,9 +437,6 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg,
if (!pts->verify_quote_signature(pts, quote_info, tpm_quote_sig))
{
- 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_TPM_QUOTE_FAIL);
goto quote_error;
@@ -449,6 +452,52 @@ quote_error:
* if all expected component measurements were received
*/
attestation_state->finalize_components(attestation_state);
+
+ session = state->get_session(state);
+ enumerator = session->create_workitem_enumerator(session);
+ while (enumerator->enumerate(enumerator, &workitem))
+ {
+ if (workitem->get_type(workitem) == IMV_WORKITEM_TPM_ATTEST)
+ {
+ TNC_IMV_Action_Recommendation rec;
+ TNC_IMV_Evaluation_Result eval;
+ char *result_str;
+ u_int32_t error;
+
+ error = attestation_state->get_measurement_error(
+ attestation_state);
+ if (error & (IMV_ATTESTATION_ERROR_COMP_EVID_FAIL |
+ IMV_ATTESTATION_ERROR_COMP_EVID_PEND |
+ IMV_ATTESTATION_ERROR_TPM_QUOTE_FAIL))
+ {
+ imv_reason_string_t *reason_string;
+ chunk_t result;
+
+ reason_string = imv_reason_string_create("en", ", ");
+ attestation_state->add_comp_evid_reasons(
+ attestation_state, reason_string);
+ result = reason_string->get_encoding(reason_string);
+ result_str = strndup(result.ptr, result.len);
+ reason_string->destroy(reason_string);
+ eval = TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR;
+ }
+ else
+ {
+ result_str = strdup("attestation successful");
+ eval = TNC_IMV_EVALUATION_RESULT_COMPLIANT;
+ }
+ session->remove_workitem(session, enumerator);
+ rec = workitem->set_result(workitem, result_str, eval);
+ state->update_recommendation(state, rec, eval);
+ imcv_db->finalize_workitem(imcv_db, workitem);
+ workitem->destroy(workitem);
+ free(result_str);
+ attestation_state->set_handshake_state(attestation_state,
+ IMV_ATTESTATION_STATE_END);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
}
if (attr_cast->get_evid_sig(attr_cast, &evid_sig))
diff --git a/src/libpts/plugins/imv_attestation/imv_attestation_state.c b/src/libpts/plugins/imv_attestation/imv_attestation_state.c
index 47011751d..9304b9a13 100644
--- a/src/libpts/plugins/imv_attestation/imv_attestation_state.c
+++ b/src/libpts/plugins/imv_attestation/imv_attestation_state.c
@@ -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);
}
@@ -161,6 +162,12 @@ static imv_lang_string_t reason_file_meas_pend[] = {
{ NULL, NULL }
};
+static imv_lang_string_t reason_no_trusted_aik[] = {
+ { "en", "No trusted AIK available" },
+ { "de", "Kein vetrauenswürdiger AIK verfügbar" },
+ { NULL, NULL }
+};
+
static imv_lang_string_t reason_comp_evid_fail[] = {
{ "en", "Incorrect component evidence" },
{ "de", "Falsche Komponenten-Evidenz" },
@@ -290,42 +297,52 @@ METHOD(imv_state_t, update_recommendation, void,
this->eval = tncif_policy_update_evaluation(this->eval, eval);
}
-METHOD(imv_state_t, get_reason_string, bool,
- private_imv_attestation_state_t *this, enumerator_t *language_enumerator,
- chunk_t *reason_string, char **reason_language)
+METHOD(imv_attestation_state_t, add_file_meas_reasons, void,
+ private_imv_attestation_state_t *this, imv_reason_string_t *reason_string)
{
- *reason_language = imv_lang_string_select_lang(language_enumerator,
- languages, countof(languages));
-
- /* Instantiate a TNC Reason String object */
- DESTROY_IF(this->reason_string);
- this->reason_string = imv_reason_string_create(*reason_language);
-
if (this->measurement_error & IMV_ATTESTATION_ERROR_FILE_MEAS_FAIL)
{
- this->reason_string->add_reason(this->reason_string,
- reason_file_meas_fail);
+ reason_string->add_reason(reason_string, reason_file_meas_fail);
}
if (this->measurement_error & IMV_ATTESTATION_ERROR_FILE_MEAS_PEND)
{
- this->reason_string->add_reason(this->reason_string,
- reason_file_meas_pend);
+ reason_string->add_reason(reason_string, reason_file_meas_pend);
+ }
+}
+
+METHOD(imv_attestation_state_t, add_comp_evid_reasons, void,
+ private_imv_attestation_state_t *this, imv_reason_string_t *reason_string)
+{
+ if (this->measurement_error & IMV_ATTESTATION_ERROR_NO_TRUSTED_AIK)
+ {
+ reason_string->add_reason(reason_string, reason_no_trusted_aik);
}
if (this->measurement_error & IMV_ATTESTATION_ERROR_COMP_EVID_FAIL)
{
- this->reason_string->add_reason(this->reason_string,
- reason_comp_evid_fail);
+ reason_string->add_reason(reason_string, reason_comp_evid_fail);
}
if (this->measurement_error & IMV_ATTESTATION_ERROR_COMP_EVID_PEND)
{
- this->reason_string->add_reason(this->reason_string,
- reason_comp_evid_pend);
+ reason_string->add_reason(reason_string, reason_comp_evid_pend);
}
if (this->measurement_error & IMV_ATTESTATION_ERROR_TPM_QUOTE_FAIL)
{
- this->reason_string->add_reason(this->reason_string,
- reason_tpm_quote_fail);
+ reason_string->add_reason(reason_string, reason_tpm_quote_fail);
}
+}
+
+METHOD(imv_state_t, get_reason_string, bool,
+ private_imv_attestation_state_t *this, enumerator_t *language_enumerator,
+ chunk_t *reason_string, char **reason_language)
+{
+ *reason_language = imv_lang_string_select_lang(language_enumerator,
+ languages, countof(languages));
+
+ /* Instantiate a TNC Reason String object */
+ DESTROY_IF(this->reason_string);
+ this->reason_string = imv_reason_string_create(*reason_language, "\n");
+ add_file_meas_reasons(this, this->reason_string);
+ add_comp_evid_reasons(this, this->reason_string);
*reason_string = this->reason_string->get_encoding(this->reason_string);
return TRUE;
@@ -390,13 +407,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;
@@ -410,13 +427,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)
{
@@ -427,8 +472,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;
@@ -458,23 +502,15 @@ 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);
- update_recommendation(this,
- TNC_IMV_ACTION_RECOMMENDATION_ISOLATE,
- TNC_IMV_EVALUATION_RESULT_ERROR);
}
free_func_comp(entry);
}
}
-METHOD(imv_attestation_state_t, components_finalized, bool,
- private_imv_attestation_state_t *this)
-{
- return this->components->get_count(this->components) == 0;
-}
-
/**
* Described in header.
*/
@@ -509,11 +545,13 @@ 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,
.get_measurement_error = _get_measurement_error,
.set_measurement_error = _set_measurement_error,
+ .add_file_meas_reasons = _add_file_meas_reasons,
+ .add_comp_evid_reasons = _add_comp_evid_reasons,
},
.connection_id = connection_id,
.state = TNC_CONNECTION_STATE_CREATE,
diff --git a/src/libpts/plugins/imv_attestation/imv_attestation_state.h b/src/libpts/plugins/imv_attestation/imv_attestation_state.h
index 27d1ae8db..9369d30a2 100644
--- a/src/libpts/plugins/imv_attestation/imv_attestation_state.h
+++ b/src/libpts/plugins/imv_attestation/imv_attestation_state.h
@@ -25,6 +25,7 @@
#define IMV_ATTESTATION_STATE_H_
#include <imv/imv_state.h>
+#include <imv/imv_reason_string.h>
#include <pts/pts.h>
#include <pts/pts_database.h>
#include <pts/components/pts_component.h>
@@ -64,9 +65,10 @@ enum imv_attestation_handshake_state_t {
enum imv_meas_error_t {
IMV_ATTESTATION_ERROR_FILE_MEAS_FAIL = 1,
IMV_ATTESTATION_ERROR_FILE_MEAS_PEND = 2,
- IMV_ATTESTATION_ERROR_COMP_EVID_FAIL = 4,
- IMV_ATTESTATION_ERROR_COMP_EVID_PEND = 8,
- IMV_ATTESTATION_ERROR_TPM_QUOTE_FAIL = 16
+ IMV_ATTESTATION_ERROR_NO_TRUSTED_AIK = 4,
+ IMV_ATTESTATION_ERROR_COMP_EVID_FAIL = 8,
+ IMV_ATTESTATION_ERROR_COMP_EVID_PEND = 16,
+ IMV_ATTESTATION_ERROR_TPM_QUOTE_FAIL = 32
};
/**
@@ -116,6 +118,13 @@ struct imv_attestation_state_t {
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
@@ -131,11 +140,6 @@ struct imv_attestation_state_t {
void (*finalize_components)(imv_attestation_state_t *this);
/**
- * Have the Functional Component measurements been finalized?
- */
- bool (*components_finalized)(imv_attestation_state_t *this);
-
- /**
* Indicates the types of measurement errors that occurred
*
* @return Measurement error flags
@@ -150,6 +154,21 @@ struct imv_attestation_state_t {
void (*set_measurement_error)(imv_attestation_state_t *this,
u_int32_t error);
+ /**
+ * Returns a concatenation of File Measurement reason strings
+ *
+ * @param reason_string Concatenated reason strings
+ */
+ void (*add_file_meas_reasons)(imv_attestation_state_t *this,
+ imv_reason_string_t *reason_string);
+
+ /**
+ * Returns a concatenation of Component Evidence reason strings
+ *
+ * @param reason_string Concatenated reason strings
+ */
+ void (*add_comp_evid_reasons)(imv_attestation_state_t *this,
+ imv_reason_string_t *reason_string);
};
/**