diff options
author | Yves-Alexis Perez <corsac@debian.org> | 2014-03-11 20:48:48 +0100 |
---|---|---|
committer | Yves-Alexis Perez <corsac@debian.org> | 2014-03-11 20:48:48 +0100 |
commit | 15fb7904f4431a6e7c305fd08732458f7f885e7e (patch) | |
tree | c93b60ee813af70509f00f34e29ebec311762427 /src/libpts | |
parent | 5313d2d78ca150515f7f5eb39801c100690b6b29 (diff) | |
download | vyos-strongswan-15fb7904f4431a6e7c305fd08732458f7f885e7e.tar.gz vyos-strongswan-15fb7904f4431a6e7c305fd08732458f7f885e7e.zip |
Imported Upstream version 5.1.2
Diffstat (limited to 'src/libpts')
26 files changed, 514 insertions, 305 deletions
diff --git a/src/libpts/Makefile.in b/src/libpts/Makefile.in index a9b3f19ef..05c27d9cb 100644 --- a/src/libpts/Makefile.in +++ b/src/libpts/Makefile.in @@ -293,8 +293,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@ @@ -362,6 +360,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@ @@ -450,12 +453,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@ @@ -470,6 +477,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/imc_attestation/Makefile.in b/src/libpts/plugins/imc_attestation/Makefile.in index 2d9279119..7a539ef22 100644 --- a/src/libpts/plugins/imc_attestation/Makefile.in +++ b/src/libpts/plugins/imc_attestation/Makefile.in @@ -217,8 +217,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@ @@ -286,6 +284,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@ @@ -374,12 +377,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@ @@ -394,6 +401,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/imc_attestation/imc_attestation_process.c b/src/libpts/plugins/imc_attestation/imc_attestation_process.c index 92e2e3abe..fbe81ee48 100644 --- a/src/libpts/plugins/imc_attestation/imc_attestation_process.c +++ b/src/libpts/plugins/imc_attestation/imc_attestation_process.c @@ -109,8 +109,8 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, imc_msg_t *msg, int nonce_len, min_nonce_len; nonce_len = lib->settings->get_int(lib->settings, - "libimcv.plugins.imc-attestation.nonce_len", - DEFAULT_NONCE_LEN); + "%s.plugins.imc-attestation.nonce_len", + DEFAULT_NONCE_LEN, lib->ns); attr_cast = (tcg_pts_attr_dh_nonce_params_req_t*)attr; min_nonce_len = attr_cast->get_min_nonce_len(attr_cast); @@ -165,8 +165,8 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, imc_msg_t *msg, initiator_nonce = attr_cast->get_initiator_nonce(attr_cast); nonce_len = lib->settings->get_int(lib->settings, - "libimcv.plugins.imc-attestation.nonce_len", - DEFAULT_NONCE_LEN); + "%s.plugins.imc-attestation.nonce_len", + DEFAULT_NONCE_LEN, lib->ns); if (nonce_len != initiator_nonce.len) { DBG1(DBG_IMC, "initiator and responder DH nonces " @@ -428,7 +428,8 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, imc_msg_t *msg, } use_quote2 = lib->settings->get_bool(lib->settings, - "libimcv.plugins.imc-attestation.use_quote2", TRUE); + "%s.plugins.imc-attestation.use_quote2", TRUE, + lib->ns); if (!pts->quote_tpm(pts, use_quote2, &pcr_composite, "e_sig)) { DBG1(DBG_IMC, "error occurred during TPM quote operation"); diff --git a/src/libpts/plugins/imc_swid/Makefile.in b/src/libpts/plugins/imc_swid/Makefile.in index f62c05a3e..e1c932e45 100644 --- a/src/libpts/plugins/imc_swid/Makefile.in +++ b/src/libpts/plugins/imc_swid/Makefile.in @@ -217,8 +217,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@ @@ -286,6 +284,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@ @@ -374,12 +377,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@ @@ -394,6 +401,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/imc_swid/imc_swid.c b/src/libpts/plugins/imc_swid/imc_swid.c index e1305805a..d4aaeff4d 100644 --- a/src/libpts/plugins/imc_swid/imc_swid.c +++ b/src/libpts/plugins/imc_swid/imc_swid.c @@ -181,8 +181,8 @@ static TNC_Result receive_message(imc_state_t *state, imc_msg_t *in_msg) full_tags = (flags & TCG_SWID_ATTR_REQ_FLAG_R) == 0; swid_directory = lib->settings->get_str(lib->settings, - "libimcv.plugins.imc-swid.swid_directory", - SWID_DIRECTORY); + "%s.plugins.imc-swid.swid_directory", + SWID_DIRECTORY, lib->ns); swid_inventory = swid_inventory_create(full_tags); if (!swid_inventory->collect(swid_inventory, swid_directory, targets)) { 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); }; /** diff --git a/src/libpts/plugins/imv_swid/Makefile.in b/src/libpts/plugins/imv_swid/Makefile.in index 852cd3d04..b92f7d4d0 100644 --- a/src/libpts/plugins/imv_swid/Makefile.in +++ b/src/libpts/plugins/imv_swid/Makefile.in @@ -215,8 +215,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@ @@ -284,6 +282,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@ @@ -372,12 +375,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@ @@ -392,6 +399,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/pts/components/ita/ita_comp_ima.c b/src/libpts/pts/components/ita/ita_comp_ima.c index 02470f5f5..c6b4131bf 100644 --- a/src/libpts/pts/components/ita/ita_comp_ima.c +++ b/src/libpts/pts/components/ita/ita_comp_ima.c @@ -683,7 +683,7 @@ METHOD(pts_component_t, verify, status_t, status = this->pts_db->check_comp_measurement(this->pts_db, measurement, this->bios_cid, this->kid, ++this->seq_no, pcr, algo); - if (status != SUCCESS) + if (status == FAILED) { return status; } @@ -803,7 +803,7 @@ METHOD(pts_component_t, verify, status_t, } if (pcrs->set(pcrs, pcr, pcr_after)) { - return SUCCESS; + return status; } } else @@ -811,7 +811,7 @@ METHOD(pts_component_t, verify, status_t, pcr_after = pcrs->extend(pcrs, pcr, measurement); if (pcr_after.ptr) { - return SUCCESS; + return status; } } return FAILED; @@ -951,7 +951,7 @@ pts_component_t *pts_ita_comp_ima_create(u_int32_t depth, .bios_list = linked_list_create(), .ima_list = linked_list_create(), .pcr_info = lib->settings->get_bool(lib->settings, - "libimcv.plugins.imc-attestation.pcr_info", TRUE), + "%s.plugins.imc-attestation.pcr_info", TRUE, lib->ns), .ref = 1, ); diff --git a/src/libpts/pts/components/ita/ita_comp_tboot.c b/src/libpts/pts/components/ita/ita_comp_tboot.c index 8fb5abddf..f4859f801 100644 --- a/src/libpts/pts/components/ita/ita_comp_tboot.c +++ b/src/libpts/pts/components/ita/ita_comp_tboot.c @@ -130,21 +130,21 @@ METHOD(pts_component_t, measure, status_t, /* dummy data since currently the TBOOT log is not retrieved */ time(&this->measurement_time); meas_hex = lib->settings->get_str(lib->settings, - "libimcv.plugins.imc-attestation.pcr17_meas", NULL); + "%s.plugins.imc-attestation.pcr17_meas", NULL, lib->ns); pcr_before_hex = lib->settings->get_str(lib->settings, - "libimcv.plugins.imc-attestation.pcr17_before", NULL); + "%s.plugins.imc-attestation.pcr17_before", NULL, lib->ns); pcr_after_hex = lib->settings->get_str(lib->settings, - "libimcv.plugins.imc-attestation.pcr17_after", NULL); + "%s.plugins.imc-attestation.pcr17_after", NULL, lib->ns); extended_pcr = PCR_TBOOT_POLICY; break; case 1: /* dummy data since currently the TBOOT log is not retrieved */ meas_hex = lib->settings->get_str(lib->settings, - "libimcv.plugins.imc-attestation.pcr18_meas", NULL); + "%s.plugins.imc-attestation.pcr18_meas", NULL, lib->ns); pcr_before_hex = lib->settings->get_str(lib->settings, - "libimcv.plugins.imc-attestation.pcr18_before", NULL); + "%s.plugins.imc-attestation.pcr18_before", NULL, lib->ns); pcr_after_hex = lib->settings->get_str(lib->settings, - "libimcv.plugins.imc-attestation.pcr18_after", NULL); + "%s.plugins.imc-attestation.pcr18_after", NULL, lib->ns); extended_pcr = PCR_TBOOT_MLE; break; default: diff --git a/src/libpts/pts/pts.c b/src/libpts/pts/pts.c index f646d67e1..8699282f0 100644 --- a/src/libpts/pts/pts.c +++ b/src/libpts/pts/pts.c @@ -377,7 +377,7 @@ static void load_aik_blob(private_pts_t *this) u_int32_t aikBlobLen; blob_path = lib->settings->get_str(lib->settings, - "libimcv.plugins.imc-attestation.aik_blob", NULL); + "%s.plugins.imc-attestation.aik_blob", NULL, lib->ns); if (blob_path) { @@ -418,9 +418,9 @@ static void load_aik(private_pts_t *this) char *cert_path, *key_path; cert_path = lib->settings->get_str(lib->settings, - "libimcv.plugins.imc-attestation.aik_cert", NULL); + "%s.plugins.imc-attestation.aik_cert", NULL, lib->ns); key_path = lib->settings->get_str(lib->settings, - "libimcv.plugins.imc-attestation.aik_key", NULL); + "%s.plugins.imc-attestation.aik_key", NULL, lib->ns); if (cert_path) { @@ -627,7 +627,7 @@ METHOD(pts_t, get_metadata, pts_file_meta_t*, metadata->destroy(metadata); return NULL; } - entry->filename = strdup(basename(pathname)); + entry->filename = path_basename(pathname); metadata->add(metadata, entry); } diff --git a/src/libpts/pts/pts_database.c b/src/libpts/pts/pts_database.c index e5a06cc8d..07e8ae1da 100644 --- a/src/libpts/pts/pts_database.c +++ b/src/libpts/pts/pts_database.c @@ -15,6 +15,7 @@ #define _GNU_SOURCE #include <stdio.h> +#include <libgen.h> #include "pts_database.h" @@ -248,13 +249,62 @@ METHOD(pts_database_t, check_file_measurement, status_t, enumerator_t *e; chunk_t hash; status_t status = NOT_FOUND; + char *dir, *file; + + if (strlen(filename) < 1) + { + return INVALID_ARG; + } + + /* separate filename into directory and basename components */ + dir = path_dirname(filename); + file = path_basename(filename); + + if (*dir == '.') + { /* relative pathname */ + e = this->db->query(this->db, + "SELECT fh.hash FROM file_hashes AS fh " + "JOIN files AS f ON f.id = fh.file " + "JOIN products AS p ON p.id = fh.product " + "WHERE p.name = ? AND f.name = ? AND fh.algo = ?", + DB_TEXT, product, DB_TEXT, file, DB_INT, algo, DB_BLOB); + } + else + { /* absolute pathname */ + bool dir_found; + int did; + + /* find directory entry first */ + e = this->db->query(this->db, + "SELECT id FROM directories WHERE path = ?", + DB_TEXT, dir, DB_INT); + if (!e) + { + free(file); + free(dir); + return FAILED; + } + dir_found = e->enumerate(e, &did); + e->destroy(e); + + if (!dir_found) + { + free(file); + free(dir); + return NOT_FOUND; + } + + e = this->db->query(this->db, + "SELECT fh.hash FROM file_hashes AS fh " + "JOIN files AS f ON f.id = fh.file " + "JOIN products AS p ON p.id = fh.product " + "WHERE p.name = ? AND f.dir = ? AND f.name = ? AND fh.algo = ?", + DB_TEXT, product, DB_INT, did, DB_TEXT, file, DB_INT, algo, + DB_BLOB); + } + free(file); + free(dir); - e = this->db->query(this->db, - "SELECT fh.hash FROM file_hashes AS fh " - "JOIN files AS f ON f.id = fh.file " - "JOIN products AS p ON p.id = fh.product " - "WHERE p.name = ? AND f.path = ? AND fh.algo = ?", - DB_TEXT, product, DB_TEXT, filename, DB_INT, algo, DB_BLOB); if (!e) { return FAILED; diff --git a/src/libpts/pts/pts_file_meas.c b/src/libpts/pts/pts_file_meas.c index f684087d7..77a0957bb 100644 --- a/src/libpts/pts/pts_file_meas.c +++ b/src/libpts/pts/pts_file_meas.c @@ -341,9 +341,10 @@ pts_file_meas_t *pts_file_meas_create_from_path(u_int16_t request_id, success = FALSE; goto end; } - filename = use_rel_name ? basename(pathname) : pathname; + filename = use_rel_name ? path_basename(pathname) : strdup(pathname); DBG2(DBG_PTS, " %#B for '%s'", &measurement, filename); add(this, filename, measurement); + free(filename); } end: diff --git a/src/libpts/swid/swid_inventory.c b/src/libpts/swid/swid_inventory.c index a689ccdaa..a71682f43 100644 --- a/src/libpts/swid/swid_inventory.c +++ b/src/libpts/swid/swid_inventory.c @@ -24,7 +24,6 @@ #include <fcntl.h> #include <unistd.h> #include <sys/stat.h> -#include <sys/mman.h> #include <libgen.h> #include <errno.h> @@ -178,40 +177,19 @@ static bool collect_tags(private_swid_inventory_t *this, char *pathname, if (this->full_tags) { swid_tag_t *tag; - chunk_t xml_tag; - struct stat sb; - void *addr; - int fd; + chunk_t *xml_tag; - fd = open(abs_name, O_RDONLY); - if (fd == -1) + xml_tag = chunk_map(abs_name, FALSE); + if (!xml_tag) { DBG1(DBG_IMC, " opening '%s' failed: %s", abs_name, strerror(errno)); goto end; } - if (fstat(fd, &sb) == -1) - { - DBG1(DBG_IMC, " getting file size of '%s' failed: %s", abs_name, - strerror(errno)); - close(fd); - goto end; - } - - addr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0); - if (addr == MAP_FAILED) - { - DBG1(DBG_IMC, " mapping '%s' failed: %s", abs_name, - strerror(errno)); - close(fd); - goto end; - } - xml_tag = chunk_create(addr, sb.st_size); - tag = swid_tag_create(xml_tag, unique_seq_id); + tag = swid_tag_create(*xml_tag, unique_seq_id); this->list->insert_last(this->list, tag); - munmap(addr, sb.st_size); - close(fd); + chunk_unmap(xml_tag); } else { @@ -290,5 +268,3 @@ swid_inventory_t *swid_inventory_create(bool full_tags) return &this->public; } - - diff --git a/src/libpts/tcg/pts/tcg_pts_attr_req_file_meas.c b/src/libpts/tcg/pts/tcg_pts_attr_req_file_meas.c index f0bc7cf60..c5a2f4b8a 100644 --- a/src/libpts/tcg/pts/tcg_pts_attr_req_file_meas.c +++ b/src/libpts/tcg/pts/tcg_pts_attr_req_file_meas.c @@ -13,6 +13,9 @@ * for more details. */ +#define _GNU_SOURCE /* for stdndup() */ +#include <string.h> + #include "tcg_pts_attr_req_file_meas.h" #include <pa_tnc/pa_tnc_msg.h> @@ -20,8 +23,6 @@ #include <bio/bio_reader.h> #include <utils/debug.h> -#include <string.h> - typedef struct private_tcg_pts_attr_req_file_meas_t private_tcg_pts_attr_req_file_meas_t; /** diff --git a/src/libpts/tcg/pts/tcg_pts_attr_req_file_meta.c b/src/libpts/tcg/pts/tcg_pts_attr_req_file_meta.c index e475cd35b..8d703af65 100644 --- a/src/libpts/tcg/pts/tcg_pts_attr_req_file_meta.c +++ b/src/libpts/tcg/pts/tcg_pts_attr_req_file_meta.c @@ -13,6 +13,9 @@ * for more details. */ +#define _GNU_SOURCE /* for stdndup() */ +#include <string.h> + #include "tcg_pts_attr_req_file_meta.h" #include <pa_tnc/pa_tnc_msg.h> @@ -20,8 +23,6 @@ #include <bio/bio_reader.h> #include <utils/debug.h> -#include <string.h> - typedef struct private_tcg_pts_attr_req_file_meta_t private_tcg_pts_attr_req_file_meta_t; /** diff --git a/src/libpts/tcg/pts/tcg_pts_attr_req_func_comp_evid.c b/src/libpts/tcg/pts/tcg_pts_attr_req_func_comp_evid.c index 5249fa2ad..e10845bbb 100644 --- a/src/libpts/tcg/pts/tcg_pts_attr_req_func_comp_evid.c +++ b/src/libpts/tcg/pts/tcg_pts_attr_req_func_comp_evid.c @@ -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); } diff --git a/src/libpts/tcg/pts/tcg_pts_attr_unix_file_meta.c b/src/libpts/tcg/pts/tcg_pts_attr_unix_file_meta.c index f96371b8b..eff64c229 100644 --- a/src/libpts/tcg/pts/tcg_pts_attr_unix_file_meta.c +++ b/src/libpts/tcg/pts/tcg_pts_attr_unix_file_meta.c @@ -13,6 +13,9 @@ * for more details. */ +#define _GNU_SOURCE /* for stdndup() */ +#include <string.h> + #include "tcg_pts_attr_unix_file_meta.h" #include <pa_tnc/pa_tnc_msg.h> @@ -21,8 +24,6 @@ #include <collections/linked_list.h> #include <utils/debug.h> -#include <string.h> - typedef struct private_tcg_pts_attr_file_meta_t private_tcg_pts_attr_file_meta_t; /** |