File not Found, Invalid path, Invalid Delimiter PTS errors case checks implemented
[strongswan.git] / src / libimcv / plugins / imc_attestation / imc_attestation.c
index 7c41e56..58fb178 100644 (file)
 #include <pa_tnc/pa_tnc_msg.h>
 #include <ietf/ietf_attr.h>
 #include <ietf/ietf_attr_pa_tnc_error.h>
 #include <pa_tnc/pa_tnc_msg.h>
 #include <ietf/ietf_attr.h>
 #include <ietf/ietf_attr_pa_tnc_error.h>
+#include <ietf/ietf_attr_product_info.h>
 
 
-#include <tcg/pts/pts_error.h>
+#include <libpts.h>
+
+#include <pts/pts_error.h>
 
 #include <tcg/tcg_pts_attr_proto_caps.h>
 #include <tcg/tcg_pts_attr_meas_algo.h>
 
 #include <tcg/tcg_pts_attr_proto_caps.h>
 #include <tcg/tcg_pts_attr_meas_algo.h>
@@ -68,12 +71,19 @@ TNC_Result TNC_IMC_Initialize(TNC_IMCID imc_id,
                DBG1(DBG_IMC, "IMC \"%s\" has already been initialized", imc_name);
                return TNC_RESULT_ALREADY_INITIALIZED;
        }
                DBG1(DBG_IMC, "IMC \"%s\" has already been initialized", imc_name);
                return TNC_RESULT_ALREADY_INITIALIZED;
        }
+       if (!pts_meas_probe_algorithms(&supported_algorithms))
+       {
+               return TNC_RESULT_FATAL;
+       }
        imc_attestation = imc_agent_create(imc_name, IMC_VENDOR_ID, IMC_SUBTYPE,
        imc_attestation = imc_agent_create(imc_name, IMC_VENDOR_ID, IMC_SUBTYPE,
-                                                               imc_id, actual_version);
-       if (!imc_attestation || !pts_meas_probe_algorithms(&supported_algorithms))
+                                                                          imc_id, actual_version);
+       if (!imc_attestation)
        {
                return TNC_RESULT_FATAL;
        }
        {
                return TNC_RESULT_FATAL;
        }
+
+       libpts_init();
+
        if (min_version > TNC_IFIMC_VERSION_1 || max_version < TNC_IFIMC_VERSION_1)
        {
                DBG1(DBG_IMC, "no common IF-IMC version");
        if (min_version > TNC_IFIMC_VERSION_1 || max_version < TNC_IFIMC_VERSION_1)
        {
                DBG1(DBG_IMC, "no common IF-IMC version");
@@ -121,12 +131,42 @@ TNC_Result TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id,
 TNC_Result TNC_IMC_BeginHandshake(TNC_IMCID imc_id,
                                                                  TNC_ConnectionID connection_id)
 {
 TNC_Result TNC_IMC_BeginHandshake(TNC_IMCID imc_id,
                                                                  TNC_ConnectionID connection_id)
 {
+       imc_state_t *state;
+       imc_attestation_state_t *attestation_state;
+       pts_t *pts;
+       char *platform_info;
+       TNC_Result result = TNC_RESULT_SUCCESS;
+
        if (!imc_attestation)
        {
                DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
                return TNC_RESULT_NOT_INITIALIZED;
        }
        if (!imc_attestation)
        {
                DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
                return TNC_RESULT_NOT_INITIALIZED;
        }
-       return TNC_RESULT_SUCCESS;
+
+       /* get current IMC state */
+       if (!imc_attestation->get_state(imc_attestation, connection_id, &state))
+       {
+               return TNC_RESULT_FATAL;
+       }
+       attestation_state = (imc_attestation_state_t*)state;
+       pts = attestation_state->get_pts(attestation_state);
+
+       platform_info = pts->get_platform_info(pts);
+       if (platform_info)
+       {
+               pa_tnc_msg_t *pa_tnc_msg;
+               pa_tnc_attr_t *attr;
+
+               pa_tnc_msg = pa_tnc_msg_create();
+               attr = ietf_attr_product_info_create(0, 0, platform_info);
+               pa_tnc_msg->add_attribute(pa_tnc_msg, attr);
+               pa_tnc_msg->build(pa_tnc_msg);
+               result = imc_attestation->send_message(imc_attestation, connection_id,
+                                                                       pa_tnc_msg->get_encoding(pa_tnc_msg));
+               pa_tnc_msg->destroy(pa_tnc_msg);
+       }
+
+       return result;
 }
 
 /**
 }
 
 /**
@@ -162,7 +202,7 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id,
        attestation_state = (imc_attestation_state_t*)state;
        pts = attestation_state->get_pts(attestation_state);
 
        attestation_state = (imc_attestation_state_t*)state;
        pts = attestation_state->get_pts(attestation_state);
 
-       /* parse received PA-TNC message and automatically handle any errors */ 
+       /* parse received PA-TNC message and automatically handle any errors */
        result = imc_attestation->receive_message(imc_attestation, connection_id,
                                                                           chunk_create(msg, msg_len), msg_type,
                                                                           &pa_tnc_msg);
        result = imc_attestation->receive_message(imc_attestation, connection_id,
                                                                           chunk_create(msg, msg_len), msg_type,
                                                                           &pa_tnc_msg);
@@ -222,7 +262,7 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id,
                                        imc_flags = pts->get_proto_caps(pts);
                                        pts->set_proto_caps(pts, imc_flags & imv_flags);
 
                                        imc_flags = pts->get_proto_caps(pts);
                                        pts->set_proto_caps(pts, imc_flags & imv_flags);
 
-                                       /* Send PTS Protocol Capabilities attribute */ 
+                                       /* Send PTS Protocol Capabilities attribute */
                                        attr = tcg_pts_attr_proto_caps_create(imc_flags & imv_flags,
                                                                                                                  FALSE);
                                        attr_list->insert_last(attr_list, attr);
                                        attr = tcg_pts_attr_proto_caps_create(imc_flags & imv_flags,
                                                                                                                  FALSE);
                                        attr_list->insert_last(attr_list, attr);
@@ -232,7 +272,7 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id,
                                {
                                        tcg_pts_attr_meas_algo_t *attr_cast;
                                        pts_meas_algorithms_t selected_algorithm;
                                {
                                        tcg_pts_attr_meas_algo_t *attr_cast;
                                        pts_meas_algorithms_t selected_algorithm;
-                                       
+       
                                        attr_cast = (tcg_pts_attr_meas_algo_t*)attr;
                                        selected_algorithm = attr_cast->get_algorithms(attr_cast);
 
                                        attr_cast = (tcg_pts_attr_meas_algo_t*)attr;
                                        selected_algorithm = attr_cast->get_algorithms(attr_cast);
 
@@ -259,14 +299,14 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id,
                                                break;
                                        }
 
                                                break;
                                        }
 
-                                       /* Send Measurement Algorithm Selection attribute */ 
+                                       /* Send Measurement Algorithm Selection attribute */
                                        selected_algorithm = pts->get_meas_algorithm(pts);
                                        attr = tcg_pts_attr_meas_algo_create(selected_algorithm,
                                                                                                                 TRUE);
                                        attr_list->insert_last(attr_list, attr);
                                        break;
                                }
                                        selected_algorithm = pts->get_meas_algorithm(pts);
                                        attr = tcg_pts_attr_meas_algo_create(selected_algorithm,
                                                                                                                 TRUE);
                                        attr_list->insert_last(attr_list, attr);
                                        break;
                                }
-                                       
+       
                                case TCG_PTS_GET_TPM_VERSION_INFO:
                                {
                                        chunk_t tpm_version_info, attr_info;
                                case TCG_PTS_GET_TPM_VERSION_INFO:
                                {
                                        chunk_t tpm_version_info, attr_info;
@@ -279,30 +319,30 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id,
                                                attr_list->insert_last(attr_list, attr);
                                                break;
                                        }
                                                attr_list->insert_last(attr_list, attr);
                                                break;
                                        }
-                                       
-                                       /* Send TPM Version Info attribute */ 
+       
+                                       /* Send TPM Version Info attribute */
                                        attr = tcg_pts_attr_tpm_version_info_create(tpm_version_info);
                                        attr_list->insert_last(attr_list, attr);
                                        break;
                                }
                                        attr = tcg_pts_attr_tpm_version_info_create(tpm_version_info);
                                        attr_list->insert_last(attr_list, attr);
                                        break;
                                }
-                               
+       
                                case TCG_PTS_GET_AIK:
                                {
                                case TCG_PTS_GET_AIK:
                                {
-                                       chunk_t aik;
-                                       bool is_naked_key;
+                                       certificate_t *aik;
 
 
-                                       if (!pts->get_aik(pts, &aik, &is_naked_key))
+                                       aik = pts->get_aik(pts);
+                                       if (!aik)
                                        {
                                        {
-                                               DBG1(DBG_IMC, "Obtaining AIK Certificate failed");
+                                               DBG1(DBG_IMC, "no AIK certificate or public key available");
                                                break;
                                        }
                                                break;
                                        }
-                                       
-                                       /* Send AIK attribute */ 
-                                       attr = tcg_pts_attr_aik_create(is_naked_key, aik);
+       
+                                       /* Send AIK attribute */
+                                       attr = tcg_pts_attr_aik_create(aik);
                                        attr_list->insert_last(attr_list, attr);
                                        break;
                                }
                                        attr_list->insert_last(attr_list, attr);
                                        break;
                                }
-                               
+       
                                /* PTS-based Attestation Evidence */
                                case TCG_PTS_REQ_FUNCT_COMP_EVID:
                                        break;
                                /* PTS-based Attestation Evidence */
                                case TCG_PTS_REQ_FUNCT_COMP_EVID:
                                        break;
@@ -314,12 +354,39 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id,
                                        char *pathname;
                                        u_int16_t request_id;
                                        bool is_directory;
                                        char *pathname;
                                        u_int16_t request_id;
                                        bool is_directory;
+                                       u_int32_t delimiter;
                                        pts_file_meas_t *measurements;
                                        pts_file_meas_t *measurements;
-
+                                       pts_error_code_t pts_error;
+                                       chunk_t attr_info;
+                                       
+                                       attr_info = attr->get_value(attr);
                                        attr_cast = (tcg_pts_attr_req_file_meas_t*)attr;
                                        is_directory = attr_cast->get_directory_flag(attr_cast);
                                        request_id = attr_cast->get_request_id(attr_cast);
                                        attr_cast = (tcg_pts_attr_req_file_meas_t*)attr;
                                        is_directory = attr_cast->get_directory_flag(attr_cast);
                                        request_id = attr_cast->get_request_id(attr_cast);
+                                       delimiter = attr_cast->get_delimiter(attr_cast);
                                        pathname = attr_cast->get_pathname(attr_cast);
                                        pathname = attr_cast->get_pathname(attr_cast);
+                                       
+                                       if (pts->is_path_valid(pts, pathname, &pts_error) && pts_error)
+                                       {
+                                               attr_info = attr->get_value(attr);
+                                               attr = ietf_attr_pa_tnc_error_create(PEN_TCG,
+                                                                                               pts_error, attr_info);
+                                               attr_list->insert_last(attr_list, attr);
+                                               break;
+                                       }
+                                       else if (!pts->is_path_valid(pts, pathname, &pts_error))
+                                       {
+                                               break;
+                                       }
+                                       
+                                       if (delimiter != SOLIDUS_UTF && delimiter != REVERSE_SOLIDUS_UTF)
+                                       {
+                                               attr_info = attr->get_value(attr);
+                                               attr = ietf_attr_pa_tnc_error_create(PEN_TCG,
+                                                                                               TCG_PTS_INVALID_DELIMITER, attr_info);
+                                               attr_list->insert_last(attr_list, attr);
+                                               break;
+                                       }
 
                                        /* Do PTS File Measurements and send them to PTS-IMV */
                                        DBG2(DBG_IMC, "measurement request %d for %s '%s'",
 
                                        /* Do PTS File Measurements and send them to PTS-IMV */
                                        DBG2(DBG_IMC, "measurement request %d for %s '%s'",
@@ -353,7 +420,7 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id,
                                case TCG_PTS_MEAS_ALGO_SELECTION:
                                case TCG_PTS_TPM_VERSION_INFO:
                                case TCG_PTS_TEMPL_REF_MANI_SET_META:
                                case TCG_PTS_MEAS_ALGO_SELECTION:
                                case TCG_PTS_TPM_VERSION_INFO:
                                case TCG_PTS_TEMPL_REF_MANI_SET_META:
-                               case TCG_PTS_AIK:                               
+                               case TCG_PTS_AIK:
                                case TCG_PTS_SIMPLE_COMP_EVID:
                                case TCG_PTS_SIMPLE_EVID_FINAL:
                                case TCG_PTS_VERIFICATION_RESULT:
                                case TCG_PTS_SIMPLE_COMP_EVID:
                                case TCG_PTS_SIMPLE_EVID_FINAL:
                                case TCG_PTS_VERIFICATION_RESULT:
@@ -372,7 +439,7 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id,
        pa_tnc_msg->destroy(pa_tnc_msg);
 
        result = TNC_RESULT_SUCCESS;
        pa_tnc_msg->destroy(pa_tnc_msg);
 
        result = TNC_RESULT_SUCCESS;
-               
+       
        if (attr_list->get_count(attr_list))
        {
                pa_tnc_msg = pa_tnc_msg_create();
        if (attr_list->get_count(attr_list))
        {
                pa_tnc_msg = pa_tnc_msg_create();
@@ -387,10 +454,9 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id,
                pa_tnc_msg->build(pa_tnc_msg);
                result = imc_attestation->send_message(imc_attestation, connection_id,
                                                        pa_tnc_msg->get_encoding(pa_tnc_msg));
                pa_tnc_msg->build(pa_tnc_msg);
                result = imc_attestation->send_message(imc_attestation, connection_id,
                                                        pa_tnc_msg->get_encoding(pa_tnc_msg));
-       
-               attr_list->destroy(attr_list);
                pa_tnc_msg->destroy(pa_tnc_msg);
        }
                pa_tnc_msg->destroy(pa_tnc_msg);
        }
+       attr_list->destroy(attr_list);
 
        return result;
 }
 
        return result;
 }
@@ -419,6 +485,9 @@ TNC_Result TNC_IMC_Terminate(TNC_IMCID imc_id)
                DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
                return TNC_RESULT_NOT_INITIALIZED;
        }
                DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
                return TNC_RESULT_NOT_INITIALIZED;
        }
+
+       libpts_deinit();
+
        imc_attestation->destroy(imc_attestation);
        imc_attestation = NULL;
 
        imc_attestation->destroy(imc_attestation);
        imc_attestation = NULL;