check if TNC client has a valid and registered AIK
[strongswan.git] / src / libpts / plugins / imv_attestation / imv_attestation_build.c
index c2447cd..4f2cc1e 100644 (file)
@@ -30,7 +30,7 @@
 
 #include <debug.h>
 
-bool imv_attestation_build(pa_tnc_msg_t *msg,
+bool imv_attestation_build(linked_list_t *attr_list,
                                                   imv_attestation_state_t *attestation_state,
                                                   pts_meas_algorithms_t supported_algorithms,
                                                   pts_dh_group_t supported_dh_groups,
@@ -43,36 +43,30 @@ 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 */
+       /**
+        * 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))
        {
-               DBG1(DBG_IMV, "PTS-IMC is not using Diffie-Hellman Nonce negotiation,"
-                                         "advancing to TPM Initialization phase");
+               DBG2(DBG_IMV, "PTS-IMC does not support DH Nonce negotiation - "
+                                         "advancing to TPM Initialization");
                handshake_state = IMV_ATTESTATION_STATE_TPM_INIT;
        }
-       /* TPM Version Info, AIK attributes are redundant */
-       /*  when TPM is not available on IMC side */
+
+       /**
+        * 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))
        {
-               DBG1(DBG_IMV, "PTS-IMC has not got TPM available,"
-                                         "advancing to File Measurement phase");
+               DBG2(DBG_IMV, "PTS-IMC made no TPM available - "
+                                         "advancing to File Measurements");
                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)
        {
                case IMV_ATTESTATION_STATE_INIT:
@@ -83,12 +77,12 @@ bool imv_attestation_build(pa_tnc_msg_t *msg,
                        flags = pts->get_proto_caps(pts);
                        attr = tcg_pts_attr_proto_caps_create(flags, TRUE);
                        attr->set_noskip_flag(attr, TRUE);
-                       msg->add_attribute(msg, attr);
+                       attr_list->insert_last(attr_list, attr);
 
                        /* Send Measurement Algorithms attribute */
                        attr = tcg_pts_attr_meas_algo_create(supported_algorithms, FALSE);
                        attr->set_noskip_flag(attr, TRUE);
-                       msg->add_attribute(msg, attr);
+                       attr_list->insert_last(attr_list, attr);
 
                        attestation_state->set_handshake_state(attestation_state,
                                                                                IMV_ATTESTATION_STATE_NONCE_REQ);
@@ -104,7 +98,7 @@ bool imv_attestation_build(pa_tnc_msg_t *msg,
                        attr = tcg_pts_attr_dh_nonce_params_req_create(min_nonce_len,
                                                                                                         supported_dh_groups);
                        attr->set_noskip_flag(attr, TRUE);
-                       msg->add_attribute(msg, attr);
+                       attr_list->insert_last(attr_list, attr);
 
                        attestation_state->set_handshake_state(attestation_state,
                                                                                IMV_ATTESTATION_STATE_TPM_INIT);
@@ -123,18 +117,18 @@ bool imv_attestation_build(pa_tnc_msg_t *msg,
                                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);
+                       attr_list->insert_last(attr_list, attr);
                        }
 
                        /* Send Get TPM Version attribute */
                        attr = tcg_pts_attr_get_tpm_version_info_create();
                        attr->set_noskip_flag(attr, TRUE);
-                       msg->add_attribute(msg, attr);
+                       attr_list->insert_last(attr_list, attr);
 
                        /* Send Get AIK attribute */
                        attr = tcg_pts_attr_get_aik_create();
                        attr->set_noskip_flag(attr, TRUE);
-                       msg->add_attribute(msg, attr);
+                       attr_list->insert_last(attr_list, attr);
 
                        attestation_state->set_handshake_state(attestation_state,
                                                                                IMV_ATTESTATION_STATE_MEAS);
@@ -180,7 +174,7 @@ bool imv_attestation_build(pa_tnc_msg_t *msg,
                                attr = tcg_pts_attr_req_file_meta_create(is_dir, delimiter,
                                                                                                                 pathname);
                                attr->set_noskip_flag(attr, TRUE);
-                               msg->add_attribute(msg, attr);
+                               attr_list->insert_last(attr_list, attr);
                        }
                        enumerator->destroy(enumerator);
                        
@@ -201,7 +195,7 @@ bool imv_attestation_build(pa_tnc_msg_t *msg,
                                attr = tcg_pts_attr_req_file_meas_create(is_dir, request_id,
                                                                                                         delimiter, pathname);
                                attr->set_noskip_flag(attr, TRUE);
-                               msg->add_attribute(msg, attr);
+                               attr_list->insert_last(attr_list, attr);
                        }
                        enumerator->destroy(enumerator);
                        break;
@@ -213,37 +207,53 @@ bool imv_attestation_build(pa_tnc_msg_t *msg,
                        pts_component_t *comp;
                        pts_comp_func_name_t *comp_name;
                        chunk_t keyid;
-                       int vid, name, qualifier;
+                       int kid, vid, name, qualifier;
                        u_int8_t flags;
                        u_int32_t depth;
-                       bool first = TRUE;
+                       bool first = TRUE, first_component = TRUE;
 
                        attestation_state->set_handshake_state(attestation_state,
                                                                                IMV_ATTESTATION_STATE_END);
 
-                       if (!pts->get_aik_keyid(pts, &keyid))
+                       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_PTS, "pts database not available");
+                               DBG1(DBG_IMV, "pts database not available");
                                break;
                        }
-                       
-                       enumerator = pts_db->create_comp_evid_enumerator(pts_db, keyid);
+                       if (pts_db->check_aik_keyid(pts_db, keyid, &kid) != SUCCESS)
+                       {
+                               return FALSE;
+                       }
+                       enumerator = pts_db->create_comp_evid_enumerator(pts_db, kid);
                        if (!enumerator)
                        {
                                break;
                        }
-                       DBG2(DBG_IMV, "evidence request by");
                        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 = pts_components->create(pts_components, comp_name, depth);
+                               comp = pts_components->create(pts_components, comp_name,
+                                                                                         depth, pts_db);
                                if (!comp)
                                {
                                        DBG2(DBG_IMV, "    not registered: removed from request");
@@ -251,11 +261,11 @@ bool imv_attestation_build(pa_tnc_msg_t *msg,
                                        continue;
                                }
                                attestation_state->add_component(attestation_state, comp);
-                               if (first)
+                               if (first_component)
                                {
                                        attr = tcg_pts_attr_req_func_comp_evid_create();
                                        attr->set_noskip_flag(attr, TRUE);
-                                       first = FALSE;
+                                       first_component = FALSE;
                                }
                                flags = comp->get_evidence_flags(comp);
                                /* TODO check flags against negotiated_caps */
@@ -267,19 +277,24 @@ bool imv_attestation_build(pa_tnc_msg_t *msg,
                        if (attr)
                        {
                                /* Send Request Functional Component Evidence attribute */
-                               msg->add_attribute(msg, attr);
+                               attr_list->insert_last(attr_list, 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);
+                               attr_list->insert_last(attr_list, attr);
+
+                               attestation_state->set_handshake_state(attestation_state,
+                                                                               IMV_ATTESTATION_STATE_EVID_FINAL);
                        }
                        break;
                }
-               default:
-                       DBG1(DBG_IMV, "Attestation IMV is in unknown state: \"%s\"",
-                                handshake_state);
-                       return FALSE;
+               case IMV_ATTESTATION_STATE_EVID_FINAL:
+                       attestation_state->set_handshake_state(attestation_state,
+                                                                               IMV_ATTESTATION_STATE_END);
+                       break;
+               case IMV_ATTESTATION_STATE_END:
+                       break;
        }
        return TRUE;
 }