Factored IMC/V Attestation build/process of Component Functional Name
[strongswan.git] / src / libimcv / plugins / imv_attestation / imv_attestation_build.c
index 6d0e894..d4ec8a6 100644 (file)
@@ -16,6 +16,7 @@
 #include "imv_attestation_build.h"
 #include "imv_attestation_state.h"
 
+#include <libpts.h>
 #include <tcg/tcg_pts_attr_proto_caps.h>
 #include <tcg/tcg_pts_attr_meas_algo.h>
 #include <tcg/tcg_pts_attr_dh_nonce_params_req.h>
@@ -42,13 +43,34 @@ bool imv_attestation_build(pa_tnc_msg_t *msg,
        handshake_state = attestation_state->get_handshake_state(attestation_state);
        pts = attestation_state->get_pts(attestation_state);
 
+       /* D-H attributes are redundant */
+       /*  when D-H Nonce Exchange is not selected on IMC side */
        if (handshake_state == IMV_ATTESTATION_STATE_NONCE_REQ &&
+               !(pts->get_proto_caps(pts) & PTS_PROTO_CAPS_D))
+       {
+               DBG1(DBG_IMV, "PTS-IMC is not using Diffie-Hellman Nonce negotiation,"
+                                         "advancing to TPM Initialization phase");
+               handshake_state = IMV_ATTESTATION_STATE_TPM_INIT;
+       }
+       /* TPM Version Info, AIK attributes are redundant */
+       /*  when TPM is not available on IMC side */
+       if (handshake_state == IMV_ATTESTATION_STATE_TPM_INIT &&
                !(pts->get_proto_caps(pts) & PTS_PROTO_CAPS_T))
        {
-               DBG1(DBG_IMV, "PTS-IMC has no TPM capability - "
-                                         "advancing to PTS measurement phase");
+               DBG1(DBG_IMV, "PTS-IMC has not got TPM available,"
+                                         "advancing to File Measurement phase");
                handshake_state = IMV_ATTESTATION_STATE_MEAS;
        }
+       /* Component Measurement cannot be done without D-H Nonce Exchange */
+       /*  or TPM on IMC side */
+       if (handshake_state == IMV_ATTESTATION_STATE_COMP_EVID &&
+               (!(pts->get_proto_caps(pts) & PTS_PROTO_CAPS_T) ||
+               !(pts->get_proto_caps(pts) & PTS_PROTO_CAPS_D)) )
+       {
+               DBG1(DBG_IMV, "PTS-IMC has not got TPM available,"
+                                         "skipping Component Measurement phase");
+               handshake_state = IMV_ATTESTATION_STATE_END;
+       }
 
        /* Switch on the attribute type IMV has received */
        switch (handshake_state)
@@ -93,13 +115,16 @@ bool imv_attestation_build(pa_tnc_msg_t *msg,
                        pts_meas_algorithms_t selected_algorithm;
                        chunk_t initiator_value, initiator_nonce;
 
-                       /* 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);
-                       msg->add_attribute(msg, attr);
+                       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,
+                                                                                       initiator_value, initiator_nonce);
+                               attr->set_noskip_flag(attr, TRUE);
+                               msg->add_attribute(msg, attr);
+                       }
 
                        /* Send Get TPM Version attribute */
                        attr = tcg_pts_attr_get_tpm_version_info_create();
@@ -117,7 +142,6 @@ bool imv_attestation_build(pa_tnc_msg_t *msg,
                }
                case IMV_ATTESTATION_STATE_MEAS:
                {
-
                        enumerator_t *enumerator;
                        u_int32_t delimiter = SOLIDUS_UTF;
                        char *platform_info, *pathname;
@@ -142,7 +166,8 @@ bool imv_attestation_build(pa_tnc_msg_t *msg,
                        DBG1(DBG_IMV, "platform is '%s'", platform_info);
 
                        /* Send Request File Metadata attribute */
-                       enumerator = pts_db->create_file_meta_enumerator(pts_db, platform_info);
+                       enumerator = pts_db->create_file_meta_enumerator(pts_db,
+                                                                                                                        platform_info);
                        if (!enumerator)
                        {
                                break;
@@ -152,14 +177,16 @@ bool imv_attestation_build(pa_tnc_msg_t *msg,
                                is_dir = (type != 0);
                                DBG2(DBG_IMV, "metadata request for %s '%s'",
                                         is_dir ? "directory" : "file", pathname);
-                               attr = tcg_pts_attr_req_file_meta_create(is_dir, delimiter, pathname);
+                               attr = tcg_pts_attr_req_file_meta_create(is_dir, delimiter,
+                                                                                                                pathname);
                                attr->set_noskip_flag(attr, TRUE);
                                msg->add_attribute(msg, attr);
                        }
                        enumerator->destroy(enumerator);
                        
                        /* Send Request File Measurement attribute */
-                       enumerator = pts_db->create_file_enumerator(pts_db, platform_info);
+                       enumerator = pts_db->create_file_meas_enumerator(pts_db,
+                                                                                                                        platform_info);
                        if (!enumerator)
                        {
                                break;
@@ -167,8 +194,8 @@ bool imv_attestation_build(pa_tnc_msg_t *msg,
                        while (enumerator->enumerate(enumerator, &id, &type, &pathname))
                        {
                                is_dir = (type != 0);
-                               request_id = attestation_state->add_request(attestation_state,
-                                                                                                                       id, is_dir);
+                               request_id = attestation_state->add_file_meas_request(
+                                                       attestation_state, id, is_dir);
                                DBG2(DBG_IMV, "measurement request %d for %s '%s'",
                                         request_id, is_dir ? "directory" : "file", pathname);
                                attr = tcg_pts_attr_req_file_meas_create(is_dir, request_id,
@@ -181,31 +208,78 @@ bool imv_attestation_build(pa_tnc_msg_t *msg,
                }
                case IMV_ATTESTATION_STATE_COMP_EVID:
                {
-                       pts_attr_req_funct_comp_evid_flag_t flags;
-                       u_int32_t sub_comp_depth;
-                       pts_qualifier_t qualifier;
-                       pts_funct_comp_name_t name;
+                       enumerator_t *enumerator;
+                       /* TODO: pts_components undeclared */
+                       /*char flags[8];
+                       int type;
+                       */
+                       char *platform_info;
+                       pts_funct_comp_evid_req_t *requests = NULL;
+                       funct_comp_evid_req_entry_t *entry;
+                       int vid, name, qualifier;
+                       
+                       bool first_req = TRUE;
 
                        attestation_state->set_handshake_state(attestation_state,
                                                                                IMV_ATTESTATION_STATE_END);
 
-                       flags = PTS_REQ_FUNC_COMP_FLAG_PCR;
-                       sub_comp_depth = 0;
-                       qualifier.kernel = FALSE;
-                       qualifier.sub_component = FALSE;
-                       qualifier.type = PTS_FUNC_COMP_TYPE_ALL;
-                       name = PTS_FUNC_COMP_NAME_BIOS;
+                       /* Get Platform and OS of the PTS-IMC */
+                       platform_info = pts->get_platform_info(pts);
+                       if (!pts_db || !platform_info)
+                       {
+                               DBG1(DBG_IMV, "%s%s%s not available",
+                                       (pts_db) ? "" : "pts database",
+                                       (!pts_db && !platform_info) ? "and" : "",
+                                       (platform_info) ? "" : "platform info");
+                               break;
+                       }
+                       DBG1(DBG_IMV, "platform is '%s'", platform_info);
+
+                       
+                       enumerator = pts_db->create_comp_evid_enumerator(pts_db, platform_info);
+                       if (!enumerator)
+                       {
+                               break;
+                       }
+                       while (enumerator->enumerate(enumerator, &vid, &name, &qualifier))
+                       {
+                               entry = malloc_thing(funct_comp_evid_req_entry_t);
+                               entry->flags = PTS_REQ_FUNC_COMP_FLAG_PCR;
+                               entry->sub_comp_depth = 0;
+                               entry->name = pts_comp_func_name_create(vid, name, qualifier);
+
+                               /* TODO: pts_components undeclared */
+                               /*type = pts_components->get_qualifier(pts_components,
+                                                                                                        entry->name, &flags);
+
+                               DBG2(DBG_TNC, "%N functional component '%N' with qualifier %s '%N'",
+                                        pen_names, vid,
+                                        pts_components->get_comp_func_names(pts_components, vid),
+                                        name, flags,
+                                        pts_components->get_qualifier_type_names(pts_components, vid),
+                                        type);
+                               */
+                               if (first_req)
+                               {
+                                       /* Create a requests object */
+                                       requests = pts_funct_comp_evid_req_create();
+                                       first_req = FALSE;
+                               }
+                               requests->add(requests, entry);
+                               attestation_state->add_comp_evid_request(attestation_state, entry);
+                       }
+                       enumerator->destroy(enumerator);
 
                        /* Send Request Functional Component Evidence attribute */
-                       attr = tcg_pts_attr_req_funct_comp_evid_create(flags, sub_comp_depth,
-                                                                                                               PEN_TCG, qualifier, name);
+                       attr = tcg_pts_attr_req_funct_comp_evid_create(requests);
                        attr->set_noskip_flag(attr, TRUE);
                        msg->add_attribute(msg, attr);
+
                        /* Send Generate Attestation Evidence attribute */
                        attr = tcg_pts_attr_gen_attest_evid_create();
                        attr->set_noskip_flag(attr, TRUE);
                        msg->add_attribute(msg, attr);
-
+                       
                        break;
                }
                default: