Do TPM measurements only if there is a TPMRA workitem
authorAndreas Steffen <andreas.steffen@strongswan.org>
Fri, 10 Jan 2014 10:53:50 +0000 (11:53 +0100)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Mon, 13 Jan 2014 11:06:18 +0000 (12:06 +0100)
src/libpts/plugins/imv_attestation/imv_attestation_agent.c
src/libpts/plugins/imv_attestation/imv_attestation_build.c
src/libpts/plugins/imv_attestation/imv_attestation_build.h
src/libpts/plugins/imv_attestation/imv_attestation_process.c
src/libpts/plugins/imv_attestation/imv_attestation_state.c
src/libpts/plugins/imv_attestation/imv_attestation_state.h
src/libpts/tcg/pts/tcg_pts_attr_req_func_comp_evid.c

index fbfde3e..74e903c 100644 (file)
 #include <pts/pts.h>
 #include <pts/pts_database.h>
 #include <pts/pts_creds.h>
+#include <pts/components/ita/ita_comp_func_name.h>
 
 #include <tcg/tcg_attr.h>
+#include <tcg/pts/tcg_pts_attr_meas_algo.h>
+#include <tcg/pts/tcg_pts_attr_proto_caps.h>
 #include <tcg/pts/tcg_pts_attr_req_file_meas.h>
 #include <tcg/pts/tcg_pts_attr_req_file_meta.h>
 
@@ -289,6 +292,7 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
        imv_state_t *state;
        imv_session_t *session;
        imv_attestation_state_t *attestation_state;
+       imv_attestation_handshake_state_t handshake_state;
        TNC_IMVID imv_id;
        TNC_Result result = TNC_RESULT_SUCCESS;
        pts_t *pts;
@@ -300,6 +304,7 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
        }
        attestation_state = (imv_attestation_state_t*)state;
        pts = attestation_state->get_pts(attestation_state);
+       handshake_state = attestation_state->get_handshake_state(attestation_state);
        platform_info = pts->get_platform_info(pts);
        session = state->get_session(state);
        imv_id = this->agent->get_id(this->agent);
@@ -340,6 +345,26 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
        out_msg = imv_msg_create(this->agent, state, id, imv_id, TNC_IMCID_ANY,
                                                         msg_types[0]);
 
+       if (handshake_state == IMV_ATTESTATION_STATE_INIT)
+       {
+               pa_tnc_attr_t *attr;
+               pts_proto_caps_flag_t flags;
+
+               /* Send Request Protocol Capabilities attribute */
+               flags = pts->get_proto_caps(pts);
+               attr = tcg_pts_attr_proto_caps_create(flags, TRUE);
+               attr->set_noskip_flag(attr, TRUE);
+               out_msg->add_attribute(out_msg, attr);
+
+               /* Send Measurement Algorithms attribute */
+               attr = tcg_pts_attr_meas_algo_create(this->supported_algorithms, FALSE);
+               attr->set_noskip_flag(attr, TRUE);
+               out_msg->add_attribute(out_msg, attr);
+
+               attestation_state->set_handshake_state(attestation_state,
+                                                                               IMV_ATTESTATION_STATE_DISCOVERY);
+       }
+
        if (platform_info && session &&
           (state->get_action_flags(state) & IMV_ATTESTATION_FLAG_ALGO) &&
          !(state->get_action_flags(state) & IMV_ATTESTATION_FLAG_FILE_MEAS))
@@ -352,6 +377,9 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
                char *pathname;
                enumerator_t *enumerator;
 
+               attestation_state->set_handshake_state(attestation_state,
+                                                                                          IMV_ATTESTATION_STATE_END);
+
                enumerator = session->create_workitem_enumerator(session);
                if (enumerator)
                {
@@ -376,6 +404,8 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
                                                break;
                                        case IMV_WORKITEM_TPM_ATTEST:
                                        {
+                                               pts_component_t *comp;
+                                               pts_comp_func_name_t *comp_name;
                                                TNC_IMV_Action_Recommendation rec;
                                                TNC_IMV_Evaluation_Result eval;
                                                bool no_d_flag, no_t_flag;
@@ -397,7 +427,45 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
                                                        state->update_recommendation(state, rec, eval);
                                                        imcv_db->finalize_workitem(imcv_db, workitem);
                                                        workitem->destroy(workitem);
+                                                       continue;
                                                }
+
+                                               /* do TPM BIOS measurements */
+                                               if (strchr(workitem->get_arg_str(workitem), 'B'))
+                                               {
+                                                       comp_name = pts_comp_func_name_create(PEN_ITA,
+                                                                                       PTS_ITA_COMP_FUNC_NAME_IMA,
+                                                                                       PTS_ITA_QUALIFIER_FLAG_KERNEL |
+                                                                                       PTS_ITA_QUALIFIER_TYPE_TRUSTED);
+                                                       comp = attestation_state->create_component(
+                                                                                       attestation_state, comp_name,
+                                                                                       0, this->pts_db);
+                                                       if (!comp)
+                                                       {
+                                                               comp_name->log(comp_name, "unregistered ");
+                                                               comp_name->destroy(comp_name);
+                                                       }
+                                               }
+
+                                               /* do TPM IMA measurements */
+                                               if (strchr(workitem->get_arg_str(workitem), 'I'))
+                                               {
+                                                       comp_name = pts_comp_func_name_create(PEN_ITA,
+                                                                                       PTS_ITA_COMP_FUNC_NAME_IMA,
+                                                                                       PTS_ITA_QUALIFIER_FLAG_KERNEL |
+                                                                                       PTS_ITA_QUALIFIER_TYPE_OS);
+                                                       comp = attestation_state->create_component(
+                                                                                       attestation_state, comp_name,
+                                                                                       0, this->pts_db);
+                                                       if (!comp)
+                                                       {
+                                                               comp_name->log(comp_name, "unregistered ");
+                                                               comp_name->destroy(comp_name);
+                                                       }
+                                               }
+
+                                               attestation_state->set_handshake_state(attestation_state,
+                                                                                       IMV_ATTESTATION_STATE_NONCE_REQ);
                                                continue;
                                        }
                                        default:
@@ -467,8 +535,8 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
        }
 
        /* check the IMV state for the next PA-TNC attributes to send */
-       if (!imv_attestation_build(out_msg, state, this->supported_algorithms,
-                                                          this->supported_dh_groups, this->pts_db))
+       if (!imv_attestation_build(out_msg, state, this->supported_dh_groups,
+                                                          this->pts_db))
        {
                state->set_recommendation(state,
                                                                TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION,
index 1fbde2c..a0d1765 100644 (file)
@@ -1,5 +1,6 @@
 /*
- * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
+ * Copyright (C) 2011-2012 Sansar Choinyambuu
+ * Copyright (C) 2011-2014 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -16,8 +17,6 @@
 #include "imv_attestation_build.h"
 #include "imv_attestation_state.h"
 
-#include <tcg/pts/tcg_pts_attr_proto_caps.h>
-#include <tcg/pts/tcg_pts_attr_meas_algo.h>
 #include <tcg/pts/tcg_pts_attr_dh_nonce_params_req.h>
 #include <tcg/pts/tcg_pts_attr_dh_nonce_finish.h>
 #include <tcg/pts/tcg_pts_attr_get_tpm_version_info.h>
@@ -27,9 +26,7 @@
 
 #include <utils/debug.h>
 
-bool imv_attestation_build(imv_msg_t *out_msg,
-                                                  imv_state_t *state,
-                                                  pts_meas_algorithms_t supported_algorithms,
+bool imv_attestation_build(imv_msg_t *out_msg, imv_state_t *state,
                                                   pts_dh_group_t supported_dh_groups,
                                                   pts_database_t *pts_db)
 {
@@ -42,60 +39,8 @@ bool imv_attestation_build(imv_msg_t *out_msg,
        handshake_state = attestation_state->get_handshake_state(attestation_state);
        pts = attestation_state->get_pts(attestation_state);
 
-       /**
-        * Received a response form the Attestation IMC so we can proceeed
-        */
-       if (handshake_state == IMV_ATTESTATION_STATE_DISCOVERY &&
-          (state->get_action_flags(state) & IMV_ATTESTATION_FLAG_ALGO))
-       {
-               handshake_state = IMV_ATTESTATION_STATE_NONCE_REQ;
-       }
-
-       /**
-        * Skip DH Nonce Parameters Request attribute when
-        *   DH Nonce Exchange is not selected by PTS-IMC side
-        */
-       if (handshake_state == IMV_ATTESTATION_STATE_NONCE_REQ &&
-               !(pts->get_proto_caps(pts) & PTS_PROTO_CAPS_D))
-       {
-               DBG2(DBG_IMV, "PTS-IMC does not support DH Nonce negotiation");
-               handshake_state = IMV_ATTESTATION_STATE_TPM_INIT;
-       }
-
-       /**
-        * Skip TPM Version Info and AIK attributes when
-        *   no TPM is available on the PTS-IMC side
-        */
-       if (handshake_state == IMV_ATTESTATION_STATE_TPM_INIT &&
-               !(pts->get_proto_caps(pts) & PTS_PROTO_CAPS_T))
-       {
-               DBG2(DBG_IMV, "PTS-IMC made no TPM available");
-               handshake_state = IMV_ATTESTATION_STATE_END;
-       }
-
        switch (handshake_state)
        {
-               case IMV_ATTESTATION_STATE_INIT:
-               {
-                       pts_proto_caps_flag_t flags;
-
-                       /* Send Request Protocol Capabilities attribute */
-                       flags = pts->get_proto_caps(pts);
-                       attr = tcg_pts_attr_proto_caps_create(flags, TRUE);
-                       attr->set_noskip_flag(attr, TRUE);
-                       out_msg->add_attribute(out_msg, attr);
-
-                       /* Send Measurement Algorithms attribute */
-                       attr = tcg_pts_attr_meas_algo_create(supported_algorithms, FALSE);
-                       attr->set_noskip_flag(attr, TRUE);
-                       out_msg->add_attribute(out_msg, attr);
-
-                       attestation_state->set_handshake_state(attestation_state,
-                                                                               IMV_ATTESTATION_STATE_DISCOVERY);
-                       break;
-               }
-               case IMV_ATTESTATION_STATE_DISCOVERY:
-                       break;
                case IMV_ATTESTATION_STATE_NONCE_REQ:
                {
                        int min_nonce_len;
@@ -117,16 +62,13 @@ bool imv_attestation_build(imv_msg_t *out_msg,
                        pts_meas_algorithms_t selected_algorithm;
                        chunk_t initiator_value, initiator_nonce;
 
-                       if ((pts->get_proto_caps(pts) & PTS_PROTO_CAPS_D))
-                       {
-                               /* Send DH nonce finish attribute */
-                               selected_algorithm = pts->get_meas_algorithm(pts);
-                               pts->get_my_public_value(pts, &initiator_value, &initiator_nonce);
-                               attr = tcg_pts_attr_dh_nonce_finish_create(selected_algorithm,
+                       /* Send DH nonce finish attribute */
+                       selected_algorithm = pts->get_meas_algorithm(pts);
+                       pts->get_my_public_value(pts, &initiator_value, &initiator_nonce);
+                       attr = tcg_pts_attr_dh_nonce_finish_create(selected_algorithm,
                                                                                        initiator_value, initiator_nonce);
-                               attr->set_noskip_flag(attr, TRUE);
-                               out_msg->add_attribute(out_msg, attr);
-                       }
+                       attr->set_noskip_flag(attr, TRUE);
+                       out_msg->add_attribute(out_msg, attr);
 
                        /* Send Get TPM Version attribute */
                        attr = tcg_pts_attr_get_tpm_version_info_create();
@@ -146,24 +88,16 @@ bool imv_attestation_build(imv_msg_t *out_msg,
                {
                        tcg_pts_attr_req_func_comp_evid_t *attr_cast;
                        enumerator_t *enumerator;
-                       pts_component_t *comp;
-                       pts_comp_func_name_t *comp_name;
+                       pts_comp_func_name_t *name;
                        chunk_t keyid;
-                       int kid, vid, name, qualifier;
+                       int kid;
                        u_int8_t flags;
                        u_int32_t depth;
-                       bool first = TRUE, first_component = TRUE;
+                       bool first_component = TRUE;
 
                        attestation_state->set_handshake_state(attestation_state,
                                                                                IMV_ATTESTATION_STATE_END);
 
-                       if (!(pts->get_proto_caps(pts) & PTS_PROTO_CAPS_T) ||
-                               !(pts->get_proto_caps(pts) & PTS_PROTO_CAPS_D))
-                       {
-                               DBG2(DBG_IMV, "PTS-IMC made no TPM available - "
-                                                         "skipping Component Measurements");
-                               break;
-                       }
                        if (!pts->get_aik_keyid(pts, &keyid))
                        {
                                DBG1(DBG_IMV, "retrieval of AIK keyid failed");
@@ -178,41 +112,22 @@ bool imv_attestation_build(imv_msg_t *out_msg,
                        {
                                return FALSE;
                        }
-                       enumerator = pts_db->create_comp_evid_enumerator(pts_db, kid);
-                       if (!enumerator)
-                       {
-                               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;
index 0cee49b..88538b1 100644 (file)
  *
  * @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);
 
index bd1109a..9422cf4 100644 (file)
@@ -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 ");
index 200de1e..c2adbf5 100644 (file)
@@ -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,
index 6ee9ed1..3636b56 100644 (file)
@@ -117,6 +117,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
index 5249fa2..e10845b 100644 (file)
@@ -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);
 }