From: Andreas Steffen Date: Fri, 10 Jan 2014 10:53:50 +0000 (+0100) Subject: Do TPM measurements only if there is a TPMRA workitem X-Git-Tag: 5.1.2dr3~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fbddf52c803eaa61cef4f61c7a0db1626308fd56;p=thirdparty%2Fstrongswan.git Do TPM measurements only if there is a TPMRA workitem --- diff --git a/src/libpts/plugins/imv_attestation/imv_attestation_agent.c b/src/libpts/plugins/imv_attestation/imv_attestation_agent.c index fbfde3e8ec..74e903c406 100644 --- a/src/libpts/plugins/imv_attestation/imv_attestation_agent.c +++ b/src/libpts/plugins/imv_attestation/imv_attestation_agent.c @@ -33,8 +33,11 @@ #include #include #include +#include #include +#include +#include #include #include @@ -289,6 +292,7 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result, imv_state_t *state; imv_session_t *session; imv_attestation_state_t *attestation_state; + imv_attestation_handshake_state_t handshake_state; TNC_IMVID imv_id; TNC_Result result = TNC_RESULT_SUCCESS; pts_t *pts; @@ -300,6 +304,7 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result, } attestation_state = (imv_attestation_state_t*)state; pts = attestation_state->get_pts(attestation_state); + handshake_state = attestation_state->get_handshake_state(attestation_state); platform_info = pts->get_platform_info(pts); session = state->get_session(state); imv_id = this->agent->get_id(this->agent); @@ -340,6 +345,26 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result, out_msg = imv_msg_create(this->agent, state, id, imv_id, TNC_IMCID_ANY, msg_types[0]); + if (handshake_state == IMV_ATTESTATION_STATE_INIT) + { + pa_tnc_attr_t *attr; + pts_proto_caps_flag_t flags; + + /* Send Request Protocol Capabilities attribute */ + flags = pts->get_proto_caps(pts); + attr = tcg_pts_attr_proto_caps_create(flags, TRUE); + attr->set_noskip_flag(attr, TRUE); + out_msg->add_attribute(out_msg, attr); + + /* Send Measurement Algorithms attribute */ + attr = tcg_pts_attr_meas_algo_create(this->supported_algorithms, FALSE); + attr->set_noskip_flag(attr, TRUE); + out_msg->add_attribute(out_msg, attr); + + attestation_state->set_handshake_state(attestation_state, + IMV_ATTESTATION_STATE_DISCOVERY); + } + if (platform_info && session && (state->get_action_flags(state) & IMV_ATTESTATION_FLAG_ALGO) && !(state->get_action_flags(state) & IMV_ATTESTATION_FLAG_FILE_MEAS)) @@ -352,6 +377,9 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result, char *pathname; enumerator_t *enumerator; + attestation_state->set_handshake_state(attestation_state, + IMV_ATTESTATION_STATE_END); + enumerator = session->create_workitem_enumerator(session); if (enumerator) { @@ -376,6 +404,8 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result, break; case IMV_WORKITEM_TPM_ATTEST: { + pts_component_t *comp; + pts_comp_func_name_t *comp_name; TNC_IMV_Action_Recommendation rec; TNC_IMV_Evaluation_Result eval; bool no_d_flag, no_t_flag; @@ -397,7 +427,45 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result, state->update_recommendation(state, rec, eval); imcv_db->finalize_workitem(imcv_db, workitem); workitem->destroy(workitem); + continue; } + + /* do TPM BIOS measurements */ + if (strchr(workitem->get_arg_str(workitem), 'B')) + { + comp_name = pts_comp_func_name_create(PEN_ITA, + PTS_ITA_COMP_FUNC_NAME_IMA, + PTS_ITA_QUALIFIER_FLAG_KERNEL | + PTS_ITA_QUALIFIER_TYPE_TRUSTED); + comp = attestation_state->create_component( + attestation_state, comp_name, + 0, this->pts_db); + if (!comp) + { + comp_name->log(comp_name, "unregistered "); + comp_name->destroy(comp_name); + } + } + + /* do TPM IMA measurements */ + if (strchr(workitem->get_arg_str(workitem), 'I')) + { + comp_name = pts_comp_func_name_create(PEN_ITA, + PTS_ITA_COMP_FUNC_NAME_IMA, + PTS_ITA_QUALIFIER_FLAG_KERNEL | + PTS_ITA_QUALIFIER_TYPE_OS); + comp = attestation_state->create_component( + attestation_state, comp_name, + 0, this->pts_db); + if (!comp) + { + comp_name->log(comp_name, "unregistered "); + comp_name->destroy(comp_name); + } + } + + attestation_state->set_handshake_state(attestation_state, + IMV_ATTESTATION_STATE_NONCE_REQ); continue; } default: @@ -467,8 +535,8 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result, } /* check the IMV state for the next PA-TNC attributes to send */ - if (!imv_attestation_build(out_msg, state, this->supported_algorithms, - this->supported_dh_groups, this->pts_db)) + if (!imv_attestation_build(out_msg, state, this->supported_dh_groups, + this->pts_db)) { state->set_recommendation(state, TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION, diff --git a/src/libpts/plugins/imv_attestation/imv_attestation_build.c b/src/libpts/plugins/imv_attestation/imv_attestation_build.c index 1fbde2c6dc..a0d1765f50 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 -#include #include #include #include @@ -27,9 +26,7 @@ #include -bool imv_attestation_build(imv_msg_t *out_msg, - imv_state_t *state, - pts_meas_algorithms_t supported_algorithms, +bool imv_attestation_build(imv_msg_t *out_msg, imv_state_t *state, pts_dh_group_t supported_dh_groups, pts_database_t *pts_db) { @@ -42,60 +39,8 @@ bool imv_attestation_build(imv_msg_t *out_msg, handshake_state = attestation_state->get_handshake_state(attestation_state); pts = attestation_state->get_pts(attestation_state); - /** - * Received a response form the Attestation IMC so we can proceeed - */ - if (handshake_state == IMV_ATTESTATION_STATE_DISCOVERY && - (state->get_action_flags(state) & IMV_ATTESTATION_FLAG_ALGO)) - { - handshake_state = IMV_ATTESTATION_STATE_NONCE_REQ; - } - - /** - * Skip DH Nonce Parameters Request attribute when - * DH Nonce Exchange is not selected by PTS-IMC side - */ - if (handshake_state == IMV_ATTESTATION_STATE_NONCE_REQ && - !(pts->get_proto_caps(pts) & PTS_PROTO_CAPS_D)) - { - DBG2(DBG_IMV, "PTS-IMC does not support DH Nonce negotiation"); - handshake_state = IMV_ATTESTATION_STATE_TPM_INIT; - } - - /** - * Skip TPM Version Info and AIK attributes when - * no TPM is available on the PTS-IMC side - */ - if (handshake_state == IMV_ATTESTATION_STATE_TPM_INIT && - !(pts->get_proto_caps(pts) & PTS_PROTO_CAPS_T)) - { - DBG2(DBG_IMV, "PTS-IMC made no TPM available"); - handshake_state = IMV_ATTESTATION_STATE_END; - } - switch (handshake_state) { - case IMV_ATTESTATION_STATE_INIT: - { - pts_proto_caps_flag_t flags; - - /* Send Request Protocol Capabilities attribute */ - flags = pts->get_proto_caps(pts); - attr = tcg_pts_attr_proto_caps_create(flags, TRUE); - attr->set_noskip_flag(attr, TRUE); - out_msg->add_attribute(out_msg, attr); - - /* Send Measurement Algorithms attribute */ - attr = tcg_pts_attr_meas_algo_create(supported_algorithms, FALSE); - attr->set_noskip_flag(attr, TRUE); - out_msg->add_attribute(out_msg, attr); - - attestation_state->set_handshake_state(attestation_state, - IMV_ATTESTATION_STATE_DISCOVERY); - break; - } - case IMV_ATTESTATION_STATE_DISCOVERY: - break; case IMV_ATTESTATION_STATE_NONCE_REQ: { int min_nonce_len; @@ -117,16 +62,13 @@ bool imv_attestation_build(imv_msg_t *out_msg, pts_meas_algorithms_t selected_algorithm; chunk_t initiator_value, initiator_nonce; - if ((pts->get_proto_caps(pts) & PTS_PROTO_CAPS_D)) - { - /* Send DH nonce finish attribute */ - selected_algorithm = pts->get_meas_algorithm(pts); - pts->get_my_public_value(pts, &initiator_value, &initiator_nonce); - attr = tcg_pts_attr_dh_nonce_finish_create(selected_algorithm, + /* Send DH nonce finish attribute */ + selected_algorithm = pts->get_meas_algorithm(pts); + pts->get_my_public_value(pts, &initiator_value, &initiator_nonce); + attr = tcg_pts_attr_dh_nonce_finish_create(selected_algorithm, initiator_value, initiator_nonce); - attr->set_noskip_flag(attr, TRUE); - out_msg->add_attribute(out_msg, attr); - } + attr->set_noskip_flag(attr, TRUE); + out_msg->add_attribute(out_msg, attr); /* Send Get TPM Version attribute */ attr = tcg_pts_attr_get_tpm_version_info_create(); @@ -146,24 +88,16 @@ bool imv_attestation_build(imv_msg_t *out_msg, { tcg_pts_attr_req_func_comp_evid_t *attr_cast; enumerator_t *enumerator; - pts_component_t *comp; - pts_comp_func_name_t *comp_name; + pts_comp_func_name_t *name; chunk_t keyid; - int kid, vid, name, qualifier; + int kid; u_int8_t flags; u_int32_t depth; - bool first = TRUE, first_component = TRUE; + bool first_component = TRUE; attestation_state->set_handshake_state(attestation_state, IMV_ATTESTATION_STATE_END); - if (!(pts->get_proto_caps(pts) & PTS_PROTO_CAPS_T) || - !(pts->get_proto_caps(pts) & PTS_PROTO_CAPS_D)) - { - DBG2(DBG_IMV, "PTS-IMC made no TPM available - " - "skipping Component Measurements"); - break; - } if (!pts->get_aik_keyid(pts, &keyid)) { DBG1(DBG_IMV, "retrieval of AIK keyid failed"); @@ -178,41 +112,22 @@ bool imv_attestation_build(imv_msg_t *out_msg, { return FALSE; } - enumerator = pts_db->create_comp_evid_enumerator(pts_db, kid); - if (!enumerator) - { - break; - } - while (enumerator->enumerate(enumerator, &vid, &name, - &qualifier, &depth)) + enumerator = attestation_state->create_component_enumerator( + attestation_state); + while (enumerator->enumerate(enumerator, &flags, &depth, &name)) { - if (first) - { - DBG2(DBG_IMV, "evidence request by"); - first = FALSE; - } - comp_name = pts_comp_func_name_create(vid, name, qualifier); - comp_name->log(comp_name, " "); - - comp = attestation_state->create_component(attestation_state, - comp_name, depth, pts_db); - if (!comp) - { - DBG2(DBG_IMV, " not registered or duplicate" - " - removed from request"); - comp_name->destroy(comp_name); - continue; - } if (first_component) { attr = tcg_pts_attr_req_func_comp_evid_create(); attr->set_noskip_flag(attr, TRUE); first_component = FALSE; + DBG2(DBG_IMV, "evidence request by"); } - flags = comp->get_evidence_flags(comp); + name->log(name, " "); + /* TODO check flags against negotiated_caps */ attr_cast = (tcg_pts_attr_req_func_comp_evid_t *)attr; - attr_cast->add_component(attr_cast, flags, depth, comp_name); + attr_cast->add_component(attr_cast, flags, depth, name); } enumerator->destroy(enumerator); @@ -238,9 +153,7 @@ bool imv_attestation_build(imv_msg_t *out_msg, IMV_ATTESTATION_STATE_END); } break; - case IMV_ATTESTATION_STATE_END: - attestation_state->set_handshake_state(attestation_state, - IMV_ATTESTATION_STATE_END); + default: break; } return TRUE; diff --git a/src/libpts/plugins/imv_attestation/imv_attestation_build.h b/src/libpts/plugins/imv_attestation/imv_attestation_build.h index 0cee49b344..88538b1989 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 bd1109a1b0..9422cf47f9 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 @@ -381,9 +382,6 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg, status = comp->verify(comp, name->get_qualifier(name), pts, evidence); if (status == VERIFY_ERROR || status == FAILED) { - state->update_recommendation(state, - TNC_IMV_ACTION_RECOMMENDATION_ISOLATE, - TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR); attestation_state->set_measurement_error(attestation_state, IMV_ATTESTATION_ERROR_COMP_EVID_FAIL); name->log(name, " measurement mismatch for "); diff --git a/src/libpts/plugins/imv_attestation/imv_attestation_state.c b/src/libpts/plugins/imv_attestation/imv_attestation_state.c index 200de1e191..c2adbf5192 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); } @@ -396,13 +397,13 @@ METHOD(imv_attestation_state_t, create_component, pts_component_t*, if (found) { - if (name->get_qualifier(name) == entry->qualifier) + if (name->equals(name, entry->name)) { /* duplicate entry */ return NULL; } new_entry = malloc_thing(func_comp_t); - new_entry->qualifier = name->get_qualifier(name); + new_entry->name = name->clone(name); new_entry->comp = entry->comp->get_ref(entry->comp); this->components->insert_last(this->components, new_entry); return entry->comp; @@ -416,13 +417,41 @@ METHOD(imv_attestation_state_t, create_component, pts_component_t*, return NULL; } new_entry = malloc_thing(func_comp_t); - new_entry->qualifier = name->get_qualifier(name); + new_entry->name = name->clone(name); new_entry->comp = component; this->components->insert_last(this->components, new_entry); return component; } } +/** + * Enumerate file measurement entries + */ +static bool entry_filter(void *null, func_comp_t **entry, u_int8_t *flags, + void *i2, u_int32_t *depth, + void *i3, pts_comp_func_name_t **comp_name) +{ + pts_component_t *comp; + pts_comp_func_name_t *name; + + comp = (*entry)->comp; + name = (*entry)->name; + + *flags = comp->get_evidence_flags(comp); + *depth = comp->get_depth(comp); + *comp_name = name; + + return TRUE; +} + +METHOD(imv_attestation_state_t, create_component_enumerator, enumerator_t*, + private_imv_attestation_state_t *this) +{ + return enumerator_create_filter( + this->components->create_enumerator(this->components), + (void*)entry_filter, NULL, NULL); +} + METHOD(imv_attestation_state_t, get_component, pts_component_t*, private_imv_attestation_state_t *this, pts_comp_func_name_t *name) { @@ -433,8 +462,7 @@ METHOD(imv_attestation_state_t, get_component, pts_component_t*, enumerator = this->components->create_enumerator(this->components); while (enumerator->enumerate(enumerator, &entry)) { - if (name->equals(name, entry->comp->get_comp_func_name(entry->comp)) && - name->get_qualifier(name) == entry->qualifier) + if (name->equals(name, entry->name)) { found = entry->comp; break; @@ -464,7 +492,8 @@ METHOD(imv_attestation_state_t, finalize_components, void, while (this->components->remove_last(this->components, (void**)&entry) == SUCCESS) { - if (!entry->comp->finalize(entry->comp, entry->qualifier)) + if (!entry->comp->finalize(entry->comp, + entry->name->get_qualifier(entry->name))) { set_measurement_error(this, IMV_ATTESTATION_ERROR_COMP_EVID_PEND); } @@ -512,6 +541,7 @@ imv_state_t *imv_attestation_state_create(TNC_ConnectionID connection_id) .set_handshake_state = _set_handshake_state, .get_pts = _get_pts, .create_component = _create_component, + .create_component_enumerator = _create_component_enumerator, .get_component = _get_component, .finalize_components = _finalize_components, .components_finalized = _components_finalized, diff --git a/src/libpts/plugins/imv_attestation/imv_attestation_state.h b/src/libpts/plugins/imv_attestation/imv_attestation_state.h index 6ee9ed11e3..3636b5656c 100644 --- a/src/libpts/plugins/imv_attestation/imv_attestation_state.h +++ b/src/libpts/plugins/imv_attestation/imv_attestation_state.h @@ -116,6 +116,13 @@ struct imv_attestation_state_t { u_int32_t depth, pts_database_t *pts_db); + /** + * Enumerate over all Functional Components + * + * @return Functional Component enumerator + */ + enumerator_t* (*create_component_enumerator)(imv_attestation_state_t *this); + /** * Get a Functional Component with a given name * 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 5249fa2ad6..e10845bbbe 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); }